Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.cvsignore17
-rw-r--r--AUTHORS1
-rw-r--r--ChangeLog108
-rw-r--r--Makefile.am2
-rw-r--r--NEWS10
-rw-r--r--README43
-rwxr-xr-xautogen.sh141
-rw-r--r--config.h.in5
-rw-r--r--configure.in18
-rw-r--r--doc/.cvsignore3
-rw-r--r--doc/Makefile.am19
-rw-r--r--doc/README17
-rw-r--r--doc/c-sharp188
-rw-r--r--doc/ccvs112
-rw-r--r--doc/class-library183
-rw-r--r--doc/class-status16
-rw-r--r--doc/contact16
-rw-r--r--doc/contributing105
-rw-r--r--doc/devel-faq190
-rw-r--r--doc/documentation50
-rw-r--r--doc/download177
-rw-r--r--doc/faq722
-rw-r--r--doc/gcc-frontend9
-rw-r--r--doc/ideas119
-rw-r--r--doc/index103
-rw-r--r--doc/passport276
-rw-r--r--doc/pending14
-rw-r--r--doc/rationale173
-rw-r--r--doc/release-notes/mono-0.346
-rw-r--r--doc/release-notes/mono-0.443
-rw-r--r--doc/resources121
-rw-r--r--doc/resources-pending30
-rw-r--r--doc/roadmap12
-rw-r--r--doc/runtime144
-rw-r--r--doc/status38
-rw-r--r--doc/team2
-rw-r--r--doc/testing21
-rw-r--r--doc/thanks6
-rw-r--r--doc/todo1
-rw-r--r--doc/tools67
-rw-r--r--doc/web/.cvsignore2
-rw-r--r--doc/web/commands17
-rw-r--r--doc/web/htmlify26
-rw-r--r--doc/web/images/bgsquares.gifbin0 -> 4963 bytes
-rw-r--r--doc/web/images/bgsquares.pngbin0 -> 4644 bytes
-rw-r--r--doc/web/images/bgsquares.xcf.gzbin0 -> 2775 bytes
-rw-r--r--doc/web/images/mono.gifbin0 -> 3079 bytes
-rw-r--r--doc/web/images/mono.pngbin0 -> 4496 bytes
-rw-r--r--doc/web/images/pixel.gifbin0 -> 49 bytes
-rw-r--r--doc/web/images/pixel.pngbin0 -> 157 bytes
-rw-r--r--doc/web/makefile39
-rwxr-xr-xdoc/web/process.pl73
-rw-r--r--doc/web/template.html.in78
-rw-r--r--libffi/.cvsignore16
-rw-r--r--libffi/ChangeLog440
-rw-r--r--libffi/ChangeLog.v1764
-rw-r--r--libffi/LICENSE20
-rw-r--r--libffi/Makefile.am72
-rw-r--r--libffi/README513
-rw-r--r--libffi/acconfig.h12
-rw-r--r--libffi/acinclude.m497
-rw-r--r--libffi/alpha/ffi.c247
-rw-r--r--libffi/alpha/osf.S278
-rw-r--r--libffi/arm/ffi.c183
-rw-r--r--libffi/arm/sysv.S111
-rwxr-xr-xlibffi/autogen.sh6
-rw-r--r--libffi/config-ml.in849
-rw-r--r--libffi/configure.in166
-rw-r--r--libffi/debug.c65
-rw-r--r--libffi/ffitest.c736
-rw-r--r--libffi/ia64/ffi.c670
-rw-r--r--libffi/ia64/ia64_flags.h62
-rw-r--r--libffi/ia64/unix.S301
-rw-r--r--libffi/include/.cvsignore3
-rw-r--r--libffi/include/Makefile.am6
-rw-r--r--libffi/include/ffi.h393
-rw-r--r--libffi/include/ffi_private.h168
-rw-r--r--libffi/java_raw_api.c269
-rw-r--r--libffi/m68k/ffi.c184
-rw-r--r--libffi/m68k/sysv.S96
-rw-r--r--libffi/mips/ffi.c469
-rw-r--r--libffi/mips/mips.h144
-rw-r--r--libffi/mips/n32.S320
-rw-r--r--libffi/mips/o32.S173
-rw-r--r--libffi/powerpc/asm.h128
-rw-r--r--libffi/powerpc/ffi.c680
-rw-r--r--libffi/powerpc/ppc_closure.S148
-rw-r--r--libffi/powerpc/sysv.S119
-rw-r--r--libffi/prep_cif.c146
-rw-r--r--libffi/raw_api.c240
-rw-r--r--libffi/s390/ffi.c589
-rw-r--r--libffi/s390/sysv.S161
-rw-r--r--libffi/sparc/ffi.c422
-rw-r--r--libffi/sparc/v8.S94
-rw-r--r--libffi/sparc/v9.S126
-rw-r--r--libffi/testsuite/.cvsignore2
-rw-r--r--libffi/testsuite/Makefile.am15
-rw-r--r--libffi/testsuite/config/default.exp1
-rw-r--r--libffi/testsuite/lib/libffi.exp44
-rw-r--r--libffi/testsuite/libffi.call/call.exp13
-rw-r--r--libffi/testsuite/libffi.call/ffitest.h4
-rw-r--r--libffi/testsuite/libffi.call/float.c55
-rw-r--r--libffi/testsuite/libffi.call/many.c63
-rw-r--r--libffi/testsuite/libffi.call/strlen.c38
-rw-r--r--libffi/types.c153
-rw-r--r--libffi/x86/ffi.c508
-rw-r--r--libffi/x86/sysv.S167
-rw-r--r--libffi/x86/win32.S125
-rwxr-xr-xmcs/AUTHORS13
-rwxr-xr-xmcs/README21
-rw-r--r--mcs/class/README34
-rw-r--r--mcs/class/System.Data/makefile4
-rw-r--r--mcs/class/System.Drawing/System.Drawing/ChangeLog8
-rw-r--r--mcs/class/System.Drawing/System.Drawing/Point.cs339
-rw-r--r--mcs/class/System.Drawing/System.Drawing/PointF.cs204
-rw-r--r--mcs/class/System.Drawing/System.Drawing/Size.cs309
-rw-r--r--mcs/class/System.Drawing/System.Drawing/SizeF.cs249
-rw-r--r--mcs/class/System.Drawing/makefile4
-rw-r--r--mcs/class/System.Management/makefile4
-rw-r--r--mcs/class/System.Web/ChangeLog16
-rw-r--r--mcs/class/System.Web/System.Web.Caching/Cache.cs520
-rw-r--r--mcs/class/System.Web/System.Web.Caching/CacheDefinitions.cs53
-rw-r--r--mcs/class/System.Web/System.Web.Caching/CacheDependency.cs79
-rw-r--r--mcs/class/System.Web/System.Web.Caching/CacheEntry.cs363
-rw-r--r--mcs/class/System.Web/System.Web.Caching/CacheExpires.cs145
-rw-r--r--mcs/class/System.Web/System.Web.Caching/ChangeLog8
-rw-r--r--mcs/class/System.Web/System.Web.Caching/ExpiresBuckets.cs253
-rw-r--r--mcs/class/System.Web/System.Web.Caching/common.src6
-rw-r--r--mcs/class/System.Web/System.Web.Caching/unix.src0
-rw-r--r--mcs/class/System.Web/System.Web.Caching/windows.src0
-rwxr-xr-xmcs/class/System.Web/System.Web.Configuration/AuthenticationMode.cs19
-rwxr-xr-xmcs/class/System.Web/System.Web.Configuration/FormsAuthPasswordFormat.cs18
-rwxr-xr-xmcs/class/System.Web/System.Web.Configuration/FormsProtectionEnum.cs19
-rw-r--r--mcs/class/System.Web/System.Web.UI.HtmlControls/ChangeLog5
-rw-r--r--mcs/class/System.Web/System.Web.UI.HtmlControls/HtmlContainerControl.cs75
-rw-r--r--mcs/class/System.Web/System.Web.UI.HtmlControls/HtmlControl.cs60
-rw-r--r--mcs/class/System.Web/System.Web.UI.HtmlControls/HtmlGenericControl.cs21
-rw-r--r--mcs/class/System.Web/System.Web.UI.HtmlControls/common.src3
-rw-r--r--mcs/class/System.Web/System.Web.UI.HtmlControls/unix.src0
-rw-r--r--mcs/class/System.Web/System.Web.UI.HtmlControls/windows.src0
-rw-r--r--mcs/class/System.Web/System.Web.UI/ChangeLog13
-rw-r--r--mcs/class/System.Web/System.Web.UI/Control.cs333
-rw-r--r--mcs/class/System.Web/System.Web.UI/LiteralControl.cs39
-rw-r--r--mcs/class/System.Web/System.Web/BeginEventHandler.cs16
-rw-r--r--mcs/class/System.Web/System.Web/ChangeLog22
-rw-r--r--mcs/class/System.Web/System.Web/EndEventHandler.cs13
-rw-r--r--mcs/class/System.Web/System.Web/HttpCacheRevalidation.cs18
-rw-r--r--mcs/class/System.Web/System.Web/HttpCacheValidateHandler.cs16
-rw-r--r--mcs/class/System.Web/System.Web/HttpCacheability.cs19
-rw-r--r--mcs/class/System.Web/System.Web/HttpCookie.cs117
-rw-r--r--mcs/class/System.Web/System.Web/HttpCookieCollection.cs70
-rw-r--r--mcs/class/System.Web/System.Web/HttpValidationStatus.cs18
-rw-r--r--mcs/class/System.Web/System.Web/HttpWorkerRequest.EndOfSendNotification.cs17
-rw-r--r--mcs/class/System.Web/System.Web/IHttpAsyncHandler.cs19
-rw-r--r--mcs/class/System.Web/System.Web/IHttpHandler.cs17
-rw-r--r--mcs/class/System.Web/System.Web/IHttpHandlerFactory.cs20
-rw-r--r--mcs/class/System.Web/System.Web/IHttpModule.cs17
-rw-r--r--mcs/class/System.Web/System.Web/NOTES10
-rw-r--r--mcs/class/System.Web/System.Web/ProcessShutdownReason.cs23
-rw-r--r--mcs/class/System.Web/System.Web/ProcessStatus.cs19
-rw-r--r--mcs/class/System.Web/System.Web/TODO27
-rw-r--r--mcs/class/System.Web/System.Web/TraceMode.cs17
-rw-r--r--mcs/class/System.Web/System.Web/common.src11
-rw-r--r--mcs/class/System.Web/System.Web/unix.src0
-rw-r--r--mcs/class/System.Web/System.Web/windows.src0
-rw-r--r--mcs/class/System.Web/Test/test.aspx29
-rw-r--r--mcs/class/System.Web/Test/test2.aspx20
-rw-r--r--mcs/class/System.Web/Test/test3.aspx23
-rw-r--r--mcs/class/System.Web/makefile17
-rw-r--r--mcs/class/System.XML/.cvsignore2
-rw-r--r--mcs/class/System.XML/System.Xml/Driver.cs57
-rw-r--r--mcs/class/System.XML/System.Xml/IXmlLineInfo.cs20
-rw-r--r--mcs/class/System.XML/System.Xml/Profile.cs47
-rw-r--r--mcs/class/System.XML/System.Xml/ReadState.cs21
-rw-r--r--mcs/class/System.XML/System.Xml/Test.cs1147
-rw-r--r--mcs/class/System.XML/System.Xml/WhitespaceHandling.cs19
-rw-r--r--mcs/class/System.XML/System.Xml/XmlChar.cs200
-rw-r--r--mcs/class/System.XML/System.Xml/XmlNameTable.cs20
-rw-r--r--mcs/class/System.XML/System.Xml/XmlNamespaceManager.cs22
-rw-r--r--mcs/class/System.XML/System.Xml/XmlNodeType.cs34
-rw-r--r--mcs/class/System.XML/System.Xml/XmlParserContext.cs127
-rw-r--r--mcs/class/System.XML/System.Xml/XmlReader.cs238
-rw-r--r--mcs/class/System.XML/System.Xml/XmlResolver.cs29
-rw-r--r--mcs/class/System.XML/System.Xml/XmlSpace.cs19
-rw-r--r--mcs/class/System.XML/System.Xml/XmlTextReader.cs1254
-rw-r--r--mcs/class/System.XML/System.Xml/common.src12
-rwxr-xr-xmcs/class/System.XML/System.Xml/unix.src0
-rwxr-xr-xmcs/class/System.XML/System.Xml/windows.src0
-rw-r--r--mcs/class/System.XML/makefile16
-rw-r--r--mcs/class/System/.cvsignore2
-rwxr-xr-xmcs/class/System/System.CodeDom.Compiler/ChangeLog5
-rwxr-xr-xmcs/class/System/System.CodeDom.Compiler/CodeGenerator.cs237
-rwxr-xr-xmcs/class/System/System.CodeDom.Compiler/ICodeGenerator.cs30
-rwxr-xr-xmcs/class/System/System.CodeDom.Compiler/common.src2
-rwxr-xr-xmcs/class/System/System.CodeDom.Compiler/unix.src0
-rwxr-xr-xmcs/class/System/System.CodeDom.Compiler/windows.src0
-rw-r--r--mcs/class/System/System.CodeDom/ChangeLog19
-rwxr-xr-xmcs/class/System/System.CodeDom/Code-X-Collection.cs159
-rwxr-xr-xmcs/class/System/System.CodeDom/CodeArrayCreateExpression.cs89
-rwxr-xr-xmcs/class/System/System.CodeDom/CodeAssignStatement.cs52
-rwxr-xr-xmcs/class/System/System.CodeDom/CodeAttachEventStatement.cs62
-rwxr-xr-xmcs/class/System/System.CodeDom/CodeAttributeArgument.cs60
-rwxr-xr-xmcs/class/System/System.CodeDom/CodeAttributeArgumentCollection.cs166
-rwxr-xr-xmcs/class/System/System.CodeDom/CodeAttributeBlock.cs42
-rwxr-xr-xmcs/class/System/System.CodeDom/CodeAttributeDeclaration.cs60
-rwxr-xr-xmcs/class/System/System.CodeDom/CodeAttributeDeclarationCollection.cs165
-rwxr-xr-xmcs/class/System/System.CodeDom/CodeBaseReferenceExpression.cs15
-rwxr-xr-xmcs/class/System/System.CodeDom/CodeBinaryOperatorExpression.cs88
-rwxr-xr-xmcs/class/System/System.CodeDom/CodeBinaryOperatorType.cs30
-rwxr-xr-xmcs/class/System/System.CodeDom/CodeCastExpression.cs52
-rwxr-xr-xmcs/class/System/System.CodeDom/CodeCatchClause.cs46
-rwxr-xr-xmcs/class/System/System.CodeDom/CodeCatchClauseCollection.cs165
-rwxr-xr-xmcs/class/System/System.CodeDom/CodeClass.cs107
-rwxr-xr-xmcs/class/System/System.CodeDom/CodeClassCollection.cs165
-rwxr-xr-xmcs/class/System/System.CodeDom/CodeClassConstructor.cs17
-rwxr-xr-xmcs/class/System/System.CodeDom/CodeClassDelegate.cs52
-rwxr-xr-xmcs/class/System/System.CodeDom/CodeClassMember.cs80
-rwxr-xr-xmcs/class/System/System.CodeDom/CodeClassMemberCollection.cs165
-rwxr-xr-xmcs/class/System/System.CodeDom/CodeCommentStatement.cs39
-rwxr-xr-xmcs/class/System/System.CodeDom/CodeConstructor.cs43
-rwxr-xr-xmcs/class/System/System.CodeDom/CodeDelegateCreateExpression.cs66
-rwxr-xr-xmcs/class/System/System.CodeDom/CodeDelegateInvokeExpression.cs59
-rwxr-xr-xmcs/class/System/System.CodeDom/CodeDelegateInvokeStatement.cs55
-rwxr-xr-xmcs/class/System/System.CodeDom/CodeDetachEventStatement.cs62
-rwxr-xr-xmcs/class/System/System.CodeDom/CodeExpression.cs35
-rwxr-xr-xmcs/class/System/System.CodeDom/CodeExpressionCollection.cs165
-rwxr-xr-xmcs/class/System/System.CodeDom/CodeFieldReferenceExpression.cs71
-rwxr-xr-xmcs/class/System/System.CodeDom/CodeForLoopStatement.cs78
-rwxr-xr-xmcs/class/System/System.CodeDom/CodeIfStatement.cs73
-rwxr-xr-xmcs/class/System/System.CodeDom/CodeIndexerExpression.cs34
-rwxr-xr-xmcs/class/System/System.CodeDom/CodeLinePragma.cs50
-rwxr-xr-xmcs/class/System/System.CodeDom/CodeLiteralClassMember.cs40
-rwxr-xr-xmcs/class/System/System.CodeDom/CodeLiteralExpression.cs40
-rwxr-xr-xmcs/class/System/System.CodeDom/CodeLiteralNamespace.cs48
-rwxr-xr-xmcs/class/System/System.CodeDom/CodeLiteralStatement.cs36
-rwxr-xr-xmcs/class/System/System.CodeDom/CodeMemberEvent.cs50
-rwxr-xr-xmcs/class/System/System.CodeDom/CodeMemberField.cs49
-rwxr-xr-xmcs/class/System/System.CodeDom/CodeMemberMethod.cs73
-rwxr-xr-xmcs/class/System/System.CodeDom/CodeMemberProperty.cs108
-rwxr-xr-xmcs/class/System/System.CodeDom/CodeMethodInvokeExpression.cs68
-rwxr-xr-xmcs/class/System/System.CodeDom/CodeMethodInvokeStatement.cs84
-rwxr-xr-xmcs/class/System/System.CodeDom/CodeMethodReturnStatement.cs12
-rwxr-xr-xmcs/class/System/System.CodeDom/CodeNamespace.cs92
-rwxr-xr-xmcs/class/System/System.CodeDom/CodeNamespaceImport.cs36
-rwxr-xr-xmcs/class/System/System.CodeDom/CodeNamespaceImportCollection.cs165
-rwxr-xr-xmcs/class/System/System.CodeDom/CodeObject.cs12
-rwxr-xr-xmcs/class/System/System.CodeDom/CodeObjectCreateExpression.cs54
-rwxr-xr-xmcs/class/System/System.CodeDom/CodeParameterDeclarationExpression.cs68
-rwxr-xr-xmcs/class/System/System.CodeDom/CodeParameterDeclarationExpressionCollection.cs165
-rwxr-xr-xmcs/class/System/System.CodeDom/CodePrimitiveExpression.cs33
-rwxr-xr-xmcs/class/System/System.CodeDom/CodePropertyReferenceExpression.cs59
-rwxr-xr-xmcs/class/System/System.CodeDom/CodeStatement.cs12
-rwxr-xr-xmcs/class/System/System.CodeDom/CodeStatementCollection.cs165
-rwxr-xr-xmcs/class/System/System.CodeDom/CodeThisReferenceExpression.cs16
-rwxr-xr-xmcs/class/System/System.CodeDom/CodeThrowExceptionStatement.cs31
-rwxr-xr-xmcs/class/System/System.CodeDom/CodeTryCatchFinallyStatement.cs70
-rwxr-xr-xmcs/class/System/System.CodeDom/CodeTypeDeclaration.cs11
-rwxr-xr-xmcs/class/System/System.CodeDom/CodeTypeMember.cs21
-rwxr-xr-xmcs/class/System/System.CodeDom/CodeTypeOfExpression.cs32
-rwxr-xr-xmcs/class/System/System.CodeDom/CodeTypeReferenceExpression.cs32
-rwxr-xr-xmcs/class/System/System.CodeDom/CodeVariableDeclarationStatement.cs62
-rwxr-xr-xmcs/class/System/System.CodeDom/FieldDirection.cs14
-rwxr-xr-xmcs/class/System/System.CodeDom/MemberAttributes.cs29
-rwxr-xr-xmcs/class/System/System.CodeDom/common.src65
-rwxr-xr-xmcs/class/System/System.CodeDom/unix.src0
-rwxr-xr-xmcs/class/System/System.CodeDom/windows.src0
-rw-r--r--mcs/class/System/System.Collections.Specialized/BitVector32.cs67
-rwxr-xr-xmcs/class/System/System.Collections.Specialized/ChangeLog19
-rw-r--r--mcs/class/System/System.Collections.Specialized/ListDictionary.cs432
-rw-r--r--mcs/class/System/System.Collections.Specialized/NameValueCollection.cs362
-rwxr-xr-xmcs/class/System/System.Collections.Specialized/StringCollection.cs292
-rw-r--r--mcs/class/System/System.Collections.Specialized/StringDictionary.cs97
-rw-r--r--mcs/class/System/System.Collections.Specialized/StringEnumerator.cs36
-rwxr-xr-xmcs/class/System/System.Collections.Specialized/common.src5
-rwxr-xr-xmcs/class/System/System.Collections.Specialized/unix.src0
-rwxr-xr-xmcs/class/System/System.Collections.Specialized/windows.src0
-rw-r--r--mcs/class/System/System.ComponentModel/ChangeLog13
-rw-r--r--mcs/class/System/System.ComponentModel/Component.cs122
-rw-r--r--mcs/class/System/System.ComponentModel/ComponentCollection.cs20
-rw-r--r--mcs/class/System/System.ComponentModel/Container.cs153
-rw-r--r--mcs/class/System/System.ComponentModel/EventHandlerList.cs64
-rw-r--r--mcs/class/System/System.ComponentModel/IComponent.cs20
-rw-r--r--mcs/class/System/System.ComponentModel/IContainer.cs24
-rw-r--r--mcs/class/System/System.ComponentModel/ISite.cs21
-rw-r--r--mcs/class/System/System.ComponentModel/common.src7
-rw-r--r--mcs/class/System/System.ComponentModel/unix.src0
-rw-r--r--mcs/class/System/System.ComponentModel/windows.src0
-rw-r--r--mcs/class/System/System.Configuration/ConfigurationException.cs179
-rw-r--r--mcs/class/System/System.Configuration/ConfigurationSettings.cs60
-rw-r--r--mcs/class/System/System.Configuration/IConfigurationSectionHandler.cs30
-rw-r--r--mcs/class/System/System.Configuration/IgnoreSectionHandler.cs45
-rw-r--r--mcs/class/System/System.Configuration/NameValueSectionHandler.cs70
-rw-r--r--mcs/class/System/System.Configuration/common.src5
-rw-r--r--mcs/class/System/System.Configuration/unix.src0
-rw-r--r--mcs/class/System/System.Configuration/windows.src0
-rw-r--r--mcs/class/System/System.Net.Sockets/AddressFamily.cs46
-rw-r--r--mcs/class/System/System.Net.Sockets/LingerOption.cs62
-rw-r--r--mcs/class/System/System.Net.Sockets/MulticastOption.cs61
-rw-r--r--mcs/class/System/System.Net.Sockets/NetworkStream.cs17
-rw-r--r--mcs/class/System/System.Net.Sockets/ProtocolFamily.cs46
-rw-r--r--mcs/class/System/System.Net.Sockets/ProtocolType.cs30
-rw-r--r--mcs/class/System/System.Net.Sockets/SelectMode.cs18
-rw-r--r--mcs/class/System/System.Net.Sockets/Socket.cs21
-rw-r--r--mcs/class/System/System.Net.Sockets/SocketException.cs103
-rw-r--r--mcs/class/System/System.Net.Sockets/SocketFlags.cs21
-rw-r--r--mcs/class/System/System.Net.Sockets/SocketOptionLevel.cs19
-rw-r--r--mcs/class/System/System.Net.Sockets/SocketOptionName.cs54
-rw-r--r--mcs/class/System/System.Net.Sockets/SocketShutdown.cs18
-rw-r--r--mcs/class/System/System.Net.Sockets/SocketType.cs21
-rw-r--r--mcs/class/System/System.Net.Sockets/common.src10
-rw-r--r--mcs/class/System/System.Net.Sockets/unix.src0
-rw-r--r--mcs/class/System/System.Net.Sockets/windows.src0
-rwxr-xr-xmcs/class/System/System.Net/AuthenticationManager.cs21
-rwxr-xr-xmcs/class/System/System.Net/Authorization.cs2
-rw-r--r--mcs/class/System/System.Net/ChangeLog13
-rwxr-xr-xmcs/class/System/System.Net/EndPoint.cs7
-rwxr-xr-xmcs/class/System/System.Net/IAuthenticationModule.cs4
-rwxr-xr-xmcs/class/System/System.Net/ICredentialLookup.cs4
-rwxr-xr-xmcs/class/System/System.Net/IPAdress.cs40
-rwxr-xr-xmcs/class/System/System.Net/IPEndPoint.cs21
-rwxr-xr-xmcs/class/System/System.Net/common.src5
-rwxr-xr-xmcs/class/System/System.Net/unix.src0
-rwxr-xr-xmcs/class/System/System.Net/windows.src0
-rwxr-xr-xmcs/class/System/System/Uri.cs315
-rwxr-xr-xmcs/class/System/System/UriFormatException.cs33
-rwxr-xr-xmcs/class/System/System/UriHostNameType.cs21
-rwxr-xr-xmcs/class/System/System/UriPartial.cs19
-rwxr-xr-xmcs/class/System/System/common.src4
-rwxr-xr-xmcs/class/System/System/unix.src0
-rwxr-xr-xmcs/class/System/System/windows.src0
-rw-r--r--mcs/class/System/Test/NameValueCollectionTest.cs178
-rw-r--r--mcs/class/System/Test/StringCollectionTest.cs152
-rw-r--r--mcs/class/System/makefile16
-rw-r--r--mcs/class/corlib/.cvsignore3
-rw-r--r--mcs/class/corlib/System.Collections/ArrayList.cs462
-rw-r--r--mcs/class/corlib/System.Collections/BitArray.cs501
-rw-r--r--mcs/class/corlib/System.Collections/CaseInsensitiveComparer.cs82
-rw-r--r--mcs/class/corlib/System.Collections/CaseInsensitiveHashCodeProvider.cs96
-rw-r--r--mcs/class/corlib/System.Collections/ChangeLog93
-rw-r--r--mcs/class/corlib/System.Collections/CollectionBase.cs131
-rw-r--r--mcs/class/corlib/System.Collections/Comparer.cs65
-rw-r--r--mcs/class/corlib/System.Collections/Hashtable.cs985
-rw-r--r--mcs/class/corlib/System.Collections/HashtableTest.cs156
-rw-r--r--mcs/class/corlib/System.Collections/ICollection.cs24
-rw-r--r--mcs/class/corlib/System.Collections/IComparer.cs19
-rw-r--r--mcs/class/corlib/System.Collections/IDictionary.cs40
-rw-r--r--mcs/class/corlib/System.Collections/IDictionaryEnumerator.cs20
-rw-r--r--mcs/class/corlib/System.Collections/IEnumerable.cs18
-rw-r--r--mcs/class/corlib/System.Collections/IEnumerator.cs22
-rw-r--r--mcs/class/corlib/System.Collections/IHashCodeProvider.cs18
-rw-r--r--mcs/class/corlib/System.Collections/IList.cs40
-rw-r--r--mcs/class/corlib/System.Collections/Queue.cs325
-rw-r--r--mcs/class/corlib/System.Collections/ReadOnlyCollectionBase.cs44
-rw-r--r--mcs/class/corlib/System.Collections/SortedList.cs864
-rw-r--r--mcs/class/corlib/System.Collections/Stack.cs315
-rwxr-xr-xmcs/class/corlib/System.Collections/common.src15
-rwxr-xr-xmcs/class/corlib/System.Collections/unix.src0
-rwxr-xr-xmcs/class/corlib/System.Collections/windows.src0
-rw-r--r--mcs/class/corlib/System.Configuration.Assemblies/AssemblyHash.cs70
-rw-r--r--mcs/class/corlib/System.Configuration.Assemblies/AssemblyHashAlgorithm.cs22
-rw-r--r--mcs/class/corlib/System.Configuration.Assemblies/AssemblyVersionCompatibility.cs23
-rw-r--r--mcs/class/corlib/System.Configuration.Assemblies/ChangeLog6
-rw-r--r--mcs/class/corlib/System.Configuration.Assemblies/common.src3
-rw-r--r--mcs/class/corlib/System.Configuration.Assemblies/unix.src0
-rw-r--r--mcs/class/corlib/System.Configuration.Assemblies/windows.src0
-rw-r--r--mcs/class/corlib/System.Diagnostics/BooleanSwitch.cs48
-rw-r--r--mcs/class/corlib/System.Diagnostics/ChangeLog3
-rw-r--r--mcs/class/corlib/System.Diagnostics/ConditionalAttribute.cs28
-rw-r--r--mcs/class/corlib/System.Diagnostics/DebuggableAttribute.cs28
-rw-r--r--mcs/class/corlib/System.Diagnostics/Switch.cs93
-rw-r--r--mcs/class/corlib/System.Diagnostics/TraceLevel.cs15
-rw-r--r--mcs/class/corlib/System.Diagnostics/TraceSwitch.cs97
-rw-r--r--mcs/class/corlib/System.Diagnostics/common.src6
-rw-r--r--mcs/class/corlib/System.Diagnostics/unix.src0
-rw-r--r--mcs/class/corlib/System.Diagnostics/windows.src0
-rw-r--r--mcs/class/corlib/System.Globalization/Calendar.cs58
-rw-r--r--mcs/class/corlib/System.Globalization/ChangeLog12
-rw-r--r--mcs/class/corlib/System.Globalization/DateTimeStyles.cs27
-rw-r--r--mcs/class/corlib/System.Globalization/NumberFormatInfo.cs691
-rw-r--r--mcs/class/corlib/System.Globalization/NumberStyles.cs45
-rw-r--r--mcs/class/corlib/System.Globalization/UnicodeCategory.cs44
-rwxr-xr-xmcs/class/corlib/System.Globalization/common.src3
-rwxr-xr-xmcs/class/corlib/System.Globalization/unix.src0
-rwxr-xr-xmcs/class/corlib/System.Globalization/windows.src0
-rw-r--r--mcs/class/corlib/System.IO/ChangeLog18
-rw-r--r--mcs/class/corlib/System.IO/Directory.cs173
-rw-r--r--mcs/class/corlib/System.IO/DirectoryInfo.cs128
-rw-r--r--mcs/class/corlib/System.IO/FileAccess.cs22
-rw-r--r--mcs/class/corlib/System.IO/FileAttributes.cs33
-rw-r--r--mcs/class/corlib/System.IO/FileInfo.cs142
-rw-r--r--mcs/class/corlib/System.IO/FileMode.cs25
-rw-r--r--mcs/class/corlib/System.IO/FileShare.cs23
-rw-r--r--mcs/class/corlib/System.IO/FileStream.cs242
-rw-r--r--mcs/class/corlib/System.IO/FileSystemInfo.cs135
-rw-r--r--mcs/class/corlib/System.IO/MemoryStream.cs403
-rw-r--r--mcs/class/corlib/System.IO/Path.cs270
-rw-r--r--mcs/class/corlib/System.IO/SeekOrigin.cs22
-rwxr-xr-xmcs/class/corlib/System.IO/Stream.cs203
-rw-r--r--mcs/class/corlib/System.IO/StringReader.cs130
-rw-r--r--mcs/class/corlib/System.IO/StringWriter.cs81
-rw-r--r--mcs/class/corlib/System.IO/TextReader.cs64
-rw-r--r--mcs/class/corlib/System.IO/TextWriter.cs104
-rw-r--r--mcs/class/corlib/System.IO/common.src11
-rwxr-xr-xmcs/class/corlib/System.IO/unix.src0
-rwxr-xr-xmcs/class/corlib/System.IO/windows.src0
-rw-r--r--mcs/class/corlib/System.Reflection/BindingFlags.cs36
-rw-r--r--mcs/class/corlib/System.Reflection/ChangeLog3
-rw-r--r--mcs/class/corlib/System.Reflection/DefaultMemberAttribute.cs26
-rw-r--r--mcs/class/corlib/System.Reflection/common.src2
-rw-r--r--mcs/class/corlib/System.Reflection/unix.src0
-rw-r--r--mcs/class/corlib/System.Reflection/windows.src0
-rw-r--r--mcs/class/corlib/System.Runtime.CompilerServices/ChangeLog3
-rw-r--r--mcs/class/corlib/System.Runtime.CompilerServices/MethodCodeType.cs23
-rw-r--r--mcs/class/corlib/System.Runtime.CompilerServices/MethodImplOptions.cs26
-rw-r--r--mcs/class/corlib/System.Runtime.CompilerServices/common.src1
-rw-r--r--mcs/class/corlib/System.Runtime.CompilerServices/unix.src0
-rw-r--r--mcs/class/corlib/System.Runtime.CompilerServices/windows.src0
-rw-r--r--mcs/class/corlib/System.Runtime.InteropServices/CallingConvention.cs24
-rw-r--r--mcs/class/corlib/System.Runtime.InteropServices/ChangeLog7
-rw-r--r--mcs/class/corlib/System.Runtime.InteropServices/CharSet.cs23
-rw-r--r--mcs/class/corlib/System.Runtime.InteropServices/GCHandleType.cs21
-rw-r--r--mcs/class/corlib/System.Runtime.InteropServices/LayoutKind.cs22
-rw-r--r--mcs/class/corlib/System.Runtime.InteropServices/OutAttribute.cs25
-rw-r--r--mcs/class/corlib/System.Runtime.InteropServices/common.src5
-rw-r--r--mcs/class/corlib/System.Runtime.InteropServices/unix.src0
-rw-r--r--mcs/class/corlib/System.Runtime.InteropServices/windows.src0
-rw-r--r--mcs/class/corlib/System.Runtime.Remoting/ObjRef.cs65
-rw-r--r--mcs/class/corlib/System.Runtime.Serialization/ChangeLog9
-rw-r--r--mcs/class/corlib/System.Runtime.Serialization/IFormatterConverter.cs32
-rw-r--r--mcs/class/corlib/System.Runtime.Serialization/IObjectReference.cs16
-rw-r--r--mcs/class/corlib/System.Runtime.Serialization/ISerializable.cs15
-rw-r--r--mcs/class/corlib/System.Runtime.Serialization/SerializationInfo.cs49
-rw-r--r--mcs/class/corlib/System.Runtime.Serialization/StreamingContext.cs59
-rw-r--r--mcs/class/corlib/System.Runtime.Serialization/StreamingContextStates.cs23
-rw-r--r--mcs/class/corlib/System.Runtime.Serialization/common.src3
-rw-r--r--mcs/class/corlib/System.Runtime.Serialization/mono.src1
-rw-r--r--mcs/class/corlib/System.Runtime.Serialization/unix.src0
-rw-r--r--mcs/class/corlib/System.Runtime.Serialization/windows.src0
-rw-r--r--mcs/class/corlib/System.Security.Cryptography.Test/ChangeLog8
-rw-r--r--mcs/class/corlib/System.Security.Cryptography.Test/MD5Test.cs83
-rw-r--r--mcs/class/corlib/System.Security.Cryptography.Test/SHA1Test.cs82
-rw-r--r--mcs/class/corlib/System.Security.Cryptography.Test/SHA256Test.cs82
-rw-r--r--mcs/class/corlib/System.Security.Cryptography.Test/SHA384Test.cs82
-rw-r--r--mcs/class/corlib/System.Security.Cryptography.Test/SHA512Test.cs82
-rw-r--r--mcs/class/corlib/System.Security.Cryptography.Test/ToBase64TransformTest.cs230
-rw-r--r--mcs/class/corlib/System.Security.Cryptography/ChangeLog31
-rw-r--r--mcs/class/corlib/System.Security.Cryptography/CipherMode.cs24
-rw-r--r--mcs/class/corlib/System.Security.Cryptography/CryptoStreamMode.cs20
-rw-r--r--mcs/class/corlib/System.Security.Cryptography/DES.cs585
-rw-r--r--mcs/class/corlib/System.Security.Cryptography/DESCryptoServiceProvider.cs248
-rw-r--r--mcs/class/corlib/System.Security.Cryptography/FromBase64Transform.cs264
-rw-r--r--mcs/class/corlib/System.Security.Cryptography/HashAlgorithm.cs153
-rw-r--r--mcs/class/corlib/System.Security.Cryptography/ICryptoTransform.cs49
-rw-r--r--mcs/class/corlib/System.Security.Cryptography/KeySizes.cs61
-rw-r--r--mcs/class/corlib/System.Security.Cryptography/MD5.cs43
-rw-r--r--mcs/class/corlib/System.Security.Cryptography/MD5CryptoServiceProvider.cs482
-rw-r--r--mcs/class/corlib/System.Security.Cryptography/PaddingMode.cs21
-rw-r--r--mcs/class/corlib/System.Security.Cryptography/SHA1.cs43
-rw-r--r--mcs/class/corlib/System.Security.Cryptography/SHA1CryptoServiceProvider.cs455
-rw-r--r--mcs/class/corlib/System.Security.Cryptography/SHA256.cs44
-rw-r--r--mcs/class/corlib/System.Security.Cryptography/SHA256Managed.cs290
-rw-r--r--mcs/class/corlib/System.Security.Cryptography/SHA384.cs44
-rw-r--r--mcs/class/corlib/System.Security.Cryptography/SHA512.cs44
-rw-r--r--mcs/class/corlib/System.Security.Cryptography/ToBase64Transform.cs233
-rw-r--r--mcs/class/corlib/System.Security.Cryptography/common.src15
-rw-r--r--mcs/class/corlib/System.Security.Cryptography/unix.src0
-rw-r--r--mcs/class/corlib/System.Security.Cryptography/windows.src0
-rw-r--r--mcs/class/corlib/System.Security.Permissions/ChangeLog3
-rw-r--r--mcs/class/corlib/System.Security.Permissions/EnvironmentPermissionAccess.cs23
-rw-r--r--mcs/class/corlib/System.Security.Permissions/FileIOPermissionAccess.cs25
-rw-r--r--mcs/class/corlib/System.Security.Permissions/ReflectionPermissionFlag.cs24
-rw-r--r--mcs/class/corlib/System.Security.Permissions/common.src3
-rw-r--r--mcs/class/corlib/System.Security.Permissions/unix.src0
-rw-r--r--mcs/class/corlib/System.Security.Permissions/windows.src0
-rwxr-xr-xmcs/class/corlib/System.Text/ASCIIEncoding.cs40
-rwxr-xr-xmcs/class/corlib/System.Text/ChangeLog31
-rwxr-xr-xmcs/class/corlib/System.Text/Encoding.cs263
-rw-r--r--mcs/class/corlib/System.Text/StringBuilder.cs564
-rwxr-xr-xmcs/class/corlib/System.Text/UTF7Encoding.cs40
-rwxr-xr-xmcs/class/corlib/System.Text/UTF8Encoding.cs40
-rwxr-xr-xmcs/class/corlib/System.Text/UnicodeEncoding.cs46
-rwxr-xr-xmcs/class/corlib/System.Text/common.src6
-rwxr-xr-xmcs/class/corlib/System.Text/unix.src0
-rwxr-xr-xmcs/class/corlib/System.Text/windows.src0
-rw-r--r--mcs/class/corlib/System.Threading/ChangeLog3
-rw-r--r--mcs/class/corlib/System.Threading/ThreadPriority.cs24
-rw-r--r--mcs/class/corlib/System.Threading/ThreadState.cs25
-rw-r--r--mcs/class/corlib/System.Threading/common.src2
-rw-r--r--mcs/class/corlib/System.Threading/unix.src0
-rw-r--r--mcs/class/corlib/System.Threading/windows.src0
-rw-r--r--mcs/class/corlib/System/ApplicationException.cs29
-rw-r--r--mcs/class/corlib/System/ArgumentException.cs50
-rw-r--r--mcs/class/corlib/System/ArgumentNullException.cs29
-rw-r--r--mcs/class/corlib/System/ArgumentOutOfRangeException.cs44
-rw-r--r--mcs/class/corlib/System/ArithmeticException.cs29
-rw-r--r--mcs/class/corlib/System/Array.cs510
-rw-r--r--mcs/class/corlib/System/ArrayTypeMismatchException.cs29
-rw-r--r--mcs/class/corlib/System/Attribute.cs284
-rw-r--r--mcs/class/corlib/System/AttributeTargets.cs33
-rw-r--r--mcs/class/corlib/System/Boolean.cs177
-rw-r--r--mcs/class/corlib/System/Byte.cs92
-rwxr-xr-xmcs/class/corlib/System/CLSCompliantAttribute.cs33
-rw-r--r--mcs/class/corlib/System/ChangeLog350
-rw-r--r--mcs/class/corlib/System/Char.cs339
-rwxr-xr-xmcs/class/corlib/System/ContextStaticAttribute.cs24
-rw-r--r--mcs/class/corlib/System/Convert.cs1630
-rw-r--r--mcs/class/corlib/System/DateTime.cs726
-rw-r--r--mcs/class/corlib/System/Delegate.cs96
-rw-r--r--mcs/class/corlib/System/DivideByZeroException.cs29
-rw-r--r--mcs/class/corlib/System/Double.cs116
-rw-r--r--mcs/class/corlib/System/DuplicateWaitObjectException.cs29
-rw-r--r--mcs/class/corlib/System/Enum.cs16
-rw-r--r--mcs/class/corlib/System/Environment.cs291
-rw-r--r--mcs/class/corlib/System/EventArgs.cs25
-rw-r--r--mcs/class/corlib/System/EventHandler.cs16
-rw-r--r--mcs/class/corlib/System/Exception.cs137
-rw-r--r--mcs/class/corlib/System/ExecutionEngineException.cs29
-rwxr-xr-xmcs/class/corlib/System/FlagsAttribute.cs26
-rw-r--r--mcs/class/corlib/System/FormatException.cs29
-rw-r--r--mcs/class/corlib/System/ICloneable.cs15
-rw-r--r--mcs/class/corlib/System/IComparable.cs15
-rw-r--r--mcs/class/corlib/System/IConvertible.cs54
-rw-r--r--mcs/class/corlib/System/ICustomFormatter.cs15
-rw-r--r--mcs/class/corlib/System/IDisposable.cs17
-rw-r--r--mcs/class/corlib/System/IFormatProvider.cs15
-rw-r--r--mcs/class/corlib/System/IFormattable.cs15
-rw-r--r--mcs/class/corlib/System/IServiceProvider.cs17
-rw-r--r--mcs/class/corlib/System/IndexOutOfRangeException.cs29
-rw-r--r--mcs/class/corlib/System/Int16.cs92
-rw-r--r--mcs/class/corlib/System/Int32.cs90
-rw-r--r--mcs/class/corlib/System/Int64.cs96
-rw-r--r--mcs/class/corlib/System/IntPtr.cs129
-rw-r--r--mcs/class/corlib/System/InvalidCastException.cs29
-rw-r--r--mcs/class/corlib/System/InvalidOperationException.cs29
-rw-r--r--mcs/class/corlib/System/InvalidProgramException.cs29
-rw-r--r--mcs/class/corlib/System/MarshalByRefObject.cs31
-rw-r--r--mcs/class/corlib/System/Math.cs311
-rw-r--r--mcs/class/corlib/System/MulticastDelegate.cs52
-rw-r--r--mcs/class/corlib/System/MulticastNotSupportedException.cs29
-rw-r--r--mcs/class/corlib/System/NotFiniteNumberException.cs49
-rw-r--r--mcs/class/corlib/System/NotSupportedException.cs29
-rw-r--r--mcs/class/corlib/System/NullReferenceException.cs29
-rw-r--r--mcs/class/corlib/System/Object.cs111
-rw-r--r--mcs/class/corlib/System/OperatingSystem.cs104
-rw-r--r--mcs/class/corlib/System/OutOfMemoryException.cs29
-rw-r--r--mcs/class/corlib/System/OverflowException.cs29
-rw-r--r--mcs/class/corlib/System/ParamArrayAttribute.cs18
-rw-r--r--mcs/class/corlib/System/PlatformID.cs26
-rw-r--r--mcs/class/corlib/System/Random.cs70
-rw-r--r--mcs/class/corlib/System/RankException.cs29
-rw-r--r--mcs/class/corlib/System/RuntimeTypeHandle.cs31
-rw-r--r--mcs/class/corlib/System/SByte.cs92
-rw-r--r--mcs/class/corlib/System/Single.cs116
-rw-r--r--mcs/class/corlib/System/StackOverflowException.cs29
-rw-r--r--mcs/class/corlib/System/String.cs1622
-rw-r--r--mcs/class/corlib/System/SystemException.cs29
-rw-r--r--mcs/class/corlib/System/TODO22
-rw-r--r--mcs/class/corlib/System/TimeSpan.cs540
-rw-r--r--mcs/class/corlib/System/Type.cs27
-rw-r--r--mcs/class/corlib/System/TypeCode.cs32
-rw-r--r--mcs/class/corlib/System/TypeInitializationException.cs30
-rw-r--r--mcs/class/corlib/System/UInt16.cs89
-rw-r--r--mcs/class/corlib/System/UInt32.cs96
-rw-r--r--mcs/class/corlib/System/UInt64.cs96
-rw-r--r--mcs/class/corlib/System/Unix.cs80
-rw-r--r--mcs/class/corlib/System/ValueType.cs66
-rw-r--r--mcs/class/corlib/System/Version.cs195
-rw-r--r--mcs/class/corlib/System/Void.cs14
-rw-r--r--mcs/class/corlib/System/Windows.cs101
-rwxr-xr-xmcs/class/corlib/System/common.src73
-rw-r--r--mcs/class/corlib/System/mono.src10
-rwxr-xr-xmcs/class/corlib/System/unix.src1
-rwxr-xr-xmcs/class/corlib/System/windows.src1
-rw-r--r--mcs/class/corlib/Test/BitArrayTest.cs272
-rw-r--r--mcs/class/corlib/Test/CaseInsensitiveComparerTest.cs62
-rw-r--r--mcs/class/corlib/Test/CaseInsensitiveHashCodeProviderTest.cs68
-rw-r--r--mcs/class/corlib/Test/CollectionBaseTest.cs231
-rw-r--r--mcs/class/corlib/Test/ComparerTest.cs72
-rw-r--r--mcs/class/corlib/Test/HashtableTest.cs202
-rw-r--r--mcs/class/corlib/Test/MemoryStreamTest.cs128
-rw-r--r--mcs/class/corlib/Test/PathTest.cs138
-rw-r--r--mcs/class/corlib/Test/QueueTest.cs176
-rw-r--r--mcs/class/corlib/Test/RandomTest.cs68
-rw-r--r--mcs/class/corlib/Test/ReadOnlyCollectionBaseTest.cs47
-rw-r--r--mcs/class/corlib/Test/StackTest.cs275
-rw-r--r--mcs/class/corlib/Test/StringBuilderTest.cs107
-rw-r--r--mcs/class/corlib/Test/StringReaderTest.cs83
-rw-r--r--mcs/class/corlib/Test/StringWriterTest.cs45
-rw-r--r--mcs/class/corlib/Unix/Wrapper.cs209
-rw-r--r--mcs/class/corlib/Unix/common.src1
-rw-r--r--mcs/class/corlib/Unix/mono.src0
-rw-r--r--mcs/class/corlib/Unix/windows.src0
-rw-r--r--mcs/class/corlib/makefile38
-rw-r--r--mcs/class/makefile15
-rw-r--r--mcs/class/notes/BitVecto32.txt6
-rwxr-xr-xmcs/docs/order.txt5
-rw-r--r--mcs/errors/cs0146.cs7
-rw-r--r--mcs/errors/cs0246.cs4
-rw-r--r--mcs/errors/cs0509.cs8
-rw-r--r--mcs/errors/cs0527-2.cs8
-rw-r--r--mcs/errors/cs0527.cs7
-rw-r--r--mcs/errors/cs0529.cs7
-rwxr-xr-xmcs/errors/errors.txt6
-rwxr-xr-xmcs/jay/.cvsignore2
-rw-r--r--mcs/jay/ACKNOWLEDGEMENTS25
-rwxr-xr-xmcs/jay/ChangeLog9
-rw-r--r--mcs/jay/NEW_FEATURES46
-rw-r--r--mcs/jay/NOTES9
-rw-r--r--mcs/jay/README10
-rw-r--r--mcs/jay/README.jay55
-rw-r--r--mcs/jay/closure.c295
-rw-r--r--mcs/jay/defs.h308
-rw-r--r--mcs/jay/depend11
-rw-r--r--mcs/jay/error.c335
-rw-r--r--mcs/jay/jay.1120
-rw-r--r--mcs/jay/lalr.c678
-rw-r--r--mcs/jay/lr0.c637
-rw-r--r--mcs/jay/main.c341
-rw-r--r--mcs/jay/makefile14
-rw-r--r--mcs/jay/mkpar.c395
-rw-r--r--mcs/jay/output.c1173
-rw-r--r--mcs/jay/reader.c1627
-rw-r--r--mcs/jay/skeleton268
-rw-r--r--mcs/jay/skeleton.cs351
-rw-r--r--mcs/jay/symtab.c158
-rw-r--r--mcs/jay/verbose.c366
-rw-r--r--mcs/jay/warshall.c122
-rwxr-xr-xmcs/makefile13
-rw-r--r--mcs/mcs/.cvsignore4
-rwxr-xr-xmcs/mcs/ChangeLog285
-rw-r--r--mcs/mcs/TODO75
-rwxr-xr-xmcs/mcs/class.cs751
-rwxr-xr-xmcs/mcs/codegen.cs58
-rwxr-xr-xmcs/mcs/compiler.csproj216
-rwxr-xr-xmcs/mcs/compiler.csproj.user43
-rwxr-xr-xmcs/mcs/compiler.sln21
-rwxr-xr-xmcs/mcs/constant.cs68
-rwxr-xr-xmcs/mcs/cs-parser.cs5531
-rwxr-xr-xmcs/mcs/cs-parser.jay286
-rwxr-xr-xmcs/mcs/cs-tokenizer.cs68
-rwxr-xr-xmcs/mcs/decl.cs17
-rwxr-xr-xmcs/mcs/driver.cs161
-rwxr-xr-xmcs/mcs/enum.cs15
-rwxr-xr-xmcs/mcs/errors.cs2
-rwxr-xr-xmcs/mcs/expression.cs100
-rwxr-xr-xmcs/mcs/gen-il.cs2
-rwxr-xr-xmcs/mcs/gen-treedump.cs95
-rwxr-xr-xmcs/mcs/interface.cs450
-rwxr-xr-xmcs/mcs/makefile48
-rwxr-xr-xmcs/mcs/modifiers.cs40
-rwxr-xr-xmcs/mcs/namespace.cs19
-rwxr-xr-xmcs/mcs/parameter.cs176
-rwxr-xr-xmcs/mcs/parameterCollection.cs6
-rwxr-xr-xmcs/mcs/parser.cs1
-rw-r--r--mcs/mcs/report.cs97
-rwxr-xr-xmcs/mcs/rootcontext.cs619
-rwxr-xr-xmcs/mcs/statement.cs174
-rwxr-xr-xmcs/mcs/statementCollection.cs6
-rwxr-xr-xmcs/mcs/tree.cs167
-rwxr-xr-xmcs/mcs/type.cs14
-rwxr-xr-xmcs/mcs/typemanager.cs94
-rwxr-xr-xmcs/tests/c1.cs7
-rwxr-xr-xmcs/tests/c2.cs2
-rwxr-xr-xmcs/tests/co1.cs4
-rwxr-xr-xmcs/tests/cs1.cs5
-rw-r--r--mcs/tests/i-recursive.cs5
-rwxr-xr-xmcs/tests/i-three.cs11
-rw-r--r--mcs/tests/i-undefined.cs2
-rwxr-xr-xmcs/tests/i1.cs2
-rwxr-xr-xmcs/tests/i2.cs5
-rwxr-xr-xmcs/tests/i3.cs5
-rwxr-xr-xmcs/tests/i4.cs8
-rwxr-xr-xmcs/tests/i5.cs8
-rwxr-xr-xmcs/tests/i6.cs4
-rwxr-xr-xmcs/tests/ix1.cs3
-rwxr-xr-xmcs/tests/ix2.cs5
-rwxr-xr-xmcs/tests/n1.cs11
-rwxr-xr-xmcs/tests/n2.cs4
-rwxr-xr-xmcs/tests/s1.cs7
-rw-r--r--mcs/tools/makefile8
-rw-r--r--mcs/tools/verifier.cs1079
-rw-r--r--mono/.cvsignore2
-rw-r--r--mono/Makefile.am2
-rw-r--r--mono/arch/ChangeLog10
-rw-r--r--mono/arch/x86/test.c211
-rw-r--r--mono/arch/x86/x86-codegen.h1238
-rw-r--r--mono/cil/.cvsignore3
-rw-r--r--mono/cil/ChangeLog19
-rw-r--r--mono/cil/Makefile.am11
-rw-r--r--mono/cil/TODO3
-rw-r--r--mono/cil/cil-opcodes.xml297
-rw-r--r--mono/cil/make-opcode-def.xsl100
-rw-r--r--mono/cil/make-opcodes-def.pl80
-rw-r--r--mono/dis/.cvsignore5
-rw-r--r--mono/dis/ChangeLog180
-rw-r--r--mono/dis/Makefile.am20
-rw-r--r--mono/dis/TODO5
-rw-r--r--mono/dis/dis-cil.c298
-rw-r--r--mono/dis/dis-cil.h1
-rw-r--r--mono/dis/dump.c471
-rw-r--r--mono/dis/dump.h18
-rw-r--r--mono/dis/get.c1194
-rw-r--r--mono/dis/get.h54
-rw-r--r--mono/dis/main.c763
-rw-r--r--mono/dis/meta.h7
-rw-r--r--mono/dis/monodis.141
-rw-r--r--mono/dis/push-pop.h265
-rw-r--r--mono/dis/util.c85
-rw-r--r--mono/dis/util.h11
-rw-r--r--mono/interpreter/.cvsignore6
-rw-r--r--mono/interpreter/ChangeLog208
-rw-r--r--mono/interpreter/Makefile.am20
-rw-r--r--mono/interpreter/hacks.h114
-rw-r--r--mono/interpreter/icall.c287
-rw-r--r--mono/interpreter/interp.c2383
-rw-r--r--mono/interpreter/interp.h57
-rw-r--r--mono/metadata/.cvsignore5
-rw-r--r--mono/metadata/ChangeLog252
-rw-r--r--mono/metadata/Makefile.am38
-rw-r--r--mono/metadata/TODO5
-rw-r--r--mono/metadata/assembly.c380
-rw-r--r--mono/metadata/assembly.h19
-rw-r--r--mono/metadata/blob.h51
-rw-r--r--mono/metadata/cil-coff.h150
-rw-r--r--mono/metadata/class.c504
-rw-r--r--mono/metadata/class.h76
-rw-r--r--mono/metadata/endian.h13
-rw-r--r--mono/metadata/icall.c287
-rw-r--r--mono/metadata/image.c532
-rw-r--r--mono/metadata/image.h106
-rw-r--r--mono/metadata/loader.c452
-rw-r--r--mono/metadata/loader.h58
-rw-r--r--mono/metadata/metadata.c1781
-rw-r--r--mono/metadata/metadata.h267
-rw-r--r--mono/metadata/metaparse.h16
-rw-r--r--mono/metadata/mono-endian.h13
-rw-r--r--mono/metadata/object.c222
-rw-r--r--mono/metadata/object.h52
-rw-r--r--mono/metadata/pedump.c136
-rw-r--r--mono/metadata/private.h78
-rw-r--r--mono/metadata/rawbuffer.c4
-rw-r--r--mono/metadata/rawbuffer.h4
-rw-r--r--mono/metadata/row-indexes.h385
-rw-r--r--mono/metadata/tabledefs.h186
-rw-r--r--mono/metadata/tokentype.h39
-rw-r--r--mono/metadata/typedef.c54
-rw-r--r--mono/metadata/types.h17
-rw-r--r--mono/tests/.cvsignore3
-rw-r--r--mono/tests/Makefile.am46
-rwxr-xr-xmono/tests/array.cs134
-rwxr-xr-xmono/tests/exception.cs34
-rwxr-xr-xmono/tests/exception2.cs22
-rwxr-xr-xmono/tests/exception3.cs40
-rwxr-xr-xmono/tests/fib.cs15
-rwxr-xr-xmono/tests/nested-loops.cs31
-rwxr-xr-xmono/tests/obj.cs30
-rwxr-xr-xmono/tests/outparm.cs21
-rwxr-xr-xmono/tests/pinvoke.cs21
-rwxr-xr-xmono/tests/random.cs21
-rwxr-xr-xmono/tests/stream.cs15
-rwxr-xr-xmono/tests/struct.cs21
-rwxr-xr-xmono/tests/switch.cs25
-rwxr-xr-xmono/tests/test-driver33
-rwxr-xr-xmono/tests/test-ops.cs32
-rw-r--r--mono/wrapper/.cvsignore8
-rw-r--r--mono/wrapper/Makefile.am22
-rwxr-xr-xmono/wrapper/genwrapper.pl458
-rw-r--r--mono/wrapper/wrapper.c68
-rw-r--r--notes/cil13
-rw-r--r--runtime/.cvsignore3
-rw-r--r--runtime/Makefile.am18
-rwxr-xr-xstatus/.cvsignore6
-rwxr-xr-xstatus/ByMaintainer.cs52
-rwxr-xr-xstatus/ByMaintainer.xsl34
-rwxr-xr-xstatus/ByNamespace.cs55
-rwxr-xr-xstatus/ByNamespace.xsl38
-rwxr-xr-xstatus/ChangeLog21
-rwxr-xr-xstatus/class.xml2224
-rwxr-xr-xstatus/commands56
-rwxr-xr-xstatus/compare-assembly.cs164
-rwxr-xr-xstatus/index.src17
-rwxr-xr-xstatus/maintainer.src1
-rwxr-xr-xstatus/maintainers.xml35
-rwxr-xr-xstatus/make_web.pl21
-rw-r--r--status/makefile35
-rwxr-xr-xstatus/mono-stats289
-rwxr-xr-xstatus/namespace.src1
-rw-r--r--web/.cvsignore3
-rw-r--r--web/Makefile.am19
-rw-r--r--web/README17
-rw-r--r--web/c-sharp188
-rw-r--r--web/ccvs112
-rw-r--r--web/class-library183
-rw-r--r--web/class-status16
-rw-r--r--web/contact16
-rw-r--r--web/contributing105
-rw-r--r--web/devel-faq190
-rw-r--r--web/documentation50
-rw-r--r--web/download177
-rw-r--r--web/faq722
-rw-r--r--web/gcc-frontend9
-rw-r--r--web/ideas119
-rw-r--r--web/index103
-rw-r--r--web/passport276
-rw-r--r--web/pending14
-rw-r--r--web/rationale173
-rw-r--r--web/release-notes/mono-0.346
-rw-r--r--web/release-notes/mono-0.443
-rw-r--r--web/resources121
-rw-r--r--web/resources-pending30
-rw-r--r--web/roadmap12
-rw-r--r--web/runtime144
-rw-r--r--web/status38
-rw-r--r--web/team2
-rw-r--r--web/testing21
-rw-r--r--web/thanks6
-rw-r--r--web/todo1
-rw-r--r--web/tools67
-rw-r--r--web/web/.cvsignore2
-rw-r--r--web/web/commands17
-rw-r--r--web/web/htmlify26
-rw-r--r--web/web/images/bgsquares.gifbin0 -> 4963 bytes
-rw-r--r--web/web/images/bgsquares.pngbin0 -> 4644 bytes
-rw-r--r--web/web/images/bgsquares.xcf.gzbin0 -> 2775 bytes
-rw-r--r--web/web/images/mono.gifbin0 -> 3079 bytes
-rw-r--r--web/web/images/mono.pngbin0 -> 4496 bytes
-rw-r--r--web/web/images/pixel.gifbin0 -> 49 bytes
-rw-r--r--web/web/images/pixel.pngbin0 -> 157 bytes
-rw-r--r--web/web/makefile39
-rwxr-xr-xweb/web/process.pl73
-rw-r--r--web/web/template.html.in78
831 files changed, 90164 insertions, 7076 deletions
diff --git a/.cvsignore b/.cvsignore
new file mode 100644
index 00000000000..ccea8b4dfbe
--- /dev/null
+++ b/.cvsignore
@@ -0,0 +1,17 @@
+aclocal.m4
+config.cache
+config.guess
+config.h
+config.h.in
+config.log
+config.status
+config.sub
+configure
+libtool
+ltmain.sh
+ltconfig
+Makefile
+Makefile.in
+mono-*.tar.gz
+stamp-h
+stamp-h.in
diff --git a/AUTHORS b/AUTHORS
index 25e66d4943c..f74a2408991 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -1 +1,2 @@
Miguel de Icaza (miguel@ximian.com)
+Paolo Molaro (lupus@ximian.com)
diff --git a/ChangeLog b/ChangeLog
index 1a76f446632..207298d93a0 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,111 @@
+
+Tue Aug 21 18:54:06 CEST 2001 Paolo Molaro <lupus@ximian.com>
+
+ * mono/tests/exceptions*: enhanced and added more tests for
+ exceptions.
+
+2001-08-20 Miguel de Icaza <miguel@ximian.com>
+
+ * mono/Makefile.am (SUBDIRS): Remove `test' from here to allow us
+ to pass make distcheck
+
+ * mono/wrapper/Makefile.am (EXTRA_DIST): Include genwrapper.pl
+
+ * configure.in, Makefile.am, runtime/Makefile.am (dist-hook,
+ install-data-hook): Added mechanism to distribute and install the
+ dll files.
+
+2001-08-20 Dietmar Maurer <dietmar@ximian.com>
+
+ * mono/tests/stream.cs: new tests for the Stream class
+
+ * configure.in: I really need LIBTOOL for libmonowrapper.so, so I
+ added it again.
+
+2001-08-16 Alex Graveley <alex@ximian.com>
+
+ * configure.in: Replace AM_PROG_LIBTOOL with AC_PROG_RANLIB. This
+ removes libtool dependency on all of Mono.
+
+2001-08-10 Dietmar Maurer <dietmar@ximian.com>
+
+ * mono/tests/array.cs: more array tests
+
+2001-08-09 Dietmar Maurer <dietmar@ximian.com>
+
+ * mono/tests/array.cs: more array tests
+
+2001-08-06 Dietmar Maurer <dietmar@ximian.com>
+
+ * mono/tests/pinvoke.cs: we can now print strings ;-)
+
+ * mono/tests/array.cs: new test for arrays
+
+2001-08-02 Alex Graveley <alex@ximian.com>
+
+ * libffi/*: Import libffi CVS version, with minor changes to make it
+ compile.
+
+ * mono/interpreter/Makefile.am: Link against
+ ../../libffi/.libs/libffi.a.
+
+ * Makefile.am: Add libffi
+
+ * autogen.sh: Replace with adapted gnome autogen.sh
+
+ * configure.in: Add AC_CONFIG_SUBDIRS(libffi).
+
+2001-08-02 Dietmar Maurer <dietmar@ximian.com>
+
+ * mono/tests/pinvoke.cs: impl.
+
+Wed Aug 1 22:34:52 CEST 2001 Paolo Molaro <lupus@ximian.com>
+
+ * configure.in, mono/tests: added some tests for the interpreter.
+
+2001-07-15 Sean MacIsaac <macisaac@ximian.com>
+
+ * doc/download: added instructions for cygwin
+
+ * doc/c-sharp: removed bit about compiling
+
+ * status/compare-assembly.cs: basedir should be there if
+ parameters are provided.
+
+ * status/makefile: made targets to dump info.
+
+2001-07-15 Joe Shaw <joe@ximian.com>
+
+ * configure.in: Don't create doc/Makefile as there's nothing there
+ to make.
+
+ * Makefile.am: Don't build the doc directory because there's no
+ Makefile.am there.
+
+ * autogen.sh: Call aclocal with the $ACLOCAL_FLAGS env var.
+
+2001-07-15 Miguel de Icaza <miguel@ximian.com>
+
+ * doc/class-library (A): Updated FAQ with question on error 1595.
+
+2001-07-14 Miguel de Icaza <miguel@ximian.com>
+
+ * doc/index:
+
+Wed Jul 11 00:36:36 CEST 2001 Paolo Molaro <lupus@ximian.com>
+
+ * status/*: scripts and data to create statistics about the
+ class library status.
+
+2001-07-09 Alex Graveley <alex@ximian.com>
+
+ * doc/makefile (clean): Add clean target.
+ * doc/web/makefile (clean): Ditto.
+
+2001-07-09 Alex Graveley <alex@ximian.com>
+
+ * doc/makefile (all-docs): Fix typo.
+
2001-05-30 Miguel de Icaza <miguel@ximian.com>
* NEWS:
diff --git a/Makefile.am b/Makefile.am
index 7a0d4a47da8..f8d5ea84f6c 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1 +1 @@
-SUBDIRS = mono
+SUBDIRS = libffi mono doc runtime
diff --git a/NEWS b/NEWS
index 37b3c8595b0..0c85e588710 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,13 @@
+2001-07-12 Miguel de Icaza <miguel@ximian.com>
+
+ New XSLT file from Sergey Chaban for CIL opcodes
+
+ Paolo got the beginning of an interpreter in.
+
+ Further work on the dissasembler.
+
+ Fix various parts of the metadata library
+
2001-05-30 Miguel de Icaza <miguel@ximian.com>
Project started
diff --git a/README b/README
index 27f2ef4c497..95b3e27ff8b 100644
--- a/README
+++ b/README
@@ -1,3 +1,42 @@
-This is MonoNet.
+This is Mono.
+
+A directory roadmap:
+
+ doc/
+ Contains documentation and the web site contents.
+
+ mono/
+ The core of the executable.
+
+ metadata/
+ The library to deal with executables and libraries for
+ .NET
+
+ dis/
+ CIL executable Disassembler
+
+ cli/
+ Common code for the JIT and the interpreter.
+
+ cil/
+ Common Intermediate Representation, XML
+ definition of the CIL bytecodes.
+
+ interp/
+ Interpreter for CLI executables.
+
+* Using Mono
+
+ Once you have installed the software, you can run a few programs:
+
+ monodis program.exe
+
+ That will dump the bytecodes for program.exe. Monodis support
+ a number of options that dumps various metadata tables
+ (chapter 23 of the Partition III).
+
+ You can try the interpreter like this:
+
+ mono-int program.exe
+
-Ximian's portable implementation of .NET
diff --git a/autogen.sh b/autogen.sh
new file mode 100755
index 00000000000..bfd7bef3037
--- /dev/null
+++ b/autogen.sh
@@ -0,0 +1,141 @@
+#!/bin/sh
+# Run this to generate all the initial makefiles, etc.
+# Ripped off from GNOME macros version
+
+DIE=0
+
+srcdir=`dirname $0`
+test -z "$srcdir" && srcdir=.
+
+if [ -n "$MONO_PATH" ]; then
+ ACLOCAL_FLAGS="-I $MONO_PATH/share/aclocal $ACLOCAL_FLAGS"
+ PATH="$MONO_PATH/bin:$PATH"
+ export PATH
+fi
+
+(autoconf --version) < /dev/null > /dev/null 2>&1 || {
+ echo
+ echo "**Error**: You must have \`autoconf' installed to compile Mono."
+ echo "Download the appropriate package for your distribution,"
+ echo "or get the source tarball at ftp://ftp.gnu.org/pub/gnu/"
+ DIE=1
+}
+
+(grep "^AM_PROG_LIBTOOL" $srcdir/configure.in >/dev/null) && {
+ (libtool --version) < /dev/null > /dev/null 2>&1 || {
+ echo
+ echo "**Error**: You must have \`libtool' installed to compile Mono."
+ echo "Get ftp://ftp.gnu.org/pub/gnu/libtool-1.2d.tar.gz"
+ echo "(or a newer version if it is available)"
+ DIE=1
+ }
+}
+
+grep "^AM_GNU_GETTEXT" $srcdir/configure.in >/dev/null && {
+ grep "sed.*POTFILES" $srcdir/configure.in >/dev/null || \
+ (gettext --version) < /dev/null > /dev/null 2>&1 || {
+ echo
+ echo "**Error**: You must have \`gettext' installed to compile Mono."
+ echo "Get ftp://alpha.gnu.org/gnu/gettext-0.10.35.tar.gz"
+ echo "(or a newer version if it is available)"
+ DIE=1
+ }
+}
+
+(automake --version) < /dev/null > /dev/null 2>&1 || {
+ echo
+ echo "**Error**: You must have \`automake' installed to compile Mono."
+ echo "Get ftp://ftp.gnu.org/pub/gnu/automake-1.3.tar.gz"
+ echo "(or a newer version if it is available)"
+ DIE=1
+ NO_AUTOMAKE=yes
+}
+
+
+# if no automake, don't bother testing for aclocal
+test -n "$NO_AUTOMAKE" || (aclocal --version) < /dev/null > /dev/null 2>&1 || {
+ echo
+ echo "**Error**: Missing \`aclocal'. The version of \`automake'"
+ echo "installed doesn't appear recent enough."
+ echo "Get ftp://ftp.gnu.org/pub/gnu/automake-1.3.tar.gz"
+ echo "(or a newer version if it is available)"
+ DIE=1
+}
+
+if test "$DIE" -eq 1; then
+ exit 1
+fi
+
+if test -z "$*"; then
+ echo "**Warning**: I am going to run \`configure' with no arguments."
+ echo "If you wish to pass any to it, please specify them on the"
+ echo \`$0\'" command line."
+ echo
+fi
+
+case $CC in
+xlc )
+ am_opt=--include-deps;;
+esac
+
+for coin in `find $srcdir -name configure.in -print`
+do
+ dr=`dirname $coin`
+ if test -f $dr/NO-AUTO-GEN; then
+ echo skipping $dr -- flagged as no auto-gen
+ else
+ echo processing $dr
+ macrodirs=`sed -n -e 's,AM_ACLOCAL_INCLUDE(\(.*\)),\1,gp' < $coin`
+ ( cd $dr
+ macrosdir=`find . -name macros -print`
+ if grep "^AM_GNU_GETTEXT" configure.in >/dev/null; then
+ if grep "sed.*POTFILES" configure.in >/dev/null; then
+ : do nothing -- we still have an old unmodified configure.in
+ else
+ echo "Creating $dr/aclocal.m4 ..."
+ test -r $dr/aclocal.m4 || touch $dr/aclocal.m4
+ echo "Running gettextize... Ignore non-fatal messages."
+ echo "no" | gettextize --force --copy
+ echo "Making $dr/aclocal.m4 writable ..."
+ test -r $dr/aclocal.m4 && chmod u+w $dr/aclocal.m4
+ fi
+ fi
+ if grep "^AM_PROG_LIBTOOL" configure.in >/dev/null; then
+ if test -z "$NO_LIBTOOLIZE" ; then
+ echo "Running libtoolize..."
+ libtoolize --force --copy
+ fi
+ fi
+ echo "Running aclocal $aclocalinclude ..."
+ aclocal $aclocalinclude || {
+ echo
+ echo "**Error**: aclocal failed. This may mean that you have not"
+ echo "installed all of the packages you need, or you may need to"
+ echo "set ACLOCAL_FLAGS to include \"-I \$prefix/share/aclocal\""
+ echo "for the prefix where you installed the packages whose"
+ echo "macros were not found"
+ exit 1
+ }
+
+ if grep "^AM_CONFIG_HEADER" configure.in >/dev/null; then
+ echo "Running autoheader..."
+ autoheader || { echo "**Error**: autoheader failed."; exit 1; }
+ fi
+ echo "Running automake --gnu $am_opt ..."
+ automake --add-missing --gnu $am_opt ||
+ { echo "**Error**: automake failed."; exit 1; }
+ echo "Running autoconf ..."
+ autoconf || { echo "**Error**: autoconf failed."; exit 1; }
+ ) || exit 1
+ fi
+done
+
+conf_flags="--enable-maintainer-mode --enable-compile-warnings" #--enable-iso-c
+
+if test x$NOCONFIGURE = x; then
+ echo Running $srcdir/configure $conf_flags "$@" ...
+ $srcdir/configure $conf_flags "$@" \
+ && echo Now type \`make\' to compile $PKG_NAME || exit 1
+else
+ echo Skipping configure process.
+fi
diff --git a/config.h.in b/config.h.in
index f871c4edf55..906b29ad55b 100644
--- a/config.h.in
+++ b/config.h.in
@@ -1,8 +1,11 @@
-/* config.h.in. Generated automatically from configure.in by autoheader. */
+/* config.h.in. Generated automatically from configure.in by autoheader 2.13. */
/* Define if you have the ANSI C header files. */
#undef STDC_HEADERS
+/* Define if you have the <dlfcn.h> header file. */
+#undef HAVE_DLFCN_H
+
/* Name of package */
#undef PACKAGE
diff --git a/configure.in b/configure.in
index b146447d4d7..505a7f950a2 100644
--- a/configure.in
+++ b/configure.in
@@ -1,6 +1,6 @@
AC_INIT(README)
AM_CONFIG_HEADER(config.h)
-AM_INIT_AUTOMAKE(mononet, 0.1)
+AM_INIT_AUTOMAKE(mono, 0.6)
AM_MAINTAINER_MODE
AC_PROG_CC
@@ -23,6 +23,14 @@ GLIB_LIBS=`glib-config --libs glib`
AC_SUBST(GLIB_CFLAGS)
AC_SUBST(GLIB_LIBS)
+GMODULE_CFLAGS=`glib-config --cflags gmodule`
+GMODULE_LIBS=`glib-config --libs gmodule`
+
+AC_SUBST(GMODULE_CFLAGS)
+AC_SUBST(GMODULE_LIBS)
+
+AC_CONFIG_SUBDIRS(libffi)
+
CFLAGS='-g -Wall -Wunused -Wmissing-prototypes -Wmissing-declarations'
AC_SUBST(CFLAGS)
@@ -31,4 +39,10 @@ Makefile
mono/Makefile
mono/metadata/Makefile
mono/dis/Makefile
-]) \ No newline at end of file
+mono/cil/Makefile
+mono/interpreter/Makefile
+mono/tests/Makefile
+mono/wrapper/Makefile
+runtime/Makefile
+doc/Makefile
+])
diff --git a/doc/.cvsignore b/doc/.cvsignore
new file mode 100644
index 00000000000..79a25824094
--- /dev/null
+++ b/doc/.cvsignore
@@ -0,0 +1,3 @@
+Makefile.in
+Makefile
+all-docs
diff --git a/doc/Makefile.am b/doc/Makefile.am
new file mode 100644
index 00000000000..dd2e2d85e2c
--- /dev/null
+++ b/doc/Makefile.am
@@ -0,0 +1,19 @@
+WEB_FILES= \
+ c-sharp class-library contact contributing documentation download \
+ faq gcc-frontend ideas index passport rationale resources \
+ roadmap runtime status team testing thanks tools
+
+OTHERS= pending resources-pending todo
+
+EXTRA_DIST = $(WEB_FILES) README $(OTHERS)
+
+all-docs: $(WEB_FILES)
+ cat rationale roadmap c-sharp tools class-library \
+ runtime documentation download faq contributing \
+ resources status > all-docs
+
+webit:
+ (cd web; make && make push)
+
+push-notes:
+ scp release-notes/mono* www@www:/web/cvsmodules/mono/archive
diff --git a/doc/README b/doc/README
new file mode 100644
index 00000000000..333d133943f
--- /dev/null
+++ b/doc/README
@@ -0,0 +1,17 @@
+To edit the website appearance:
+
+cd doc/web
+edit template.html.in
+make
+
+To edit website content:
+
+cd doc (this directory)
+edit files carefully
+cd web
+make
+
+To publish changes:
+
+cd web
+make push
diff --git a/doc/c-sharp b/doc/c-sharp
new file mode 100644
index 00000000000..0c5be542f02
--- /dev/null
+++ b/doc/c-sharp
@@ -0,0 +1,188 @@
+* MCS: The Ximian C# compiler
+
+ MCS began as an experiment to learn the features of C# by
+ writing a large C# program. MCS is currently able to parse C#
+ programs and create an internal tree representation of the
+ program. MCS can parse itself.
+
+ MCS now does type checking at the class, interface and struct
+ levels and can resolve the class hierarchy and as of last week
+ can generate interface code.
+
+ Work is progressing quickly on various fronts in the C#
+ compiler. Recently I started using the System.Reflection API
+ to load system type definitions and avoid self-population of
+ types in the compiler and dropped my internal Type
+ representation in favor of using the CLI's System.Type.
+
+** Phases of the compiler
+
+ The compiler has a number of phases:
+
+ <ul>
+ * Lexical analyzer: hand-coded lexical analyzer that
+ provides tokens to the parser.
+
+ * The Parser: the parser is implemented using Jay (A
+ Berkeley Yacc port to Java, that I ported to C#).
+ The parser does minimal work and syntax checking,
+ and only constructs a parsed tree.
+
+ Each language element gets its own class. The code
+ convention is to use an uppercase name for the
+ language element. So a C# class and its associated
+ information is kept in a "Class" class, a "struct"
+ in a "Struct" class and so on. Statements derive
+ from the "Statement" class, and Expressions from the
+ Expr class.
+
+ * Parent class resolution: before the actual code
+ generation, we need to resolve the parents and
+ interfaces for interface, classe and struct
+ definitions.
+
+ * Semantic analysis: since C# can not resolve in a
+ top-down pass what identifiers actually mean, we
+ have to postpone this decision until the above steps
+ are finished.
+
+ * Code generation: The compiler recently started generating IL
+ executables that contain interfaces. Work is
+ progressing in other areas.
+
+ The code generation is done through the System.Reflection.Emit API.
+ </ul>
+
+<a name="tasks">
+** Current pending tasks
+
+ Simple tasks:
+
+ <ul>
+ * Array declarations are currently being ignored,
+
+ * PInvoke declarations are not supported.
+
+ * Pre-processing is not supported.
+
+ * Attribute declarations and passing currently ignored.
+
+ * Compiler does not pass around line/col information from tokenizer for error reporting.
+
+ * Jay does not work correctly with `error'
+ productions, making parser errors hard to point. It
+ would be best to port the Bison-To-Java compiler to
+ become Bison-to-C# compiler (bjepson@oreilly.com
+ might have more information)
+ </ul>
+
+ Interesting and Fun hacks to the compiler:
+
+ <ul>
+ * Finishing the JB port from Java to C#. If you are
+ interested in working on this, please contact Brian
+ Jepson (bjepson at oreilly d-o-t com).
+
+ More on JB at: <a href="http://www.cs.colorado.edu/~dennis/software/jb.html">
+ http://www.cs.colorado.edu/~dennis/software/jb.html</a>
+
+ JB will allow us to move from the Berkeley Yacc
+ based Jay to a Bison-based compiler (better error
+ reporting and recovery).
+
+ * Semantic Analysis: Return path coverage and
+ initialization before use coverage are two great
+ features of C# that help reduce the number of bugs
+ in applications. It is one interesting hack.
+
+ * Enum resolutions: it is another fun hack, as enums can be defined
+ in terms of themselves (<tt>enum X { a = b + 1, b = 5 }</tt>).
+
+ </ul>
+
+** Questions and Answers
+
+Q: Why not write a C# front-end for GCC?
+
+A: I wanted to learn about C#, and this was an exercise in this
+ task. The resulting compiler is highly object-oriented, which has
+ lead to a very nice, easy to follow and simple implementation of
+ the compiler.
+
+ I found that the design of this compiler is very similar to
+ Guavac's implementation.
+
+ Targeting the CIL/MSIL byte codes would require to re-architecting
+ GCC, as GCC is mostly designed to be used for register machines.
+
+ The GCC Java engine that generates Java byte codes cheats: it does
+ not use the GCC backend; it has a special backend just for Java, so
+ you can not really generate Java bytecodes from the other languages
+ supported by GCC.
+
+Q: If your C# compiler is written in C#, how do you plan on getting
+ this working on a non-Microsoft environment.
+
+ We will do this through an implementation of the CLI Virtual
+ Execution System for Unix (our JIT engine).
+
+Q: Do you use Bison?
+
+A: No, currently I am using Jay which is a port of Berkeley Yacc to
+ Java that I later ported to C#. This means that error recovery is
+ not as nice as I would like to, and for some reason error
+ productions are not being caught.
+
+ In the future I want to port one of the Bison/Java ports to C# for
+ the parser.
+
+Q: Should someone work on a GCC front-end to C#?
+
+A: I would love if someone does, and we would love to help anyone that
+ takes on that task, but we do not have the time or expertise to
+ build a C# compiler with the GCC engine. I find it a lot more fun
+ personally to work on C# on a C# compiler, which has an intrinsic
+ beauty.
+
+ We can provide help and assistance to anyone who would like to work
+ on this task.
+
+Q: Should someone make a GCC backend that will generate CIL images?
+
+A: I would love to see a backend to GCC that generates CIL images. It
+ would provide a ton of free compilers that would generate CIL
+ code. This is something that people would want to look into
+ anyways for Windows interoperation in the future.
+
+ Again, we would love to provide help and assistance to anyone
+ interested in working in such a project.
+
+Q: What about making a front-end to GCC that takes CIL images and
+ generates native code?
+
+A: I would love to see this, specially since GCC supports this same
+ feature for Java Byte Codes. You could use the metadata library
+ from Mono to read the byte codes (ie, this would be your
+ "front-end") and generate the trees that get passed to the
+ optimizer.
+
+ Ideally our implementation of the CLI will be available as a shared
+ library that could be linked with your application as its runtime
+ support.
+
+ Again, we would love to provide help and assistance to anyone
+ interested in working in such a project.
+
+Q: But would this work around the GPL in the GCC compiler and allow
+ people to work on non-free front-ends?
+
+A: People can already do this by targeting the JVM byte codes (there
+ are about 130 compilers for various languages that target the JVM).
+
+Q: Why are you writing a JIT engine instead of a front-end to GCC?
+
+A: The JIT engine and runtime engine will be able to execute CIL
+ executables generated on Windows.
+
+You might also want to look at the <a href="faq.html#gcc">GCC</a>
+section on the main FAQ
diff --git a/doc/ccvs b/doc/ccvs
new file mode 100644
index 00000000000..b67e8dc0c5b
--- /dev/null
+++ b/doc/ccvs
@@ -0,0 +1,112 @@
+* CVS Access
+
+ If you are an active Mono developer, you can get a CVS account
+ that hosts the Mono source code.
+
+ Send an e-mail to miguel with your public SSH key for this
+ purpose. Please specify if the key was generated with SSH1 or SSH2.
+
+ If you are using SSH2, please generate your key using:
+
+<pre>
+ ssh-keygen -t rsa
+</pre>
+
+ And mail me the id_rsa.pub file.
+
+ If you are using SSH1, run:
+<pre>
+ ssh-keygen
+</pre>
+
+ And mail me your identity.pub file.
+
+ You will need CVS and SSH. Windows users can get both by
+ installing Cygwin (<a
+ href="http://www.cygwin.com">http://www.cygwin.com</a>)
+
+ Unix users will probably have those tools installed already.
+
+** Checking out the sources
+
+ To check out the sources for the first time from the
+ repository, use this command:
+
+<pre>
+ export CVS_RSH=ssh
+ export CVSROOT=username@mono-cvs.ximian.com:/cvs/public
+ cvs -z3 co mcs mono
+</pre>
+
+** Updating your sources
+
+ Every day people will be making changes, to get your latest
+ updated sources, use:
+
+<pre>
+ cvs -z3 update -Pd mcs mono
+</pre>
+
+ Note: The '-z3' enables compression for the whole cvs action.
+ The '-Pd' makes the update operation (P)rune directories that
+ have been deleted and get new (d)irectories added to the
+ repository.
+
+** Making patches
+
+ Usually you will want to make a patch to contribute, and let
+ other people review it before commiting it. To obtain such a
+ "patch", you type:
+
+<pre>
+ cd directory-you-want-to-diff
+ cvs -z3 diff -u > file.diff
+ mail mono-list@ximian.com < file.diff
+</pre>
+
+** Commiting your work
+
+ Once you get approval to commit to the CVS, or if you are
+ commiting code that you are the maintainer of, you will want
+ to commit your code to CVS.
+
+ To do this, you have to "add" any new files that you created:
+
+<pre>
+ cvs add new-file.cs
+</pre>
+
+ And then commit your changes to the repository:
+
+<pre>
+ cvs commit file-1.cs file-2.cs
+</pre>
+
+** The Mailing List
+
+ To keep track of the various development and changes to the
+ CVS tree, you can subscribe to the mono-cvs-list@ximian.com.
+ To subscribe, send an email message to
+ mono-cvs-list-request@ximian.com and in the body of the
+ message put `subscribe'.
+
+ This will send you an email message every time a change is
+ made to the CVS repository, together with the information that
+ the author of the changes submitted.
+
+** Recommendations
+
+ Please do not commit code that would break the compile to the
+ CVS, because that normally wastes everybody's time.
+
+ Make sure that you add all the files before you do a commit.
+
+ Use ChangeLog entries so we can keep textual descriptions of
+ your work, and use the contents of your ChangeLog file as the
+ CVS commit message (ie, paste the contents of this into the
+ editor buffer).
+
+ If you are making changes to someone else's code, please make
+ sure you get in touch with the maintainer of that code before
+ applying patches. You want to avoid commiting conflicting
+ work to someone else's code.
diff --git a/doc/class-library b/doc/class-library
new file mode 100644
index 00000000000..2819ff8ba43
--- /dev/null
+++ b/doc/class-library
@@ -0,0 +1,183 @@
+* The Class Library
+
+ The Class Library should be compatible with Microsoft's .NET
+ implementation.
+
+ Please see the <a href="class-status.html">Class Status</a>
+ page for a status of who is working on which classes.
+
+ We will write as much code as possible in C#. We may need to
+ interface with code written in C to gain access to the
+ functionality of libraries like libart, Gtk+, and libc.
+
+** Contributing
+
+ We welcome contributions to the the Class Library. To get
+ started, check the status page for information about which
+ APIs are being worked on, and how to get in touch with
+ individual maintainers.
+
+ If you want to work on a class, first check the <a
+ href="download.html">Classes Distribution</a> to see if it is
+ not implemented yet, if not, check the <a
+ href="class-status.html">Class Status</a> to see if someone is
+ already working on it, and maybe contact them.
+
+ If nobody is working on it, mail <a
+ href="mailto:mono-list@ximian.com">mono-list@ximian.com</a>
+ with the class you want to implement and CC <a
+ href="mailto:miguel@ximian.com">miguel@ximian.com</a>.
+
+ You can also track live the activities of the Mono CVS module
+ by subscribing to the <a
+ href="http://mail.ximian.com/mailman/listinfo/mono-cvs-list">mono-cvs-list</a>
+
+
+
+** Layout
+
+ The Class Library resides in the `mcs' module in the directoy
+ `class'.
+
+ Each directory in the directory represents the assembly where
+ the code belongs to, and inside each directory we divide the
+ code based on the namespace they implement.
+
+ There are two cases when we should consider portability: when
+ we are dealing with a couple of classes only that differ from
+ system to system (Consider System.Net and System.IO for Win32
+ and Unix). In those cases we will just place the files for
+ example on <t>corlib/System/System.IO/Unix-Console.cs</t> and
+ <t>corlib/System/System.IO/Win32-Console.cs</t>.
+
+ For classes that might differ more (for example, the
+ implementation of Windows.Forms), we might have different
+ directories altogether: <t>System.Windows.Forms/Win32</t>,
+ <t>System.Windows.Forms/Gtk+</t> and
+ <t>System.Windows.Forms/Cocoa</t>.
+
+** Using existing components from GNOME.
+
+ Our current plan is to implement the GUI tools on top of
+ Gtk+. The only obstacle here is that applications from Windows
+ might expect to be able to pull the HWND property from the
+ widgets and use PInvoke to call Windows functions.
+
+** Class Library and Win32 dependencies.
+
+ There are a few spots where the Win32 foundation is exposed to
+ the class library (for example, the HDC and HWND properties in
+ the GDI+). Casual inspection suggests that these can be
+ safely mapped to Gdk's GC and GdkWindow pointers without
+ breaking anything.
+
+ The only drawback is that support for PInvoke of Win32 code
+ won't be available. An alternate solution would be to use
+ portions of Wine, or even to use Wine as our toolkit.
+
+*** Initial GDI+ and WinForms implementation
+
+ The initial implementation will use Gtk+ as the underlying
+ toolkit. Since GTK+ has already been ported to many windowing
+ systems other than X (including frame buffer, Win32, and BeOS)
+ its use should cover most applications for most users.
+
+*** Database access
+
+ We will implement ADO.NET functionality by reusing <a
+ href="http://www.gnome-db.org">GNOME-DB</a>. This is an ideal
+ choice, since GNOME-DB was implemented precisely to provide an
+ ADO-like system for GNOME.
+
+*** Component Integration
+
+ We will provide a new namespace to use GNOME specific features
+ as well as a namespace to host Bonobo interfaces and classes
+ in Mono.
+
+** Licensing
+
+ The class library will be licensed under the terms of the GNU
+ LGPL. Some people have pointed out that the plain LGPL is
+ troublesome for embedded use of the Mono class libraries. So
+ we are considering to use the GPL with a special exception
+ (like the <a
+ href="http://www.gnu.org/software/classpath/classpath.html">GNU
+ Classpath</a> project did.
+
+ The exception to the GPL would be:
+
+ <i>The library is distributed under the terms of the GNU General
+ Public License with the following exception:
+
+ If you link this library against your own program, then you do not
+ need to release the source code for that program. However, any
+ changes that you make to the library itself, or to any native
+ methods upon which the library relies, must be re-distributed in
+ accordance with the terms of the GPL.</i>
+
+ If you are going to contribute, please keep in mind that we
+ might require you to agree that Ximian might adjust the
+ license to enable the use of the class libraries on embedded
+ systems or to develop proprietary applications using Mono.
+
+ We suggest that you assign the copyright of your work to the
+ GNOME Foundation or the Free Software Foundation to simplify
+ defending the code in case it is used inappropiately.
+
+** Class Library testing
+
+ We need to write regression tests that will verify
+ the correctness of the class library, compiler, and JIT
+ engine.
+
+ Please write your regression tests using <a
+ href="http://nunit.sourceforge.net">NUnit</a>
+
+** Coding conventions
+
+ Please follow the conventions on the ECMA specification (On
+ the Annex Partition) for your coding your libraries.
+
+ Use 8 space tabs for writing your code (hopefully we can keep
+ this consistent). If you are modifying someone else's code, try
+ to keep the coding style similar.
+
+ For a rationale on 8 space tabs, read Linus Torvald's Coding
+ Style guidelines in the Linux kernel source for a rationale.
+
+*** Missing implementation bits
+
+ If you implement a class and you are missing implementation bits,
+ please put in the code the word "TODO" and a description of what
+ is missing to be implemented.
+
+*** Tagging buggy code
+
+ If there is a bug in your implementation tag the problem by using
+ the word "FIXME" in the code, together with a description of the
+ problem.
+
+ Do not use XXX or obscure descriptions, because otherwise people
+ will not be able to understand what you mean.
+
+*** Tagging Lame specs
+
+ Sometimes the specification will be lame (consider Version.ToString (fieldCount)
+ where there is no way of knowing how many fields are available, making the API
+ not only stupid, but leading to unreliable code).
+
+ In those cases, use the keyword "LAMESPEC".
+
+** FAQ
+
+Frequently asked questions about the class library:
+
+Q: I am writing a new class that overrides one of the system classes,
+ and I am getting a 1595 warning from the compiler. Should we use a
+ different namespace?
+
+A: There is a quick solution to the problem, you can pass the command
+ line argument /nowarn:1595 and this will effectively let you use
+ your implementation of the code, while overriding the ones from the
+ system assemblies. \ No newline at end of file
diff --git a/doc/class-status b/doc/class-status
new file mode 100644
index 00000000000..db8d360dbff
--- /dev/null
+++ b/doc/class-status
@@ -0,0 +1,16 @@
+* Status of the various pieces of the class library
+
+ You can browse the status of the class library and see who has
+ registered to work on what parts of the system. These list
+ work-in-progress components currently.
+
+ Browse the current <a href="class-status/index.html">status</a>.
+
+ You can also download the XML <a
+ href="class-status/maintainers.xml">maintainers</a> file that
+ contains the actual maintainers list.
+
+ You can also download the master <a
+ href="class-status/class.xml">Class Status XML</a> file.
+
+
diff --git a/doc/contact b/doc/contact
new file mode 100644
index 00000000000..a268f704731
--- /dev/null
+++ b/doc/contact
@@ -0,0 +1,16 @@
+* Contacting the Mono team.
+
+ You can contact the Mono Team by sending e-mail to `<a
+ href="mailto:mono-hackers@ximian.com">mono-hackers@ximian.com</a>'.
+
+ You can contact the general forum of discussion by sending
+ e-mail to <a href="mailto:mono-list@ximian.com">mono-list@ximian.com</a>
+
+ You can contact me (Miguel de Icaza) by sending e-mail to <a
+ href="mailto:miguel@ximian.com">miguel@ximian.com</a>. My web
+ page is <a
+ href="http://primates.ximian.com/~miguel">http://primates.ximian.com/~miguel"</a>
+
+ You can also <a
+ href="http://www.ximian.com/about/contact.php3">reach Ximian.</a>
+
diff --git a/doc/contributing b/doc/contributing
new file mode 100644
index 00000000000..d0e5925d8fa
--- /dev/null
+++ b/doc/contributing
@@ -0,0 +1,105 @@
+* Contributing to the Mono project
+
+ There are many ways in which you can help in the Mono project:
+
+ <ul>
+ * <b>Programmers:</b> You can work on a free
+ implementation of the <a
+ href="class-library.html">class libraries</a>, the
+ <a href="runtime.html">runtime engine</a>, <a
+ href="tools.html">the tools</a>, the <a
+ href="testing.html">testing framework</a>
+
+ * <b>Writers:</b> You can help us bywriting <a
+ href="documentation.html">documentation</a>.
+ </ul>
+
+ Those are just broad things that need to be worked on, but
+ something that would help tremendously would be to help with
+ small duties in the project that need to be addressed.
+
+** To start contributing
+
+ To start developing classes or to contribute to the compiler,
+ you only need Windows and the .NET Beta 2 SDK. Please notice
+ that you do not need Visual Studio (although you can use it if
+ you want).
+
+ You can get it <a href="http://msdn.microsoft.com/downloads/default.asp?url=/downloads/sample.asp?url=/msdn-files/027/000/976/msdncompositedoc.xml&frame=true">here</a>
+
+ Alternatively you can use the <a
+ href="#compile-service">compilation service</a> that was setup by
+ Derek.
+
+** Bug reporting
+
+ If you find bugs in Mono, please make sure you enter a bug
+ report so we can keep track of problems in Mono.
+
+ To enter bug reports go to <a href="http://bugzilla.ximian.com">
+ http://bugzilla.ximian.com</a> and enter bug reports against
+ your favorite component (Mono, Runtime, C# compiler).
+
+** Small tasks
+
+ A few smaller tasks are here, dropped in no particular order:
+ <ul>
+ * <b>MCS compilation process:</b> Currently MCS does
+ not build with a single `make' command. This should
+ be fixed (this being part of the `Joel Test' that
+ software has to pass).
+
+ * <b>Mono/doc and web site:</b> They need to be
+ packaged up in the official `distribution'
+ </ul>
+
+<a name="compile-service">
+* C# Compilation Service
+
+ If you are working on a class for the Mono project, but do not
+ have a C# compiler available or a Windows machine to run the
+ .NET SDK, you can use the compilation service that Derek
+ Holden setup in the following URL: <a
+ href="http://toilet.2y.net:8080/">http://toilet.2y.net:8080/</a>
+
+ The service will let you compile a source file and get back a
+ list of errors in the class file. You will not be able to run
+ the code, but at least you can get some code written that will
+ help us further down the line.
+
+ You can contact (and thank) Derek for this service by sending
+ him nice email at <a
+ href="mailto:derek@Draper.Com">derek@draper.com</a>
+
+* Books on C# and DotNet.
+
+ <ul>
+ * Dotnet Books (<a href="http://www.dotnetbooks.com">http://www.dotnetbooks.com</a>)
+
+ * Dotnet Resources (<a href="http://www.dotnetexperts.com/resources/">
+ http://www.dotnetexperts.com/resources</a>)
+
+ * O'Really C# Essentials (<a href="http://www.oreilly.com/catalog/csharpess/">
+ http://www.oreally.com/catalog/csharpess</a>)
+
+ * O'Really .NET Essentials (<a href="http://www.oreilly.com/catalog/dotnetfrmess/">
+ http://www.oreally.com/catalog/dotnetfrmess</a>)
+
+* Special note
+
+ If you have looked at Microsoft's implementation of .NET or
+ their shared source code, you may not be able to contribute
+ to Mono. Details will follow when we know more about this.
+
+ In general be careful when you are implementing free software
+ and you have access to proprietary code. We need to make sure
+ that we are not using someone else's copyrighted code
+ accidentally.
+
+ Please do not use the <b>ildasm</b> program to disassemble
+ proprietary code when you are planning to reimplement a class
+ for Mono. If you have done this, we might not be able to use
+ your code.
+
+ Please stick to published documentation for implementing any
+ classes.
diff --git a/doc/devel-faq b/doc/devel-faq
new file mode 100644
index 00000000000..9ca89285219
--- /dev/null
+++ b/doc/devel-faq
@@ -0,0 +1,190 @@
+* Developer FAQ
+
+** New classes
+
+Q: Should we write classes which are not part of the .NET or ECMA specs?
+
+A: Yes. The ECMA and .NET specifications are far from complete, and
+ to produce a complete platform we will need a number of other
+ classes and components.
+
+ Any new classes that are not part of .NET or ECMA should be
+ designed to be reusable on anyone's CLI implementation. So that
+ Windows developers can also use any new classes that we come up
+ with.
+
+ We have a few existing <a href="ideas.html">Ideas on missing
+ classes</a>
+
+** Language Compatibility
+
+Q: What is the magic that allow multiple languages to co-exist?
+
+A: From Fergus Henderson:
+
+<i><blockquote>
+There are different levels of interoperability.
+The ECMA spec defines different categories of
+CLS (Common Language Specification) conformance.
+There are also some useful categories that don't
+correspond to any of the levels defined in the ECMA spec.
+In increasing degree of difficulty, your language implementation
+can
+
+ <ul>
+ * (a) just generate IL
+
+ * (b) be a CLS "consumer", which means that it can read in
+ meta-data describing component interfaces,
+ and that it provides a way to declare variables of
+ CLS-complaint types and to call CLS-complaint methods.
+
+ * (c) be a CLS "extender", which means that it can in addition
+ derive from CLS-compliant classes
+ and implement CLS-compliant interfaces
+
+ * (d) be able to produce components with *any* CLS-compliant
+ component interface.
+ </ul>
+
+Supporting some of these may require extending your language. However,
+you can get quite a lot of interoperability by just putting appropriate
+functionality in your compiler, without extending your language.
+
+For some things, e.g. ASP.NET, your language implementation also needs to be
+able to
+
+ <ul>
+ * (e) consume CodeDom trees. CodeDom trees are an abstract
+ representation of programs in a form similar to a C# parse
+ tree, with embedded code snippets (unparsed strings).
+ Given a CodeDom tree, with the snippets in your language,
+ your language implementation needs to generate a (i) .NET
+ assembly and possibly also (ii) a source file in your language.
+
+ * (f) produce CodeDom trees. For some applications,
+ your language implementation also needs to be able to
+ round-trip from CodeDom -> your language -> CodeDom.
+ </ul>
+
+and for some things it needs to
+
+ <ul>
+ * (g) generate *verifiable* IL
+ </ul>
+
+So when you hear all the hype about how language XYZ is a
+".NET language", make sure you ask which of these different
+things are supported.
+
+[For the record, Mercury currently supports (a). We're working on
+(b) and (g), and on parts of (c) and (e). We're never going to do (f), I very
+strongly doubt we'll ever do (d), and for (c) we might only ever support
+implementing interfaces, not deriving from classes.]
+
+</blockquote></i>
+
+** PInvoke
+
+Q: What are the two major initiatives to implement PInvoke?
+
+A: Fergus Henderson answers:
+
+<i><blockquote>
+Many of the .NET APIs will need to be implemented using code that calls C/Unix
+APIs, such as stat(). The standard way of interfacing with native code from
+.NET code is to use "PInvoke". However, there is a difficulty: many of
+these APIs are defined in terms of types such as C's `long' or `size_t'
+or the Posix `struct stat' whose representation varies depending on the
+platform (architecture/OS/C compiler). There's no *portable* way of
+accessing those from .NET managed code.
+
+So, there are a couple of different approaches.
+One possibility is to access such routines by writing a wrapper, e.g. in C,
+that provides the same functionality without using types with a system-dependent
+representation. The wrapper can then be directly accessed from portable
+.NET code. The .NET code remains both source- and binary-portable;
+the wrapper code is source-portable, but needs to be compiled
+seperately for each target platform. The drawback of this approach is
+that you have to write a lot of cumbersome wrapper code.
+
+Another possibility is to extend the .NET VM with support for an
+additional custom attribute, e.g. "[PosixType]". The VM would then
+represent types tagged with this attribute in the same way that the
+underlying system represents those types. With this approach, no
+wrapper code would be needed. A drawback of this approach is that it
+pushes quite a bit of complexity into the VM; the VM would have to know
+the native representation of all types annotated with this attribute.
+Another drawback is that code using this extension might not work on
+different VMs.
+
+There have also been some other suggestions, but those are the two that
+I think are the best.
+</blockquote></i>
+
+Q: What is the problem implementing PInvoke?
+
+A: Again, from Fergus Henderson:
+
+<i><blockquote>
+There's no problem implementing PInvoke as specified in the ECMA
+specs and/or MS documentation. It's just that PInvoke by itself
+doesn't solve all of the problems; in particular it doesn't solve
+the problem of C types whose representation is different on different
+systems.
+</blockquote></i>
+
+** CVS use
+
+Q: Why do we keep ChangeLogs and make the CVS commit messages be the
+ same? One could be generated from the other
+
+A: There are a number of reasons for keeping ChangeLog files as well as
+ CVS commit files:
+
+ <ul>
+ * Offline programming: when people are traveling, CVS logs are
+ not available.
+
+ * Slow CVS access: Many people work over modem lines (very
+ typical for contributors in Europe, Asia, Latin America)
+ using CVS is slow and might not be available to you (cvs
+ server down, no anoncvs server available).
+
+ * ChangeLogs travel in a released tarball package, so it is
+ possible to study the rationale of changes even after a
+ project is long "released", or you only have the sources for
+ the code.
+
+ * ChangeLog are not metadata for each file, they are live
+ files that you can browse in the package that is being
+ distributed.
+ </ul>
+
+Making the CVS commit message be the same as the ChangeLog has other
+benefits:
+
+ <ul>
+ * You can track down with `cvs log' what things were changed,
+ and match those to meaningful reports on the intentions of
+ the commit.
+
+ * When reading the commits-list, you can get a glimpse of the
+ changes without having to diff out or cvs update your tree.
+
+ * You can read off-line the changes that are being made
+ (asyncrouns operation).
+ </ul>
+
+This mechanism works very well for GNOME and other projects.
+
+Q: Should I use any of the special RCS keywords like $Id: devel-faq,v 1.1 2001/07/31 21:13:05 miguel Exp $, $Author: miguel $,
+ $Date: 2001/07/31 21:13:05 $, or $Revision: 1.1 $?
+
+A: Please avoid using those in the source code in the CVS. They
+ are not really useful, and they cause a lot of conflicts when
+ people have separate CVS trees.
+
+ It was a nightmare with the Linux kernel when two people had their
+ private CVS trees and were submitting patches to the core.
+
diff --git a/doc/documentation b/doc/documentation
new file mode 100644
index 00000000000..166e0e8ccfe
--- /dev/null
+++ b/doc/documentation
@@ -0,0 +1,50 @@
+* Documentation
+
+ Although most of the concepts from Microsoft.NET can
+ be applied to the completed Mono platform, we do need to
+ have a complete set of free documentation written specifically
+ for Mono.
+
+ The documentation license we have chosen is the GNU Free
+ Documentation License (FDL), the standard for most documents
+ in the free software world.
+
+ We need documentation on a number of topics:
+
+ <ul>
+
+ * The development tools (compilers, assembler tools,
+ language reference, design time features).
+
+ * Frequently Asked Question compilations.
+
+ * HOWTO documents.
+
+ * The Class Libraries
+
+ * Tutorials on Mono and the specifics of running it.
+
+ * A guide to Mono as compared to the Microsoft.NET
+ Framework SDK
+
+ </ul>
+
+** Class Library documentation
+
+ When contributing to the Class Library effort, please use the
+ inline XML documentation tags to document your classes so we
+ can automatically generate the documentation from the class
+ libraries.
+
+ If you provide examples, please do not embed them into the
+ source code, as that will make the source code harder to read
+ and maintain. Instead, put examples for your code into a
+ subdirectory of the class libraries. Make your sample
+ code a full standalone application that people can compile.
+ Ideally the Mono documentation browser will let you edit, modify
+ and run the sample programs.
+
+
+
+
+
diff --git a/doc/download b/doc/download
new file mode 100644
index 00000000000..64daa7761fb
--- /dev/null
+++ b/doc/download
@@ -0,0 +1,177 @@
+* Software Availability
+
+ The Virtual Execution System is available in package `mono'.
+ Currently this contains a metadata library and the
+ disassembler. Please reffer to our <a
+ href="runtime.html">Runtime</a> description for more details
+ on this part of the project.
+
+ The code for the C# compiler as well as the language error
+ test suite and the class library are in the `mcs' package, we
+ will move this later into `mono' itself.
+
+ In order to make mcs and the class libraries you will need the
+ GNU make tools. These may be obtained for the Windows
+ environment from <a href="http://www.cygwin.com">cygwin.com</a>.
+
+ You will also need to get GLIB, from: <a
+href="ftp://ftp.gtk.org/pub/gtk/v1.2/glib-1.2.10.tar.gz">ftp://ftp.gtk.org/pub/gtk/v1.2/glib-1.2.10.tar.gz</a>
+
+<a name="sources">
+** Sources
+
+ We provide both <a href="packaged">packaged and tested</a>
+ tarballs (those are known to compile and pass `make
+ distcheck') as well as <a href="snapshots">daily snapshots</a> done
+ at 10pm Boston Time
+
+<a name="snapshots">
+*** Snapshots
+
+ The daily snapshots are available <a
+ href="http://www.go-mono.com/snapshots">here</a>. These
+ snapshots are done every day at 10pm EST (Boston Time).
+
+ They are not guaranteed to build, but most of the time they
+ should. They should give you a window to see what we are up to.
+
+ You might also want to track our development using the <a
+ href="http://mail.ximian.com/mailman/listinfo/mono-cvs-list">mono-cvs-list</a>
+ mailing list.
+
+<a name="packaged">
+*** Released and tested packages
+
+ <ul>
+ <a name="july-29">
+ <b>July 29, 2001</b>
+ <ul>
+ * <a href="archive/mono-0.5.tar.gz">mono-0.5.tar.gz</a>: Mono Runtime 0.5 release
+ * <a href="archive/mono-0.5">Release Notes</a>
+ </ul>
+
+ <a name="july-22">
+ <b>July 22, 2001</b>
+ <ul>
+ * <a href="archive/mcs-22-Jul-2001.tar.gz">mcs-22-Jul-2001.tar.gz</a>: CVS snapshot.
+ * <a href="archive/mcs-Jul-22-Jul-19-2001.tar.gz">Differences since 19</a>: CVS snapshot.
+ * <a href="archive/mcs-22">Release Notes</a>
+ </ul>
+
+ <a name="july-19">
+ <b>July 19th, 2001</b>
+ <ul>
+ * <a href="archive/mcs-19-Jul-2001.tar.gz">mcs-19-Jul-2001.tar.gz</a>: CVS snapshot.
+ * <a href="archive/mcs-Jul-17-Jul-19-2001.tar.gz">Differences since 17</a>: CVS snapshot.
+ * <a href="archive/mcs-19">Release Notes</a>
+ </ul>
+
+ <a name="july-17">
+ <b>July 17th, 2001</b>
+ <ul>
+ * <a href="archive/mcs-17-Jul-2001.tar.gz">mcs-17-Jul-2001.tar.gz</a>: CVS snapshot.
+ * <a href="archive/mcs-Jul-15-Jul-17-2001.tar.gz">Differences since 15</a>: CVS snapshot.
+ * <a href="archive/mcs-17">Release Notes</a>
+ </ul>
+
+ <a name="july-15">
+ <b>July 15th, 2001</b>
+ <ul>
+ * <a href="archive/mcs-15-Jul-2001.tar.gz">mcs-15-Jul-2001.tar.gz</a>: CVS snapshot.
+ * <a href="archive/mono-0.4.tar.gz">mono-0.4.tar.gz</a>: Packaged Source Code.
+ * <a href="archive/mono-0.4">Release Notes</a>
+ </ul>
+
+ <a name="july-14">
+ <b>July 14th, 2001</b>
+ <ul>
+ * <a href="archive/mcs-12-Jul-2001.tar.gz">mcs-12-Jul-2001.tar.gz</a>: CVS snapshot.
+ * <a href="archive/mono-0.3.tar.gz">mono-0.3.tar.gz</a>: Packaged Source Code.
+ </ul>
+
+ <a name="july-8">
+ <b>July 8th, 2001</b>
+
+ <ul>
+ * <a href="archive/mcs-08-Jul-2001.tar.gz">mcs-08-Jul-2001.tar.gz</a>: CVS Snapshot
+ * <a href="archive/mono-08-Jul-2001.tar.gz">mono-08-Jul-2001.tar.gz</a>: CVS Snapshot
+ </ul>
+ </ul>
+
+<a name="install">
+** Installing the software
+
+ To install and work on the compiler and the class libraries,
+ follow these instructions:
+
+ <ul>
+ * Install <a href="http://www.cygwin.com">CygWin</a> first.
+
+ * Untar the MCS distribution (see below for information).
+
+ * Go into the MCS directory and type `make windows'
+ </ul>
+
+ To compile the mono runtime on windows:
+
+ <ul>
+ * Install <a href="http://www.cygwin.com">CygWin</a> first.
+
+ * Once installed, in a terminal window or a cygwin
+ window (a shortcut should be on your desktop), untar the glib
+ distribution:
+
+<pre>
+tar xzvf glib-1.2.10.tar.gz
+</pre>
+
+ * Configure, compile and install glib, like this:
+
+<pre>
+./configure --prefix=/usr
+make
+make install
+</pre>
+
+ * Unpack the mono distribution:
+
+<pre>
+tar xzvf mono-XXX.tar.gz
+</pre>
+
+ * Configure, compile and install:
+
+<pre>
+./configure --prefix=//c/mono
+make
+make install
+</pre>
+ </ul>
+
+ To compile the mono runtime on Unix:
+
+ <ul>
+
+ * Download the mono distribution
+
+ * Unpack the mono distribution:
+
+<pre>
+tar xzvf mono-XXX.tar.gz
+</pre>
+
+ * Configure, compile and install:
+<pre>
+./configure
+make
+make install
+</pre>
+ </ul>
+
+** CVS
+
+ We are trying to figure out where to put our CVS repository.
+ We are debating between the GNOME CVS or SourceForge. Watch
+ this spot.
+
+
diff --git a/doc/faq b/doc/faq
new file mode 100644
index 00000000000..3bb7d839e14
--- /dev/null
+++ b/doc/faq
@@ -0,0 +1,722 @@
+** Basics
+
+Q: Is Mono the same as Microsoft's .NET initiative?
+
+A: It is not.
+
+ .NET is a company-wide initiative at Microsoft that
+ encompasses many different areas. The .NET development framework,
+ Passport, Biztalk, new server products, and anything that is
+ remotely connected to .NET gets the ".NET-stamping" treatment.
+ Some components of Microsoft's .NET initiative have been announced
+ and some others are in the works.
+
+ Mono is a project to implement several technologies developed by
+ Microsoft that have now been submitted to the ECMA Standards Body.
+
+Q: What technologies are included in Mono?
+
+A: Mono contains a number of components useful for building new
+ software:
+
+ <ul>
+ * A Common Language Infrastructure (CLI) virtual
+ machine that contains a class loader, Just-in-time
+ compiler, and a garbage collecting runtime.
+
+ * A class library that can work with any language
+ which works on the CLR.
+
+ * A compiler for the C# language. In the future we
+ might work on other compilers that target the Common
+ Language Runtime.
+
+ Windows has compilers that target the
+ virtual machine from
+ <a href="http://msdn.microsoft.com/net/thirdparty/default.asp#lang">a
+ number of languages:</a> Managed C++, Java Script,
+ Eiffel, Component Pascal, APL, Cobol, Oberon, Perl,
+ Python, Scheme, Smalltalk, Standard ML, Haskell,
+ Mercury and Oberon.
+ </ul>
+
+ The CLR and the Common Type System (CTS) enables applications and
+ libraries to be written in a number of languages. Classes and
+ methods created in one language can be used from a different
+ language.
+
+ This means for example that if you define a class to do algebraic
+ manipulation in C#, that class can be reused from any other
+ language that supports the CLI. You could create a class in C#,
+ subclass it in C++ and instantiate it in an Eiffel program.
+
+ A single object system, threading system, class libraries, and
+ garbage collection system can be shared across all these languages.
+
+Q: Where can I find the specification for these technologies?
+
+A: You can find the work-in-progress documentation from the T3G ECMA
+ group here:
+
+ <a href="http://www.dotnetexperts.com">http://www.dotnetexperts.com</a>
+
+Q: Will you implement the .NET Framework SDK class libraries?
+
+A: Yes, we will be implementing the APIs of the .NET Framework SDK
+ class libraries.
+
+Q: What does Mono stand for?
+
+A: Mono is the word for `Monkey' in Spanish. We like monkeys.
+
+ It only means a number of other things: monochromatic (hence the
+ gray theme used in the Web site).
+
+Q: When will you ship it?
+
+A: We do not know when the code will be shipped. The more
+ contributions we get to the project, the sooner it will ship.
+
+ A rough estimate is that we might be able to run our C# compiler on
+ Linux by the end of the year. That means running the Windows
+ Executable generated by a Microsoft .NET compiler on the Linux
+ platform.
+
+ We expect that doing GUI applications will require more work on the
+ class libraries. That could take another six months.
+
+Q: How can I contribute?
+
+A: Check the <a href="contributing.html">contributing</a> section.
+
+Q: You guys should innovate instead of copying.
+
+A: In this particular case, we see a clear advantage in the platform
+ and we are interested in using the features of the CLI on open source systems.
+
+ We have decided that we should spend our limited resources towards
+ implementing an existing specification instead of designing and
+ implementing our own.
+
+ Designing and implementing our own would be possible, but it doesn't make
+ sense to do that just because the specification comes from a
+ proprietary vendor.
+
+** Ximian
+
+Q: Why is Ximian working on .NET?
+
+A: We are interested in providing the best tools for programmers to
+ develop applications for Free Operating Systems.
+
+ For more information, read the project <a
+ href="rationale.html">rationale</a> page.
+
+Q: Will Ximian be able to take on a project of this size?
+
+A: Ximian will not be able to taken on the whole project on its own.
+ Mono will be a free software/open source community project, that is
+ the only way we can hope to implement something of this size. You
+ can <a href="contributing.html">contribute</a> to this effort.
+
+Q: What pieces will Ximian be working on?
+
+A: We will focus on building a development and execution
+ environment.
+
+ The idea is to get Mono to a state of that would allow
+ third parties to actually be able to use it real-world development.
+
+Q: Why does Ximian even care?
+
+A: We like the features that the CLI and its related technologies
+ bring to the table. An exciting addition to the developer toolkit.
+ The goal of Mono is to bring this technology to non-Windows
+ platforms (although we hope Mono will also run on Windows, for
+ debugging and comparative purposes).
+
+
+** Licensing
+
+Q: Will I be able to write proprietary applications that run with
+ Mono?
+
+A: Yes. The licensing scheme is planned to allow proprietary
+ developers to write applications with Mono.
+
+Q: What license is Mono on?
+
+A: The C# Compiler is released under the terms of the GPL. The class
+ libraries will be under the LGPL or the GPL with a special
+ exception. The runtime libraries are under the LGPL.
+
+ Since the LGPL is not suitable for embedded systems development, we
+ are also licensing the libraries under the GPL with the following exception:
+
+ If you link this library against your own program, then you do not
+ need to release the source code for that program. However, any
+ changes that you make to the library itself, or to any native
+ methods upon which the library relies, must be re-distributed in
+ accordance with the terms of the GPL.
+
+ This is similar in spirit to <a
+ href="http://www.gnu.org/software/classpath/classpath.html">GNU
+ Classpath.</a>
+
+Q: But in Object Oriented Programming I need to subclass your library
+ functions, does that mean that I am making modifications to your
+ library and hence I would have to distribute my sources under the
+ LGPL?
+
+A: No. Object Oriented Programming in the class library is a well
+ understood interface barrier, so you can actually develop
+ proprietary applications with the Mono libraries.
+
+Q: Will you accept code under the XXX License?
+
+A: If the XXX License is compatible with the license we use in that
+ specific piece of code, then yes. If you want to use the BSD license, make
+ sure you use the BSD license without the advertisement clause (The
+ `Ousterhout License').
+
+** Mono and .NET
+
+Q: If applications use Mono, does that mean that I have to pay a service fee?
+
+A: No. Mono is not related to Microsoft's initiative of
+ software-as-a-service.
+
+Q: If you implement .NET, will I depend on Microsoft Passport to run my software?
+
+A: No. The .NET Framework is a runtime infrastructure and collection
+ of class libraries. Passport may be required to access certain web
+ services written for that framework, but only if the programmer
+ chooses Passport as the authentication mechanism.
+
+Q: Is .NET just a bunch of marketing slogans?
+
+A: Although the `.NET initiative' is still quite nebulous, The .NET Framework
+ has been available for some time. Mono is not an implementation of the .NET
+ initiative, just the development framework.
+
+Q: What is a 100% .NET application?
+
+A: A `100% .NET application' is one that only uses the APIs defined
+ under the System namespace and does not use PInvoke. These
+ applications would in theory run unmodified on Windows, Linux,
+ HP-UX, Solaris, MacOS X and others.
+
+Q: But Microsoft will release a port of the real thing under the
+ `Shared Source' license, why bother with anything else?
+
+A: The Shared Source implementation will not be usable for commercial
+ purposes. We are working towards an implementation that will grant
+ a number of rights to recipients: use for any purpose,
+ redistribution, modification, and redistribution of modifications.
+
+ This is what we call <a
+ href="http://www.gnu.org/philosophy/free-sw.html">Free Software</a>
+
+** Passport
+
+Q: Is this a free implementation of Passport?
+
+A: No. Passport is part of Microsoft's Hailstorm initiative. Mono
+ is just a runtime, a compiler and a set of class libraries.
+
+Q: Will the System.Web.Security.PassportIdentity class, mean
+ that my software will depend on Passport?
+
+A: No. That just means that applications might use that API to
+ contact a Passport site.
+
+ As long as your application does not use Passport, you will not
+ need Passport.
+
+ It might even be possible to implement that class with
+ a set of dummy functions, or use an alternate Passport implementation.
+
+ We do not know at this time whether the Passport protocol is
+ documented and whether we will be able to talk to
+ passport.com
+
+Q: But that must mean that you are tied to Passport!
+
+A: All the contrary. The implementation could keep the interface (for
+ the sake of simplicity, lets say it implements the method `Login'
+ and `GetUserName').
+
+ We could implement `Login' and `GetUserName' by talking to XNS or
+ any other decentralized systems. Or any other system that the
+ industry standarizes on.
+
+Q: What is your opinion?
+
+A: You can read my personal <a href="passport.html">opinion on
+ passport</a>.
+
+Q: Will Mono running on Linux make Passport available for Linux?
+
+A: The Passport toolkit for Linux-based web servers is available from
+ Microsoft.
+
+ Again, Mono has nothing to do with Passport.
+
+** Mono and Windows
+
+Q: Will Mono allow me to run Microsoft Office on Linux?
+
+A: No, it will not. Microsoft Office is a Windows application. To
+ run Windows applications on Intel Unix systems refer to <a
+ href="http://www.winehq.com">the Wine Project</a>
+
+** GNOME
+
+Q: How is this related to GNOME?
+
+A: In a number of ways:
+
+ * Mono will use existing
+ components that have been developed for GNOME when it makes
+ sense. For example on X systems, we will use Gtk+ and
+ Libart to implement Winforms and the Drawing2D API.
+
+ For database access, we will use LibGDA (not really
+ depending on GNOME, but related to).
+
+ * This project was born out of the need of providing improved
+ tools for the GNOME community.
+
+ * We would like to add support to our CLR implementation to
+ deal with GObjects (in GNOME 1.x, they are called
+ GtkObjects), and allow Mono developers to provide GObjects
+ or use and extend existing GObjects.
+
+Q: Has the GNOME Foundation or the GNOME team adopted Mono?
+
+A: Mono is too new to be adopted by those groups. We hope that the
+ tools that we will provide will be adopted by free software
+ programmers including the GNOME Foundation members and the GNOME
+ project generally.
+
+Q: Should GNOME programmers switch over to Mono?
+
+A: Mono will not be ready even within the next six months, and a
+ complete implementation is probably one year away.
+
+ We encourage GNOME developers to continue using the existing tools,
+ libraries and components. Improvements made to GNOME will have an
+ impact on Mono, as they will provide the "backend" for various
+ classes.
+
+Q: Will Mono include compatibility with Bonobo components?
+
+A: Yes, we will provide a set of classes for implementing and using
+ Bonobo components from within Mono.
+
+Q: Does Mono replace Bonobo?
+
+A: Bonobo is very focused on cross-application component reuse. Mono
+ will provide a Bonobo framework to allow you to develop Bonobo
+ components and use Bonobo components on Unix.
+
+ Mono should allow you to write Bonobo components more easily, just
+ like .NET on Windows allows you to export .NET components to COM.
+
+** Mono and the Web
+
+Q: Is Mono a way of running Java applets?
+
+A: No.
+
+** Web Services
+
+Q: Is Mono just a new way of writing Web Services?
+
+A: No.
+
+Q: If this implements the SDK classes, will I be able to write and
+ execute .NET Web Services with this?
+
+A: Yes, you will.
+
+ When the project is finished, you will be able to use the same
+ technologies that are available through the .NET Framework SDK on
+ Windows to write Web Services.
+
+Q: What about Soup?
+
+A: Soup is a library for GNOME applications to create SOAP server and
+ SOAP clients. You can browse the source code for soup using <a
+ href="http://cvs.gnome.org/bonsai">GNOME's Bonsai</a>
+
+Q: Can I use CORBA?
+
+A: Yes. The CLI contains enough information about a class that
+ exposing it to other RPC systems (like CORBA) is really simple, and
+ does not even require support from an object.
+
+ We will be implementing CORBA interoperation as an extension to the
+ Mono classes so that we can integrate with Bonobo, just like
+ Microsoft provides COM interoperation classes and support
+ mechanisms.
+
+Q: Can I serialize my objects to other things other than XML?
+
+A: Yes, although the serializing tools have not yet been planned, and
+you would probably have to implement them yourself.
+
+** Development Tools
+
+Q: Will it be possible to use the CLI features without using bytecodes
+ or the JIT?
+
+A: Yes. The CLI engine will be made available as a shared library.
+ The garbage collection engine, the threading abstraction, the
+ object system, the dynamic type code system and the JIT will be
+ available for C developers to integreate with their applications if
+ they wish to do so.
+
+Q: Will you have new development tools?
+
+A: Hopefully Free Software enthusiasts will contribute tools to
+ improve the developer environment. These tools could be developed
+ initially using Microsoft implementation of the CLI and then
+ executed later with Mono.
+
+** Mono and Java
+
+Q: What about using Java? After all there are many languages that
+ target the Java VM.
+
+A: You can get very good tools for doing Java development on free
+ systems right now. <a href="http://www.redhat.com">Red Hat</a> has
+ contributed a <a href="http://gcc.gnu.org">GCC</a> <a
+ href="http://gcc.gnu.org/java">frontend for Java</a> that can take
+ Java sources or Java byte codes and generate native executables; <a
+ href="http://www.transvirtual.com">Transvirtual</a> has implemented
+ <a href="http://www.kaffe.org">Kaffe</a> a JIT engine for Java;
+ Intel also has a Java VM called <a
+ href="http://www.intel.com/research/mrl/orp">ORP</a>.
+
+ The JVM is not designed to be a general purpose virtual machine.
+ The Common Intermediate Language (CIL), on the other hand, is
+ designed to be a target for a
+ wide variety of programming languages, and has a set of rules
+ designed to be optimal for JITers.
+
+
+Q: What kind of rules make the Common Intermediate Language useful for
+ JITers?
+
+A: The main rule is that the stack in the CLI is not a general purpose
+ stack. You are not allowed to use it for other purposes than
+ computing values and passing arguments to functions or return
+ values.
+
+ At any given call or return instruction, the types on the stack
+ have to be the same independently of the flow of execution of your
+ code.
+
+Q: I heard that the CIL is ideal for JITing and not efficient for
+ interpreters, is this the case?
+
+A: The CIL is better suited to be JITed than JVM byte codes, but you
+ can interpret them as trivially as you can interpret JVM byte
+ codes.
+
+Q: Could Java target the CLI?
+
+A: Yes, Java could target the CLI. We have details on a <a
+ href="ideas.html#guavac">project</a> that someone could take on to
+ make this happen.
+
+** Extending Mono
+
+Q: Would you allow other classes other than those in the
+ specification?
+
+A: Yes. The Microsoft class collection is very big, but it is by no
+ means complete. It would be nice to have a port of `Camel' (the
+ Mail API used by Evolution inspired by Java Mail) for Mono
+ applications.
+
+ You might also want to look into implementing CORBA for Mono. Not
+ only because it would be useful, but because it sounds like a fun
+ thing to do, given the fact that the CLI is such a type rich
+ system.
+
+ For more information on extending Mono, see our <a
+ href="ideas.html">ideas</a> page.
+
+** Mono and portability
+
+Q: Will Mono only work on Linux?
+
+A: Currently, we are doing our work on Linux-based systems and
+ Windows. We do not expect many Linux-isms in the code, so it
+ should be easy to port Mono to other UNIX variants.
+
+Q: What about Mono on non X-based systems?
+
+A: Our main intention at Ximian is to be able to develop GNOME
+ applications with Mono, but if you are interested in providing a
+ port of the Winform classes to other platforms (frame buffer or
+ MacOS X for example), we would gladly integrate them, as long
+ they are under a Free Software License.
+
+** Reusing existing Code
+
+Q: What projects will you reuse or build upon?
+
+A: We want to get Mono in the hands of programmers soon. We are
+ interested in reusing existing open source software.
+
+Q: What about Intel's research JIT framework, ORP?
+
+A: At this time, we are investigating whether we can use elements of
+ ORP for Mono. ORP is a research JIT engine that has a clear
+ defined API that splits the JIT from the GC system and the actual
+ byte code implementation. It is a research product.
+
+Q: What about using GNU Lightning?
+
+A: We are also researching <a
+ href="http://www.gnu.org/software/lightning/lightning.html">GNU
+ Lightning</a>.
+
+<a name="ximian-and-microsoft">
+** Ximian and Microsoft
+
+Q: I read that Microsoft is helping out Ximian, is this true?
+
+A: Initial contact between David Stutz and Miguel de Icaza happened.
+ It was a friendly conversation. Microsoft is interested in other
+ implementing .NET and are willing to help make the ECMA spec more
+ accurate for this purpose.
+
+ We were initially contacted by Sam Ruby at the ECMA TG3 committee
+ to discuss the same issue. And we are glad to have good contacts
+ to ask questions about the specs.
+
+Q: Is Microsoft paying Ximian to do this?
+
+A: No, we are doing this for purely selfish reasons. We are upgrading
+ our development platform to build better applications on Unix and other
+ systems.
+
+Q: Do you fear that Microsoft will change the spec and render Mono useless?
+
+A: No. Microsoft proved with the CLI and the C# language that it was
+ possible to create a powerful foundation for many languages to
+ interoperate. We will always have that.
+
+ Even if changes happened in the platform which were undocumented
+ (which is very unlikely), the existing platform has a value on its
+ own.
+
+ Miguel once explained its motivation for working on Mono to Dave
+ Winer, and his mail got posted <a
+ href="http://scriptingnews.userland.com/stories/storyReader$1275">here</a>
+
+Q: Didn't Miguel de Icaza say that `Unix Sucks'?
+
+A: Yes, he did, as a catch phrase in his opening remark on the Ottawa
+ Linux Symposium. His talk focused on various ways to improve Unix.
+
+ There is a paper describing some ways to improve Unix at:
+
+ <a href="http://primates.ximian.com/~miguel/bongo-bong.html">
+ http://primates.ximian.com/~miguel/bongo-bong.html</a>
+
+Q: Didn't Ximian's Miguel work for Microsoft?
+
+A: Actually, Nat Friedman (Ximian's co-founder) did work as an
+ intern for Microsoft for one summer but Miguel did not.
+
+Q: Did Nat and Miguel meet at Microsoft?
+
+A: They met online on the Linux IRC network; They met in person for
+ the first time in 1997.
+
+** Mono and Microsoft
+
+Q: How can you expect Mono to compete with Microsoft, wont this
+ require an effort too large?
+
+A: You are right. Mono will never become a reality without the help
+ of other contributors. Ximian is a small company that can not
+ finish Mono alone. We will be working with members of the
+ community to deliver the product.
+
+Q: Is Microsoft and Corel involved in the Mono implementation?
+
+A: No, they are not.
+
+Q: Are you writing Mono from the ECMA specs?
+
+A: yes, we are writing them from the ECMA specs and the published
+ materials in print about .NET
+
+Q: What happens if Microsoft `Embraces and Extends' the CLI standard
+ and keeps Mono out of the play?
+
+A: There are various explanations to this question. The first one is
+ that the benefits that you can get from the CLI are going to be
+ there with or without `embracing and extending'. We might not be
+ able to run every .NET Windows application on Mono. But remember:
+ it was already easy for someone to just use PInvoke to tie their
+ application to Windows.
+
+ The bottom line is that the advantages of having a CLI runtime will
+ be with us, no matter if Microsoft forks their version to be
+ incompatible.
+
+Q: What if Microsoft changes the interface, and all of a sudden
+ applications break?
+
+A: If they change their released API, every application that was
+ developed against it will break.
+
+ That being said, Microsoft have a pretty good record of keeping
+ backwards binary compatibility.
+
+** Acronyms
+
+Q: What is the difference between CLR (Common Language Runtime) and
+ CLI (Common Language Infrastructure)?
+
+A: CLI is the specification of an execution system. The Microsoft
+ implementation of this specification is named CLR.
+
+ Unless we come up with our own acronym, we could just call ours
+ also CLR, just because it would do exactly the same thing the
+ Microsoft implementation does.
+
+<a name="gcc">
+** Mono and GCC
+
+Q: Should someone work on a GCC front-end to C#?
+
+A: I would love if someone does, and we would love to help anyone that
+ takes on that task, but we do not have the time or expertise to
+ build a C# compiler with the GCC engine. I find it a lot more fun
+ personally to work on C# on a C# compiler, which has an intrinsic
+ beauty.
+
+ We can provide help and assistance to anyone who would like to work
+ on this task.
+
+Q: Should someone make a GCC backend that will generate CIL images?
+
+A: I would love to see a backend to GCC that generates CIL images. It
+ would provide a ton of free compilers that would generate CIL
+ code. This is something that people would want to look into
+ anyways for Windows interoperation in the future.
+
+ Again, we would love to provide help and assistance to anyone
+ interested in working in such a project.
+
+Q: What about making a front-end to GCC that takes CIL images and
+ generates native code?
+
+A: I would love to see this, specially since GCC supports this same
+ feature for Java Byte Codes. You could use the metadata library
+ from Mono to read the byte codes (ie, this would be your
+ "front-end") and generate the trees that get passed to the
+ optimizer.
+
+ Ideally our implementation of the CLI will be available as a shared
+ library that could be linked with your application as its runtime
+ support.
+
+ Again, we would love to provide help and assistance to anyone
+ interested in working in such a project.
+
+Q: But would this work around the GPL in the GCC compiler and allow
+ people to work on non-free front-ends?
+
+A: People can already do this by targeting the JVM byte codes (there
+ are about 130 compilers for various languages that target the JVM).
+
+Q: Why are you writing a JIT engine instead of a front-end to GCC?
+
+A: The JIT engine and runtime engine will be able to execute CIL
+ executables generated on Windows.
+
+** Mono and Portability
+
+Q: Will Mono work on other variants of Unix?
+
+A: Yes. We do not expect to add any gratuitous incompatibilities.
+
+Q: Will Mono run on Windows?
+
+A: Hopefully yes. Currently some parts of Mono only run on Windows
+ (the C# compiler is a .NET executable) and other parts have only
+ been compiled on Linux, but work on Windows with Cygwin.
+
+Q: Will Mono depend on GNOME?
+
+A: It will depend only if you are using a particular assembly (for
+ example, for doing GUI applications). If you are just interested
+ in Mono for implementing a `Hello World Enterprise P2P Web
+ Service', you will not need any GNOME component.
+
+** Performance
+
+Q: How fast will be Mono?
+
+A: We can not predict the future, but a conservative estimate is that
+ it would be at least `as fast as other JIT engines'.
+
+ Now, wishfully thinking I hope that we will ship various JITs with
+ Mono just like Microsoft has done. A fast JITer when maximum
+ performance is not needed, but fast load times are important; And
+ an optimizing JITer that would be slower at generating code but
+ produce more optimal output.
+
+ The CIL has some advantages over the Java byte code: it is really
+ an intermediate representation and there are a number of
+ restrictions on how you can emit CIL code that simplify creating
+ better JIT engines.
+
+ For example, on the CIL the stack is not really an abstraction
+ available for the code generator to use at will: it is just a way
+ of creating a postfix representation of the parsed tree. At any
+ given call point or return point, the contents of the stack are
+ expected to contain the same object types independently of how the
+ instructions was reached.
+
+
+** Mono and Portable.NET
+
+Q: What are the differences between Mono and Portable.NET?
+
+A: Most of Mono is being written using C#, the only pieces written in
+ C are those who have to absolutely be built using C (The JIT
+ engine, the runtime, the interfaces to the garbage collection
+ system).
+
+ The C# compiler and the tools will become reusable C# components.
+
+ Portable.NET is building its components out of C pieces.
+
+** Assorted questions
+
+Q: You say that the CLI allows multiple languages to execute on the
+ same environment. Isn't this the purpose of CORBA?
+
+A: The key difference between CORBA (and COM) and the CLI is that the
+ CLI allows "data-level interoperability" because every
+ language/component uses the same data layout and memory management.
+
+ This means you can operate directly upon the datatypes that someone
+ else provides, without having to go via their interfaces. It also
+ means you don't have to "marshall" (convert) parameters (data
+ layouts are the same, so you can just pass components directly) and
+ you don't have to worry about memory managment, because all
+ languages/components share the same garbage collector and address
+ space. This means much less copying and no need for reference
+ counting.
+
diff --git a/doc/gcc-frontend b/doc/gcc-frontend
new file mode 100644
index 00000000000..2b15346db69
--- /dev/null
+++ b/doc/gcc-frontend
@@ -0,0 +1,9 @@
+* The GCC front-end
+
+ The GCC front-end will accept input in a binary file with
+ codes in the Common Intermediate Language (CIL), and generate
+ native code.
+
+ This will allow pre-compilation and full optimization to take
+ place before a program is executed.
+
diff --git a/doc/ideas b/doc/ideas
new file mode 100644
index 00000000000..fb2a89aa205
--- /dev/null
+++ b/doc/ideas
@@ -0,0 +1,119 @@
+* Ideas
+
+ Here are a few ideas of tools, classes and projects that you
+ could start. More are forthcoming.
+
+<a name="runtime">
+** Runtime
+
+ We need a verifier that can be run on an executable (assembly)
+ and tells whether the metadata for the executable is correct
+ or not. It should report any anomalies.
+
+ For a list of anomalies in assemblies, check the various assertions
+ that are described on the ECMA documentation.
+
+ This will help test our generated executables and can be also
+ used as an external verifier.
+
+<a name="classes">
+** Classes
+
+ <ul>
+TODO=jxta,The JXTA Peer to Peer foundation
+ * Implement a JXTA protocol implementation:
+ <a href="http://www.jxta.org">http://www.jxta.org</a>
+
+TODO=camel,Mail API
+ * Implement a Mail API, similar to Camel or JavaMail (Camel has
+ significant architecture features that are required on a real
+ mailer).
+
+ You can check the current C
+ <a href="http://cvs.gnome.org/bonsai/rview.cgi?dir=evolution%2Fcamel">
+ Camel implementation</a>.
+
+ Such an implementation could be used both with
+ Microsoft .NET and Mono.
+
+TODO=multimedia
+ * Interfacing to Multimedia systems. You might want
+ to look into the Quicktime API. I know <a
+ href="mailto:vladimir@ximian.com">Vladimir</a> has
+ researched the problem before
+
+TODO=gtk,Gtk+ wrappers for Mono and .NET
+ * Wrap the Gtk+ API. This is simple and can be done
+ on Windows as Gtk+ 2.0 works on Windows.
+
+ This work can also be used on Windows and will
+ enable developers on Windows to use some of Gtk+'s
+ advanced features.
+
+ The idea is to wrap the Gtk+ API and allow us to
+ build GUI applications using Gtk+ and in the future
+ other Gtk+-based libraries from Mono (Gal, GtkHTML).
+
+ There is extensive knowledge on wrapping Gtk+ in
+ other languages (this has been done this for Perl,
+ Python, Java, Scheme, Haskel and other languages in
+ the past).
+ </ul>
+
+<a name="projects">
+** Projects
+
+ <ul>
+TODO=xmlStorage,
+ * Implement an xmlStorageSystem for the CLI:
+ <a href="http://www.soapware.org/xmlStorageSystem">
+ http://www.soapware.org/xmlStorageSystem</a>
+
+TODO=guavac,Java compiler for .NET
+ * You could take one of the existing Java compilers
+ (Guavac comes to mind as it is so nice) and modify
+ it to generate .NET code rather than JVM byte
+ codes.
+
+ This should be a pretty straightforward task.
+ Guavac has the advantage of being written in C++ and
+ it could be compiled with the Microsoft Managed C++
+ compiler and produce a .NET executable with it.
+
+TODO=CORBA,CORBA implementation
+ * Build a CORBA interoperability engine for the CLR.
+ You do not need to do all of the work, just talking
+ the protocol will get us a long way (<a
+ href="http://www.omg.org">The OMG site</a> has the
+ CORBA specs).
+
+ Get in touch with David Taylor (dtaylo11 at bigpond
+ dot net dot au) as he has been working on this
+ project.
+
+TODO=Bonobo,Bonobo for Mono
+ * Once CORBA is done, implement the Bonobo interfaces
+ to allow people to use Bonobo components in Mono and
+ Mono components with Bonobo. The best of both worlds!
+
+TODO=moniker,Object Naming System with Monikers
+ * A naming space for Mono. An object naming space is
+ a very powerful tool. Bonobo implements a moniker
+ system that is more powerful than the original
+ moniker concept that was pioneered by COM/OLE in the
+ Microsoft world.
+
+ Our implementation builds on a concept, and we have
+ made it simpler, more powerful, more extensible and
+ a much better mechanism than the equivalent monikers
+ on Windows.
+
+ Implementing Mono monikers would benefit both
+ Windows users using .NET and Mono users on Unix and
+ Windows.
+
+ Here is <a
+ href="http://primates.ximian.com/~miguel/monikers.html">an
+ overview of the moniker system</a> in Bonobo.
+
+ </ul>
diff --git a/doc/index b/doc/index
new file mode 100644
index 00000000000..d43c81135ed
--- /dev/null
+++ b/doc/index
@@ -0,0 +1,103 @@
+ <a href="http://www.ximian.com">Ximian</a> announced the
+ launch of the Mono project, an effort to create an Open Source
+ implementation of the .NET Development Framework.
+
+ Mono includes: <a href="c-sharp.html">a compiler</a> for the
+ C# language, a <a href="runtime.html">runtime</a> for the
+ Common Language Infrastructure and a set of <a
+ href="class-librayr.html">class libraries</a>
+
+ You can read our <a href="rationale.html">rationale</a> for
+ this project. If you have questions about the project, please
+ read our list of <a href="faq.html">Frequently Asked
+ Questions</a> or <a href="mailto:mono-list@ximian.com">contact us.</a>
+
+ You might also want to <a href="download.html">Download the
+ source</a> for our work so far. Or you can grab a <a
+ href="snapshots">snapshot</a> of our current work.
+
+ You might want to <a
+ href="resources.html#mailing">subscribe</a> to our mono-list
+ and mono-announce-list
+
+ You can contact the team at: <a
+ href="mailto:mono-list@ximian.com">mono-list@ximian.com</a>
+
+** Aug 20, 2001
+
+ A new <a href="contributing.html#compile-service">Compilation
+ service</a> has been made available by Derek to allow people
+ without access to the <a
+ href="http://msdn.microsoft.com/downloads/default.asp?url=/downloads/sample.asp?url=/msdn-files/027/000/976/msdncompositedoc.xml&frame=true">.NET SDK</a>
+
+** Aug 3, 2001
+
+ Daily snapshots of mcs and mono are now available, they will
+ run every night at 10pm Boston time.
+
+** Jul 29, 2001
+
+ Mono Runtime 0.5 has been <a
+ href="download.html#july-29">released.</a> Check the <a
+ href="archive/mono-0.5">release notes</a>
+
+** Jul 25, 2001
+
+ The slides for <A href="Presentations/O-Reilly">my
+ presentation</a> at <a href="http://www.oreilly.com">O'Reilly
+ Open Source Software Convention</a>
+
+** Jul 22, 2001
+
+ Another release of the class libraries is out, check the <a
+ href="archive/mcs-22">MCS 22-July Release Notes</a>. You can
+ get the new class libraries from <a
+ href="download.html#july-22">here</a>
+
+** Jul 19, 2001
+
+ Another release of the class libraries is out, check the <a
+ href="archive/mcs-19">MCS 19-July Release Notes</a>. You can
+ get the new class libraries from <a
+ href="download.html#july-19">here</a>
+
+** Jul 17, 2001
+
+ Another release of the class libraries is out, check the <a
+ href="archive/mcs-17">MCS 17-July Release Notes</a>. You can
+ get the new class libraries from <a
+ href="download.html#july-17">here</a>
+
+ Do not forget to check out the updated <a href="faq.html">FAQ</a>.
+
+ Got Sean's new <a href="class-status/index.html">Class
+ Status</a> web pages up. These are a lot better than mine, and
+ we are now keeping better track of contributors.
+
+** Jul 15, 2001
+
+ Another release of Mono is out, check the <a
+ href="archive/mono-0.4">Mono 0.4 Release Notes</a>. Get it <a
+ href="download.html#july-15">here</a>.
+
+** Jul 14, 2001
+
+ A <a
+ href="http://mail.ximian.com/archives/public/mono-list/2001-July/000399.html">new
+ release</a> of the
+ runtime, compiler and classes has been made. Get it <a href="download.html#july-14">here</a>
+
+** Jul 12, 2001
+
+ I keep getting questions about my opinion on Passport, even when
+ Mono has <b>nothing</b> to do with it. I finally <a
+ href="passport.html">wrote something.</a>
+
+** Jul 9, 2001
+
+ Project launched.
+
+** O'Reilly
+
+ Brian posted a story on <a
+ href="http://www.oreillynet.com/dotnet">O'Reilly Network .NET</a>
diff --git a/doc/passport b/doc/passport
new file mode 100644
index 00000000000..05346d8aa20
--- /dev/null
+++ b/doc/passport
@@ -0,0 +1,276 @@
+* Updates
+
+ I have received many comments from people, and I have updated
+ the page accordingly. From removing incorrect statements, to
+ fixing typos, to include mentions to other software pieces.
+
+ I also corrected my statement about IIS and a trojan horse, I
+ should read a more educated press in the future. My apologies
+ to Microsoft and its employees on this particular topic. IIS
+ did not have a trojan horse built in.
+
+* Microsoft Hailstorm and Passport
+
+ Microsoft Passport is a centralized database hosted by
+ Microsoft that enhances the consumer experience with the Web
+ by providing a single logon system that they can use across a
+ number of participant web sites.
+
+ As you might know by now from our extensive <a
+ href="faq.html">FAQ</a>, the Mono project has nothing to do
+ with Microsoft Hailstorm or <a
+ href="http://www.passport.com">Microsoft Passport.</a>
+
+ Still a lot of people have asked us our opinion on them.
+
+** Passport
+
+ Passport is important not because of it being a breakthrough
+ technologically speaking, but because the company is in a
+ position to drive most people toward being suscribers of it.
+
+ At the time of this writing passport is required to use the
+ free mail service <a href="http://www.hotmail.com">Hotmail</a>
+ to get customized support for the <a
+ href="http://www.msn.com">MSN portal</a>, <a
+ href="http://msdn.microsoft.com">Microsoft Developers
+ Network</a> and according to the original announcement from
+ Microsoft <a href="http://www.americanexpress.com">American
+ Express</a> and <a href="http://www.ebay.com">EBay</a> will be
+ adopting it.
+
+ There is already a <a
+ href="http://www.passport.com/Directory/Default.asp?PPDir=C&lc=1033">Large
+ list</a> of participating sites.
+
+ There are many current users of it and Microsoft will be
+ driving more users towards Passport as it <a
+ href="http://news.cnet.com/news/0-1003-200-6343275.html">integrates
+ it</a> in their upcoming release of Windows.
+
+ Microsoft has also <a
+ href="http://www.passport.com/Business/JoinPassportNetwork.asp?lc=1033">developed
+ a toolkit</a> to enable current web merchants to integrate
+ their services with passport.
+
+ To the end user, there is a clear benefit: they only have to
+ log into a single network and not remember multiple passwords
+ across sites on the internet. Companies that adopt passport
+ will have a competition advantage over those that dont.
+ Microsoft lists a list of <a
+ href="http://www.passport.com/Business/Default.asp?lc=1033">benefits</a>
+ to companies.
+
+
+** The problems of Passport
+
+ There are a number of concerns that different groups have over
+ Passport. Sometimes I have some, sometimes I do not. But
+ overall, consumers and businesses can have better solutions.
+
+ <ul>
+ * <b>Single Point of Failure:</b> As more services and
+ components depend on remote servers, functionality can
+ grind to a halt if there is a failure on the
+ centralized Passport system.
+
+ Such a failure was predicted, and we recently <a
+ href="http://news.cnet.com/news/0-1005-200-6473003.html">witnessed</a>
+ got a lot of people worried.
+
+ The outgage lasted for seven days. Think what this
+ could do to your business.
+
+ * <b>Trust:</b> Not everyone trusts Microsoft to keep
+ their information confidential. Concerns are not only
+ at the corporate level policy, but also the fact that
+ the source code for Microsoft products is not
+ available, means that trojans or worms could be built
+ into the products by malicious engineers.
+
+ * <b>Security:</b> With a centralized system like
+ Passport, imagine the repercussions of a malicious
+ hacker gaining access to the Passport database.
+ Personal information and credit card information about
+ almost everyone using a computer could be stored there.
+
+ Hackers have already <a
+ href="http://slashdot.org/articles/00/10/27/1147248.shtml">broken
+ into Microsoft</a> in the past. And the company was
+ unable to figure out for how long their systems had
+ been hacked.
+
+ Security holes have been found in <a
+ href="http://slashdot.org/articles/00/04/14/0619206.shtml">IIS
+ in the past.</a> If all the world's data is stored on
+ a central location, when a single security hole is
+ detected, it would allow an intruder to install a
+ backdoor within seconds into the corporate network
+ without people ever noticing.
+
+ Microsoft itself has been recently hit by worms,
+ imagine if all your business depended on a single
+ provider for providing all or your authentication
+ needs
+ </ul>
+
+ Microsoft might or might not realize this. The idea behind
+ Passport is indeed a good one (I can start to get rid of my
+ file that keeps track of the 30 logins and passwords or so
+ that I use across the various services on the net myself).
+
+** Alternatives to Microsoft Passport
+
+ An alternative to Microsoft Passport needs to take the above
+ problems into consideration. Any solution of the form `We
+ will just have a competing offering' will not work.
+
+ The system thus has to be:
+
+ <ul>
+ * <b>Distributed:</b> The entire authentication
+ system should not create an internet `blackout' in the
+ case of failure.
+
+ A distributed system using different software
+ platforms and different vendors would be more
+ resistent to an attack, as holes in a particular
+ implementation of the server software would not affect
+ every person at the same time.
+
+ A security hole attack might not even be relevant to
+ other software vendors software.
+
+ * <b>Allow for multiple registrars:</b> Users should
+ be able to choose a registrar (their banks, local
+ phone company, service provider, Swiss bank, or any
+ other entity they trust.
+
+ * <b>Mandate good security measures:</b> As a
+ principle, only Open Source software should be used
+ for servers in the registrar, and they should conform
+ to a standard set of tools and software that can be
+ examined by third parties.
+ </ul>
+
+ An implementation of this protocol could use the DNS or a
+ DNS-like setup to distribute the information of users with the
+ possibility of replicating and caching public information
+ about the user.
+
+ For instant messaging (another piece of the Hailstorm bit),
+ you want to use a non-centralized system like Sun's <a
+ href="http://www.jxta.org">JXTA</a>. Some people mailed me to
+ mention Jabber as a messaging platform and other people
+ pointed out to the <a
+ href="http://java.sun.com/products/jms/">Java Message
+ Service</a>. The JMS does support a number of very
+ interesting features that are worth researching.
+
+ It could also just use the user e-mail address as the `key' to
+ choose the registrar (msn.com, hotmail.com -> passport.com;
+ aol.com -> aol.passport.com; you get the idea).
+
+ The <a
+ href="http://www.soapware.org/xmlStorageSystem">xmlStorage</a>
+ idea from <a href="http://www.scripting.com">Dave Winer</a>
+ could be used to store the information.
+
+ A toolkit for various popular web servers could be provided,
+ authenticated and should be open sourced (for those of you who
+ think that a binary program would give more security and would
+ prevent people from tampering: you are wrong. You can always
+ use a proxy system that "behaves" like the binary, and passes
+ information back and forth from the real program, and snoops
+ in-transit information).
+
+ Good cryptographers need to be involved in this problem to
+ figure out the details and the possible insecure pieces of a
+ proposal like this.
+
+** Implementation: In short
+
+ To keep it short: <b>DNS, JXTA, xmlStorage.</b>
+
+
+** Deploying it
+
+ The implementation of such a system should be a pretty
+ straightforward task once security cryptographers have
+ designed such a beast.
+
+ The major problems are:
+
+ <ul>
+ * <b>People might just not care:</b> In a poll to US
+ citizens a couple of decades ago, it was found that
+ most people did not care about the rights they were
+ given by the Bill of Rights, which lead to a number of
+ laws to be passed in the US that eliminated most of
+ the rights people had.
+
+ * <b>The industry will move way too slow:</b>
+ Microsoft's implementation is out in the open now: it
+ is being deployed, and soon it will be insinuated to
+ many, many users. The industry needs to get together
+ soon if they care about this issue.
+
+ By the time the industry reacts, it might be too
+ late.
+ </ul>
+
+** Passport and Mono
+
+ The .NET class libraries include a Passport class that
+ applications might use to authenticate with Passport. Since
+ we do not have information at this point on the exact protocol
+ of Passport, it is not even feasible to implement it.
+
+ If at some point the information is disclosed, it could be
+ implemented.
+
+ If a competing system to Passport existed, we could probably
+ hide all the authentication information to use a number of
+ different passport-like systems.
+
+ If a user does not want to use Passport at all, he could
+ always turn it off (or completely remove the class from the
+ library). After all, this is free software.
+
+ Currently, we are too far from the point where this is a real
+ issue.
+
+** Passport and endangering Open Source.
+
+ A few people have said: `Mono will allow Passport to be
+ available for Linux and that is bad'. This is plain
+ missinformation.
+
+ Currently, you can obtain Passport for Linux from Microsoft
+ itself and deploy it today on your Web server. Mono does not
+ even enter the picture here. Go to passport.com and download
+ the toolkit and you will see with your own eyes that passport
+ is <B>already</b> available for Linux.
+
+** Disclaimer
+
+ This is just a group of personal thoughts of mine that I have
+ placed here because I get asked this question a lot lately.
+ The views of this page are not a statement from my employer
+ (Ximian, Inc).
+
+ This is not part of Mono. We are not trying to deal with this
+ problem.
+
+ Nat Friedman (Ximian's co-founder) has his own ideas on how a
+ competing system to Passport could be designed, but I will let
+ <a href="http://www.nat.org/">him</a> post his own story.
+
+** Other Alternatives
+
+ Some people have pointed out <a
+ href="http://www.xns.org">XNS</a>
+
+Send comments to me: Miguel de Icaza (<a
+ href="mailto:miguel@ximian.com">miguel@ximian.com</a>)
+
diff --git a/doc/pending b/doc/pending
new file mode 100644
index 00000000000..e243a10dedf
--- /dev/null
+++ b/doc/pending
@@ -0,0 +1,14 @@
+** Microsoft and GNU and Linux.
+
+Q: Does this mean that Microsoft is better than Linux?
+
+A: Many of us are working on <a
+ href="http://www.gnu.org/philosophy/free-sw.html">free software<a>
+ and want to have an <a href="http://www.opensource.org">open
+ source</a> environment that we can change, modify, improve, learn
+ from, and share with others. Some of us also think that this will
+ lead on the long run to better software: more efficient, faster,
+ more robust and more.
+
+ We are willing to take good ideas from any source they come from.
+
diff --git a/doc/rationale b/doc/rationale
new file mode 100644
index 00000000000..1027d292286
--- /dev/null
+++ b/doc/rationale
@@ -0,0 +1,173 @@
+
+* The Mono Project
+
+** Background.
+
+ The GNOME project goal was to bring missing technologies to
+ Unix and make it competitive in the current market place for
+ desktop applications. We also realized early on that language
+ independence was important, and that is why GNOME APIs were
+ coded using a standard that allowed the APIs to be easily
+ wrapped for other languages. Our APIs are available to most
+ programming languages on Unix (Perl, Python, Scheme, C++,
+ Objective-C, Ada).
+
+ Later on we decided to use better methods for encapsulating
+ our APIs, and we started to use CORBA to define interfaces to
+ components. We complemented it with policy and a set of
+ standard GNOME interfaces for easily creating reusable,
+ language independent components, controls and compound
+ documents. This technology is known as <a
+ href="http://www.ximian.com/tech/bonobo.php3">Bonobo</a>.
+ Interfaces to Bonobo exist for C, Perl, Python, and
+ Java.
+
+ CORBA is good when you define coarse interfaces, and most
+ Bonobo interfaces are coarse. The only problem is that
+ Bonobo/CORBA interfaces are not good for small interfaces.
+ For example, an XML parsing Bonobo/CORBA component would be
+ inefficient compared to a C API.
+
+** Another explanation
+
+ I recently explained our motivations to Dave Winer, and he posted
+ it <a
+ href="http://scriptingnews.userland.com/stories/storyReader$1275">here</a>
+
+** Microsoft's .NET
+
+ The Microsoft .NET initiative is confusing because it is a
+ company wide effort that ranges from development tools to end
+ user applications. .NET is a branding formative that
+ has been applied to:
+
+ <ul>
+ * The .NET development platform, a new platform for
+ writing software.
+
+ * Web services.
+
+ * Microsoft Server Applications.
+
+ * New tools that use the new development platform.
+
+ * Hailstorm, the Passport centralized single-signon
+ system that is being integrated into Windows XP.
+
+ </ul>
+
+ Mono is an implementation of the .NET development platform.
+
+** The Common Language Infrastructure platform.
+
+ Microsoft has created a new development platform. The
+ highlights of this new development platform are:
+
+ <ul>
+ * A runtime environment that provides garbage
+ collection, threading and a virtual machine
+ specification (The Virtual Execution System, VES)
+
+ * A comprehensive class library.
+
+ * A new language, C#. Very similar to Java, C#
+ allows programmers to use all the features available
+ on the .NET runtime.
+
+ * A language specification that compilers can
+ follow if they want to generate classes and code
+ that can interoperate with other programming
+ languages (The Common Language Specification: CLS)
+ </ul>
+
+ The Common Language Infrastructure platform is similar to the
+ goals we had in GNOME of giving language independence to
+ programmers. It is more mature, documented, larger in scope,
+ and has a consistent design.
+
+ Any API that is written using a CLS provider language can be
+ used by any language that is a CLS consumer. Compilers
+ generate code in a format called Common Intermediate Language
+ (CIL) which is an intermediate representation of a compiled
+ program and is easy to compile to native code or compiled
+ using Just-in-Time (JIT) engines. The restrictions placed by
+ the runtime on the CIL byte codes ensures that it is possible
+ to do a good job at optimizing the code in a JIT compiler.
+
+ There is not really a lot of innovation in this platform: we
+ have seen all of these concepts before, and we are all
+ familiar with how these things work.
+
+ What makes the Common Language Infrastructure development
+ platform interesting is that it is a good mix of technologies
+ that have been nicely integrated.
+
+ The .NET development platform is essentially a new foundation
+ for program development that gives Microsoft a room to grow
+ for the coming years.
+
+** ECMA standards.
+
+ Microsoft has submitted the
+ specifications of C#, the runtime, the metadata and the
+ other various bits of the .NET development platform to the
+ <a href="http://www.ecma.ch">ECMA</a> for standarization.
+
+ You can get a copy of the specifications submitted to ECMA
+ from: <a href="http://www.dotnetexperts.com/ecma">http://www.dotnetexperts.com/ecma</a>
+
+** Mono: an Open Source Common Language Infrastructure implementation.
+
+ Ximian has begun work on Mono, a project that aims to bring
+ the Common Language Infrastructure platform to free systems.
+
+ When the GNU project was launched, they picked the best
+ operating system that was available out there, and they
+ began to clone it: Unix.
+
+ The .NET development platform is a very rich, powerful, and
+ well designed platform that would help improve the free
+ software development platform. Just like the GNU project
+ began to clone Unix sixteen years ago, we will be cloning the
+ .NET development platform because it is a great platform to
+ build on.
+
+** What makes up Mono?
+
+ There are various pieces that will make up Mono:
+
+ <ul>
+ * A C# compiler.
+
+ * The Virtual Execution System: that will have the
+ Just-in-Time compiler, garbage collector, loader,
+ threading engine.
+
+ A byte code interpreter will be provided for quickly
+ porting Mono to new systems and debugging the JIT
+ purposes, but it is not intended to be the ideal
+ execution environment.
+
+ * An implemenation of the .NET class library.
+
+ * Visual development tools.
+
+ * A CIL GCC frontend.
+ </ul>
+
+** Why use GNOME components?
+
+ GNOME is an umbrella project that consists of infrastructural
+ components (GUI toolkit, XML libraries, CORBA implementation,
+ printing architecture, imaging system), a desktop environment,
+ and productivity applications.
+
+ The GNOME infrastructural components can be used to quickly
+ implement various pieces of the class libraries without reinventing
+ the wheel, and since all those components are licensed under
+ the terms of the GNU LGPL it is a perfect fit.
+
+ Libart will be used to implement the Drawing.2D API; Gtk+ and
+ the GNOME libraries will be used to implement the WinForms
+ API and of course Glib and libxml will be used in various
+ places. \ No newline at end of file
diff --git a/doc/release-notes/mono-0.3 b/doc/release-notes/mono-0.3
new file mode 100644
index 00000000000..4976037b957
--- /dev/null
+++ b/doc/release-notes/mono-0.3
@@ -0,0 +1,46 @@
+To: mono-list@ximian.com, mono-announce-list@ximian.com
+Subject: July 12 snapshots.
+FCC: ~/Mail/outbox.txt
+X-Windows: Sometimes you fill a vacuum and it still sucks.
+--text follows this line--
+
+Hey!
+
+ July 12 snapshots of class libraries, the compiler and the mono
+runtime are available.
+
+New on this release:
+
+ * Runtime (module: mono)
+
+ The beginning of a simple interpreter that Paolo started
+ workign on (can run really simple .NET programs).
+
+ Disassembler copes with more elements of the binary format and
+ more tokens are decoded. Paolo is working now on moving some
+ of these to the metadata library.
+
+ More tables are dumped.
+
+ * Class libraries (module: mcs/class)
+
+ Many new more classes are in from Joe, Vladimir, Jeff, Sean
+ and yours truly.
+
+ Sean fixed the build process, and it is now possible to
+ compile with a single command the assemblies. We will be
+ revisiting this mechanism in the future to compile per-OS
+ assemblies (ie, Unix, Windows, MacOS, etc).
+
+ * Compiler (module mcs/mcs)
+
+ Not much done this week, just a few fixes here and there, and
+ more work to make it easy to compiler.
+
+ * Documentation (module: mono/doc)
+
+ All the changes to the web site are there for your browsing
+ pleasure. We still need to integrate the status system in
+ there.
+
+Miguel.
diff --git a/doc/release-notes/mono-0.4 b/doc/release-notes/mono-0.4
new file mode 100644
index 00000000000..1d7e1cea5f1
--- /dev/null
+++ b/doc/release-notes/mono-0.4
@@ -0,0 +1,43 @@
+To: mono-list@ximian.com
+Subject: Sunday snapshot available.
+Gcc: mail.2001-07
+--text follows this line--
+
+Hey guys,
+
+ I promise I will not be doing these so often once we have the CVS
+server up. In the meantime:
+
+ * MCS
+
+ Sean got the classes to compile in a single go. You
+ will need CygWin (www.cygwin.org) to compile though
+ (GNU make and stuff is required).
+
+ System.Xml.XmlReader contribution from Jason
+ (WOOHHOO!!). It also contains a nice test-suite for
+ his functions, and in his new code bit, his
+ implementation is faster than Microsoft's
+
+ We now ship `jay' as part of the distribution to allow
+ you to compile the compiler with the same `make'
+ command. Small fixes to the parser as well were
+ introduced.
+
+ * Mono 0.4
+
+ Paolo's interpreter supports call instructions and has
+ the test suite program that he posted about.
+
+
+ All documentation ships now in the mono-0.4.tar.gz
+
+Notes:
+
+ As usual, MCS is targeted to be compiled on a Windows machine
+ (you will need Cygwin).
+
+ Mono is targeted to be compiled on a Unix machine or a Windows
+ machine running Cygwin.
+
+Miguel. \ No newline at end of file
diff --git a/doc/resources b/doc/resources
new file mode 100644
index 00000000000..1e0a361b23e
--- /dev/null
+++ b/doc/resources
@@ -0,0 +1,121 @@
+
+* Resources
+
+ There are a number of resources available for those of you who
+ want to contribute to the Mono project. Here are a few links.
+
+ If you want to send suggestions for links, address them to <a
+ mailto="web-mono@ximian.com">web-mono@ximian.com</a>.
+
+** ECMA Documentation.
+
+ You can get the documentation for the ECMA specs from a number of sites:
+ <ul>
+ * <a href="http://msdn.microsoft.com/net/ecma">At MSDN</a>
+ * <a href="http://www.dotnetexperts.com">Dot Net Experts</a>
+ * <a href="http://developer.intel.com/software/idap/ecma">Intel</a>
+ * <a href="http://lightning.csse.monash.edu.au/.net/CLI">Monash University</a>
+ </ul>
+
+ These contain specifications for the assembler, the metadata,
+ byte codes supported by the CLI virtual machine, the C#
+ language and the core class libraries.
+
+ For details on the .NET class libraries, you can
+ visit the Microsoft's Developer Network:
+
+ <ul>
+ * <a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/cpref_start.asp">.NET Framework Class Library</a>
+ </ul>
+
+ You can also get this information if you install the Beta2
+ release of the .NET Framework.
+
+<a name="mailing">
+** Mailing Lists
+
+ There are a number of mailing lists for Mono
+
+ <ul>
+
+ * <b><a
+ href="http://mail.ximian.com/mailman/listinfo/mono-list">mono-list:</a></b>
+ The general Mono discussion list.
+ * <b><a
+ href="http://mail.ximian.com/mailman/listinfo/mono-announce-list">mono-announce-list:</a></b>
+ Announcements of Mono developments.
+ * <b><a
+ href="http://mail.ximian.com/mailman/listinfo/mono-gc-list">mono-gc-list:</a></b>
+ Discussion on the GC system of Mono.
+ * <b><a
+ href="http://mail.ximian.com/mailman/listinfo/mono-cvs-list">mono-cvs-list:</a></b>
+ Track the CVS activity of Mono on this mailing list. You can get <a href="http://www.go-mono.com/snapshots">daily snapshots</a> as well.
+ * <b><a
+ href="http://mail.ximian.com/mailman/listinfo/mono-docs-list">mono-docs-list:</a></b>
+ Discussion on the documentation of Mono.
+ * <b><a
+ href="http://discuss.develop.com/dotnet.html">Dotnet mailing
+ list at Develop.com:</a></b> The guys at Develop Mentor run
+ this general purpose mailing list.
+ </ul>
+
+** Discussion Groups.
+
+ <ul>
+
+ * <a href="http://www.oreillynet.com">O'Reilly
+ Network</a> has a <a
+ href="http://www.oreillynet.com/dotnet">section devoted to
+ .NET</a>
+ * <a
+ href="http://msdn.microsoft.com/newsgroups">MSDN</a> also
+ lists various newsgroups related to .NET</ul>
+ </ul>
+
+** Other .NET related projects
+
+ There are a number of related projects to Mono:
+
+ <ul>
+ * <a
+ href="http://www.icsharpcode.net/OpenSource/SD/default.asp">Sharp
+ Develop:</a> an IDE for the C# language written in C#.
+
+ * <a
+ href="http://janet-js.sourceforge.net/">Janet:</a>
+ an implemention of ECMAScript (the standarized
+ version of JavaScript) in C#
+
+ * <a
+ href="http://www.southern-storm.com.au/portable_net.html">Portable.NET:</a>
+ Another implementation of the CLI and C# compiler.
+
+ * <a href="http://nunit.sourceforge.net">NUnit:</a> A
+ testing framework for .NET classes.
+
+ * <a href="http://www.kaffe.org">Kaffe:</a> A popular
+ Free Software JIT engine for Java.
+
+ * <a href="http://www.intel.com/research/mrl/orp">ORP:</a> A research
+ JIT/VM/GC system from Intel.
+ </ul>
+
+** GNOME Documentation
+
+ Documnetation on GNOME, and the GNOME APIs is available from
+ the <a href="http://developer.gnome.org">developer</a> site at
+ GNOME:
+
+ <ul>
+ * <a href="http://developer.gnome.org/doc/API/">GNOME
+ API documentation</a>
+
+ * <a href="http://developer.gnome.org/doc/books">GNOME
+ Online books</a>
+
+ * <A
+ href="http://developer.gnome.org/arch/">Architecture Overview</a>
+ </ul>
+
+
+ \ No newline at end of file
diff --git a/doc/resources-pending b/doc/resources-pending
new file mode 100644
index 00000000000..fd9b9073d64
--- /dev/null
+++ b/doc/resources-pending
@@ -0,0 +1,30 @@
+** MacOS Documentation
+
+** Assembly Language Manuals online
+ Intel
+ MIPS
+ SPARC
+
+** Microsoft
+ msdn.microsoft.com/net
+ Research.microsoft.com
+
+** Related Technologies
+
+ <ul>
+
+ * The CLI allows people to create Web Services using the SOAP
+ protocol. SOAP is based on XML, XML schemas an the HTTP
+ protocol.
+ <ul>
+ * XML specification.
+ * XML Namespaces.
+ * XML Schemas.
+ * SOAP Specification.
+ </ul>
+ </ul>
+
+** Compiler Information
+ GCC
+ GCC Sample front-end tutorial
+
diff --git a/doc/roadmap b/doc/roadmap
new file mode 100644
index 00000000000..6cdfa1366a8
--- /dev/null
+++ b/doc/roadmap
@@ -0,0 +1,12 @@
+* Roadmap
+
+ We are working on the following three projects at Ximian:
+
+ The C# Compiler (mcs/mcs)
+
+ A .NET compatible Class Library (mcs/class)
+
+ The JIT/interpreter (mono)
+
+
+ \ No newline at end of file
diff --git a/doc/runtime b/doc/runtime
new file mode 100644
index 00000000000..7217abfa83f
--- /dev/null
+++ b/doc/runtime
@@ -0,0 +1,144 @@
+* The Mono runtime
+
+ The Mono runtime will implement the JIT engine (and a byte
+ code interpreter for quickly porting to new systems), the
+ class loader, the garbage collector, threading system and
+ metadata access libraries.
+
+ Currently the runtime has an image loader and metadata access
+ entry points. The runtime comes with a simple interpreter
+ that can execute very simple programs.
+
+** Executing MSIL/CIL images
+
+ The code will load an executable and map the references to
+ external assemblies to our own version of the assemblies on
+ GNU/Linux.
+
+ Our roadmap looks like this, this has been updated as of
+ <b>Jul 15, 2001</b>:
+
+ <ul>
+
+ * Milestone 1: <b> Done</b> Fully read and parse all CIL byte-codes
+ and metadata tokens (ie, a disassembler).
+
+ * Milestone 2: Complete an interpreter for CIL byte
+ codes. This interpreter can be used temporarly to
+ run CIL byte code on a system where no JIT is
+ available.
+
+ * Milestone 3: Define an <i>lburg</i>-like instruction
+ selector for the JITer for Intel. Although slower
+ at JITing than a streaming JITer, it generates
+ better code. The same grammar can later be used for
+ the stream jitter.
+
+ * Milestone 4: Implement JITer.
+
+ * Milestone 5: Port of the JITer to non IA32 systems.
+ </ul>
+
+ A setup similar to the Kaffe JIT engine can be used to
+ layout the code to support non-IA32 architectures. Our work
+ will be focused on getting a IA32 version running first.
+
+ The JIT engine should work on Linux and Win32, although you
+ will need to install the CygWin32 development tools to get a
+ Unix-like compilation environment.
+
+** JIT Engine (<b>updated, Jul 14th, 2001</b>)
+
+ We will be using a code-generator generator approach for our
+ JITer. Given the properties of CIL byte codes, we can take
+ full advantage of a real instruction selector for our code
+ generator.
+
+ There are a couple of books that deal with this technique: "A
+ Retargetable C Compiler" and "Advanced Compiler Design and
+ Implementation" are good references. You can also get a
+ technical description of <a
+ href="http://research.microsoft.com/copyright/accept.asp?path=http://www.research.microsoft.com/~drh/pubs/iburg.pdf&pub=ACM">lbrug</a>
+
+ Previously we had looked at a number of JIT engines and tools,
+ but they would not take full advantage of the CIL properties:
+
+ <ul>
+ * <a
+ href="http://www.intel.com/research/mrl/orp/">ORP</a>
+
+ * <a
+ href="http://www.gnu.org/software/lightning/">GNU
+ Lightning</a>
+
+ * <a href="http://www.eecs.harvard.edu/~nr/toolkit/">NJ Machine
+ Toolkit</a>.).
+
+ * VCODE.
+ </ul>
+
+** Garbage Collection
+
+ We have decided to implement a generational tracing garbage
+ collector, which is very similar to the one being used by
+ .NET. For an introduction to the garbage collection system
+ used by Microsoft's CLR implementation, you can read this book
+ on <a
+ href="http://www.amazon.com/exec/obidos/ASIN/0471941484/o/qid=992556433/sr=2-1/ref=aps_sr_b_1_1/103-5866388-0492603">Garbage
+ Collection.</a>
+
+ Another consideration is to use the same interface that ORP
+ uses to its Garbage Collection system and reuse that GC system
+ instead of rolling our own, as the ORP system is pretty advanced
+ and is independent of the rest of ORP.
+
+ Although using a conservative garbage collector like Bohem's
+ would work, all the type information is available at runtime,
+ so we can actually implement a better collector than a
+ conservative collector.
+
+ <ul>
+ * Garbage collection list and FAQ:<br>
+ <a href="http://www.iecc.com/gclist/">http://www.iecc.com/gclist/</a>
+
+ * "GC points in a Threaded Environment":<br>
+ <a href="http://research.sun.com/techrep/1998/abstract-70.html">
+ http://research.sun.com/techrep/1998/abstract-70.html</a>
+
+ * "A Generational Mostly-concurrent Garbage Collector":
+ <a href="http://research.sun.com/techrep/2000/abstract-88.html">
+ http://research.sun.com/techrep/2000/abstract-88.html</a>
+
+ * Details on The Microsoft .NET Garbage Collection Implementation:<br>
+ <a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnmag00/html/GCI.asp">http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnmag00/html/GCI.asp</a>
+ <a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnmag00/html/GCI2.asp">http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnmag00/html/GCI2.asp</a>
+ </ul>
+
+** Useful links
+
+ Paolo Molaro found a few interesting links:
+
+ <ul>
+ * On compilation of stack-based languages:<br>
+ <a href="http://www.complang.tuwien.ac.at/projects/rafts.html">
+ http://www.complang.tuwien.ac.at/projects/rafts.html</a>
+
+ * A paper on fast JIT compilation of a stack-based language:<br>
+ <a href="http://www.research.microsoft.com/~cwfraser/pldi99codegen.pdf">
+ http://www.research.microsoft.com/~cwfraser/pldi99codegen.pdf</a>
+
+ * Vmgen generates much of the code for efficient virtual machine (VM)
+ interpreters from simple descriptions of the VM instructions:<br>
+ <a href="http://www.complang.tuwien.ac.at/anton/vmgen/">
+ http://www.complang.tuwien.ac.at/anton/vmgen</a>
+ </ul>
+
+** PInvoke
+
+ PInvoke is the mechanism we are using to wrap Unix API calls
+ as well as talking to system libraries.
+
+ We hvae implemented PInvoke through libffi, but we are likely
+ going to roll our own system as the runtime matures, specially
+ as the interpreter is approaching completion, and we move into
+ the JITer.
diff --git a/doc/status b/doc/status
new file mode 100644
index 00000000000..d2e09c7e837
--- /dev/null
+++ b/doc/status
@@ -0,0 +1,38 @@
+* Project Status
+
+
+ Pieces of Mono that have been implemented:
+
+ <ul>
+ * C# compiler: The C# parser can now generate parse
+ trees. Next up: semantic analysis, compiler lever optimizations
+ and code generation.
+
+ * Metadata library: Can currently parse and load
+ information from .NET modules (executables and DLL
+ files).
+
+ Parsing of Exception tables is missing.
+
+ * Disassembler: Can disassemble .NET modules. Still
+ lacking exception handling as well as useful debugging
+ tools (hex dumping, token dumping).
+
+ * Class Libraries: You can check the current status in the
+ <a href="class-status.html">Class Status page</a>
+ </ul>
+
+ Tasks on the critical path:
+
+ <ul>
+ * Bytecode interpreter: (Paolo is working on this).
+
+ * Simple JIT: Not implemented yet (Miguel is
+ researching the code-generator generator)
+
+ * Garbage collection engine (Dick is working on this, his contact is <a
+ href="mailto:dick@ximian.com">dick@ximian.com</a>
+ </ul>
+
+ If you want to work on any task here, please mail <a
+ href="mailto:mono-list@ximian.com">mono-list@ximian.com</a>
diff --git a/doc/team b/doc/team
new file mode 100644
index 00000000000..eff7bc9d3d5
--- /dev/null
+++ b/doc/team
@@ -0,0 +1,2 @@
+* The MonoNet Team
+
diff --git a/doc/testing b/doc/testing
new file mode 100644
index 00000000000..febabf6550e
--- /dev/null
+++ b/doc/testing
@@ -0,0 +1,21 @@
+* Testing
+
+ All classes in Mono libraries should have comprehensive unit test
+ suites to go with them. Unit testing is a software engineering
+ methodology that makes it easier to build correct code. Every
+ method in every class should have a set of tests to verify
+ that they work correctly. Mono also needs a testing framework
+ to make it easy to write and run lots of tests.
+
+ Try <a href="http://nunit.sourceforge.net">NUnit</a>
+
+ Why do unit testing? It becomes simple to run automated tests
+ for the whole library. Unit tests are a safety net - you can
+ change part of the code and verify that you haven't broken
+ anything. Ideally, tests are written before the actual library
+ code itself. And every time a bug is discovered, a test should
+ be written to demonstrate the bug and its fix. Then, if
+ you ever reintroduce the bug, you will know immediately. For
+ more info, read <a
+ href="http://nunit.sourceforge.net/doc/testinfected/testing.html">
+ JUnit Test Infected: Programmers Love Writing Tests</a>.
diff --git a/doc/thanks b/doc/thanks
new file mode 100644
index 00000000000..5f2df36f9cd
--- /dev/null
+++ b/doc/thanks
@@ -0,0 +1,6 @@
+* Thanks
+
+ We would like to thank Tim O'Reilly, Brian Jepson and Nathan
+ Torkington for their help.
+
+ Dave Winer for provided interesting comments and a to read.
diff --git a/doc/todo b/doc/todo
new file mode 100644
index 00000000000..abae8cdfb40
--- /dev/null
+++ b/doc/todo
@@ -0,0 +1 @@
+Discuss with write new JIT \ No newline at end of file
diff --git a/doc/tools b/doc/tools
new file mode 100644
index 00000000000..eabef48bb88
--- /dev/null
+++ b/doc/tools
@@ -0,0 +1,67 @@
+* Tools
+
+ We need a number of tools to make people productive using a
+ Mono-based solution. Some of these tools can be developed on
+ Windows before Mono is fully finished.
+
+ All of these tools should be written using C#.
+
+ For the tools that are typically command line tools: Try to
+ write these as components that could load their input from
+ streams or collections of streams, and implement the command
+ line tools as wrappers around those classes.
+
+ For example, we will be making the C# compiler a component
+ that could be reused by applications that might have a use for
+ the various bits of the compiler (either to embed the
+ compiler, or reuse the code generator part of it).
+
+ This is important so that these components (compiler,
+ assembler, linker, etc) can be integrated later into the
+ visual development environment (hopefully with the help of the
+ SharpDevelop hackers).
+
+TODO=ilasm,IL Assembler
+** IL Assembler.
+
+ This assembler should basically take as input a file
+ containing IL bytecodes as specified in the `Partition II' of
+ the ECMA spec, and produce a binary file.
+
+TODO=al,Assembly Linker
+** Assembly Linker.
+
+ This tool is used to construct assemblies, which are basically
+ deployment units for CLI executables.
+
+TODO=debugger,Debugger
+** Debugger
+
+ We will need a debugging API to debug CLI applications and
+ then a debugger component that can be used in an IDE
+ environment.
+
+TODO=ide,Integrated Development Environment
+** Integrated Development Environment
+
+ There is already a project to create a C# development
+ environment: <a
+ href="http://www.icsharpcode.net/OpenSource/SD/default.asp">SharpDevelop</a>.
+ People should work with the SharpDevelop hackers to produce a
+ unified development environment.
+
+ Please work with the SharpDevelop hackers to build a good IDE.
+ We will work on creating an embedable compiler component and
+ an embeddable debugger component that can be used withing
+ SharpDevelop
+
+TODO=hbrowser,Help Browser
+** Help Browser
+
+ We need a good help browser that can be used to browse
+ documentation. Ideally this help browser can accept as input
+ XML Docbook input and an assorted set of file formats
+ (Microsoft Help, Unix manual pages, Unix Info pages)
+
+ Look at the GNOME DevHelp for a good set of ideas on how to
+ implement this. \ No newline at end of file
diff --git a/doc/web/.cvsignore b/doc/web/.cvsignore
new file mode 100644
index 00000000000..a023a6f9c7c
--- /dev/null
+++ b/doc/web/.cvsignore
@@ -0,0 +1,2 @@
+*.src
+*.html
diff --git a/doc/web/commands b/doc/web/commands
new file mode 100644
index 00000000000..4184a72fecb
--- /dev/null
+++ b/doc/web/commands
@@ -0,0 +1,17 @@
+0,Home,index.html,index.src
+1,FAQ,faq.html,faq.src
+0,Mono,rationale.html,rationale.src
+1,Runtime,runtime.html,runtime.src
+1,Classes,class-library.html,class-library.src
+2,Class Status,class-status.html,class-status.src
+1,C# Compiler,c-sharp.html,c-sharp.src
+1,Status,status.html,status.src
+0,Contributing,contributing.html,contributing.src
+1,Documentation,documentation.html,documentation.src
+1,Test Suite,testing.html,testing.src
+1,Tools,tools.html,tools.src
+0,Download,download.html,download.src
+0,Resources,resources.html,resources.src
+1,Ideas,ideas.html,ideas.src
+1,Passport,passport.html,passport.src
+0,Contact,contact.html,contact.src
diff --git a/doc/web/htmlify b/doc/web/htmlify
new file mode 100644
index 00000000000..a2b2706f16e
--- /dev/null
+++ b/doc/web/htmlify
@@ -0,0 +1,26 @@
+#!/usr/bin/perl
+$q = 1;
+
+while (<>){
+ chop;
+ if (/^\* (.*)$/){
+ print "<h1>$1</h1>\n";
+ } elsif (/^\*\* (.*)$/) {
+ print "<h2>$1</h2>\n";
+ } elsif (/^\*\*\* (.*)$/) {
+ print "<h3>$1</h3>\n";
+ } elsif (/^$/) {
+ print "<p>\n";
+ } elsif (/^\t\t\* (.*)$/) {
+ print "<li>$1\n";
+ } elsif (/^Q: (.*)$/){
+ print "<p><a name=\"q$q\"></a><b>Question $q:</b> $1\n";
+ $q++;
+ } elsif (/^A: (.*)$/){
+ print "$1\n";
+ } elsif (/^TODO=(.*),$/){
+ print "<a name=\"$1\">\n";
+ } else {
+ print "$_\n";
+ }
+}
diff --git a/doc/web/images/bgsquares.gif b/doc/web/images/bgsquares.gif
new file mode 100644
index 00000000000..864bcd44038
--- /dev/null
+++ b/doc/web/images/bgsquares.gif
Binary files differ
diff --git a/doc/web/images/bgsquares.png b/doc/web/images/bgsquares.png
new file mode 100644
index 00000000000..54de2ad1e6d
--- /dev/null
+++ b/doc/web/images/bgsquares.png
Binary files differ
diff --git a/doc/web/images/bgsquares.xcf.gz b/doc/web/images/bgsquares.xcf.gz
new file mode 100644
index 00000000000..200b5805615
--- /dev/null
+++ b/doc/web/images/bgsquares.xcf.gz
Binary files differ
diff --git a/doc/web/images/mono.gif b/doc/web/images/mono.gif
new file mode 100644
index 00000000000..298976a07b7
--- /dev/null
+++ b/doc/web/images/mono.gif
Binary files differ
diff --git a/doc/web/images/mono.png b/doc/web/images/mono.png
new file mode 100644
index 00000000000..a19e38acedd
--- /dev/null
+++ b/doc/web/images/mono.png
Binary files differ
diff --git a/doc/web/images/pixel.gif b/doc/web/images/pixel.gif
new file mode 100644
index 00000000000..a4f37d7e02e
--- /dev/null
+++ b/doc/web/images/pixel.gif
Binary files differ
diff --git a/doc/web/images/pixel.png b/doc/web/images/pixel.png
new file mode 100644
index 00000000000..d8f33a2a3e4
--- /dev/null
+++ b/doc/web/images/pixel.png
Binary files differ
diff --git a/doc/web/makefile b/doc/web/makefile
new file mode 100644
index 00000000000..1e549a40c3a
--- /dev/null
+++ b/doc/web/makefile
@@ -0,0 +1,39 @@
+SOURCES= \
+ ../contributing \
+ ../class-library \
+ ../class-status \
+ ../contact \
+ ../c-sharp \
+ ../documentation \
+ ../download \
+ ../faq \
+ ../gcc-frontend \
+ ../index \
+ ../ideas \
+ ../passport \
+ ../rationale \
+ ../resources \
+ ../roadmap \
+ ../runtime \
+ ../status \
+ ../testing \
+ ../tools
+
+all:
+ -mkdir site
+ for i in $(SOURCES); do \
+ perl htmlify $$i > `basename $$i`.src; \
+ done;
+
+ perl process.pl commands template.html.in .
+
+clean:
+ for i in $(SOURCES); do \
+ rm -f `basename $$i`.src `basename $$i`.html; \
+ done;
+
+push:
+ scp *.html www@www.ximian.com:/web/cvsmodules/mono
+
+push2:
+ scp *.html primates:public_html/xxx
diff --git a/doc/web/process.pl b/doc/web/process.pl
new file mode 100755
index 00000000000..157ae9bb08f
--- /dev/null
+++ b/doc/web/process.pl
@@ -0,0 +1,73 @@
+#!/usr/bin/perl
+#
+# Author:
+# Sean MacIsaac
+#
+
+use strict;
+
+my $full_expand = 1;
+my @template;
+my $n;
+
+if ($#ARGV != 2) {
+ print "process.pl command_file template_file directory_prefix\n";
+ exit ();
+}
+
+my $menu = "";
+
+open COMMANDS, $ARGV[0] || die "Can not open $ARGV[0]";
+while (<COMMANDS>) {
+ chop;
+ my @command = split /,/;
+ if ($command[0] != -1) {
+ $menu .= "\t\t";
+ if ($command[0] == 0){
+ $menu .= "<tr><td valign=\"top\" class=\"navi\"><a class=\"navi\"";
+ } else {
+ $menu .= "<tr><td valign=\"top\" class=\"subnavi\">&nbsp;&nbsp;&nbsp<a class=\"subnavi\"";
+ }
+ $menu .= "HREF=\"$command[2]\">$command[1]</A></td></tr>\n\n";
+ }
+}
+close COMMANDS;
+
+open TEMPLATE, $ARGV[1] || die "Can not open $ARGV[1]";
+while (<TEMPLATE>) {
+ push @template, $_;
+}
+close TEMPLATE;
+
+open COMMANDS, $ARGV[0] || die "Can not open $ARGV[0]";
+while (<COMMANDS>) {
+ chop;
+ my @command = split /,/;
+
+ $n = $ARGV[2] . "/" . $command[2];
+ open OUTPUT, ">" . $n || die "Can not create $n";
+
+ my $content = "";
+ open INPUT, $command[3] || die "Can not open $command[3]";
+ while (<INPUT>) {
+ $content .= $_;
+ }
+ close INPUT;
+
+ my $line;
+ my $temp;
+ my $tit;
+ my $title;
+
+ $tit = $command[1];
+ foreach $line (@template) {
+ $temp = $line;
+ $title = "$tit / Mono";
+ $temp =~ s/#TITLE#/$title/;
+ $temp =~ s/#CONTENT#/$content/;
+ $temp =~ s/#MENU#/$menu/;
+ print OUTPUT $temp;
+ }
+
+ close OUTPUT;
+}
diff --git a/doc/web/template.html.in b/doc/web/template.html.in
new file mode 100644
index 00000000000..7afdfca4a1b
--- /dev/null
+++ b/doc/web/template.html.in
@@ -0,0 +1,78 @@
+<html>
+<head>
+<title>#TITLE#</title>
+<style type="text/css">
+<!--
+ body { font-family: "trebuchet ms", lucida, verdana, helvetica;
+ background-image: url("images/bgsquares.gif");
+ background-attachment: fixed; }
+ body, td, table { font-family: "trebuchet ms", lucida, verdana, helvetica;
+ font-size: 12px; }
+
+ .navi { font-size: 14px; background: #444444; }
+ .subnavi { font-size: 12px; }
+ .footnote { font-size: 10px; color: #aaaaaa; }
+
+ a.navi { color: #ffffff; text-decoration: none; font-weight: bold; }
+ a.navi:visited { color: #cccccc; }
+ a.navi:hover { color: #ee9900; text-decoration: underline; }
+
+ a.subnavi { color: #ffffff; text-decoration: none; font-weight: bold; }
+ a.subnavi:visited { color: #cccccc; }
+ a.subnavi:hover { color: #ee9900; text-decoration: underline; }
+
+// -->
+</style>
+</head>
+<body bgcolor="#555555" text="#000000">
+
+<table cellpadding="0" cellspacing="0" border="0" width="100%">
+ <tr>
+ <td><img src="images/pixel.gif"></td><!-- left border -->
+ <td colspan="4">
+ <a href="/"><img src="images/mono.gif" border="0"></a></td>
+ <td><img src="images/pixel.gif"></td><!-- right border -->
+ </tr>
+ <tr>
+ <td><img src="images/pixel.gif" width="1" height="1"></td>
+ <td colspan="3" bgcolor="black"><img src="images/pixel.gif" height="2"></td>
+ <td bgcolor="black"><img src="images/pixel.gif" width="1"></td>
+ <td><img src="images/pixel.gif"></td>
+ </tr>
+ <tr>
+ <td width="100"><img src="images/pixel.gif"></td>
+ <td valign="top">
+ <table cellpadding="2" valign="top" cellspacing="0" border="0">
+ #MENU#
+ </table>
+ </td>
+ <td bgcolor="black" width="1"><img src="images/pixel.gif" width="1"></td>
+ <td bgcolor="white" align="left" width="80%" valign="top">
+ <table cellpadding="16">
+ <tr><td>
+ #CONTENT#
+ </td></tr>
+ </table>
+ </td>
+ <td bgcolor="black"><img src="images/pixel.gif" width="1"></td>
+ <td width="100"><img src="images/pixel.gif"></td>
+ </tr>
+ <tr>
+ <td colspan="2">
+ <img src="images/pixel.gif"></td>
+ <td colspan="2" bgcolor="black"><img src="images/pixel.gif" height="1"></td>
+ <td bgcolor="black"><img src="images/pixel.gif" width="1"></td>
+ <td><img src="images/pixel.gif"></td>
+ </tr>
+
+ <td colspan="2"></td>
+ <td colspan="2" align="center">
+ <a class="footnote" href="mailto: webmaster@go-mono.com">webmaster@go-mono.com</a>
+ </td>
+ <td colspan="2"></td>
+ </tr>
+</tr>
+</table>
+
+</body>
+</html>
diff --git a/libffi/.cvsignore b/libffi/.cvsignore
new file mode 100644
index 00000000000..187ae647aa1
--- /dev/null
+++ b/libffi/.cvsignore
@@ -0,0 +1,16 @@
+.deps
+aclocal.m4
+config.cache
+config.guess
+config.h
+config.h.in
+config.log
+config.status
+config.sub
+configure
+fficonfig.h
+fficonfig.h.in
+Makefile
+Makefile.in
+stamp-h
+stamp-h.in
diff --git a/libffi/ChangeLog b/libffi/ChangeLog
new file mode 100644
index 00000000000..bc6bae64957
--- /dev/null
+++ b/libffi/ChangeLog
@@ -0,0 +1,440 @@
+2001-08-16 Alex Graveley <alex@ximian.com>
+
+ * libffi/include/fficonfig.h: Remove as this is auto generated.
+
+ * Makefile.am: Only generate libffi.a.
+
+ * configure.in: replace A[CM]_PROG_LIBTOOL with AC_PROG_RANLIB.
+
+Sun Apr 22 15:50:08 2001 Anthony Green <green@redhat.com>
+
+ * include/ffi_common.h: Delete, after moving contents to...
+ * include/ffi_private.h: Subsume contents of ffi_common.h.
+ * include/Makefile.am (noinst_HEADERS): Remove ffi_common.h.
+ * include/Makefile.in: Rebuilt.
+ * arm/ffi.c, m68k/ffi.c, mips/ffi.c, powerpc/ffi.c, s390/ffi.c,
+ ia64/ffi.c: Include ffi_private.h, not ffi_common.h.
+ * alpha/ffi.c, sparc/ffi.c, x86/ffi.c: Don't include ffi_common.h.
+ * types.c, raw_api.c, java_raw_api.c, prep_cif.c: Don't include
+ ffi_common.h.
+ * debug.c: Include ffi_private.h instead of ffi_common.h.
+
+ * mips/ffi.c (calc_n32_struct_flags): Make static.
+ (FIX_ARGP): Remove call to debugging routine ffi_stop_here.
+
+ * mips/n32.S: Include ffi_private.h.
+ * mips/o32.S: Include ffi_private.h.
+
+Sun Apr 22 12:37:44 2001 Anthony Green <green@redhat.com>
+
+ * README: Update some comments.
+
+ * Makefile.am (SUBDIRS): Add include so ffi.h gets installed.
+ * Makefile.in: Rebuilt.
+
+ * include/ffi.h: Change ALPHA to __alpha__ and SPARC to __sparc__.
+ * types.c: Ditto.
+ * prep_cif.c (ffi_prep_cif): Ditto.
+
+ * alpha/ffi.c, alpha/osf.S, sparc/ffi.c, sparc/v8.S, sparc/v9.S:
+ Include ffi_private.h.
+
+ * include/ffi_private.h (FFI_TYPE_LAST): Define.
+
+Sun Apr 22 11:41:55 2001 Anthony Green <green@redhat.com>
+
+ * Revolutionary changes. Target independent ffi.h. dejagnu
+ testing infrastructure. Moved source files around. Configure no
+ longer depends on run tests.
+
+Sat Apr 14 20:49:46 2001 Anthony Green <green@cygnus.com>
+
+ * mips/ffi.c: Include mips/mips.h.
+ * mips/o32.S: Ditto.
+ * mips/n32.S: Ditto.
+ * mips/o32.s: Deleted.
+ * mips/n32.s: Deleted.
+
+Sat Apr 14 20:47:13 2001 Anthony Green <green@cygnus.com>
+
+ * mips/mips.h: Moved from include/ffi_mips.h.
+
+Sat Apr 14 20:09:05 2001 Anthony Green <green@cygnus.com>
+
+ * powerpc/asm.h: Remove rcs id.
+
+Sat Apr 14 15:04:08 2001 Anthony Green <green@cygnus.com>
+
+ * configure.in: Use AC_COMPILE_CHECK_SIZEOF and
+ AC_C_BIGENDIAN_CROSS.
+
+Sat Apr 14 15:02:53 2001 Anthony Green <green@cygnus.com>
+
+ * aclocal.m4: Rebuilt.
+ * acinclude.m4: New file. Add AC_COMPILE_CHECK_SIZEOF and
+ AC_C_BIGENDIAN_CROSS.
+
+2001-04-8 Neale Ferguson <Neale.Ferguson@softwareAG-usa.com>
+
+ * src/s390/ffi.c: New file.
+ * src/s390/sysv.S: New file.
+ * include/ffi.h: Add s390 bits.
+ * configure.in: Ditto.
+ * configure: Rebuild.
+
+2001-03-29 Bryce McKinlay <bryce@albatross.co.nz>
+
+ * configure.in: Use different syntax for subdirectory creation.
+ * configure: Rebuilt.
+
+2001-03-27 Jon Beniston <jon@beniston.com>
+
+ * configure.in: Added X86_WIN32 target (Win32, CygWin, MingW).
+ * configure: Rebuilt.
+ * Makefile.am: Added X86_WIN32 target support.
+ * Makefile.in: Rebuilt.
+
+ * include/ffi.h.in: Added X86_WIN32 target support.
+
+ * src/ffitest.c: Doesn't run structure tests for X86_WIN32 targets.
+ * src/types.c: Added X86_WIN32 target support.
+
+ * src/x86/win32.S: New file. Based on sysv.S, but with EH
+ stuff removed and made to work with CygWin's gas.
+
+2001-03-26 Bryce McKinlay <bryce@albatross.co.nz>
+
+ * configure.in: Make target subdirectory in build dir.
+ * Makefile.am: Override suffix based rules to specify correct output
+ subdirectory.
+ * Makefile.in: Rebuilt.
+ * configure: Rebuilt.
+
+2001-03-23 Kevin B Hendricks <khendricks@ivey.uwo.ca>
+
+ * src/powerpc/ppc_closure.S: New file.
+ * src/powerpc/ffi.c (ffi_prep_args): Fixed ABI compatibility bug
+ involving long long and register pairs.
+ (ffi_prep_closure): New function.
+ (flush_icache): Likewise.
+ (ffi_closure_helper_SYSV): Likewise.
+ * include/ffi.h.in (FFI_CLOSURES): Define on PPC.
+ (FFI_TRAMPOLINE_SIZE): Likewise.
+ (FFI_NATIVE_RAW_API): Likewise.
+ * Makefile.in: Rebuilt.
+ * Makefile.am (EXTRA_DIST): Added src/powerpc/ppc_closure.S.
+ (TARGET_SRC_POWERPC): Likewise.
+
+2001-03-19 Tom Tromey <tromey@redhat.com>
+
+ * Makefile.in: Rebuilt.
+ * Makefile.am (ffitest_LDFLAGS): New macro.
+
+2001-03-02 Nick Clifton <nickc@redhat.com>
+
+ * include/ffi.h.in: Remove RCS ident string.
+ * include/ffi_mips.h: Remove RCS ident string.
+ * src/debug.c: Remove RCS ident string.
+ * src/ffitest.c: Remove RCS ident string.
+ * src/prep_cif.c: Remove RCS ident string.
+ * src/types.c: Remove RCS ident string.
+ * src/alpha/ffi.c: Remove RCS ident string.
+ * src/alpha/osf.S: Remove RCS ident string.
+ * src/arm/ffi.c: Remove RCS ident string.
+ * src/arm/sysv.S: Remove RCS ident string.
+ * src/mips/ffi.c: Remove RCS ident string.
+ * src/mips/n32.S: Remove RCS ident string.
+ * src/mips/o32.S: Remove RCS ident string.
+ * src/sparc/ffi.c: Remove RCS ident string.
+ * src/sparc/v8.S: Remove RCS ident string.
+ * src/sparc/v9.S: Remove RCS ident string.
+ * src/x86/ffi.c: Remove RCS ident string.
+ * src/x86/sysv.S: Remove RCS ident string.
+
+2001-02-08 Joseph S. Myers <jsm28@cam.ac.uk>
+
+ * include/ffi.h.in: Change sourceware.cygnus.com references to
+ gcc.gnu.org.
+
+2000-12-09 Richard Henderson <rth@redhat.com>
+
+ * src/alpha/ffi.c (ffi_call): Simplify struct return test.
+ (ffi_closure_osf_inner): Index rather than increment avalue
+ and arg_types. Give ffi_closure_osf the raw return value type.
+ * src/alpha/osf.S (ffi_closure_osf): Handle return value type
+ promotion.
+
+2000-12-07 Richard Henderson <rth@redhat.com>
+
+ * src/raw_api.c (ffi_translate_args): Fix typo.
+ (ffi_prep_closure): Likewise.
+
+ * include/ffi.h.in [ALPHA]: Define FFI_CLOSURES and
+ FFI_TRAMPOLINE_SIZE.
+ * src/alpha/ffi.c (ffi_prep_cif_machdep): Adjust minimal
+ cif->bytes for new ffi_call_osf implementation.
+ (ffi_prep_args): Absorb into ...
+ (ffi_call): ... here. Do all stack allocation here and
+ avoid a callback function.
+ (ffi_prep_closure, ffi_closure_osf_inner): New.
+ * src/alpha/osf.S (ffi_call_osf): Reimplement with no callback.
+ (ffi_closure_osf): New.
+
+2000-09-10 Alexandre Oliva <aoliva@redhat.com>
+
+ * config.guess, config.sub, install-sh: Removed.
+ * ltconfig, ltmain.sh, missing, mkinstalldirs: Likewise.
+ * Makefile.in: Rebuilt.
+
+ * acinclude.m4: Include libtool macros from the top level.
+ * aclocal.m4, configure: Rebuilt.
+
+2000-08-22 Alexandre Oliva <aoliva@redhat.com>
+
+ * configure.in [i*86-*-freebsd*] (TARGET, TARGETDIR): Set.
+ * configure: Rebuilt.
+
+2000-05-11 Scott Bambrough <scottb@netwinder.org>
+
+ * libffi/src/arm/sysv.S (ffi_call_SYSV): Doubles are not saved to
+ memory correctly. Use conditional instructions, not branches where
+ possible.
+
+2000-05-04 Tom Tromey <tromey@cygnus.com>
+
+ * configure: Rebuilt.
+ * configure.in: Match `arm*-*-linux-*'.
+ From Chris Dornan <cdornan@arm.com>.
+
+2000-04-28 Jakub Jelinek <jakub@redhat.com>
+
+ * Makefile.am (SUBDIRS): Define.
+ (AM_MAKEFLAGS): Likewise.
+ (Multilib support.): Add section.
+ * Makefile.in: Rebuilt.
+ * ltconfig (extra_compiler_flags, extra_compiler_flags_value):
+ New variables. Set for gcc using -print-multi-lib. Export them
+ to libtool.
+ (sparc64-*-linux-gnu*): Use libsuff 64 for search paths.
+ * ltmain.sh (B|b|V): Don't throw away gcc's -B, -b and -V options
+ for -shared links.
+ (extra_compiler_flags_value, extra_compiler_flags): Check these
+ for extra compiler options which need to be passed down in
+ compiler_flags.
+
+2000-04-16 Anthony Green <green@redhat.com>
+
+ * README: Credit updates. Update supported platorms.
+
+ * include/ffi.h.in: Important size fixes from William Knottenblet
+ (wjk@doc.ic.ac.uk).
+
+2000-04-16 Anthony Green <green@redhat.com>
+
+ * configure: Rebuilt.
+ * configure.in: Change i*86-pc-linux* to i*86-*-linux*.
+
+2000-04-14 Jakub Jelinek <jakub@redhat.com>
+
+ * include/ffi.h.in (SPARC64): Define for 64bit SPARC builds.
+ Set SPARC FFI_DEFAULT_ABI based on SPARC64 define.
+ * src/sparc/ffi.c (ffi_prep_args_v8): Renamed from ffi_prep_args.
+ Replace all void * sizeofs with sizeof(int).
+ Only compare type with FFI_TYPE_LONGDOUBLE if LONGDOUBLE is
+ different than DOUBLE.
+ Remove FFI_TYPE_SINT32 and FFI_TYPE_UINT32 cases (handled elsewhere).
+ (ffi_prep_args_v9): New function.
+ (ffi_prep_cif_machdep): Handle V9 ABI and long long on V8.
+ (ffi_V9_return_struct): New function.
+ (ffi_call): Handle FFI_V9 ABI from 64bit code and FFI_V8 ABI from
+ 32bit code (not yet cross-arch calls).
+ * src/sparc/v8.S: Add struct return delay nop.
+ Handle long long.
+ * src/sparc/v9.S: New file.
+ * src/prep_cif.c (ffi_prep_cif): Return structure pointer
+ is used on sparc64 only for structures larger than 32 bytes.
+ Pass by reference for structures is done for structure arguments
+ larger than 16 bytes.
+ * src/ffitest.c (main): Use 64bit rint on sparc64.
+ Run long long tests on sparc.
+ * src/types.c (FFI_TYPE_POINTER): Pointer is 64bit on alpha and
+ sparc64.
+ (FFI_TYPE_LONGDOUBLE): long double is 128 bit aligned to 128 bits
+ on sparc64.
+ * configure.in (sparc-*-linux*): New supported target.
+ (sparc64-*-linux*): Likewise.
+ * configure: Rebuilt.
+ * Makefile.am: Add v9.S to SPARC files.
+ * Makefile.in: Likewise.
+ (LINK): Surround $(CCLD) into double quotes, so that multilib
+ compiles work correctly.
+
+2000-04-04 Alexandre Petit-Bianco <apbianco@cygnus.com>
+
+ * configure: Rebuilt.
+
+ * configure.in: (i*86-*-solaris*): New libffi target. Patch
+ proposed by Bryce McKinlay.
+
+2000-03-20 Tom Tromey <tromey@cygnus.com>
+
+ * Makefile.in: Hand edit for java_raw_api.lo.
+
+2000-03-08 Bryce McKinlay <bryce@albatross.co.nz>
+
+ * config.guess, config.sub: Update from the gcc tree.
+ Fix for PR libgcj/168.
+
+2000-03-03 Tom Tromey <tromey@cygnus.com>
+
+ * Makefile.in: Fixed ia64 by hand.
+
+ * configure: Rebuilt.
+ * configure.in (--enable-multilib): New option.
+ (libffi_basedir): New subst.
+ (AC_OUTPUT): Added multilib code.
+
+2000-03-02 Tom Tromey <tromey@cygnus.com>
+
+ * Makefile.in: Rebuilt.
+ * Makefile.am (TARGET_SRC_IA64): Use `ia64', not `alpha', as
+ directory name.
+
+2000-02-25 Hans Boehm <boehm@acm.org>
+
+ * src/ia64/ffi.c, src/ia64/ia64_flags.h, src/ia64/unix.S: New
+ files.
+ * src/raw_api.c (ffi_translate_args): Fixed typo in argument
+ list.
+ (ffi_prep_raw_closure): Use ffi_translate_args, not
+ ffi_closure_translate.
+ * src/java_raw_api.c: New file.
+ * src/ffitest.c (closure_test_fn): New function.
+ (main): Define `rint' as long long on IA64. Added new test when
+ FFI_CLOSURES is defined.
+ * include/ffi.h.in (ALIGN): Use size_t, not unsigned.
+ (ffi_abi): Recognize IA64.
+ (ffi_raw): Added `flt' field.
+ Added "Java raw API" code.
+ * configure.in: Recognize ia64.
+ * Makefile.am (TARGET_SRC_IA64): New macro.
+ (libffi_la_common_SOURCES): Added java_raw_api.c.
+ (libffi_la_SOURCES): Define in IA64 case.
+
+2000-01-04 Tom Tromey <tromey@cygnus.com>
+
+ * Makefile.in: Rebuilt with newer automake.
+
+1999-12-31 Tom Tromey <tromey@cygnus.com>
+
+ * Makefile.am (INCLUDES): Added -I$(top_srcdir)/src.
+
+1999-09-01 Tom Tromey <tromey@cygnus.com>
+
+ * include/ffi.h.in: Removed PACKAGE and VERSION defines and
+ undefs.
+ * fficonfig.h.in: Rebuilt.
+ * configure: Rebuilt.
+ * configure.in: Pass 3rd argument to AM_INIT_AUTOMAKE.
+ Use AM_PROG_LIBTOOL (automake 1.4 compatibility).
+ * acconfig.h: Don't #undef PACKAGE or VERSION.
+
+1999-08-09 Anthony Green <green@cygnus.com>
+
+ * include/ffi.h.in: Try to work around messy header problem
+ with PACKAGE and VERSION.
+
+ * configure: Rebuilt.
+ * configure.in: Change version to 2.00-beta.
+
+ * fficonfig.h.in: Rebuilt.
+ * acconfig.h (FFI_NO_STRUCTS, FFI_NO_RAW_API): Define.
+
+ * src/x86/ffi.c (ffi_raw_call): Rename.
+
+Mon Aug 9 18:33:38 1999 Rainer Orth <ro@TechFak.Uni-Bielefeld.DE>
+
+ * include/Makefile.in: Rebuilt.
+ * Makefile.in: Rebuilt
+ * Makefile.am (toolexeclibdir): Add $(MULTISUBDIR) even for native
+ builds.
+ Use USE_LIBDIR.
+
+ * configure: Rebuilt.
+ * configure.in (USE_LIBDIR): Define for native builds.
+ Use lowercase in configure --help explanations.
+
+1999-08-08 Anthony Green <green@cygnus.com>
+
+ * include/ffi.h.in (FFI_FN): Remove `...'.
+
+1999-08-08 Anthony Green <green@cygnus.com>
+
+ * Makefile.in: Rebuilt.
+ * Makefile.am (AM_CFLAGS): Compile with -fexceptions.
+
+ * src/x86/sysv.S: Add exception handling metadata.
+
+1999-08-02 Kresten Krab Thorup <krab@dominiq.is.s.u-tokyo.ac.jp>
+
+ * src/x86/ffi.c (ffi_closure_SYSV): New function.
+ (ffi_prep_incoming_args_SYSV): Ditto.
+ (ffi_prep_closure): Ditto.
+ (ffi_closure_raw_SYSV): Ditto.
+ (ffi_prep_raw_closure): More ditto.
+ (ffi_call_raw): Final ditto.
+
+ * include/ffi.h.in: Add definitions for closure and raw API.
+
+ * src/x86/ffi.c (ffi_prep_cif_machdep): Added case for
+ FFI_TYPE_UINT64.
+
+ * Makefile.am (libffi_la_common_SOURCES): Added raw_api.c
+
+ * src/raw_api.c: New file.
+
+ * include/ffi.h.in (ffi_raw): New type.
+ (UINT_ARG, SINT_ARG): New defines.
+ (ffi_closure, ffi_raw_closure): New types.
+ (ffi_prep_closure, ffi_prep_raw_closure): New declarations.
+
+ * configure.in: Add check for endianness and sizeof void*.
+
+ * src/x86/sysv.S (ffi_call_SYSV): Call fixup routine via argument,
+ instead of directly.
+
+ * configure: Rebuilt.
+
+Thu Jul 8 14:28:42 1999 Anthony Green <green@cygnus.com>
+
+ * configure.in: Add x86 and powerpc BeOS configurations.
+ From Makoto Kato <m_kato@ga2.so-net.ne.jp>.
+
+1999-05-09 Anthony Green <green@cygnus.com>
+
+ * configure.in: Add warning about this being beta code.
+ Remove src/Makefile.am from the picture.
+ * configure: Rebuilt.
+
+ * Makefile.am: Move logic from src/Makefile.am. Add changes
+ to support libffi as a target library.
+ * Makefile.in: Rebuilt.
+
+ * aclocal.m4, config.guess, config.sub, ltconfig, ltmain.sh:
+ Upgraded to new autoconf, automake, libtool.
+
+ * README: Tweaks.
+
+ * LICENSE: Update copyright date.
+
+ * src/Makefile.am, src/Makefile.in: Removed.
+
+1998-11-29 Anthony Green <green@cygnus.com>
+
+ * include/ChangeLog: Removed.
+ * src/ChangeLog: Removed.
+ * src/mips/ChangeLog: Removed.
+ * src/sparc/ChangeLog: Remboved.
+ * src/x86/ChangeLog: Removed.
+
+ * ChangeLog.v1: Created.
diff --git a/libffi/ChangeLog.v1 b/libffi/ChangeLog.v1
new file mode 100644
index 00000000000..369820cbdb0
--- /dev/null
+++ b/libffi/ChangeLog.v1
@@ -0,0 +1,764 @@
+The libffi version 1 ChangeLog archive.
+
+Version 1 of libffi had per-directory ChangeLogs. Current and future
+versions have a single ChangeLog file in the root directory. The
+version 1 ChangeLogs have all been concatonated into this file for
+future reference only.
+
+--- libffi ----------------------------------------------------------------
+
+Mon Oct 5 02:17:50 1998 Anthony Green <green@cygnus.com>
+
+ * configure.in: Boosted rev.
+ * configure, Makefile.in, aclocal.m4: Rebuilt.
+ * README: Boosted rev and updated release notes.
+
+Mon Oct 5 01:03:03 1998 Anthony Green <green@cygnus.com>
+
+ * configure.in: Boosted rev.
+ * configure, Makefile.in, aclocal.m4: Rebuilt.
+ * README: Boosted rev and updated release notes.
+
+1998-07-25 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ * m68k/ffi.c (ffi_prep_cif_machdep): Use bitmask for cif->flags.
+ Correctly handle small structures.
+ (ffi_prep_args): Also handle small structures.
+ (ffi_call): Pass size of return type to ffi_call_SYSV.
+ * m68k/sysv.S: Adjust for above changes. Correctly align small
+ structures in the return value.
+
+ * types.c (uint64, sint64) [M68K]: Change alignment to 4.
+
+Fri Apr 17 17:26:58 1998 Anthony Green <green@hoser.cygnus.com>
+
+ * configure.in: Boosted rev.
+ * configure,Makefile.in,aclocal.m4: Rebuilt.
+ * README: Boosted rev and added release notes.
+
+Sun Feb 22 00:50:41 1998 Geoff Keating <geoffk@ozemail.com.au>
+
+ * configure.in: Add PowerPC config bits.
+
+1998-02-14 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ * configure.in: Add m68k config bits. Change AC_CANONICAL_SYSTEM
+ to AC_CANONICAL_HOST, this is not a compiler. Use $host instead
+ of $target. Remove AC_CHECK_SIZEOF(char), we already know the
+ result. Fix argument of AC_ARG_ENABLE.
+ * configure, fficonfig.h.in: Rebuilt.
+
+Tue Feb 10 20:53:40 1998 Richard Henderson <rth@cygnus.com>
+
+ * configure.in: Add Alpha config bits.
+
+Tue May 13 13:39:20 1997 Anthony Green <green@hoser.cygnus.com>
+
+ * README: Updated dates and reworded Irix comments.
+
+ * configure.in: Removed AC_PROG_RANLIB.
+
+ * Makefile.in, aclocal.m4, config.guess, config.sub, configure,
+ ltmain.sh, */Makefile.in: libtoolized again and rebuilt with
+ automake and autoconf.
+
+Sat May 10 18:44:50 1997 Tom Tromey <tromey@cygnus.com>
+
+ * configure, aclocal.m4: Rebuilt.
+ * configure.in: Don't compute EXTRADIST; now handled in
+ src/Makefile.in. Removed macros implied by AM_INIT_AUTOMAKE.
+ Don't run AM_MAINTAINER_MODE.
+
+Thu May 8 14:34:05 1997 Anthony Green <green@hoser.cygnus.com>
+
+ * missing, ltmain.sh, ltconfig.sh: Created. These are new files
+ required by automake and libtool.
+
+ * README: Boosted rev to 1.14. Added notes.
+
+ * acconfig.h: Moved PACKAGE and VERSION for new automake.
+
+ * configure.in: Changes for libtool.
+
+ * Makefile.am (check): make test now make check. Uses libtool now.
+
+ * Makefile.in, configure.in, aclocal.h, fficonfig.h.in: Rebuilt.
+
+Thu May 1 16:27:07 1997 Anthony Green <green@hoser.cygnus.com>
+
+ * missing: Added file required by new automake.
+
+Tue Nov 26 14:10:42 1996 Anthony Green <green@csk3.cygnus.com>
+
+ * acconfig.h: Added USING_PURIFY flag. This is defined when
+ --enable-purify-safety was used at configure time.
+
+ * configure.in (allsources): Added --enable-purify-safety switch.
+ (VERSION): Boosted rev to 1.13.
+ * configure: Rebuilt.
+
+Fri Nov 22 06:46:12 1996 Anthony Green <green@rtl.cygnus.com>
+
+ * configure.in (VERSION): Boosted rev to 1.12.
+ Removed special CFLAGS hack for gcc.
+ * configure: Rebuilt.
+
+ * README: Boosted rev to 1.12. Added notes.
+
+ * Many files: Cygnus Support changed to Cygnus Solutions.
+
+Wed Oct 30 11:15:25 1996 Anthony Green <green@rtl.cygnus.com>
+
+ * configure.in (VERSION): Boosted rev to 1.11.
+ * configure: Rebuilt.
+
+ * README: Boosted rev to 1.11. Added notes about GNU make.
+
+Tue Oct 29 12:25:12 1996 Anthony Green <green@rtl.cygnus.com>
+
+ * configure.in: Fixed -Wall trick.
+ (VERSION): Boosted rev.
+ * configure: Rebuilt
+
+ * acconfig.h: Needed for --enable-debug configure switch.
+
+ * README: Boosted rev to 1.09. Added more notes on building
+ libffi, and LCLint.
+
+ * configure.in: Added --enable-debug switch. Boosted rev to
+ 1.09.
+ * configure: Rebuilt
+
+Tue Oct 15 13:11:28 1996 Anthony Green <green@hoser.cygnus.com>
+
+ * configure.in (VERSION): Boosted rev to 1.08
+ * configure: Rebuilt.
+
+ * README: Added n32 bug fix notes.
+
+ * Makefile.am: Added "make lint" production.
+ * Makefile.in: Rebuilt.
+
+Mon Oct 14 10:54:46 1996 Anthony Green <green@rtl.cygnus.com>
+
+ * README: Added web page reference.
+
+ * configure.in, README: Boosted rev to 1.05
+ * configure: Rebuilt.
+
+ * README: Fixed n32 sample code.
+
+Fri Oct 11 17:09:28 1996 Anthony Green <green@rtl.cygnus.com>
+
+ * README: Added sparc notes.
+
+ * configure.in, README: Boosted rev to 1.04.
+ * configure: Rebuilt.
+
+Thu Oct 10 10:31:03 1996 Anthony Green <green@rtl.cygnus.com>
+
+ * configure.in, README: Boosted rev to 1.03.
+ * configure: Rebuilt.
+
+ * README: Added struct notes.
+
+ * Makefile.am (EXTRA_DIST): Added LICENSE to distribution.
+ * Makefile.in: Rebuilt.
+
+ * README: Removed Linux section. No special notes now
+ because aggregates arg/return types work.
+
+Wed Oct 9 16:16:42 1996 Anthony Green <green@rtl.cygnus.com>
+
+ * README, configure.in (VERSION): Boosted rev to 1.02
+ * configure: Rebuilt.
+
+Tue Oct 8 11:56:33 1996 Anthony Green <green@rtl.cygnus.com>
+
+ * README (NOTE): Added n32 notes.
+
+ * Makefile.am: Added test production.
+ * Makefile: Rebuilt
+
+ * README: spell checked!
+
+ * configure.in (VERSION): Boosted rev to 1.01
+ * configure: Rebuilt.
+
+Mon Oct 7 15:50:22 1996 Anthony Green <green@rtl.cygnus.com>
+
+ * configure.in: Added nasty bit to support SGI tools.
+ * configure: Rebuilt.
+
+ * README: Added SGI notes. Added note about automake bug.
+
+Mon Oct 7 11:00:28 1996 Anthony Green <green@hoser.cygnus.com>
+
+ * README: Rewrote intro, and fixed examples.
+
+Fri Oct 4 10:19:55 1996 Anthony Green <green@hoser.cygnus.com>
+
+ * configure.in: -D$TARGET is no longer used as a compiler switch.
+ It is now inserted into ffi.h at configure time.
+ * configure: Rebuilt.
+
+ * FFI_ABI and FFI_STATUS are now ffi_abi and ffi_status.
+
+Thu Oct 3 13:47:34 1996 Anthony Green <green@hoser.cygnus.com>
+
+ * README, LICENSE: Created. Wrote some docs.
+
+ * configure.in: Don't barf on i586-unknown-linuxaout.
+ Added EXTRADIST code for "make dist".
+ * configure: Rebuilt.
+
+ * */Makefile.in: Rebuilt with patched automake.
+
+Tue Oct 1 17:12:25 1996 Anthony Green <green@rtl.cygnus.com>
+
+ * Makefile.am, aclocal.m4, config.guess, config.sub,
+ configure.in, fficonfig.h.in, install-sh, mkinstalldirs,
+ stamp-h.in: Created
+ * Makefile.in, configure: Generated
+
+--- libffi/include --------------------------------------------------------
+
+Tue Feb 24 13:09:36 1998 Anthony Green <green@gerbil.cygnus.com>
+
+ * ffi_mips.h: Updated FFI_TYPE_STRUCT_* values based on
+ ffi.h.in changes. This is a work-around for SGI's "simple"
+ assembler.
+
+Sun Feb 22 00:51:55 1998 Geoff Keating <geoffk@ozemail.com.au>
+
+ * ffi.h.in: PowerPC support.
+
+1998-02-14 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ * ffi.h.in: Add m68k support.
+ (FFI_TYPE_LONGDOUBLE): Make it a separate value.
+
+Tue Feb 10 20:55:16 1998 Richard Henderson <rth@cygnus.com>
+
+ * ffi.h.in (SIZEOF_ARG): Use a pointer type by default.
+
+ * ffi.h.in: Alpha support.
+
+Fri Nov 22 06:48:45 1996 Anthony Green <green@rtl.cygnus.com>
+
+ * ffi.h.in, ffi_common.h: Cygnus Support -> Cygnus Solutions.
+
+Wed Nov 20 22:31:01 1996 Anthony Green <green@hoser.cygnus.com>
+
+ * ffi.h.in: Added ffi_type_void definition.
+
+Tue Oct 29 12:22:40 1996 Anthony Green <green@rtl.cygnus.com>
+
+ * Makefile.am (hack_DATA): Always install ffi_mips.h.
+
+ * ffi.h.in: Removed FFI_DEBUG. It's now in the correct
+ place (acconfig.h).
+ Added #include <stddef.h> for size_t definition.
+
+Tue Oct 15 17:23:35 1996 Anthony Green <green@hoser.cygnus.com>
+
+ * ffi.h.in, ffi_common.h, ffi_mips.h: More clean up.
+ Commented out #define of FFI_DEBUG.
+
+Tue Oct 15 13:01:06 1996 Anthony Green <green@rtl.cygnus.com>
+
+ * ffi_common.h: Added bool definition.
+
+ * ffi.h.in, ffi_common.h: Clean up based on LCLint output.
+ Added funny /*@...@*/ comments to annotate source.
+
+Mon Oct 14 12:29:23 1996 Anthony Green <green@rtl.cygnus.com>
+
+ * ffi.h.in: Interface changes based on feedback from Jim
+ Blandy.
+
+Fri Oct 11 16:49:35 1996 Anthony Green <green@rtl.cygnus.com>
+
+ * ffi.h.in: Small change for sparc support.
+
+Thu Oct 10 14:53:37 1996 Anthony Green <green@rtl.cygnus.com>
+
+ * ffi_mips.h: Added FFI_TYPE_STRUCT_* definitions for
+ special structure return types.
+
+Wed Oct 9 13:55:57 1996 Anthony Green <green@rtl.cygnus.com>
+
+ * ffi.h.in: Added SIZEOF_ARG definition for X86
+
+Tue Oct 8 11:40:36 1996 Anthony Green <green@rtl.cygnus.com>
+
+ * ffi.h.in (FFI_FN): Added macro for eliminating compiler warnings.
+ Use it to case your function pointers to the proper type.
+
+ * ffi_mips.h (SIZEOF_ARG): Added magic to fix type promotion bug.
+
+ * Makefile.am (EXTRA_DIST): Added ffi_mips.h to EXTRA_DIST.
+ * Makefile: Rebuilt.
+
+ * ffi_mips.h: Created. Moved all common mips definitions here.
+
+Mon Oct 7 10:58:12 1996 Anthony Green <green@hoser.cygnus.com>
+
+ * ffi.h.in: The SGI assember is very picky about parens. Redefined
+ some macros to avoid problems.
+
+ * ffi.h.in: Added FFI_DEFAULT_ABI definitions. Also added
+ externs for pointer, and 64bit integral ffi_types.
+
+Fri Oct 4 09:51:37 1996 Anthony Green <green@hoser.cygnus.com>
+
+ * ffi.h.in: Added FFI_ABI member to ffi_cif and changed
+ function prototypes accordingly.
+ Added #define @TARGET@. Now programs including ffi.h don't
+ have to specify this themselves.
+
+Thu Oct 3 15:36:44 1996 Anthony Green <green@hoser.cygnus.com>
+
+ * ffi.h.in: Changed ffi_prep_cif's values from void* to void**
+
+ * Makefile.am (EXTRA_DIST): Added EXTRA_DIST for "make dist"
+ to work.
+ * Makefile.in: Regenerated.
+
+Wed Oct 2 10:16:59 1996 Anthony Green <green@hoser.cygnus.com>
+
+ * Makefile.am: Created
+ * Makefile.in: Generated
+
+ * ffi_common.h: Added rcsid comment
+
+Tue Oct 1 17:13:51 1996 Anthony Green <green@rtl.cygnus.com>
+
+ * ffi.h.in, ffi_common.h: Created
+
+--- libffi/src ------------------------------------------------------------
+
+Mon Oct 5 02:17:50 1998 Anthony Green <green@cygnus.com>
+
+ * arm/ffi.c, arm/sysv.S: Created.
+
+ * Makefile.am: Added arm files.
+ * Makefile.in: Rebuilt.
+
+Mon Oct 5 01:41:38 1998 Anthony Green <green@rtl.cygnus.com>
+
+ * Makefile.am (libffi_la_LDFLAGS): Incremented revision.
+
+Sun Oct 4 16:27:17 1998 Anthony Green <green@cygnus.com>
+
+ * alpha/osf.S (ffi_call_osf): Patch for DU assembler.
+
+ * ffitest.c (main): long long and long double return values work
+ for x86.
+
+Fri Apr 17 11:50:58 1998 Anthony Green <green@hoser.cygnus.com>
+
+ * Makefile.in: Rebuilt.
+
+ * ffitest.c (main): Floating point tests not executed for systems
+ with broken lond double (SunOS 4 w/ GCC).
+
+ * types.c: Fixed x86 alignment info for long long types.
+
+Thu Apr 16 07:15:28 1998 Anthony Green <green@ada.cygnus.com>
+
+ * ffitest.c: Added more notes about GCC bugs under Irix 6.
+
+Wed Apr 15 08:42:22 1998 Anthony Green <green@hoser.cygnus.com>
+
+ * ffitest.c (struct5): New test function.
+ (main): New test with struct5.
+
+Thu Mar 5 10:48:11 1998 Anthony Green <green@tootie.to.cygnus.com>
+
+ * prep_cif.c (initialize_aggregate): Fix assertion for
+ nested structures.
+
+Tue Feb 24 16:33:41 1998 Anthony Green <green@hoser.cygnus.com>
+
+ * prep_cif.c (ffi_prep_cif): Added long double support for sparc.
+
+Sun Feb 22 00:52:18 1998 Geoff Keating <geoffk@ozemail.com.au>
+
+ * powerpc/asm.h: New file.
+ * powerpc/ffi.c: New file.
+ * powerpc/sysv.S: New file.
+ * Makefile.am: PowerPC port.
+ * ffitest.c (main): Allow all tests to run even in presence of gcc
+ bug on PowerPC.
+
+1998-02-17 Anthony Green <green@hoser.cygnus.com>
+
+ * mips/ffi.c: Fixed comment typo.
+
+ * x86/ffi.c (ffi_prep_cif_machdep), x86/sysv.S (retfloat):
+ Fixed x86 long double return handling.
+
+ * types.c: Fixed x86 long double alignment info.
+
+1998-02-14 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
+
+ * types.c: Add m68k support.
+
+ * ffitest.c (floating): Add long double parameter.
+ (return_ll, ldblit): New functions to test long long and long
+ double return value.
+ (main): Fix type error in assignment of ts[1-4]_type.elements.
+ Add tests for long long and long double arguments and return
+ values.
+
+ * prep_cif.c (ffi_prep_cif) [M68K]: Don't allocate argument for
+ struct value pointer.
+
+ * m68k/ffi.c, m68k/sysv.S: New files.
+ * Makefile.am: Add bits for m68k port. Add kludge to work around
+ automake deficiency.
+ (test): Don't require "." in $PATH.
+ * Makefile.in: Rebuilt.
+
+Wed Feb 11 07:36:50 1998 Anthony Green <green@hoser.cygnus.com>
+
+ * Makefile.in: Rebuilt.
+
+Tue Feb 10 20:56:00 1998 Richard Henderson <rth@cygnus.com>
+
+ * alpha/ffi.c, alpha/osf.S: New files.
+ * Makefile.am: Alpha port.
+
+Tue Nov 18 14:12:07 1997 Anthony Green <green@hoser.cygnus.com>
+
+ * mips/ffi.c (ffi_prep_cif_machdep): Initialize rstruct_flag
+ for n32.
+
+Tue Jun 3 17:18:20 1997 Anthony Green <green@hoser.cygnus.com>
+
+ * ffitest.c (main): Added hack to get structure tests working
+ correctly.
+
+Sat May 10 19:06:42 1997 Tom Tromey <tromey@cygnus.com>
+
+ * Makefile.in: Rebuilt.
+ * Makefile.am (EXTRA_DIST): Explicitly list all distributable
+ files in subdirs.
+ (VERSION, CC): Removed.
+
+Thu May 8 17:19:01 1997 Anthony Green <green@hoser.cygnus.com>
+
+ * Makefile.am: Many changes for new automake and libtool.
+ * Makefile.in: Rebuilt.
+
+Fri Nov 22 06:57:56 1996 Anthony Green <green@rtl.cygnus.com>
+
+ * ffitest.c (main): Fixed test case for non mips machines.
+
+Wed Nov 20 22:31:59 1996 Anthony Green <green@hoser.cygnus.com>
+
+ * types.c: Added ffi_type_void declaration.
+
+Tue Oct 29 13:07:19 1996 Anthony Green <green@rtl.cygnus.com>
+
+ * ffitest.c (main): Fixed character constants.
+ (main): Emit warning for structure test 3 failure on Sun.
+
+ * Makefile.am (VPATH): Fixed VPATH def'n so automake won't
+ strip it out.
+ Moved distdir hack from libffi to automake.
+ (ffitest): Added missing -c for $(COMPILE) (change in automake).
+ * Makefile.in: Rebuilt.
+
+Tue Oct 15 13:08:20 1996 Anthony Green <green@hoser.cygnus.com>
+
+ * Makefile.am: Added "make lint" production.
+ * Makefile.in: Rebuilt.
+
+ * prep_cif.c (STACK_ARG_SIZE): Improved STACK_ARG_SIZE macro.
+ Clean up based on LCLint output. Added funny /*@...@*/ comments to
+ annotate source.
+
+ * ffitest.c, debug.c: Cleaned up code.
+
+Mon Oct 14 12:26:56 1996 Anthony Green <green@rtl.cygnus.com>
+
+ * ffitest.c: Changes based on interface changes.
+
+ * prep_cif.c (ffi_prep_cif): Cleaned up interface based on
+ feedback from Jim Blandy.
+
+Fri Oct 11 15:53:18 1996 Anthony Green <green@rtl.cygnus.com>
+
+ * ffitest.c: Reordered tests while porting to sparc.
+ Made changes to handle lame structure passing for sparc.
+ Removed calls to fflush().
+
+ * prep_cif.c (ffi_prep_cif): Added special case for sparc
+ aggregate type arguments.
+
+Thu Oct 10 09:56:51 1996 Anthony Green <green@rtl.cygnus.com>
+
+ * ffitest.c (main): Added structure passing/returning tests.
+
+ * prep_cif.c (ffi_prep_cif): Perform proper initialization
+ of structure return types if needed.
+ (initialize_aggregate): Bug fix
+
+Wed Oct 9 16:04:20 1996 Anthony Green <green@rtl.cygnus.com>
+
+ * types.c: Added special definitions for x86 (double doesn't
+ need double word alignment).
+
+ * ffitest.c: Added many tests
+
+Tue Oct 8 09:19:22 1996 Anthony Green <green@rtl.cygnus.com>
+
+ * prep_cif.c (ffi_prep_cif): Fixed assertion.
+
+ * debug.c (ffi_assert): Must return a non void now.
+
+ * Makefile.am: Added test production.
+ * Makefile: Rebuilt.
+
+ * ffitest.c (main): Created.
+
+ * types.c: Created. Stripped common code out of */ffi.c.
+
+ * prep_cif.c: Added missing stdlib.h include.
+
+ * debug.c (ffi_type_test): Used "a" to eliminate compiler
+ warnings in non-debug builds. Included ffi_common.h.
+
+Mon Oct 7 15:36:42 1996 Anthony Green <green@rtl.cygnus.com>
+
+ * Makefile.am: Added a rule for .s -> .o
+ This is required by the SGI compiler.
+ * Makefile: Rebuilt.
+
+Fri Oct 4 09:51:08 1996 Anthony Green <green@hoser.cygnus.com>
+
+ * prep_cif.c (initialize_aggregate): Moved abi specification
+ to ffi_prep_cif().
+
+Thu Oct 3 15:37:37 1996 Anthony Green <green@hoser.cygnus.com>
+
+ * prep_cif.c (ffi_prep_cif): Changed values from void* to void**.
+ (initialize_aggregate): Fixed aggregate type initialization.
+
+ * Makefile.am (EXTRA_DIST): Added support code for "make dist".
+ * Makefile.in: Regenerated.
+
+Wed Oct 2 11:41:57 1996 Anthony Green <green@hoser.cygnus.com>
+
+ * debug.c, prep_cif: Created.
+
+ * Makefile.am: Added debug.o and prep_cif.o to OBJ.
+ * Makefile.in: Regenerated.
+
+ * Makefile.am (INCLUDES): Added missing -I../include
+ * Makefile.in: Regenerated.
+
+Tue Oct 1 17:11:51 1996 Anthony Green <green@rtl.cygnus.com>
+
+ * error.c, Makefile.am: Created.
+ * Makefile.in: Generated.
+
+--- libffi/src/x86 --------------------------------------------------------
+
+Sun Oct 4 16:27:17 1998 Anthony Green <green@cygnus.com>
+
+ * sysv.S (retlongdouble): Fixed long long return value support.
+ * ffi.c (ffi_prep_cif_machdep): Ditto.
+
+Wed May 13 04:30:33 1998 Anthony Green <green@raft.ppp.tsoft.net>
+
+ * ffi.c (ffi_prep_cif_machdep): Fixed long double return value
+ support.
+
+Wed Apr 15 08:43:20 1998 Anthony Green <green@hoser.cygnus.com>
+
+ * ffi.c (ffi_prep_args): small struct support was missing.
+
+Thu May 8 16:53:58 1997 Anthony Green <green@hoser.cygnus.com>
+
+ * objects.mak: Removed.
+
+Mon Dec 2 15:12:58 1996 Tom Tromey <tromey@cygnus.com>
+
+ * sysv.S: Use .balign, for a.out Linux boxes.
+
+Tue Oct 15 13:06:50 1996 Anthony Green <green@hoser.cygnus.com>
+
+ * ffi.c: Clean up based on LCLint output.
+ Added funny /*@...@*/ comments to annotate source.
+
+Fri Oct 11 16:43:38 1996 Anthony Green <green@rtl.cygnus.com>
+
+ * ffi.c (ffi_call): Added assertion for bad ABIs.
+
+Wed Oct 9 13:57:27 1996 Anthony Green <green@rtl.cygnus.com>
+
+ * sysv.S (retdouble): Fixed double return problems.
+
+ * ffi.c (ffi_call): Corrected fn arg definition.
+ (ffi_prep_cif_machdep): Fixed double return problems
+
+Tue Oct 8 12:12:49 1996 Anthony Green <green@rtl.cygnus.com>
+
+ * ffi.c: Moved ffi_type definitions to types.c.
+ (ffi_prep_args): Fixed type promotion bug.
+
+Mon Oct 7 15:53:06 1996 Anthony Green <green@rtl.cygnus.com>
+
+ * ffi.c (FFI_*_TYPEDEF): Removed redundant ';'
+
+Fri Oct 4 09:54:53 1996 Anthony Green <green@hoser.cygnus.com>
+
+ * ffi.c (ffi_call): Removed FFI_ABI arg, and swapped
+ remaining args.
+
+Wed Oct 2 10:07:05 1996 Anthony Green <green@hoser.cygnus.com>
+
+ * ffi.c, sysv.S, objects.mak: Created.
+ (ffi_prep_cif): cif->rvalue no longer initialized to NULL.
+ (ffi_prep_cif_machdep): Moved machine independent cif processing
+ to src/prep_cif.c. Introduced ffi_prep_cif_machdep().
+
+--- libffi/src/mips -------------------------------------------------------
+
+Tue Feb 17 17:18:07 1998 Anthony Green <green@hoser.cygnus.com>
+
+ * o32.S: Fixed typo in comment.
+
+ * ffi.c (ffi_prep_cif_machdep): Fixed argument processing.
+
+Thu May 8 16:53:58 1997 Anthony Green <green@hoser.cygnus.com>
+
+ * o32.s, n32.s: Wrappers for SGI tool support.
+
+ * objects.mak: Removed.
+
+Tue Oct 29 14:37:45 1996 Anthony Green <green@rtl.cygnus.com>
+
+ * ffi.c (ffi_prep_args): Changed int z to size_t z.
+
+Tue Oct 15 13:17:25 1996 Anthony Green <green@hoser.cygnus.com>
+
+ * n32.S: Fixed bad stack munging.
+
+ * ffi.c: Moved prototypes for ffi_call_?32() to here from
+ ffi_mips.h because extended_cif is not defined in ffi_mips.h.
+
+Mon Oct 14 12:42:02 1996 Anthony Green <green@rtl.cygnus.com>
+
+ * ffi.c: Interface changes based on feedback from Jim Blandy.
+
+Thu Oct 10 11:22:16 1996 Anthony Green <green@rtl.cygnus.com>
+
+ * n32.S, ffi.c: Lots of changes to support passing and
+ returning structures with the n32 calling convention.
+
+ * n32.S: Fixed fn pointer bug.
+
+ * ffi.c (ffi_prep_cif_machdep): Fix for o32 structure
+ return values.
+ (ffi_prep_args): Fixed n32 structure passing when structures
+ partially fit in registers.
+
+Wed Oct 9 13:49:25 1996 Anthony Green <green@rtl.cygnus.com>
+
+ * objects.mak: Added n32.o.
+
+ * n32.S: Created.
+
+ * ffi.c (ffi_prep_args): Added magic to support proper
+ n32 processing.
+
+Tue Oct 8 10:37:35 1996 Anthony Green <green@rtl.cygnus.com>
+
+ * ffi.c: Moved ffi_type definitions to types.c.
+ (ffi_prep_args): Fixed type promotion bug.
+
+ * o32.S: This code is only built for o32 compiles.
+ A lot of the #define cruft has moved to ffi_mips.h.
+
+ * ffi.c (ffi_prep_cif_machdep): Fixed arg flags. Second arg
+ is only processed if the first is either a float or double.
+
+Mon Oct 7 15:33:59 1996 Anthony Green <green@rtl.cygnus.com>
+
+ * o32.S: Modified to compile under each of o32, n32 and n64.
+
+ * ffi.c (FFI_*_TYPEDEF): Removed redundant ';'
+
+Fri Oct 4 09:53:25 1996 Anthony Green <green@hoser.cygnus.com>
+
+ * ffi.c (ffi_call): Removed FFI_ABI arg, and swapped
+ remaining args.
+
+Wed Oct 2 17:41:22 1996 Anthony Green <green@rtl.cygnus.com>
+
+ * o32.S: Removed crufty definitions.
+
+Wed Oct 2 12:53:42 1996 Anthony Green <green@hoser.cygnus.com>
+
+ * ffi.c (ffi_prep_cif): cif->rvalue no longer initialized to NULL.
+ (ffi_prep_cif_machdep): Moved all machine independent cif processing
+ to src/prep_cif.c. Introduced ffi_prep_cif_machdep. Return types
+ of FFI_TYPE_STRUCT are no different than FFI_TYPE_INT.
+
+Tue Oct 1 17:11:02 1996 Anthony Green <green@rtl.cygnus.com>
+
+ * ffi.c, o32.S, object.mak: Created
+
+--- libffi/src/sparc ------------------------------------------------------
+
+Tue Feb 24 16:33:18 1998 Anthony Green <green@hoser.cygnus.com>
+
+ * ffi.c (ffi_prep_args): Added long double support.
+
+Thu May 8 16:53:58 1997 Anthony Green <green@hoser.cygnus.com>
+
+ * objects.mak: Removed.
+
+Thu May 1 16:07:56 1997 Anthony Green <green@hoser.cygnus.com>
+
+ * v8.S: Fixed minor portability problem reported by
+ Russ McManus <mcmanr@eq.gs.com>.
+
+Tue Nov 26 14:12:43 1996 Anthony Green <green@csk3.cygnus.com>
+
+ * v8.S: Used STACKFRAME define elsewhere.
+
+ * ffi.c (ffi_prep_args): Zero out space when USING_PURIFY
+ is set.
+ (ffi_prep_cif_machdep): Allocate the correct stack frame
+ space for functions with < 6 args.
+
+Tue Oct 29 15:08:55 1996 Anthony Green <green@rtl.cygnus.com>
+
+ * ffi.c (ffi_prep_args): int z is now size_t z.
+
+Mon Oct 14 13:31:24 1996 Anthony Green <green@rtl.cygnus.com>
+
+ * v8.S (ffi_call_V8): Gordon rewrites this again. It looks
+ great now.
+
+ * ffi.c (ffi_call): The comment about hijacked registers
+ is no longer valid after gordoni hacked v8.S.
+
+ * v8.S (ffi_call_V8): Rewrote with gordoni. Much simpler.
+
+ * v8.S, ffi.c: ffi_call() had changed to accept more than
+ two args, so v8.S had to change (because it hijacks incoming
+ arg registers).
+
+ * ffi.c: Interface changes based on feedback from Jim Blandy.
+
+Thu Oct 10 17:48:16 1996 Anthony Green <green@rtl.cygnus.com>
+
+ * ffi.c, v8.S, objects.mak: Created.
+
+
diff --git a/libffi/LICENSE b/libffi/LICENSE
new file mode 100644
index 00000000000..9aac69c3077
--- /dev/null
+++ b/libffi/LICENSE
@@ -0,0 +1,20 @@
+libffi - Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001 Red Hat, Inc.
+
+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 CYGNUS SOLUTIONS 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/libffi/Makefile.am b/libffi/Makefile.am
new file mode 100644
index 00000000000..a070f71e690
--- /dev/null
+++ b/libffi/Makefile.am
@@ -0,0 +1,72 @@
+## Process this with automake to create Makefile.in
+
+AUTOMAKE_OPTIONS = foreign no-installinfo
+
+if TESTSUBDIR
+SUBDIRS = include testsuite
+else
+SUBDIRS = include
+endif
+
+EXTRA_DIST = \
+ LICENSE \
+ README \
+ ChangeLog.v1 \
+ alpha/ffi.c \
+ arm/ffi.c \
+ ia64/ffi.c \
+ m68k/ffi.c \
+ mips/ffi.c \
+ powerpc/ffi.c \
+ s390/ffi.c \
+ sparc/ffi.c \
+ x86/ffi.c \
+ alpha/osf.S \
+ arm/sysv.S \
+ ia64/unix.S \
+ m68k/sysv.S \
+ mips/n32.S \
+ mips/o32.S \
+ powerpc/sysv.S \
+ s390/sysv.S \
+ sparc/v8.S \
+ sparc/v9.S \
+ x86/win32.S \
+ x86/sysv.S
+
+# Multilib support variables.
+MULTISRCTOP =
+MULTIBUILDTOP =
+MULTIDIRS =
+MULTISUBDIR =
+MULTIDO = true
+MULTICLEAN = true
+
+## Install a library built with a cross compiler in tooldir, not
+## libdir.
+if USE_LIBDIR
+toolexeclibdir = $(libdir)$(MULTISUBDIR)
+else
+toolexecdir = $(exec_prefix)/$(target_alias)
+toolexeclibdir = $(toolexecdir)/lib$(MULTISUBDIR)
+endif
+
+toolexeclib_LIBRARIES = libffi.a
+
+## Work around automake deficiency
+nodist_libffi_a_SOURCES = t-ffi.c t-asm.S
+
+libffi_a_SOURCES = \
+ debug.c \
+ prep_cif.c \
+ types.c \
+ raw_api.c \
+ java_raw_api.c \
+ $(nodist_libffi_a_SOURCES)
+
+AM_CFLAGS = -fexceptions
+
+INCLUDES = \
+ -I$(top_srcdir)/include \
+ -Iinclude \
+ -I$(top_srcdir)/src
diff --git a/libffi/README b/libffi/README
new file mode 100644
index 00000000000..7dc1fa5e745
--- /dev/null
+++ b/libffi/README
@@ -0,0 +1,513 @@
+README for libffi-2.00
+
+libffi-2.00 has not been released yet! This is a development snapshot!
+
+libffi-1.20 was released on [SOME FUTURE DAY]. Check the libffi web
+page for updates: <URL:http://sourceware.cygnus.com/libffi/>.
+
+
+What is libffi?
+===============
+
+Compilers for high level languages generate code that follow certain
+conventions. These conventions are necessary, in part, for separate
+compilation to work. One such convention is the "calling
+convention". The "calling convention" is essentially a set of
+assumptions made by the compiler about where function arguments will
+be found on entry to a function. A "calling convention" also specifies
+where the return value for a function is found.
+
+Some programs may not know at the time of compilation what arguments
+are to be passed to a function. For instance, an interpreter may be
+told at run-time about the number and types of arguments used to call
+a given function. Libffi can be used in such programs to provide a
+bridge from the interpreter program to compiled code.
+
+The libffi library provides a portable, high level programming
+interface to various calling conventions. This allows a programmer to
+call any function specified by a call interface description at run
+time.
+
+Ffi stands for Foreign Function Interface. A foreign function
+interface is the popular name for the interface that allows code
+written in one language to call code written in another language. The
+libffi library really only provides the lowest, machine dependent
+layer of a fully featured foreign function interface. A layer must
+exist above libffi that handles type conversions for values passed
+between the two languages.
+
+
+Supported Platforms and Prerequisites
+=====================================
+
+Libffi has been ported to:
+
+ Alpha - Linux and OSF/1
+
+ ARM - Linux (System V ABI)
+
+ IA-32 - Linux, Solaris, and BeOS (System V ABI)
+
+ IA-64 - Linux (System V ABI)
+
+ m68k - Linux (System V ABI)
+
+ MIPS, 32- and 64-bit - Irix (System V/o32 and n32)
+
+ PowerPC - Linux (System V ABI)
+
+ S390 - Linux (System V ABI)
+
+ Sparc, 32-bit - SunOS 4.1.3, Solaris 2.x, and Linux (Sparc v8)
+
+ Sparc, 64-bit - Linux (Sparc v9)
+
+
+Libffi has been tested with GCC 3.00 and newer compilers.
+
+You must use GNU make to build libffi.
+
+If you port libffi to another platform, please let me know! I assume
+that some will be easy (x86 NetBSD), and others will be more difficult
+(HP, AIX).
+
+
+Installing libffi
+=================
+
+[Note: before actually performing any of these installation steps,
+ you may wish to read the "Platform Specific Notes" below.]
+
+First you must configure the distribution for your particular
+system. Go to the directory you wish to build libffi in and run the
+"configure" program found in the root directory of the libffi source
+distribution.
+
+You may want to tell configure where to install the libffi library and
+header files. To do that, use the --prefix configure switch. Libffi
+will install under /usr/local by default.
+
+If you want to enable extra run-time debugging checks use the the
+--enable-debug configure switch. This is useful when your program dies
+mysteriously while using libffi.
+
+Another useful configure switch is --enable-purify-safety. Using this
+will add some extra code which will suppress certain warnings when you
+are using Purify with libffi. Only use this switch when using
+Purify, as it will slow down the library.
+
+Configure has many other options. Use "configure --help" to see them all.
+
+Once configure has finished, type "make". Note that you must be using
+GNU make. SGI's make will not work. Sun's probably won't either.
+You can ftp GNU make from prep.ai.mit.edu:/pub/gnu.
+
+To ensure that libffi is working as advertised, type "make test".
+
+To install the library and header files, type "make install".
+
+
+Using libffi
+============
+
+ The Basics
+ ----------
+
+Libffi assumes that you have a pointer to the function you wish to
+call and that you know the number and types of arguments to pass it,
+as well as the return type of the function.
+
+The first thing you must do is create an ffi_cif object that matches
+the signature of the function you wish to call. The cif in ffi_cif
+stands for Call InterFace. To prepare a call interface object, use the
+following function:
+
+ffi_status ffi_prep_cif(ffi_cif *cif, ffi_abi abi,
+ unsigned int nargs,
+ ffi_type *rtype, ffi_type **atypes);
+
+ CIF is a pointer to the call interface object you wish
+ to initialize.
+
+ ABI is an enum that specifies the calling convention
+ to use for the call. FFI_DEFAULT_ABI defaults
+ to the system's native calling convention. Other
+ ABI's may be used with care. They are system
+ specific.
+
+ NARGS is the number of arguments this function accepts.
+ libffi does not yet support vararg functions.
+
+ RTYPE is a pointer to an ffi_type structure that represents
+ the return type of the function. Ffi_type objects
+ describe the types of values. libffi provides
+ ffi_type objects for many of the native C types:
+ signed int, unsigned int, signed char, unsigned char,
+ etc. There is also a pointer ffi_type object and
+ a void ffi_type. Use &ffi_type_void for functions that
+ don't return values.
+
+ ATYPES is a vector of ffi_type pointers. ARGS must be NARGS long.
+ If NARGS is 0, this is ignored.
+
+
+ffi_prep_cif will return a status code that you are responsible
+for checking. It will be one of the following:
+
+ FFI_OK - All is good.
+
+ FFI_BAD_TYPEDEF - One of the ffi_type objects that ffi_prep_cif
+ came across is bad.
+
+
+Before making the call, the VALUES vector should be initialized
+with pointers to the appropriate argument values.
+
+To call the the function using the initialized ffi_cif, use the
+ffi_call function:
+
+void ffi_call(ffi_cif *cif, void *fn, void *rvalue, void **avalues);
+
+ CIF is a pointer to the ffi_cif initialized specifically
+ for this function.
+
+ FN is a pointer to the function you want to call.
+
+ RVALUE is a pointer to a chunk of memory that is to hold the
+ result of the function call. Currently, it must be
+ at least one word in size (except for the n32 version
+ under Irix 6.x, which must be a pointer to an 8 byte
+ aligned value (a long long). It must also be at least
+ word aligned (depending on the return type, and the
+ system's alignment requirements). If RTYPE is
+ &ffi_type_void, this is ignored. If RVALUE is NULL,
+ the return value is discarded.
+
+ AVALUES is a vector of void* that point to the memory locations
+ holding the argument values for a call.
+ If NARGS is 0, this is ignored.
+
+
+If you are expecting a return value from FN it will have been stored
+at RVALUE.
+
+
+
+ An Example
+ ----------
+
+Here is a trivial example that calls puts() a few times.
+
+ #include <stdio.h>
+ #include <ffi.h>
+
+ int main()
+ {
+ ffi_cif cif;
+ ffi_type *args[1];
+ void *values[1];
+ char *s;
+ int rc;
+
+ /* Initialize the argument info vectors */
+ args[0] = &ffi_type_uint;
+ values[0] = &s;
+
+ /* Initialize the cif */
+ if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
+ &ffi_type_uint, args) == FFI_OK)
+ {
+ s = "Hello World!";
+ ffi_call(&cif, puts, &rc, values);
+ /* rc now holds the result of the call to puts */
+
+ /* values holds a pointer to the function's arg, so to
+ call puts() again all we need to do is change the
+ value of s */
+ s = "This is cool!";
+ ffi_call(&cif, puts, &rc, values);
+ }
+
+ return 0;
+ }
+
+
+
+ Aggregate Types
+ ---------------
+
+Although libffi has no special support for unions or bit-fields, it is
+perfectly happy passing structures back and forth. You must first
+describe the structure to libffi by creating a new ffi_type object
+for it. Here is the definition of ffi_type:
+
+ typedef struct _ffi_type
+ {
+ unsigned size;
+ short alignment;
+ short type;
+ struct _ffi_type **elements;
+ } ffi_type;
+
+All structures must have type set to FFI_TYPE_STRUCT. You may set
+size and alignment to 0. These will be calculated and reset to the
+appropriate values by ffi_prep_cif().
+
+elements is a NULL terminated array of pointers to ffi_type objects
+that describe the type of the structure elements. These may, in turn,
+be structure elements.
+
+The following example initializes a ffi_type object representing the
+tm struct from Linux's time.h:
+
+ struct tm {
+ int tm_sec;
+ int tm_min;
+ int tm_hour;
+ int tm_mday;
+ int tm_mon;
+ int tm_year;
+ int tm_wday;
+ int tm_yday;
+ int tm_isdst;
+ /* Those are for future use. */
+ long int __tm_gmtoff__;
+ __const char *__tm_zone__;
+ };
+
+ {
+ ffi_type tm_type;
+ ffi_type *tm_type_elements[12];
+ int i;
+
+ tm_type.size = tm_type.alignment = 0;
+ tm_type.elements = &tm_type_elements;
+
+ for (i = 0; i < 9; i++)
+ tm_type_elements[i] = &ffi_type_sint;
+
+ tm_type_elements[9] = &ffi_type_slong;
+ tm_type_elements[10] = &ffi_type_pointer;
+ tm_type_elements[11] = NULL;
+
+ /* tm_type can now be used to represent tm argument types and
+ return types for ffi_prep_cif() */
+ }
+
+
+
+Platform Specific Notes
+=======================
+
+ Intel x86
+ ---------
+
+There are no known problems with the x86 port.
+
+ Sun Sparc - SunOS 4.1.3 & Solaris 2.x
+ -------------------------------------
+
+There's a bug in the structure passing code for sparc processors.
+Struct arguments that are passed in value actually end up being passed
+by reference. This will be fixed Real Soon Now.
+
+"long long" values are not supported yet.
+
+You must use GNU Make to build libffi on Sun platforms.
+
+ MIPS - Irix 5.3 & 6.x
+ ---------------------
+
+Irix 6.2 and better supports three different calling conventions: o32,
+n32 and n64. Currently, libffi only supports both o32 and n32 under
+Irix 6.x, but only o32 under Irix 5.3. Libffi will automatically be
+configured for whichever calling convention it was built for.
+
+By default, the configure script will try to build libffi with the GNU
+development tools. To build libffi with the SGI development tools, set
+the environment variable CC to either "cc -32" or "cc -n32" before
+running configure under Irix 6.x (depending on whether you want an o32
+or n32 library), or just "cc" for Irix 5.3.
+
+With the n32 calling convention, when returning structures smaller
+than 16 bytes, be sure to provide an RVALUE that is 8 byte aligned.
+Here's one way of forcing this:
+
+ double struct_storage[2];
+ my_small_struct *s = (my_small_struct *) struct_storage;
+ /* Use s for RVALUE */
+
+If you don't do this you are liable to get spurious bus errors.
+
+"long long" values are not supported yet.
+
+You must use GNU Make to build libffi on SGI platforms.
+
+ ARM - System V ABI
+ ------------------
+
+The ARM port was performed on a NetWinder running ARM Linux ELF
+(2.0.31) and gcc 2.8.1. config.sub still does not recognize the
+machine name sa110-unknown-linux-gnu (currently returned by
+NetWinder). In the mean time the package can be configured by running
+'configure arm-linux'.
+
+
+
+ PowerPC System V ABI
+ --------------------
+
+There are two `System V ABI's which libffi implements for PowerPC.
+They differ only in how small structures are returned from functions.
+
+In the FFI_SYSV version, structures that are 8 bytes or smaller are
+returned in registers. This is what GCC does when it is configured
+for solaris, and is what the System V ABI I have (dated September
+1995) says.
+
+In the FFI_GCC_SYSV version, all structures are returned the same way:
+by passing a pointer as the first argument to the function. This is
+what GCC does when it is configured for linux or a generic sysv
+target.
+
+EGCS 1.0.1 (and probably other versions of EGCS/GCC) also has a
+inconsistency with the SysV ABI: When a procedure is called with many
+floating-point arguments, some of them get put on the stack. They are
+all supposed to be stored in double-precision format, even if they are
+only single-precision, but EGCS stores single-precision arguments as
+single-precision anyway. This causes one test to fail (the `many
+arguments' test).
+
+
+History
+=======
+
+2.00 ???-??-01
+
+ Many configure improvements. No more run tests required at
+ configure time so cross compiling should work well. ffi.h is
+ target independent now and may be installed safely anywhere.
+ ffitest replaced with dejagnu testing infrastructure. s390
+ port from ????. ia64 port from Hans Boehm. General
+ performance improvements. Closures designed and implemented
+ by Kresten Krab Thorup and ported to ia64 and powerpc by Hans
+ Boehm and ???? respectively.
+
+1.20 Oct-5-98
+ Raffaele Sena produces ARM port.
+
+1.19 Oct-5-98
+ Fixed x86 long double and long long return support.
+ m68k bug fixes from Andreas Schwab.
+ Patch for DU assembler compatibility for the Alpha from Richard
+ Henderson.
+
+1.18 Apr-17-98
+ Bug fixes and MIPS configuration changes.
+
+1.17 Feb-24-98
+ Bug fixes and m68k port from Andreas Schwab. PowerPC port from
+ Geoffrey Keating. Various bug x86, Sparc and MIPS bug fixes.
+
+1.16 Feb-11-98
+ Richard Henderson produces Alpha port.
+
+1.15 Dec-4-97
+ Fixed an n32 ABI bug. New libtool, auto* support.
+
+1.14 May-13-97
+ libtool is now used to generate shared and static libraries.
+ Fixed a minor portability problem reported by Russ McManus
+ <mcmanr@eq.gs.com>.
+
+1.13 Dec-2-96
+ Added --enable-purify-safety to keep Purify from complaining
+ about certain low level code.
+ Sparc fix for calling functions with < 6 args.
+ Linux x86 a.out fix.
+
+1.12 Nov-22-96
+ Added missing ffi_type_void, needed for supporting void return
+ types. Fixed test case for non MIPS machines. Cygnus Support
+ is now Cygnus Solutions.
+
+1.11 Oct-30-96
+ Added notes about GNU make.
+
+1.10 Oct-29-96
+ Added configuration fix for non GNU compilers.
+
+1.09 Oct-29-96
+ Added --enable-debug configure switch. Clean-ups based on LCLint
+ feedback. ffi_mips.h is always installed. Many configuration
+ fixes. Fixed ffitest.c for sparc builds.
+
+1.08 Oct-15-96
+ Fixed n32 problem. Many clean-ups.
+
+1.07 Oct-14-96
+ Gordon Irlam rewrites v8.S again. Bug fixes.
+
+1.06 Oct-14-96
+ Gordon Irlam improved the sparc port.
+
+1.05 Oct-14-96
+ Interface changes based on feedback.
+
+1.04 Oct-11-96
+ Sparc port complete (modulo struct passing bug).
+
+1.03 Oct-10-96
+ Passing struct args, and returning struct values works for
+ all architectures/calling conventions. Expanded tests.
+
+1.02 Oct-9-96
+ Added SGI n32 support. Fixed bugs in both o32 and Linux support.
+ Added "make test".
+
+1.01 Oct-8-96
+ Fixed float passing bug in mips version. Restructured some
+ of the code. Builds cleanly with SGI tools.
+
+1.00 Oct-7-96
+ First release. No public announcement.
+
+
+Authors & Credits
+=================
+
+libffi was written by Anthony Green <green@redhat.com>.
+
+Portions of libffi were derived from Gianni Mariani's free gencall
+library for Silicon Graphics machines.
+
+The closure mechanism was designed and implemented on IA-32 by Kresten
+Krab Thorup.
+
+The initial Sparc port was derived from code contributed by the fine
+folks at Visible Decisions Inc. Further enhancements were made by
+Gordon Irlam while at Cygnus Solutions.
+
+The Alpha port was written by Richard Henderson at Cygnus Solutions/Red Hat.
+
+Andreas Schwab ported libffi to m68k Linux and provided a number of
+bug fixes.
+
+Geoffrey Keating ported libffi to the PowerPC.
+
+Raffaele Sena ported libffi to the ARM.
+
+Hans Boehm ported libffi to IA-64.
+
+Jakub Jelinek ported libffi to 32- and 64-bit Sparc Linux.
+
+Jesper Skov and Andrew Haley both did more than their fair share of
+stepping through the code and tracking down bugs.
+
+Thanks also to Tom Tromey for bug fixes and configuration help.
+
+Thanks to Jim Blandy, who provided some useful feedback on the libffi
+interface.
+
+If you have a problem, or have found a bug, please send a note to
+green@cygnus.com.
diff --git a/libffi/acconfig.h b/libffi/acconfig.h
new file mode 100644
index 00000000000..9c553150c02
--- /dev/null
+++ b/libffi/acconfig.h
@@ -0,0 +1,12 @@
+/* Define this if you want extra debugging */
+#undef FFI_DEBUG
+
+/* Define this if you are using Purify and want to suppress
+ spurious messages. */
+#undef USING_PURIFY
+
+/* Define this is you do not want support for aggregate types. */
+#undef FFI_NO_STRUCTS
+
+/* Define this is you do not want support for the raw API. */
+#undef FFI_NO_RAW_API
diff --git a/libffi/acinclude.m4 b/libffi/acinclude.m4
new file mode 100644
index 00000000000..0f4b0be1f08
--- /dev/null
+++ b/libffi/acinclude.m4
@@ -0,0 +1,97 @@
+AC_DEFUN([AC_COMPILE_CHECK_SIZEOF],
+[changequote(<<, >>)dnl
+dnl The name to #define.
+define(<<AC_TYPE_NAME>>, translit(sizeof_$1, [a-z *], [A-Z_P]))dnl
+dnl The cache variable name.
+define(<<AC_CV_NAME>>, translit(ac_cv_sizeof_$1, [ *], [_p]))dnl
+changequote([, ])dnl
+AC_MSG_CHECKING(size of $1)
+AC_CACHE_VAL(AC_CV_NAME,
+[for ac_size in 4 8 1 2 16 12 $2 ; do # List sizes in rough order of prevalence.
+ AC_TRY_COMPILE([#include "confdefs.h"
+#include <sys/types.h>
+$2
+], [switch (0) case 0: case (sizeof ($1) == $ac_size):;], AC_CV_NAME=$ac_size)
+ if test x$AC_CV_NAME != x ; then break; fi
+done
+])
+if test x$AC_CV_NAME = x ; then
+ AC_MSG_ERROR([cannot determine a size for $1])
+fi
+AC_MSG_RESULT($AC_CV_NAME)
+AC_DEFINE_UNQUOTED(AC_TYPE_NAME, $AC_CV_NAME, [The number of bytes in type $1])
+undefine([AC_TYPE_NAME])dnl
+undefine([AC_CV_NAME])dnl
+])
+
+
+AC_DEFUN([AC_C_BIGENDIAN_CROSS],
+[AC_CACHE_CHECK(whether byte ordering is bigendian, ac_cv_c_bigendian,
+[ac_cv_c_bigendian=unknown
+# See if sys/param.h defines the BYTE_ORDER macro.
+AC_TRY_COMPILE([#include <sys/types.h>
+#include <sys/param.h>], [
+#if !BYTE_ORDER || !BIG_ENDIAN || !LITTLE_ENDIAN
+ bogus endian macros
+#endif], [# It does; now see whether it defined to BIG_ENDIAN or not.
+AC_TRY_COMPILE([#include <sys/types.h>
+#include <sys/param.h>], [
+#if BYTE_ORDER != BIG_ENDIAN
+ not big endian
+#endif], ac_cv_c_bigendian=yes, ac_cv_c_bigendian=no)])
+if test $ac_cv_c_bigendian = unknown; then
+AC_TRY_RUN([main () {
+ /* Are we little or big endian? From Harbison&Steele. */
+ union
+ {
+ long l;
+ char c[sizeof (long)];
+ } u;
+ u.l = 1;
+ exit (u.c[sizeof (long) - 1] == 1);
+}], ac_cv_c_bigendian=no, ac_cv_c_bigendian=yes,
+[ echo $ac_n "cross-compiling... " 2>&AC_FD_MSG ])
+fi])
+if test $ac_cv_c_bigendian = unknown; then
+AC_MSG_CHECKING(to probe for byte ordering)
+[
+cat >conftest.c <<EOF
+short ascii_mm[] = { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 };
+short ascii_ii[] = { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 };
+void _ascii() { char* s = (char*) ascii_mm; s = (char*) ascii_ii; }
+short ebcdic_ii[] = { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 };
+short ebcdic_mm[] = { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 };
+void _ebcdic() { char* s = (char*) ebcdic_mm; s = (char*) ebcdic_ii; }
+int main() { _ascii (); _ebcdic (); return 0; }
+EOF
+] if test -f conftest.c ; then
+ if ${CC-cc} ${CFLAGS} conftest.c -o conftest.o && test -f conftest.o ; then
+ if test `grep -l BIGenDianSyS conftest.o` ; then
+ echo $ac_n ' big endian probe OK, ' 1>&AC_FD_MSG
+ ac_cv_c_bigendian=yes
+ fi
+ if test `grep -l LiTTleEnDian conftest.o` ; then
+ echo $ac_n ' little endian probe OK, ' 1>&AC_FD_MSG
+ if test $ac_cv_c_bigendian = yes ; then
+ ac_cv_c_bigendian=unknown;
+ else
+ ac_cv_c_bigendian=no
+ fi
+ fi
+ echo $ac_n 'guessing bigendian ... ' >&AC_FD_MSG
+ fi
+ fi
+AC_MSG_RESULT($ac_cv_c_bigendian)
+fi
+if test $ac_cv_c_bigendian = yes; then
+ AC_DEFINE(WORDS_BIGENDIAN, 1, [whether byteorder is bigendian])
+ BYTEORDER=4321
+else
+ BYTEORDER=1234
+fi
+AC_DEFINE_UNQUOTED(BYTEORDER, $BYTEORDER, [1234 = LIL_ENDIAN, 4321 = BIGENDIAN])
+if test $ac_cv_c_bigendian = unknown; then
+ AC_MSG_ERROR(unknown endianess - sorry, please pre-set ac_cv_c_bigendian)
+fi
+])
+
diff --git a/libffi/alpha/ffi.c b/libffi/alpha/ffi.c
new file mode 100644
index 00000000000..30d30f0edb8
--- /dev/null
+++ b/libffi/alpha/ffi.c
@@ -0,0 +1,247 @@
+/* -----------------------------------------------------------------------
+ ffi.c - Copyright (c) 1998 Cygnus Solutions
+
+ Alpha Foreign Function Interface
+
+ 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 CYGNUS SOLUTIONS 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.
+ ----------------------------------------------------------------------- */
+
+#include <ffi.h>
+#include <ffi_private.h>
+
+#include <stdlib.h>
+
+extern void ffi_call_osf(void *, unsigned long, unsigned, void *, void (*)());
+extern void ffi_closure_osf(void);
+
+
+ffi_status
+ffi_prep_cif_machdep(ffi_cif *cif)
+{
+ /* Adjust cif->bytes to represent a minimum 6 words for the temporary
+ register argument loading area. */
+ if (cif->bytes < 6*SIZEOF_ARG)
+ cif->bytes = 6*SIZEOF_ARG;
+
+ /* Set the return type flag */
+ switch (cif->rtype->type)
+ {
+ case FFI_TYPE_STRUCT:
+ case FFI_TYPE_FLOAT:
+ case FFI_TYPE_DOUBLE:
+ cif->flags = cif->rtype->type;
+ break;
+
+ default:
+ cif->flags = FFI_TYPE_INT;
+ break;
+ }
+
+ return FFI_OK;
+}
+
+void
+ffi_call(ffi_cif *cif, void (*fn)(), void *rvalue, void **avalue)
+{
+ unsigned long *stack, *argp;
+ long i, avn;
+ ffi_type **arg_types;
+
+ FFI_ASSERT (cif->abi == FFI_OSF);
+
+ /* If the return value is a struct and we don't have a return
+ value address then we need to make one. */
+ if (rvalue == NULL && cif->flags == FFI_TYPE_STRUCT)
+ rvalue = alloca(cif->rtype->size);
+
+ /* Allocate the space for the arguments, plus 4 words of temp
+ space for ffi_call_osf. */
+ argp = stack = alloca(cif->bytes + 4*SIZEOF_ARG);
+
+ if (cif->flags == FFI_TYPE_STRUCT)
+ *(void **) argp++ = rvalue;
+
+ i = 0;
+ avn = cif->nargs;
+ arg_types = cif->arg_types;
+
+ while (i < avn)
+ {
+ switch ((*arg_types)->type)
+ {
+ case FFI_TYPE_SINT8:
+ *(SINT64 *) argp = *(SINT8 *)(* avalue);
+ break;
+
+ case FFI_TYPE_UINT8:
+ *(SINT64 *) argp = *(UINT8 *)(* avalue);
+ break;
+
+ case FFI_TYPE_SINT16:
+ *(SINT64 *) argp = *(SINT16 *)(* avalue);
+ break;
+
+ case FFI_TYPE_UINT16:
+ *(SINT64 *) argp = *(UINT16 *)(* avalue);
+ break;
+
+ case FFI_TYPE_SINT32:
+ case FFI_TYPE_UINT32:
+ /* Note that unsigned 32-bit quantities are sign extended. */
+ *(SINT64 *) argp = *(SINT32 *)(* avalue);
+ break;
+
+ case FFI_TYPE_SINT64:
+ case FFI_TYPE_UINT64:
+ case FFI_TYPE_POINTER:
+ *(UINT64 *) argp = *(UINT64 *)(* avalue);
+ break;
+
+ case FFI_TYPE_FLOAT:
+ if (argp - stack < 6)
+ {
+ /* Note the conversion -- all the fp regs are loaded as
+ doubles. The in-register format is the same. */
+ *(double *) argp = *(float *)(* avalue);
+ }
+ else
+ *(float *) argp = *(float *)(* avalue);
+ break;
+
+ case FFI_TYPE_DOUBLE:
+ *(double *) argp = *(double *)(* avalue);
+ break;
+
+ case FFI_TYPE_STRUCT:
+ memcpy(argp, *avalue, (*arg_types)->size);
+ break;
+
+ default:
+ FFI_ASSERT(0);
+ }
+
+ argp += ALIGN((*arg_types)->size, SIZEOF_ARG) / SIZEOF_ARG;
+ i++, arg_types++, avalue++;
+ }
+
+ ffi_call_osf(stack, cif->bytes, cif->flags, rvalue, fn);
+}
+
+
+ffi_status
+ffi_prep_closure (ffi_closure* closure,
+ ffi_cif* cif,
+ void (*fun)(ffi_cif*, void*, void**, void*),
+ void *user_data)
+{
+ unsigned int *tramp;
+
+ FFI_ASSERT (cif->abi == FFI_OSF);
+
+ tramp = (unsigned int *) &closure->tramp[0];
+ tramp[0] = 0x47fb0401; /* mov $27,$1 */
+ tramp[1] = 0xa77b0010; /* ldq $27,16($27) */
+ tramp[2] = 0x6bfb0000; /* jmp $31,($27),0 */
+ tramp[3] = 0x47ff041f; /* nop */
+ *(void **) &tramp[4] = ffi_closure_osf;
+
+ closure->cif = cif;
+ closure->fun = fun;
+ closure->user_data = user_data;
+
+ /* Flush the Icache. */
+ asm volatile ("imb" : : : "memory");
+
+ return FFI_OK;
+}
+
+int
+ffi_closure_osf_inner(ffi_closure *closure, void *rvalue, unsigned long *argp)
+{
+ ffi_cif *cif;
+ void **avalue;
+ ffi_type **arg_types;
+ long i, avn, argn;
+
+ cif = closure->cif;
+ avalue = alloca(cif->nargs * sizeof(void *));
+
+ argn = 0;
+
+ /* Copy the caller's structure return address to that the closure
+ returns the data directly to the caller. */
+ if (cif->flags == FFI_TYPE_STRUCT)
+ {
+ rvalue = (void *) argp[0];
+ argn = 1;
+ }
+
+ i = 0;
+ avn = cif->nargs;
+ arg_types = cif->arg_types;
+
+ /* Grab the addresses of the arguments from the stack frame. */
+ while (i < avn)
+ {
+ switch (arg_types[i]->type)
+ {
+ case FFI_TYPE_SINT8:
+ case FFI_TYPE_UINT8:
+ case FFI_TYPE_SINT16:
+ case FFI_TYPE_UINT16:
+ case FFI_TYPE_SINT32:
+ case FFI_TYPE_UINT32:
+ case FFI_TYPE_SINT64:
+ case FFI_TYPE_UINT64:
+ case FFI_TYPE_POINTER:
+ case FFI_TYPE_STRUCT:
+ avalue[i] = &argp[argn];
+ break;
+
+ case FFI_TYPE_FLOAT:
+ if (argn < 6)
+ {
+ /* Floats coming from registers need conversion from double
+ back to float format. */
+ *(float *)&argp[argn - 6] = *(double *)&argp[argn - 6];
+ avalue[i] = &argp[argn - 6];
+ }
+ else
+ avalue[i] = &argp[argn];
+ break;
+
+ case FFI_TYPE_DOUBLE:
+ avalue[i] = &argp[argn - (argn < 6 ? 6 : 0)];
+ break;
+
+ default:
+ FFI_ASSERT(0);
+ }
+
+ argn += ALIGN(arg_types[i]->size, SIZEOF_ARG) / SIZEOF_ARG;
+ i++;
+ }
+
+ /* Invoke the closure. */
+ (closure->fun) (cif, rvalue, avalue, closure->user_data);
+
+ /* Tell ffi_closure_osf how to perform return type promotions. */
+ return cif->rtype->type;
+}
diff --git a/libffi/alpha/osf.S b/libffi/alpha/osf.S
new file mode 100644
index 00000000000..6ede1aa1b6b
--- /dev/null
+++ b/libffi/alpha/osf.S
@@ -0,0 +1,278 @@
+/* -----------------------------------------------------------------------
+ osf.S - Copyright (c) 1998 Cygnus Solutions
+
+ Alpha/OSF Foreign Function Interface
+
+ 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 CYGNUS SOLUTIONS 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.
+ ----------------------------------------------------------------------- */
+
+#define LIBFFI_ASM
+#include <ffi.h>
+#include <ffi_private.h>
+
+ .arch ev6
+ .text
+
+/* ffi_call_osf (void *args, unsigned long bytes, unsigned flags,
+ void *raddr, void (*fnaddr)());
+
+ Bit o trickiness here -- ARGS+BYTES is the base of the stack frame
+ for this function. This has been allocated by ffi_call. We also
+ deallocate some of the stack that has been alloca'd. */
+
+ .align 3
+ .globl ffi_call_osf
+ .ent ffi_call_osf
+ffi_call_osf:
+ .frame $15, 32, $26, 0
+ .mask 0x4008000, -32
+ addq $16,$17,$1
+ mov $16, $30
+ stq $26, 0($1)
+ stq $15, 8($1)
+ stq $18, 16($1)
+ mov $1, $15
+ .prologue 0
+
+ stq $19, 24($1)
+ mov $20, $27
+
+ # Load up all of the (potential) argument registers.
+ ldq $16, 0($30)
+ ldt $f16, 0($30)
+ ldt $f17, 8($30)
+ ldq $17, 8($30)
+ ldt $f18, 16($30)
+ ldq $18, 16($30)
+ ldt $f19, 24($30)
+ ldq $19, 24($30)
+ ldt $f20, 32($30)
+ ldq $20, 32($30)
+ ldt $f21, 40($30)
+ ldq $21, 40($30)
+
+ # Deallocate the register argument area.
+ lda $30, 48($30)
+
+ jsr $26, ($27), 0
+ ldgp $29, 0($26)
+
+ # If the return value pointer is NULL, assume no return value.
+ ldq $19, 24($15)
+ ldq $18, 16($15)
+ ldq $26, 0($15)
+ beq $19, $noretval
+
+ # Store the return value out in the proper type.
+ cmpeq $18, FFI_TYPE_INT, $1
+ bne $1, $retint
+ cmpeq $18, FFI_TYPE_FLOAT, $2
+ bne $2, $retfloat
+ cmpeq $18, FFI_TYPE_DOUBLE, $3
+ bne $3, $retdouble
+
+$noretval:
+ ldq $15, 8($15)
+ ret
+
+$retint:
+ stq $0, 0($19)
+ nop
+ ldq $15, 8($15)
+ ret
+
+$retfloat:
+ sts $f0, 0($19)
+ nop
+ ldq $15, 8($15)
+ ret
+
+$retdouble:
+ stt $f0, 0($19)
+ nop
+ ldq $15, 8($15)
+ ret
+
+ .end ffi_call_osf
+
+/* ffi_closure_osf(...)
+
+ Receives the closure argument in $1. */
+
+ .align 3
+ .globl ffi_closure_osf
+ .ent ffi_closure_osf
+ffi_closure_osf:
+ .frame $30, 16*8, $26, 0
+ .mask 0x4000000, -16*8
+ ldgp $29, 0($27)
+ subq $30, 16*8, $30
+ stq $26, 0($30)
+ .prologue 1
+
+ # Store all of the potential argument registers in va_list format.
+ stt $f16, 4*8($30)
+ stt $f17, 5*8($30)
+ stt $f18, 6*8($30)
+ stt $f19, 7*8($30)
+ stt $f20, 8*8($30)
+ stt $f21, 9*8($30)
+ stq $16, 10*8($30)
+ stq $17, 11*8($30)
+ stq $18, 12*8($30)
+ stq $19, 13*8($30)
+ stq $20, 14*8($30)
+ stq $21, 15*8($30)
+
+ # Call ffi_closure_osf_inner to do the bulk of the work.
+ mov $1, $16
+ lda $17, 2*8($30)
+ lda $18, 10*8($30)
+ jsr $26, ffi_closure_osf_inner
+ ldgp $29, 0($26)
+ ldq $26, 0($30)
+
+ # Load up the return value in the proper type.
+ lda $1, $load_table
+ s4addq $0, $1, $1
+ ldl $1, 0($1)
+ addq $1, $29, $1
+ jmp $31, ($1), $load_32
+
+ .align 4
+$load_none:
+ addq $30, 16*8, $30
+ ret
+
+ .align 4
+$load_float:
+ lds $f0, 16($30)
+ nop
+ addq $30, 16*8, $30
+ ret
+
+ .align 4
+$load_double:
+ ldt $f0, 16($30)
+ nop
+ addq $30, 16*8, $30
+ ret
+
+ .align 4
+$load_u8:
+#ifdef __alpha_bwx__
+ ldbu $0, 16($30)
+ nop
+#else
+ ldq $0, 16($30)
+ and $0, 255, $0
+#endif
+ addq $30, 16*8, $30
+ ret
+
+ .align 4
+$load_s8:
+#ifdef __alpha_bwx__
+ ldbu $0, 16($30)
+ sextb $0, $0
+#else
+ ldq $0, 16($30)
+ sll $0, 56, $0
+ sra $0, 56, $0
+#endif
+ addq $30, 16*8, $30
+ ret
+
+ .align 4
+$load_u16:
+#ifdef __alpha_bwx__
+ ldwu $0, 16($30)
+ nop
+#else
+ ldq $0, 16($30)
+ zapnot $0, 3, $0
+#endif
+ addq $30, 16*8, $30
+ ret
+
+ .align 4
+$load_s16:
+#ifdef __alpha_bwx__
+ ldwu $0, 16($30)
+ sextw $0, $0
+#else
+ ldq $0, 16($30)
+ sll $0, 48, $0
+ sra $0, 48, $0
+#endif
+ addq $30, 16*8, $30
+ ret
+
+ .align 4
+$load_32:
+ ldl $0, 16($30)
+ nop
+ addq $30, 16*8, $30
+ ret
+
+ .align 4
+$load_64:
+ ldq $0, 16($30)
+ nop
+ addq $30, 16*8, $30
+ ret
+
+ .end ffi_closure_osf
+
+.section .rodata
+$load_table:
+ .gprel32 $load_none # FFI_TYPE_VOID
+ .gprel32 $load_32 # FFI_TYPE_INT
+ .gprel32 $load_float # FFI_TYPE_FLOAT
+ .gprel32 $load_double # FFI_TYPE_DOUBLE
+ .gprel32 $load_double # FFI_TYPE_LONGDOUBLE
+ .gprel32 $load_u8 # FFI_TYPE_UINT8
+ .gprel32 $load_s8 # FFI_TYPE_SINT8
+ .gprel32 $load_u16 # FFI_TYPE_UINT16
+ .gprel32 $load_s16 # FFI_TYPE_SINT16
+ .gprel32 $load_32 # FFI_TYPE_UINT32
+ .gprel32 $load_32 # FFI_TYPE_SINT32
+ .gprel32 $load_64 # FFI_TYPE_UINT64
+ .gprel32 $load_64 # FFI_TYPE_SINT64
+ .gprel32 $load_none # FFI_TYPE_STRUCT
+ .gprel32 $load_64 # FFI_TYPE_POINTER
+
+/* Assert that the table above is in sync with ffi.h. */
+
+#if FFI_TYPE_FLOAT != 2 \
+ || FFI_TYPE_DOUBLE != 3 \
+ || FFI_TYPE_UINT8 != 5 \
+ || FFI_TYPE_SINT8 != 6 \
+ || FFI_TYPE_UINT16 != 7 \
+ || FFI_TYPE_SINT16 != 8 \
+ || FFI_TYPE_UINT32 != 9 \
+ || FFI_TYPE_SINT32 != 10 \
+ || FFI_TYPE_UINT64 != 11 \
+ || FFI_TYPE_SINT64 != 12 \
+ || FFI_TYPE_STRUCT != 13 \
+ || FFI_TYPE_POINTER != 14 \
+ || FFI_TYPE_LAST != 14
+#error "osf.S out of sync with ffi.h"
+#endif
diff --git a/libffi/arm/ffi.c b/libffi/arm/ffi.c
new file mode 100644
index 00000000000..c4e8fafec4f
--- /dev/null
+++ b/libffi/arm/ffi.c
@@ -0,0 +1,183 @@
+/* -----------------------------------------------------------------------
+ ffi.c - Copyright (c) 1998 Cygnus Solutions
+
+ ARM Foreign Function Interface
+
+ 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 CYGNUS SOLUTIONS 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.
+ ----------------------------------------------------------------------- */
+
+#include <ffi.h>
+#include <ffi_private.h>
+
+#include <stdlib.h>
+
+/* ffi_prep_args is called by the assembly routine once stack space
+ has been allocated for the function's arguments */
+
+/*@-exportheader@*/
+void ffi_prep_args(char *stack, extended_cif *ecif)
+/*@=exportheader@*/
+{
+ register unsigned int i;
+ register int tmp;
+ register unsigned int avn;
+ register void **p_argv;
+ register char *argp;
+ register ffi_type **p_arg;
+
+ tmp = 0;
+ argp = stack;
+
+ if ( ecif->cif->rtype->type == FFI_TYPE_STRUCT ) {
+ *(void **) argp = ecif->rvalue;
+ argp += 4;
+ }
+
+ avn = ecif->cif->nargs;
+ p_argv = ecif->avalue;
+
+ for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types;
+ (i != 0) && (avn != 0);
+ i--, p_arg++)
+ {
+ size_t z;
+
+ /* Align if necessary */
+ if (((*p_arg)->alignment - 1) & (unsigned) argp) {
+ argp = (char *) ALIGN(argp, (*p_arg)->alignment);
+ }
+
+ if (avn != 0)
+ {
+ avn--;
+ z = (*p_arg)->size;
+ if (z < sizeof(int))
+ {
+ z = sizeof(int);
+ switch ((*p_arg)->type)
+ {
+ case FFI_TYPE_SINT8:
+ *(signed int *) argp = (signed int)*(SINT8 *)(* p_argv);
+ break;
+
+ case FFI_TYPE_UINT8:
+ *(unsigned int *) argp = (unsigned int)*(UINT8 *)(* p_argv);
+ break;
+
+ case FFI_TYPE_SINT16:
+ *(signed int *) argp = (signed int)*(SINT16 *)(* p_argv);
+ break;
+
+ case FFI_TYPE_UINT16:
+ *(unsigned int *) argp = (unsigned int)*(UINT16 *)(* p_argv);
+ break;
+
+ case FFI_TYPE_STRUCT:
+ *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv);
+ break;
+
+ default:
+ FFI_ASSERT(0);
+ }
+ }
+ else if (z == sizeof(int))
+ {
+ *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv);
+ }
+ else
+ {
+ memcpy(argp, *p_argv, z);
+ }
+ p_argv++;
+ argp += z;
+ }
+ }
+
+ return;
+}
+
+/* Perform machine dependent cif processing */
+ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
+{
+ /* Set the return type flag */
+ switch (cif->rtype->type)
+ {
+ case FFI_TYPE_VOID:
+ case FFI_TYPE_STRUCT:
+ case FFI_TYPE_FLOAT:
+ case FFI_TYPE_DOUBLE:
+ cif->flags = (unsigned) cif->rtype->type;
+ break;
+
+ default:
+ cif->flags = FFI_TYPE_INT;
+ break;
+ }
+
+ return FFI_OK;
+}
+
+/*@-declundef@*/
+/*@-exportheader@*/
+extern void ffi_call_SYSV(void (*)(char *, extended_cif *),
+ /*@out@*/ extended_cif *,
+ unsigned, unsigned,
+ /*@out@*/ unsigned *,
+ void (*fn)());
+/*@=declundef@*/
+/*@=exportheader@*/
+
+void ffi_call(/*@dependent@*/ ffi_cif *cif,
+ void (*fn)(),
+ /*@out@*/ void *rvalue,
+ /*@dependent@*/ void **avalue)
+{
+ extended_cif ecif;
+
+ ecif.cif = cif;
+ ecif.avalue = avalue;
+
+ /* If the return value is a struct and we don't have a return */
+ /* value address then we need to make one */
+
+ if ((rvalue == NULL) &&
+ (cif->rtype->type == FFI_TYPE_STRUCT))
+ {
+ /*@-sysunrecog@*/
+ ecif.rvalue = alloca(cif->rtype->size);
+ /*@=sysunrecog@*/
+ }
+ else
+ ecif.rvalue = rvalue;
+
+
+ switch (cif->abi)
+ {
+ case FFI_SYSV:
+ /*@-usedef@*/
+ ffi_call_SYSV(ffi_prep_args, &ecif, cif->bytes,
+ cif->flags, ecif.rvalue, fn);
+ /*@=usedef@*/
+ break;
+ default:
+ FFI_ASSERT(0);
+ break;
+ }
+}
diff --git a/libffi/arm/sysv.S b/libffi/arm/sysv.S
new file mode 100644
index 00000000000..84744d77562
--- /dev/null
+++ b/libffi/arm/sysv.S
@@ -0,0 +1,111 @@
+/* -----------------------------------------------------------------------
+ sysv.S - Copyright (c) 1998 Cygnus Solutions
+
+ ARM Foreign Function Interface
+
+ 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 CYGNUS SOLUTIONS 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.
+ ----------------------------------------------------------------------- */
+
+#define LIBFFI_ASM
+#include <ffi.h>
+#ifdef HAVE_MACHINE_ASM_H
+#include <machine/asm.h>
+#else
+/* XXX these lose for some platforms, I'm sure. */
+#define CNAME(x) x
+#define ENTRY(x) .globl CNAME(x); .type CNAME(x),%function; CNAME(x):
+#endif
+
+.text
+
+ # a1: ffi_prep_args
+ # a2: &ecif
+ # a3: cif->bytes
+ # a4: fig->flags
+ # sp+0: ecif.rvalue
+ # sp+4: fn
+
+ # This assumes we are using gas.
+ENTRY(ffi_call_SYSV)
+ # Save registers
+ stmfd sp!, {a1-a4, fp, lr}
+ mov fp, sp
+
+ # Make room for all of the new args.
+ sub sp, fp, a3
+
+ # Place all of the ffi_prep_args in position
+ mov ip, a1
+ mov a1, sp
+ # a2 already set
+
+ # And call
+ mov lr, pc
+ mov pc, ip
+
+ # move first 4 parameters in registers
+ ldr a1, [sp, #0]
+ ldr a2, [sp, #4]
+ ldr a3, [sp, #8]
+ ldr a4, [sp, #12]
+
+ # and adjust stack
+ ldr ip, [fp, #8]
+ cmp ip, #16
+ movge ip, #16
+ add sp, sp, ip
+
+ # call function
+ mov lr, pc
+ ldr pc, [fp, #28]
+
+ # Remove the space we pushed for the args
+ mov sp, fp
+
+ # Load a3 with the pointer to storage for the return value
+ ldr a3, [sp, #24]
+
+ # Load a4 with the return type code
+ ldr a4, [sp, #12]
+
+ # If the return value pointer is NULL, assume no return value.
+ cmp a3, #0
+ beq epilogue
+
+# return INT
+ cmp a4, #FFI_TYPE_INT
+ streq a1, [a3]
+ beq epilogue
+
+# return FLOAT
+ cmp a4, #FFI_TYPE_FLOAT
+ stfeqs f0, [a3]
+ beq epilogue
+
+# return DOUBLE or LONGDOUBLE
+ cmp a4, #FFI_TYPE_DOUBLE
+ stfeqd f0, [a3]
+
+epilogue:
+ ldmfd sp!, {a1-a4, fp, pc}
+
+.ffi_call_SYSV_end:
+ .size CNAME(ffi_call_SYSV),.ffi_call_SYSV_end-CNAME(ffi_call_SYSV)
+
diff --git a/libffi/autogen.sh b/libffi/autogen.sh
new file mode 100755
index 00000000000..0b11f883c53
--- /dev/null
+++ b/libffi/autogen.sh
@@ -0,0 +1,6 @@
+libtoolize --automake
+automake -a
+autoheader
+aclocal $ACLOCAL_FLAGS
+autoconf
+./configure $*
diff --git a/libffi/config-ml.in b/libffi/config-ml.in
new file mode 100644
index 00000000000..8c879184384
--- /dev/null
+++ b/libffi/config-ml.in
@@ -0,0 +1,849 @@
+# Configure fragment invoked in the post-target section for subdirs
+# wanting multilib support.
+#
+# It is advisable to support a few --enable/--disable options to let the
+# user select which libraries s/he really wants.
+#
+# Subdirectories wishing to use multilib should put the following lines
+# in the "post-target" section of configure.in.
+#
+# if [ "${srcdir}" = "." ] ; then
+# if [ "${with_target_subdir}" != "." ] ; then
+# . ${with_multisrctop}../../config-ml.in
+# else
+# . ${with_multisrctop}../config-ml.in
+# fi
+# else
+# . ${srcdir}/../config-ml.in
+# fi
+#
+#
+# Things are complicated because 6 separate cases must be handled:
+# 2 (native, cross) x 3 (absolute-path, relative-not-dot, dot) = 6.
+#
+# srcdir=. is special. It must handle make programs that don't handle VPATH.
+# To implement this, a symlink tree is built for each library and for each
+# multilib subdir.
+#
+# The build tree is layed out as
+#
+# ./
+# newlib
+# m68020/
+# newlib
+# m68881/
+# newlib
+#
+# The nice feature about this arrangement is that inter-library references
+# in the build tree work without having to care where you are. Note that
+# inter-library references also work in the source tree because symlink trees
+# are built when srcdir=.
+#
+# Unfortunately, trying to access the libraries in the build tree requires
+# the user to manually choose which library to use as GCC won't be able to
+# find the right one. This is viewed as the lesser of two evils.
+#
+# Configure variables:
+# ${with_target_subdir} = "." for native, or ${target_alias} for cross.
+# Set by top level Makefile.
+# ${with_multisrctop} = how many levels of multilibs there are in the source
+# tree. It exists to handle the case of configuring in the source tree:
+# ${srcdir} is not constant.
+# ${with_multisubdir} = name of multilib subdirectory (eg: m68020/m68881).
+#
+# Makefile variables:
+# MULTISRCTOP = number of multilib levels in source tree (+1 if cross)
+# (FIXME: note that this is different than ${with_multisrctop}. Check out.).
+# MULTIBUILDTOP = number of multilib levels in build tree
+# MULTIDIRS = list of multilib subdirs (eg: m68000 m68020 ...)
+# (only defined in each library's main Makefile).
+# MULTISUBDIR = installed subdirectory name with leading '/' (eg: /m68000)
+# (only defined in each multilib subdir).
+
+# FIXME: Multilib is currently disabled by default for everything other than
+# newlib. It is up to each target to turn on multilib support for the other
+# libraries as desired.
+
+# We have to handle being invoked by both Cygnus configure and Autoconf.
+#
+# Cygnus configure incoming variables:
+# srcdir, subdir, host, arguments
+#
+# Autoconf incoming variables:
+# srcdir, host, ac_configure_args
+#
+# We *could* figure srcdir and host out, but we'd have to do work that
+# our caller has already done to figure them out and requiring these two
+# seems reasonable.
+# Note that `host' in this case is GCC's `target'. Target libraries are
+# configured for a particular host.
+
+if [ -n "${ac_configure_args}" ]; then
+ Makefile=${ac_file-Makefile}
+ ml_config_shell=${CONFIG_SHELL-/bin/sh}
+ ml_arguments="${ac_configure_args}"
+ ml_realsrcdir=${srcdir}
+else
+ Makefile=${Makefile-Makefile}
+ ml_config_shell=${config_shell-/bin/sh}
+ ml_arguments="${arguments}"
+ if [ -n "${subdir}" -a "${subdir}" != "." ] ; then
+ ml_realsrcdir=${srcdir}/${subdir}
+ else
+ ml_realsrcdir=${srcdir}
+ fi
+fi
+
+# Scan all the arguments and set all the ones we need.
+
+ml_verbose=--verbose
+for option in ${ml_arguments}
+do
+ case $option in
+ --*) ;;
+ -*) option=-$option ;;
+ esac
+
+ case $option in
+ --*=*)
+ optarg=`echo $option | sed -e 's/^[^=]*=//'`
+ ;;
+ esac
+
+ case $option in
+ --disable-*)
+ enableopt=`echo ${option} | sed 's:^--disable-:enable_:;s:-:_:g'`
+ eval $enableopt=no
+ ;;
+ --enable-*)
+ case "$option" in
+ *=*) ;;
+ *) optarg=yes ;;
+ esac
+ enableopt=`echo ${option} | sed 's:^--::;s:=.*$::;s:-:_:g'`
+ eval $enableopt="$optarg"
+ ;;
+ --norecursion | --no*)
+ ml_norecursion=yes
+ ;;
+ --silent | --sil* | --quiet | --q*)
+ ml_verbose=--silent
+ ;;
+ --verbose | --v | --verb*)
+ ml_verbose=--verbose
+ ;;
+ --with-*)
+ case "$option" in
+ *=*) ;;
+ *) optarg=yes ;;
+ esac
+ withopt=`echo ${option} | sed 's:^--::;s:=.*$::;s:-:_:g'`
+ eval $withopt="$optarg"
+ ;;
+ --without-*)
+ withopt=`echo ${option} | sed 's:^--::;s:out::;s:-:_:g'`
+ eval $withopt=no
+ ;;
+ esac
+done
+
+# Only do this if --enable-multilib.
+if [ "${enable_multilib}" = yes ]; then
+
+# Compute whether this is the library's top level directory
+# (ie: not a multilib subdirectory, and not a subdirectory like newlib/src).
+# ${with_multisubdir} tells us we're in the right branch, but we could be
+# in a subdir of that.
+# ??? The previous version could void this test by separating the process into
+# two files: one that only the library's toplevel configure.in ran (to
+# configure the multilib subdirs), and another that all configure.in's ran to
+# update the Makefile. It seemed reasonable to collapse all multilib support
+# into one file, but it does leave us with having to perform this test.
+ml_toplevel_p=no
+if [ -z "${with_multisubdir}" ]; then
+ if [ "${srcdir}" = "." ]; then
+ # Use ${ml_realsrcdir} instead of ${srcdir} here to account for ${subdir}.
+ # ${with_target_subdir} = "." for native, otherwise target alias.
+ if [ "${with_target_subdir}" = "." ]; then
+ if [ -f ${ml_realsrcdir}/../config-ml.in ]; then
+ ml_toplevel_p=yes
+ fi
+ else
+ if [ -f ${ml_realsrcdir}/../../config-ml.in ]; then
+ ml_toplevel_p=yes
+ fi
+ fi
+ else
+ # Use ${ml_realsrcdir} instead of ${srcdir} here to account for ${subdir}.
+ if [ -f ${ml_realsrcdir}/../config-ml.in ]; then
+ ml_toplevel_p=yes
+ fi
+ fi
+fi
+
+# If this is the library's top level directory, set multidirs to the
+# multilib subdirs to support. This lives at the top because we need
+# `multidirs' set right away.
+
+if [ "${ml_toplevel_p}" = yes ]; then
+
+multidirs=
+for i in `${CC-gcc} --print-multi-lib 2>/dev/null`; do
+ dir=`echo $i | sed -e 's/;.*$//'`
+ if [ "${dir}" = "." ]; then
+ true
+ else
+ if [ -z "${multidirs}" ]; then
+ multidirs="${dir}"
+ else
+ multidirs="${multidirs} ${dir}"
+ fi
+ fi
+done
+
+# Target libraries are configured for the host they run on, so we check
+# $host here, not $target.
+
+case "${host}" in
+arc-*-elf*)
+ if [ x$enable_biendian != xyes ]
+ then
+ old_multidirs=${multidirs}
+ multidirs=""
+ for x in ${old_multidirs}; do
+ case "${x}" in
+ *be*) : ;;
+ *) multidirs="${multidirs} ${x}" ;;
+ esac
+ done
+ fi
+ ;;
+arm-*-*)
+ if [ x"$enable_fpu" = xno ]
+ then
+ old_multidirs=${multidirs}
+ multidirs=""
+ for x in ${old_multidirs}; do
+ case "${x}" in
+ *fpu*) : ;;
+ *) multidirs="${multidirs} ${x}" ;;
+ esac
+ done
+ fi
+ if [ x"$enable_26bit" = xno ]
+ then
+ old_multidirs=${multidirs}
+ multidirs=""
+ for x in ${old_multidirs}; do
+ case "${x}" in
+ *26bit*) : ;;
+ *) multidirs="${multidirs} ${x}" ;;
+ esac
+ done
+ fi
+ if [ x"$enable_underscore" = xno ]
+ then
+ old_multidirs=${multidirs}
+ multidirs=""
+ for x in ${old_multidirs}; do
+ case "${x}" in
+ *under*) : ;;
+ *) multidirs="${multidirs} ${x}" ;;
+ esac
+ done
+ fi
+ if [ x"$enable_interwork" = xno ]
+ then
+ old_multidirs=${multidirs}
+ multidirs=""
+ for x in ${old_multidirs}; do
+ case "${x}" in
+ *interwork*) : ;;
+ *) multidirs="${multidirs} ${x}" ;;
+ esac
+ done
+ fi
+ if [ x$enable_biendian = xno ]
+ then
+ old_multidirs="${multidirs}"
+ multidirs=""
+ for x in ${old_multidirs}; do
+ case "$x" in
+ *le* ) : ;;
+ *be* ) : ;;
+ *) multidirs="${multidirs} ${x}" ;;
+ esac
+ done
+ fi
+ if [ x"$enable_nofmult" = xno ]
+ then
+ old_multidirs="${multidirs}"
+ multidirs=""
+ for x in ${old_multidirs}; do
+ case "$x" in
+ *nofmult* ) : ;;
+ *) multidirs="${multidirs} ${x}" ;;
+ esac
+ done
+ fi
+ ;;
+m68*-*-*)
+ if [ x$enable_softfloat = xno ]
+ then
+ old_multidirs="${multidirs}"
+ multidirs=""
+ for x in ${old_multidirs}; do
+ case "$x" in
+ *soft-float* ) : ;;
+ *) multidirs="${multidirs} ${x}" ;;
+ esac
+ done
+ fi
+ if [ x$enable_m68881 = xno ]
+ then
+ old_multidirs="${multidirs}"
+ multidirs=""
+ for x in ${old_multidirs}; do
+ case "$x" in
+ *m68881* ) : ;;
+ *) multidirs="${multidirs} ${x}" ;;
+ esac
+ done
+ fi
+ if [ x$enable_m68000 = xno ]
+ then
+ old_multidirs="${multidirs}"
+ multidirs=""
+ for x in ${old_multidirs}; do
+ case "$x" in
+ *m68000* ) : ;;
+ *) multidirs="${multidirs} ${x}" ;;
+ esac
+ done
+ fi
+ if [ x$enable_m68020 = xno ]
+ then
+ old_multidirs="${multidirs}"
+ multidirs=""
+ for x in ${old_multidirs}; do
+ case "$x" in
+ *m68020* ) : ;;
+ *) multidirs="${multidirs} ${x}" ;;
+ esac
+ done
+ fi
+ ;;
+mips*-*-*)
+ if [ x$enable_single_float = xno ]
+ then
+ old_multidirs="${multidirs}"
+ multidirs=""
+ for x in ${old_multidirs}; do
+ case "$x" in
+ *single* ) : ;;
+ *) multidirs="${multidirs} ${x}" ;;
+ esac
+ done
+ fi
+ if [ x$enable_biendian = xno ]
+ then
+ old_multidirs="${multidirs}"
+ multidirs=""
+ for x in ${old_multidirs}; do
+ case "$x" in
+ *el* ) : ;;
+ *eb* ) : ;;
+ *) multidirs="${multidirs} ${x}" ;;
+ esac
+ done
+ fi
+ if [ x$enable_softfloat = xno ]
+ then
+ old_multidirs="${multidirs}"
+ multidirs=""
+ for x in ${old_multidirs}; do
+ case "$x" in
+ *soft-float* ) : ;;
+ *) multidirs="${multidirs} ${x}" ;;
+ esac
+ done
+ fi
+ case " $multidirs " in
+ *" mabi=64 "*)
+ # We will not be able to create libraries with -mabi=64 if
+ # we cannot even link a trivial program. It usually
+ # indicates the 64bit libraries are missing.
+ if echo 'main() {}' > conftest.c &&
+ ${CC-gcc} -mabi=64 conftest.c -o conftest; then
+ :
+ else
+ echo Could not link program with -mabi=64, disabling it.
+ old_multidirs="${multidirs}"
+ multidirs=""
+ for x in ${old_multidirs}; do
+ case "$x" in
+ *mabi=64* ) : ;;
+ *) multidirs="${multidirs} ${x}" ;;
+ esac
+ done
+ fi
+ rm -f conftest.c conftest
+ ;;
+ esac
+ ;;
+powerpc*-*-* | rs6000*-*-*)
+ if [ x$enable_softfloat = xno ]
+ then
+ old_multidirs="${multidirs}"
+ multidirs=""
+ for x in ${old_multidirs}; do
+ case "$x" in
+ *soft-float* ) : ;;
+ *) multidirs="${multidirs} ${x}" ;;
+ esac
+ done
+ fi
+ if [ x$enable_powercpu = xno ]
+ then
+ old_multidirs="${multidirs}"
+ multidirs=""
+ for x in ${old_multidirs}; do
+ case "$x" in
+ power | */power | */power/* ) : ;;
+ *) multidirs="${multidirs} ${x}" ;;
+ esac
+ done
+ fi
+ if [ x$enable_powerpccpu = xno ]
+ then
+ old_multidirs="${multidirs}"
+ multidirs=""
+ for x in ${old_multidirs}; do
+ case "$x" in
+ *powerpc* ) : ;;
+ *) multidirs="${multidirs} ${x}" ;;
+ esac
+ done
+ fi
+ if [ x$enable_powerpcos = xno ]
+ then
+ old_multidirs="${multidirs}"
+ multidirs=""
+ for x in ${old_multidirs}; do
+ case "$x" in
+ *mcall-linux* | *mcall-solaris* ) : ;;
+ *) multidirs="${multidirs} ${x}" ;;
+ esac
+ done
+ fi
+ if [ x$enable_biendian = xno ]
+ then
+ old_multidirs="${multidirs}"
+ multidirs=""
+ for x in ${old_multidirs}; do
+ case "$x" in
+ *mlittle* | *mbig* ) : ;;
+ *) multidirs="${multidirs} ${x}" ;;
+ esac
+ done
+ fi
+ if [ x$enable_sysv = xno ]
+ then
+ old_multidirs="${multidirs}"
+ multidirs=""
+ for x in ${old_multidirs}; do
+ case "$x" in
+ *mcall-sysv* ) : ;;
+ *) multidirs="${multidirs} ${x}" ;;
+ esac
+ done
+ fi
+ if [ x$enable_aix = xno ]
+ then
+ old_multidirs="${multidirs}"
+ multidirs=""
+ for x in ${old_multidirs}; do
+ case "$x" in
+ *mcall-aix* ) : ;;
+ *) multidirs="${multidirs} ${x}" ;;
+ esac
+ done
+ fi
+ ;;
+sparc*-*-*)
+ case " $multidirs " in
+ *" m64 "*)
+ # We will not be able to create libraries with -m64 if
+ # we cannot even link a trivial program. It usually
+ # indicates the 64bit libraries are missing.
+ if echo 'main() {}' > conftest.c &&
+ ${CC-gcc} -m64 conftest.c -o conftest; then
+ :
+ else
+ echo Could not link program with -m64, disabling it.
+ old_multidirs="${multidirs}"
+ multidirs=""
+ for x in ${old_multidirs}; do
+ case "$x" in
+ *m64* ) : ;;
+ *) multidirs="${multidirs} ${x}" ;;
+ esac
+ done
+ fi
+ rm -f conftest.c conftest
+ ;;
+ esac
+ ;;
+esac
+
+# Remove extraneous blanks from multidirs.
+# Tests like `if [ -n "$multidirs" ]' require it.
+multidirs=`echo "$multidirs" | sed -e 's/^[ ][ ]*//' -e 's/[ ][ ]*$//' -e 's/[ ][ ]*/ /g'`
+
+# Add code to library's top level makefile to handle building the multilib
+# subdirs.
+
+cat > Multi.tem <<\EOF
+
+# FIXME: There should be an @-sign in front of the `if'.
+# Leave out until this is tested a bit more.
+multi-do:
+ if [ -z "$(MULTIDIRS)" ]; then \
+ true; \
+ else \
+ rootpre=`pwd`/; export rootpre; \
+ srcrootpre=`cd $(srcdir); pwd`/; export srcrootpre; \
+ lib=`echo $${rootpre} | sed -e 's,^.*/\([^/][^/]*\)/$$,\1,'`; \
+ compiler="$(CC)"; \
+ for i in `$${compiler} --print-multi-lib 2>/dev/null`; do \
+ dir=`echo $$i | sed -e 's/;.*$$//'`; \
+ if [ "$${dir}" = "." ]; then \
+ true; \
+ else \
+ if [ -d ../$${dir}/$${lib} ]; then \
+ flags=`echo $$i | sed -e 's/^[^;]*;//' -e 's/@/ -/g'`; \
+ if (cd ../$${dir}/$${lib}; $(MAKE) $(FLAGS_TO_PASS) \
+ CFLAGS="$(CFLAGS) $${flags}" \
+ prefix="$(prefix)" \
+ exec_prefix="$(exec_prefix)" \
+ GCJFLAGS="$(GCJFLAGS) $${flags}" \
+ CXXFLAGS="$(CXXFLAGS) $${flags}" \
+ LIBCFLAGS="$(LIBCFLAGS) $${flags}" \
+ LIBCXXFLAGS="$(LIBCXXFLAGS) $${flags}" \
+ LDFLAGS="$(LDFLAGS) $${flags}" \
+ $(DO)); then \
+ true; \
+ else \
+ exit 1; \
+ fi; \
+ else true; \
+ fi; \
+ fi; \
+ done; \
+ fi
+
+# FIXME: There should be an @-sign in front of the `if'.
+# Leave out until this is tested a bit more.
+multi-clean:
+ if [ -z "$(MULTIDIRS)" ]; then \
+ true; \
+ else \
+ lib=`pwd | sed -e 's,^.*/\([^/][^/]*\)$$,\1,'`; \
+ for dir in Makefile $(MULTIDIRS); do \
+ if [ -f ../$${dir}/$${lib}/Makefile ]; then \
+ if (cd ../$${dir}/$${lib}; $(MAKE) $(FLAGS_TO_PASS) $(DO)); \
+ then true; \
+ else exit 1; \
+ fi; \
+ else true; \
+ fi; \
+ done; \
+ fi
+EOF
+
+cat ${Makefile} Multi.tem > Makefile.tem
+rm -f ${Makefile} Multi.tem
+mv Makefile.tem ${Makefile}
+
+fi # ${ml_toplevel_p} = yes
+
+if [ "${ml_verbose}" = --verbose ]; then
+ echo "Adding multilib support to Makefile in ${ml_realsrcdir}"
+ if [ "${ml_toplevel_p}" = yes ]; then
+ echo "multidirs=${multidirs}"
+ fi
+ echo "with_multisubdir=${with_multisubdir}"
+fi
+
+if [ "${srcdir}" = "." ]; then
+ if [ "${with_target_subdir}" != "." ]; then
+ ml_srcdotdot="../"
+ else
+ ml_srcdotdot=""
+ fi
+else
+ ml_srcdotdot=""
+fi
+
+if [ -z "${with_multisubdir}" ]; then
+ ml_subdir=
+ ml_builddotdot=
+ : # ml_srcdotdot= # already set
+else
+ ml_subdir="/${with_multisubdir}"
+ # The '[^/][^/]*' appears that way to work around a SunOS sed bug.
+ ml_builddotdot=`echo ${with_multisubdir} | sed -e 's:[^/][^/]*:..:g'`/
+ if [ "$srcdir" = "." ]; then
+ ml_srcdotdot=${ml_srcdotdot}${ml_builddotdot}
+ else
+ : # ml_srcdotdot= # already set
+ fi
+fi
+
+if [ "${ml_toplevel_p}" = yes ]; then
+ ml_do='$(MAKE)'
+ ml_clean='$(MAKE)'
+else
+ ml_do=true
+ ml_clean=true
+fi
+
+# TOP is used by newlib and should not be used elsewhere for this purpose.
+# MULTI{SRC,BUILD}TOP are the proper ones to use. MULTISRCTOP is empty
+# when srcdir != builddir. MULTIBUILDTOP is always some number of ../'s.
+# FIXME: newlib needs to be updated to use MULTI{SRC,BUILD}TOP so we can
+# delete TOP. Newlib may wish to continue to use TOP for its own purposes
+# of course.
+# MULTIDIRS is non-empty for the cpu top level Makefile (eg: newlib/Makefile)
+# and lists the subdirectories to recurse into.
+# MULTISUBDIR is non-empty in each cpu subdirectory's Makefile
+# (eg: newlib/h8300h/Makefile) and is the installed subdirectory name with
+# a leading '/'.
+# MULTIDO is used for targets like all, install, and check where
+# $(FLAGS_TO_PASS) augmented with the subdir's compiler option is needed.
+# MULTICLEAN is used for the *clean targets.
+#
+# ??? It is possible to merge MULTIDO and MULTICLEAN into one. They are
+# currently kept separate because we don't want the *clean targets to require
+# the existence of the compiler (which MULTIDO currently requires) and
+# therefore we'd have to record the directory options as well as names
+# (currently we just record the names and use --print-multi-lib to get the
+# options).
+
+sed -e "s:^TOP[ ]*=[ ]*\([./]*\)[ ]*$:TOP = ${ml_builddotdot}\1:" \
+ -e "s:^MULTISRCTOP[ ]*=.*$:MULTISRCTOP = ${ml_srcdotdot}:" \
+ -e "s:^MULTIBUILDTOP[ ]*=.*$:MULTIBUILDTOP = ${ml_builddotdot}:" \
+ -e "s:^MULTIDIRS[ ]*=.*$:MULTIDIRS = ${multidirs}:" \
+ -e "s:^MULTISUBDIR[ ]*=.*$:MULTISUBDIR = ${ml_subdir}:" \
+ -e "s:^MULTIDO[ ]*=.*$:MULTIDO = $ml_do:" \
+ -e "s:^MULTICLEAN[ ]*=.*$:MULTICLEAN = $ml_clean:" \
+ ${Makefile} > Makefile.tem
+rm -f ${Makefile}
+mv Makefile.tem ${Makefile}
+
+# If this is the library's top level, configure each multilib subdir.
+# This is done at the end because this is the loop that runs configure
+# in each multilib subdir and it seemed reasonable to finish updating the
+# Makefile before going on to configure the subdirs.
+
+if [ "${ml_toplevel_p}" = yes ]; then
+
+# We must freshly configure each subdirectory. This bit of code is
+# actually partially stolen from the main configure script. FIXME.
+
+if [ -n "${multidirs}" ] && [ -z "${ml_norecursion}" ]; then
+
+ if [ "${ml_verbose}" = --verbose ]; then
+ echo "Running configure in multilib subdirs ${multidirs}"
+ echo "pwd: `pwd`"
+ fi
+
+ ml_origdir=`pwd`
+ ml_libdir=`echo $ml_origdir | sed -e 's,^.*/,,'`
+ # cd to top-level-build-dir/${with_target_subdir}
+ cd ..
+
+ for ml_dir in ${multidirs}; do
+
+ if [ "${ml_verbose}" = --verbose ]; then
+ echo "Running configure in multilib subdir ${ml_dir}"
+ echo "pwd: `pwd`"
+ fi
+
+ if [ -d ${ml_dir} ]; then true; else
+ # ``mkdir -p ${ml_dir}'' See also mkinstalldirs.
+ pathcomp=""
+ for d in `echo ":${ml_dir}" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'`; do
+ pathcomp="$pathcomp$d"
+ case "$pathcomp" in
+ -* ) pathcomp=./$pathcomp ;;
+ esac
+ if test ! -d "$pathcomp"; then
+ echo "mkdir $pathcomp" 1>&2
+ mkdir "$pathcomp" > /dev/null 2>&1 || lasterr=$?
+ fi
+ if test ! -d "$pathcomp"; then
+ exit $lasterr
+ fi
+ pathcomp="$pathcomp/"
+ done
+ fi
+ if [ -d ${ml_dir}/${ml_libdir} ]; then true; else mkdir ${ml_dir}/${ml_libdir}; fi
+
+ # Eg: if ${ml_dir} = m68000/m68881, dotdot = ../../
+ dotdot=../`echo ${ml_dir} | sed -e 's|[^/]||g' -e 's|/|../|g'`
+
+ case ${srcdir} in
+ ".")
+ echo Building symlink tree in `pwd`/${ml_dir}/${ml_libdir}
+ if [ "${with_target_subdir}" != "." ]; then
+ ml_unsubdir="../"
+ else
+ ml_unsubdir=""
+ fi
+ (cd ${ml_dir}/${ml_libdir};
+ ../${dotdot}${ml_unsubdir}symlink-tree ../${dotdot}${ml_unsubdir}${ml_libdir} "")
+ if [ -f ${ml_dir}/${ml_libdir}/Makefile ]; then
+ if [ x"${MAKE}" = x ]; then
+ (cd ${ml_dir}/${ml_libdir}; make distclean)
+ else
+ (cd ${ml_dir}/${ml_libdir}; ${MAKE} distclean)
+ fi
+ fi
+ ml_newsrcdir="."
+ ml_srcdiroption=
+ multisrctop=${dotdot}
+ ;;
+ *)
+ case "${srcdir}" in
+ /* | [A-Za-z]:[\\/]* ) # absolute path
+ ml_newsrcdir=${srcdir}
+ ;;
+ *) # otherwise relative
+ ml_newsrcdir=${dotdot}${srcdir}
+ ;;
+ esac
+ ml_srcdiroption="-srcdir=${ml_newsrcdir}"
+ multisrctop=
+ ;;
+ esac
+
+ case "${progname}" in
+ /* | [A-Za-z]:[\\/]* ) ml_recprog=${progname} ;;
+ *) ml_recprog=${dotdot}${progname} ;;
+ esac
+
+ # FIXME: POPDIR=${PWD=`pwd`} doesn't work here.
+ ML_POPDIR=`pwd`
+ cd ${ml_dir}/${ml_libdir}
+
+ if [ -f ${ml_newsrcdir}/configure ]; then
+ ml_recprog="${ml_newsrcdir}/configure --cache-file=../config.cache"
+ fi
+
+ # find compiler flag corresponding to ${ml_dir}
+ for i in `${CC-gcc} --print-multi-lib 2>/dev/null`; do
+ dir=`echo $i | sed -e 's/;.*$//'`
+ if [ "${dir}" = "${ml_dir}" ]; then
+ flags=`echo $i | sed -e 's/^[^;]*;//' -e 's/@/ -/g'`
+ break
+ fi
+ done
+ ml_config_env='CC="${CC_}$flags" CXX="${CXX_}$flags" GCJ="${GCJ_}$flags"'
+
+ if [ "${with_target_subdir}" = "." ]; then
+ CC_=$CC' '
+ CXX_=$CXX' '
+ GCJ_=$GCJ' '
+ else
+ # Create a regular expression that matches any string as long
+ # as ML_POPDIR.
+ popdir_rx=`echo ${ML_POPDIR} | sed 's,.,.,g'`
+ CC_=
+ for arg in ${CC}; do
+ case $arg in
+ -[BIL]"${ML_POPDIR}"/*)
+ CC_="${CC_}"`echo "X${arg}" | sed -n "s/X\\(-[BIL]${popdir_rx}\\).*/\\1/p"`/${ml_dir}`echo "X${arg}" | sed -n "s/X-[BIL]${popdir_rx}\\(.*\\)/\1/p"`' ' ;;
+ "${ML_POPDIR}"/*)
+ CC_="${CC_}"`echo "X${arg}" | sed -n "s/X\\(${popdir_rx}\\).*/\\1/p"`/${ml_dir}`echo "X${arg}" | sed -n "s/X${popdir_rx}\\(.*\\)/\\1/p"`' ' ;;
+ *)
+ CC_="${CC_}${arg} " ;;
+ esac
+ done
+
+ CXX_=
+ for arg in ${CXX}; do
+ case $arg in
+ -[BIL]"${ML_POPDIR}"/*)
+ CXX_="${CXX_}"`echo "X${arg}" | sed -n "s/X\\(-[BIL]${popdir_rx}\\).*/\\1/p"`/${ml_dir}`echo "X${arg}" | sed -n "s/X-[BIL]${popdir_rx}\\(.*\\)/\\1/p"`' ' ;;
+ "${ML_POPDIR}"/*)
+ CXX_="${CXX_}"`echo "X${arg}" | sed -n "s/X\\(${popdir_rx}\\).*/\\1/p"`/${ml_dir}`echo "X${arg}" | sed -n "s/X${popdir_rx}\\(.*\\)/\\1/p"`' ' ;;
+ *)
+ CXX_="${CXX_}${arg} " ;;
+ esac
+ done
+
+ GCJ_=
+ for arg in ${GCJ}; do
+ case $arg in
+ -[BIL]"${ML_POPDIR}"/*)
+ GCJ_="${GCJ_}"`echo "X${arg}" | sed -n "s/X\\(-[BIL]${popdir_rx}\\).*/\\1/p"`/${ml_dir}`echo "X${arg}" | sed -n "s/X-[BIL]${popdir_rx}\\(.*\\)/\\1/p"`' ' ;;
+ "${ML_POPDIR}"/*)
+ GCJ_="${GCJ_}"`echo "X${arg}" | sed -n "s/X\\(${popdir_rx}\\).*/\\1/p"`/${ml_dir}`echo "X${arg}" | sed -n "s/X${popdir_rx}\\(.*\\)/\\1/p"`' ' ;;
+ *)
+ GCJ_="${GCJ_}${arg} " ;;
+ esac
+ done
+
+ if test "x${LD_LIBRARY_PATH+set}" = xset; then
+ LD_LIBRARY_PATH_=
+ for arg in `echo "$LD_LIBRARY_PATH" | tr ':' ' '`; do
+ case "$arg" in
+ "${ML_POPDIR}"/*)
+ arg=`echo "X${arg}" | sed -n "s/X\\(${popdir_rx}\\).*/\\1/p"`/${ml_dir}`echo "X${arg}" | sed -n "s/X${popdir_rx}\\(.*\\)/\\1/p"`
+ ;;
+ esac
+ if test "x$LD_LIBRARY_PATH_" != x; then
+ LD_LIBRARY_PATH_=$LD_LIBRARY_PATH_:$arg
+ else
+ LD_LIBRARY_PATH_=$arg
+ fi
+ done
+ ml_config_env="$ml_config_env LD_LIBRARY_PATH=$LD_LIBRARY_PATH_"
+ fi
+
+ if test "x${SHLIB_PATH+set}" = xset; then
+ SHLIB_PATH_=
+ for arg in `echo "$SHLIB_PATH" | tr ':' ' '`; do
+ case "$arg" in
+ "${ML_POPDIR}"/*)
+ arg=`echo "X${arg}" | sed -n "s/X\\(${popdir_rx}\\).*/\\1/p"`/${ml_dir}`echo "X${arg}" | sed -n "s/X${popdir_rx}\\(.*\\)/\\1/p"`
+ ;;
+ esac
+ if test "x$SHLIB_PATH_" != x; then
+ SHLIB_PATH_=$SHLIB_PATH_:$arg
+ else
+ SHLIB_PATH_=$arg
+ fi
+ done
+ ml_config_env="$ml_config_env SHLIB_PATH=$SHLIB_PATH_"
+ fi
+ fi
+
+ if eval ${ml_config_env} ${ml_config_shell} ${ml_recprog} \
+ --with-multisubdir=${ml_dir} --with-multisrctop=${multisrctop} \
+ ${ml_arguments} ${ml_srcdiroption} ; then
+ true
+ else
+ exit 1
+ fi
+
+ cd ${ML_POPDIR}
+
+ done
+
+ cd ${ml_origdir}
+fi
+
+fi # ${ml_toplevel_p} = yes
+fi # ${enable_multilib} = yes
diff --git a/libffi/configure.in b/libffi/configure.in
new file mode 100644
index 00000000000..5e56ddc0c7c
--- /dev/null
+++ b/libffi/configure.in
@@ -0,0 +1,166 @@
+dnl Process this with autoconf to create configure
+AC_INIT(fficonfig.h.in)
+AM_CONFIG_HEADER(fficonfig.h)
+
+dnl Default to --enable-multilib
+AC_ARG_ENABLE(multilib,
+[ --enable-multilib build many library versions (default)],
+[case "${enableval}" in
+ yes) multilib=yes ;;
+ no) multilib=no ;;
+ *) AC_MSG_ERROR(bad value ${enableval} for multilib option) ;;
+ esac], [multilib=yes])dnl
+
+dnl We may get other options which we don't document:
+dnl --with-target-subdir, --with-multisrctop, --with-multisubdir
+
+### I don't understand this, so comment it out for now
+#if test "${srcdir}" = "."; then
+# if test "${with_target_subdir}" != "."; then
+# libffi_basedir="${srcdir}/${with_multisrctop}.."
+# else
+# libffi_basedir="${srcdir}/${with_multisrctop}"
+# fi
+#else
+ libffi_basedir="${srcdir}"
+#fi
+AC_SUBST(libffi_basedir)
+
+AC_CANONICAL_HOST
+
+AM_INIT_AUTOMAKE(libffi,2.00-beta,no-define)
+
+AC_EXEEXT
+AM_MAINTAINER_MODE
+
+AC_PROG_CC
+AC_PROG_RANLIB
+AC_PROG_LN_S
+
+dnl The -no-testsuite modules omit the test subdir.
+AM_CONDITIONAL(TESTSUBDIR, test -d $srcdir/testsuite)
+
+TARGET="unknown"
+case "$host" in
+ alpha*-*-linux* | alpha*-*-osf*)
+ TARGET=ALPHA;
+ $LN_S ${srcdir}/alpha/ffi.c t-ffi.c;
+ $LN_S $srcdir/alpha/osf.S t-asm.S;;
+ arm*-*-linux-*)
+ TARGET=ARM;
+ $LN_S $srcdir/arm/ffi.c t-ffi.c;
+ $LN_S $srcdir/arm/ffi.S t-asm.S;;
+ i*86-*-beos*|i*86-*-freebsd*|i*86-*-linux*|i*86-*-solaris*)
+ TARGET=X86;
+ $LN_S $srcdir/x86/ffi.c t-ffi.c;
+ $LN_S $srcdir/x86/sysv.S t-asm.S;;
+ i*86-*-cygwin*|i*86-*-mingw*|i*86-*-win32*)
+ TARGET=X86_WIN32;
+ $LN_S $srcdir/x86/ffi.c t-ffi.c;
+ $LN_S $srcdir/x86/win32.S t-asm.S;;
+ ia64*-*-*)
+ TARGET=IA64;
+ $LN_S $srcdir/ia64/ffi.c t-ffi.c;
+ $LN_S $srcdir/ia64/unix.S t-asm.S;;
+ m68k-*-linux*)
+ TARGET=M68K;
+ $LN_S $srcdir/m68k/ffi.c t-ffi.c;
+ $LN_S $srcdir/m68k/unix.S t-asm.S;;
+ mips-*-elf)
+ TARGET=MIPS;
+ $LN_S $srcdir/mips/ffi.c t-ffi.c;
+ $LN_S $srcdir/mips/o32.S t-asm.S;;
+ mips-sgi-irix5.*)
+ TARGET=MIPS;
+ $LN_S $srcdir/mips/ffi.c t-ffi.c;
+ $LN_S $srcdir/mips/o32.S t-asm.S;;
+ mips-sgi-irix6.*)
+ TARGET=MIPS;
+ $LN_S $srcdir/mips/ffi.c t-ffi.c;
+ $LN_S $srcdir/mips/n32.S t-asm.S;;
+ powerpc-*-linux* | powerpc-*-sysv* | powerpc-*-beos*)
+ TARGET=POWERPC;
+ $LN_S $srcdir/powerpc/ffi.c t-ffi.c;
+ $LN_S $srcdir/powerpc/sysv.S t-asm.S;;
+ s390-*-linux*)
+ TARGET=S390;
+ $LN_S $srcdir/s390/ffi.c t-ffi.c;
+ $LN_S $srcdir/s390/v8.S t-asm.S;;
+ sparc-*-linux*|sparc-sun-*)
+ TARGET=SPARC;
+ $LN_S $srcdir/sparc/ffi.c t-ffi.c;
+ $LN_S $srcdir/sparc/v8.S t-asm.S;;
+ sparc64-*-linux*)
+ TARGET=SPARC;
+ $LN_S $srcdir/sparc/ffi.c t-ffi.c;
+ $LN_S $srcdir/sparc/v9.S t-asm.S;;
+esac
+
+AC_SUBST(AM_RUNTESTFLAGS)
+
+if test ${TARGET} = unknown; then
+ AC_ERROR("libffi has not been ported to $host.")
+fi
+
+AC_HEADER_STDC
+AC_CHECK_FUNCS(memcpy)
+AC_FUNC_ALLOCA
+
+dnl AC_CHECK_SIZEOF(char)
+AC_COMPILE_CHECK_SIZEOF(short)
+AC_COMPILE_CHECK_SIZEOF(int)
+AC_COMPILE_CHECK_SIZEOF(long)
+AC_COMPILE_CHECK_SIZEOF(long long)
+AC_COMPILE_CHECK_SIZEOF(float)
+AC_COMPILE_CHECK_SIZEOF(double)
+AC_COMPILE_CHECK_SIZEOF(long double)
+
+AC_COMPILE_CHECK_SIZEOF(void *)
+AC_C_BIGENDIAN_CROSS
+
+AC_SUBST(TARGET)
+AC_SUBST(TARGETDIR)
+
+AC_SUBST(SHELL)
+
+AC_ARG_ENABLE(debug,[ --enable-debug debugging mode], AC_DEFINE(FFI_DEBUG))
+
+AC_ARG_ENABLE(debug,[ --disable-structs omit code for struct support], AC_DEFINE(FFI_NO_STRUCTS))
+
+AC_ARG_ENABLE(debug,[ --disable-raw-api make the raw api unavailable], AC_DEFINE(FFI_NO_RAW_API))
+
+AC_ARG_ENABLE(purify-safety,
+[ --enable-purify-safety purify-safe mode], AC_DEFINE(USING_PURIFY))
+
+AM_CONDITIONAL(USE_LIBDIR, test -z "$with_cross_host")
+
+if test "${multilib}" = "yes"; then
+ multilib_arg="--enable-multilib"
+else
+ multilib_arg=
+fi
+
+AC_OUTPUT(include/Makefile testsuite/Makefile Makefile,
+[
+if test -n "$CONFIG_FILES"; then
+ ac_file=Makefile . ${libffi_basedir}/config-ml.in
+fi
+],
+srcdir=${srcdir}
+host=${host}
+target=${target}
+with_multisubdir=${with_multisubdir}
+ac_configure_args="${multilib_arg} ${ac_configure_args}"
+CONFIG_SHELL=${CONFIG_SHELL-/bin/sh}
+libffi_basedir=${libffi_basedir}
+CC="${CC}"
+DEFS="$DEFS"
+test ! -d include && mkdir include
+test ! -f include/fficonfig.h && cp fficonfig.h include/fficonfig.h
+if cmp -s fficonfig.h include/fficonfig.h 2>/dev/null; then
+ echo fficonfig.h unchanged
+else
+ echo Moving fficonfig.h to include/fficonfig.h
+ cp fficonfig.h include/fficonfig.h
+fi
+)
diff --git a/libffi/debug.c b/libffi/debug.c
new file mode 100644
index 00000000000..42416594d5f
--- /dev/null
+++ b/libffi/debug.c
@@ -0,0 +1,65 @@
+/* -----------------------------------------------------------------------
+ debug.c - Copyright (c) 1996 Red Hat, Inc.
+
+ 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 RED HAT 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.
+ ----------------------------------------------------------------------- */
+
+#include <ffi.h>
+#include <ffi_private.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+/* General debugging routines */
+
+void ffi_stop_here(void)
+{
+ /* This function is only useful for debugging purposes.
+ Place a breakpoint on ffi_stop_here to be notified of
+ significant events. */
+}
+
+/* This function should only be called via the FFI_ASSERT() macro */
+
+int ffi_assert(char *file, int line)
+{
+ fprintf(stderr, "ASSERTION FAILURE: %s line %d\n", file, line);
+ ffi_stop_here();
+ abort();
+
+ /* This has to return something for the compiler not to complain */
+ /*@notreached@*/
+ return 0;
+}
+
+/* Perform a sanity check on an ffi_type structure */
+
+bool ffi_type_test(ffi_type *a)
+{
+ /*@-usedef@*/
+ FFI_ASSERT(a->type <= FFI_TYPE_LAST);
+ FFI_ASSERT(a->type > FFI_TYPE_VOID ? a->size > 0 : 1);
+ FFI_ASSERT(a->type > FFI_TYPE_VOID ? a->alignment > 0 : 1);
+ FFI_ASSERT(a->type == FFI_TYPE_STRUCT ? a->elements != NULL : 1);
+ /*@=usedef@*/
+
+ /* This is a silly thing to return, but it keeps the compiler from
+ issuing warnings about "a" not being used in non-debug builds. */
+ return (a != NULL);
+}
diff --git a/libffi/ffitest.c b/libffi/ffitest.c
new file mode 100644
index 00000000000..70fecb1c652
--- /dev/null
+++ b/libffi/ffitest.c
@@ -0,0 +1,736 @@
+/* -----------------------------------------------------------------------
+ ffitest.c - Copyright (c) 1996, 1997, 1998 Cygnus Solutions
+
+ 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 RED HAT 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.
+ ----------------------------------------------------------------------- */
+
+#include <ffi.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <float.h>
+
+/* This is lame. Long double support is barely there under SunOS 4.x */
+#if defined(__sparc__) && (SIZEOF_LONG_DOUBLE != 16)
+#define BROKEN_LONG_DOUBLE
+#endif
+
+#define CHECK(x) !(x) ? fail(__FILE__, __LINE__) : 0
+
+static int fail(char *file, int line)
+{
+ fprintf(stderr, "Test failure: %s line %d\n", file, line);
+ exit(EXIT_FAILURE);
+ /*@notreached@*/
+ return 0;
+}
+
+#define MAX_ARGS 256
+
+static size_t my_strlen(char *s)
+{
+ return (strlen(s));
+}
+
+static int promotion(signed char sc, signed short ss,
+ unsigned char uc, unsigned short us)
+{
+ int r = (int) sc + (int) ss + (int) uc + (int) us;
+
+ return r;
+}
+
+static signed char return_sc(signed char sc)
+{
+ return sc;
+}
+
+static unsigned char return_uc(unsigned char uc)
+{
+ return uc;
+}
+
+static long long return_ll(long long ll)
+{
+ return ll;
+}
+
+static int floating(int a, float b, double c, long double d, int e)
+{
+ int i;
+
+#if 0
+ /* This is ifdef'd out for now. long double support under SunOS/gcc
+ is pretty much non-existent. You'll get the odd bus error in library
+ routines like printf(). */
+ printf("%d %f %f %Lf %d\n", a, (double)b, c, d, e);
+#endif
+
+ i = (int) ((float)a/b + ((float)c/(float)d));
+
+ return i;
+}
+
+static float many(float f1,
+ float f2,
+ float f3,
+ float f4,
+ float f5,
+ float f6,
+ float f7,
+ float f8,
+ float f9,
+ float f10,
+ float f11,
+ float f12,
+ float f13)
+{
+#if 0
+ printf("%f %f %f %f %f %f %f %f %f %f %f %f %f\n",
+ (double) f1, (double) f2, (double) f3, (double) f4, (double) f5,
+ (double) f6, (double) f7, (double) f8, (double) f9, (double) f10,
+ (double) f11, (double) f12, (double) f13);
+#endif
+
+ return ((f1/f2+f3/f4+f5/f6+f7/f8+f9/f10+f11/f12) * f13);
+}
+
+static double dblit(float f)
+{
+ return f/3.0;
+}
+
+static long double ldblit(float f)
+{
+ return (long double) (((long double) f)/ (long double) 3.0);
+}
+
+typedef struct
+{
+ unsigned char uc;
+ double d;
+ unsigned int ui;
+} test_structure_1;
+
+typedef struct
+{
+ double d1;
+ double d2;
+} test_structure_2;
+
+typedef struct
+{
+ int si;
+} test_structure_3;
+
+typedef struct
+{
+ unsigned ui1;
+ unsigned ui2;
+ unsigned ui3;
+} test_structure_4;
+
+typedef struct
+{
+ char c1;
+ char c2;
+} test_structure_5;
+
+static test_structure_1 struct1(test_structure_1 ts)
+{
+ /*@-type@*/
+ ts.uc++;
+ /*@=type@*/
+ ts.d--;
+ ts.ui++;
+
+ return ts;
+}
+
+static test_structure_2 struct2(test_structure_2 ts)
+{
+ ts.d1--;
+ ts.d2--;
+
+ return ts;
+}
+
+static test_structure_3 struct3(test_structure_3 ts)
+{
+ ts.si = -(ts.si*2);
+
+ return ts;
+}
+
+static test_structure_4 struct4(test_structure_4 ts)
+{
+ ts.ui3 = ts.ui1 * ts.ui2 * ts.ui3;
+
+ return ts;
+}
+
+static test_structure_5 struct5(test_structure_5 ts1, test_structure_5 ts2)
+{
+ ts1.c1 += ts2.c1;
+ ts1.c2 -= ts2.c2;
+
+ return ts1;
+}
+
+/* Take an int and a float argument, together with int userdata, and */
+/* return the sum. */
+static void closure_test_fn(ffi_cif* cif,void* resp,void** args, void* userdata)
+{
+ *(int*)resp =
+ *(int *)args[0] + (int)(*(float *)args[1]) + (int)(long)userdata;
+}
+
+typedef int (*closure_test_type)(int, float);
+
+int main(/*@unused@*/ int argc, /*@unused@*/ char *argv[])
+{
+ ffi_cif cif;
+ ffi_type *args[MAX_ARGS];
+ void *values[MAX_ARGS];
+ char *s;
+ signed char sc;
+ unsigned char uc;
+ signed short ss;
+ unsigned short us;
+ unsigned long ul;
+ long long ll;
+ float f;
+ double d;
+ long double ld;
+ signed int si1;
+ signed int si2;
+
+#if defined(__alpha__) || defined(IA64) || defined(SPARC64) || (defined(__mips__) && (_MIPS_SIM == _ABIN32))
+ long long rint;
+#else
+ int rint;
+#endif
+ long long rlonglong;
+
+ ffi_type ts1_type;
+ ffi_type ts2_type;
+ ffi_type ts3_type;
+ ffi_type ts4_type;
+ ffi_type ts5_type;
+ ffi_type *ts1_type_elements[4];
+ ffi_type *ts2_type_elements[3];
+ ffi_type *ts3_type_elements[2];
+ ffi_type *ts4_type_elements[4];
+ ffi_type *ts5_type_elements[3];
+
+ ts1_type.size = 0;
+ ts1_type.alignment = 0;
+ ts1_type.type = FFI_TYPE_STRUCT;
+
+ ts2_type.size = 0;
+ ts2_type.alignment = 0;
+ ts2_type.type = FFI_TYPE_STRUCT;
+
+ ts3_type.size = 0;
+ ts3_type.alignment = 0;
+ ts3_type.type = FFI_TYPE_STRUCT;
+
+ ts4_type.size = 0;
+ ts4_type.alignment = 0;
+ ts4_type.type = FFI_TYPE_STRUCT;
+
+ ts5_type.size = 0;
+ ts5_type.alignment = 0;
+ ts5_type.type = FFI_TYPE_STRUCT;
+
+ /*@-immediatetrans@*/
+ ts1_type.elements = ts1_type_elements;
+ ts2_type.elements = ts2_type_elements;
+ ts3_type.elements = ts3_type_elements;
+ ts4_type.elements = ts4_type_elements;
+ ts5_type.elements = ts5_type_elements;
+ /*@=immediatetrans@*/
+
+ ts1_type_elements[0] = &ffi_type_uchar;
+ ts1_type_elements[1] = &ffi_type_double;
+ ts1_type_elements[2] = &ffi_type_uint;
+ ts1_type_elements[3] = NULL;
+
+ ts2_type_elements[0] = &ffi_type_double;
+ ts2_type_elements[1] = &ffi_type_double;
+ ts2_type_elements[2] = NULL;
+
+ ts3_type_elements[0] = &ffi_type_sint;
+ ts3_type_elements[1] = NULL;
+
+ ts4_type_elements[0] = &ffi_type_uint;
+ ts4_type_elements[1] = &ffi_type_uint;
+ ts4_type_elements[2] = &ffi_type_uint;
+ ts4_type_elements[3] = NULL;
+
+ ts5_type_elements[0] = &ffi_type_schar;
+ ts5_type_elements[1] = &ffi_type_schar;
+ ts5_type_elements[2] = NULL;
+
+ ul = 0;
+
+ /* return value tests */
+ {
+#if defined(__mips__) /* || defined(ARM) */
+ puts ("long long tests not run. This is a known bug on this architecture.");
+#else
+ args[0] = &ffi_type_sint64;
+ values[0] = &ll;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
+ &ffi_type_sint64, args) == FFI_OK);
+
+ for (ll = 0LL; ll < 100LL; ll++)
+ {
+ ul++;
+ ffi_call(&cif, FFI_FN(return_ll), &rlonglong, values);
+ CHECK(rlonglong == ll);
+ }
+
+ for (ll = 55555555555000LL; ll < 55555555555100LL; ll++)
+ {
+ ul++;
+ ffi_call(&cif, FFI_FN(return_ll), &rlonglong, values);
+ CHECK(rlonglong == ll);
+ }
+#endif
+
+ args[0] = &ffi_type_schar;
+ values[0] = &sc;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
+ &ffi_type_schar, args) == FFI_OK);
+
+ for (sc = (signed char) -127;
+ sc < (signed char) 127; /*@-type@*/ sc++ /*@=type@*/)
+ {
+ ul++;
+ ffi_call(&cif, FFI_FN(return_sc), &rint, values);
+ CHECK(rint == (int) sc);
+ }
+
+ args[0] = &ffi_type_uchar;
+ values[0] = &uc;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
+ &ffi_type_uchar, args) == FFI_OK);
+
+ for (uc = (unsigned char) '\x00';
+ uc < (unsigned char) '\xff'; /*@-type@*/ uc++ /*@=type@*/)
+ {
+ ul++;
+ ffi_call(&cif, FFI_FN(return_uc), &rint, values);
+ CHECK(rint == (signed int) uc);
+ }
+
+ printf("%lu return value tests run\n", ul);
+ }
+
+#ifdef BROKEN_LONG_DOUBLE
+ printf ("This architecture has broken `long double' support. No floating point\ntests have been run.\n");
+#else
+ /* float arg tests */
+ {
+ args[0] = &ffi_type_float;
+ values[0] = &f;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
+ &ffi_type_longdouble, args) == FFI_OK);
+
+ f = 3.14159;
+
+#if 0
+ /* This is ifdef'd out for now. long double support under SunOS/gcc
+ is pretty much non-existent. You'll get the odd bus error in library
+ routines like printf(). */
+ printf ("%Lf\n", ldblit(f));
+#endif
+ ld = 666;
+ ffi_call(&cif, FFI_FN(ldblit), &ld, values);
+
+#if 0
+ /* This is ifdef'd out for now. long double support under SunOS/gcc
+ is pretty much non-existent. You'll get the odd bus error in library
+ routines like printf(). */
+ printf ("%Lf, %Lf, %Lf, %Lf\n", ld, ldblit(f), ld - ldblit(f), LDBL_EPSILON);
+#endif
+
+ /* These are not always the same!! Check for a reasonable delta */
+ /*@-realcompare@*/
+ if (ld - ldblit(f) < LDBL_EPSILON)
+ /*@=realcompare@*/
+ puts("long double return value tests ok!");
+ else
+ CHECK(0);
+ }
+
+ /* float arg tests */
+ {
+ args[0] = &ffi_type_sint;
+ values[0] = &si1;
+ args[1] = &ffi_type_float;
+ values[1] = &f;
+ args[2] = &ffi_type_double;
+ values[2] = &d;
+ args[3] = &ffi_type_longdouble;
+ values[3] = &ld;
+ args[4] = &ffi_type_sint;
+ values[4] = &si2;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 5,
+ &ffi_type_sint, args) == FFI_OK);
+
+ si1 = 6;
+ f = 3.14159;
+ d = (double)1.0/(double)3.0;
+ ld = 2.71828182846L;
+ si2 = 10;
+
+ floating (si1, f, d, ld, si2);
+
+ ffi_call(&cif, FFI_FN(floating), &rint, values);
+
+ printf ("%d vs %d\n", rint, floating (si1, f, d, ld, si2));
+
+ CHECK(rint == floating(si1, f, d, ld, si2));
+
+ printf("float arg tests ok!\n");
+ }
+#endif
+
+ /* strlen tests */
+ {
+ args[0] = &ffi_type_pointer;
+ values[0] = (void*) &s;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
+ &ffi_type_sint, args) == FFI_OK);
+
+ s = "a";
+ ffi_call(&cif, FFI_FN(my_strlen), &rint, values);
+ CHECK(rint == 1);
+
+ s = "1234567";
+ ffi_call(&cif, FFI_FN(my_strlen), &rint, values);
+ CHECK(rint == 7);
+
+ s = "1234567890123456789012345";
+ ffi_call(&cif, FFI_FN(my_strlen), &rint, values);
+ CHECK(rint == 25);
+
+ printf("strlen tests passed\n");
+ }
+
+ /* float arg tests */
+ {
+ args[0] = &ffi_type_float;
+ values[0] = &f;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
+ &ffi_type_double, args) == FFI_OK);
+
+ f = 3.14159;
+
+ ffi_call(&cif, FFI_FN(dblit), &d, values);
+
+ /* These are not always the same!! Check for a reasonable delta */
+ /*@-realcompare@*/
+ CHECK(d - dblit(f) < DBL_EPSILON);
+ /*@=realcompare@*/
+
+ printf("double return value tests ok!\n");
+ }
+
+ /* many arg tests */
+ {
+ float ff;
+ float fa[13];
+
+ for (ul = 0; ul < 13; ul++)
+ {
+ args[ul] = &ffi_type_float;
+ values[ul] = &fa[ul];
+ fa[ul] = (float) ul;
+ }
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 13,
+ &ffi_type_float, args) == FFI_OK);
+
+ /*@-usedef@*/
+ ff = many(fa[0], fa[1],
+ fa[2], fa[3],
+ fa[4], fa[5],
+ fa[6], fa[7],
+ fa[8], fa[9],
+ fa[10],fa[11],fa[12]);
+ /*@=usedef@*/
+
+ ffi_call(&cif, FFI_FN(many), &f, values);
+
+ /*@-realcompare@*/
+ if (f - ff < FLT_EPSILON)
+ /*@=realcompare@*/
+ printf("many arg tests ok!\n");
+ else
+#ifdef POWERPC
+ printf("many arg tests failed! This is a gcc bug.\n");
+#else
+ CHECK(0);
+#endif
+ }
+
+ /* promotion tests */
+ {
+ args[0] = &ffi_type_schar;
+ args[1] = &ffi_type_sshort;
+ args[2] = &ffi_type_uchar;
+ args[3] = &ffi_type_ushort;
+ values[0] = &sc;
+ values[1] = &ss;
+ values[2] = &uc;
+ values[3] = &us;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4,
+ &ffi_type_sint, args) == FFI_OK);
+
+ us = 0;
+ ul = 0;
+
+ for (sc = (signed char) -127;
+ sc <= (signed char) 120; /*@-type@*/ sc += 1 /*@=type@*/)
+ for (ss = -30000; ss <= 30000; ss += 10000)
+ for (uc = (unsigned char) 0;
+ uc <= (unsigned char) 200; /*@-type@*/ uc += 20 /*@=type@*/)
+ for (us = 0; us <= 60000; us += 10000)
+ {
+ ul++;
+ ffi_call(&cif, FFI_FN(promotion), &rint, values);
+ CHECK(rint == (int) sc + (int) ss + (int) uc + (int) us);
+ }
+ printf("%lu promotion tests run\n", ul);
+ }
+
+#ifndef X86_WIN32 /* Structures dont work on Win32 */
+
+ /* struct tests */
+ {
+ test_structure_1 ts1_arg;
+ /* This is a hack to get a properly aligned result buffer */
+ test_structure_1 *ts1_result =
+ (test_structure_1 *) malloc (sizeof(test_structure_1));
+
+ args[0] = &ts1_type;
+ values[0] = &ts1_arg;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
+ &ts1_type, args) == FFI_OK);
+
+ ts1_arg.uc = '\x01';
+ ts1_arg.d = 3.14159;
+ ts1_arg.ui = 555;
+
+ ffi_call(&cif, FFI_FN(struct1), ts1_result, values);
+
+ CHECK(ts1_result->ui == 556);
+ CHECK(ts1_result->d == 3.14159 - 1);
+
+ puts ("structure test 1 ok!\n");
+
+ free (ts1_result);
+ }
+
+ /* struct tests */
+ {
+ test_structure_2 ts2_arg;
+
+ /* This is a hack to get a properly aligned result buffer */
+ test_structure_2 *ts2_result =
+ (test_structure_2 *) malloc (sizeof(test_structure_2));
+
+ args[0] = &ts2_type;
+ values[0] = &ts2_arg;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
+ &ts2_type, args) == FFI_OK);
+
+ ts2_arg.d1 = 5.55;
+ ts2_arg.d2 = 6.66;
+
+ printf ("%g\n", ts2_result->d1);
+ printf ("%g\n", ts2_result->d2);
+
+ ffi_call(&cif, FFI_FN(struct2), ts2_result, values);
+
+ printf ("%g\n", ts2_result->d1);
+ printf ("%g\n", ts2_result->d2);
+
+ CHECK(ts2_result->d1 == 5.55 - 1);
+ CHECK(ts2_result->d2 == 6.66 - 1);
+
+ printf("structure test 2 ok!\n");
+
+ free (ts2_result);
+ }
+
+ /* struct tests */
+ {
+ int compare_value;
+ test_structure_3 ts3_arg;
+ test_structure_3 *ts3_result =
+ (test_structure_3 *) malloc (sizeof(test_structure_3));
+
+ args[0] = &ts3_type;
+ values[0] = &ts3_arg;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
+ &ts3_type, args) == FFI_OK);
+
+ ts3_arg.si = -123;
+ compare_value = ts3_arg.si;
+
+ ffi_call(&cif, FFI_FN(struct3), ts3_result, values);
+
+ printf ("%d %d\n", ts3_result->si, -(compare_value*2));
+
+ if (ts3_result->si == -(ts3_arg.si*2))
+ puts ("structure test 3 ok!");
+ else
+ {
+ puts ("Structure test 3 found structure passing bug.");
+ puts (" Current versions of GCC are not 100% compliant with the");
+ puts (" n32 ABI. There is a known problem related to passing");
+ puts (" small structures. Send a bug report to the gcc maintainers.");
+ }
+
+ free (ts3_result);
+ }
+
+ /* struct tests */
+ {
+ test_structure_4 ts4_arg;
+
+ /* This is a hack to get a properly aligned result buffer */
+ test_structure_4 *ts4_result =
+ (test_structure_4 *) malloc (sizeof(test_structure_4));
+
+ args[0] = &ts4_type;
+ values[0] = &ts4_arg;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
+ &ts4_type, args) == FFI_OK);
+
+ ts4_arg.ui1 = 2;
+ ts4_arg.ui2 = 3;
+ ts4_arg.ui3 = 4;
+
+ ffi_call (&cif, FFI_FN(struct4), ts4_result, values);
+
+ if (ts4_result->ui3 == 2U * 3U * 4U)
+ puts ("structure test 4 ok!");
+ else
+ puts ("Structure test 4 found GCC's structure passing bug.");
+
+ free (ts4_result);
+ }
+
+ /* struct tests */
+ {
+ test_structure_5 ts5_arg1, ts5_arg2;
+
+ /* This is a hack to get a properly aligned result buffer */
+ test_structure_5 *ts5_result =
+ (test_structure_5 *) malloc (sizeof(test_structure_5));
+
+ args[0] = &ts5_type;
+ args[1] = &ts5_type;
+ values[0] = &ts5_arg1;
+ values[1] = &ts5_arg2;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2,
+ &ts5_type, args) == FFI_OK);
+
+ ts5_arg1.c1 = 2;
+ ts5_arg1.c2 = 6;
+ ts5_arg2.c1 = 5;
+ ts5_arg2.c2 = 3;
+
+ ffi_call (&cif, FFI_FN(struct5), ts5_result, values);
+
+ if (ts5_result->c1 == 7
+ && ts5_result->c2 == 3)
+ puts ("structure test 5 ok!");
+ else
+ puts ("Structure test 5 found GCC's structure passing bug.");
+
+ free (ts5_result);
+ }
+
+#else
+ printf("Structure passing doesn't work on Win32.\n");
+#endif /* X86_WIN32 */
+
+# if FFI_CLOSURES
+ /* A simple closure test */
+ {
+ ffi_closure cl;
+ ffi_type * cl_arg_types[3];
+
+ cl_arg_types[0] = &ffi_type_sint;
+ cl_arg_types[1] = &ffi_type_float;
+ cl_arg_types[2] = NULL;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2,
+ &ffi_type_sint, cl_arg_types) == FFI_OK);
+
+ CHECK(ffi_prep_closure(&cl, &cif, closure_test_fn,
+ (void *) 3 /* userdata */)
+ == FFI_OK);
+ CHECK((*((closure_test_type)(&cl)))(1, 2.0) == 6);
+ }
+# endif
+
+ /* If we arrived here, all is good */
+ (void) puts("\nLooks good. No surprises.\n");
+
+ /*@-compdestroy@*/
+
+ return 0;
+}
+
diff --git a/libffi/ia64/ffi.c b/libffi/ia64/ffi.c
new file mode 100644
index 00000000000..c84f86f7c6a
--- /dev/null
+++ b/libffi/ia64/ffi.c
@@ -0,0 +1,670 @@
+/* -----------------------------------------------------------------------
+ ffi.c - Copyright (c) 1998 Cygnus Solutions
+ Copyright (c) 2000 Hewlett Packard Company
+
+ IA64 Foreign Function Interface
+
+ 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 CYGNUS SOLUTIONS 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.
+ ----------------------------------------------------------------------- */
+
+#include <ffi.h>
+#include <ffi_private.h>
+
+#include <stdlib.h>
+
+#include "ia64_flags.h"
+
+/* Memory image of fp register contents. Should eventually be an fp */
+/* type long enough to hold an entire register. For now we use double. */
+typedef double float80;
+
+/* The stack layout at call to ffi_prep_regs. Other_args will remain */
+/* on the stack for the actual call. Everything else we be transferred */
+/* to registers and popped by the assembly code. */
+
+struct ia64_args {
+ long scratch[2]; /* Two scratch words at top of stack. */
+ /* Allows sp to passed as arg pointer. */
+ void * r8_contents; /* Value to be passed in r8 */
+ long spare; /* Not used. */
+ float80 fp_regs[8]; /* Contents of 8 floating point argument */
+ /* registers. */
+ long out_regs[8]; /* Contents of the 8 out registers used */
+ /* for integer parameters. */
+ long other_args[0]; /* Arguments passed on stack, variable size */
+ /* Treated as continuation of out_regs. */
+};
+
+static size_t float_type_size(unsigned short tp)
+{
+ switch(tp) {
+ case FFI_TYPE_FLOAT:
+ return sizeof(float);
+ case FFI_TYPE_DOUBLE:
+ return sizeof(double);
+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+ case FFI_TYPE_LONGDOUBLE:
+ return sizeof(long double);
+#endif
+ default:
+ FFI_ASSERT(0);
+ }
+}
+
+/*
+ * Is type a struct containing at most n floats, doubles, or extended
+ * doubles, all of the same fp type?
+ * If so, set *element_type to the fp type.
+ */
+static bool is_homogeneous_fp_aggregate(ffi_type * type, int n,
+ unsigned short * element_type)
+{
+ ffi_type **ptr;
+ unsigned short element, struct_element;
+
+ int type_set = 0;
+
+ FFI_ASSERT(type != NULL);
+
+ FFI_ASSERT(type->elements != NULL);
+
+ ptr = &(type->elements[0]);
+
+ while ((*ptr) != NULL)
+ {
+ switch((*ptr) -> type) {
+ case FFI_TYPE_FLOAT:
+ if (type_set && element != FFI_TYPE_FLOAT) return 0;
+ if (--n < 0) return FALSE;
+ type_set = 1;
+ element = FFI_TYPE_FLOAT;
+ break;
+ case FFI_TYPE_DOUBLE:
+ if (type_set && element != FFI_TYPE_DOUBLE) return 0;
+ if (--n < 0) return FALSE;
+ type_set = 1;
+ element = FFI_TYPE_DOUBLE;
+ break;
+ case FFI_TYPE_STRUCT:
+ if (!is_homogeneous_fp_aggregate(type, n, &struct_element))
+ return FALSE;
+ if (type_set && struct_element != element) return FALSE;
+ n -= (type -> size)/float_type_size(element);
+ element = struct_element;
+ if (n < 0) return FALSE;
+ break;
+ /* case FFI_TYPE_LONGDOUBLE:
+ Not yet implemented. */
+ default:
+ return FALSE;
+ }
+ ptr++;
+ }
+ *element_type = element;
+ return TRUE;
+
+}
+
+/* ffi_prep_args is called by the assembly routine once stack space
+ has been allocated for the function's arguments. Returns nonzero
+ if fp registers are used for arguments. */
+
+static bool
+ffi_prep_args(struct ia64_args *stack, extended_cif *ecif, int bytes)
+{
+ register long i, avn;
+ register void **p_argv;
+ register long *argp = stack -> out_regs;
+ register float80 *fp_argp = stack -> fp_regs;
+ register ffi_type **p_arg;
+
+ /* For big return structs, r8 needs to contain the target address. */
+ /* Since r8 is otherwise dead, we set it unconditionally. */
+ stack -> r8_contents = ecif -> rvalue;
+ i = 0;
+ avn = ecif->cif->nargs;
+ p_arg = ecif->cif->arg_types;
+ p_argv = ecif->avalue;
+ while (i < avn)
+ {
+ size_t z; /* z is in units of arg slots or words, not bytes. */
+
+ switch ((*p_arg)->type)
+ {
+ case FFI_TYPE_SINT8:
+ z = 1;
+ *(SINT64 *) argp = *(SINT8 *)(* p_argv);
+ break;
+
+ case FFI_TYPE_UINT8:
+ z = 1;
+ *(UINT64 *) argp = *(UINT8 *)(* p_argv);
+ break;
+
+ case FFI_TYPE_SINT16:
+ z = 1;
+ *(SINT64 *) argp = *(SINT16 *)(* p_argv);
+ break;
+
+ case FFI_TYPE_UINT16:
+ z = 1;
+ *(UINT64 *) argp = *(UINT16 *)(* p_argv);
+ break;
+
+ case FFI_TYPE_SINT32:
+ z = 1;
+ *(SINT64 *) argp = *(SINT32 *)(* p_argv);
+ break;
+
+ case FFI_TYPE_UINT32:
+ z = 1;
+ *(UINT64 *) argp = *(UINT32 *)(* p_argv);
+ break;
+
+ case FFI_TYPE_SINT64:
+ case FFI_TYPE_UINT64:
+ case FFI_TYPE_POINTER:
+ z = 1;
+ *(UINT64 *) argp = *(UINT64 *)(* p_argv);
+ break;
+
+ case FFI_TYPE_FLOAT:
+ z = 1;
+ if (fp_argp - stack->fp_regs < 8)
+ {
+ /* Note the conversion -- all the fp regs are loaded as
+ doubles. */
+ *fp_argp++ = *(float *)(* p_argv);
+ }
+ /* Also put it into the integer registers or memory: */
+ *(UINT64 *) argp = *(UINT32 *)(* p_argv);
+ break;
+
+ case FFI_TYPE_DOUBLE:
+ z = 1;
+ if (fp_argp - stack->fp_regs < 8)
+ *fp_argp++ = *(double *)(* p_argv);
+ /* Also put it into the integer registers or memory: */
+ *(double *) argp = *(double *)(* p_argv);
+ break;
+
+ case FFI_TYPE_STRUCT:
+ {
+ size_t sz = (*p_arg)->size;
+ unsigned short element_type;
+ z = ((*p_arg)->size + SIZEOF_ARG - 1)/SIZEOF_ARG;
+ if (is_homogeneous_fp_aggregate(*p_arg, 8, &element_type)) {
+ int i;
+ int nelements = sz/float_type_size(element_type);
+ for (i = 0; i < nelements; ++i) {
+ switch (element_type) {
+ case FFI_TYPE_FLOAT:
+ if (fp_argp - stack->fp_regs < 8)
+ *fp_argp++ = ((float *)(* p_argv))[i];
+ break;
+ case FFI_TYPE_DOUBLE:
+ if (fp_argp - stack->fp_regs < 8)
+ *fp_argp++ = ((double *)(* p_argv))[i];
+ break;
+ default:
+ /* Extended precision not yet implemented. */
+ abort();
+ }
+ }
+ }
+ /* And pass it in integer registers as a struct, with */
+ /* its actual field sizes packed into registers. */
+ memcpy(argp, *p_argv, (*p_arg)->size);
+ }
+ break;
+
+ default:
+ FFI_ASSERT(0);
+ }
+
+ argp += z;
+ i++, p_arg++, p_argv++;
+ }
+ return (fp_argp != stack -> fp_regs);
+}
+
+/* Perform machine dependent cif processing */
+ffi_status
+ffi_prep_cif_machdep(ffi_cif *cif)
+{
+ long i, avn;
+ bool is_simple = TRUE;
+ long simple_flag = FFI_SIMPLE_V;
+ /* Adjust cif->bytes to include space for the 2 scratch words,
+ r8 register contents, spare word,
+ the 8 fp register contents, and all 8 integer register contents.
+ This will be removed before the call, though 2 scratch words must
+ remain. */
+
+ cif->bytes += 4*sizeof(long) + 8 *sizeof(float80);
+ if (cif->bytes < sizeof(struct ia64_args))
+ cif->bytes = sizeof(struct ia64_args);
+
+ /* The stack must be double word aligned, so round bytes up
+ appropriately. */
+
+ cif->bytes = ALIGN(cif->bytes, 2*sizeof(void*));
+
+ avn = cif->nargs;
+ if (avn <= 2) {
+ for (i = 0; i < avn; ++i) {
+ switch(cif -> arg_types[i] -> type) {
+ case FFI_TYPE_SINT32:
+ simple_flag = FFI_ADD_INT_ARG(simple_flag);
+ break;
+ case FFI_TYPE_SINT64:
+ case FFI_TYPE_UINT64:
+ case FFI_TYPE_POINTER:
+ simple_flag = FFI_ADD_LONG_ARG(simple_flag);
+ break;
+ default:
+ is_simple = FALSE;
+ }
+ }
+ } else {
+ is_simple = FALSE;
+ }
+
+ /* Set the return type flag */
+ switch (cif->rtype->type)
+ {
+ case FFI_TYPE_VOID:
+ cif->flags = FFI_TYPE_VOID;
+ break;
+
+ case FFI_TYPE_STRUCT:
+ {
+ size_t sz = cif -> rtype -> size;
+ unsigned short element_type;
+
+ is_simple = FALSE;
+ if (is_homogeneous_fp_aggregate(cif -> rtype, 8, &element_type)) {
+ int nelements = sz/float_type_size(element_type);
+ if (nelements <= 1) {
+ if (0 == nelements) {
+ cif -> flags = FFI_TYPE_VOID;
+ } else {
+ cif -> flags = element_type;
+ }
+ } else {
+ switch(element_type) {
+ case FFI_TYPE_FLOAT:
+ cif -> flags = FFI_IS_FLOAT_FP_AGGREGATE | nelements;
+ break;
+ case FFI_TYPE_DOUBLE:
+ cif -> flags = FFI_IS_DOUBLE_FP_AGGREGATE | nelements;
+ break;
+ default:
+ /* long double NYI */
+ abort();
+ }
+ }
+ break;
+ }
+ if (sz <= 32) {
+ if (sz <= 8) {
+ cif->flags = FFI_TYPE_INT;
+ } else if (sz <= 16) {
+ cif->flags = FFI_IS_SMALL_STRUCT2;
+ } else if (sz <= 24) {
+ cif->flags = FFI_IS_SMALL_STRUCT3;
+ } else {
+ cif->flags = FFI_IS_SMALL_STRUCT4;
+ }
+ } else {
+ cif->flags = FFI_TYPE_STRUCT;
+ }
+ }
+ break;
+
+ case FFI_TYPE_FLOAT:
+ is_simple = FALSE;
+ cif->flags = FFI_TYPE_FLOAT;
+ break;
+
+ case FFI_TYPE_DOUBLE:
+ is_simple = FALSE;
+ cif->flags = FFI_TYPE_DOUBLE;
+ break;
+
+ default:
+ cif->flags = FFI_TYPE_INT;
+ /* This seems to depend on little endian mode, and the fact that */
+ /* the return pointer always points to at least 8 bytes. But */
+ /* that also seems to be true for other platforms. */
+ break;
+ }
+
+ if (is_simple) cif -> flags |= simple_flag;
+ return FFI_OK;
+}
+
+extern int ffi_call_unix(bool (*)(struct ia64_args *, extended_cif *, int),
+ extended_cif *, unsigned,
+ unsigned, unsigned *, void (*)());
+
+void
+ffi_call(ffi_cif *cif, void (*fn)(), void *rvalue, void **avalue)
+{
+ extended_cif ecif;
+ long simple = cif -> flags & FFI_SIMPLE;
+
+ /* Should this also check for Unix ABI? */
+ /* This is almost, but not quite, machine independent. Note that */
+ /* we can get away with not caring about length of the result because */
+ /* we assume we are little endian, and the result buffer is large */
+ /* enough. */
+ /* This needs work for HP/UX. */
+ if (simple) {
+ long (*lfn)() = (long (*)())fn;
+ long result;
+ switch(simple) {
+ case FFI_SIMPLE_V:
+ result = lfn();
+ break;
+ case FFI_SIMPLE_I:
+ result = lfn(*(int *)avalue[0]);
+ break;
+ case FFI_SIMPLE_L:
+ result = lfn(*(long *)avalue[0]);
+ break;
+ case FFI_SIMPLE_II:
+ result = lfn(*(int *)avalue[0], *(int *)avalue[1]);
+ break;
+ case FFI_SIMPLE_IL:
+ result = lfn(*(int *)avalue[0], *(long *)avalue[1]);
+ break;
+ case FFI_SIMPLE_LI:
+ result = lfn(*(long *)avalue[0], *(int *)avalue[1]);
+ break;
+ case FFI_SIMPLE_LL:
+ result = lfn(*(long *)avalue[0], *(long *)avalue[1]);
+ break;
+ }
+ if ((cif->flags & ~FFI_SIMPLE) != FFI_TYPE_VOID && 0 != rvalue) {
+ * (long *)rvalue = result;
+ }
+ return;
+ }
+ ecif.cif = cif;
+ ecif.avalue = avalue;
+
+ /* If the return value is a struct and we don't have a return
+ value address then we need to make one. */
+
+ if (rvalue == NULL && cif->rtype->type == FFI_TYPE_STRUCT)
+ ecif.rvalue = alloca(cif->rtype->size);
+ else
+ ecif.rvalue = rvalue;
+
+ switch (cif->abi)
+ {
+ case FFI_UNIX:
+ ffi_call_unix(ffi_prep_args, &ecif, cif->bytes,
+ cif->flags, rvalue, fn);
+ break;
+
+ default:
+ FFI_ASSERT(0);
+ break;
+ }
+}
+
+/*
+ * Closures represent a pair consisting of a function pointer, and
+ * some user data. A closure is invoked by reinterpreting the closure
+ * as a function pointer, and branching to it. Thus we can make an
+ * interpreted function callable as a C function: We turn the interpreter
+ * itself, together with a pointer specifying the interpreted procedure,
+ * into a closure.
+ * On X86, the first few words of the closure structure actually contain code,
+ * which will do the right thing. On most other architectures, this
+ * would raise some Icache/Dcache coherence issues (which can be solved, but
+ * often not cheaply).
+ * For IA64, function pointer are already pairs consisting of a code
+ * pointer, and a gp pointer. The latter is needed to access global variables.
+ * Here we set up such a pair as the first two words of the closure (in
+ * the "trampoline" area), but we replace the gp pointer with a pointer
+ * to the closure itself. We also add the real gp pointer to the
+ * closure. This allows the function entry code to both retrieve the
+ * user data, and to restire the correct gp pointer.
+ */
+
+static void
+ffi_prep_incoming_args_UNIX(struct ia64_args *args, void **rvalue,
+ void **avalue, ffi_cif *cif);
+
+/* This function is entered with the doctored gp (r1) value.
+ * This code is extremely gcc specific. There is some argument that
+ * it should really be written in assembly code, since it depends on
+ * gcc properties that might change over time.
+ */
+
+/* ffi_closure_UNIX is an assembly routine, which copies the register */
+/* state into s struct ia64_args, and the invokes */
+/* ffi_closure_UNIX_inner. It also recovers the closure pointer */
+/* from its fake gp pointer. */
+void ffi_closure_UNIX();
+
+#ifndef __GNUC__
+# error This requires gcc
+#endif
+void
+ffi_closure_UNIX_inner (ffi_closure *closure, struct ia64_args * args)
+/* Hopefully declarint this as a varargs function will force all args */
+/* to memory. */
+{
+ // this is our return value storage
+ long double res;
+
+ // our various things...
+ ffi_cif *cif;
+ unsigned short rtype;
+ void *resp;
+ void **arg_area;
+
+ resp = (void*)&res;
+ cif = closure->cif;
+ arg_area = (void**) alloca (cif->nargs * sizeof (void*));
+
+ /* this call will initialize ARG_AREA, such that each
+ * element in that array points to the corresponding
+ * value on the stack; and if the function returns
+ * a structure, it will re-set RESP to point to the
+ * structure return address. */
+
+ ffi_prep_incoming_args_UNIX(args, (void**)&resp, arg_area, cif);
+
+ (closure->fun) (cif, resp, arg_area, closure->user_data);
+
+ rtype = cif->flags;
+
+ /* now, do a generic return based on the value of rtype */
+ if (rtype == FFI_TYPE_INT)
+ {
+ asm volatile ("ld8 r8=[%0]" : : "r" (resp) : "r8");
+ }
+ else if (rtype == FFI_TYPE_FLOAT)
+ {
+ asm volatile ("ldfs f8=[%0]" : : "r" (resp) : "f8");
+ }
+ else if (rtype == FFI_TYPE_DOUBLE)
+ {
+ asm volatile ("ldfd f8=[%0]" : : "r" (resp) : "f8");
+ }
+ else if (rtype == FFI_IS_SMALL_STRUCT2)
+ {
+ asm volatile ("ld8 r8=[%0]; ld8 r9=[%1]"
+ : : "r" (resp), "r" (resp+8) : "r8","r9");
+ }
+ else if (rtype == FFI_IS_SMALL_STRUCT3)
+ {
+ asm volatile ("ld8 r8=[%0]; ld8 r9=[%1]; ld8 r10=[%2]"
+ : : "r" (resp), "r" (resp+8), "r" (resp+16)
+ : "r8","r9","r10");
+ }
+ else if (rtype == FFI_IS_SMALL_STRUCT4)
+ {
+ asm volatile ("ld8 r8=[%0]; ld8 r9=[%1]; ld8 r10=[%2]; ld8 r11=[%3]"
+ : : "r" (resp), "r" (resp+8), "r" (resp+16), "r" (resp+24)
+ : "r8","r9","r10","r11");
+ }
+ else if (rtype != FFI_TYPE_VOID && rtype != FFI_TYPE_STRUCT)
+ {
+ /* Can only happen for homogeneous FP aggregates? */
+ abort();
+ }
+}
+
+static void
+ffi_prep_incoming_args_UNIX(struct ia64_args *args, void **rvalue,
+ void **avalue, ffi_cif *cif)
+{
+ register unsigned int i;
+ register unsigned int avn;
+ register void **p_argv;
+ register unsigned long *argp = args -> out_regs;
+ unsigned fp_reg_num = 0;
+ register ffi_type **p_arg;
+
+ avn = cif->nargs;
+ p_argv = avalue;
+
+ for (i = cif->nargs, p_arg = cif->arg_types; i != 0; i--, p_arg++)
+ {
+ size_t z; /* In units of words or argument slots. */
+
+ switch ((*p_arg)->type)
+ {
+ case FFI_TYPE_SINT8:
+ case FFI_TYPE_UINT8:
+ case FFI_TYPE_SINT16:
+ case FFI_TYPE_UINT16:
+ case FFI_TYPE_SINT32:
+ case FFI_TYPE_UINT32:
+ case FFI_TYPE_SINT64:
+ case FFI_TYPE_UINT64:
+ case FFI_TYPE_POINTER:
+ z = 1;
+ *p_argv = (void *)argp;
+ break;
+
+ case FFI_TYPE_FLOAT:
+ z = 1;
+ /* Convert argument back to float in place from the saved value */
+ if (fp_reg_num < 8) {
+ *(float *)argp = args -> fp_regs[fp_reg_num++];
+ } else {
+ *(float *)argp = *(double *)argp;
+ }
+ *p_argv = (void *)argp;
+ break;
+
+ case FFI_TYPE_DOUBLE:
+ z = 1;
+ if (fp_reg_num < 8) {
+ *p_argv = args -> fp_regs + fp_reg_num++;
+ } else {
+ *p_argv = (void *)argp;
+ }
+ break;
+
+ case FFI_TYPE_STRUCT:
+ {
+ size_t sz = (*p_arg)->size;
+ unsigned short element_type;
+ z = ((*p_arg)->size + SIZEOF_ARG - 1)/SIZEOF_ARG;
+ if (is_homogeneous_fp_aggregate(*p_arg, 8, &element_type)) {
+ int nelements = sz/float_type_size(element_type);
+ if (nelements + fp_reg_num >= 8) {
+ /* hard case NYI. */
+ abort();
+ }
+ if (element_type == FFI_TYPE_DOUBLE) {
+ *p_argv = args -> fp_regs + fp_reg_num;
+ fp_reg_num += nelements;
+ break;
+ }
+ if (element_type == FFI_TYPE_FLOAT) {
+ int j;
+ for (j = 0; j < nelements; ++ j) {
+ ((float *)argp)[j] = args -> fp_regs[fp_reg_num + j];
+ }
+ *p_argv = (void *)argp;
+ fp_reg_num += nelements;
+ break;
+ }
+ abort(); /* Other fp types NYI */
+ }
+ }
+ break;
+
+ default:
+ FFI_ASSERT(0);
+ }
+
+ argp += z;
+ p_argv++;
+
+ }
+
+ return;
+}
+
+
+/* Fill in a closure to refer to the specified fun and user_data. */
+/* cif specifies the argument and result types for fun. */
+/* the cif must already be prep'ed */
+
+/* The layout of a function descriptor. A C function pointer really */
+/* points to one of these. */
+typedef struct ia64_fd_struct {
+ void *code_pointer;
+ void *gp;
+} ia64_fd;
+
+ffi_status
+ffi_prep_closure (ffi_closure* closure,
+ ffi_cif* cif,
+ void (*fun)(ffi_cif*,void*,void**,void*),
+ void *user_data)
+{
+ struct ffi_ia64_trampoline_struct *tramp =
+ (struct ffi_ia64_trampoline_struct *) (closure -> tramp);
+ ia64_fd *fd = (ia64_fd *)(void *)ffi_closure_UNIX;
+
+ FFI_ASSERT (cif->abi == FFI_UNIX);
+
+ tramp -> code_pointer = fd -> code_pointer;
+ tramp -> real_gp = fd -> gp;
+ tramp -> fake_gp = closure;
+ closure->cif = cif;
+ closure->user_data = user_data;
+ closure->fun = fun;
+
+ return FFI_OK;
+}
+
+
diff --git a/libffi/ia64/ia64_flags.h b/libffi/ia64/ia64_flags.h
new file mode 100644
index 00000000000..23dbd3e0237
--- /dev/null
+++ b/libffi/ia64/ia64_flags.h
@@ -0,0 +1,62 @@
+/* -----------------------------------------------------------------------
+ ia64_flags.h - Copyright (c) 2000 Hewlett Packard Company
+
+ IA64/unix Foreign Function Interface
+
+ Original author: Hans Boehm, HP Labs
+
+ 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 CYGNUS SOLUTIONS 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.
+ ----------------------------------------------------------------------- */
+
+
+/* Homogeneous Floating Point Aggregates (HFAs) which are returned */
+/* in FP registers. The least significant bits specify the size in */
+/* words. */
+#define FFI_IS_FLOAT_FP_AGGREGATE 0x1000
+#define FFI_IS_DOUBLE_FP_AGGREGATE 0x0800
+#define FLOAT_FP_AGGREGATE_BIT 12
+#define DOUBLE_FP_AGGREGATE_BIT 11
+
+/* Small structures containing N words. If N=1, they are returned */
+/* as though they were integers. */
+#define FFI_IS_SMALL_STRUCT2 0x40 /* Struct > 8, <=16 bytes */
+#define FFI_IS_SMALL_STRUCT3 0x41 /* Struct > 16 <= 24 bytes */
+#define FFI_IS_SMALL_STRUCT4 0x42 /* Struct > 24, <=32 bytes */
+
+/* Flag values identifying particularly simple cases, which are */
+/* handled specially. We treat functions as simple if they take all */
+/* arguments can be passed as 32 or 64 bit integer quantities, there is */
+/* either no return value or it can be treated as a 64bit integer, and */
+/* if there are at most 2 arguments. */
+/* This is OR'ed with the normal flag values. */
+#define FFI_SIMPLE_V 0x10000 /* () -> X */
+#define FFI_SIMPLE_I 0x20000 /* (int) -> X */
+#define FFI_SIMPLE_L 0x30000 /* (long) -> X */
+#define FFI_SIMPLE_II 0x40000 /* (int,int) -> X */
+#define FFI_SIMPLE_IL 0x50000 /* (int,long) -> X */
+#define FFI_SIMPLE_LI 0x60000 /* (long,int) -> X */
+#define FFI_SIMPLE_LL 0x70000 /* (long,long) -> X */
+
+/* Mask for all of the FFI_SIMPLE bits: */
+#define FFI_SIMPLE 0xf0000
+
+/* An easy way to build FFI_SIMPLE flags from FFI_SIMPLE_V: */
+#define FFI_ADD_LONG_ARG(flag) (((flag) << 1) | 0x10000)
+#define FFI_ADD_INT_ARG(flag) ((flag) << 1)
diff --git a/libffi/ia64/unix.S b/libffi/ia64/unix.S
new file mode 100644
index 00000000000..fdaf8be28ad
--- /dev/null
+++ b/libffi/ia64/unix.S
@@ -0,0 +1,301 @@
+/* -----------------------------------------------------------------------
+ unix.S - Copyright (c) 1998 Cygnus Solutions
+ Copyright (c) 2000 Hewlett Packard Company
+
+ IA64/unix Foreign Function Interface
+
+ Primary author: Hans Boehm, HP Labs
+
+ Loosely modeled on Cygnus code for other platforms.
+
+ 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 CYGNUS SOLUTIONS 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.
+ ----------------------------------------------------------------------- */
+
+#define LIBFFI_ASM
+#include <ffi.h>
+#include "ia64_flags.h"
+
+/* parameters: */
+#define callback in0
+#define ecifp in1
+#define bytes in2
+#define flags in3
+#define raddr in4
+#define fn in5
+
+#define FLOAT_SZ 8 /* in-memory size of fp operands */
+
+.text
+ .align 16
+ .global ffi_call_unix#
+ .proc ffi_call_unix#
+ffi_call_unix:
+ alloc loc0=ar.pfs,6,5,8,0
+ mov loc1=b0;
+ sub sp=sp,bytes
+ mov loc4=r1 /* Save gp */
+ ld8 r8=[callback],8 /* code address of callback */
+ ;;
+ mov out0=sp
+ mov out1=ecifp
+ mov out2=bytes
+ ld8 r1=[callback] /* Set up gp for callback. Unnecessary? */
+ mov b6=r8
+ ;;
+ br.call.sptk.many b0 = b6 /* call ffi_prep_args */
+ cmp.eq p6,p0=0,r8 /* r8 nonzero ==> need fp regs */
+ ;;
+(p6) add loc2=32+8*FLOAT_SZ,sp
+(p6) br.cond.dptk.many fp_done
+ ;; /* Quiets warning; needed? */
+ add loc2=32,sp
+ add loc3=32+FLOAT_SZ,sp
+ ;;
+ ldfd f8=[loc2],2*FLOAT_SZ
+ ldfd f9=[loc3],2*FLOAT_SZ
+ ;;
+ ldfd f10=[loc2],2*FLOAT_SZ
+ ldfd f11=[loc3],2*FLOAT_SZ
+ ;;
+ ldfd f12=[loc2],2*FLOAT_SZ
+ ldfd f13=[loc3],2*FLOAT_SZ
+ ;;
+ ldfd f14=[loc2],2*FLOAT_SZ
+ ldfd f15=[loc3]
+fp_done:
+ add r9=16,sp /* Pointer to r8_contents */
+ /* loc2 points at first integer register value. */
+ add loc3=8,loc2
+ ;;
+ ld8 r8=[r9] /* Just in case we return large struct */
+ ld8 out0=[loc2],16
+ ld8 out1=[loc3],16
+ ;;
+ ld8 out2=[loc2],16
+ ld8 out3=[loc3],16
+ ;;
+ ld8 out4=[loc2],16
+ ld8 out5=[loc3],16
+ ;;
+ ld8 out6=[loc2],16
+ ld8 out7=[loc3]
+ /* loc2 points at first stack parameter. Set sp to 16 bytes */
+ /* below that. */
+ add sp=-16,loc2
+
+ ld8 r8=[fn],8
+ ;;
+ ld8 r1=[fn] /* Set up gp */
+ mov b6=r8;;
+ br.call.sptk.many b0 = b6 /* call ffi_prep_args */
+
+ /* Handle return value. */
+ cmp.eq p6,p0=0,raddr
+ cmp.eq p7,p0=FFI_TYPE_INT,flags
+ cmp.eq p10,p0=FFI_IS_SMALL_STRUCT2,flags
+ cmp.eq p11,p0=FFI_IS_SMALL_STRUCT3,flags
+ cmp.eq p12,p0=FFI_IS_SMALL_STRUCT4,flags
+ ;;
+(p6) br.cond.dpnt.few done /* Dont copy ret values if raddr = 0 */
+(p7) br.cond.dptk.few copy1
+(p10) br.cond.dpnt.few copy2
+(p11) br.cond.dpnt.few copy3
+(p12) br.cond.dpnt.few copy4
+ cmp.eq p8,p0=FFI_TYPE_FLOAT,flags
+ cmp.eq p9,p0=FFI_TYPE_DOUBLE,flags
+ tbit.nz p6,p0=flags,FLOAT_FP_AGGREGATE_BIT
+ tbit.nz p7,p0=flags,DOUBLE_FP_AGGREGATE_BIT
+ ;;
+(p8) stfs [raddr]=f8
+(p9) stfd [raddr]=f8
+ ;;
+(p6) br.cond.dpnt.few handle_float_hfa
+(p7) br.cond.dpnt.few handle_double_hfa
+ br done
+
+copy4:
+ add loc3=24,raddr
+ ;;
+ st8 [loc3]=r11
+copy3:
+ add loc3=16,raddr
+ ;;
+ st8 [loc3]=r10
+copy2:
+ add loc3=8,raddr
+ ;;
+ st8 [loc3]=r9
+copy1:
+ st8 [raddr]=r8
+ /* In the big struct case, raddr was passed as an argument. */
+ /* In the void case there was nothing to do. */
+
+done:
+ mov r1=loc4 /* Restore gp */
+ mov ar.pfs = loc0
+ mov b0 = loc1
+ br.ret.sptk.many b0
+
+handle_double_hfa:
+ /* Homogeneous floating point array of doubles is returned in */
+ /* registers f8-f15. Save one at a time to return area. */
+ and flags=0xf,flags /* Retrieve size */
+ ;;
+ cmp.eq p6,p0=2,flags
+ cmp.eq p7,p0=3,flags
+ cmp.eq p8,p0=4,flags
+ cmp.eq p9,p0=5,flags
+ cmp.eq p10,p0=6,flags
+ cmp.eq p11,p0=7,flags
+ cmp.eq p12,p0=8,flags
+ ;;
+(p6) br.cond.dptk.few dhfa2
+(p7) br.cond.dptk.few dhfa3
+(p8) br.cond.dptk.few dhfa4
+(p9) br.cond.dptk.few dhfa5
+(p10) br.cond.dptk.few dhfa6
+(p11) br.cond.dptk.few dhfa7
+dhfa8: add loc3=7*8,raddr
+ ;;
+ stfd [loc3]=f15
+dhfa7: add loc3=6*8,raddr
+ ;;
+ stfd [loc3]=f14
+dhfa6: add loc3=5*8,raddr
+ ;;
+ stfd [loc3]=f13
+dhfa5: add loc3=4*8,raddr
+ ;;
+ stfd [loc3]=f12
+dhfa4: add loc3=3*8,raddr
+ ;;
+ stfd [loc3]=f11
+dhfa3: add loc3=2*8,raddr
+ ;;
+ stfd [loc3]=f10
+dhfa2: add loc3=1*8,raddr
+ ;;
+ stfd [loc3]=f9
+ stfd [raddr]=f8
+ br done
+
+handle_float_hfa:
+ /* Homogeneous floating point array of floats is returned in */
+ /* registers f8-f15. Save one at a time to return area. */
+ and flags=0xf,flags /* Retrieve size */
+ ;;
+ cmp.eq p6,p0=2,flags
+ cmp.eq p7,p0=3,flags
+ cmp.eq p8,p0=4,flags
+ cmp.eq p9,p0=5,flags
+ cmp.eq p10,p0=6,flags
+ cmp.eq p11,p0=7,flags
+ cmp.eq p12,p0=8,flags
+ ;;
+(p6) br.cond.dptk.few shfa2
+(p7) br.cond.dptk.few shfa3
+(p8) br.cond.dptk.few shfa4
+(p9) br.cond.dptk.few shfa5
+(p10) br.cond.dptk.few shfa6
+(p11) br.cond.dptk.few shfa7
+shfa8: add loc3=7*4,raddr
+ ;;
+ stfd [loc3]=f15
+shfa7: add loc3=6*4,raddr
+ ;;
+ stfd [loc3]=f14
+shfa6: add loc3=5*4,raddr
+ ;;
+ stfd [loc3]=f13
+shfa5: add loc3=4*4,raddr
+ ;;
+ stfd [loc3]=f12
+shfa4: add loc3=3*4,raddr
+ ;;
+ stfd [loc3]=f11
+shfa3: add loc3=2*4,raddr
+ ;;
+ stfd [loc3]=f10
+shfa2: add loc3=1*4,raddr
+ ;;
+ stfd [loc3]=f9
+ stfd [raddr]=f8
+ br done
+
+ .endp ffi_call_unix
+
+
+.text
+ .align 16
+ .global ffi_closure_UNIX
+ .proc ffi_closure_UNIX
+ffi_closure_UNIX:
+ alloc loc0=ar.pfs,8,2,2,0
+ mov loc1=b0
+ /* Retrieve closure pointer and real gp. */
+ mov out0=gp
+ add gp=16,gp
+ ;;
+ ld8 gp=[gp]
+ /* Reserve a structia64_args on the stack such that arguments */
+ /* past the first 8 are automatically placed in the right */
+ /* slot. Note that when we start the sp points at 2 8-byte */
+ /* scratch words, followed by the extra arguments. */
+# define BASIC_ARGS_SZ (8*FLOAT_SZ+8*8+2*8)
+# define FIRST_FP_OFFSET (4*8)
+ add r14=-(BASIC_ARGS_SZ-FIRST_FP_OFFSET),sp
+ add r15=-(BASIC_ARGS_SZ-FIRST_FP_OFFSET-FLOAT_SZ),sp
+ add sp=-BASIC_ARGS_SZ,sp
+ /* r14 points to fp_regs[0], r15 points to fp_regs[1] */
+ ;;
+ stfd [r14]=f8,2*FLOAT_SZ
+ stfd [r15]=f9,2*FLOAT_SZ
+ ;;
+ stfd [r14]=f10,2*FLOAT_SZ
+ stfd [r15]=f11,2*FLOAT_SZ
+ ;;
+ stfd [r14]=f12,2*FLOAT_SZ
+ stfd [r15]=f13,2*FLOAT_SZ
+ ;;
+ stfd [r14]=f14,FLOAT_SZ+8
+ stfd [r15]=f15,2*8
+ ;;
+ /* r14 points to first parameter register area, r15 to second. */
+ st8 [r14]=in0,2*8
+ st8 [r15]=in1,2*8
+ ;;
+ st8 [r14]=in2,2*8
+ st8 [r15]=in3,2*8
+ ;;
+ st8 [r14]=in4,2*8
+ st8 [r15]=in5,2*8
+ ;;
+ st8 [r14]=in6,2*8
+ st8 [r15]=in7,2*8
+ /* Call ffi_closure_UNIX_inner */
+ mov out1=sp
+ br.call.sptk.many b0=ffi_closure_UNIX_inner
+ ;;
+ mov b0=loc1
+ mov ar.pfs=loc0
+ br.ret.sptk.many b0
+ .endp ffi_closure_UNIX
+
+
diff --git a/libffi/include/.cvsignore b/libffi/include/.cvsignore
new file mode 100644
index 00000000000..030cac18450
--- /dev/null
+++ b/libffi/include/.cvsignore
@@ -0,0 +1,3 @@
+fficonfig.h
+Makefile
+Makefile.in
diff --git a/libffi/include/Makefile.am b/libffi/include/Makefile.am
new file mode 100644
index 00000000000..525984f70cb
--- /dev/null
+++ b/libffi/include/Makefile.am
@@ -0,0 +1,6 @@
+## Process this with automake to create Makefile.in
+
+AUTOMAKE_OPTIONS = foreign
+
+noinst_HEADERS=ffi_private.h
+include_HEADERS=ffi.h
diff --git a/libffi/include/ffi.h b/libffi/include/ffi.h
new file mode 100644
index 00000000000..1ad4acf10e2
--- /dev/null
+++ b/libffi/include/ffi.h
@@ -0,0 +1,393 @@
+/* -----------------------------------------------------------------*-C-*-
+ libffi 2.0.0 - Copyright (C) 1996, 1997, 1998, 1999, 2000,
+ 2001 Red Hat, Inc.
+
+ 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 RED HAT 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.
+
+ ----------------------------------------------------------------------- */
+
+/* -------------------------------------------------------------------
+ The basic API is described in the README file.
+
+ The raw API is designed to bypass some of the argument packing
+ and unpacking on architectures for which it can be avoided.
+
+ The closure API allows interpreted functions to be packaged up
+ inside a C function pointer, so that they can be called as C functions,
+ with no understanding on the client side that they are interpreted.
+ It can also be used in other cases in which it is necessary to package
+ up a user specified parameter and a function pointer as a single
+ function pointer.
+
+ The closure API must be implemented in order to get its functionality,
+ e.g. for use by gij. Routines are provided to emulate the raw API
+ if the underlying platform doesn't allow faster implementation.
+
+ More details on the raw and cloure API can be found in:
+
+ http://gcc.gnu.org/ml/java/1999-q3/msg00138.html
+
+ and
+
+ http://gcc.gnu.org/ml/java/1999-q3/msg00174.html
+ -------------------------------------------------------------------- */
+
+#ifndef FFI_H
+#define FFI_H
+
+#if !defined(__ASSEMBLER__) && !defined(__GNUC__)
+#error --- ffi.h requires GNU C ---
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if !defined(LIBFFI_ASM)
+#include <stddef.h>
+#if defined(FFI_DEBUG)
+#include <stdio.h>
+#endif
+#endif
+
+#ifndef LIBFFI_ASM
+
+/* ---- Generic type definitions ----------------------------------------- */
+
+typedef enum ffi_abi {
+
+ /* Leave this for debugging purposes */
+ FFI_FIRST_ABI = 0,
+
+ /* ---- Sparc -------------------- */
+#ifdef __sparc__
+ FFI_V8,
+ FFI_V8PLUS,
+ FFI_V9,
+#if defined(__arch64__) || defined(__sparcv9)
+ FFI_DEFAULT_ABI = FFI_V9,
+#else
+ FFI_DEFAULT_ABI = FFI_V8,
+#endif
+#endif
+
+ /* ---- Intel x86 ---------------- */
+#ifdef __i386__
+ FFI_SYSV,
+ FFI_DEFAULT_ABI = FFI_SYSV,
+#endif
+
+ /* ---- Intel ia64 ---------------- */
+#ifdef __ia64__
+ FFI_UNIX, /* Linux and all Unix variants use the same conventions */
+ FFI_DEFAULT_ABI = FFI_UNIX,
+#endif
+
+ /* ---- Mips --------------------- */
+#ifdef __mips__
+ FFI_O32,
+ FFI_N32,
+ FFI_N64,
+
+# if defined(__mips_eabi)
+# define FFI_MIPS_EABI
+# define FFI_MIPS_O32
+# else
+# if !defined(_MIPS_SIM)
+#error -- something is very wrong --
+# else
+# if _MIPS_SIM==_ABIN32 && defined(_ABIN32)
+# define FFI_MIPS_N32
+# else
+# define FFI_MIPS_O32
+# endif
+# endif
+# endif
+# if defined(FFI_MIPS_O32)
+ FFI_DEFAULT_ABI = FFI_O32,
+# else
+ FFI_DEFAULT_ABI = FFI_N32,
+# endif
+
+#endif
+
+ /* ---- Alpha -------------------- */
+#ifdef __alpha__
+ FFI_OSF,
+ FFI_DEFAULT_ABI = FFI_OSF,
+#endif
+
+ /* ---- Motorola m68k ------------ */
+#ifdef __m68k__
+ FFI_SYSV,
+ FFI_DEFAULT_ABI = FFI_SYSV,
+#endif
+
+ /* ---- PowerPC ------------------ */
+#ifdef __powerpc__
+ FFI_SYSV,
+ FFI_GCC_SYSV,
+ FFI_DEFAULT_ABI = FFI_GCC_SYSV,
+#endif
+
+ /* ---- ARM --------------------- */
+#ifdef __arm__
+ FFI_SYSV,
+ FFI_DEFAULT_ABI = FFI_SYSV,
+#endif
+
+ /* ---- S390 --------------------- */
+#ifdef __S390__
+ FFI_SYSV,
+ FFI_DEFAULT_ABI = FFI_SYSV,
+#endif
+
+ /* Leave this for debugging purposes */
+ FFI_LAST_ABI
+
+} ffi_abi;
+
+typedef struct _ffi_type
+{
+ size_t size;
+ unsigned short alignment;
+ unsigned short type;
+ struct _ffi_type **elements;
+} ffi_type;
+
+/* These are defined in ffi.c */
+extern ffi_type ffi_type_void;
+extern ffi_type ffi_type_uint8;
+extern ffi_type ffi_type_sint8;
+extern ffi_type ffi_type_uint16;
+extern ffi_type ffi_type_sint16;
+extern ffi_type ffi_type_uint32;
+extern ffi_type ffi_type_sint32;
+extern ffi_type ffi_type_uint64;
+extern ffi_type ffi_type_sint64;
+extern ffi_type ffi_type_float;
+extern ffi_type ffi_type_double;
+extern ffi_type ffi_type_longdouble;
+extern ffi_type ffi_type_pointer;
+
+extern ffi_type ffi_type_ushort;
+extern ffi_type ffi_type_sint;
+extern ffi_type ffi_type_uint;
+extern ffi_type ffi_type_slong;
+extern ffi_type ffi_type_ulong;
+
+typedef enum {
+ FFI_OK = 0,
+ FFI_BAD_TYPEDEF,
+ FFI_BAD_ABI
+} ffi_status;
+
+typedef unsigned FFI_TYPE;
+
+typedef struct {
+ ffi_abi abi;
+ unsigned nargs;
+ ffi_type **arg_types;
+ ffi_type *rtype;
+ unsigned bytes;
+ unsigned flags;
+
+#ifdef __mips__
+#if _MIPS_SIM == _ABIN32
+ unsigned rstruct_flag;
+#endif
+#endif
+
+} ffi_cif;
+
+/* ---- Definitions for the raw API -------------------------------------- */
+
+#if !FFI_NO_RAW_API
+
+typedef union {
+#if _MIPS_SIM==_ABIN32 && defined(_ABIN32)
+ long sint;
+ unsigned long uint;
+#else
+ int sint;
+ unsigned uint;
+#endif
+ float flt;
+ char data[sizeof(void*)];
+ void* ptr;
+} ffi_raw;
+
+void ffi_raw_call (/*@dependent@*/ ffi_cif *cif,
+ void (*fn)(),
+ /*@out@*/ void *rvalue,
+ /*@dependent@*/ ffi_raw *avalue);
+
+void ffi_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_raw *raw);
+void ffi_raw_to_ptrarray (ffi_cif *cif, ffi_raw *raw, void **args);
+size_t ffi_raw_size (ffi_cif *cif);
+
+#if !NO_JAVA_RAW_API
+
+/* This is analogous to the raw API, except it uses Java parameter */
+/* packing, even on 64-bit machines. I.e. on 64-bit machines */
+/* longs and doubles are followed by an empty 64-bit word. */
+
+void ffi_java_raw_call (/*@dependent@*/ ffi_cif *cif,
+ void (*fn)(),
+ /*@out@*/ void *rvalue,
+ /*@dependent@*/ ffi_raw *avalue);
+
+void ffi_java_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_raw *raw);
+void ffi_java_raw_to_ptrarray (ffi_cif *cif, ffi_raw *raw, void **args);
+size_t ffi_java_raw_size (ffi_cif *cif);
+
+#endif /* !NO_JAVA_RAW_API */
+
+#endif /* !FFI_NO_RAW_API */
+
+/* ---- Definitions for closures ----------------------------------------- */
+
+#ifdef __i386__
+
+#define FFI_CLOSURES 1 /* x86 supports closures */
+#define FFI_TRAMPOLINE_SIZE 10
+#define FFI_NATIVE_RAW_API 1 /* and has native raw api support */
+
+#elif defined(X86_WIN32)
+
+#define FFI_CLOSURES 1 /* x86 supports closures */
+#define FFI_TRAMPOLINE_SIZE 10
+#define FFI_NATIVE_RAW_API 1 /* and has native raw api support */
+
+#elif defined(IA64)
+
+#define FFI_CLOSURES 1
+#define FFI_TRAMPOLINE_SIZE 24 /* Really the following struct, which */
+ /* can be interpreted as a C function */
+ /* decriptor: */
+
+struct ffi_ia64_trampoline_struct {
+ void * code_pointer; /* Pointer to ffi_closure_UNIX */
+ void * fake_gp; /* Pointer to closure, installed as gp */
+ void * real_gp; /* Real gp value, reinstalled by */
+ /* ffi_closure_UNIX. */
+};
+#define FFI_NATIVE_RAW_API 0
+
+#elif defined(__alpha__)
+
+#define FFI_CLOSURES 1
+#define FFI_TRAMPOLINE_SIZE 24
+#define FFI_NATIVE_RAW_API 0
+
+#elif defined(POWERPC)
+
+#define FFI_CLOSURES 1
+#define FFI_TRAMPOLINE_SIZE 40
+#define FFI_NATIVE_RAW_API 0
+
+#else
+
+#define FFI_CLOSURES 0
+#define FFI_NATIVE_RAW_API 0
+
+#endif
+
+
+
+#if FFI_CLOSURES
+
+typedef struct {
+ char tramp[FFI_TRAMPOLINE_SIZE];
+ ffi_cif *cif;
+ void (*fun)(ffi_cif*,void*,void**,void*);
+ void *user_data;
+} ffi_closure;
+
+ffi_status
+ffi_prep_closure (ffi_closure*,
+ ffi_cif *,
+ void (*fun)(ffi_cif*,void*,void**,void*),
+ void *user_data);
+
+#if !FFI_NO_RAW_API
+
+typedef struct {
+ char tramp[FFI_TRAMPOLINE_SIZE];
+
+ ffi_cif *cif;
+
+#if !FFI_NATIVE_RAW_API
+
+ /* if this is enabled, then a raw closure has the same layout
+ as a regular closure. We use this to install an intermediate
+ handler to do the transaltion, void** -> ffi_raw*. */
+
+ void (*translate_args)(ffi_cif*,void*,void**,void*);
+ void *this_closure;
+
+#endif
+
+ void (*fun)(ffi_cif*,void*,ffi_raw*,void*);
+ void *user_data;
+
+} ffi_raw_closure;
+
+ffi_status
+ffi_prep_raw_closure (ffi_raw_closure*,
+ ffi_cif *cif,
+ void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
+ void *user_data);
+
+#ifndef NO_JAVA_RAW_API
+ffi_status
+ffi_prep_java_raw_closure (ffi_raw_closure*,
+ ffi_cif *cif,
+ void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
+ void *user_data);
+#endif
+
+#endif /* !FFI_NO_RAW_API */
+#endif /* FFI_CLOSURES */
+
+/* ---- Public interface definition -------------------------------------- */
+
+ffi_status ffi_prep_cif (ffi_cif *cif,
+ ffi_abi abi,
+ unsigned int nargs,
+ ffi_type *rtype,
+ ffi_type **atypes);
+
+void ffi_call (ffi_cif *cif,
+ void (*fn)(),
+ void *rvalue,
+ void **avalue);
+
+/* Useful for eliminating compiler warnings */
+#define FFI_FN(f) ((void (*)())f)
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/libffi/include/ffi_private.h b/libffi/include/ffi_private.h
new file mode 100644
index 00000000000..d3af43ba721
--- /dev/null
+++ b/libffi/include/ffi_private.h
@@ -0,0 +1,168 @@
+/* -----------------------------------------------------------------*-C-*-
+ libffi 2.0.0 - Copyright (C) 1996, 1997, 1998, 1999, 2000,
+ 2001 Red Hat, Inc.
+
+ 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 RED HAT 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.
+
+ ----------------------------------------------------------------------- */
+
+#include <fficonfig.h>
+
+#define ALIGN(v, a) (((((size_t) (v))-1) | ((a)-1))+1)
+
+/* ---- Generic type definitions ----------------------------------------- */
+
+#define FLOAT32 float
+#define FLOAT64 double
+#define FLOAT80 long double
+
+#define UINT8 unsigned char
+#define SINT8 signed char
+
+#if SIZEOF_INT == 2
+
+#define UINT16 unsigned int
+#define SINT16 int
+
+#else
+#if SIZEOF_SHORT == 2
+
+#define UINT16 unsigned short
+#define SINT16 short
+
+#endif
+#endif
+
+#if SIZEOF_INT == 4
+
+#define UINT32 unsigned int
+#define SINT32 int
+
+#else
+#if SIZEOF_SHORT == 4
+
+#define UINT32 unsigned short
+#define SINT32 short
+
+#else
+#if SIZEOF_LONG == 4
+
+#define UINT32 unsigned long
+#define SINT32 long
+
+#endif
+#endif
+#endif
+
+#if SIZEOF_INT == 8
+
+#define UINT64 unsigned int
+#define SINT64 int
+
+#else
+#if SIZEOF_LONG == 8
+
+#define UINT64 unsigned long
+#define SINT64 long
+
+#else
+#if SIZEOF_LONG_LONG == 8
+
+#define UINT64 unsigned long long
+#define SINT64 long long
+
+#endif
+#endif
+#endif
+
+#define FFI_TYPE_VOID 0
+#define FFI_TYPE_INT 1
+#define FFI_TYPE_FLOAT 2
+#define FFI_TYPE_DOUBLE 3
+#if SIZEOF_LONG_DOUBLE == SIZEOF_DOUBLE
+#define FFI_TYPE_LONGDOUBLE FFI_TYPE_DOUBLE
+#else
+#define FFI_TYPE_LONGDOUBLE 4
+#endif
+#define FFI_TYPE_UINT8 5 /* If this changes, update ffi_mips.h. */
+#define FFI_TYPE_SINT8 6 /* If this changes, update ffi_mips.h. */
+#define FFI_TYPE_UINT16 7
+#define FFI_TYPE_SINT16 8
+#define FFI_TYPE_UINT32 9
+#define FFI_TYPE_SINT32 10
+#define FFI_TYPE_UINT64 11
+#define FFI_TYPE_SINT64 12
+#define FFI_TYPE_STRUCT 13 /* If this changes, update ffi_mips.h. */
+#define FFI_TYPE_POINTER 14
+#define FFI_TYPE_LAST 14
+
+#if _MIPS_SIM==_ABIN32 && defined(_ABIN32)
+#define SIZEOF_ARG 8
+#else
+#define SIZEOF_ARG SIZEOF_VOID_P
+#endif
+
+#ifndef __ASSEMBLER__
+/* This part of the private header file is only for C code. */
+
+/* Check for the existence of memcpy. */
+#if STDC_HEADERS
+# include <string.h>
+#else
+# ifndef HAVE_MEMCPY
+# define memcpy(d, s, n) bcopy ((s), (d), (n))
+# endif
+#endif
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+#ifndef TRUE
+#define TRUE (!FALSE)
+#endif
+
+#ifndef __cplusplus
+/* bool is a keyword in C++ */
+typedef int bool;
+#endif
+
+#ifdef FFI_DEBUG
+/* Debugging functions */
+void ffi_stop_here(void);
+bool ffi_type_test(ffi_type *a);
+#define FFI_ASSERT(x) ((x) ? 0 : ffi_assert(__FILE__,__LINE__))
+#else
+#define FFI_ASSERT(x)
+#endif
+
+/* Perform machine dependent cif processing */
+ffi_status ffi_prep_cif_machdep(ffi_cif *cif);
+
+/* Extended cif, used in callback from assembly routine */
+typedef struct
+{
+ ffi_cif *cif;
+ void *rvalue;
+ void **avalue;
+} extended_cif;
+
+#endif /* __ASSEMBLER__ */
+
diff --git a/libffi/java_raw_api.c b/libffi/java_raw_api.c
new file mode 100644
index 00000000000..1b00cd35238
--- /dev/null
+++ b/libffi/java_raw_api.c
@@ -0,0 +1,269 @@
+/* -----------------------------------------------------------------------
+ java_raw_api.c - Copyright (c) 1999 Cygnus Solutions
+
+ Cloned from raw_api.c
+
+ Raw_api.c author: Kresten Krab Thorup <krab@gnu.org>
+ Java_raw_api.c author: Hans-J. Boehm <hboehm@hpl.hp.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 RED HAT 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.
+ ----------------------------------------------------------------------- */
+
+/* This defines a Java- and 64-bit specific variant of the raw API. */
+/* It assumes that "raw" argument blocks look like Java stacks on a */
+/* 64-bit machine. Arguments that can be stored in a single stack */
+/* stack slots (longs, doubles) occupy 128 bits, but only the first */
+/* 64 bits are actually used. */
+
+#include <ffi.h>
+#include <ffi_private.h>
+
+#if !defined(NO_JAVA_RAW_API) && !defined(FFI_NO_RAW_API)
+
+size_t
+ffi_java_raw_size (ffi_cif *cif)
+{
+ size_t result = 0;
+ int i;
+
+ ffi_type **at = cif->arg_types;
+
+ for (i = cif->nargs-1; i >= 0; i--, at++)
+ {
+ switch((*at) -> type) {
+ case FFI_TYPE_UINT64:
+ case FFI_TYPE_SINT64:
+ result += 2 * SIZEOF_ARG;
+ break;
+ case FFI_TYPE_STRUCT:
+ /* No structure parameters in Java. */
+ abort();
+ default:
+ result += SIZEOF_ARG;
+ }
+ }
+
+ return result;
+}
+
+
+void
+ffi_java_raw_to_ptrarray (ffi_cif *cif, ffi_raw *raw, void **args)
+{
+ unsigned i;
+ ffi_type **tp = cif->arg_types;
+
+#if WORDS_BIGENDIAN
+
+ for (i = 0; i < cif->nargs; i++, tp++, args++)
+ {
+ switch ((*tp)->type)
+ {
+ case FFI_TYPE_UINT8:
+ case FFI_TYPE_SINT8:
+ *args = (void*) ((char*)(raw++) + SIZEOF_ARG - 1);
+ break;
+
+ case FFI_TYPE_UINT16:
+ case FFI_TYPE_SINT16:
+ *args = (void*) ((char*)(raw++) + SIZEOF_ARG - 2);
+ break;
+
+#if SIZEOF_ARG >= 4
+ case FFI_TYPE_UINT32:
+ case FFI_TYPE_SINT32:
+ *args = (void*) ((char*)(raw++) + SIZEOF_ARG - 4);
+ break;
+#endif
+
+#if SIZEOF_ARG == 8
+ case FFI_TYPE_UINT64:
+ case FFI_TYPE_SINT64:
+ case FFI_TYPE_DOUBLE:
+ *args = (void *)raw;
+ raw += 2;
+ break;
+#endif
+
+ case FFI_TYPE_POINTER:
+ *args = (void*) &(raw++)->ptr;
+ break;
+
+ default:
+ *args = raw;
+ raw += ALIGN ((*tp)->size, SIZEOF_ARG) / SIZEOF_ARG;
+ }
+ }
+
+#else /* WORDS_BIGENDIAN */
+
+#if !PDP
+
+ /* then assume little endian */
+ for (i = 0; i < cif->nargs; i++, tp++, args++)
+ {
+#if SIZEOF_ARG == 8
+ switch((*tp)->type) {
+ case FFI_TYPE_UINT64:
+ case FFI_TYPE_SINT64:
+ case FFI_TYPE_DOUBLE:
+ *args = (void*) raw;
+ raw += 2;
+ break;
+ default:
+ *args = (void*) raw++;
+ }
+#else /* SIZEOF_ARG != 8 */
+ *args = (void*) raw;
+ raw += ALIGN ((*tp)->size, sizeof (void*)) / sizeof (void*);
+#endif /* SIZEOF_ARG == 8 */
+ }
+
+#else
+#error "pdp endian not supported"
+#endif /* ! PDP */
+
+#endif /* WORDS_BIGENDIAN */
+}
+
+void
+ffi_java_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_raw *raw)
+{
+ unsigned i;
+ ffi_type **tp = cif->arg_types;
+
+ for (i = 0; i < cif->nargs; i++, tp++, args++)
+ {
+ switch ((*tp)->type)
+ {
+ case FFI_TYPE_UINT8:
+ (raw++)->uint = *(UINT8*) (*args);
+ break;
+
+ case FFI_TYPE_SINT8:
+ (raw++)->sint = *(SINT8*) (*args);
+ break;
+
+ case FFI_TYPE_UINT16:
+ (raw++)->uint = *(UINT16*) (*args);
+ break;
+
+ case FFI_TYPE_SINT16:
+ (raw++)->sint = *(SINT16*) (*args);
+ break;
+
+#if SIZEOF_ARG >= 4
+ case FFI_TYPE_UINT32:
+ (raw++)->uint = *(UINT32*) (*args);
+ break;
+
+ case FFI_TYPE_SINT32:
+ (raw++)->sint = *(SINT32*) (*args);
+ break;
+#endif
+ case FFI_TYPE_FLOAT:
+ (raw++)->flt = *(FLOAT32*) (*args);
+ break;
+
+#if SIZEOF_ARG == 8
+ case FFI_TYPE_UINT64:
+ case FFI_TYPE_SINT64:
+ case FFI_TYPE_DOUBLE:
+ raw->uint = *(UINT64*) (*args);
+ raw += 2;
+ break;
+#endif
+
+ case FFI_TYPE_POINTER:
+ (raw++)->ptr = **(void***) args;
+ break;
+
+ default:
+#if SIZEOF_ARG == 8
+ FFI_ASSERT(FALSE); /* Should have covered all cases */
+#else
+ memcpy ((void*) raw->data, (void*)*args, (*tp)->size);
+ raw += ALIGN ((*tp)->size, SIZEOF_ARG) / SIZEOF_ARG;
+#endif
+ }
+ }
+}
+
+#if !FFI_NATIVE_RAW_API
+
+
+/* This is a generic definition of ffi_raw_call, to be used if the
+ * native system does not provide a machine-specific implementation.
+ * Having this, allows code to be written for the raw API, without
+ * the need for system-specific code to handle input in that format;
+ * these following couple of functions will handle the translation forth
+ * and back automatically. */
+
+void ffi_java_raw_call (/*@dependent@*/ ffi_cif *cif,
+ void (*fn)(),
+ /*@out@*/ void *rvalue,
+ /*@dependent@*/ ffi_raw *raw)
+{
+ void **avalue = (void**) alloca (cif->nargs * sizeof (void*));
+ ffi_java_raw_to_ptrarray (cif, raw, avalue);
+ ffi_call (cif, fn, rvalue, avalue);
+}
+
+#if FFI_CLOSURES /* base system provides closures */
+
+static void
+ffi_java_translate_args (ffi_cif *cif, void *rvalue,
+ void **avalue, void *user_data)
+{
+ ffi_raw *raw = (ffi_raw*)alloca (ffi_java_raw_size (cif));
+ ffi_raw_closure *cl = (ffi_raw_closure*)user_data;
+
+ ffi_java_ptrarray_to_raw (cif, avalue, raw);
+ (*cl->fun) (cif, rvalue, raw, cl->user_data);
+}
+
+/* Again, here is the generic version of ffi_prep_raw_closure, which
+ * will install an intermediate "hub" for translation of arguments from
+ * the pointer-array format, to the raw format */
+
+ffi_status
+ffi_prep_java_raw_closure (ffi_raw_closure* cl,
+ ffi_cif *cif,
+ void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
+ void *user_data)
+{
+ ffi_status status;
+
+ status = ffi_prep_closure ((ffi_closure*) cl,
+ cif,
+ &ffi_java_translate_args,
+ (void*)cl);
+ if (status == FFI_OK)
+ {
+ cl->fun = fun;
+ cl->user_data = user_data;
+ }
+
+ return status;
+}
+
+#endif /* FFI_CLOSURES */
+#endif /* !FFI_NATIVE_RAW_API */
+#endif /* !FFI_NO_RAW_API */
diff --git a/libffi/m68k/ffi.c b/libffi/m68k/ffi.c
new file mode 100644
index 00000000000..e9686f4e619
--- /dev/null
+++ b/libffi/m68k/ffi.c
@@ -0,0 +1,184 @@
+/* -----------------------------------------------------------------------
+ ffi.c
+
+ m68k Foreign Function Interface
+ ----------------------------------------------------------------------- */
+
+#include <ffi.h>
+#include <ffi_private.h>
+
+#include <stdlib.h>
+
+/* ffi_prep_args is called by the assembly routine once stack space has
+ been allocated for the function's arguments. */
+
+static void *
+ffi_prep_args (void *stack, extended_cif *ecif)
+{
+ unsigned int i;
+ int tmp;
+ unsigned int avn;
+ void **p_argv;
+ char *argp;
+ ffi_type **p_arg;
+ void *struct_value_ptr;
+
+ tmp = 0;
+ argp = stack;
+
+ if (ecif->cif->rtype->type == FFI_TYPE_STRUCT
+ && ecif->cif->rtype->size > 8)
+ struct_value_ptr = ecif->rvalue;
+ else
+ struct_value_ptr = NULL;
+
+ avn = ecif->cif->nargs;
+ p_argv = ecif->avalue;
+
+ for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types;
+ i != 0 && avn != 0;
+ i--, p_arg++)
+ {
+ size_t z;
+
+ /* Align if necessary. */
+ if (((*p_arg)->alignment - 1) & (unsigned) argp)
+ argp = (char *) ALIGN (argp, (*p_arg)->alignment);
+
+ if (avn != 0)
+ {
+ avn--;
+ z = (*p_arg)->size;
+ if (z < sizeof (int))
+ {
+ switch ((*p_arg)->type)
+ {
+ case FFI_TYPE_SINT8:
+ *(signed int *) argp = (signed int) *(SINT8 *) *p_argv;
+ break;
+
+ case FFI_TYPE_UINT8:
+ *(unsigned int *) argp = (unsigned int) *(UINT8 *) *p_argv;
+ break;
+
+ case FFI_TYPE_SINT16:
+ *(signed int *) argp = (signed int) *(SINT16 *) *p_argv;
+ break;
+
+ case FFI_TYPE_UINT16:
+ *(unsigned int *) argp = (unsigned int) *(UINT16 *) *p_argv;
+ break;
+
+ case FFI_TYPE_STRUCT:
+ memcpy (argp + sizeof (int) - z, *p_argv, z);
+ break;
+
+ default:
+ FFI_ASSERT (0);
+ }
+ z = sizeof (int);
+ }
+ else
+ memcpy (argp, *p_argv, z);
+ p_argv++;
+ argp += z;
+ }
+ }
+
+ return struct_value_ptr;
+}
+
+#define CIF_FLAGS_INT 1
+#define CIF_FLAGS_DINT 2
+#define CIF_FLAGS_FLOAT 4
+#define CIF_FLAGS_DOUBLE 8
+#define CIF_FLAGS_LDOUBLE 16
+#define CIF_FLAGS_POINTER 32
+#define CIF_FLAGS_STRUCT 64
+
+/* Perform machine dependent cif processing */
+ffi_status
+ffi_prep_cif_machdep (ffi_cif *cif)
+{
+ /* Set the return type flag */
+ switch (cif->rtype->type)
+ {
+ case FFI_TYPE_VOID:
+ cif->flags = 0;
+ break;
+
+ case FFI_TYPE_STRUCT:
+ if (cif->rtype->size > 4 && cif->rtype->size <= 8)
+ cif->flags = CIF_FLAGS_DINT;
+ else if (cif->rtype->size <= 4)
+ cif->flags = CIF_FLAGS_STRUCT;
+ else
+ cif->flags = 0;
+ break;
+
+ case FFI_TYPE_FLOAT:
+ cif->flags = CIF_FLAGS_FLOAT;
+ break;
+
+ case FFI_TYPE_DOUBLE:
+ cif->flags = CIF_FLAGS_DOUBLE;
+ break;
+
+ case FFI_TYPE_LONGDOUBLE:
+ cif->flags = CIF_FLAGS_LDOUBLE;
+ break;
+
+ case FFI_TYPE_POINTER:
+ cif->flags = CIF_FLAGS_POINTER;
+ break;
+
+ case FFI_TYPE_SINT64:
+ case FFI_TYPE_UINT64:
+ cif->flags = CIF_FLAGS_DINT;
+ break;
+
+ default:
+ cif->flags = CIF_FLAGS_INT;
+ break;
+ }
+
+ return FFI_OK;
+}
+
+extern void ffi_call_SYSV (void *(*) (void *, extended_cif *),
+ extended_cif *,
+ unsigned, unsigned, unsigned,
+ void *, void (*fn) ());
+
+void
+ffi_call (ffi_cif *cif, void (*fn) (), void *rvalue, void **avalue)
+{
+ extended_cif ecif;
+
+ ecif.cif = cif;
+ ecif.avalue = avalue;
+
+ /* If the return value is a struct and we don't have a return value
+ address then we need to make one. */
+
+ if (rvalue == NULL
+ && cif->rtype->type == FFI_TYPE_STRUCT
+ && cif->rtype->size > 8)
+ ecif.rvalue = alloca (cif->rtype->size);
+ else
+ ecif.rvalue = rvalue;
+
+
+ switch (cif->abi)
+ {
+ case FFI_SYSV:
+ ffi_call_SYSV (ffi_prep_args, &ecif, cif->bytes,
+ cif->flags, cif->rtype->size * 8,
+ ecif.rvalue, fn);
+ break;
+
+ default:
+ FFI_ASSERT (0);
+ break;
+ }
+}
diff --git a/libffi/m68k/sysv.S b/libffi/m68k/sysv.S
new file mode 100644
index 00000000000..a925d99e3ce
--- /dev/null
+++ b/libffi/m68k/sysv.S
@@ -0,0 +1,96 @@
+/* -----------------------------------------------------------------------
+ sysv.S
+
+ m68k Foreign Function Interface
+ ----------------------------------------------------------------------- */
+
+#define LIBFFI_ASM
+#include <ffi.h>
+
+ .text
+
+ .globl ffi_call_SYSV
+ .type ffi_call_SYSV,@function
+
+ffi_call_SYSV:
+ link %fp,#0
+ move.l %d2,-(%sp)
+
+ | Make room for all of the new args.
+ sub.l 16(%fp),%sp
+
+ | Call ffi_prep_args
+ move.l 12(%fp),-(%sp)
+ pea 4(%sp)
+ move.l 8(%fp),%a0
+ jsr (%a0)
+ addq.l #8,%sp
+
+ | Pass pointer to struct value, if any
+ move.l %a0,%a1
+
+ | Call the function
+ move.l 32(%fp),%a0
+ jsr (%a0)
+
+ | Remove the space we pushed for the args
+ add.l 16(%fp),%sp
+
+ | Load the pointer to storage for the return value
+ move.l 28(%fp),%a1
+
+ | Load the return type code
+ move.l 20(%fp),%d2
+
+ | If the return value pointer is NULL, assume no return value.
+ tst.l %a1
+ jbeq noretval
+
+ btst #0,%d2
+ jbeq retlongint
+ move.l %d0,(%a1)
+ jbra epilogue
+
+retlongint:
+ btst #1,%d2
+ jbeq retfloat
+ move.l %d0,(%a1)
+ move.l %d1,4(%a1)
+ jbra epilogue
+
+retfloat:
+ btst #2,%d2
+ jbeq retdouble
+ fmove.s %fp0,(%a1)
+ jbra epilogue
+
+retdouble:
+ btst #3,%d2
+ jbeq retlongdouble
+ fmove.d %fp0,(%a1)
+ jbra epilogue
+
+retlongdouble:
+ btst #4,%d2
+ jbeq retpointer
+ fmove.x %fp0,(%a1)
+ jbra epilogue
+
+retpointer:
+ btst #5,%d2
+ jbeq retstruct
+ move.l %a0,(%a1)
+ jbra epilogue
+
+retstruct:
+ btst #6,%d2
+ jbeq noretval
+ move.l 24(%fp),%d2
+ bfins %d0,(%a1){#0,%d2}
+
+noretval:
+epilogue:
+ move.l (%sp)+,%d2
+ unlk %a6
+ rts
+ .size ffi_call_SYSV,.-ffi_call_SYSV
diff --git a/libffi/mips/ffi.c b/libffi/mips/ffi.c
new file mode 100644
index 00000000000..9709819ef32
--- /dev/null
+++ b/libffi/mips/ffi.c
@@ -0,0 +1,469 @@
+/* -----------------------------------------------------------------------
+ ffi.c - Copyright (c) 1996, 2001 Red Hat, Inc.
+
+ MIPS Foreign Function Interface
+
+ 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 CYGNUS SOLUTIONS 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.
+ ----------------------------------------------------------------------- */
+
+#include <ffi.h>
+#include <ffi_private.h>
+#include <mips/mips.h>
+
+#include <stdlib.h>
+
+#if _MIPS_SIM == _MIPS_SIM_NABI32
+#define FIX_ARGP \
+FFI_ASSERT(argp <= &stack[bytes]); \
+if (argp == &stack[bytes]) \
+{ \
+ argp = stack; \
+}
+#else
+#define FIX_ARGP
+#endif
+
+
+/* ffi_prep_args is called by the assembly routine once stack space
+ has been allocated for the function's arguments */
+
+static void ffi_prep_args(char *stack,
+ extended_cif *ecif,
+ int bytes,
+ int flags)
+{
+ register int i;
+ register int avn;
+ register void **p_argv;
+ register char *argp;
+ register ffi_type **p_arg;
+
+#if _MIPS_SIM == _MIPS_SIM_NABI32
+ /* If more than 8 double words are used, the remainder go
+ on the stack. We reorder stuff on the stack here to
+ support this easily. */
+ if (bytes > 8 * SIZEOF_ARG)
+ argp = &stack[bytes - (8 * SIZEOF_ARG)];
+ else
+ argp = stack;
+#else
+ argp = stack;
+#endif
+
+ memset(stack, 0, bytes);
+
+#if _MIPS_SIM == _MIPS_SIM_NABI32
+ if ( ecif->cif->rstruct_flag != 0 )
+#else
+ if ( ecif->cif->rtype->type == FFI_TYPE_STRUCT )
+#endif
+ {
+ *(SLOT_TYPE_UNSIGNED *) argp = (SLOT_TYPE_UNSIGNED) ecif->rvalue;
+ argp += sizeof(SLOT_TYPE_UNSIGNED);
+ FIX_ARGP;
+ }
+
+ avn = ecif->cif->nargs;
+ p_argv = ecif->avalue;
+
+ for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types;
+ i && avn;
+ i--, p_arg++)
+ {
+ size_t z;
+
+ /* Align if necessary */
+ if (((*p_arg)->alignment - 1) & (unsigned) argp) {
+ argp = (char *) ALIGN(argp, (*p_arg)->alignment);
+ FIX_ARGP;
+ }
+
+#if _MIPS_SIM == _MIPS_SIM_ABI32
+#define OFFSET 0
+#else
+#define OFFSET sizeof(int)
+#endif
+
+ if (avn)
+ {
+ avn--;
+ z = (*p_arg)->size;
+ if (z < sizeof(SLOT_TYPE_UNSIGNED))
+ {
+ z = sizeof(SLOT_TYPE_UNSIGNED);
+
+ switch ((*p_arg)->type)
+ {
+ case FFI_TYPE_SINT8:
+ *(SINT32 *) &argp[OFFSET] = (SINT32)*(SINT8 *)(* p_argv);
+ break;
+
+ case FFI_TYPE_UINT8:
+ *(UINT32 *) &argp[OFFSET] = (UINT32)*(UINT8 *)(* p_argv);
+ break;
+
+ case FFI_TYPE_SINT16:
+ *(SINT32 *) &argp[OFFSET] = (SINT32)*(SINT16 *)(* p_argv);
+ break;
+
+ case FFI_TYPE_UINT16:
+ *(UINT32 *) &argp[OFFSET] = (UINT32)*(UINT16 *)(* p_argv);
+ break;
+
+ case FFI_TYPE_SINT32:
+ *(SINT32 *) &argp[OFFSET] = (SINT32)*(SINT32 *)(* p_argv);
+ break;
+
+ case FFI_TYPE_UINT32:
+ case FFI_TYPE_POINTER:
+ *(UINT32 *) &argp[OFFSET] = (UINT32)*(UINT32 *)(* p_argv);
+ break;
+
+ /* This can only happen with 64bit slots */
+ case FFI_TYPE_FLOAT:
+ *(float *) argp = *(float *)(* p_argv);
+ break;
+
+ /* Handle small structures */
+ case FFI_TYPE_STRUCT:
+ memcpy(argp, *p_argv, (*p_arg)->size);
+ break;
+
+ default:
+ FFI_ASSERT(0);
+ }
+ }
+ else
+ {
+#if _MIPS_SIM == _MIPS_SIM_ABI32
+ memcpy(argp, *p_argv, z);
+#else
+ {
+ unsigned end = (unsigned) argp+z;
+ unsigned cap = (unsigned) stack+bytes;
+
+ /* Check if the data will fit within the register
+ space. Handle it if it doesn't. */
+
+ if (end <= cap)
+ memcpy(argp, *p_argv, z);
+ else
+ {
+ unsigned portion = end - cap;
+
+ memcpy(argp, *p_argv, portion);
+ argp = stack;
+ memcpy(argp,
+ (void*)((unsigned)(*p_argv)+portion), z - portion);
+ }
+ }
+#endif
+ }
+ p_argv++;
+ argp += z;
+ FIX_ARGP;
+ }
+ }
+
+ return;
+}
+
+#if _MIPS_SIM == _MIPS_SIM_NABI32
+
+/* The n32 spec says that if "a chunk consists solely of a double
+ float field (but not a double, which is part of a union), it
+ is passed in a floating point register. Any other chunk is
+ passed in an integer register". This code traverses structure
+ definitions and generates the appropriate flags. */
+
+static unsigned calc_n32_struct_flags(ffi_type *arg, unsigned *shift)
+{
+ unsigned flags = 0;
+ unsigned index = 0;
+
+ ffi_type *e;
+
+ while (e = arg->elements[index])
+ {
+ if (e->type == FFI_TYPE_DOUBLE)
+ {
+ flags += (FFI_TYPE_DOUBLE << *shift);
+ *shift += FFI_FLAG_BITS;
+ }
+ else if (e->type == FFI_TYPE_STRUCT)
+ flags += calc_n32_struct_flags(e, shift);
+ else
+ *shift += FFI_FLAG_BITS;
+
+ index++;
+ }
+
+ return flags;
+}
+
+unsigned calc_n32_return_struct_flags(ffi_type *arg)
+{
+ unsigned flags = 0;
+ unsigned index = 0;
+ unsigned small = FFI_TYPE_SMALLSTRUCT;
+ ffi_type *e;
+
+ /* Returning structures under n32 is a tricky thing.
+ A struct with only one or two floating point fields
+ is returned in $f0 (and $f2 if necessary). Any other
+ struct results at most 128 bits are returned in $2
+ (the first 64 bits) and $3 (remainder, if necessary).
+ Larger structs are handled normally. */
+
+ if (arg->size > 16)
+ return 0;
+
+ if (arg->size > 8)
+ small = FFI_TYPE_SMALLSTRUCT2;
+
+ e = arg->elements[0];
+ if (e->type == FFI_TYPE_DOUBLE)
+ flags = FFI_TYPE_DOUBLE << FFI_FLAG_BITS;
+ else if (e->type == FFI_TYPE_FLOAT)
+ flags = FFI_TYPE_FLOAT << FFI_FLAG_BITS;
+
+ if (flags && (e = arg->elements[1]))
+ {
+ if (e->type == FFI_TYPE_DOUBLE)
+ flags += FFI_TYPE_DOUBLE;
+ else if (e->type == FFI_TYPE_FLOAT)
+ flags += FFI_TYPE_FLOAT;
+ else
+ return small;
+
+ if (flags && (arg->elements[2]))
+ {
+ /* There are three arguments and the first two are
+ floats! This must be passed the old way. */
+ return small;
+ }
+ }
+ else
+ if (!flags)
+ return small;
+
+ return flags;
+}
+
+#endif
+
+/* Perform machine dependent cif processing */
+ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
+{
+ cif->flags = 0;
+
+#if _MIPS_SIM == _MIPS_SIM_ABI32
+ /* Set the flags necessary for O32 processing */
+
+ if (cif->rtype->type != FFI_TYPE_STRUCT)
+ {
+ if (cif->nargs > 0)
+ {
+ switch ((cif->arg_types)[0]->type)
+ {
+ case FFI_TYPE_FLOAT:
+ case FFI_TYPE_DOUBLE:
+ cif->flags += (cif->arg_types)[0]->type;
+ break;
+
+ default:
+ break;
+ }
+
+ if (cif->nargs > 1)
+ {
+ /* Only handle the second argument if the first
+ is a float or double. */
+ if (cif->flags)
+ {
+ switch ((cif->arg_types)[1]->type)
+ {
+ case FFI_TYPE_FLOAT:
+ case FFI_TYPE_DOUBLE:
+ cif->flags += (cif->arg_types)[1]->type << FFI_FLAG_BITS;
+ break;
+
+ default:
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ /* Set the return type flag */
+ switch (cif->rtype->type)
+ {
+ case FFI_TYPE_VOID:
+ case FFI_TYPE_STRUCT:
+ case FFI_TYPE_FLOAT:
+ case FFI_TYPE_DOUBLE:
+ cif->flags += cif->rtype->type << (FFI_FLAG_BITS * 2);
+ break;
+
+ default:
+ cif->flags += FFI_TYPE_INT << (FFI_FLAG_BITS * 2);
+ break;
+ }
+#endif
+
+#if _MIPS_SIM == _MIPS_SIM_NABI32
+ /* Set the flags necessary for N32 processing */
+ {
+ unsigned shift = 0;
+ unsigned count = (cif->nargs < 8) ? cif->nargs : 8;
+ unsigned index = 0;
+
+ unsigned struct_flags = 0;
+
+ if (cif->rtype->type == FFI_TYPE_STRUCT)
+ {
+ struct_flags = calc_n32_return_struct_flags(cif->rtype);
+
+ if (struct_flags == 0)
+ {
+ /* This means that the structure is being passed as
+ a hidden argument */
+
+ shift = FFI_FLAG_BITS;
+ count = (cif->nargs < 7) ? cif->nargs : 7;
+
+ cif->rstruct_flag = !0;
+ }
+ else
+ cif->rstruct_flag = 0;
+ }
+ else
+ cif->rstruct_flag = 0;
+
+ while (count-- > 0)
+ {
+ switch ((cif->arg_types)[index]->type)
+ {
+ case FFI_TYPE_FLOAT:
+ case FFI_TYPE_DOUBLE:
+ cif->flags += ((cif->arg_types)[index]->type << shift);
+ shift += FFI_FLAG_BITS;
+ break;
+
+ case FFI_TYPE_STRUCT:
+ cif->flags += calc_n32_struct_flags((cif->arg_types)[index],
+ &shift);
+ break;
+
+ default:
+ shift += FFI_FLAG_BITS;
+ }
+
+ index++;
+ }
+
+ /* Set the return type flag */
+ switch (cif->rtype->type)
+ {
+ case FFI_TYPE_STRUCT:
+ {
+ if (struct_flags == 0)
+ {
+ /* The structure is returned through a hidden
+ first argument. Do nothing, 'cause FFI_TYPE_VOID
+ is 0 */
+ }
+ else
+ {
+ /* The structure is returned via some tricky
+ mechanism */
+ cif->flags += FFI_TYPE_STRUCT << (FFI_FLAG_BITS * 8);
+ cif->flags += struct_flags << (4 + (FFI_FLAG_BITS * 8));
+ }
+ break;
+ }
+
+ case FFI_TYPE_VOID:
+ /* Do nothing, 'cause FFI_TYPE_VOID is 0 */
+ break;
+
+ case FFI_TYPE_FLOAT:
+ case FFI_TYPE_DOUBLE:
+ cif->flags += cif->rtype->type << (FFI_FLAG_BITS * 8);
+ break;
+
+ default:
+ cif->flags += FFI_TYPE_INT << (FFI_FLAG_BITS * 8);
+ break;
+ }
+ }
+#endif
+
+ return FFI_OK;
+}
+
+/* Low level routine for calling O32 functions */
+extern int ffi_call_O32(void (*)(char *, extended_cif *, int, int),
+ extended_cif *, unsigned,
+ unsigned, unsigned *, void (*)());
+
+/* Low level routine for calling N32 functions */
+extern int ffi_call_N32(void (*)(char *, extended_cif *, int, int),
+ extended_cif *, unsigned,
+ unsigned, unsigned *, void (*)());
+
+void ffi_call(ffi_cif *cif, void (*fn)(), void *rvalue, void **avalue)
+{
+ extended_cif ecif;
+
+ ecif.cif = cif;
+ ecif.avalue = avalue;
+
+ /* If the return value is a struct and we don't have a return */
+ /* value address then we need to make one */
+
+ if ((rvalue == NULL) &&
+ (cif->rtype->type == FFI_TYPE_STRUCT))
+ ecif.rvalue = alloca(cif->rtype->size);
+ else
+ ecif.rvalue = rvalue;
+
+ switch (cif->abi)
+ {
+#if _MIPS_SIM == _MIPS_SIM_ABI32
+ case FFI_O32:
+ ffi_call_O32(ffi_prep_args, &ecif, cif->bytes,
+ cif->flags, ecif.rvalue, fn);
+ break;
+#endif
+
+#if _MIPS_SIM == _MIPS_SIM_NABI32
+ case FFI_N32:
+ ffi_call_N32(ffi_prep_args, &ecif, cif->bytes,
+ cif->flags, ecif.rvalue, fn);
+ break;
+#endif
+
+ default:
+ FFI_ASSERT(0);
+ break;
+ }
+}
diff --git a/libffi/mips/mips.h b/libffi/mips/mips.h
new file mode 100644
index 00000000000..8ca9e849aca
--- /dev/null
+++ b/libffi/mips/mips.h
@@ -0,0 +1,144 @@
+/* -----------------------------------------------------------------------
+ ffi-mips.h - Copyright (c) 1996, 2001 Red Hat, Inc.
+
+ MIPS FFI Definitions
+
+ 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 CYGNUS SUPPORT 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.
+ ----------------------------------------------------------------------- */
+
+#ifndef MIPS_H
+
+#if defined(__mips_eabi)
+# define FFI_MIPS_EABI
+# define FFI_MIPS_O32
+#else
+# if !defined(_MIPS_SIM)
+-- something is very wrong --
+# else
+# if _MIPS_SIM==_ABIN32 && defined(_ABIN32)
+# define FFI_MIPS_N32
+# else
+# if defined(__GNUC__)
+# define FFI_MIPS_O32
+# else
+# if _MIPS_SIM==_ABIO32
+# define FFI_MIPS_O32
+# else
+-- this is an unsupported platform --
+# endif
+# endif
+# endif
+# endif
+#endif
+
+#define v0 $2
+#define v1 $3
+#define a0 $4
+#define a1 $5
+#define a2 $6
+#define a3 $7
+#define a4 $8
+#define a5 $9
+#define a6 $10
+#define a7 $11
+#define t0 $8
+#define t1 $9
+#define t2 $10
+#define t3 $11
+#define t4 $12
+#define t5 $13
+#define t6 $14
+#define t7 $15
+#define t8 $24
+#define t9 $25
+#define ra $31
+
+#if defined(FFI_MIPS_O32)
+
+#define FFI_DEFAULT_ABI FFI_O32
+
+/* O32 stack frames have 32bit integer args */
+#define SLOT_TYPE_UNSIGNED UINT32
+#define SLOT_TYPE_SIGNED SINT32
+#define SIZEOF_ARG 4
+
+#define REG_L lw
+#define REG_S sw
+#define SUBU subu
+#define ADDU addu
+#define SRL srl
+#define LI li
+
+#else
+
+#define FFI_DEFAULT_ABI FFI_N32
+
+/* N32 and N64 frames have 64bit integer args */
+#define SLOT_TYPE_UNSIGNED UINT64
+#define SLOT_TYPE_SIGNED SINT64
+#define SIZEOF_ARG 8
+
+#define REG_L ld
+#define REG_S sd
+#define SUBU dsubu
+#define ADDU daddu
+#define SRL dsrl
+#define LI dli
+
+#endif
+
+#define FFI_FLAG_BITS 2
+
+/* SGI's strange assembler requires that we multiply by 4 rather
+ than shift left by FFI_FLAG_BITS */
+
+#define FFI_ARGS_D FFI_TYPE_DOUBLE
+#define FFI_ARGS_F FFI_TYPE_FLOAT
+#define FFI_ARGS_DD FFI_TYPE_DOUBLE * 4 + FFI_TYPE_DOUBLE
+#define FFI_ARGS_FF FFI_TYPE_FLOAT * 4 + FFI_TYPE_FLOAT
+#define FFI_ARGS_FD FFI_TYPE_DOUBLE * 4 + FFI_TYPE_FLOAT
+#define FFI_ARGS_DF FFI_TYPE_FLOAT * 4 + FFI_TYPE_DOUBLE
+
+/* Needed for N32 structure returns */
+#define FFI_TYPE_SMALLSTRUCT FFI_TYPE_UINT8
+#define FFI_TYPE_SMALLSTRUCT2 FFI_TYPE_SINT8
+
+#if 0
+
+/* The SGI assembler can't handle this.. */
+
+#define FFI_TYPE_STRUCT_DD (( FFI_ARGS_DD ) << 4) + FFI_TYPE_STRUCT
+
+#else
+
+/* ...so we calculate these by hand! */
+
+#define FFI_TYPE_STRUCT_D 61
+#define FFI_TYPE_STRUCT_F 45
+#define FFI_TYPE_STRUCT_DD 253
+#define FFI_TYPE_STRUCT_FF 173
+#define FFI_TYPE_STRUCT_FD 237
+#define FFI_TYPE_STRUCT_DF 189
+#define FFI_TYPE_STRUCT_SMALL 93
+#define FFI_TYPE_STRUCT_SMALL2 109
+
+#endif
+
+#endif
diff --git a/libffi/mips/n32.S b/libffi/mips/n32.S
new file mode 100644
index 00000000000..4eeef07aa8c
--- /dev/null
+++ b/libffi/mips/n32.S
@@ -0,0 +1,320 @@
+/* -----------------------------------------------------------------------
+ n32.S - Copyright (c) 1996, 1998, 2001 Red Hat, Inc.
+
+ MIPS Foreign Function Interface
+
+ 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 CYGNUS SOLUTIONS 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.
+ ----------------------------------------------------------------------- */
+
+#define LIBFFI_ASM
+#include <ffi.h>
+#include <ffi_private.h>
+#include <mips/mips.h>
+
+/* Only build this code if we are compiling for n32 */
+
+#if defined(FFI_MIPS_N32)
+
+#define callback a0
+#define bytes a2
+#define flags a3
+#define raddr a4
+#define fn a5
+
+#define SIZEOF_FRAME ( 8 * SIZEOF_ARG )
+
+ .text
+ .align 2
+ .globl ffi_call_N32
+ .ent ffi_call_N32
+ffi_call_N32:
+
+ # Prologue
+ SUBU $sp, SIZEOF_FRAME # Frame size
+ REG_S $fp, SIZEOF_FRAME - 2*SIZEOF_ARG($sp) # Save frame pointer
+ REG_S ra, SIZEOF_FRAME - 1*SIZEOF_ARG($sp) # Save return address
+ move $fp, $sp
+
+ move t9, callback # callback function pointer
+ REG_S bytes, 2*SIZEOF_ARG($fp) # bytes
+ REG_S flags, 3*SIZEOF_ARG($fp) # flags
+ REG_S raddr, 4*SIZEOF_ARG($fp) # raddr
+ REG_S fn, 5*SIZEOF_ARG($fp) # fn
+
+ # Allocate at least 4 words in the argstack
+ move v0, bytes
+ bge bytes, 4 * SIZEOF_ARG, bigger
+ LI v0, 4 * SIZEOF_ARG
+ b sixteen
+
+ bigger:
+ ADDU t4, v0, 2 * SIZEOF_ARG -1 # make sure it is aligned
+ and v0, t4, -2 * SIZEOF_ARG # to a proper boundry.
+
+sixteen:
+ SUBU $sp, $sp, v0 # move the stack pointer to reflect the
+ # arg space
+
+ ADDU a0, $sp, 0 # 4 * SIZEOF_ARG
+ ADDU a3, $fp, 3 * SIZEOF_ARG
+
+ # Call ffi_prep_args
+ jal t9
+
+ # ADDU $sp, $sp, 4 * SIZEOF_ARG # adjust $sp to new args
+
+ # Copy the stack pointer to t9
+ move t9, $sp
+
+ # Fix the stack if there are more than 8 64bit slots worth
+ # of arguments.
+
+ # Load the number of bytes
+ REG_L t6, 2*SIZEOF_ARG($fp)
+
+ # Is it bigger than 8 * SIZEOF_ARG?
+ dadd t7, $0, 8 * SIZEOF_ARG
+ dsub t8, t6, t7
+ bltz t8, loadregs
+
+ add t9, t9, t8
+
+loadregs:
+
+ REG_L t4, 3*SIZEOF_ARG($fp) # load the flags word
+ add t6, t4, 0 # and copy it into t6
+
+ and t4, ((1<<FFI_FLAG_BITS)-1)
+ bnez t4, arg1_floatp
+ REG_L a0, 0*SIZEOF_ARG(t9)
+ b arg1_next
+arg1_floatp:
+ bne t4, FFI_TYPE_FLOAT, arg1_doublep
+ l.s $f12, 0*SIZEOF_ARG(t9)
+ b arg1_next
+arg1_doublep:
+ l.d $f12, 0*SIZEOF_ARG(t9)
+arg1_next:
+
+ add t4, t6, 0
+ SRL t4, 1*FFI_FLAG_BITS
+ and t4, ((1<<FFI_FLAG_BITS)-1)
+ bnez t4, arg2_floatp
+ REG_L a1, 1*SIZEOF_ARG(t9)
+ b arg2_next
+arg2_floatp:
+ bne t4, FFI_TYPE_FLOAT, arg2_doublep
+ l.s $f13, 1*SIZEOF_ARG(t9)
+ b arg2_next
+arg2_doublep:
+ l.d $f13, 1*SIZEOF_ARG(t9)
+arg2_next:
+
+ add t4, t6, 0
+ SRL t4, 2*FFI_FLAG_BITS
+ and t4, ((1<<FFI_FLAG_BITS)-1)
+ bnez t4, arg3_floatp
+ REG_L a2, 2*SIZEOF_ARG(t9)
+ b arg3_next
+arg3_floatp:
+ bne t4, FFI_TYPE_FLOAT, arg3_doublep
+ l.s $f14, 2*SIZEOF_ARG(t9)
+ b arg3_next
+arg3_doublep:
+ l.d $f14, 2*SIZEOF_ARG(t9)
+arg3_next:
+
+ add t4, t6, 0
+ SRL t4, 3*FFI_FLAG_BITS
+ and t4, ((1<<FFI_FLAG_BITS)-1)
+ bnez t4, arg4_floatp
+ REG_L a3, 3*SIZEOF_ARG(t9)
+ b arg4_next
+arg4_floatp:
+ bne t4, FFI_TYPE_FLOAT, arg4_doublep
+ l.s $f15, 3*SIZEOF_ARG(t9)
+ b arg4_next
+arg4_doublep:
+ l.d $f15, 3*SIZEOF_ARG(t9)
+arg4_next:
+
+ add t4, t6, 0
+ SRL t4, 4*FFI_FLAG_BITS
+ and t4, ((1<<FFI_FLAG_BITS)-1)
+ bnez t4, arg5_floatp
+ REG_L a4, 4*SIZEOF_ARG(t9)
+ b arg5_next
+arg5_floatp:
+ bne t4, FFI_TYPE_FLOAT, arg5_doublep
+ l.s $f16, 4*SIZEOF_ARG(t9)
+ b arg5_next
+arg5_doublep:
+ l.d $f16, 4*SIZEOF_ARG(t9)
+arg5_next:
+
+ add t4, t6, 0
+ SRL t4, 5*FFI_FLAG_BITS
+ and t4, ((1<<FFI_FLAG_BITS)-1)
+ bnez t4, arg6_floatp
+ REG_L a5, 5*SIZEOF_ARG(t9)
+ b arg6_next
+arg6_floatp:
+ bne t4, FFI_TYPE_FLOAT, arg6_doublep
+ l.s $f17, 5*SIZEOF_ARG(t9)
+ b arg6_next
+arg6_doublep:
+ l.d $f17, 5*SIZEOF_ARG(t9)
+arg6_next:
+
+ add t4, t6, 0
+ SRL t4, 6*FFI_FLAG_BITS
+ and t4, ((1<<FFI_FLAG_BITS)-1)
+ bnez t4, arg7_floatp
+ REG_L a6, 6*SIZEOF_ARG(t9)
+ b arg7_next
+arg7_floatp:
+ bne t4, FFI_TYPE_FLOAT, arg7_doublep
+ l.s $f18, 6*SIZEOF_ARG(t9)
+ b arg7_next
+arg7_doublep:
+ l.d $f18, 6*SIZEOF_ARG(t9)
+arg7_next:
+
+ add t4, t6, 0
+ SRL t4, 7*FFI_FLAG_BITS
+ and t4, ((1<<FFI_FLAG_BITS)-1)
+ bnez t4, arg8_floatp
+ REG_L a7, 7*SIZEOF_ARG(t9)
+ b arg8_next
+arg8_floatp:
+ bne t4, FFI_TYPE_FLOAT, arg8_doublep
+ l.s $f19, 7*SIZEOF_ARG(t9)
+ b arg8_next
+arg8_doublep:
+ l.d $f19, 7*SIZEOF_ARG(t9)
+arg8_next:
+
+callit:
+ # Load the function pointer
+ REG_L t9, 5*SIZEOF_ARG($fp)
+
+ # If the return value pointer is NULL, assume no return value.
+ REG_L t5, 4*SIZEOF_ARG($fp)
+ beqz t5, noretval
+
+ # Shift the return type flag over
+ SRL t6, 8*FFI_FLAG_BITS
+
+ bne t6, FFI_TYPE_INT, retfloat
+ jal t9
+ REG_L t4, 4*SIZEOF_ARG($fp)
+ REG_S v0, 0(t4)
+ b epilogue
+
+retfloat:
+ bne t6, FFI_TYPE_FLOAT, retdouble
+ jal t9
+ REG_L t4, 4*SIZEOF_ARG($fp)
+ s.s $f0, 0(t4)
+ b epilogue
+
+retdouble:
+ bne t6, FFI_TYPE_DOUBLE, retstruct_d
+ jal t9
+ REG_L t4, 4*SIZEOF_ARG($fp)
+ s.d $f0, 0(t4)
+ b epilogue
+
+retstruct_d:
+ bne t6, FFI_TYPE_STRUCT_D, retstruct_f
+ jal t9
+ REG_L t4, 4*SIZEOF_ARG($fp)
+ s.d $f0, 0(t4)
+ b epilogue
+
+retstruct_f:
+ bne t6, FFI_TYPE_STRUCT_F, retstruct_d_d
+ jal t9
+ REG_L t4, 4*SIZEOF_ARG($fp)
+ s.s $f0, 0(t4)
+ b epilogue
+
+retstruct_d_d:
+ bne t6, FFI_TYPE_STRUCT_DD, retstruct_f_f
+ jal t9
+ REG_L t4, 4*SIZEOF_ARG($fp)
+ s.d $f0, 0(t4)
+ s.d $f2, 8(t4)
+ b epilogue
+
+retstruct_f_f:
+ bne t6, FFI_TYPE_STRUCT_FF, retstruct_d_f
+ jal t9
+ REG_L t4, 4*SIZEOF_ARG($fp)
+ s.s $f0, 0(t4)
+ s.s $f2, 4(t4)
+ b epilogue
+
+retstruct_d_f:
+ bne t6, FFI_TYPE_STRUCT_DF, retstruct_f_d
+ jal t9
+ REG_L t4, 4*SIZEOF_ARG($fp)
+ s.d $f0, 0(t4)
+ s.s $f2, 8(t4)
+ b epilogue
+
+retstruct_f_d:
+ bne t6, FFI_TYPE_STRUCT_FD, retstruct_small
+ jal t9
+ REG_L t4, 4*SIZEOF_ARG($fp)
+ s.s $f0, 0(t4)
+ s.d $f2, 8(t4)
+ b epilogue
+
+retstruct_small:
+ bne t6, FFI_TYPE_STRUCT_SMALL, retstruct_small2
+ jal t9
+ REG_L t4, 4*SIZEOF_ARG($fp)
+ REG_S v0, 0(t4)
+ b epilogue
+
+retstruct_small2:
+ bne t6, FFI_TYPE_STRUCT_SMALL2, retstruct
+ jal t9
+ REG_L t4, 4*SIZEOF_ARG($fp)
+ REG_S v0, 0(t4)
+ REG_S v1, 8(t4)
+ b epilogue
+
+retstruct:
+noretval:
+ jal t9
+
+ # Epilogue
+epilogue:
+ move $sp, $fp
+ REG_L $fp, SIZEOF_FRAME - 2*SIZEOF_ARG($sp) # Restore frame pointer
+ REG_L ra, SIZEOF_FRAME - 1*SIZEOF_ARG($sp) # Restore return address
+ ADDU $sp, SIZEOF_FRAME # Fix stack pointer
+ j ra
+
+ .end ffi_call_N32
+
+#endif
diff --git a/libffi/mips/o32.S b/libffi/mips/o32.S
new file mode 100644
index 00000000000..6efc8f7bf4b
--- /dev/null
+++ b/libffi/mips/o32.S
@@ -0,0 +1,173 @@
+/* -----------------------------------------------------------------------
+ o32.S - Copyright (c) 1996, 1998, 2001 Red Hat, Inc.
+
+ MIPS Foreign Function Interface
+
+ 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 CYGNUS SOLUTIONS 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.
+ ----------------------------------------------------------------------- */
+
+#define LIBFFI_ASM
+#include <ffi.h>
+#include <ffi_private.h>
+#include <mips/mips.h>
+
+/* Only build this code if we are compiling for o32 */
+
+#if defined(FFI_MIPS_O32)
+
+#define callback a0
+#define bytes a2
+#define flags a3
+
+#define SIZEOF_FRAME ( 4 * SIZEOF_ARG + 2 * SIZEOF_ARG )
+
+ .text
+ .align 2
+ .globl ffi_call_O32
+ .ent ffi_call_O32
+ffi_call_O32:
+
+ # Prologue
+ SUBU $sp, SIZEOF_FRAME # Frame size
+ REG_S $fp, SIZEOF_FRAME - 2*SIZEOF_ARG($sp) # Save frame pointer
+ REG_S ra, SIZEOF_FRAME - 1*SIZEOF_ARG($sp) # Save return address
+ move $fp, $sp
+
+ move t9, callback # callback function pointer
+ REG_S flags, SIZEOF_FRAME + 3*SIZEOF_ARG($fp) # flags
+
+ # Allocate at least 4 words in the argstack
+ move v0, bytes
+ bge bytes, 4 * SIZEOF_ARG, bigger
+ LI v0, 4 * SIZEOF_ARG
+ b sixteen
+
+bigger:
+ ADDU t0, v0, 2 * SIZEOF_ARG -1 # make sure it is aligned
+ and v0, t0, -2 * SIZEOF_ARG # to an 8 byte boundry
+
+sixteen:
+ SUBU $sp, $sp, v0 # move the stack pointer to reflect the
+ # arg space
+
+ ADDU a0, $sp, 4 * SIZEOF_ARG
+ ADDU a3, $fp, SIZEOF_FRAME + 3*SIZEOF_ARG
+
+ jal t9
+
+ REG_L t0, SIZEOF_FRAME + 3*SIZEOF_ARG($fp) # load the flags word
+ add t2, t0, 0 # and copy it into t2
+
+ and t0, ((1<<4)-1) # mask out the return type
+ SRL t2, 4 # shift our arg info
+
+ ADDU $sp, $sp, 4 * SIZEOF_ARG # adjust $sp to new args
+
+ bnez t0, pass_d # make it quick for int
+ REG_L a0, 0*SIZEOF_ARG($sp) # just go ahead and load the
+ REG_L a1, 1*SIZEOF_ARG($sp) # four regs.
+ REG_L a2, 2*SIZEOF_ARG($sp)
+ REG_L a3, 3*SIZEOF_ARG($sp)
+ b call_it
+
+pass_d:
+ bne t0, FFI_ARGS_D, pass_f
+ l.d $f12, 0*SIZEOF_ARG($sp) # load $fp regs from args
+ REG_L a2, 2*SIZEOF_ARG($sp) # passing a double
+ REG_L a3, 3*SIZEOF_ARG($sp)
+ b call_it
+
+pass_f:
+ bne t0, FFI_ARGS_F, pass_d_d
+ l.s $f12, 0*SIZEOF_ARG($sp) # load $fp regs from args
+ REG_L a1, 1*SIZEOF_ARG($sp) # passing a float
+ REG_L a2, 2*SIZEOF_ARG($sp)
+ REG_L a3, 3*SIZEOF_ARG($sp)
+ b call_it
+
+pass_d_d:
+ bne t0, FFI_ARGS_DD, pass_f_f
+ l.d $f12, 0*SIZEOF_ARG($sp) # load $fp regs from args
+ l.d $f14, 2*SIZEOF_ARG($sp) # passing two doubles
+ b call_it
+
+pass_f_f:
+ bne t0, FFI_ARGS_FF, pass_d_f
+ l.s $f12, 0*SIZEOF_ARG($sp) # load $fp regs from args
+ l.s $f14, 1*SIZEOF_ARG($sp) # passing two floats
+ REG_L a2, 2*SIZEOF_ARG($sp)
+ REG_L a3, 3*SIZEOF_ARG($sp)
+ b call_it
+
+pass_d_f:
+ bne t0, FFI_ARGS_DF, pass_f_d
+ l.d $f12, 0*SIZEOF_ARG($sp) # load $fp regs from args
+ l.s $f14, 2*SIZEOF_ARG($sp) # passing double and float
+ REG_L a3, 3*SIZEOF_ARG($sp)
+ b call_it
+
+pass_f_d:
+ # assume that the only other combination must be float then double
+ # bne t0, FFI_ARGS_F_D, call_it
+ l.s $f12, 0*SIZEOF_ARG($sp) # load $fp regs from args
+ l.d $f14, 2*SIZEOF_ARG($sp) # passing double and float
+
+call_it:
+ # Load the function pointer
+ REG_L t9, SIZEOF_FRAME + 5*SIZEOF_ARG($fp)
+
+ # If the return value pointer is NULL, assume no return value.
+ REG_L t1, SIZEOF_FRAME + 4*SIZEOF_ARG($fp)
+ beqz t1, noretval
+
+ bne t2, FFI_TYPE_INT, retfloat
+ jal t9
+ REG_L t0, SIZEOF_FRAME + 4*SIZEOF_ARG($fp)
+ REG_S v0, 0(t0)
+ b epilogue
+
+retfloat:
+ bne t2, FFI_TYPE_FLOAT, retdouble
+ jal t9
+ REG_L t0, SIZEOF_FRAME + 4*SIZEOF_ARG($fp)
+ s.s $f0, 0(t0)
+ b epilogue
+
+retdouble:
+ bne t2, FFI_TYPE_DOUBLE, noretval
+ jal t9
+ REG_L t0, SIZEOF_FRAME + 4*SIZEOF_ARG($fp)
+ s.d $f0, 0(t0)
+ b epilogue
+
+noretval:
+ jal t9
+
+ # Epilogue
+epilogue:
+ move $sp, $fp
+ REG_L $fp, SIZEOF_FRAME - 2*SIZEOF_ARG($sp) # Restore frame pointer
+ REG_L ra, SIZEOF_FRAME - 1*SIZEOF_ARG($sp) # Restore return address
+ ADDU $sp, SIZEOF_FRAME # Fix stack pointer
+ j ra
+
+ .end ffi_call_O32
+
+#endif
diff --git a/libffi/powerpc/asm.h b/libffi/powerpc/asm.h
new file mode 100644
index 00000000000..5ba70375ecb
--- /dev/null
+++ b/libffi/powerpc/asm.h
@@ -0,0 +1,128 @@
+/* -----------------------------------------------------------------------
+ asm.h - Copyright (c) 1998 Geoffrey Keating
+
+ PowerPC Assembly glue.
+
+ $Id: asm.h,v 1.1 2001/08/02 19:33:38 orph Exp $
+
+ 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 AUTHOR 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.
+ ----------------------------------------------------------------------- */
+
+#define ASM_GLOBAL_DIRECTIVE .globl
+
+
+#define C_SYMBOL_NAME(name) name
+/* Macro for a label. */
+#ifdef __STDC__
+#define C_LABEL(name) name##:
+#else
+#define C_LABEL(name) name/**/:
+#endif
+
+/* This seems to always be the case on PPC. */
+#define ALIGNARG(log2) log2
+/* For ELF we need the `.type' directive to make shared libs work right. */
+#define ASM_TYPE_DIRECTIVE(name,typearg) .type name,typearg;
+#define ASM_SIZE_DIRECTIVE(name) .size name,.-name
+
+/* If compiled for profiling, call `_mcount' at the start of each function. */
+#ifdef PROF
+/* The mcount code relies on a the return address being on the stack
+ to locate our caller and so it can restore it; so store one just
+ for its benefit. */
+#ifdef PIC
+#define CALL_MCOUNT \
+ .pushsection; \
+ .section ".data"; \
+ .align ALIGNARG(2); \
+0:.long 0; \
+ .previous; \
+ mflr %r0; \
+ stw %r0,4(%r1); \
+ bl _GLOBAL_OFFSET_TABLE_@local-4; \
+ mflr %r11; \
+ lwz %r0,0b@got(%r11); \
+ bl JUMPTARGET(_mcount);
+#else /* PIC */
+#define CALL_MCOUNT \
+ .section ".data"; \
+ .align ALIGNARG(2); \
+0:.long 0; \
+ .previous; \
+ mflr %r0; \
+ lis %r11,0b@ha; \
+ stw %r0,4(%r1); \
+ addi %r0,%r11,0b@l; \
+ bl JUMPTARGET(_mcount);
+#endif /* PIC */
+#else /* PROF */
+#define CALL_MCOUNT /* Do nothing. */
+#endif /* PROF */
+
+#define ENTRY(name) \
+ ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(name); \
+ ASM_TYPE_DIRECTIVE (C_SYMBOL_NAME(name),@function) \
+ .align ALIGNARG(2); \
+ C_LABEL(name) \
+ CALL_MCOUNT
+
+#define EALIGN_W_0 /* No words to insert. */
+#define EALIGN_W_1 nop
+#define EALIGN_W_2 nop;nop
+#define EALIGN_W_3 nop;nop;nop
+#define EALIGN_W_4 EALIGN_W_3;nop
+#define EALIGN_W_5 EALIGN_W_4;nop
+#define EALIGN_W_6 EALIGN_W_5;nop
+#define EALIGN_W_7 EALIGN_W_6;nop
+
+/* EALIGN is like ENTRY, but does alignment to 'words'*4 bytes
+ past a 2^align boundary. */
+#ifdef PROF
+#define EALIGN(name, alignt, words) \
+ ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(name); \
+ ASM_TYPE_DIRECTIVE (C_SYMBOL_NAME(name),@function) \
+ .align ALIGNARG(2); \
+ C_LABEL(name) \
+ CALL_MCOUNT \
+ b 0f; \
+ .align ALIGNARG(alignt); \
+ EALIGN_W_##words; \
+ 0:
+#else /* PROF */
+#define EALIGN(name, alignt, words) \
+ ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(name); \
+ ASM_TYPE_DIRECTIVE (C_SYMBOL_NAME(name),@function) \
+ .align ALIGNARG(alignt); \
+ EALIGN_W_##words; \
+ C_LABEL(name)
+#endif
+
+#define END(name) \
+ ASM_SIZE_DIRECTIVE(name)
+
+#ifdef PIC
+#define JUMPTARGET(name) name##@plt
+#else
+#define JUMPTARGET(name) name
+#endif
+
+/* Local labels stripped out by the linker. */
+#define L(x) .L##x
+
diff --git a/libffi/powerpc/ffi.c b/libffi/powerpc/ffi.c
new file mode 100644
index 00000000000..d705b604fd5
--- /dev/null
+++ b/libffi/powerpc/ffi.c
@@ -0,0 +1,680 @@
+/* -----------------------------------------------------------------------
+ ffi.c - Copyright (c) 1998 Geoffrey Keating
+
+ PowerPC Foreign Function Interface
+
+ $Id: ffi.c,v 1.1 2001/08/02 19:31:55 orph Exp $
+
+ 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 AUTHOR 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.
+ ----------------------------------------------------------------------- */
+
+#include <ffi.h>
+#include <ffi_private.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+
+extern void ffi_closure_SYSV(void);
+
+enum {
+ /* The assembly depends on these exact flags. */
+ FLAG_RETURNS_NOTHING = 1 << (31-30), /* These go in cr7 */
+ FLAG_RETURNS_FP = 1 << (31-29),
+ FLAG_RETURNS_64BITS = 1 << (31-28),
+
+ FLAG_ARG_NEEDS_COPY = 1 << (31- 7),
+ FLAG_FP_ARGUMENTS = 1 << (31- 6), /* cr1.eq; specified by ABI */
+ FLAG_4_GPR_ARGUMENTS = 1 << (31- 5),
+ FLAG_RETVAL_REFERENCE = 1 << (31- 4)
+};
+
+/* About the SYSV ABI. */
+enum {
+ NUM_GPR_ARG_REGISTERS = 8,
+ NUM_FPR_ARG_REGISTERS = 8
+};
+enum { ASM_NEEDS_REGISTERS = 4 };
+
+/* ffi_prep_args is called by the assembly routine once stack space
+ has been allocated for the function's arguments.
+
+ The stack layout we want looks like this:
+
+ | Return address from ffi_call_SYSV 4bytes | higher addresses
+ |--------------------------------------------|
+ | Previous backchain pointer 4 | stack pointer here
+ |--------------------------------------------|<+ <<< on entry to
+ | Saved r28-r31 4*4 | | ffi_call_SYSV
+ |--------------------------------------------| |
+ | GPR registers r3-r10 8*4 | | ffi_call_SYSV
+ |--------------------------------------------| |
+ | FPR registers f1-f8 (optional) 8*8 | |
+ |--------------------------------------------| | stack |
+ | Space for copied structures | | grows |
+ |--------------------------------------------| | down V
+ | Parameters that didn't fit in registers | |
+ |--------------------------------------------| | lower addresses
+ | Space for callee's LR 4 | |
+ |--------------------------------------------| | stack pointer here
+ | Current backchain pointer 4 |-/ during
+ |--------------------------------------------| <<< ffi_call_SYSV
+
+ */
+
+/*@-exportheader@*/
+void ffi_prep_args(extended_cif *ecif, unsigned *const stack)
+/*@=exportheader@*/
+{
+ const unsigned bytes = ecif->cif->bytes;
+ const unsigned flags = ecif->cif->flags;
+
+ /* 'stacktop' points at the previous backchain pointer. */
+ unsigned *const stacktop = stack + (ecif->cif->bytes / sizeof(unsigned));
+
+ /* 'gpr_base' points at the space for gpr3, and grows upwards as
+ we use GPR registers. */
+ unsigned *gpr_base = stacktop - ASM_NEEDS_REGISTERS - NUM_GPR_ARG_REGISTERS;
+ int intarg_count = 0;
+
+ /* 'fpr_base' points at the space for fpr1, and grows upwards as
+ we use FPR registers. */
+ double *fpr_base = (double *)gpr_base - NUM_FPR_ARG_REGISTERS;
+ int fparg_count = 0;
+
+ /* 'copy_space' grows down as we put structures in it. It should
+ stay 16-byte aligned. */
+ char *copy_space = ((flags & FLAG_FP_ARGUMENTS)
+ ? (char *)fpr_base
+ : (char *)gpr_base);
+
+ /* 'next_arg' grows up as we put parameters in it. */
+ unsigned *next_arg = stack + 2;
+
+ int i;
+ ffi_type **ptr;
+ double double_tmp;
+ void **p_argv;
+ size_t struct_copy_size;
+ unsigned gprvalue;
+
+ /* Check that everything starts aligned properly. */
+ FFI_ASSERT(((unsigned)(char *)stack & 0xF) == 0);
+ FFI_ASSERT(((unsigned)(char *)copy_space & 0xF) == 0);
+ FFI_ASSERT(((unsigned)(char *)stacktop & 0xF) == 0);
+ FFI_ASSERT((bytes & 0xF) == 0);
+ FFI_ASSERT(copy_space >= (char *)next_arg);
+
+ /* Deal with return values that are actually pass-by-reference. */
+ if (flags & FLAG_RETVAL_REFERENCE)
+ {
+ *gpr_base++ = (unsigned)(char *)ecif->rvalue;
+ intarg_count++;
+ }
+
+ /* Now for the arguments. */
+ p_argv = ecif->avalue;
+ for (ptr = ecif->cif->arg_types, i = ecif->cif->nargs;
+ i > 0;
+ i--, ptr++, p_argv++)
+ {
+ switch ((*ptr)->type)
+ {
+ case FFI_TYPE_FLOAT:
+ case FFI_TYPE_DOUBLE:
+ if ((*ptr)->type == FFI_TYPE_FLOAT)
+ double_tmp = *(float *)*p_argv;
+ else
+ double_tmp = *(double *)*p_argv;
+
+ if (fparg_count >= NUM_FPR_ARG_REGISTERS)
+ {
+ if (intarg_count%2 != 0)
+ {
+ intarg_count++;
+ next_arg++;
+ }
+ *(double *)next_arg = double_tmp;
+ next_arg += 2;
+ }
+ else
+ *fpr_base++ = double_tmp;
+ fparg_count++;
+ FFI_ASSERT(flags & FLAG_FP_ARGUMENTS);
+ break;
+
+ case FFI_TYPE_UINT64:
+ case FFI_TYPE_SINT64:
+ if (intarg_count == NUM_GPR_ARG_REGISTERS-1)
+ intarg_count++;
+ if (intarg_count >= NUM_GPR_ARG_REGISTERS)
+ {
+ if (intarg_count%2 != 0)
+ {
+ intarg_count++;
+ next_arg++;
+ }
+ *(long long *)next_arg = *(long long *)*p_argv;
+ next_arg += 2;
+ }
+ else
+ {
+ /* whoops: abi states only certain register pairs
+ * can be used for passing long long int
+ * specifically (r3,r4), (r5,r6), (r7,r8),
+ * (r9,r10) and if next arg is long long but
+ * not correct starting register of pair then skip
+ * until the proper starting register
+ */
+ if (intarg_count%2 != 0)
+ {
+ intarg_count ++;
+ gpr_base++;
+ }
+ *(long long *)gpr_base = *(long long *)*p_argv;
+ gpr_base += 2;
+ }
+ intarg_count += 2;
+ break;
+
+ case FFI_TYPE_STRUCT:
+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+ case FFI_TYPE_LONGDOUBLE:
+#endif
+ struct_copy_size = ((*ptr)->size + 15) & ~0xF;
+ copy_space -= struct_copy_size;
+ memcpy(copy_space, (char *)*p_argv, (*ptr)->size);
+
+ gprvalue = (unsigned)copy_space;
+
+ FFI_ASSERT(copy_space > (char *)next_arg);
+ FFI_ASSERT(flags & FLAG_ARG_NEEDS_COPY);
+ goto putgpr;
+
+ case FFI_TYPE_UINT8:
+ gprvalue = *(unsigned char *)*p_argv;
+ goto putgpr;
+ case FFI_TYPE_SINT8:
+ gprvalue = *(signed char *)*p_argv;
+ goto putgpr;
+ case FFI_TYPE_UINT16:
+ gprvalue = *(unsigned short *)*p_argv;
+ goto putgpr;
+ case FFI_TYPE_SINT16:
+ gprvalue = *(signed short *)*p_argv;
+ goto putgpr;
+
+ case FFI_TYPE_INT:
+ case FFI_TYPE_UINT32:
+ case FFI_TYPE_SINT32:
+ case FFI_TYPE_POINTER:
+ gprvalue = *(unsigned *)*p_argv;
+ putgpr:
+ if (intarg_count >= NUM_GPR_ARG_REGISTERS)
+ *next_arg++ = gprvalue;
+ else
+ *gpr_base++ = gprvalue;
+ intarg_count++;
+ break;
+ }
+ }
+
+ /* Check that we didn't overrun the stack... */
+ FFI_ASSERT(copy_space >= (char *)next_arg);
+ FFI_ASSERT(gpr_base <= stacktop - ASM_NEEDS_REGISTERS);
+ FFI_ASSERT((unsigned *)fpr_base
+ <= stacktop - ASM_NEEDS_REGISTERS - NUM_GPR_ARG_REGISTERS);
+ FFI_ASSERT(flags & FLAG_4_GPR_ARGUMENTS || intarg_count <= 4);
+}
+
+/* Perform machine dependent cif processing */
+ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
+{
+ /* All this is for the SYSV ABI. */
+ int i;
+ ffi_type **ptr;
+ unsigned bytes;
+ int fparg_count = 0, intarg_count = 0;
+ unsigned flags = 0;
+ unsigned struct_copy_size = 0;
+
+ /* All the machine-independent calculation of cif->bytes will be wrong.
+ Redo the calculation for SYSV. */
+
+ /* Space for the frame pointer, callee's LR, and the asm's temp regs. */
+ bytes = (2 + ASM_NEEDS_REGISTERS) * sizeof(int);
+
+ /* Space for the GPR registers. */
+ bytes += NUM_GPR_ARG_REGISTERS * sizeof(int);
+
+ /* Return value handling. The rules are as follows:
+ - 32-bit (or less) integer values are returned in gpr3;
+ - Structures of size <= 4 bytes also returned in gpr3;
+ - 64-bit integer values and structures between 5 and 8 bytes are returned
+ in gpr3 and gpr4;
+ - Single/double FP values are returned in fpr1;
+ - Larger structures and long double (if not equivalent to double) values
+ are allocated space and a pointer is passed as the first argument. */
+ switch (cif->rtype->type)
+ {
+ case FFI_TYPE_DOUBLE:
+ flags |= FLAG_RETURNS_64BITS;
+ /* Fall through. */
+ case FFI_TYPE_FLOAT:
+ flags |= FLAG_RETURNS_FP;
+ break;
+
+ case FFI_TYPE_UINT64:
+ case FFI_TYPE_SINT64:
+ flags |= FLAG_RETURNS_64BITS;
+ break;
+
+ case FFI_TYPE_STRUCT:
+ if (cif->abi != FFI_GCC_SYSV)
+ if (cif->rtype->size <= 4)
+ break;
+ else if (cif->rtype->size <= 8)
+ {
+ flags |= FLAG_RETURNS_64BITS;
+ break;
+ }
+ /* else fall through. */
+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+ case FFI_TYPE_LONGDOUBLE:
+#endif
+ intarg_count++;
+ flags |= FLAG_RETVAL_REFERENCE;
+ /* Fall through. */
+ case FFI_TYPE_VOID:
+ flags |= FLAG_RETURNS_NOTHING;
+ break;
+
+ default:
+ /* Returns 32-bit integer, or similar. Nothing to do here. */
+ break;
+ }
+
+ /* The first NUM_GPR_ARG_REGISTERS words of integer arguments, and the
+ first NUM_FPR_ARG_REGISTERS fp arguments, go in registers; the rest
+ goes on the stack. Structures and long doubles (if not equivalent
+ to double) are passed as a pointer to a copy of the structure.
+ Stuff on the stack needs to keep proper alignment. */
+ for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++)
+ {
+ switch ((*ptr)->type)
+ {
+ case FFI_TYPE_FLOAT:
+ case FFI_TYPE_DOUBLE:
+ fparg_count++;
+ /* If this FP arg is going on the stack, it must be
+ 8-byte-aligned. */
+ if (fparg_count > NUM_FPR_ARG_REGISTERS
+ && intarg_count%2 != 0)
+ intarg_count++;
+ break;
+
+ case FFI_TYPE_UINT64:
+ case FFI_TYPE_SINT64:
+ /* 'long long' arguments are passed as two words, but
+ either both words must fit in registers or both go
+ on the stack. If they go on the stack, they must
+ be 8-byte-aligned. */
+ if (intarg_count == NUM_GPR_ARG_REGISTERS-1
+ || intarg_count >= NUM_GPR_ARG_REGISTERS && intarg_count%2 != 0)
+ intarg_count++;
+ intarg_count += 2;
+ break;
+
+ case FFI_TYPE_STRUCT:
+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+ case FFI_TYPE_LONGDOUBLE:
+#endif
+ /* We must allocate space for a copy of these to enforce
+ pass-by-value. Pad the space up to a multiple of 16
+ bytes (the maximum alignment required for anything under
+ the SYSV ABI). */
+ struct_copy_size += ((*ptr)->size + 15) & ~0xF;
+ /* Fall through (allocate space for the pointer). */
+
+ default:
+ /* Everything else is passed as a 4-byte word in a GPR, either
+ the object itself or a pointer to it. */
+ intarg_count++;
+ break;
+ }
+ }
+
+ if (fparg_count != 0)
+ flags |= FLAG_FP_ARGUMENTS;
+ if (intarg_count > 4)
+ flags |= FLAG_4_GPR_ARGUMENTS;
+ if (struct_copy_size != 0)
+ flags |= FLAG_ARG_NEEDS_COPY;
+
+ /* Space for the FPR registers, if needed. */
+ if (fparg_count != 0)
+ bytes += NUM_FPR_ARG_REGISTERS * sizeof(double);
+
+ /* Stack space. */
+ if (intarg_count > NUM_GPR_ARG_REGISTERS)
+ bytes += (intarg_count - NUM_GPR_ARG_REGISTERS) * sizeof(int);
+ if (fparg_count > NUM_FPR_ARG_REGISTERS)
+ bytes += (fparg_count - NUM_FPR_ARG_REGISTERS) * sizeof(double);
+
+ /* The stack space allocated needs to be a multiple of 16 bytes. */
+ bytes = (bytes + 15) & ~0xF;
+
+ /* Add in the space for the copied structures. */
+ bytes += struct_copy_size;
+
+ cif->flags = flags;
+ cif->bytes = bytes;
+
+ return FFI_OK;
+}
+
+/*@-declundef@*/
+/*@-exportheader@*/
+extern void ffi_call_SYSV(/*@out@*/ extended_cif *,
+ unsigned, unsigned,
+ /*@out@*/ unsigned *,
+ void (*fn)());
+/*@=declundef@*/
+/*@=exportheader@*/
+
+void ffi_call(/*@dependent@*/ ffi_cif *cif,
+ void (*fn)(),
+ /*@out@*/ void *rvalue,
+ /*@dependent@*/ void **avalue)
+{
+ extended_cif ecif;
+
+ ecif.cif = cif;
+ ecif.avalue = avalue;
+
+ /* If the return value is a struct and we don't have a return */
+ /* value address then we need to make one */
+
+ if ((rvalue == NULL) &&
+ (cif->rtype->type == FFI_TYPE_STRUCT))
+ {
+ /*@-sysunrecog@*/
+ ecif.rvalue = alloca(cif->rtype->size);
+ /*@=sysunrecog@*/
+ }
+ else
+ ecif.rvalue = rvalue;
+
+
+ switch (cif->abi)
+ {
+ case FFI_SYSV:
+ case FFI_GCC_SYSV:
+ /*@-usedef@*/
+ ffi_call_SYSV(&ecif, -cif->bytes,
+ cif->flags, ecif.rvalue, fn);
+ /*@=usedef@*/
+ break;
+ default:
+ FFI_ASSERT(0);
+ break;
+ }
+}
+
+
+static void flush_icache(char *, int);
+
+ffi_status
+ffi_prep_closure (ffi_closure* closure,
+ ffi_cif* cif,
+ void (*fun)(ffi_cif*, void*, void**, void*),
+ void *user_data)
+{
+ unsigned int *tramp;
+
+ FFI_ASSERT (cif->abi == FFI_GCC_SYSV);
+
+ tramp = (unsigned int *) &closure->tramp[0];
+ tramp[0] = 0x7c0802a6; /* mflr r0 */
+ tramp[1] = 0x4800000d; /* bl 10 <trampoline_initial+0x10> */
+ tramp[4] = 0x7d6802a6; /* mflr r11 */
+ tramp[5] = 0x7c0803a6; /* mtlr r0 */
+ tramp[6] = 0x800b0000; /* lwz r0,0(r11) */
+ tramp[7] = 0x816b0004; /* lwz r11,4(r11) */
+ tramp[8] = 0x7c0903a6; /* mtctr r0 */
+ tramp[9] = 0x4e800420; /* bctr */
+ *(void **) &tramp[2] = (void *)ffi_closure_SYSV; /* function */
+ *(void **) &tramp[3] = (void *)closure; /* context */
+
+ closure->cif = cif;
+ closure->fun = fun;
+ closure->user_data = user_data;
+
+ /* Flush the icache. */
+ flush_icache(&closure->tramp[0],FFI_TRAMPOLINE_SIZE);
+
+ return FFI_OK;
+}
+
+
+#define MIN_CACHE_LINE_SIZE 8
+
+static void flush_icache(char * addr1, int size)
+{
+ int i;
+ char * addr;
+ for (i = 0; i < size; i += MIN_CACHE_LINE_SIZE) {
+ addr = addr1 + i;
+ __asm__ volatile ("icbi 0,%0;" "dcbf 0,%0;" : : "r"(addr) : "memory");
+ }
+ addr = addr1 + size - 1;
+ __asm__ volatile ("icbi 0,%0;" "dcbf 0,%0;" "sync;" "isync;" : : "r"(addr) : "memory");
+}
+
+
+int ffi_closure_helper_SYSV (ffi_closure*, void*, unsigned long*,
+ unsigned long*, unsigned long*);
+
+/* Basically the trampoline invokes ffi_closure_SYSV, and on
+ * entry, r11 holds the address of the closure.
+ * After storing the registers that could possibly contain
+ * parameters to be passed into the stack frame and setting
+ * up space for a return value, ffi_closure_SYSV invokes the
+ * following helper function to do most of the work
+ */
+
+int
+ffi_closure_helper_SYSV (ffi_closure* closure, void * rvalue,
+ unsigned long * pgr, unsigned long * pfr,
+ unsigned long * pst)
+{
+ /* rvalue is the pointer to space for return value in closure assembly */
+ /* pgr is the pointer to where r3-r10 are stored in ffi_closure_SYSV */
+ /* pfr is the pointer to where f1-f8 are stored in ffi_closure_SYSV */
+ /* pst is the pointer to outgoing parameter stack in original caller */
+
+ void ** avalue;
+ ffi_type ** arg_types;
+ long i, avn;
+ long nf; /* number of floating registers already used */
+ long ng; /* number of general registers already used */
+ ffi_cif * cif;
+ double temp;
+
+ cif = closure->cif;
+ avalue = alloca(cif->nargs * sizeof(void *));
+
+ nf = 0;
+ ng = 0;
+
+ /* Copy the caller's structure return value address so that the closure
+ returns the data directly to the caller. */
+ if (cif->rtype->type == FFI_TYPE_STRUCT)
+ {
+ rvalue = *pgr;
+ ng++;
+ pgr++;
+ }
+
+ i = 0;
+ avn = cif->nargs;
+ arg_types = cif->arg_types;
+
+ /* Grab the addresses of the arguments from the stack frame. */
+ while (i < avn)
+ {
+ switch (arg_types[i]->type)
+ {
+ case FFI_TYPE_SINT8:
+ case FFI_TYPE_UINT8:
+ /* there are 8 gpr registers used to pass values */
+ if (ng < 8) {
+ avalue[i] = (((char *)pgr)+3);
+ ng++;
+ pgr++;
+ } else {
+ avalue[i] = (((char *)pst)+3);
+ pst++;
+ }
+ break;
+
+ case FFI_TYPE_SINT16:
+ case FFI_TYPE_UINT16:
+ /* there are 8 gpr registers used to pass values */
+ if (ng < 8) {
+ avalue[i] = (((char *)pgr)+2);
+ ng++;
+ pgr++;
+ } else {
+ avalue[i] = (((char *)pst)+2);
+ pst++;
+ }
+ break;
+
+ case FFI_TYPE_SINT32:
+ case FFI_TYPE_UINT32:
+ case FFI_TYPE_POINTER:
+ case FFI_TYPE_STRUCT:
+ /* there are 8 gpr registers used to pass values */
+ if (ng < 8) {
+ avalue[i] = pgr;
+ ng++;
+ pgr++;
+ } else {
+ avalue[i] = pst;
+ pst++;
+ }
+ break;
+
+ case FFI_TYPE_SINT64:
+ case FFI_TYPE_UINT64:
+ /* passing long long ints are complex, they must
+ * be passed in suitable register pairs such as
+ * (r3,r4) or (r5,r6) or (r6,r7), or (r7,r8) or (r9,r10)
+ * and if the entire pair aren't available then the outgoing
+ * parameter stack is used for both but an alignment of 8
+ * must will be kept. So we must either look in pgr
+ * or pst to find the correct address for this type
+ * of parameter.
+ */
+ if (ng < 7) {
+ if (ng & 0x01) {
+ /* skip r4, r6, r8 as starting points */
+ ng++;
+ pgr++;
+ }
+ avalue[i] = pgr;
+ ng+=2;
+ pgr+=2;
+ } else {
+ if (((long)pst) & 4) pst++;
+ avalue[i] = pst;
+ pst+=2;
+ }
+ break;
+
+ case FFI_TYPE_FLOAT:
+ /* unfortunately float values are stored as doubles
+ * in the ffi_closure_SYSV code (since we don't check
+ * the type in that routine). This is also true
+ * of floats passed on the outgoing parameter stack.
+ * Also, on the outgoing stack all values are aligned
+ * to 8
+ *
+ * Don't you just love the simplicity of this ABI!
+ */
+
+ /* there are 8 64bit floating point registers */
+
+ if (nf < 8) {
+ temp = *(double*)pfr;
+ *(float*)pfr = (float)temp;
+ avalue[i] = pfr;
+ nf++;
+ pfr+=2;
+ } else {
+ /* FIXME? here we are really changing the values
+ * stored in the original calling routines outgoing
+ * parameter stack. This is probably a really
+ * naughty thing to do but...
+ */
+ if (((long)pst) & 4) pst++;
+ temp = *(double*)pst;
+ *(float*)pst = (float)temp;
+ avalue[i] = pst;
+ nf++;
+ pst+=2;
+ }
+ break;
+
+ case FFI_TYPE_DOUBLE:
+ /* On the outgoing stack all values are aligned to 8 */
+ /* there are 8 64bit floating point registers */
+
+ if (nf < 8) {
+ avalue[i] = pfr;
+ nf++;
+ pfr+=2;
+ } else {
+ if (((long)pst) & 4) pst++;
+ avalue[i] = pst;
+ nf++;
+ pst+=2;
+ }
+ break;
+
+ default:
+ FFI_ASSERT(0);
+ }
+
+ i++;
+ }
+
+
+ (closure->fun) (cif, rvalue, avalue, closure->user_data);
+
+ /* Tell ffi_closure_osf how to perform return type promotions. */
+ return cif->rtype->type;
+
+}
+
+
+
+
+
diff --git a/libffi/powerpc/ppc_closure.S b/libffi/powerpc/ppc_closure.S
new file mode 100644
index 00000000000..311857724cc
--- /dev/null
+++ b/libffi/powerpc/ppc_closure.S
@@ -0,0 +1,148 @@
+#define LIBFFI_ASM
+#include <powerpc/asm.h>
+
+.globl ffi_closure_helper_SYSV
+
+ENTRY(ffi_closure_SYSV)
+ stwu %r1,-144(%r1)
+ mflr %r0
+ stw %r31,140(%r1)
+ stw %r0,148(%r1)
+
+# we want to build up an areas for the parameters passed
+# in registers (both floating point and integer)
+
+ # so first save gpr 3 to gpr 10 (aligned to 4)
+ stw %r3, 16(%r1)
+ stw %r4, 20(%r1)
+ stw %r5, 24(%r1)
+ stw %r6, 28(%r1)
+ stw %r7, 32(%r1)
+ stw %r8, 36(%r1)
+ stw %r9, 40(%r1)
+ stw %r10,44(%r1)
+
+ # next save fpr 1 to fpr 8 (aligned to 8)
+ stfd %f1, 48(%r1)
+ stfd %f2, 56(%r1)
+ stfd %f3, 64(%r1)
+ stfd %f4, 72(%r1)
+ stfd %f5, 80(%r1)
+ stfd %f6, 88(%r1)
+ stfd %f7, 96(%r1)
+ stfd %f8, 104(%r1)
+
+ # set up registers for the routine that actually does the work
+ # get the context pointer from the trampoline
+ mr %r3,%r11
+
+ # now load up the pointer to the result storage
+ addi %r4,%r1,112
+
+ # now load up the pointer to the saved gpr registers
+ addi %r5,%r1,16
+
+ # now load up the pointer to the saved fpr registers */
+ addi %r6,%r1,48
+
+ # now load up the pointer to the outgoing parameter
+ # stack in the previous frame
+ # i.e. the previous frame pointer + 8
+ addi %r7,%r1,152
+
+ # make the call
+ bl JUMPTARGET(ffi_closure_helper_SYSV)
+
+ # now r3 contains the return type
+ # so use it to look up in a table
+ # so we know how to deal with each type
+
+ # look up the proper starting point in table
+ # by using return type as offset
+ addi %r5,%r1,112 # get pointer to results area
+ addis %r4,0,.L60@ha # get address of jump table
+ addi %r4,%r4,.L60@l
+ slwi %r3,%r3,2 # now multiply return type by 4
+ lwzx %r3,%r4,%r3 # get the contents of that table value
+ add %r3,%r3,%r4 # add contents of table to table address
+ mtctr %r3
+ bctr # jump to it
+ .align 2
+.L60:
+ .long .L44-.L60 # FFI_TYPE_VOID
+ .long .L50-.L60 # FFI_TYPE_INT
+ .long .L47-.L60 # FFI_TYPE_FLOAT
+ .long .L46-.L60 # FFI_TYPE_DOUBLE
+ .long .L46-.L60 # FFI_TYPE_LONGDOUBLE
+ .long .L56-.L60 # FFI_TYPE_UINT8
+ .long .L55-.L60 # FFI_TYPE_SINT8
+ .long .L58-.L60 # FFI_TYPE_UINT16
+ .long .L57-.L60 # FFI_TYPE_SINT16
+ .long .L50-.L60 # FFI_TYPE_UINT32
+ .long .L50-.L60 # FFI_TYPE_SINT32
+ .long .L48-.L60 # FFI_TYPE_UINT64
+ .long .L48-.L60 # FFI_TYPE_SINT64
+ .long .L44-.L60 # FFI_TYPE_STRUCT
+ .long .L50-.L60 # FFI_TYPE_POINTER
+
+
+# case double
+.L46:
+ lfd %f1,0(%r5)
+ b .L44
+
+# case float
+.L47:
+ lfs %f1,0(%r5)
+ b .L44
+
+# case long long
+.L48:
+ lwz %r3,0(%r5)
+ lwz %r4,4(%r5)
+ b .L44
+
+# case default / int32 / pointer
+.L50:
+ lwz %r3,0(%r5)
+ b .L44
+
+# case signed int8
+.L55:
+ addi %r5,%r5,3
+ lbz %r3,0(%r5)
+ extsb %r3,%r3
+ b .L44
+
+# case unsigned int8
+.L56:
+ addi %r5,%r5,3
+ lbz %r3,0(%r5)
+ b .L44
+
+# case signed int16
+.L57:
+ addi %r5,%r5,2
+ lhz %r3,0(%r5)
+ extsh %r3,%r3
+ b .L44
+
+#case unsigned int16
+.L58:
+ addi %r5,%r5,2
+ lhz %r3,0(%r5)
+
+# case void / done
+.L44:
+
+ lwz %r11,0(%r1)
+ lwz %r0,4(%r11)
+ mtlr %r0
+ lwz %r31,-4(%r11)
+ mr %r1,%r11
+ blr
+END(ffi_closure_SYSV)
+
+
+
+
diff --git a/libffi/powerpc/sysv.S b/libffi/powerpc/sysv.S
new file mode 100644
index 00000000000..6680b4932a1
--- /dev/null
+++ b/libffi/powerpc/sysv.S
@@ -0,0 +1,119 @@
+/* -----------------------------------------------------------------------
+ sysv.h - Copyright (c) 1998 Geoffrey Keating
+
+ PowerPC Assembly glue.
+
+ $Id: sysv.S,v 1.1 2001/08/02 19:31:55 orph Exp $
+
+ 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 AUTHOR 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.
+ ----------------------------------------------------------------------- */
+
+#define LIBFFI_ASM
+#include <ffi.h>
+#include <powerpc/asm.h>
+
+ .globl ffi_prep_args
+ENTRY(ffi_call_SYSV)
+ /* Save the old stack pointer as AP. */
+ mr %r8,%r1
+
+ /* Allocate the stack space we need. */
+ stwux %r1,%r1,%r4
+ /* Save registers we use. */
+ mflr %r9
+ stw %r28,-16(%r8)
+ stw %r29,-12(%r8)
+ stw %r30, -8(%r8)
+ stw %r31, -4(%r8)
+ stw %r9, 4(%r8)
+
+ /* Save arguments over call... */
+ mr %r31,%r5 /* flags, */
+ mr %r30,%r6 /* rvalue, */
+ mr %r29,%r7 /* function address, */
+ mr %r28,%r8 /* our AP. */
+
+ /* Call ffi_prep_args. */
+ mr %r4,%r1
+ bl JUMPTARGET(ffi_prep_args)
+
+ /* Now do the call. */
+ /* Set up cr1 with bits 4-7 of the flags. */
+ mtcrf 0x40,%r31
+ /* Get the address to call into CTR. */
+ mtctr %r29
+ /* Load all those argument registers. */
+ lwz %r3,-16-(8*4)(%r28)
+ lwz %r4,-16-(7*4)(%r28)
+ lwz %r5,-16-(6*4)(%r28)
+ lwz %r6,-16-(5*4)(%r28)
+ bf- 5,1f
+ nop
+ lwz %r7,-16-(4*4)(%r28)
+ lwz %r8,-16-(3*4)(%r28)
+ lwz %r9,-16-(2*4)(%r28)
+ lwz %r10,-16-(1*4)(%r28)
+ nop
+1:
+
+ /* Load all the FP registers. */
+ bf- 6,2f
+ lfd %f1,-16-(8*4)-(8*8)(%r28)
+ lfd %f2,-16-(8*4)-(7*8)(%r28)
+ lfd %f3,-16-(8*4)-(6*8)(%r28)
+ lfd %f4,-16-(8*4)-(5*8)(%r28)
+ nop
+ lfd %f5,-16-(8*4)-(4*8)(%r28)
+ lfd %f6,-16-(8*4)-(3*8)(%r28)
+ lfd %f7,-16-(8*4)-(2*8)(%r28)
+ lfd %f8,-16-(8*4)-(1*8)(%r28)
+2:
+
+ /* Make the call. */
+ bctrl
+
+ /* Now, deal with the return value. */
+ mtcrf 0x01,%r31
+ bt- 30,L(done_return_value)
+ bt- 29,L(fp_return_value)
+ stw %r3,0(%r30)
+ bf+ 28,L(done_return_value)
+ stw %r4,4(%r30)
+ /* Fall through... */
+
+L(done_return_value):
+ /* Restore the registers we used and return. */
+ lwz %r9, 4(%r28)
+ lwz %r31, -4(%r28)
+ mtlr %r9
+ lwz %r30, -8(%r28)
+ lwz %r29,-12(%r28)
+ lwz %r28,-16(%r28)
+ lwz %r1,0(%r1)
+ blr
+
+L(fp_return_value):
+ bf 28,L(float_return_value)
+ stfd %f1,0(%r30)
+ b L(done_return_value)
+L(float_return_value):
+ stfs %f1,0(%r30)
+ b L(done_return_value)
+END(ffi_call_SYSV)
diff --git a/libffi/prep_cif.c b/libffi/prep_cif.c
new file mode 100644
index 00000000000..107330334f2
--- /dev/null
+++ b/libffi/prep_cif.c
@@ -0,0 +1,146 @@
+/* -----------------------------------------------------------------------
+ prep_cif.c - Copyright (c) 1996, 1998 Cygnus Solutions
+
+ 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 RED HAT 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.
+ ----------------------------------------------------------------------- */
+
+#include <ffi.h>
+#include <ffi_private.h>
+#include <stdlib.h>
+
+
+/* Round up to SIZEOF_ARG. */
+
+#define STACK_ARG_SIZE(x) ALIGN(x, SIZEOF_ARG)
+
+/* Perform machine independent initialization of aggregate type
+ specifications. */
+
+static ffi_status initialize_aggregate(/*@out@*/ ffi_type *arg)
+{
+ ffi_type **ptr;
+
+ FFI_ASSERT(arg != NULL);
+
+ /*@-usedef@*/
+
+ FFI_ASSERT(arg->elements != NULL);
+ FFI_ASSERT(arg->size == 0);
+ FFI_ASSERT(arg->alignment == 0);
+
+ ptr = &(arg->elements[0]);
+
+ while ((*ptr) != NULL)
+ {
+ if (((*ptr)->size == 0) && (initialize_aggregate((*ptr)) != FFI_OK))
+ return FFI_BAD_TYPEDEF;
+
+ /* Perform a sanity check on the argument type */
+ FFI_ASSERT(ffi_type_test((*ptr)));
+
+ arg->size = ALIGN(arg->size, (*ptr)->alignment);
+ arg->size += (*ptr)->size;
+
+ arg->alignment = (arg->alignment > (*ptr)->alignment) ?
+ arg->alignment : (*ptr)->alignment;
+
+ ptr++;
+ }
+
+ if (arg->size == 0)
+ return FFI_BAD_TYPEDEF;
+ else
+ return FFI_OK;
+
+ /*@=usedef@*/
+}
+
+/* Perform machine independent ffi_cif preparation, then call
+ machine dependent routine. */
+
+ffi_status ffi_prep_cif(/*@out@*/ /*@partial@*/ ffi_cif *cif,
+ ffi_abi abi, unsigned int nargs,
+ /*@dependent@*/ /*@out@*/ /*@partial@*/ ffi_type *rtype,
+ /*@dependent@*/ ffi_type **atypes)
+{
+ unsigned bytes = 0;
+ unsigned int i;
+ ffi_type **ptr;
+
+ FFI_ASSERT(cif != NULL);
+ FFI_ASSERT((abi > FFI_FIRST_ABI) && (abi < FFI_LAST_ABI));
+
+ cif->abi = abi;
+ cif->arg_types = atypes;
+ cif->nargs = nargs;
+ cif->rtype = rtype;
+
+ cif->flags = 0;
+
+ /* Initialize the return type if necessary */
+ /*@-usedef@*/
+ if ((cif->rtype->size == 0) && (initialize_aggregate(cif->rtype) != FFI_OK))
+ return FFI_BAD_TYPEDEF;
+ /*@=usedef@*/
+
+ /* Perform a sanity check on the return type */
+ FFI_ASSERT(ffi_type_test(cif->rtype));
+
+#ifndef M68K
+ /* Make space for the return structure pointer */
+ if (cif->rtype->type == FFI_TYPE_STRUCT
+#ifdef __sparc__
+ && (cif->abi != FFI_V9 || cif->rtype->size > 32)
+#endif
+ )
+ bytes = STACK_ARG_SIZE(sizeof(void*));
+#endif
+
+ for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++)
+ {
+ /* Perform a sanity check on the argument type */
+ FFI_ASSERT(ffi_type_test(*ptr));
+
+ /* Initialize any uninitialized aggregate type definitions */
+ if (((*ptr)->size == 0) && (initialize_aggregate((*ptr)) != FFI_OK))
+ return FFI_BAD_TYPEDEF;
+
+#ifdef __sparc__
+ if (((*ptr)->type == FFI_TYPE_STRUCT
+ && ((*ptr)->size > 16 || cif->abi != FFI_V9))
+ || ((*ptr)->type == FFI_TYPE_LONGDOUBLE
+ && cif->abi != FFI_V9))
+ bytes += sizeof(void*);
+ else
+#endif
+ {
+ /* Add any padding if necessary */
+ if (((*ptr)->alignment - 1) & bytes)
+ bytes = ALIGN(bytes, (*ptr)->alignment);
+
+ bytes += STACK_ARG_SIZE((*ptr)->size);
+ }
+ }
+
+ cif->bytes = bytes;
+
+ /* Perform machine dependent cif processing */
+ return ffi_prep_cif_machdep(cif);
+}
diff --git a/libffi/raw_api.c b/libffi/raw_api.c
new file mode 100644
index 00000000000..c41cf2eea9c
--- /dev/null
+++ b/libffi/raw_api.c
@@ -0,0 +1,240 @@
+/* -----------------------------------------------------------------------
+ raw_api.c - Copyright (c) 1999 Cygnus Solutions
+
+ Author: Kresten Krab Thorup <krab@gnu.org>
+
+ 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 RED HAT 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.
+ ----------------------------------------------------------------------- */
+
+/* This file defines generic functions for use with the raw api. */
+
+#include <ffi.h>
+#include <ffi_private.h>
+
+#if !FFI_NO_RAW_API
+
+size_t
+ffi_raw_size (ffi_cif *cif)
+{
+ size_t result = 0;
+ int i;
+
+ ffi_type **at = cif->arg_types;
+
+ for (i = cif->nargs-1; i >= 0; i--, at++)
+ {
+#if !FFI_NO_STRUCTS
+ if ((*at)->type == FFI_TYPE_STRUCT)
+ result += ALIGN (sizeof (void*), SIZEOF_ARG);
+ else
+#endif
+ result += ALIGN ((*at)->size, SIZEOF_ARG);
+ }
+
+ return result;
+}
+
+
+void
+ffi_raw_to_ptrarray (ffi_cif *cif, ffi_raw *raw, void **args)
+{
+ unsigned i;
+ ffi_type **tp = cif->arg_types;
+
+#if WORDS_BIGENDIAN
+
+ for (i = 0; i < cif->nargs; i++, tp++, args++)
+ {
+ switch ((*tp)->type)
+ {
+ case FFI_TYPE_UINT8:
+ case FFI_TYPE_SINT8:
+ *args = (void*) ((char*)(raw++) + SIZEOF_ARG - 1);
+ break;
+
+ case FFI_TYPE_UINT16:
+ case FFI_TYPE_SINT16:
+ *args = (void*) ((char*)(raw++) + SIZEOF_ARG - 2);
+ break;
+
+#if SIZEOF_ARG >= 4
+ case FFI_TYPE_UINT32:
+ case FFI_TYPE_SINT32:
+ *args = (void*) ((char*)(raw++) + SIZEOF_ARG - 4);
+ break;
+#endif
+
+#if !FFI_NO_STRUCTS
+ case FFI_TYPE_STRUCT:
+ *args = (raw++)->ptr;
+ break;
+#endif
+
+ case FFI_TYPE_POINTER:
+ *args = (void*) &(raw++)->ptr;
+ break;
+
+ default:
+ *args = raw;
+ raw += ALIGN ((*tp)->size, SIZEOF_ARG) / SIZEOF_ARG;
+ }
+ }
+
+#else /* WORDS_BIGENDIAN */
+
+#if !PDP
+
+ /* then assume little endian */
+ for (i = 0; i < cif->nargs; i++, tp++, args++)
+ {
+#if !FFI_NO_STRUCTS
+ if ((*tp)->type == FFI_TYPE_STRUCT)
+ {
+ *args = (raw++)->ptr;
+ }
+ else
+#endif
+ {
+ *args = (void*) raw;
+ raw += ALIGN ((*tp)->size, sizeof (void*)) / sizeof (void*);
+ }
+ }
+
+#else
+#error "pdp endian not supported"
+#endif /* ! PDP */
+
+#endif /* WORDS_BIGENDIAN */
+}
+
+void
+ffi_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_raw *raw)
+{
+ unsigned i;
+ ffi_type **tp = cif->arg_types;
+
+ for (i = 0; i < cif->nargs; i++, tp++, args++)
+ {
+ switch ((*tp)->type)
+ {
+ case FFI_TYPE_UINT8:
+ (raw++)->uint = *(UINT8*) (*args);
+ break;
+
+ case FFI_TYPE_SINT8:
+ (raw++)->sint = *(SINT8*) (*args);
+ break;
+
+ case FFI_TYPE_UINT16:
+ (raw++)->uint = *(UINT16*) (*args);
+ break;
+
+ case FFI_TYPE_SINT16:
+ (raw++)->sint = *(SINT16*) (*args);
+ break;
+
+#if SIZEOF_ARG >= 4
+ case FFI_TYPE_UINT32:
+ (raw++)->uint = *(UINT32*) (*args);
+ break;
+
+ case FFI_TYPE_SINT32:
+ (raw++)->sint = *(SINT32*) (*args);
+ break;
+#endif
+
+#if !FFI_NO_STRUCTS
+ case FFI_TYPE_STRUCT:
+ (raw++)->ptr = *args;
+ break;
+#endif
+
+ case FFI_TYPE_POINTER:
+ (raw++)->ptr = **(void***) args;
+ break;
+
+ default:
+ memcpy ((void*) raw->data, (void*)*args, (*tp)->size);
+ raw += ALIGN ((*tp)->size, SIZEOF_ARG) / SIZEOF_ARG;
+ }
+ }
+}
+
+#if !FFI_NATIVE_RAW_API
+
+
+/* This is a generic definition of ffi_raw_call, to be used if the
+ * native system does not provide a machine-specific implementation.
+ * Having this, allows code to be written for the raw API, without
+ * the need for system-specific code to handle input in that format;
+ * these following couple of functions will handle the translation forth
+ * and back automatically. */
+
+void ffi_raw_call (/*@dependent@*/ ffi_cif *cif,
+ void (*fn)(),
+ /*@out@*/ void *rvalue,
+ /*@dependent@*/ ffi_raw *raw)
+{
+ void **avalue = (void**) alloca (cif->nargs * sizeof (void*));
+ ffi_raw_to_ptrarray (cif, raw, avalue);
+ ffi_call (cif, fn, rvalue, avalue);
+}
+
+#if FFI_CLOSURES /* base system provides closures */
+
+static void
+ffi_translate_args (ffi_cif *cif, void *rvalue,
+ void **avalue, void *user_data)
+{
+ ffi_raw *raw = (ffi_raw*)alloca (ffi_raw_size (cif));
+ ffi_raw_closure *cl = (ffi_raw_closure*)user_data;
+
+ ffi_ptrarray_to_raw (cif, avalue, raw);
+ (*cl->fun) (cif, rvalue, raw, cl->user_data);
+}
+
+/* Again, here is the generic version of ffi_prep_raw_closure, which
+ * will install an intermediate "hub" for translation of arguments from
+ * the pointer-array format, to the raw format */
+
+ffi_status
+ffi_prep_raw_closure (ffi_raw_closure* cl,
+ ffi_cif *cif,
+ void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
+ void *user_data)
+{
+ ffi_status status;
+
+ status = ffi_prep_closure ((ffi_closure*) cl,
+ cif,
+ &ffi_translate_args,
+ (void*)cl);
+ if (status == FFI_OK)
+ {
+ cl->fun = fun;
+ cl->user_data = user_data;
+ }
+
+ return status;
+}
+
+#endif /* FFI_CLOSURES */
+#endif /* !FFI_NATIVE_RAW_API */
+#endif /* !FFI_NO_RAW_API */
diff --git a/libffi/s390/ffi.c b/libffi/s390/ffi.c
new file mode 100644
index 00000000000..f605152838c
--- /dev/null
+++ b/libffi/s390/ffi.c
@@ -0,0 +1,589 @@
+/* -----------------------------------------------------------------------
+ ffi.c - Copyright (c) 2000 Software AG
+
+ S390 Foreign Function Interface
+
+ 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 AUTHOR 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.
+ ----------------------------------------------------------------------- */
+/*====================================================================*/
+/* Includes */
+/* -------- */
+/*====================================================================*/
+
+#include <ffi.h>
+#include <ffi_private.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+
+/*====================== End of Includes =============================*/
+
+/*====================================================================*/
+/* Defines */
+/* ------- */
+/*====================================================================*/
+
+#define MAX_GPRARGS 5 /* Max. no. of GPR available */
+#define MAX_FPRARGS 2 /* Max. no. of FPR available */
+
+#define STR_GPR 1 /* Structure will fit in 1 or 2 GPR */
+#define STR_FPR 2 /* Structure will fit in a FPR */
+#define STR_STACK 3 /* Structure needs to go on stack */
+
+/*===================== End of Defines ===============================*/
+
+/*====================================================================*/
+/* Types */
+/* ----- */
+/*====================================================================*/
+
+typedef struct stackLayout
+{
+ int *backChain;
+ int *endOfStack;
+ int glue[2];
+ int scratch[2];
+ int gprArgs[MAX_GPRARGS];
+ int notUsed;
+ union
+ {
+ float f;
+ double d;
+ } fprArgs[MAX_FPRARGS];
+ int unUsed[8];
+ int outArgs[100];
+} stackLayout;
+
+/*======================== End of Types ==============================*/
+
+/*====================================================================*/
+/* Prototypes */
+/* ---------- */
+/*====================================================================*/
+
+void ffi_prep_args(stackLayout *, extended_cif *);
+static int ffi_check_struct(ffi_type *, unsigned int *);
+static void ffi_insert_int(int, stackLayout *, int *, int *);
+static void ffi_insert_int64(long long, stackLayout *, int *, int *);
+static void ffi_insert_double(double, stackLayout *, int *, int *);
+
+/*====================== End of Prototypes ===========================*/
+
+/*====================================================================*/
+/* Externals */
+/* --------- */
+/*====================================================================*/
+
+extern void ffi_call_SYSV(void (*)(stackLayout *, extended_cif *),
+ extended_cif *,
+ unsigned, unsigned,
+ unsigned *,
+ void (*fn)());
+
+/*====================== End of Externals ============================*/
+
+/*====================================================================*/
+/* */
+/* Name - ffi_check_struct. */
+/* */
+/* Function - Determine if a structure can be passed within a */
+/* general or floating point register. */
+/* */
+/*====================================================================*/
+
+int
+ffi_check_struct(ffi_type *arg, unsigned int *strFlags)
+{
+ ffi_type *element;
+ int i_Element;
+
+ for (i_Element = 0; arg->elements[i_Element]; i_Element++) {
+ element = arg->elements[i_Element];
+ switch (element->type) {
+ case FFI_TYPE_DOUBLE :
+ *strFlags |= STR_FPR;
+ break;
+
+ case FFI_TYPE_STRUCT :
+ *strFlags |= ffi_check_struct(element, strFlags);
+ break;
+
+ default :
+ *strFlags |= STR_GPR;
+ }
+ }
+ return (*strFlags);
+}
+
+/*======================== End of Routine ============================*/
+
+/*====================================================================*/
+/* */
+/* Name - ffi_insert_int. */
+/* */
+/* Function - Insert an integer parameter in a register if there are */
+/* spares else on the stack. */
+/* */
+/*====================================================================*/
+
+void
+ffi_insert_int(int gprValue, stackLayout *stack,
+ int *intArgC, int *outArgC)
+{
+ if (*intArgC < MAX_GPRARGS) {
+ stack->gprArgs[*intArgC] = gprValue;
+ *intArgC += 1;
+ }
+ else {
+ stack->outArgs[*outArgC++] = gprValue;
+ *outArgC += 1;
+ }
+}
+
+/*======================== End of Routine ============================*/
+
+/*====================================================================*/
+/* */
+/* Name - ffi_insert_int64. */
+/* */
+/* Function - Insert a long long parameter in registers if there are */
+/* spares else on the stack. */
+/* */
+/*====================================================================*/
+
+void
+ffi_insert_int64(long long llngValue, stackLayout *stack,
+ int *intArgC, int *outArgC)
+{
+
+ if (*intArgC < (MAX_GPRARGS-1)) {
+ memcpy(&stack->gprArgs[*intArgC],
+ &llngValue, sizeof(long long));
+ *intArgC += 2;
+ }
+ else {
+ memcpy(&stack->outArgs[*outArgC],
+ &llngValue, sizeof(long long));
+ *outArgC += 2;
+ }
+
+}
+
+/*======================== End of Routine ============================*/
+
+/*====================================================================*/
+/* */
+/* Name - ffi_insert_double. */
+/* */
+/* Function - Insert a double parameter in a FP register if there is */
+/* a spare else on the stack. */
+/* */
+/*====================================================================*/
+
+void
+ffi_insert_double(double dblValue, stackLayout *stack,
+ int *fprArgC, int *outArgC)
+{
+
+ if (*fprArgC < MAX_FPRARGS) {
+ stack->fprArgs[*fprArgC].d = dblValue;
+ *fprArgC += 1;
+ }
+ else {
+ memcpy(&stack->outArgs[*outArgC],
+ &dblValue,sizeof(double));
+ *outArgC += 2;
+ }
+
+}
+
+/*======================== End of Routine ============================*/
+
+/*====================================================================*/
+/* */
+/* Name - ffi_prep_args. */
+/* */
+/* Function - Prepare parameters for call to function. */
+/* */
+/* ffi_prep_args is called by the assembly routine once stack space */
+/* has been allocated for the function's arguments. */
+/* */
+/* The stack layout we want looks like this: */
+/* *------------------------------------------------------------* */
+/* | 0 | Back chain (a 0 here signifies end of back chain) | */
+/* +--------+---------------------------------------------------+ */
+/* | 4 | EOS (end of stack, not used on Linux for S390) | */
+/* +--------+---------------------------------------------------+ */
+/* | 8 | Glue used in other linkage formats | */
+/* +--------+---------------------------------------------------+ */
+/* | 12 | Glue used in other linkage formats | */
+/* +--------+---------------------------------------------------+ */
+/* | 16 | Scratch area | */
+/* +--------+---------------------------------------------------+ */
+/* | 20 | Scratch area | */
+/* +--------+---------------------------------------------------+ */
+/* | 24 | GPR parameter register 1 | */
+/* +--------+---------------------------------------------------+ */
+/* | 28 | GPR parameter register 2 | */
+/* +--------+---------------------------------------------------+ */
+/* | 32 | GPR parameter register 3 | */
+/* +--------+---------------------------------------------------+ */
+/* | 36 | GPR parameter register 4 | */
+/* +--------+---------------------------------------------------+ */
+/* | 40 | GPR parameter register 5 | */
+/* +--------+---------------------------------------------------+ */
+/* | 44 | Unused | */
+/* +--------+---------------------------------------------------+ */
+/* | 48 | FPR parameter register 1 | */
+/* +--------+---------------------------------------------------+ */
+/* | 56 | FPR parameter register 2 | */
+/* +--------+---------------------------------------------------+ */
+/* | 64 | Unused | */
+/* +--------+---------------------------------------------------+ */
+/* | 96 | Outgoing args (length x) | */
+/* +--------+---------------------------------------------------+ */
+/* | 96+x | Copy area for structures (length y) | */
+/* +--------+---------------------------------------------------+ */
+/* | 96+x+y | Possible stack alignment | */
+/* *------------------------------------------------------------* */
+/* */
+/*====================================================================*/
+
+void
+ffi_prep_args(stackLayout *stack, extended_cif *ecif)
+{
+ const unsigned bytes = ecif->cif->bytes;
+ const unsigned flags = ecif->cif->flags;
+
+ /*----------------------------------------------------------*/
+ /* Pointer to the copy area on stack for structures */
+ /*----------------------------------------------------------*/
+ char *copySpace = (char *) stack + bytes + sizeof(stackLayout);
+
+ /*----------------------------------------------------------*/
+ /* Count of general and floating point register usage */
+ /*----------------------------------------------------------*/
+ int intArgC = 0,
+ fprArgC = 0,
+ outArgC = 0;
+
+ int i;
+ ffi_type **ptr;
+ void **p_argv;
+ size_t structCopySize;
+ unsigned gprValue, strFlags = 0;
+ unsigned long long llngValue;
+ double dblValue;
+
+ /* Now for the arguments. */
+ p_argv = ecif->avalue;
+
+ /*----------------------------------------------------------------------*/
+ /* If we returning a structure then we set the first parameter register */
+ /* to the address of where we are returning this structure */
+ /*----------------------------------------------------------------------*/
+ if (flags == FFI_TYPE_STRUCT)
+ stack->gprArgs[intArgC++] = (int) ecif->rvalue;
+
+ for (ptr = ecif->cif->arg_types, i = ecif->cif->nargs;
+ i > 0;
+ i--, ptr++, p_argv++)
+ {
+ switch ((*ptr)->type) {
+
+ case FFI_TYPE_FLOAT:
+ if (fprArgC < MAX_FPRARGS)
+ stack->fprArgs[fprArgC++].f = *(float *) *p_argv;
+ else
+ stack->outArgs[outArgC++] = *(int *) *p_argv;
+ break;
+
+ case FFI_TYPE_DOUBLE:
+ dblValue = *(double *) *p_argv;
+ ffi_insert_double(dblValue, stack, &fprArgC, &outArgC);
+ break;
+
+ case FFI_TYPE_UINT64:
+ case FFI_TYPE_SINT64:
+ llngValue = *(unsigned long long *) *p_argv;
+ ffi_insert_int64(llngValue, stack, &intArgC, &outArgC);
+ break;
+
+ case FFI_TYPE_UINT8:
+ gprValue = *(unsigned char *)*p_argv;
+ ffi_insert_int(gprValue, stack, &intArgC, &outArgC);
+ break;
+
+ case FFI_TYPE_SINT8:
+ gprValue = *(signed char *)*p_argv;
+ ffi_insert_int(gprValue, stack, &intArgC, &outArgC);
+ break;
+
+ case FFI_TYPE_UINT16:
+ gprValue = *(unsigned short *)*p_argv;
+ ffi_insert_int(gprValue, stack, &intArgC, &outArgC);
+ break;
+
+ case FFI_TYPE_SINT16:
+ gprValue = *(signed short *)*p_argv;
+ ffi_insert_int(gprValue, stack, &intArgC, &outArgC);
+ break;
+
+ case FFI_TYPE_STRUCT:
+ /*--------------------------------------------------*/
+ /* If structure > 8 bytes then it goes on the stack */
+ /*--------------------------------------------------*/
+ if (((*ptr)->size > 8) ||
+ ((*ptr)->size > 4 &&
+ (*ptr)->size < 8))
+ strFlags = STR_STACK;
+ else
+ strFlags = ffi_check_struct((ffi_type *) *ptr, &strFlags);
+
+ switch (strFlags) {
+ /*-------------------------------------------*/
+ /* Structure that will fit in one or two GPR */
+ /*-------------------------------------------*/
+ case STR_GPR :
+ if ((*ptr)->size <= 4) {
+ gprValue = *(unsigned int *) *p_argv;
+ gprValue = gprValue >> ((4 - (*ptr)->size) * 8);
+ ffi_insert_int(gprValue, stack, &intArgC, &outArgC);
+ }
+ else {
+ llngValue = *(unsigned long long *) *p_argv;
+ ffi_insert_int64(llngValue, stack, &intArgC, &outArgC);
+ }
+ break;
+
+ /*-------------------------------------------*/
+ /* Structure that will fit in one FPR */
+ /*-------------------------------------------*/
+ case STR_FPR :
+ dblValue = *(double *) *p_argv;
+ ffi_insert_double(dblValue, stack, &fprArgC, &outArgC);
+ break;
+
+ /*-------------------------------------------*/
+ /* Structure that must be copied to stack */
+ /*-------------------------------------------*/
+ default :
+ structCopySize = (((*ptr)->size + 15) & ~0xF);
+ copySpace -= structCopySize;
+ memcpy(copySpace, (char *)*p_argv, (*ptr)->size);
+ gprValue = (unsigned) copySpace;
+ if (intArgC < MAX_GPRARGS)
+ stack->gprArgs[intArgC++] = gprValue;
+ else
+ stack->outArgs[outArgC++] = gprValue;
+ }
+ break;
+
+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+ case FFI_TYPE_LONGDOUBLE:
+ structCopySize = (((*ptr)->size + 15) & ~0xF);
+ copySpace -= structCopySize;
+ memcpy(copySpace, (char *)*p_argv, (*ptr)->size);
+ gprValue = (unsigned) copySpace;
+ if (intArgC < MAX_GPRARGS)
+ stack->gprArgs[intArgC++] = gprValue;
+ else
+ stack->outArgs[outArgC++] = gprValue;
+ break;
+#endif
+
+ case FFI_TYPE_INT:
+ case FFI_TYPE_UINT32:
+ case FFI_TYPE_SINT32:
+ case FFI_TYPE_POINTER:
+ gprValue = *(unsigned *)*p_argv;
+ if (intArgC < MAX_GPRARGS)
+ stack->gprArgs[intArgC++] = gprValue;
+ else
+ stack->outArgs[outArgC++] = gprValue;
+ break;
+
+ }
+ }
+}
+
+/*======================== End of Routine ============================*/
+
+/*====================================================================*/
+/* */
+/* Name - ffi_prep_cif_machdep. */
+/* */
+/* Function - Perform machine dependent CIF processing. */
+/* */
+/*====================================================================*/
+
+ffi_status
+ffi_prep_cif_machdep(ffi_cif *cif)
+{
+ int i;
+ ffi_type **ptr;
+ unsigned bytes;
+ int fpArgC = 0,
+ intArgC = 0;
+ unsigned flags = 0;
+ unsigned structCopySize = 0;
+
+ /*-----------------------------------------------------------------*/
+ /* Extra space required in stack for overflow parameters. */
+ /*-----------------------------------------------------------------*/
+ bytes = 0;
+
+ /*--------------------------------------------------------*/
+ /* Return value handling. The rules are as follows: */
+ /* - 32-bit (or less) integer values are returned in gpr2 */
+ /* - Structures are returned as pointers in gpr2 */
+ /* - 64-bit integer values are returned in gpr2 and 3 */
+ /* - Single/double FP values are returned in fpr0 */
+ /*--------------------------------------------------------*/
+ flags = cif->rtype->type;
+
+ /*------------------------------------------------------------------------*/
+ /* The first MAX_GPRARGS words of integer arguments, and the */
+ /* first MAX_FPRARGS floating point arguments, go in registers; the rest */
+ /* goes on the stack. Structures and long doubles (if not equivalent */
+ /* to double) are passed as a pointer to a copy of the structure. */
+ /* Stuff on the stack needs to keep proper alignment. */
+ /*------------------------------------------------------------------------*/
+ for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++)
+ {
+ switch ((*ptr)->type)
+ {
+ case FFI_TYPE_FLOAT:
+ case FFI_TYPE_DOUBLE:
+ fpArgC++;
+ if (fpArgC > MAX_FPRARGS && intArgC%2 != 0)
+ intArgC++;
+ break;
+
+ case FFI_TYPE_UINT64:
+ case FFI_TYPE_SINT64:
+ /*----------------------------------------------------*/
+ /* 'long long' arguments are passed as two words, but */
+ /* either both words must fit in registers or both go */
+ /* on the stack. If they go on the stack, they must */
+ /* be 8-byte-aligned. */
+ /*----------------------------------------------------*/
+ if ((intArgC == MAX_GPRARGS-1) ||
+ (intArgC >= MAX_GPRARGS) &&
+ (intArgC%2 != 0))
+ intArgC++;
+ intArgC += 2;
+ break;
+
+ case FFI_TYPE_STRUCT:
+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+ case FFI_TYPE_LONGDOUBLE:
+#endif
+ /*----------------------------------------------------*/
+ /* We must allocate space for a copy of these to */
+ /* enforce pass-by-value. Pad the space up to a */
+ /* multiple of 16 bytes (the maximum alignment */
+ /* required for anything under the SYSV ABI). */
+ /*----------------------------------------------------*/
+ structCopySize += ((*ptr)->size + 15) & ~0xF;
+ /*----------------------------------------------------*/
+ /* Fall through (allocate space for the pointer). */
+ /*----------------------------------------------------*/
+
+ default:
+ /*----------------------------------------------------*/
+ /* Everything else is passed as a 4-byte word in a */
+ /* GPR either the object itself or a pointer to it. */
+ /*----------------------------------------------------*/
+ intArgC++;
+ break;
+ }
+ }
+
+ /*-----------------------------------------------------------------*/
+ /* Stack space. */
+ /*-----------------------------------------------------------------*/
+ if (intArgC > MAX_GPRARGS)
+ bytes += (intArgC - MAX_GPRARGS) * sizeof(int);
+ if (fpArgC > MAX_FPRARGS)
+ bytes += (fpArgC - MAX_FPRARGS) * sizeof(double);
+
+ /*-----------------------------------------------------------------*/
+ /* The stack space allocated needs to be a multiple of 16 bytes. */
+ /*-----------------------------------------------------------------*/
+ bytes = (bytes + 15) & ~0xF;
+
+ /*-----------------------------------------------------------------*/
+ /* Add in the space for the copied structures. */
+ /*-----------------------------------------------------------------*/
+ bytes += structCopySize;
+
+ cif->flags = flags;
+ cif->bytes = bytes;
+
+ return FFI_OK;
+}
+
+/*======================== End of Routine ============================*/
+
+/*====================================================================*/
+/* */
+/* Name - ffi_call. */
+/* */
+/* Function - Call the FFI routine. */
+/* */
+/*====================================================================*/
+
+void
+ffi_call(ffi_cif *cif,
+ void (*fn)(),
+ void *rvalue,
+ void **avalue)
+{
+ extended_cif ecif;
+
+ ecif.cif = cif;
+ ecif.avalue = avalue;
+
+ /*-----------------------------------------------------------------*/
+ /* If the return value is a struct and we don't have a return */
+ /* value address then we need to make one */
+ /*-----------------------------------------------------------------*/
+ if ((rvalue == NULL) &&
+ (cif->rtype->type == FFI_TYPE_STRUCT))
+ ecif.rvalue = alloca(cif->rtype->size);
+ else
+ ecif.rvalue = rvalue;
+
+ switch (cif->abi)
+ {
+ case FFI_SYSV:
+ ffi_call_SYSV(ffi_prep_args,
+ &ecif, cif->bytes,
+ cif->flags, ecif.rvalue, fn);
+ break;
+
+ default:
+ FFI_ASSERT(0);
+ break;
+ }
+}
+
+/*======================== End of Routine ============================*/
diff --git a/libffi/s390/sysv.S b/libffi/s390/sysv.S
new file mode 100644
index 00000000000..afaf1ea1ca3
--- /dev/null
+++ b/libffi/s390/sysv.S
@@ -0,0 +1,161 @@
+/* -----------------------------------------------------------------------
+ sysv.S - Copyright (c) 2000 Software AG
+
+ S390 Foreign Function Interface
+
+ 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 CYGNUS SOLUTIONS 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.
+ ----------------------------------------------------------------------- */
+
+#define LIBFFI_ASM
+#include <ffi.h>
+#ifdef HAVE_MACHINE_ASM_H
+#include <machine/asm.h>
+#endif
+
+.text
+
+ # r2: ffi_prep_args
+ # r3: &ecif
+ # r4: cif->bytes
+ # r5: fig->flags
+ # r6: ecif.rvalue
+ # sp+0: fn
+
+ # This assumes we are using gas.
+ .globl ffi_call_SYSV
+ .type ffi_call_SYSV,%function
+ffi_call_SYSV:
+ # Save registers
+ stm %r7,%r15,28(%r15)
+ l %r7,96(%r15) # Get A(fn)
+ lr %r0,%r15
+ ahi %r15,-128 # Make room for my args
+ st %r0,0(%r15) # Set backchain
+ lr %r11,%r15 # Establish my stack register
+ sr %r15,%r4 # Make room for fn args
+ ahi %r15,-96 # Make room for new frame
+ lr %r10,%r15 # Establish stack build area
+ ahi %r15,-96 # Stack for next call
+ lr %r1,%r7
+ stm %r2,%r7,96(%r11) # Save args on my stack
+
+#------------------------------------------------------------------
+# move first 3 parameters in registers
+#------------------------------------------------------------------
+ lr %r9,%r2 # r9: &ffi_prep_args
+ lr %r2,%r10 # Parm 1: &stack Parm 2: &ecif
+ basr %r14,%r9 # call ffi_prep_args
+
+#------------------------------------------------------------------
+# load first 5 parameter registers
+#------------------------------------------------------------------
+ lm %r2,%r6,24(%r10)
+
+#------------------------------------------------------------------
+# load fp parameter registers
+#------------------------------------------------------------------
+ ld %f0,48(%r10)
+ ld %f2,56(%r10)
+
+#------------------------------------------------------------------
+# call function
+#------------------------------------------------------------------
+ lr %r15,%r10 # Set new stack
+ l %r9,116(%r11) # Get &fn
+ basr %r14,%r9 # Call function
+
+#------------------------------------------------------------------
+# On return:
+# r2: Return value (r3: Return value + 4 for long long)
+#------------------------------------------------------------------
+
+#------------------------------------------------------------------
+# If the return value pointer is NULL, assume no return value.
+#------------------------------------------------------------------
+ icm %r6,15,112(%r11)
+ jz .Lepilogue
+
+ l %r5,108(%r11) # Get return type
+#------------------------------------------------------------------
+# return INT
+#------------------------------------------------------------------
+ chi %r5,FFI_TYPE_INT
+ jne .Lchk64
+
+ st %r2,0(%r6)
+ j .Lepilogue
+
+.Lchk64:
+#------------------------------------------------------------------
+# return LONG LONG (signed/unsigned)
+#------------------------------------------------------------------
+ chi %r5,FFI_TYPE_UINT64
+ je .LdoLongLong
+
+ chi %r5,FFI_TYPE_SINT64
+ jne .LchkFloat
+
+.LdoLongLong:
+ stm %r2,%r3,0(%r6)
+ j .Lepilogue
+
+.LchkFloat:
+#------------------------------------------------------------------
+# return FLOAT
+#------------------------------------------------------------------
+ chi %r5,FFI_TYPE_FLOAT
+ jne .LchkDouble
+
+ std %f0,0(%r6)
+ j .Lepilogue
+
+.LchkDouble:
+#------------------------------------------------------------------
+# return DOUBLE or LONGDOUBLE
+#------------------------------------------------------------------
+ chi %r5,FFI_TYPE_DOUBLE
+ jne .LchkStruct
+
+ std %f0,0(%r6)
+ std %f2,8(%r6)
+ j .Lepilogue
+
+.LchkStruct:
+#------------------------------------------------------------------
+# Structure - rvalue already set as sent as 1st parm to routine
+#------------------------------------------------------------------
+ chi %r5,FFI_TYPE_STRUCT
+ je .Lepilogue
+
+.Ldefault:
+#------------------------------------------------------------------
+# return a pointer
+#------------------------------------------------------------------
+ st %r2,0(%r6)
+ j .Lepilogue
+
+.Lepilogue:
+ l %r15,0(%r11)
+ l %r4,56(%r15)
+ lm %r7,%r15,28(%r15)
+ br %r4
+
+.ffi_call_SYSV_end:
+ .size ffi_call_SYSV,.ffi_call_SYSV_end-ffi_call_SYSV
diff --git a/libffi/sparc/ffi.c b/libffi/sparc/ffi.c
new file mode 100644
index 00000000000..f7d909b6486
--- /dev/null
+++ b/libffi/sparc/ffi.c
@@ -0,0 +1,422 @@
+/* -----------------------------------------------------------------------
+ ffi.c - Copyright (c) 1996 Cygnus Solutions
+
+ Sparc Foreign Function Interface
+
+ 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 CYGNUS SOLUTIONS 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.
+ ----------------------------------------------------------------------- */
+
+#include <ffi.h>
+#include <ffi_private.h>
+
+#include <stdlib.h>
+
+/* ffi_prep_args is called by the assembly routine once stack space
+ has been allocated for the function's arguments */
+
+void ffi_prep_args_v8(char *stack, extended_cif *ecif)
+{
+ int i;
+ int tmp;
+ int avn;
+ void **p_argv;
+ char *argp;
+ ffi_type **p_arg;
+
+ tmp = 0;
+
+ /* Skip 16 words for the window save area */
+ argp = stack + 16*sizeof(int);
+
+ /* This should only really be done when we are returning a structure,
+ however, it's faster just to do it all the time...
+
+ if ( ecif->cif->rtype->type == FFI_TYPE_STRUCT ) */
+ *(int *) argp = (long)ecif->rvalue;
+
+ /* And 1 word for the structure return value. */
+ argp += sizeof(int);
+
+#ifdef USING_PURIFY
+ /* Purify will probably complain in our assembly routine, unless we
+ zero out this memory. */
+
+ ((int*)argp)[0] = 0;
+ ((int*)argp)[1] = 0;
+ ((int*)argp)[2] = 0;
+ ((int*)argp)[3] = 0;
+ ((int*)argp)[4] = 0;
+ ((int*)argp)[5] = 0;
+#endif
+
+ avn = ecif->cif->nargs;
+ p_argv = ecif->avalue;
+
+ for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types;
+ i && avn;
+ i--, p_arg++)
+ {
+ size_t z;
+
+ if (avn)
+ {
+ avn--;
+ if ((*p_arg)->type == FFI_TYPE_STRUCT
+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+ || (*p_arg)->type == FFI_TYPE_LONGDOUBLE
+#endif
+ )
+ {
+ *(unsigned int *) argp = (unsigned long)(* p_argv);
+ z = sizeof(int);
+ }
+ else
+ {
+ z = (*p_arg)->size;
+ if (z < sizeof(int))
+ {
+ z = sizeof(int);
+ switch ((*p_arg)->type)
+ {
+ case FFI_TYPE_SINT8:
+ *(signed int *) argp = *(SINT8 *)(* p_argv);
+ break;
+
+ case FFI_TYPE_UINT8:
+ *(unsigned int *) argp = *(UINT8 *)(* p_argv);
+ break;
+
+ case FFI_TYPE_SINT16:
+ *(signed int *) argp = *(SINT16 *)(* p_argv);
+ break;
+
+ case FFI_TYPE_UINT16:
+ *(unsigned int *) argp = *(UINT16 *)(* p_argv);
+ break;
+
+ default:
+ FFI_ASSERT(0);
+ }
+ }
+ else
+ {
+ memcpy(argp, *p_argv, z);
+ }
+ }
+ p_argv++;
+ argp += z;
+ }
+ }
+
+ return;
+}
+
+int ffi_prep_args_v9(char *stack, extended_cif *ecif)
+{
+ int i, ret = 0;
+ int tmp;
+ void **p_argv;
+ char *argp;
+ ffi_type **p_arg;
+
+ tmp = 0;
+
+ /* Skip 16 words for the window save area */
+ argp = stack + 16*sizeof(long long);
+
+#ifdef USING_PURIFY
+ /* Purify will probably complain in our assembly routine, unless we
+ zero out this memory. */
+
+ ((long long*)argp)[0] = 0;
+ ((long long*)argp)[1] = 0;
+ ((long long*)argp)[2] = 0;
+ ((long long*)argp)[3] = 0;
+ ((long long*)argp)[4] = 0;
+ ((long long*)argp)[5] = 0;
+#endif
+
+ p_argv = ecif->avalue;
+
+ if (ecif->cif->rtype->type == FFI_TYPE_STRUCT &&
+ ecif->cif->rtype->size > 32)
+ {
+ *(unsigned long long *) argp = (unsigned long)ecif->rvalue;
+ tmp = 1;
+ }
+
+ for (i = 0, p_arg = ecif->cif->arg_types; i < ecif->cif->nargs;
+ i++, p_arg++)
+ {
+ size_t z;
+
+ z = (*p_arg)->size;
+ switch ((*p_arg)->type)
+ {
+ case FFI_TYPE_STRUCT:
+ if (z > 16)
+ {
+ /* For structures larger than 16 bytes we pass reference. */
+ *(unsigned long long *) argp = (unsigned long)* p_argv;
+ argp += sizeof(long long);
+ tmp++;
+ p_argv++;
+ continue;
+ }
+ /* FALLTHROUGH */
+ case FFI_TYPE_FLOAT:
+ case FFI_TYPE_DOUBLE:
+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+ case FFI_TYPE_LONGDOUBLE:
+#endif
+ ret = 1; /* We should promote into FP regs as well as integer. */
+ break;
+ }
+ if (z < sizeof(long long))
+ {
+ switch ((*p_arg)->type)
+ {
+ case FFI_TYPE_SINT8:
+ *(signed long long *) argp = *(SINT8 *)(* p_argv);
+ break;
+
+ case FFI_TYPE_UINT8:
+ *(unsigned long long *) argp = *(UINT8 *)(* p_argv);
+ break;
+
+ case FFI_TYPE_SINT16:
+ *(signed long long *) argp = *(SINT16 *)(* p_argv);
+ break;
+
+ case FFI_TYPE_UINT16:
+ *(unsigned long long *) argp = *(UINT16 *)(* p_argv);
+ break;
+
+ case FFI_TYPE_SINT32:
+ *(signed long long *) argp = *(SINT32 *)(* p_argv);
+ break;
+
+ case FFI_TYPE_UINT32:
+ *(unsigned long long *) argp = *(UINT32 *)(* p_argv);
+ break;
+
+ case FFI_TYPE_FLOAT:
+ *(float *) (argp + 4) = *(FLOAT32 *)(* p_argv); /* Right justify */
+ break;
+
+ case FFI_TYPE_STRUCT:
+ memcpy(argp, *p_argv, z);
+ break;
+
+ default:
+ FFI_ASSERT(0);
+ }
+ z = sizeof(long long);
+ tmp++;
+ }
+ else if (z == sizeof(long long))
+ {
+ memcpy(argp, *p_argv, z);
+ z = sizeof(long long);
+ tmp++;
+ }
+ else
+ {
+ if ((tmp & 1) && (*p_arg)->alignment > 8)
+ {
+ tmp++;
+ argp += sizeof(long long);
+ }
+ memcpy(argp, *p_argv, z);
+ z = 2 * sizeof(long long);
+ tmp += 2;
+ }
+ p_argv++;
+ argp += z;
+ }
+
+ return ret;
+}
+
+/* Perform machine dependent cif processing */
+ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
+{
+ int wordsize;
+
+ if (cif->abi != FFI_V9)
+ {
+ wordsize = 4;
+
+ /* If we are returning a struct, this will already have been added.
+ Otherwise we need to add it because it's always got to be there! */
+
+ if (cif->rtype->type != FFI_TYPE_STRUCT)
+ cif->bytes += wordsize;
+
+ /* sparc call frames require that space is allocated for 6 args,
+ even if they aren't used. Make that space if necessary. */
+
+ if (cif->bytes < 4*6+4)
+ cif->bytes = 4*6+4;
+ }
+ else
+ {
+ wordsize = 8;
+
+ /* sparc call frames require that space is allocated for 6 args,
+ even if they aren't used. Make that space if necessary. */
+
+ if (cif->bytes < 8*6)
+ cif->bytes = 8*6;
+ }
+
+ /* Adjust cif->bytes. to include 16 words for the window save area,
+ and maybe the struct/union return pointer area, */
+
+ cif->bytes += 16 * wordsize;
+
+ /* The stack must be 2 word aligned, so round bytes up
+ appropriately. */
+
+ cif->bytes = ALIGN(cif->bytes, 2 * wordsize);
+
+ /* Set the return type flag */
+ switch (cif->rtype->type)
+ {
+ case FFI_TYPE_VOID:
+ case FFI_TYPE_FLOAT:
+ case FFI_TYPE_DOUBLE:
+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+ case FFI_TYPE_LONGDOUBLE:
+#endif
+ cif->flags = cif->rtype->type;
+ break;
+
+ case FFI_TYPE_STRUCT:
+ if (cif->abi == FFI_V9 && cif->rtype->size > 32)
+ cif->flags = FFI_TYPE_VOID;
+ else
+ cif->flags = FFI_TYPE_STRUCT;
+ break;
+
+ case FFI_TYPE_SINT64:
+ case FFI_TYPE_UINT64:
+ if (cif->abi != FFI_V9)
+ {
+ cif->flags = FFI_TYPE_SINT64;
+ break;
+ }
+ /* FALLTHROUGH */
+ default:
+ cif->flags = FFI_TYPE_INT;
+ break;
+ }
+ return FFI_OK;
+}
+
+int ffi_V9_return_struct(ffi_type *arg, int off, char *ret, char *intg, char *flt)
+{
+ ffi_type **ptr = &arg->elements[0];
+
+ while (*ptr != NULL)
+ {
+ if (off & ((*ptr)->alignment - 1))
+ off = ALIGN(off, (*ptr)->alignment);
+
+ switch ((*ptr)->type)
+ {
+ case FFI_TYPE_STRUCT:
+ off = ffi_V9_return_struct(*ptr, off, ret, intg, flt);
+ break;
+ case FFI_TYPE_FLOAT:
+ case FFI_TYPE_DOUBLE:
+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+ case FFI_TYPE_LONGDOUBLE:
+#endif
+ memcpy(ret + off, flt + off, (*ptr)->size);
+ off += (*ptr)->size;
+ break;
+ default:
+ memcpy(ret + off, intg + off, (*ptr)->size);
+ off += (*ptr)->size;
+ break;
+ }
+ ptr++;
+ }
+ return off;
+}
+
+extern int ffi_call_V8(void *, extended_cif *, unsigned,
+ unsigned, unsigned *, void (*fn)());
+extern int ffi_call_V9(void *, extended_cif *, unsigned,
+ unsigned, unsigned *, void (*fn)());
+
+void ffi_call(ffi_cif *cif, void (*fn)(), void *rvalue, void **avalue)
+{
+ extended_cif ecif;
+ void *rval = rvalue;
+
+ ecif.cif = cif;
+ ecif.avalue = avalue;
+
+ /* If the return value is a struct and we don't have a return */
+ /* value address then we need to make one */
+
+ ecif.rvalue = rvalue;
+ if (cif->rtype->type == FFI_TYPE_STRUCT)
+ {
+ if (cif->rtype->size <= 32)
+ rval = alloca(64);
+ else
+ {
+ rval = NULL;
+ if (rvalue == NULL)
+ ecif.rvalue = alloca(cif->rtype->size);
+ }
+ }
+
+ switch (cif->abi)
+ {
+ case FFI_V8:
+#ifdef SPARC64
+ /* We don't yet support calling 32bit code from 64bit */
+ FFI_ASSERT(0);
+#else
+ ffi_call_V8(ffi_prep_args_v8, &ecif, cif->bytes,
+ cif->flags, rvalue, fn);
+#endif
+ break;
+ case FFI_V9:
+#ifdef SPARC64
+ ffi_call_V9(ffi_prep_args_v9, &ecif, cif->bytes,
+ cif->flags, rval, fn);
+ if (rvalue && rval && cif->rtype->type == FFI_TYPE_STRUCT)
+ ffi_V9_return_struct(cif->rtype, 0, (char *)rvalue, (char *)rval, ((char *)rval)+32);
+#else
+ /* And vice versa */
+ FFI_ASSERT(0);
+#endif
+ break;
+ default:
+ FFI_ASSERT(0);
+ break;
+ }
+
+}
diff --git a/libffi/sparc/v8.S b/libffi/sparc/v8.S
new file mode 100644
index 00000000000..3f29dce90d0
--- /dev/null
+++ b/libffi/sparc/v8.S
@@ -0,0 +1,94 @@
+/* -----------------------------------------------------------------------
+ v8.S - Copyright (c) 1996, 1997 Cygnus Solutions
+
+ Sparc Foreign Function Interface
+
+ 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 CYGNUS SOLUTIONS 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.
+ ----------------------------------------------------------------------- */
+
+#define LIBFFI_ASM
+#include <ffi.h>
+#include <ffi_private.h>
+
+#define STACKFRAME 96 /* Minimum stack framesize for SPARC */
+#define ARGS (64+4) /* Offset of register area in frame */
+
+.text
+ .align 8
+.globl ffi_call_V8
+.globl _ffi_call_V8
+
+ffi_call_V8:
+_ffi_call_V8:
+ save %sp, -STACKFRAME, %sp
+
+ sub %sp, %i2, %sp ! alloca() space in stack for frame to set up
+ add %sp, STACKFRAME, %l0 ! %l0 has start of
+ ! frame to set up
+
+ mov %l0, %o0 ! call routine to set up frame
+ call %i0
+ mov %i1, %o1 ! (delay)
+
+ ld [%l0+ARGS], %o0 ! call foreign function
+ ld [%l0+ARGS+4], %o1
+ ld [%l0+ARGS+8], %o2
+ ld [%l0+ARGS+12], %o3
+ ld [%l0+ARGS+16], %o4
+ ld [%l0+ARGS+20], %o5
+ call %i5
+ mov %l0, %sp ! (delay) switch to frame
+ nop ! STRUCT returning functions skip 12 instead of 8 bytes
+
+ ! If the return value pointer is NULL, assume no return value.
+ tst %i4
+ bz done
+ nop
+
+ cmp %i3, FFI_TYPE_INT
+ be,a done
+ st %o0, [%i4] ! (delay)
+
+ cmp %i3, FFI_TYPE_FLOAT
+ be,a done
+ st %f0, [%i4+0] ! (delay)
+
+ cmp %i3, FFI_TYPE_SINT64
+ be longlong
+
+ cmp %i3, FFI_TYPE_DOUBLE
+ bne done
+ nop
+ st %f0, [%i4+0]
+ st %f1, [%i4+4]
+
+done:
+ ret
+ restore
+
+longlong:
+ st %o0, [%i4+0]
+ st %o1, [%i4+4]
+ ret
+ restore
+
+.ffi_call_V8_end:
+ .size ffi_call_V8,.ffi_call_V8_end-ffi_call_V8
+
diff --git a/libffi/sparc/v9.S b/libffi/sparc/v9.S
new file mode 100644
index 00000000000..f7e44c15838
--- /dev/null
+++ b/libffi/sparc/v9.S
@@ -0,0 +1,126 @@
+/* -----------------------------------------------------------------------
+ v9.S - Copyright (c) 2000 Cygnus Solutions
+
+ Sparc 64bit Foreign Function Interface
+
+ 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 CYGNUS SOLUTIONS 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.
+ ----------------------------------------------------------------------- */
+
+#define LIBFFI_ASM
+#include <ffi.h>
+#include <ffi_private.h>
+
+#if defined(__arch64__) || defined(__sparcv9)
+/* Only compile this in for 64bit builds, because otherwise the object file
+ will have inproper architecture due to used instructions. */
+
+#define STACKFRAME 128 /* Minimum stack framesize for SPARC */
+#define STACK_BIAS 2047
+#define ARGS (128) /* Offset of register area in frame */
+
+.text
+ .align 8
+.globl ffi_call_V9
+.globl _ffi_call_V9
+
+ffi_call_V9:
+_ffi_call_V9:
+ save %sp, -STACKFRAME, %sp
+
+ sub %sp, %i2, %sp ! alloca() space in stack for frame to set up
+ add %sp, STACKFRAME+STACK_BIAS, %l0 ! %l0 has start of
+ ! frame to set up
+
+ mov %l0, %o0 ! call routine to set up frame
+ call %i0
+ mov %i1, %o1 ! (delay)
+ brz,pt %o0, 1f
+ ldx [%l0+ARGS], %o0 ! call foreign function
+
+ ldd [%l0+ARGS], %f0
+ ldd [%l0+ARGS+8], %f2
+ ldd [%l0+ARGS+16], %f4
+ ldd [%l0+ARGS+24], %f6
+ ldd [%l0+ARGS+32], %f8
+ ldd [%l0+ARGS+40], %f10
+ ldd [%l0+ARGS+48], %f12
+ ldd [%l0+ARGS+56], %f14
+ ldd [%l0+ARGS+64], %f16
+ ldd [%l0+ARGS+72], %f18
+ ldd [%l0+ARGS+80], %f20
+ ldd [%l0+ARGS+88], %f22
+ ldd [%l0+ARGS+96], %f24
+ ldd [%l0+ARGS+104], %f26
+ ldd [%l0+ARGS+112], %f28
+ ldd [%l0+ARGS+120], %f30
+
+1: ldx [%l0+ARGS+8], %o1
+ ldx [%l0+ARGS+16], %o2
+ ldx [%l0+ARGS+24], %o3
+ ldx [%l0+ARGS+32], %o4
+ ldx [%l0+ARGS+40], %o5
+ call %i5
+ sub %l0, STACK_BIAS, %sp ! (delay) switch to frame
+
+ ! If the return value pointer is NULL, assume no return value.
+ brz,pn %i4, done
+ nop
+
+ cmp %i3, FFI_TYPE_INT
+ be,a,pt %icc, done
+ stx %o0, [%i4] ! (delay)
+
+ cmp %i3, FFI_TYPE_FLOAT
+ be,a,pn %icc, done
+ st %f0, [%i4+0] ! (delay)
+
+ cmp %i3, FFI_TYPE_DOUBLE
+ be,a,pn %icc, done
+ std %f0, [%i4+0] ! (delay)
+
+ cmp %i3, FFI_TYPE_STRUCT
+ be,pn %icc, dostruct
+
+ cmp %i3, FFI_TYPE_LONGDOUBLE
+ bne,pt %icc, done
+ nop
+ std %f0, [%i4+0]
+ std %f2, [%i4+8]
+
+done: ret
+ restore
+
+dostruct:
+ /* This will not work correctly for unions. */
+ stx %o0, [%i4+0]
+ stx %o1, [%i4+8]
+ stx %o2, [%i4+16]
+ stx %o3, [%i4+24]
+ std %f0, [%i4+32]
+ std %f2, [%i4+40]
+ std %f4, [%i4+48]
+ std %f6, [%i4+56]
+ ret
+ restore
+
+.ffi_call_V9_end:
+ .size ffi_call_V9,.ffi_call_V9_end-ffi_call_V9
+
+#endif
diff --git a/libffi/testsuite/.cvsignore b/libffi/testsuite/.cvsignore
new file mode 100644
index 00000000000..282522db034
--- /dev/null
+++ b/libffi/testsuite/.cvsignore
@@ -0,0 +1,2 @@
+Makefile
+Makefile.in
diff --git a/libffi/testsuite/Makefile.am b/libffi/testsuite/Makefile.am
new file mode 100644
index 00000000000..67bce5c3939
--- /dev/null
+++ b/libffi/testsuite/Makefile.am
@@ -0,0 +1,15 @@
+## Process this file with automake to produce Makefile.in.
+
+AUTOMAKE_OPTIONS = foreign dejagnu
+
+# Setup the testing framework, if you have one
+EXPECT = `if [ -f $(top_builddir)/../expect/expect ] ; then \
+ echo $(top_builddir)/../expect/expect ; \
+ else echo expect ; fi`
+
+RUNTEST = `if [ -f $(top_srcdir)/../dejagnu/runtest ] ; then \
+ echo $(top_srcdir)/../dejagnu/runtest ; \
+ else echo runtest; fi`
+
+RUNTESTFLAGS = @AM_RUNTESTFLAGS@
+
diff --git a/libffi/testsuite/config/default.exp b/libffi/testsuite/config/default.exp
new file mode 100644
index 00000000000..90967cccc18
--- /dev/null
+++ b/libffi/testsuite/config/default.exp
@@ -0,0 +1 @@
+load_lib "standard.exp"
diff --git a/libffi/testsuite/lib/libffi.exp b/libffi/testsuite/lib/libffi.exp
new file mode 100644
index 00000000000..00c28d3cd90
--- /dev/null
+++ b/libffi/testsuite/lib/libffi.exp
@@ -0,0 +1,44 @@
+# Copyright (C) 2001 Red Hat, Inc.
+
+load_lib "libgloss.exp"
+
+global tmpdir
+
+if ![info exists tmpdir] {
+ set tmpdir "/tmp"
+}
+
+proc test_libffi {src} {
+
+ global tmpdir srcdir
+
+ set executable $tmpdir/[file tail [file rootname $src].x]
+
+ regsub "^$srcdir/?" $src "" testcase
+ # If we couldn't rip $srcdir out of `src' then just do the best we can.
+ # The point is to reduce the unnecessary noise in the logs. Don't strip
+ # out too much because different testcases with the same name can confuse
+ # `test-tool'.
+ if [string match "/*" $testcase] {
+ set testcase "[file tail [file dirname $src]]/[file tail $src]"
+ }
+
+ remote_file build delete $executable;
+ verbose "Testing $testcase" 1
+
+ set comp_output [target_compile $src $executable executable "additional_flags=-g additional_flags=-I$srcdir/../include libs=../.libs/libffi.a"]
+
+ set result [libffi_load "$executable" "" ""]
+ set status [lindex $result 0];
+ set output [lindex $result 1];
+
+ $status "$testcase"
+
+# if { $status == "pass" } {
+# remote_file build delete $executable;
+# }
+}
+
+# Local Variables:
+# tcl-indent-level:4
+# End:
diff --git a/libffi/testsuite/libffi.call/call.exp b/libffi/testsuite/libffi.call/call.exp
new file mode 100644
index 00000000000..58be0ade24a
--- /dev/null
+++ b/libffi/testsuite/libffi.call/call.exp
@@ -0,0 +1,13 @@
+global srcdir subdir
+
+catch "glob -nocomplain ${srcdir}/${subdir}/*.c" srcfiles
+verbose "srcfiles are $srcfiles"
+
+set prefix ""
+foreach x $srcfiles {
+ test_libffi $x
+}
+
+# Local Variables:
+# tcl-indent-level:4
+# End:
diff --git a/libffi/testsuite/libffi.call/ffitest.h b/libffi/testsuite/libffi.call/ffitest.h
new file mode 100644
index 00000000000..42cb46f2124
--- /dev/null
+++ b/libffi/testsuite/libffi.call/ffitest.h
@@ -0,0 +1,4 @@
+#include <ffi.h>
+
+#define CHECK(x) !(x) ? abort() : 0
+
diff --git a/libffi/testsuite/libffi.call/float.c b/libffi/testsuite/libffi.call/float.c
new file mode 100644
index 00000000000..95e7a31ecd3
--- /dev/null
+++ b/libffi/testsuite/libffi.call/float.c
@@ -0,0 +1,55 @@
+#include "ffitest.h"
+
+static int floating(int a, float b, double c, long double d, int e)
+{
+ int i;
+
+ i = (int) ((float)a/b + ((float)c/(float)d));
+
+ return i;
+}
+
+int
+main ()
+{
+ ffi_cif cif;
+ ffi_type *args[5];
+ void *values[5];
+ int si1, si2;
+ float f;
+ double d;
+ long double ld;
+ int rint __attribute__((aligned(8)));
+
+ args[0] = &ffi_type_sint;
+ values[0] = &si1;
+ args[1] = &ffi_type_float;
+ values[1] = &f;
+ args[2] = &ffi_type_double;
+ values[2] = &d;
+ args[3] = &ffi_type_longdouble;
+ values[3] = &ld;
+ args[4] = &ffi_type_sint;
+ values[4] = &si2;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 5,
+ &ffi_type_sint, args) == FFI_OK);
+
+ si1 = 6;
+ f = 3.14159;
+ d = (double)1.0/(double)3.0;
+ ld = 2.71828182846L;
+ si2 = 10;
+
+ floating (si1, f, d, ld, si2);
+
+ ffi_call(&cif, FFI_FN(floating), &rint, values);
+
+ printf ("%d vs %d\n", rint, floating (si1, f, d, ld, si2));
+
+ CHECK(rint == floating(si1, f, d, ld, si2));
+
+ exit (0);
+}
+
diff --git a/libffi/testsuite/libffi.call/many.c b/libffi/testsuite/libffi.call/many.c
new file mode 100644
index 00000000000..1b3d72c07ee
--- /dev/null
+++ b/libffi/testsuite/libffi.call/many.c
@@ -0,0 +1,63 @@
+#include "ffitest.h"
+
+#include <float.h>
+
+static float many(float f1,
+ float f2,
+ float f3,
+ float f4,
+ float f5,
+ float f6,
+ float f7,
+ float f8,
+ float f9,
+ float f10,
+ float f11,
+ float f12,
+ float f13)
+{
+#if 1
+ printf("%f %f %f %f %f %f %f %f %f %f %f %f %f\n",
+ (double) f1, (double) f2, (double) f3, (double) f4, (double) f5,
+ (double) f6, (double) f7, (double) f8, (double) f9, (double) f10,
+ (double) f11, (double) f12, (double) f13);
+#endif
+
+ return ((f1/f2+f3/f4+f5/f6+f7/f8+f9/f10+f11/f12) * f13);
+}
+
+int
+main ()
+{
+ ffi_cif cif;
+ ffi_type *args[13];
+ void *values[13];
+ float fa[13];
+ float f, ff;
+ int i;
+
+ for (i = 0; i < 13; i++)
+ {
+ args[i] = &ffi_type_float;
+ values[i] = &fa[i];
+ fa[i] = (float) i;
+ }
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 13,
+ &ffi_type_float, args) == FFI_OK);
+
+ ffi_call(&cif, FFI_FN(many), &f, values);
+
+ ff = many(fa[0], fa[1],
+ fa[2], fa[3],
+ fa[4], fa[5],
+ fa[6], fa[7],
+ fa[8], fa[9],
+ fa[10],fa[11],fa[12]);
+
+ if (f - ff < FLT_EPSILON)
+ exit(0);
+ else
+ abort();
+}
diff --git a/libffi/testsuite/libffi.call/strlen.c b/libffi/testsuite/libffi.call/strlen.c
new file mode 100644
index 00000000000..35172784563
--- /dev/null
+++ b/libffi/testsuite/libffi.call/strlen.c
@@ -0,0 +1,38 @@
+#include "ffitest.h"
+
+static size_t my_strlen(char *s)
+{
+ return (strlen(s));
+}
+
+int
+main ()
+{
+ ffi_cif cif;
+ ffi_type *args[1];
+ void *values[1];
+ int rint __attribute__((aligned(8)));
+ char *s;
+
+ args[0] = &ffi_type_pointer;
+ values[0] = (void*) &s;
+
+ /* Initialize the cif */
+ CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
+ &ffi_type_sint, args) == FFI_OK);
+
+ s = "a";
+ ffi_call(&cif, FFI_FN(my_strlen), &rint, values);
+ CHECK(rint == 1);
+
+ s = "1234567";
+ ffi_call(&cif, FFI_FN(my_strlen), &rint, values);
+ CHECK(rint == 7);
+
+ s = "1234567890123456789012345";
+ ffi_call(&cif, FFI_FN(my_strlen), &rint, values);
+ CHECK(rint == 25);
+
+ exit (0);
+}
+
diff --git a/libffi/types.c b/libffi/types.c
new file mode 100644
index 00000000000..9ab573d95cd
--- /dev/null
+++ b/libffi/types.c
@@ -0,0 +1,153 @@
+/* -----------------------------------------------------------------------
+ types.c - Copyright (c) 1996, 1998 Cygnus Solutions
+
+ Predefined ffi_types needed by libffi.
+
+ 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 RED HAT 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.
+ ----------------------------------------------------------------------- */
+
+#include <ffi.h>
+#include <ffi_private.h>
+
+/* Type definitions */
+
+#define FFI_INTEGRAL_TYPEDEF(n, s, a, t) ffi_type ffi_type_##n = { s, a, t, NULL }
+#define FFI_AGGREGATE_TYPEDEF(n, e) ffi_type ffi_type_##n = { 0, 0, FFI_TYPE_STRUCT, e }
+
+/* Size and alignment are fake here. They must not be 0. */
+FFI_INTEGRAL_TYPEDEF(void, 1, 1, FFI_TYPE_VOID);
+
+FFI_INTEGRAL_TYPEDEF(uint8, 1, 1, FFI_TYPE_UINT8);
+FFI_INTEGRAL_TYPEDEF(sint8, 1, 1, FFI_TYPE_SINT8);
+FFI_INTEGRAL_TYPEDEF(uint16, 2, 2, FFI_TYPE_UINT16);
+FFI_INTEGRAL_TYPEDEF(sint16, 2, 2, FFI_TYPE_SINT16);
+FFI_INTEGRAL_TYPEDEF(uint32, 4, 4, FFI_TYPE_UINT32);
+FFI_INTEGRAL_TYPEDEF(sint32, 4, 4, FFI_TYPE_SINT32);
+FFI_INTEGRAL_TYPEDEF(float, 4, 4, FFI_TYPE_FLOAT);
+
+#if defined __alpha__ || defined SPARC64
+
+FFI_INTEGRAL_TYPEDEF(pointer, 8, 8, FFI_TYPE_POINTER);
+
+#else
+
+FFI_INTEGRAL_TYPEDEF(pointer, 4, 4, FFI_TYPE_POINTER);
+
+#endif
+
+#ifdef __i386__
+
+FFI_INTEGRAL_TYPEDEF(uint64, 8, 4, FFI_TYPE_UINT64);
+FFI_INTEGRAL_TYPEDEF(sint64, 8, 4, FFI_TYPE_SINT64);
+
+#elif defined X86_WIN32
+
+FFI_INTEGRAL_TYPEDEF(uint64, 8, 4, FFI_TYPE_UINT64);
+FFI_INTEGRAL_TYPEDEF(sint64, 8, 4, FFI_TYPE_SINT64);
+
+#elif defined ARM
+
+FFI_INTEGRAL_TYPEDEF(uint64, 8, 4, FFI_TYPE_UINT64);
+FFI_INTEGRAL_TYPEDEF(sint64, 8, 4, FFI_TYPE_SINT64);
+
+#elif defined M68K
+
+FFI_INTEGRAL_TYPEDEF(uint64, 8, 4, FFI_TYPE_UINT64);
+FFI_INTEGRAL_TYPEDEF(sint64, 8, 4, FFI_TYPE_SINT64);
+
+#else
+
+FFI_INTEGRAL_TYPEDEF(uint64, 8, 8, FFI_TYPE_UINT64);
+FFI_INTEGRAL_TYPEDEF(sint64, 8, 8, FFI_TYPE_SINT64);
+
+#endif
+
+
+#ifdef __i386__
+
+FFI_INTEGRAL_TYPEDEF(double, 8, 4, FFI_TYPE_DOUBLE);
+FFI_INTEGRAL_TYPEDEF(longdouble, 12, 4, FFI_TYPE_LONGDOUBLE);
+
+#elif defined X86_WIN32
+
+FFI_INTEGRAL_TYPEDEF(double, 8, 4, FFI_TYPE_DOUBLE);
+FFI_INTEGRAL_TYPEDEF(longdouble, 12, 4, FFI_TYPE_LONGDOUBLE);
+
+#elif defined ARM
+
+FFI_INTEGRAL_TYPEDEF(double, 8, 4, FFI_TYPE_DOUBLE);
+FFI_INTEGRAL_TYPEDEF(longdouble, 8, 4, FFI_TYPE_LONGDOUBLE);
+
+#elif defined M68K
+
+FFI_INTEGRAL_TYPEDEF(double, 8, 4, FFI_TYPE_DOUBLE);
+FFI_INTEGRAL_TYPEDEF(longdouble, 12, 4, FFI_TYPE_LONGDOUBLE);
+
+#elif defined SPARC
+
+FFI_INTEGRAL_TYPEDEF(double, 8, 8, FFI_TYPE_DOUBLE);
+
+#ifdef SPARC64
+
+FFI_INTEGRAL_TYPEDEF(longdouble, 16, 16, FFI_TYPE_LONGDOUBLE);
+
+#else
+
+FFI_INTEGRAL_TYPEDEF(longdouble, 16, 8, FFI_TYPE_LONGDOUBLE);
+
+#endif
+
+#else
+
+FFI_INTEGRAL_TYPEDEF(double, 8, 8, FFI_TYPE_DOUBLE);
+FFI_INTEGRAL_TYPEDEF(longdouble, 8, 8, FFI_TYPE_LONGDOUBLE);
+
+#endif
+
+#if SIZEOF_SHORT==1
+extern ffi_type ffi_type_sshort __attribute__((alias("ffi_type_sint8")));
+extern ffi_type ffi_type_ushort __attribute__((alias("ffi_type_uint8")));
+#elif SIZEOF_SHORT==2
+extern ffi_type ffi_type_sshort __attribute__((alias("ffi_type_sint16")));
+extern ffi_type ffi_type_ushort __attribute__((alias("ffi_type_uint16")));
+#elif SIZEOF_SHORT==4
+extern ffi_type ffi_type_sshort __attribute__((alias("ffi_type_sint32")));
+extern ffi_type ffi_type_ushort __attribute__((alias("ffi_type_uint32")));
+#endif
+
+#if SIZEOF_INT==2
+extern ffi_type ffi_type_sint __attribute__((alias("ffi_type_sint16")));
+extern ffi_type ffi_type_uint __attribute__((alias("ffi_type_uint16")));
+#elif SIZEOF_INT==4
+extern ffi_type ffi_type_sint __attribute__((alias("ffi_type_sint32")));
+extern ffi_type ffi_type_uint __attribute__((alias("ffi_type_uint32")));
+#elif SIZEOF_INT==8
+extern ffi_type ffi_type_sint __attribute__((alias("ffi_type_sint64")));
+extern ffi_type ffi_type_uint __attribute__((alias("ffi_type_uint64")));
+#endif
+
+#if SIZEOF_LONG==4
+extern ffi_type ffi_type_slong __attribute__((alias("ffi_type_sint32")));
+extern ffi_type ffi_type_ulong __attribute__((alias("ffi_type_uint32")));
+#elif SIZEOF_INT==8
+extern ffi_type ffi_type_slong __attribute__((alias("ffi_type_sint64")));
+extern ffi_type ffi_type_ulong __attribute__((alias("ffi_type_uint64")));
+#endif
+
diff --git a/libffi/x86/ffi.c b/libffi/x86/ffi.c
new file mode 100644
index 00000000000..74fbcda9269
--- /dev/null
+++ b/libffi/x86/ffi.c
@@ -0,0 +1,508 @@
+/* -----------------------------------------------------------------------
+ ffi.c - Copyright (c) 1996, 1998, 1999 Cygnus Solutions
+
+ x86 Foreign Function Interface
+
+ 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 CYGNUS SOLUTIONS 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.
+ ----------------------------------------------------------------------- */
+
+#include <ffi.h>
+#include <ffi_private.h>
+
+#include <stdlib.h>
+
+/* ffi_prep_args is called by the assembly routine once stack space
+ has been allocated for the function's arguments */
+
+/*@-exportheader@*/
+void ffi_prep_args(char *stack, extended_cif *ecif)
+/*@=exportheader@*/
+{
+ register unsigned int i;
+ register int tmp;
+ register unsigned int avn;
+ register void **p_argv;
+ register char *argp;
+ register ffi_type **p_arg;
+
+ tmp = 0;
+ argp = stack;
+
+ if ( ecif->cif->rtype->type == FFI_TYPE_STRUCT ) {
+ *(void **) argp = ecif->rvalue;
+ argp += 4;
+ }
+
+ avn = ecif->cif->nargs;
+ p_argv = ecif->avalue;
+
+ for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types;
+ (i != 0) && (avn != 0);
+ i--, p_arg++)
+ {
+ size_t z;
+
+ /* Align if necessary */
+ if (((*p_arg)->alignment - 1) & (unsigned) argp) {
+ argp = (char *) ALIGN(argp, (*p_arg)->alignment);
+ }
+
+ if (avn != 0)
+ {
+ avn--;
+ z = (*p_arg)->size;
+ if (z < sizeof(int))
+ {
+ z = sizeof(int);
+ switch ((*p_arg)->type)
+ {
+ case FFI_TYPE_SINT8:
+ *(signed int *) argp = (signed int)*(SINT8 *)(* p_argv);
+ break;
+
+ case FFI_TYPE_UINT8:
+ *(unsigned int *) argp = (unsigned int)*(UINT8 *)(* p_argv);
+ break;
+
+ case FFI_TYPE_SINT16:
+ *(signed int *) argp = (signed int)*(SINT16 *)(* p_argv);
+ break;
+
+ case FFI_TYPE_UINT16:
+ *(unsigned int *) argp = (unsigned int)*(UINT16 *)(* p_argv);
+ break;
+
+ case FFI_TYPE_SINT32:
+ *(signed int *) argp = (signed int)*(SINT32 *)(* p_argv);
+ break;
+
+ case FFI_TYPE_UINT32:
+ *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv);
+ break;
+
+ case FFI_TYPE_STRUCT:
+ *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv);
+ break;
+
+ default:
+ FFI_ASSERT(0);
+ }
+ }
+ else
+ {
+ memcpy(argp, *p_argv, z);
+ }
+ p_argv++;
+ argp += z;
+ }
+ }
+
+ return;
+}
+
+/* Perform machine dependent cif processing */
+ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
+{
+ /* Set the return type flag */
+ switch (cif->rtype->type)
+ {
+ case FFI_TYPE_VOID:
+ case FFI_TYPE_STRUCT:
+ case FFI_TYPE_SINT64:
+ case FFI_TYPE_FLOAT:
+ case FFI_TYPE_DOUBLE:
+ case FFI_TYPE_LONGDOUBLE:
+ cif->flags = (unsigned) cif->rtype->type;
+ break;
+
+ case FFI_TYPE_UINT64:
+ cif->flags = FFI_TYPE_SINT64;
+ break;
+
+ default:
+ cif->flags = FFI_TYPE_INT;
+ break;
+ }
+
+ return FFI_OK;
+}
+
+/*@-declundef@*/
+/*@-exportheader@*/
+extern void ffi_call_SYSV(void (*)(char *, extended_cif *),
+ /*@out@*/ extended_cif *,
+ unsigned, unsigned,
+ /*@out@*/ unsigned *,
+ void (*fn)());
+/*@=declundef@*/
+/*@=exportheader@*/
+
+void ffi_call(/*@dependent@*/ ffi_cif *cif,
+ void (*fn)(),
+ /*@out@*/ void *rvalue,
+ /*@dependent@*/ void **avalue)
+{
+ extended_cif ecif;
+
+ ecif.cif = cif;
+ ecif.avalue = avalue;
+
+ /* If the return value is a struct and we don't have a return */
+ /* value address then we need to make one */
+
+ if ((rvalue == NULL) &&
+ (cif->rtype->type == FFI_TYPE_STRUCT))
+ {
+ /*@-sysunrecog@*/
+ ecif.rvalue = alloca(cif->rtype->size);
+ /*@=sysunrecog@*/
+ }
+ else
+ ecif.rvalue = rvalue;
+
+
+ switch (cif->abi)
+ {
+ case FFI_SYSV:
+ /*@-usedef@*/
+ ffi_call_SYSV(ffi_prep_args, &ecif, cif->bytes,
+ cif->flags, ecif.rvalue, fn);
+ /*@=usedef@*/
+ break;
+ default:
+ FFI_ASSERT(0);
+ break;
+ }
+}
+
+
+/** private members **/
+
+static void ffi_prep_incoming_args_SYSV (char *stack, void **ret,
+ void** args, ffi_cif* cif);
+static void ffi_closure_SYSV ();
+static void ffi_closure_raw_SYSV ();
+
+/* This function is jumped to by the trampoline, on entry, %ecx (a
+ * caller-save register) holds the address of the closure.
+ * Clearly, this requires __GNUC__, so perhaps we should translate this
+ * into an assembly file if this is to be distributed with ffi.
+ */
+
+static void
+ffi_closure_SYSV ()
+{
+ // this is our return value storage
+ long double res;
+
+ // our various things...
+ void *args;
+ ffi_cif *cif;
+ void **arg_area;
+ ffi_closure *closure;
+ unsigned short rtype;
+ void *resp = (void*)&res;
+
+ /* grab the trampoline context pointer */
+ asm ("movl %%ecx,%0" : "=r" (closure));
+
+ cif = closure->cif;
+ arg_area = (void**) alloca (cif->nargs * sizeof (void*));
+ asm ("leal 8(%%ebp),%0" : "=q" (args));
+
+ /* this call will initialize ARG_AREA, such that each
+ * element in that array points to the corresponding
+ * value on the stack; and if the function returns
+ * a structure, it will re-set RESP to point to the
+ * structure return address. */
+
+ ffi_prep_incoming_args_SYSV(args, (void**)&resp, arg_area, cif);
+
+ (closure->fun) (cif, resp, arg_area, closure->user_data);
+
+ rtype = cif->flags;
+
+ /* now, do a generic return based on the value of rtype */
+ if (rtype == FFI_TYPE_INT)
+ {
+ asm ("movl (%0),%%eax" : : "r" (resp) : "eax");
+ }
+ else if (rtype == FFI_TYPE_FLOAT)
+ {
+ asm ("flds (%0)" : : "r" (resp) : "st" );
+ }
+ else if (rtype == FFI_TYPE_DOUBLE)
+ {
+ asm ("fldl (%0)" : : "r" (resp) : "st", "st(1)" );
+ }
+ else if (rtype == FFI_TYPE_LONGDOUBLE)
+ {
+ asm ("fldt (%0)" : : "r" (resp) : "st", "st(1)" );
+ }
+ else if (rtype == FFI_TYPE_SINT64)
+ {
+ asm ("movl 0(%0),%%eax;"
+ "movl 4(%0),%%edx"
+ : : "r"(resp)
+ : "eax", "edx");
+ }
+}
+
+/*@-exportheader@*/
+static void
+ffi_prep_incoming_args_SYSV(char *stack, void **rvalue,
+ void **avalue, ffi_cif *cif)
+/*@=exportheader@*/
+{
+ register unsigned int i;
+ register int tmp;
+ register unsigned int avn;
+ register void **p_argv;
+ register char *argp;
+ register ffi_type **p_arg;
+
+ tmp = 0;
+ argp = stack;
+
+ if ( cif->rtype->type == FFI_TYPE_STRUCT ) {
+ *rvalue = *(void **) argp;
+ argp += 4;
+ }
+
+ avn = cif->nargs;
+ p_argv = avalue;
+
+ for (i = cif->nargs, p_arg = cif->arg_types;
+ (i != 0) && (avn != 0);
+ i--, p_arg++)
+ {
+ size_t z;
+
+ /* Align if necessary */
+ if (((*p_arg)->alignment - 1) & (unsigned) argp) {
+ argp = (char *) ALIGN(argp, (*p_arg)->alignment);
+ }
+
+ if (avn != 0)
+ {
+ avn--;
+ z = (*p_arg)->size;
+
+ /* because we're little endian, this is
+ what it turns into. */
+
+ *p_argv = (void*) argp;
+
+ p_argv++;
+ argp += z;
+ }
+ }
+
+ return;
+}
+
+/* How to make a trampoline. Derived from gcc/config/i386/i386.c. */
+
+#define FFI_INIT_TRAMPOLINE(TRAMP,FUN,CTX) \
+({ unsigned char *__tramp = (unsigned char*)(TRAMP); \
+ unsigned int __fun = (unsigned int)(FUN); \
+ unsigned int __ctx = (unsigned int)(CTX); \
+ unsigned int __dis = __fun - ((unsigned int) __tramp + 10); \
+ *(unsigned char*) &__tramp[0] = 0xb9; \
+ *(unsigned int*) &__tramp[1] = __ctx; \
+ *(unsigned char*) &__tramp[5] = 0xe9; \
+ *(unsigned int*) &__tramp[6] = __dis; \
+ })
+
+
+/* the cif must already be prep'ed */
+
+ffi_status
+ffi_prep_closure (ffi_closure* closure,
+ ffi_cif* cif,
+ void (*fun)(ffi_cif*,void*,void**,void*),
+ void *user_data)
+{
+ FFI_ASSERT (cif->abi == FFI_SYSV);
+
+ FFI_INIT_TRAMPOLINE (&closure->tramp[0], \
+ &ffi_closure_SYSV, \
+ (void*)closure);
+
+ closure->cif = cif;
+ closure->user_data = user_data;
+ closure->fun = fun;
+
+ return FFI_OK;
+}
+
+/* ------- Native raw API support -------------------------------- */
+
+#if !FFI_NO_RAW_API
+
+static void
+ffi_closure_raw_SYSV ()
+{
+ // this is our return value storage
+ long double res;
+
+ // our various things...
+ void *args;
+ ffi_raw *raw_args;
+ ffi_cif *cif;
+ ffi_raw_closure *closure;
+ unsigned short rtype;
+ void *resp = (void*)&res;
+
+ /* grab the trampoline context pointer */
+ asm ("movl %%ecx,%0" : "=r" (closure));
+
+ /* take the argument pointer */
+ asm ("leal 8(%%ebp),%0" : "=q" (args));
+
+ /* get the cif */
+ cif = closure->cif;
+
+ /* the SYSV/X86 abi matches the RAW API exactly, well.. almost */
+ raw_args = (ffi_raw*) args;
+
+ (closure->fun) (cif, resp, raw_args, closure->user_data);
+
+ rtype = cif->flags;
+
+ /* now, do a generic return based on the value of rtype */
+ if (rtype == FFI_TYPE_INT)
+ {
+ asm ("movl (%0),%%eax" : : "r" (resp) : "eax");
+ }
+ else if (rtype == FFI_TYPE_FLOAT)
+ {
+ asm ("flds (%0)" : : "r" (resp) : "st" );
+ }
+ else if (rtype == FFI_TYPE_DOUBLE)
+ {
+ asm ("fldl (%0)" : : "r" (resp) : "st", "st(1)" );
+ }
+ else if (rtype == FFI_TYPE_LONGDOUBLE)
+ {
+ asm ("fldt (%0)" : : "r" (resp) : "st", "st(1)" );
+ }
+ else if (rtype == FFI_TYPE_SINT64)
+ {
+ asm ("movl 0(%0),%%eax; movl 4(%0),%%edx"
+ : : "r"(resp)
+ : "eax", "edx");
+ }
+}
+
+
+
+
+ffi_status
+ffi_prep_raw_closure (ffi_raw_closure* closure,
+ ffi_cif* cif,
+ void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
+ void *user_data)
+{
+ int i;
+
+ FFI_ASSERT (cif->abi == FFI_SYSV);
+
+ // we currently don't support certain kinds of arguments for raw
+ // closures. This should be implemented by a seperate assembly language
+ // routine, since it would require argument processing, something we
+ // don't do now for performance.
+
+ for (i = cif->nargs-1; i >= 0; i--)
+ {
+ FFI_ASSERT (cif->arg_types[i]->type != FFI_TYPE_STRUCT);
+ FFI_ASSERT (cif->arg_types[i]->type != FFI_TYPE_LONGDOUBLE);
+ }
+
+
+ FFI_INIT_TRAMPOLINE (&closure->tramp[0], &ffi_closure_raw_SYSV,
+ (void*)closure);
+
+ closure->cif = cif;
+ closure->user_data = user_data;
+ closure->fun = fun;
+
+ return FFI_OK;
+}
+
+static void
+ffi_prep_args_raw(char *stack, extended_cif *ecif)
+{
+ memcpy (stack, ecif->avalue, ecif->cif->bytes);
+}
+
+/* we borrow this routine from libffi (it must be changed, though, to
+ * actually call the function passed in the first argument. as of
+ * libffi-1.20, this is not the case.)
+ */
+
+extern void
+ffi_call_SYSV(void (*)(char *, extended_cif *),
+ /*@out@*/ extended_cif *,
+ unsigned, unsigned,
+ /*@out@*/ unsigned *,
+ void (*fn)());
+
+void
+ffi_raw_call(/*@dependent@*/ ffi_cif *cif,
+ void (*fn)(),
+ /*@out@*/ void *rvalue,
+ /*@dependent@*/ ffi_raw *fake_avalue)
+{
+ extended_cif ecif;
+ void **avalue = (void **)fake_avalue;
+
+ ecif.cif = cif;
+ ecif.avalue = avalue;
+
+ /* If the return value is a struct and we don't have a return */
+ /* value address then we need to make one */
+
+ if ((rvalue == NULL) &&
+ (cif->rtype->type == FFI_TYPE_STRUCT))
+ {
+ /*@-sysunrecog@*/
+ ecif.rvalue = alloca(cif->rtype->size);
+ /*@=sysunrecog@*/
+ }
+ else
+ ecif.rvalue = rvalue;
+
+
+ switch (cif->abi)
+ {
+ case FFI_SYSV:
+ /*@-usedef@*/
+ ffi_call_SYSV(ffi_prep_args_raw, &ecif, cif->bytes,
+ cif->flags, ecif.rvalue, fn);
+ /*@=usedef@*/
+ break;
+ default:
+ FFI_ASSERT(0);
+ break;
+ }
+}
+
+#endif
diff --git a/libffi/x86/sysv.S b/libffi/x86/sysv.S
new file mode 100644
index 00000000000..c7a7812746d
--- /dev/null
+++ b/libffi/x86/sysv.S
@@ -0,0 +1,167 @@
+/* -----------------------------------------------------------------------
+ sysv.S - Copyright (c) 1996, 1998 Cygnus Solutions
+
+ X86 Foreign Function Interface
+
+ 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 CYGNUS SOLUTIONS 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.
+ ----------------------------------------------------------------------- */
+
+#define LIBFFI_ASM
+#include <ffi.h>
+#include <ffi_private.h>
+
+.text
+
+.globl ffi_prep_args
+
+ # This assumes we are using gas.
+ .balign 16
+.globl ffi_call_SYSV
+ .type ffi_call_SYSV,@function
+
+ffi_call_SYSV:
+.LFB1:
+ pushl %ebp
+.LCFI0:
+ movl %esp,%ebp
+.LCFI1:
+ # Make room for all of the new args.
+ movl 16(%ebp),%ecx
+ subl %ecx,%esp
+
+ movl %esp,%eax
+
+ # Place all of the ffi_prep_args in position
+ pushl 12(%ebp)
+ pushl %eax
+ call *8(%ebp)
+
+ # Return stack to previous state and call the function
+ addl $8,%esp
+
+ call *28(%ebp)
+
+ # Remove the space we pushed for the args
+ movl 16(%ebp),%ecx
+ addl %ecx,%esp
+
+ # Load %ecx with the return type code
+ movl 20(%ebp),%ecx
+
+ # If the return value pointer is NULL, assume no return value.
+ cmpl $0,24(%ebp)
+ jne retint
+
+ # Even if there is no space for the return value, we are
+ # obliged to handle floating-point values.
+ cmpl $FFI_TYPE_FLOAT,%ecx
+ jne noretval
+ fstp %st(0)
+
+ jmp epilogue
+
+retint:
+ cmpl $FFI_TYPE_INT,%ecx
+ jne retfloat
+ # Load %ecx with the pointer to storage for the return value
+ movl 24(%ebp),%ecx
+ movl %eax,0(%ecx)
+ jmp epilogue
+
+retfloat:
+ cmpl $FFI_TYPE_FLOAT,%ecx
+ jne retdouble
+ # Load %ecx with the pointer to storage for the return value
+ movl 24(%ebp),%ecx
+ fstps (%ecx)
+ jmp epilogue
+
+retdouble:
+ cmpl $FFI_TYPE_DOUBLE,%ecx
+ jne retlongdouble
+ # Load %ecx with the pointer to storage for the return value
+ movl 24(%ebp),%ecx
+ fstpl (%ecx)
+ jmp epilogue
+
+retlongdouble:
+ cmpl $FFI_TYPE_LONGDOUBLE,%ecx
+ jne retint64
+ # Load %ecx with the pointer to storage for the return value
+ movl 24(%ebp),%ecx
+ fstpt (%ecx)
+ jmp epilogue
+
+retint64:
+ cmpl $FFI_TYPE_SINT64,%ecx
+ jne retstruct
+ # Load %ecx with the pointer to storage for the return value
+ movl 24(%ebp),%ecx
+ movl %eax,0(%ecx)
+ movl %edx,4(%ecx)
+
+retstruct:
+ # Nothing to do!
+
+noretval:
+epilogue:
+ movl %ebp,%esp
+ popl %ebp
+ ret
+.LFE1:
+.ffi_call_SYSV_end:
+ .size ffi_call_SYSV,.ffi_call_SYSV_end-ffi_call_SYSV
+
+.section .eh_frame,"aw",@progbits
+__FRAME_BEGIN__:
+ .4byte .LLCIE1
+.LSCIE1:
+ .4byte 0x0
+ .byte 0x1
+ .byte 0x0
+ .byte 0x1
+ .byte 0x7c
+ .byte 0x8
+ .byte 0xc
+ .byte 0x4
+ .byte 0x4
+ .byte 0x88
+ .byte 0x1
+ .align 4
+.LECIE1:
+ .set .LLCIE1,.LECIE1-.LSCIE1
+ .4byte .LLFDE1
+.LSFDE1:
+ .4byte .LSFDE1-__FRAME_BEGIN__
+ .4byte .LFB1
+ .4byte .LFE1-.LFB1
+ .byte 0x4
+ .4byte .LCFI0-.LFB1
+ .byte 0xe
+ .byte 0x8
+ .byte 0x85
+ .byte 0x2
+ .byte 0x4
+ .4byte .LCFI1-.LCFI0
+ .byte 0xd
+ .byte 0x5
+ .align 4
+.LEFDE1:
+ .set .LLFDE1,.LEFDE1-.LSFDE1
diff --git a/libffi/x86/win32.S b/libffi/x86/win32.S
new file mode 100644
index 00000000000..520d1fc0898
--- /dev/null
+++ b/libffi/x86/win32.S
@@ -0,0 +1,125 @@
+/* -----------------------------------------------------------------------
+ win32.S - Copyright (c) 1996, 1998, 2001 Cygnus Solutions
+
+ X86 Foreign Function Interface
+
+ 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 CYGNUS SOLUTIONS 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.
+ ----------------------------------------------------------------------- */
+
+#define LIBFFI_ASM
+#include <ffi.h>
+
+.text
+
+.globl ffi_prep_args
+
+ # This assumes we are using gas.
+ .balign 16
+.globl _ffi_call_SYSV
+
+_ffi_call_SYSV:
+ pushl %ebp
+ movl %esp,%ebp
+
+ # Make room for all of the new args.
+ movl 16(%ebp),%ecx
+ subl %ecx,%esp
+
+ movl %esp,%eax
+
+ # Place all of the ffi_prep_args in position
+ pushl 12(%ebp)
+ pushl %eax
+ call *8(%ebp)
+
+ # Return stack to previous state and call the function
+ addl $8,%esp
+
+ call *28(%ebp)
+
+ # Remove the space we pushed for the args
+ movl 16(%ebp),%ecx
+ addl %ecx,%esp
+
+ # Load %ecx with the return type code
+ movl 20(%ebp),%ecx
+
+ # If the return value pointer is NULL, assume no return value.
+ cmpl $0,24(%ebp)
+ jne retint
+
+ # Even if there is no space for the return value, we are
+ # obliged to handle floating-point values.
+ cmpl $FFI_TYPE_FLOAT,%ecx
+ jne noretval
+ fstp %st(0)
+
+ jmp epilogue
+
+retint:
+ cmpl $FFI_TYPE_INT,%ecx
+ jne retfloat
+ # Load %ecx with the pointer to storage for the return value
+ movl 24(%ebp),%ecx
+ movl %eax,0(%ecx)
+ jmp epilogue
+
+retfloat:
+ cmpl $FFI_TYPE_FLOAT,%ecx
+ jne retdouble
+ # Load %ecx with the pointer to storage for the return value
+ movl 24(%ebp),%ecx
+ fstps (%ecx)
+ jmp epilogue
+
+retdouble:
+ cmpl $FFI_TYPE_DOUBLE,%ecx
+ jne retlongdouble
+ # Load %ecx with the pointer to storage for the return value
+ movl 24(%ebp),%ecx
+ fstpl (%ecx)
+ jmp epilogue
+
+retlongdouble:
+ cmpl $FFI_TYPE_LONGDOUBLE,%ecx
+ jne retint64
+ # Load %ecx with the pointer to storage for the return value
+ movl 24(%ebp),%ecx
+ fstpt (%ecx)
+ jmp epilogue
+
+retint64:
+ cmpl $FFI_TYPE_SINT64,%ecx
+ jne retstruct
+ # Load %ecx with the pointer to storage for the return value
+ movl 24(%ebp),%ecx
+ movl %eax,0(%ecx)
+ movl %edx,4(%ecx)
+
+retstruct:
+ # Nothing to do!
+
+noretval:
+epilogue:
+ movl %ebp,%esp
+ popl %ebp
+ ret
+
+.ffi_call_SYSV_end:
diff --git a/mcs/AUTHORS b/mcs/AUTHORS
index b3d640ef755..cb016b0b38c 100755
--- a/mcs/AUTHORS
+++ b/mcs/AUTHORS
@@ -1 +1,12 @@
-Miguel de Icaza (miguel@ximian.com) \ No newline at end of file
+C# Compiler:
+ Miguel de Icaza (miguel@ximian.com)
+
+Class Libraries:
+ Jeff Stedfast (fejj@ximian.com)
+ Joe Shaw (joe@ximian.com)
+ Miguel de Icaza (miguel@ximian.com)
+ Sean MacIsaac (macisaac@ximian.com)
+ Vladimir Vukicevic (vladimir@ximian.com)
+ Garrett Rooney (rooneg@electricjellyfish.net)
+ Bob Smith (bob@thestuff.net)
+ John Barnette (jbarn@httcb.net)
diff --git a/mcs/README b/mcs/README
index c4ef996c177..ea389e73fee 100755
--- a/mcs/README
+++ b/mcs/README
@@ -1,2 +1,21 @@
-This is the Ximian MCS C# compiler written in C# \ No newline at end of file
+This contains the Mono C# compiler as well as the Mono runtime
+library.
+
+Layout:
+
+ class/
+ Class libraries
+
+ errors/
+ Sample programs that should generate errors by the compiler.
+
+ jay/
+ Yacc-based parser generator.
+
+ mcs/
+ The Mono C# compiler
+
+ tests/
+ Sample tests
+
diff --git a/mcs/class/README b/mcs/class/README
new file mode 100644
index 00000000000..d64070d314e
--- /dev/null
+++ b/mcs/class/README
@@ -0,0 +1,34 @@
+The class libraries are grouped together in the assemblies they belong.
+
+Each directory here represents an assembly, and inside each directory we
+divide the code based on the namespace they implement.
+
+* Missing implementation bits
+
+ If you implement a class and you are missing implementation bits,
+ please put in the code the word "TODO" and a description of what
+ is missing to be implemented.
+
+* Tagging buggy code
+
+ If there is a bug in your implementation tag the problem by using
+ the word "FIXME" in the code, together with a description of the
+ problem.
+
+ Do not use XXX or obscure descriptions, because otherwise people
+ will not be able to understand what you mean.
+
+* Tagging Lame specs
+
+ Sometimes the specification will be lame (consider Version.ToString (fieldCount)
+ where there is no way of knowing how many fields are available, making the API
+ not only stupid, but leading to unreliable code).
+
+ In those cases, use the keyword "LAMESPEC".
+
+* Coding consideration
+
+ Use 8 space tabs for writing your code (hopefully we can keep
+ this consistent). If you are modifying someone else's code, try
+ to keep the coding style similar.
+
diff --git a/mcs/class/System.Data/makefile b/mcs/class/System.Data/makefile
new file mode 100644
index 00000000000..0309fce6107
--- /dev/null
+++ b/mcs/class/System.Data/makefile
@@ -0,0 +1,4 @@
+all: windows
+
+windows:
+ $(csc) /target:library /out:System.Data.dll /nowarn:1595 /recurse:*.cs
diff --git a/mcs/class/System.Drawing/System.Drawing/ChangeLog b/mcs/class/System.Drawing/System.Drawing/ChangeLog
new file mode 100644
index 00000000000..1244482eaf0
--- /dev/null
+++ b/mcs/class/System.Drawing/System.Drawing/ChangeLog
@@ -0,0 +1,8 @@
+2001-08-17 Mike Kestner <mkestner@speakeasy.net>
+
+ * PointF.cs, Size.cs, SizeF.cs : New struct implementations.
+
+2001-08-16 Mike Kestner <mkestner@speakeasy.net>
+
+ * Point.cs : New. Implementation of System.Drawing.Point struct.
+
diff --git a/mcs/class/System.Drawing/System.Drawing/Point.cs b/mcs/class/System.Drawing/System.Drawing/Point.cs
new file mode 100644
index 00000000000..b5500fab19f
--- /dev/null
+++ b/mcs/class/System.Drawing/System.Drawing/Point.cs
@@ -0,0 +1,339 @@
+//
+// System.Drawing.Point.cs
+//
+// Author:
+// Mike Kestner (mkestner@speakeasy.net)
+//
+// (C) Ximian, Inc. http://www.ximian.com
+//
+
+using System;
+
+namespace System.Drawing {
+
+ public struct Point {
+
+ // Private x and y coordinate fields.
+ int cx, cy;
+
+ // -----------------------
+ // Public Shared Members
+ // -----------------------
+
+ /// <summary>
+ /// Empty Shared Field
+ /// </summary>
+ ///
+ /// <remarks>
+ /// An uninitialized Point Structure.
+ /// </remarks>
+
+ public static readonly Point Empty;
+
+ /// <summary>
+ /// Ceiling Shared Method
+ /// </summary>
+ ///
+ /// <remarks>
+ /// Produces a Point structure from a PointF structure by
+ /// taking the ceiling of the X and Y properties.
+ /// </remarks>
+
+ public static Point Ceiling (PointF value)
+ {
+ int x, y;
+ checked {
+ x = (int) Math.Ceiling (value.X);
+ y = (int) Math.Ceiling (value.Y);
+ }
+
+ return new Point (x, y);
+ }
+
+ /// <summary>
+ /// Round Shared Method
+ /// </summary>
+ ///
+ /// <remarks>
+ /// Produces a Point structure from a PointF structure by
+ /// rounding the X and Y properties.
+ /// </remarks>
+
+ public static Point Round (PointF value)
+ {
+ int x, y;
+ checked {
+ x = (int) Math.Round (value.X);
+ y = (int) Math.Round (value.Y);
+ }
+
+ return new Point (x, y);
+ }
+
+ /// <summary>
+ /// Truncate Shared Method
+ /// </summary>
+ ///
+ /// <remarks>
+ /// Produces a Point structure from a PointF structure by
+ /// truncating the X and Y properties.
+ /// </remarks>
+
+ // LAMESPEC: Should this be floor, or a pure cast to int?
+
+ public static Point Truncate (PointF value)
+ {
+ int x, y;
+ checked {
+ x = (int) value.X;
+ y = (int) value.Y;
+ }
+
+ return new Point (x, y);
+ }
+
+ /// <summary>
+ /// Addition Operator
+ /// </summary>
+ ///
+ /// <remarks>
+ /// Translates a Point using the Width and Height
+ /// properties of the given <typeref>Size</typeref>.
+ /// </remarks>
+
+ public static Point operator + (Point pt, Size sz)
+ {
+ return new Point (pt.X + sz.Width, pt.Y + sz.Height);
+ }
+
+ /// <summary>
+ /// Equality Operator
+ /// </summary>
+ ///
+ /// <remarks>
+ /// Compares two Point objects. The return value is
+ /// based on the equivalence of the X and Y properties
+ /// of the two points.
+ /// </remarks>
+
+ public static bool operator == (Point pt_a, Point pt_b)
+ {
+ return ((pt_a.X == pt_b.X) && (pt_a.Y == pt_b.Y));
+ }
+
+ /// <summary>
+ /// Inequality Operator
+ /// </summary>
+ ///
+ /// <remarks>
+ /// Compares two Point objects. The return value is
+ /// based on the equivalence of the X and Y properties
+ /// of the two points.
+ /// </remarks>
+
+ public static bool operator != (Point pt_a, Point pt_b)
+ {
+ return ((pt_a.X != pt_b.X) || (pt_a.Y != pt_b.Y));
+ }
+
+ /// <summary>
+ /// Subtraction Operator
+ /// </summary>
+ ///
+ /// <remarks>
+ /// Translates a Point using the negation of the Width
+ /// and Height properties of the given Size.
+ /// </remarks>
+
+ public static Point operator - (Point pt, Size sz)
+ {
+ return new Point (pt.X - sz.Width, pt.Y - sz.Height);
+ }
+
+ /// <summary>
+ /// Point to Size Conversion
+ /// </summary>
+ ///
+ /// <remarks>
+ /// Returns a Size based on the Coordinates of a given
+ /// Point. Requires explicit cast.
+ /// </remarks>
+
+ public static explicit operator Size (Point pt)
+ {
+ return new Size (pt.X, pt.Y);
+ }
+
+ /// <summary>
+ /// Point to PointF Conversion
+ /// </summary>
+ ///
+ /// <remarks>
+ /// Creates a PointF based on the coordinates of a given
+ /// Point. No explicit cast is required.
+ /// </remarks>
+
+ public static implicit operator PointF (Point pt)
+ {
+ return new PointF (pt.X, pt.Y);
+ }
+
+
+ // -----------------------
+ // Public Constructors
+ // -----------------------
+
+ /// <summary>
+ /// Point Constructor
+ /// </summary>
+ ///
+ /// <remarks>
+ /// Creates a Point from an integer which holds the X
+ /// coordinate in the high order 16 bits and the Y
+ /// coordinate in the low order 16 bits.
+ /// </remarks>
+
+ public Point (int dw)
+ {
+ cx = dw >> 16;
+ cy = dw & 0xffff;
+ }
+
+ /// <summary>
+ /// Point Constructor
+ /// </summary>
+ ///
+ /// <remarks>
+ /// Creates a Point from a Size value.
+ /// </remarks>
+
+ public Point (Size sz)
+ {
+ cx = sz.Width;
+ cy = sz.Height;
+ }
+
+ /// <summary>
+ /// Point Constructor
+ /// </summary>
+ ///
+ /// <remarks>
+ /// Creates a Point from a specified x,y coordinate pair.
+ /// </remarks>
+
+ public Point (int x, int y)
+ {
+ cx = x;
+ cy = y;
+ }
+
+ // -----------------------
+ // Public Instance Members
+ // -----------------------
+
+ /// <summary>
+ /// IsEmpty Property
+ /// </summary>
+ ///
+ /// <remarks>
+ /// Indicates if both X and Y are zero.
+ /// </remarks>
+
+ public bool IsEmpty {
+ get {
+ return ((cx == 0) && (cy == 0));
+ }
+ }
+
+ /// <summary>
+ /// X Property
+ /// </summary>
+ ///
+ /// <remarks>
+ /// The X coordinate of the Point.
+ /// </remarks>
+
+ public int X {
+ get {
+ return cx;
+ }
+ set {
+ cx = value;
+ }
+ }
+
+ /// <summary>
+ /// Y Property
+ /// </summary>
+ ///
+ /// <remarks>
+ /// The Y coordinate of the Point.
+ /// </remarks>
+
+ public int Y {
+ get {
+ return cy;
+ }
+ set {
+ cy = value;
+ }
+ }
+
+ /// <summary>
+ /// Equals Method
+ /// </summary>
+ ///
+ /// <remarks>
+ /// Checks equivalence of this Point and another object.
+ /// </remarks>
+
+ public override bool Equals (object o)
+ {
+ if (!(o is Point))
+ return false;
+
+ return (this == (Point) o);
+ }
+
+ /// <summary>
+ /// GetHashCode Method
+ /// </summary>
+ ///
+ /// <remarks>
+ /// Calculates a hashing value.
+ /// </remarks>
+
+ public override int GetHashCode ()
+ {
+ return cx^cy;
+ }
+
+ /// <summary>
+ /// Offset Method
+ /// </summary>
+ ///
+ /// <remarks>
+ /// Moves the Point a specified distance.
+ /// </remarks>
+
+ public void Offset (int dx, int dy)
+ {
+ cx += dx;
+ cy += dy;
+ }
+
+ /// <summary>
+ /// ToString Method
+ /// </summary>
+ ///
+ /// <remarks>
+ /// Formats the Point as a string in coordinate notation.
+ /// </remarks>
+
+ public override string ToString ()
+ {
+ return String.Format ("[{0},{1}]", cx, cy);
+ }
+
+ }
+}
diff --git a/mcs/class/System.Drawing/System.Drawing/PointF.cs b/mcs/class/System.Drawing/System.Drawing/PointF.cs
new file mode 100644
index 00000000000..8397aa38048
--- /dev/null
+++ b/mcs/class/System.Drawing/System.Drawing/PointF.cs
@@ -0,0 +1,204 @@
+//
+// System.Drawing.PointF.cs
+//
+// Author:
+// Mike Kestner (mkestner@speakeasy.net)
+//
+// (C) Ximian, Inc. http://www.ximian.com
+//
+
+using System;
+
+namespace System.Drawing {
+
+ public struct PointF {
+
+ // Private x and y coordinate fields.
+ float cx, cy;
+
+ // -----------------------
+ // Public Shared Members
+ // -----------------------
+
+ /// <summary>
+ /// Empty Shared Field
+ /// </summary>
+ ///
+ /// <remarks>
+ /// An uninitialized PointF Structure.
+ /// </remarks>
+
+ public static readonly PointF Empty;
+
+ /// <summary>
+ /// Addition Operator
+ /// </summary>
+ ///
+ /// <remarks>
+ /// Translates a PointF using the Width and Height
+ /// properties of the given Size.
+ /// </remarks>
+
+ public static PointF operator + (PointF pt, Size sz)
+ {
+ return new PointF (pt.X + sz.Width, pt.Y + sz.Height);
+ }
+
+ /// <summary>
+ /// Equality Operator
+ /// </summary>
+ ///
+ /// <remarks>
+ /// Compares two PointF objects. The return value is
+ /// based on the equivalence of the X and Y properties
+ /// of the two points.
+ /// </remarks>
+
+ public static bool operator == (PointF pt_a, PointF pt_b)
+ {
+ return ((pt_a.X == pt_b.X) && (pt_a.Y == pt_b.Y));
+ }
+
+ /// <summary>
+ /// Inequality Operator
+ /// </summary>
+ ///
+ /// <remarks>
+ /// Compares two PointF objects. The return value is
+ /// based on the equivalence of the X and Y properties
+ /// of the two points.
+ /// </remarks>
+
+ public static bool operator != (PointF pt_a, PointF pt_b)
+ {
+ return ((pt_a.X != pt_b.X) || (pt_a.Y != pt_b.Y));
+ }
+
+ /// <summary>
+ /// Subtraction Operator
+ /// </summary>
+ ///
+ /// <remarks>
+ /// Translates a PointF using the negation of the Width
+ /// and Height properties of the given Size.
+ /// </remarks>
+
+ public static PointF operator - (PointF pt, Size sz)
+ {
+ return new PointF (pt.X - sz.Width, pt.Y - sz.Height);
+ }
+
+ // -----------------------
+ // Public Constructor
+ // -----------------------
+
+ /// <summary>
+ /// PointF Constructor
+ /// </summary>
+ ///
+ /// <remarks>
+ /// Creates a PointF from a specified x,y coordinate pair.
+ /// </remarks>
+
+ public PointF (float x, float y)
+ {
+ cx = x;
+ cy = y;
+ }
+
+ // -----------------------
+ // Public Instance Members
+ // -----------------------
+
+ /// <summary>
+ /// IsEmpty Property
+ /// </summary>
+ ///
+ /// <remarks>
+ /// Indicates if both X and Y are zero.
+ /// </remarks>
+
+ public bool IsEmpty {
+ get {
+ return ((cx == 0.0) && (cy == 0.0));
+ }
+ }
+
+ /// <summary>
+ /// X Property
+ /// </summary>
+ ///
+ /// <remarks>
+ /// The X coordinate of the PointF.
+ /// </remarks>
+
+ public float X {
+ get {
+ return cx;
+ }
+ set {
+ cx = value;
+ }
+ }
+
+ /// <summary>
+ /// Y Property
+ /// </summary>
+ ///
+ /// <remarks>
+ /// The Y coordinate of the PointF.
+ /// </remarks>
+
+ public float Y {
+ get {
+ return cy;
+ }
+ set {
+ cy = value;
+ }
+ }
+
+ /// <summary>
+ /// Equals Method
+ /// </summary>
+ ///
+ /// <remarks>
+ /// Checks equivalence of this PointF and another object.
+ /// </remarks>
+
+ public override bool Equals (object o)
+ {
+ if (!(o is PointF))
+ return false;
+
+ return (this == (PointF) o);
+ }
+
+ /// <summary>
+ /// GetHashCode Method
+ /// </summary>
+ ///
+ /// <remarks>
+ /// Calculates a hashing value.
+ /// </remarks>
+
+ public override int GetHashCode ()
+ {
+ return (int) cx ^ (int) cy;
+ }
+
+ /// <summary>
+ /// ToString Method
+ /// </summary>
+ ///
+ /// <remarks>
+ /// Formats the PointF as a string in coordinate notation.
+ /// </remarks>
+
+ public override string ToString ()
+ {
+ return String.Format ("[{0},{1}]", cx, cy);
+ }
+
+ }
+}
diff --git a/mcs/class/System.Drawing/System.Drawing/Size.cs b/mcs/class/System.Drawing/System.Drawing/Size.cs
new file mode 100644
index 00000000000..6d45325895d
--- /dev/null
+++ b/mcs/class/System.Drawing/System.Drawing/Size.cs
@@ -0,0 +1,309 @@
+//
+// System.Drawing.Size.cs
+//
+// Author:
+// Mike Kestner (mkestner@speakeasy.net)
+//
+// (C) Ximian, Inc. http://www.ximian.com
+//
+
+using System;
+
+namespace System.Drawing {
+
+ public struct Size {
+
+ // Private height and width fields.
+ int wd, ht;
+
+ // -----------------------
+ // Public Shared Members
+ // -----------------------
+
+ /// <summary>
+ /// Empty Shared Field
+ /// </summary>
+ ///
+ /// <remarks>
+ /// An uninitialized Size Structure.
+ /// </remarks>
+
+ public static readonly Size Empty;
+
+ /// <summary>
+ /// Ceiling Shared Method
+ /// </summary>
+ ///
+ /// <remarks>
+ /// Produces a Size structure from a SizeF structure by
+ /// taking the ceiling of the Width and Height properties.
+ /// </remarks>
+
+ public static Size Ceiling (SizeF value)
+ {
+ int w, h;
+ checked {
+ w = (int) Math.Ceiling (value.Width);
+ h = (int) Math.Ceiling (value.Height);
+ }
+
+ return new Size (w, h);
+ }
+
+ /// <summary>
+ /// Round Shared Method
+ /// </summary>
+ ///
+ /// <remarks>
+ /// Produces a Size structure from a SizeF structure by
+ /// rounding the Width and Height properties.
+ /// </remarks>
+
+ public static Size Round (SizeF value)
+ {
+ int w, h;
+ checked {
+ w = (int) Math.Round (value.Width);
+ h = (int) Math.Round (value.Height);
+ }
+
+ return new Size (w, h);
+ }
+
+ /// <summary>
+ /// Truncate Shared Method
+ /// </summary>
+ ///
+ /// <remarks>
+ /// Produces a Size structure from a SizeF structure by
+ /// truncating the Width and Height properties.
+ /// </remarks>
+
+ public static Size Truncate (SizeF value)
+ {
+ int w, h;
+ checked {
+ w = (int) value.Width;
+ h = (int) value.Height;
+ }
+
+ return new Size (w, h);
+ }
+
+ /// <summary>
+ /// Addition Operator
+ /// </summary>
+ ///
+ /// <remarks>
+ /// Addition of two Size structures.
+ /// </remarks>
+
+ public static Size operator + (Size sz1, Size sz2)
+ {
+ return new Size (sz1.Width + sz2.Width,
+ sz1.Height + sz2.Height);
+ }
+
+ /// <summary>
+ /// Equality Operator
+ /// </summary>
+ ///
+ /// <remarks>
+ /// Compares two Size objects. The return value is
+ /// based on the equivalence of the Width and Height
+ /// properties of the two Sizes.
+ /// </remarks>
+
+ public static bool operator == (Size sz_a, Size sz_b)
+ {
+ return ((sz_a.Width == sz_b.Width) &&
+ (sz_a.Height == sz_b.Height));
+ }
+
+ /// <summary>
+ /// Inequality Operator
+ /// </summary>
+ ///
+ /// <remarks>
+ /// Compares two Size objects. The return value is
+ /// based on the equivalence of the Width and Height
+ /// properties of the two Sizes.
+ /// </remarks>
+
+ public static bool operator != (Size sz_a, Size sz_b)
+ {
+ return ((sz_a.Width != sz_b.Width) ||
+ (sz_a.Height != sz_b.Height));
+ }
+
+ /// <summary>
+ /// Subtraction Operator
+ /// </summary>
+ ///
+ /// <remarks>
+ /// Subtracts two Size structures.
+ /// </remarks>
+
+ public static Size operator - (Size sz1, Size sz2)
+ {
+ return new Size (sz1.Width - sz2.Width,
+ sz1.Height - sz2.Height);
+ }
+
+ /// <summary>
+ /// Size to Point Conversion
+ /// </summary>
+ ///
+ /// <remarks>
+ /// Returns a Point based on the dimensions of a given
+ /// Size. Requires explicit cast.
+ /// </remarks>
+
+ public static explicit operator Point (Size sz)
+ {
+ return new Point (sz.Width, sz.Height);
+ }
+
+ /// <summary>
+ /// Size to SizeF Conversion
+ /// </summary>
+ ///
+ /// <remarks>
+ /// Creates a SizeF based on the dimensions of a given
+ /// Size. No explicit cast is required.
+ /// </remarks>
+
+ public static implicit operator SizeF (Size sz)
+ {
+ return new SizeF (sz.Width, sz.Height);
+ }
+
+
+ // -----------------------
+ // Public Constructors
+ // -----------------------
+
+ /// <summary>
+ /// Size Constructor
+ /// </summary>
+ ///
+ /// <remarks>
+ /// Creates a Size from a Point value.
+ /// </remarks>
+
+ public Size (Point pt)
+ {
+ wd = pt.X;
+ ht = pt.Y;
+ }
+
+ /// <summary>
+ /// Size Constructor
+ /// </summary>
+ ///
+ /// <remarks>
+ /// Creates a Size from specified dimensions.
+ /// </remarks>
+
+ public Size (int width, int height)
+ {
+ wd = width;
+ ht = height;
+ }
+
+ // -----------------------
+ // Public Instance Members
+ // -----------------------
+
+ /// <summary>
+ /// IsEmpty Property
+ /// </summary>
+ ///
+ /// <remarks>
+ /// Indicates if both Width and Height are zero.
+ /// </remarks>
+
+ public bool IsEmpty {
+ get {
+ return ((wd == 0) && (ht == 0));
+ }
+ }
+
+ /// <summary>
+ /// Width Property
+ /// </summary>
+ ///
+ /// <remarks>
+ /// The Width coordinate of the Size.
+ /// </remarks>
+
+ public int Width {
+ get {
+ return wd;
+ }
+ set {
+ wd = value;
+ }
+ }
+
+ /// <summary>
+ /// Height Property
+ /// </summary>
+ ///
+ /// <remarks>
+ /// The Height coordinate of the Size.
+ /// </remarks>
+
+ public int Height {
+ get {
+ return ht;
+ }
+ set {
+ ht = value;
+ }
+ }
+
+ /// <summary>
+ /// Equals Method
+ /// </summary>
+ ///
+ /// <remarks>
+ /// Checks equivalence of this Size and another object.
+ /// </remarks>
+
+ public override bool Equals (object o)
+ {
+ if (!(o is Size))
+ return false;
+
+ return (this == (Size) o);
+ }
+
+ /// <summary>
+ /// GetHashCode Method
+ /// </summary>
+ ///
+ /// <remarks>
+ /// Calculates a hashing value.
+ /// </remarks>
+
+ public override int GetHashCode ()
+ {
+ return wd^ht;
+ }
+
+ /// <summary>
+ /// ToString Method
+ /// </summary>
+ ///
+ /// <remarks>
+ /// Formats the Size as a string in coordinate notation.
+ /// </remarks>
+
+ public override string ToString ()
+ {
+ return String.Format ("[{0},{1}]", wd, ht);
+ }
+
+ }
+}
diff --git a/mcs/class/System.Drawing/System.Drawing/SizeF.cs b/mcs/class/System.Drawing/System.Drawing/SizeF.cs
new file mode 100644
index 00000000000..9d90c289d0f
--- /dev/null
+++ b/mcs/class/System.Drawing/System.Drawing/SizeF.cs
@@ -0,0 +1,249 @@
+//
+// System.Drawing.SizeF.cs
+//
+// Author:
+// Mike Kestner (mkestner@speakeasy.net)
+//
+// (C) Ximian, Inc. http://www.ximian.com
+//
+
+using System;
+
+namespace System.Drawing {
+
+ public struct SizeF {
+
+ // Private height and width fields.
+ float wd, ht;
+
+ // -----------------------
+ // Public Shared Members
+ // -----------------------
+
+ /// <summary>
+ /// Empty Shared Field
+ /// </summary>
+ ///
+ /// <remarks>
+ /// An uninitialized SizeF Structure.
+ /// </remarks>
+
+ public static readonly SizeF Empty;
+
+ /// <summary>
+ /// Addition Operator
+ /// </summary>
+ ///
+ /// <remarks>
+ /// Addition of two SizeF structures.
+ /// </remarks>
+
+ public static SizeF operator + (SizeF sz1, SizeF sz2)
+ {
+ return new SizeF (sz1.Width + sz2.Width,
+ sz1.Height + sz2.Height);
+ }
+
+ /// <summary>
+ /// Equality Operator
+ /// </summary>
+ ///
+ /// <remarks>
+ /// Compares two SizeF objects. The return value is
+ /// based on the equivalence of the Width and Height
+ /// properties of the two Sizes.
+ /// </remarks>
+
+ public static bool operator == (SizeF sz_a, SizeF sz_b)
+ {
+ return ((sz_a.Width == sz_b.Width) &&
+ (sz_a.Height == sz_b.Height));
+ }
+
+ /// <summary>
+ /// Inequality Operator
+ /// </summary>
+ ///
+ /// <remarks>
+ /// Compares two SizeF objects. The return value is
+ /// based on the equivalence of the Width and Height
+ /// properties of the two Sizes.
+ /// </remarks>
+
+ public static bool operator != (SizeF sz_a, SizeF sz_b)
+ {
+ return ((sz_a.Width != sz_b.Width) ||
+ (sz_a.Height != sz_b.Height));
+ }
+
+ /// <summary>
+ /// Subtraction Operator
+ /// </summary>
+ ///
+ /// <remarks>
+ /// Subtracts two SizeF structures.
+ /// </remarks>
+
+ public static SizeF operator - (SizeF sz1, SizeF sz2)
+ {
+ return new SizeF (sz1.Width - sz2.Width,
+ sz1.Height - sz2.Height);
+ }
+
+ /// <summary>
+ /// SizeF to PointF Conversion
+ /// </summary>
+ ///
+ /// <remarks>
+ /// Returns a PointF based on the dimensions of a given
+ /// SizeF. Requires explicit cast.
+ /// </remarks>
+
+ public static explicit operator PointF (SizeF sz)
+ {
+ return new PointF (sz.Width, sz.Height);
+ }
+
+
+ // -----------------------
+ // Public Constructors
+ // -----------------------
+
+ /// <summary>
+ /// SizeF Constructor
+ /// </summary>
+ ///
+ /// <remarks>
+ /// Creates a SizeF from a PointF value.
+ /// </remarks>
+
+ public SizeF (PointF pt)
+ {
+ wd = pt.X;
+ ht = pt.Y;
+ }
+
+ /// <summary>
+ /// SizeF Constructor
+ /// </summary>
+ ///
+ /// <remarks>
+ /// Creates a SizeF from an existing SizeF value.
+ /// </remarks>
+
+ public SizeF (SizeF sz)
+ {
+ wd = sz.Width;
+ ht = sz.Height;
+ }
+
+ /// <summary>
+ /// SizeF Constructor
+ /// </summary>
+ ///
+ /// <remarks>
+ /// Creates a SizeF from specified dimensions.
+ /// </remarks>
+
+ public SizeF (float width, float height)
+ {
+ wd = width;
+ ht = height;
+ }
+
+ // -----------------------
+ // Public Instance Members
+ // -----------------------
+
+ /// <summary>
+ /// IsEmpty Property
+ /// </summary>
+ ///
+ /// <remarks>
+ /// Indicates if both Width and Height are zero.
+ /// </remarks>
+
+ public bool IsEmpty {
+ get {
+ return ((wd == 0.0) && (ht == 0.0));
+ }
+ }
+
+ /// <summary>
+ /// Width Property
+ /// </summary>
+ ///
+ /// <remarks>
+ /// The Width coordinate of the SizeF.
+ /// </remarks>
+
+ public float Width {
+ get {
+ return wd;
+ }
+ set {
+ wd = value;
+ }
+ }
+
+ /// <summary>
+ /// Height Property
+ /// </summary>
+ ///
+ /// <remarks>
+ /// The Height coordinate of the SizeF.
+ /// </remarks>
+
+ public float Height {
+ get {
+ return ht;
+ }
+ set {
+ ht = value;
+ }
+ }
+
+ /// <summary>
+ /// Equals Method
+ /// </summary>
+ ///
+ /// <remarks>
+ /// Checks equivalence of this SizeF and another object.
+ /// </remarks>
+
+ public override bool Equals (object o)
+ {
+ if (!(o is SizeF))
+ return false;
+
+ return (this == (SizeF) o);
+ }
+
+ /// <summary>
+ /// GetHashCode Method
+ /// </summary>
+ ///
+ /// <remarks>
+ /// Calculates a hashing value.
+ /// </remarks>
+
+ public override int GetHashCode ()
+ {
+ return (int) wd ^ (int) ht;
+ }
+
+ /// <summary>
+ /// ToString Method
+ /// </summary>
+ ///
+ /// <remarks>
+ /// Formats the SizeF as a string in coordinate notation.
+ /// </remarks>
+
+ public override string ToString ()
+ {
+ return String.Format ("[{0},{1}]", wd, ht);
+ }
+
+ }
+}
diff --git a/mcs/class/System.Drawing/makefile b/mcs/class/System.Drawing/makefile
new file mode 100644
index 00000000000..eac0610998b
--- /dev/null
+++ b/mcs/class/System.Drawing/makefile
@@ -0,0 +1,4 @@
+all: windows
+
+windows:
+ $(CSC) /target:library /out:System.Drawing.dll /nowarn:1595 /recurse:*.cs
diff --git a/mcs/class/System.Management/makefile b/mcs/class/System.Management/makefile
new file mode 100644
index 00000000000..c7e57cf750a
--- /dev/null
+++ b/mcs/class/System.Management/makefile
@@ -0,0 +1,4 @@
+all: windows
+
+windows:
+ $(csc) /target:library /out:System.Management.dll /nowarn:1595 /recurse:*.cs
diff --git a/mcs/class/System.Web/ChangeLog b/mcs/class/System.Web/ChangeLog
new file mode 100644
index 00000000000..37154807b13
--- /dev/null
+++ b/mcs/class/System.Web/ChangeLog
@@ -0,0 +1,16 @@
+2001-08-22 Bob Smith <bob@thestuff.net>
+
+ * Added directory: System.Web.UI.HtmlControls
+ * Added directory: Test
+
+2001-08-17 Bob Smith <bob@thestuff.net>
+
+ * Added directory: System.Web.UI
+
+2001-08-09 Bob Smith <bob@thestuff.net>
+
+ * Added directory: System.Web
+
+2001-07-20 Patrik Torstensson (Patrik.Torstensson@labs2.com)
+
+ * Added directory: System.Web.Caching \ No newline at end of file
diff --git a/mcs/class/System.Web/System.Web.Caching/Cache.cs b/mcs/class/System.Web/System.Web.Caching/Cache.cs
new file mode 100644
index 00000000000..5e331aa43c4
--- /dev/null
+++ b/mcs/class/System.Web/System.Web.Caching/Cache.cs
@@ -0,0 +1,520 @@
+//
+// System.Web.Caching
+//
+// Author:
+// Patrik Torstensson (Patrik.Torstensson@labs2.com)
+//
+// (C) Copyright Patrik Torstensson, 2001
+//
+namespace System.Web.Caching
+{
+ /// <summary>
+ /// Implements a cache for Web applications and other. The difference from the MS.NET implementation is that we
+ /// support to use the Cache object as cache in our applications.
+ /// </summary>
+ /// <remarks>
+ /// The Singleton cache is created per application domain, and it remains valid as long as the application domain remains active.
+ /// </remarks>
+ /// <example>
+ /// Usage of the singleton cache:
+ ///
+ /// Cache objManager = Cache.SingletonCache;
+ ///
+ /// String obj = "tobecached";
+ /// objManager.Add("kalle", obj);
+ /// </example>
+ public class Cache : System.Collections.IEnumerable, System.IDisposable
+ {
+ // Declarations
+
+ // MS.NET Does only have the cache connected to the HttpRuntime and we don't have the HttpRuntime (yet)
+ static Cache objSingletonCache = new Cache();
+
+ private bool _boolDisposed;
+
+ // Helper objects
+ private CacheExpires _objExpires;
+
+ // The data storage
+ // Todo: Make a specialized storage for the cache entries?
+ // todo: allow system to replace the storage?
+ private System.Collections.Hashtable _arrEntries;
+ private System.Threading.ReaderWriterLock _lockEntries;
+
+ static private System.TimeSpan _datetimeOneYear = System.TimeSpan.FromDays(365);
+
+ // Number of items in the cache
+ private long _longItems;
+
+ // Constructor
+ public Cache()
+ {
+ _boolDisposed = false;
+ _longItems = 0;
+
+ _lockEntries = new System.Threading.ReaderWriterLock();
+ _arrEntries = new System.Collections.Hashtable();
+
+ _objExpires = new CacheExpires(this);
+ }
+
+ // Public methods and properties
+
+ //
+ /// <summary>
+ /// Returns a static version of the cache. In MS.NET the cache is stored in the System.Web.HttpRuntime
+ /// but we keep it here as a singleton (right now anyway).
+ /// </summary>
+ public static Cache SingletonCache
+ {
+ get
+ {
+ if (objSingletonCache == null)
+ {
+ throw new System.InvalidOperationException();
+ }
+
+ return objSingletonCache;
+ }
+ }
+
+ /// <summary>
+ /// Used in the absoluteExpiration parameter in an Insert method call to indicate the item should never expire. This field is read-only.
+ /// </summary>
+ public static readonly System.DateTime NoAbsoluteExpiration = System.DateTime.MaxValue;
+
+ /// <summary>
+ /// Used as the slidingExpiration parameter in an Insert method call to disable sliding expirations. This field is read-only.
+ /// </summary>
+ public static readonly System.TimeSpan NoSlidingExpiration = System.TimeSpan.Zero;
+
+ /// <summary>
+ /// Internal method to create a enumerator and over all public items in the cache and is used by GetEnumerator method.
+ /// </summary>
+ /// <returns>Returns IDictionaryEnumerator that contains all public items in the cache</returns>
+ private System.Collections.IDictionaryEnumerator CreateEnumerator()
+ {
+ System.Collections.Hashtable objTable;
+
+ _lockEntries.AcquireReaderLock(int.MaxValue);
+ try
+ {
+ // Create a new hashtable to return as collection of public items
+ objTable = new System.Collections.Hashtable(_arrEntries.Count);
+
+ foreach(System.Collections.DictionaryEntry objEntry in _arrEntries)
+ {
+ if (objEntry.Key != null)
+ {
+ // Check if this is a public entry
+ if (((CacheEntry) objEntry.Value).TestFlag(CacheEntry.Flags.Public))
+ {
+ // Add to the collection
+ objTable.Add(objEntry.Key, ((CacheEntry) objEntry.Value).Item);
+ }
+ }
+ }
+ }
+ finally
+ {
+ _lockEntries.ReleaseReaderLock();
+ }
+
+ return objTable.GetEnumerator();
+ }
+
+ /// <summary>
+ /// Implementation of IEnumerable interface and calls the GetEnumerator that returns
+ /// IDictionaryEnumerator.
+ /// </summary>
+ System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
+ {
+ return GetEnumerator();
+ }
+
+ /// <summary>
+ /// Virtual override of the IEnumerable.GetEnumerator() method, returns a specialized enumerator.
+ /// </summary>
+ public virtual System.Collections.IDictionaryEnumerator GetEnumerator()
+ {
+ return CreateEnumerator();
+ }
+
+ /// <summary>
+ /// Touches a object in the cache. Used to update expire time and hit count.
+ /// </summary>
+ /// <param name="strKey">The identifier for the cache item to retrieve.</param>
+ public void Touch(string strKey)
+ {
+ // Just touch the object
+ Get(strKey);
+ }
+
+ /// <summary>
+ /// Adds the specified item to the Cache object with dependencies, expiration and priority policies, and a
+ /// delegate you can use to notify your application when the inserted item is removed from the Cache.
+ /// </summary>
+ /// <param name="strKey">The cache key used to reference the item.</param>
+ /// <param name="objItem">The item to be added to the cache.</param>
+ /// <param name="objDependency">The file or cache key dependencies for the item. When any dependency changes, the object becomes invalid and is removed from the cache. If there are no dependencies, this paramter contains a null reference.</param>
+ /// <param name="absolutExpiration">The time at which the added object expires and is removed from the cache. </param>
+ /// <param name="slidingExpiration">The interval between the time the added object was last accessed and when that object expires. If this value is the equivalent of 20 minutes, the object expires and is removed from the cache 20 minutes after it is last accessed.</param>
+ /// <param name="enumPriority">The relative cost of the object, as expressed by the CacheItemPriority enumeration. The cache uses this value when it evicts objects; objects with a lower cost are removed from the cache before objects with a higher cost.</param>
+ /// <param name="enumPriorityDecay">The rate at which an object in the cache decays in importance. Objects that decay quickly are more likely to be removed.</param>
+ /// <param name="eventRemoveCallback">A delegate that, if provided, is called when an object is removed from the cache. You can use this to notify applications when their objects are deleted from the cache.</param>
+ /// <returns>The Object item added to the Cache.</returns>
+ public object Add(string strKey, object objItem, CacheDependency objDependency, System.DateTime absolutExpiration, System.TimeSpan slidingExpiration, CacheItemPriority enumPriority, CacheItemPriorityDecay enumPriorityDecay, CacheItemRemovedCallback eventRemoveCallback)
+ {
+ if (_boolDisposed)
+ {
+ throw new System.ObjectDisposedException("System.Web.Cache");
+ }
+
+ if (strKey == null)
+ {
+ throw new System.ArgumentNullException("strKey");
+ }
+
+ if (objItem == null)
+ {
+ throw new System.ArgumentNullException("objItem");
+ }
+
+ if (slidingExpiration > _datetimeOneYear)
+ {
+ throw new System.ArgumentOutOfRangeException("slidingExpiration");
+ }
+
+ CacheEntry objEntry;
+ CacheEntry objNewEntry;
+
+ long longHitRange = 10000;
+
+ // todo: check decay and make up the minHit range
+
+ objEntry = new CacheEntry(this, strKey, objItem, objDependency, eventRemoveCallback, absolutExpiration, slidingExpiration, longHitRange, true, enumPriority);
+
+ System.Threading.Interlocked.Increment(ref _longItems);
+
+ // If we have any kind of expiration add into the CacheExpires class
+ if (objEntry.HasSlidingExpiration || objEntry.HasAbsoluteExpiration)
+ {
+ // Add it to CacheExpires
+ _objExpires.Add(objEntry);
+ }
+
+ // Check and get the new item..
+ objNewEntry = UpdateCache(strKey, objEntry, true, CacheItemRemovedReason.Removed);
+
+ if (objNewEntry != null)
+ {
+ // Return added item
+ return objEntry.Item;
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ /// <summary>
+ /// Inserts an item into the Cache object with a cache key to reference its location and using default values
+ /// provided by the CacheItemPriority and CacheItemPriorityDecay enumerations.
+ /// </summary>
+ /// <param name="strKey">The cache key used to reference the item.</param>
+ /// <param name="objItem">The item to be added to the cache.</param>
+ public void Insert(string strKey, object objItem)
+ {
+ Add(strKey, objItem, null, System.DateTime.MaxValue, System.TimeSpan.Zero, CacheItemPriority.Default, CacheItemPriorityDecay.Default, null);
+ }
+
+ /// <summary>
+ /// Inserts an object into the Cache that has file or key dependencies.
+ /// </summary>
+ /// <param name="strKey">The cache key used to reference the item.</param>
+ /// <param name="objItem">The item to be added to the cache.</param>
+ /// <param name="objDependency">The file or cache key dependencies for the item. When any dependency changes, the object becomes invalid and is removed from the cache. If there are no dependencies, this paramter contains a null reference.</param>
+ public void Insert(string strKey, object objItem, CacheDependency objDependency)
+ {
+ Add(strKey, objItem, objDependency, System.DateTime.MaxValue, System.TimeSpan.Zero, CacheItemPriority.Default, CacheItemPriorityDecay.Default, null);
+ }
+
+ /// <summary>
+ /// Inserts an object into the Cache with dependencies and expiration policies.
+ /// </summary>
+ /// <param name="strKey">The cache key used to reference the item.</param>
+ /// <param name="objItem">The item to be added to the cache.</param>
+ /// <param name="objDependency">The file or cache key dependencies for the item. When any dependency changes, the object becomes invalid and is removed from the cache. If there are no dependencies, this paramter contains a null reference.</param>
+ /// <param name="absolutExpiration">The time at which the added object expires and is removed from the cache. </param>
+ /// <param name="slidingExpiration">The interval between the time the added object was last accessed and when that object expires. If this value is the equivalent of 20 minutes, the object expires and is removed from the cache 20 minutes after it is last accessed.</param>
+ public void Insert(string strKey, object objItem, CacheDependency objDependency, System.DateTime absolutExpiration, System.TimeSpan slidingExpiration)
+ {
+ Add(strKey, objItem, objDependency, absolutExpiration, slidingExpiration, CacheItemPriority.Default, CacheItemPriorityDecay.Default, null);
+ }
+
+ /// <summary>
+ /// Inserts an object into the Cache object with dependencies, expiration and priority policies, and a delegate
+ /// you can use to notify your application when the inserted item is removed from the Cache.
+ /// </summary>
+ /// <param name="strKey">The cache key used to reference the item.</param>
+ /// <param name="objItem">The item to be added to the cache.</param>
+ /// <param name="objDependency">The file or cache key dependencies for the item. When any dependency changes, the object becomes invalid and is removed from the cache. If there are no dependencies, this paramter contains a null reference.</param>
+ /// <param name="absolutExpiration">The time at which the added object expires and is removed from the cache. </param>
+ /// <param name="slidingExpiration">The interval between the time the added object was last accessed and when that object expires. If this value is the equivalent of 20 minutes, the object expires and is removed from the cache 20 minutes after it is last accessed.</param>
+ /// <param name="enumPriority">The relative cost of the object, as expressed by the CacheItemPriority enumeration. The cache uses this value when it evicts objects; objects with a lower cost are removed from the cache before objects with a higher cost.</param>
+ /// <param name="enumPriorityDecay">The rate at which an object in the cache decays in importance. Objects that decay quickly are more likely to be removed.</param>
+ /// <param name="eventRemoveCallback">A delegate that, if provided, is called when an object is removed from the cache. You can use this to notify applications when their objects are deleted from the cache.</param>
+ public void Insert(string strKey, object objItem, CacheDependency objDependency, System.DateTime absolutExpiration, System.TimeSpan slidingExpiration, CacheItemPriority enumPriority, CacheItemPriorityDecay enumPriorityDecay, CacheItemRemovedCallback eventRemoveCallback)
+ {
+ Add(strKey, objItem, objDependency, absolutExpiration, slidingExpiration, enumPriority, enumPriorityDecay, eventRemoveCallback);
+ }
+
+ /// <summary>
+ /// Removes the specified item from the Cache object.
+ /// </summary>
+ /// <param name="strKey">The cache key for the cache item to remove.</param>
+ /// <returns>The item removed from the Cache. If the value in the key parameter is not found, returns a null reference.</returns>
+ public object Remove(string strKey)
+ {
+ return Remove(strKey, CacheItemRemovedReason.Removed);
+ }
+
+ /// <summary>
+ /// Internal method that updates the cache, decremenents the number of existing items and call close on the cache entry. This method
+ /// is also used from the ExpiresBuckets class to remove an item during GC flush.
+ /// </summary>
+ /// <param name="strKey">The cache key for the cache item to remove.</param>
+ /// <param name="enumReason">Reason why the item is removed.</param>
+ /// <returns>The item removed from the Cache. If the value in the key parameter is not found, returns a null reference.</returns>
+ internal object Remove(string strKey, CacheItemRemovedReason enumReason)
+ {
+ CacheEntry objEntry = UpdateCache(strKey, null, true, enumReason);
+
+ if (objEntry != null)
+ {
+ System.Threading.Interlocked.Decrement(ref _longItems);
+
+ // Close the cache entry (calls the remove delegate)
+ objEntry.Close(enumReason);
+
+ return objEntry.Item;
+ } else
+ {
+ return null;
+ }
+ }
+
+ /// <summary>
+ /// Retrieves the specified item from the Cache object.
+ /// </summary>
+ /// <param name="strKey">The identifier for the cache item to retrieve.</param>
+ /// <returns>The retrieved cache item, or a null reference.</returns>
+ public object Get(string strKey)
+ {
+ CacheEntry objEntry = UpdateCache(strKey, null, false, CacheItemRemovedReason.Expired);
+
+ if (objEntry == null)
+ {
+ return null;
+ } else
+ {
+ return objEntry.Item;
+ }
+ }
+
+ /// <summary>
+ /// Internal method used for removing, updating and adding CacheEntries into the cache.
+ /// </summary>
+ /// <param name="strKey">The identifier for the cache item to modify</param>
+ /// <param name="objEntry">CacheEntry to use for overwrite operation, if this parameter is null and overwrite true the item is going to be removed</param>
+ /// <param name="boolOverwrite">If true the objEntry parameter is used to overwrite the strKey entry</param>
+ /// <param name="enumReason">Reason why an item was removed</param>
+ /// <returns></returns>
+ private CacheEntry UpdateCache(string strKey, CacheEntry objEntry, bool boolOverwrite, CacheItemRemovedReason enumReason)
+ {
+ if (_boolDisposed)
+ {
+ throw new System.ObjectDisposedException("System.Web.Cache", "Can't update item(s) in a disposed cache");
+ }
+
+ if (strKey == null)
+ {
+ throw new System.ArgumentNullException("System.Web.Cache");
+ }
+
+ long ticksNow = System.DateTime.Now.Ticks;
+ long ticksExpires = long.MaxValue;
+
+ bool boolGetItem = false;
+ bool boolExpiried = false;
+ bool boolWrite = false;
+ bool boolRemoved = false;
+
+ // Are we getting the item from the hashtable
+ if (boolOverwrite == false && strKey.Length > 0 && objEntry == null)
+ {
+ boolGetItem = true;
+ }
+
+ // TODO: Optimize this method, move out functionality outside the lock
+ _lockEntries.AcquireReaderLock(int.MaxValue);
+ try
+ {
+ if (boolGetItem)
+ {
+ objEntry = (CacheEntry) _arrEntries[strKey];
+ if (objEntry == null)
+ {
+ return null;
+ }
+ }
+
+ if (objEntry != null)
+ {
+ // Check if we have expired
+ if (objEntry.HasSlidingExpiration || objEntry.HasAbsoluteExpiration)
+ {
+ if (objEntry.Expires < ticksNow)
+ {
+ // We have expired, remove the item from the cache
+ boolWrite = true;
+ boolExpiried = true;
+ }
+ }
+ }
+
+ // Check if we going to modify the hashtable
+ if (boolWrite || (boolOverwrite && !boolExpiried))
+ {
+ // Upgrade our lock to write
+ System.Threading.LockCookie objCookie = _lockEntries.UpgradeToWriterLock(int.MaxValue);
+ try
+ {
+ // Check if we going to just modify an existing entry (or add)
+ if (boolOverwrite && objEntry != null)
+ {
+ _arrEntries[strKey] = objEntry;
+ }
+ else
+ {
+ // We need to remove the item, fetch the item first
+ objEntry = (CacheEntry) _arrEntries[strKey];
+ if (objEntry != null)
+ {
+ _arrEntries.Remove(strKey);
+ }
+
+ boolRemoved = true;
+ }
+ }
+ finally
+ {
+ _lockEntries.DowngradeFromWriterLock(ref objCookie);
+ }
+ }
+
+ // If the entry haven't expired or been removed update the info
+ if (!boolExpiried && !boolRemoved)
+ {
+ // Update that we got a hit
+ objEntry.Hits++;
+ if (objEntry.HasSlidingExpiration)
+ {
+ ticksExpires = ticksNow + objEntry.SlidingExpiration;
+ }
+ }
+ }
+ finally
+ {
+ _lockEntries.ReleaseLock();
+
+ }
+
+ // If the item was removed we need to remove it from the CacheExpired class also
+ if (boolRemoved)
+ {
+ if (objEntry != null)
+ {
+ if (objEntry.HasAbsoluteExpiration || objEntry.HasSlidingExpiration)
+ {
+ _objExpires.Remove(objEntry);
+ }
+ }
+
+ // Return the entry, it's not up to the UpdateCache to call Close on the entry
+ return objEntry;
+ }
+
+ // If we have sliding expiration and we have a correct hit, update the expiration manager
+ if (objEntry.HasSlidingExpiration)
+ {
+ _objExpires.Update(objEntry, ticksExpires);
+ }
+
+ // Return the cache entry
+ return objEntry;
+ }
+
+ /// <summary>
+ /// Gets the number of items stored in the cache.
+ /// </summary>
+ long Count
+ {
+ get
+ {
+ return _longItems;
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the cache item at the specified key.
+ /// </summary>
+ public object this[string strKey]
+ {
+ get
+ {
+ return Get(strKey);
+ }
+
+ set
+ {
+ Insert(strKey, value);
+ }
+ }
+
+ /// <summary>
+ /// Called to close the cache when the AppDomain is closing down or the GC has decided it's time to destroy the object.
+ /// </summary>
+ public void Dispose()
+ {
+ _boolDisposed = true;
+
+ _lockEntries.AcquireReaderLock(int.MaxValue);
+ try
+ {
+ foreach(System.Collections.DictionaryEntry objEntry in _arrEntries)
+ {
+ if (objEntry.Key != null)
+ {
+ // Check if this is active
+ if ( ((CacheEntry) objEntry.Value).TestFlag(CacheEntry.Flags.Removed) )
+ {
+ try
+ {
+ ((CacheEntry) objEntry.Value).Close(CacheItemRemovedReason.Removed);
+ }
+ catch (System.Exception objException)
+ {
+ System.Diagnostics.Debug.Fail("System.Web.Cache.Dispose() Exception when closing cache entry", "Message: " + objException.Message + " Stack: " + objException.StackTrace + " Source:" + objException.Source);
+ }
+ }
+ }
+ }
+ }
+ finally
+ {
+ _lockEntries.ReleaseReaderLock();
+ }
+ }
+ }
+}
diff --git a/mcs/class/System.Web/System.Web.Caching/CacheDefinitions.cs b/mcs/class/System.Web/System.Web.Caching/CacheDefinitions.cs
new file mode 100644
index 00000000000..d59afadc184
--- /dev/null
+++ b/mcs/class/System.Web/System.Web.Caching/CacheDefinitions.cs
@@ -0,0 +1,53 @@
+//
+// System.Web.Caching
+//
+// Author:
+// Patrik Torstensson (Patrik.Torstensson@labs2.com)
+//
+// (C) Copyright Patrik Torstensson, 2001
+//
+namespace System.Web.Caching
+{
+ /// <summary>
+ /// Specifies the relative priority of items stored in the Cache.
+ /// </summary>
+ public enum CacheItemPriority {
+ AboveNormal,
+ BelowNormal,
+ Default,
+ High,
+ Low,
+ Normal,
+ NotRemovable
+ }
+
+ /// <summary>
+ /// Specifies the rate at which the priority of items stored in the Cache are downgraded when not accessed frequently.
+ /// </summary>
+ public enum CacheItemPriorityDecay {
+ Default,
+ Fast,
+ Medium,
+ Never,
+ Slow
+ }
+
+ /// <summary>
+ /// Specifies the reason an item was removed from the Cache.
+ /// </summary>
+ public enum CacheItemRemovedReason {
+ DependencyChanged,
+ Expired,
+ Removed,
+ Underused
+ }
+
+ /// <summary>
+ /// Defines a callback method for notifying applications when a cached item is removed from the Cache.
+ /// </summary>
+ /// <param name="key">The index location for the item removed from the cache. </param>
+ /// <param name="value">The Object item removed from the cache. </param>
+ /// <param name="reason">The reason the item was removed from the cache, as specified by the CacheItemRemovedReason enumeration.</param>
+ public delegate void CacheItemRemovedCallback(string key, object value, CacheItemRemovedReason reason);
+
+ }
diff --git a/mcs/class/System.Web/System.Web.Caching/CacheDependency.cs b/mcs/class/System.Web/System.Web.Caching/CacheDependency.cs
new file mode 100644
index 00000000000..20f5e838b0f
--- /dev/null
+++ b/mcs/class/System.Web/System.Web.Caching/CacheDependency.cs
@@ -0,0 +1,79 @@
+//
+// System.Web.Caching
+//
+// Author:
+// Patrik Torstensson (Patrik.Torstensson@labs2.com)
+//
+// (C) Copyright Patrik Torstensson, 2001
+//
+namespace System.Web.Caching
+{
+ /// <summary>
+ /// Class to handle cache dependency, right now this class is only a mookup
+ /// </summary>
+ public class CacheDependency : System.IDisposable
+ {
+ private bool _boolDisposed;
+
+ public CacheDependency()
+ {
+ _boolDisposed = false;
+ }
+
+ public delegate void CacheDependencyCallback(CacheDependency objDependency);
+
+ public event CacheDependencyCallback Changed;
+
+ public void OnChanged()
+ {
+ if (_boolDisposed)
+ {
+ throw new System.ObjectDisposedException("System.Web.CacheDependency");
+ }
+
+ if (Changed != null)
+ {
+ Changed(this);
+ }
+ }
+
+ public bool IsDisposed
+ {
+ get
+ {
+ return _boolDisposed;
+ }
+ }
+
+ public bool HasEvents
+ {
+ get
+ {
+ if (_boolDisposed)
+ {
+ throw new System.ObjectDisposedException("System.Web.CacheDependency");
+ }
+
+ if (Changed != null)
+ {
+ return true;
+ }
+
+ return false;
+ }
+ }
+
+ public void Dispose()
+ {
+ _boolDisposed = true;
+ }
+
+ /// <summary>
+ /// Used in testing.
+ /// </summary>
+ public void Signal()
+ {
+ OnChanged();
+ }
+ }
+}
diff --git a/mcs/class/System.Web/System.Web.Caching/CacheEntry.cs b/mcs/class/System.Web/System.Web.Caching/CacheEntry.cs
new file mode 100644
index 00000000000..0943be5db30
--- /dev/null
+++ b/mcs/class/System.Web/System.Web.Caching/CacheEntry.cs
@@ -0,0 +1,363 @@
+//
+// System.Web.Caching
+//
+// Author:
+// Patrik Torstensson (Patrik.Torstensson@labs2.com)
+//
+// (C) Copyright Patrik Torstensson, 2001
+//
+namespace System.Web.Caching
+{
+ /// <summary>
+ /// Class responsible for representing a cache entry.
+ /// </summary>
+ public class CacheEntry
+ {
+ /// <summary>
+ /// Defines the status of the current cache entry
+ /// </summary>
+ public enum Flags
+ {
+ Removed = 0,
+ Public = 1
+ }
+
+ private CacheItemPriority _enumPriority;
+
+ private long _longHits;
+
+ private byte _byteExpiresBucket;
+ private int _intExpiresIndex;
+
+ private long _ticksExpires;
+ private long _ticksSlidingExpiration;
+
+ private string _strKey;
+ private object _objItem;
+
+ private long _longMinHits;
+
+ private Flags _enumFlags;
+
+ private CacheDependency _objDependency;
+ private Cache _objCache;
+
+ /// <summary>
+ /// Constructs a new cache entry
+ /// </summary>
+ /// <param name="strKey">The cache key used to reference the item.</param>
+ /// <param name="objItem">The item to be added to the cache.</param>
+ /// <param name="objDependency">The file or cache key dependencies for the item. When any dependency changes, the object becomes invalid and is removed from the cache. If there are no dependencies, this paramter contains a null reference.</param>
+ /// <param name="dtExpires">The time at which the added object expires and is removed from the cache. </param>
+ /// <param name="tsSpan">The interval between the time the added object was last accessed and when that object expires. If this value is the equivalent of 20 minutes, the object expires and is removed from the cache 20 minutes after it is last accessed.</param>
+ /// <param name="longMinHits">Used to detect and control if the item should be flushed due to under usage</param>
+ /// <param name="boolPublic">Defines if the item is public or not</param>
+ /// <param name="enumPriority">The relative cost of the object, as expressed by the CacheItemPriority enumeration. The cache uses this value when it evicts objects; objects with a lower cost are removed from the cache before objects with a higher cost.</param>
+ public CacheEntry( Cache objManager, string strKey, object objItem, CacheDependency objDependency, CacheItemRemovedCallback eventRemove,
+ System.DateTime dtExpires, System.TimeSpan tsSpan, long longMinHits, bool boolPublic, CacheItemPriority enumPriority )
+ {
+ if (boolPublic)
+ {
+ SetFlag(Flags.Public);
+ }
+
+ _strKey = strKey;
+ _objItem = objItem;
+ _objCache = objManager;
+
+ _onRemoved += eventRemove;
+
+ _enumPriority = enumPriority;
+
+ _ticksExpires = dtExpires.Ticks;
+
+ _ticksSlidingExpiration = tsSpan.Ticks;
+
+ // If we have a sliding expiration it overrides the absolute expiration (MS behavior)
+ if (tsSpan.Ticks != System.TimeSpan.Zero.Ticks)
+ {
+ _ticksExpires = System.DateTime.Now.AddTicks(_ticksSlidingExpiration).Ticks;
+ }
+
+ _objDependency = objDependency;
+ if (_objDependency != null)
+ {
+ if (_objDependency.IsDisposed)
+ {
+ throw new System.ObjectDisposedException("System.Web.CacheDependency");
+ }
+
+ // Add the entry to the cache dependency handler (we support multiple entries per handler)
+ _objDependency.Changed += new CacheDependency.CacheDependencyCallback(OnChanged);
+ }
+
+ _longMinHits = longMinHits;
+ }
+
+ private event CacheItemRemovedCallback _onRemoved;
+
+ public void OnChanged(CacheDependency objDependency)
+ {
+ _objCache.Remove(_strKey, CacheItemRemovedReason.DependencyChanged);
+ }
+
+ /// <summary>
+ /// Cleans up the cache entry, removes the cache dependency and calls the remove delegate.
+ /// </summary>
+ /// <param name="enumReason">The reason why the cache entry are going to be removed</param>
+ public void Close(CacheItemRemovedReason enumReason)
+ {
+ lock(this)
+ {
+ // Check if the item already is removed
+ if (TestFlag(Flags.Removed))
+ {
+ return;
+ }
+
+ SetFlag(Flags.Removed);
+
+ if (_onRemoved != null)
+ {
+ // Call the delegate to tell that we are now removing the entry
+ try
+ {
+ _onRemoved(_strKey, _objItem, enumReason);
+ }
+ catch (System.Exception objException)
+ {
+ System.Diagnostics.Debug.Fail("System.Web.CacheEntry.Close() Exception when calling remove delegate", "Message: " + objException.Message + " Stack: " + objException.StackTrace + " Source:" + objException.Source);
+ }
+ }
+
+ // If we have a dependency, remove the entry
+ if (_objDependency != null)
+ {
+ _objDependency.Changed -= new CacheDependency.CacheDependencyCallback(OnChanged);
+ if (!_objDependency.HasEvents)
+ {
+ _objDependency.Dispose();
+ }
+ }
+ }
+ }
+
+ /// <summary>
+ /// Tests a specific flag is set or not.
+ /// </summary>
+ /// <param name="oFlag">Flag to test agains</param>
+ /// <returns>Returns true if the flag is set.</returns>
+ public bool TestFlag(Flags oFlag)
+ {
+ lock(this)
+ {
+ if ((_enumFlags & oFlag) != 0)
+ {
+ return true;
+ }
+
+ return false;
+ }
+ }
+
+ /// <summary>
+ /// Sets a specific flag.
+ /// </summary>
+ /// <param name="oFlag">Flag to set.</param>
+ public void SetFlag(Flags oFlag)
+ {
+ lock (this)
+ {
+ _enumFlags |= oFlag;
+ }
+ }
+
+ /// <summary>
+ /// Returns true if the object has minimum hit usage flushing enabled.
+ /// </summary>
+ public bool HasUsage
+ {
+ get {
+ if (_longMinHits == System.Int64.MaxValue)
+ {
+ return false;
+ }
+
+ return true;
+ }
+ }
+
+ /// <summary>
+ /// Returns true if the entry has absolute expiration.
+ /// </summary>
+ public bool HasAbsoluteExpiration
+ {
+ get
+ {
+ if (_ticksExpires == System.DateTime.MaxValue.Ticks)
+ {
+ return false;
+ }
+
+ return true;
+ }
+ }
+
+ /// <summary>
+ /// Returns true if the entry has sliding expiration enabled.
+ /// </summary>
+ public bool HasSlidingExpiration
+ {
+ get
+ {
+ if (_ticksSlidingExpiration == System.TimeSpan.Zero.Ticks)
+ {
+ return false;
+ }
+
+ return true;
+ }
+ }
+
+ /// <summary>
+ /// Gets and sets the current expires bucket the entry is active in.
+ /// </summary>
+ public byte ExpiresBucket
+ {
+ get
+ {
+ lock (this)
+ {
+ return _byteExpiresBucket;
+ }
+ }
+ set
+ {
+ lock (this)
+ {
+ _byteExpiresBucket = ExpiresBucket;
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets and sets the current index in the expires bucket of the current cache entry.
+ /// </summary>
+ public int ExpiresIndex
+ {
+ get
+ {
+ lock (this)
+ {
+ return _intExpiresIndex;
+ }
+ }
+
+ set
+ {
+ lock (this)
+ {
+ _intExpiresIndex = ExpiresIndex;
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets and sets the expiration of the cache entry.
+ /// </summary>
+ public long Expires
+ {
+ get
+ {
+ lock (this)
+ {
+ return _ticksExpires;
+ }
+ }
+ set
+ {
+ lock (this)
+ {
+ _ticksExpires = Expires;
+ }
+ }
+ }
+
+ /// <summary>
+ /// Gets the sliding expiration value. The return value is in ticks (since 0/0-01 in 100nanosec)
+ /// </summary>
+ public long SlidingExpiration
+ {
+ get
+ {
+ return _ticksSlidingExpiration;
+ }
+ }
+
+ /// <summary>
+ /// Returns the current cached item.
+ /// </summary>
+ public object Item
+ {
+ get
+ {
+ return _objItem;
+ }
+ }
+
+ /// <summary>
+ /// Returns the current cache identifier.
+ /// </summary>
+ public string Key
+ {
+ get
+ {
+ return _strKey;
+ }
+ }
+
+ /// <summary>
+ /// Gets and sets the current number of hits on the cache entry.
+ /// </summary>
+ public long Hits
+ {
+ // todo: Could be optimized by using interlocked methods..
+ get
+ {
+ lock (this)
+ {
+ return _longHits;
+ }
+ }
+ set
+ {
+ lock (this)
+ {
+ _longHits = Hits;
+ }
+ }
+ }
+
+ /// <summary>
+ /// Returns minimum hits for the usage flushing rutine.
+ /// </summary>
+ public long MinimumHits
+ {
+ get
+ {
+ return _longMinHits;
+ }
+ }
+
+ /// <summary>
+ /// Returns the priority of the cache entry.
+ /// </summary>
+ public CacheItemPriority Priority
+ {
+ get
+ {
+ return _enumPriority;
+ }
+ }
+ }
+}
diff --git a/mcs/class/System.Web/System.Web.Caching/CacheExpires.cs b/mcs/class/System.Web/System.Web.Caching/CacheExpires.cs
new file mode 100644
index 00000000000..a58eb5c1e69
--- /dev/null
+++ b/mcs/class/System.Web/System.Web.Caching/CacheExpires.cs
@@ -0,0 +1,145 @@
+//
+// System.Web.Caching
+//
+// Author:
+// Patrik Torstensson (Patrik.Torstensson@labs2.com)
+//
+// (C) Copyright Patrik Torstensson, 2001
+//
+namespace System.Web.Caching
+{
+ /// <summary>
+ /// Class responsible for handling time based flushing of entries in the cache. The class creates
+ /// and manages 60 buckets each holding every item that expires that minute. The bucket calculated
+ /// for an entry is one minute more than the timeout just to make sure that the item end up in the
+ /// bucket where it should be flushed.
+ /// </summary>
+ public class CacheExpires : System.IDisposable
+ {
+ static int _intFlush;
+ static long _ticksPerBucket = 600000000;
+ static long _ticksPerCycle = _ticksPerBucket * 60;
+
+ private ExpiresBucket[] _arrBuckets;
+ private System.Threading.Timer _objTimer;
+ private Cache _objManager;
+
+ /// <summary>
+ /// Constructor
+ /// </summary>
+ /// <param name="objManager">The cache manager, used when flushing items in a bucket.</param>
+ public CacheExpires(Cache objManager)
+ {
+ _objManager = objManager;
+ Initialize();
+ }
+
+ /// <summary>
+ /// Initializes the class.
+ /// </summary>
+ private void Initialize()
+ {
+ // Create one bucket per minute
+ _arrBuckets = new ExpiresBucket[60];
+
+ byte bytePos = 0;
+ do
+ {
+ _arrBuckets[bytePos] = new ExpiresBucket(bytePos, _objManager);
+ bytePos++;
+ } while (bytePos < 60);
+
+ // GC Bucket controller
+ _intFlush = System.DateTime.Now.Minute - 1;
+ _objTimer = new System.Threading.Timer(new System.Threading.TimerCallback(GarbageCleanup), null, 10000, 60000);
+ }
+
+ /// <summary>
+ /// Adds a Cache entry to the correct flush bucket.
+ /// </summary>
+ /// <param name="objEntry">Cache entry to add.</param>
+ public void Add(CacheEntry objEntry)
+ {
+ long ticksNow = System.DateTime.Now.Ticks;
+
+ lock(this)
+ {
+ // If the entry doesn't have a expires time we assume that the entry is due to expire now.
+ if (objEntry.Expires == 0)
+ {
+ objEntry.Expires = ticksNow;
+ }
+
+ _arrBuckets[GetHashBucket(objEntry.Expires)].Add(objEntry);
+ }
+ }
+
+ public void Remove(CacheEntry objEntry)
+ {
+ long ticksNow = System.DateTime.Now.Ticks;
+
+ lock(this)
+ {
+ // If the entry doesn't have a expires time we assume that the entry is due to expire now.
+ if (objEntry.Expires == 0)
+ {
+ objEntry.Expires = ticksNow;
+ }
+
+ _arrBuckets[GetHashBucket(objEntry.Expires)].Remove(objEntry);
+ }
+ }
+
+ public void Update(CacheEntry objEntry, long ticksExpires)
+ {
+ long ticksNow = System.DateTime.Now.Ticks;
+
+ lock(this)
+ {
+ // If the entry doesn't have a expires time we assume that the entry is due to expire now.
+ if (objEntry.Expires == 0)
+ {
+ objEntry.Expires = ticksNow;
+ }
+
+ _arrBuckets[GetHashBucket(objEntry.Expires)].Update(objEntry, ticksExpires);
+ }
+ }
+
+ public void GarbageCleanup(object State)
+ {
+ ExpiresBucket objBucket;
+
+ lock(this)
+ {
+ // Do cleanup of the bucket
+ objBucket = _arrBuckets[(++_intFlush) % 60];
+ }
+
+ // Flush expired items in the current bucket (defined by _intFlush)
+ objBucket.FlushExpiredItems();
+ }
+
+ private int GetHashBucket(long ticks)
+ {
+ // Get bucket to add expire item into, add one minute to the bucket just to make sure that we get it in the bucket gc
+ return (int) (((((ticks + 60000) % _ticksPerCycle) / _ticksPerBucket) + 1) % 60);
+ }
+
+ /// <summary>
+ /// Called by the cache for cleanup.
+ /// </summary>
+ public void Dispose()
+ {
+ lock(this)
+ {
+ // Cleanup the internal timer
+ if (_objTimer != null)
+ {
+ _objTimer.Dispose();
+ _objTimer = null;
+ }
+ }
+ }
+ }
+}
diff --git a/mcs/class/System.Web/System.Web.Caching/ChangeLog b/mcs/class/System.Web/System.Web.Caching/ChangeLog
new file mode 100644
index 00000000000..9b497a9c822
--- /dev/null
+++ b/mcs/class/System.Web/System.Web.Caching/ChangeLog
@@ -0,0 +1,8 @@
+2001-07-20 Patrik Torstensson (Patrik.Torstensson@labs2.com)
+
+ * Cache.cs: Implemented. (90% ready)
+ * CacheDefinitions.cs: Implemented.
+ * CacheDependency.cs: Added. (20% ready)
+ * CacheExpires: Implemented.
+ * CacheEntry.cs: Implemented. (95% ready, going to be changed due to CacheDependecy support)
+ * ExpiresBuckets.cs: Implemented.
diff --git a/mcs/class/System.Web/System.Web.Caching/ExpiresBuckets.cs b/mcs/class/System.Web/System.Web.Caching/ExpiresBuckets.cs
new file mode 100644
index 00000000000..b5b877d455d
--- /dev/null
+++ b/mcs/class/System.Web/System.Web.Caching/ExpiresBuckets.cs
@@ -0,0 +1,253 @@
+//
+// System.Web.Caching
+//
+// Author:
+// Patrik Torstensson (Patrik.Torstensson@labs2.com)
+//
+// (C) Copyright Patrik Torstensson, 2001
+//
+namespace System.Web.Caching
+{
+ /// <summary>
+ /// Responsible for holding a cache entry in the linked list bucket.
+ /// </summary>
+ public struct ExpiresEntry
+ {
+ public CacheEntry _objEntry;
+ public long _ticksExpires;
+ public int _intNext;
+ }
+
+ /// <summary>
+ /// Holds cache entries that has a expiration in a bucket list.
+ /// </summary>
+ public class ExpiresBucket
+ {
+ private static int MIN_ENTRIES = 16;
+
+ private byte _byteID;
+ private int _intSize;
+ private int _intCount;
+ private int _intNext;
+
+ private Cache _objManager;
+
+ private ExpiresEntry [] _arrEntries;
+
+ /// <summary>
+ /// Constructs a new bucket.
+ /// </summary>
+ /// <param name="bucket">Current bucket ID.</param>
+ /// <param name="objManager">Cache manager reponsible for the item(s) in the expires bucket.</param>
+ public ExpiresBucket(byte bucket, Cache objManager)
+ {
+ _objManager = objManager;
+ Initialize(bucket);
+ }
+
+ /// <summary>
+ /// Initializes the expires bucket, creates a linked list of MIN_ENTRIES.
+ /// </summary>
+ /// <param name="bucket">Bucket ID.</param>
+ private void Initialize(byte bucket)
+ {
+ _byteID = bucket;
+ _intNext = 0;
+ _intCount = 0;
+
+ _arrEntries = new ExpiresEntry[MIN_ENTRIES];
+ _intSize = MIN_ENTRIES;
+
+ int intPos = 0;
+ do
+ {
+ _arrEntries[intPos]._intNext = intPos + 1;
+ _arrEntries[intPos]._ticksExpires = System.DateTime.MaxValue.Ticks;
+
+ intPos++;
+ } while (intPos < _intSize);
+
+ _arrEntries[_intSize - 1]._intNext = -1;
+ }
+
+ /// <summary>
+ /// Expands the bucket linked array list.
+ /// </summary>
+ private void Expand()
+ {
+ ExpiresEntry [] arrData;
+ int intPos = 0;
+ int intOldSize;
+
+ lock(this)
+ {
+ intOldSize = _intSize;
+ _intSize *= 2;
+
+ // Create a new array and copy the old data into the new array
+ arrData = new ExpiresEntry[_intSize];
+ do
+ {
+ arrData[intPos] = _arrEntries[intPos];
+ intPos++;
+ } while (intPos < intOldSize);
+
+ _intNext = intPos;
+
+ // Initialize the "new" positions.
+ do
+ {
+ arrData[intPos]._intNext = intPos + 1;
+ intPos++;
+ } while (intPos < _intSize);
+
+ arrData[_intSize - 1]._intNext = -1;
+
+ _arrEntries = arrData;
+ }
+ }
+
+ /// <summary>
+ /// Adds a cache entry into the expires bucket.
+ /// </summary>
+ /// <param name="objEntry">Cache Entry object to be added.</param>
+ public void Add(CacheEntry objEntry)
+ {
+ if (_intNext == -1)
+ {
+ Expand();
+ }
+
+ lock(this)
+ {
+ _arrEntries[_intNext]._ticksExpires = objEntry.Expires;
+ _arrEntries[_intNext]._objEntry = objEntry;
+
+ _intNext = _arrEntries[_intNext]._intNext;
+
+ _intCount++;
+ }
+ }
+
+ /// <summary>
+ /// Removes a cache entry from the expires bucket.
+ /// </summary>
+ /// <param name="objEntry">Cache entry to be removed.</param>
+ public void Remove(CacheEntry objEntry)
+ {
+ lock(this)
+ {
+ // Check if this is our bucket
+ if (objEntry.ExpiresIndex != _byteID) return;
+ if (objEntry.ExpiresIndex == System.Int32.MaxValue) return;
+ if (_arrEntries.Length < objEntry.ExpiresIndex) return;
+
+ _intCount--;
+
+ _arrEntries[objEntry.ExpiresIndex]._objEntry.ExpiresBucket = byte.MaxValue;
+ _arrEntries[objEntry.ExpiresIndex]._objEntry.ExpiresIndex = int.MaxValue;
+ _arrEntries[objEntry.ExpiresIndex]._objEntry = null;
+ _intNext = _arrEntries[objEntry.ExpiresIndex]._intNext;
+ }
+ }
+
+ /// <summary>
+ /// Updates a cache entry in the expires bucket, this is called during a hit of an item if the
+ /// cache item has a sliding expiration. The function is responsible for updating the cache
+ /// entry.
+ /// </summary>
+ /// <param name="objEntry">Cache entry to update.</param>
+ /// <param name="ticksExpires">New expiration value for the cache entry.</param>
+ public void Update(CacheEntry objEntry, long ticksExpires)
+ {
+ lock(this)
+ {
+ // Check if this is our bucket
+ if (objEntry.ExpiresIndex != _byteID) return;
+ if (objEntry.ExpiresIndex == System.Int32.MaxValue) return;
+ if (_arrEntries.Length < objEntry.ExpiresIndex) return;
+
+ _arrEntries[objEntry.ExpiresIndex]._ticksExpires = ticksExpires;
+ _arrEntries[objEntry.ExpiresIndex]._objEntry.Expires = ticksExpires;
+ }
+ }
+
+ /// <summary>
+ /// Flushes all cache entries that has expired and removes them from the cache manager.
+ /// </summary>
+ public void FlushExpiredItems()
+ {
+ ExpiresEntry objEntry;
+ CacheEntry [] arrCacheEntries;
+
+ int intCachePos;
+ int intPos;
+ long ticksNow;
+
+ ticksNow = System.DateTime.Now.Ticks;
+
+ intCachePos = 0;
+
+ // Lookup all items that needs to be removed, this is done in a two part
+ // operation to minimize the locking time.
+ lock (this)
+ {
+ arrCacheEntries = new CacheEntry[_intSize];
+
+ intPos = 0;
+ do
+ {
+ objEntry = _arrEntries[intPos];
+ if (objEntry._objEntry != null)
+ {
+ if (objEntry._ticksExpires < ticksNow)
+ {
+ arrCacheEntries[intCachePos++] = objEntry._objEntry;
+
+ objEntry._objEntry.ExpiresBucket = byte.MaxValue;
+ objEntry._objEntry.ExpiresIndex = int.MaxValue;
+ objEntry._objEntry = null;
+ _intNext = objEntry._intNext;
+ }
+ }
+
+ intPos++;
+ } while (intPos < _intSize);
+ }
+
+ // If we have any entries to remove, go ahead and call the cache manager remove.
+ if (intCachePos > 0)
+ {
+ intPos = 0;
+ do
+ {
+ _objManager.Remove(arrCacheEntries[intPos].Key, CacheItemRemovedReason.Expired);
+
+ intPos++;
+ } while (intPos < intCachePos);
+ }
+ }
+
+ /// <summary>
+ /// Returns the current size of the expires bucket.
+ /// </summary>
+ public int Size
+ {
+ get
+ {
+ return _arrEntries.Length;
+ }
+ }
+
+ /// <summary>
+ /// Returns number of items in the bucket.
+ /// </summary>
+ public int Count
+ {
+ get
+ {
+ return _intCount;
+ }
+ }
+ }
+}
diff --git a/mcs/class/System.Web/System.Web.Caching/common.src b/mcs/class/System.Web/System.Web.Caching/common.src
new file mode 100644
index 00000000000..145759c646b
--- /dev/null
+++ b/mcs/class/System.Web/System.Web.Caching/common.src
@@ -0,0 +1,6 @@
+Cache.cs
+CacheDefinitions.cs
+CacheDependency.cs
+CacheEntry.cs
+CacheExpires.cs
+ExpiresBuckets.cs
diff --git a/mcs/class/System.Web/System.Web.Caching/unix.src b/mcs/class/System.Web/System.Web.Caching/unix.src
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/mcs/class/System.Web/System.Web.Caching/unix.src
diff --git a/mcs/class/System.Web/System.Web.Caching/windows.src b/mcs/class/System.Web/System.Web.Caching/windows.src
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/mcs/class/System.Web/System.Web.Caching/windows.src
diff --git a/mcs/class/System.Web/System.Web.Configuration/AuthenticationMode.cs b/mcs/class/System.Web/System.Web.Configuration/AuthenticationMode.cs
new file mode 100755
index 00000000000..1bc1d9e9a36
--- /dev/null
+++ b/mcs/class/System.Web/System.Web.Configuration/AuthenticationMode.cs
@@ -0,0 +1,19 @@
+/* System.Web.Configuration
+ * Authors:
+ * Leen Toelen (toelen@hotmail.com)
+ * Copyright (C) 2001 Leen Toelen
+*/
+
+namespace System.Web.Configuration {
+
+ /// <summary>
+ /// Defines the AuthenticationMode for a Web Application.
+ /// </summary>
+ public enum AuthenticationMode{
+ Forms,
+ None,
+ Passport,
+ Windows
+ }
+
+} //namespace System.Web.Configuration
diff --git a/mcs/class/System.Web/System.Web.Configuration/FormsAuthPasswordFormat.cs b/mcs/class/System.Web/System.Web.Configuration/FormsAuthPasswordFormat.cs
new file mode 100755
index 00000000000..ff416bc6ebc
--- /dev/null
+++ b/mcs/class/System.Web/System.Web.Configuration/FormsAuthPasswordFormat.cs
@@ -0,0 +1,18 @@
+/* System.Web.Configuration
+ * Authors:
+ * Leen Toelen (toelen@hotmail.com)
+ * Copyright (C) 2001 Leen Toelen
+*/
+
+namespace System.Web.Configuration {
+
+ /// <summary>
+ /// Defines the password encryption format.
+ /// </summary>
+ public enum FormsAuthPasswordFormat{
+ Clear,
+ MD5,
+ SHA1
+ }
+
+} //namespace System.Web.Configuration
diff --git a/mcs/class/System.Web/System.Web.Configuration/FormsProtectionEnum.cs b/mcs/class/System.Web/System.Web.Configuration/FormsProtectionEnum.cs
new file mode 100755
index 00000000000..e94950e067e
--- /dev/null
+++ b/mcs/class/System.Web/System.Web.Configuration/FormsProtectionEnum.cs
@@ -0,0 +1,19 @@
+/* System.Web.Configuration
+ * Authors:
+ * Leen Toelen (toelen@hotmail.com)
+ * Copyright (C) 2001 Leen Toelen
+*/
+
+namespace System.Web.Configuration {
+
+ /// <summary>
+ /// Defines the method used for securing web forms.
+ /// </summary>
+ public enum FormsProtectionEnum{
+ All,
+ Encryption,
+ None,
+ Validation
+ }
+
+} //namespace System.Web.Configuration
diff --git a/mcs/class/System.Web/System.Web.UI.HtmlControls/ChangeLog b/mcs/class/System.Web/System.Web.UI.HtmlControls/ChangeLog
new file mode 100644
index 00000000000..a903b635067
--- /dev/null
+++ b/mcs/class/System.Web/System.Web.UI.HtmlControls/ChangeLog
@@ -0,0 +1,5 @@
+2001-08-22 Bob Smith <bob@thestuff.net>
+
+ * HtmlContainerControl.cs: Initial implementation.
+ * HtmlControl.cs: Initial implementation.
+ * HtmlGenericControl.cs: Initial implementation.
diff --git a/mcs/class/System.Web/System.Web.UI.HtmlControls/HtmlContainerControl.cs b/mcs/class/System.Web/System.Web.UI.HtmlControls/HtmlContainerControl.cs
new file mode 100644
index 00000000000..cdb5d28e97f
--- /dev/null
+++ b/mcs/class/System.Web/System.Web.UI.HtmlControls/HtmlContainerControl.cs
@@ -0,0 +1,75 @@
+//
+// System.Web.UI.HtmlControls.HtmlContainerControl.cs
+//
+// Author:
+// Bob Smith <bob@thestuff.net>
+//
+// (C) Bob Smith
+//
+
+using System;
+using System.Web;
+using System.Web.UI;
+
+//LAMESPEC: The dox talk about HttpException but are very ambigious.
+//TODO: Check to see if Render really is overridden instead of a LiteralControl being added. It apears that this is the
+//case due to testing. Anything inside the block is overwritten by the content of this control, so it doesnt apear
+//to do anything with children.
+// a doc references this. add? protected override ControlCollection CreateControlCollection();
+
+//TODO: If Test.InnerText = Test.InnerHtml without ever assigning anything into InnerHtml, you get this:
+// Exception Details: System.Web.HttpException: Cannot get inner content of Message because the contents are not literal.
+//[HttpException (0x80004005): Cannot get inner content of Message because the contents are not literal.]
+// System.Web.UI.HtmlControls.HtmlContainerControl.get_InnerHtml() +278
+// ASP.test3_aspx.AnchorBtn_Click(Object Source, EventArgs E) in \\genfs2\www24\bobsmith11\test3.aspx:6
+// System.Web.UI.HtmlControls.HtmlAnchor.OnServerClick(EventArgs e) +108
+// System.Web.UI.HtmlControls.HtmlAnchor.System.Web.UI.IPostBackEventHandler.RaisePostBackEvent(String eventArgument) +26
+// System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler sourceControl, String eventArgument) +18
+// System.Web.UI.Page.RaisePostBackEvent(NameValueCollection postData) +149
+// System.Web.UI.Page.ProcessRequestMain() +660
+
+
+namespace System.Web.UI.HtmlControls
+{
+ public abstract class HtmlContainerControl : HtmlControl
+ {
+ private string _innterHtml = "";
+ private string _innterText = "";
+ private bool _doText = false;
+ private bool _doChildren = true;
+ public HtmlContainerControl() : base(); {}
+ public HtmlContainerControl(string tag) : base(tag) {}
+ public virtual string InnerHtml
+ {
+ get
+ {
+ return _innerHtml;
+ }
+ set
+ {
+ _innerHtml = value;
+ _doText = false;
+ _doChildren = false;
+ }
+ }
+ public virtual string InnerText
+ {
+ get
+ {
+ return _innerText;
+ }
+ set
+ {
+ _innerText = value;
+ _doText = true;
+ _doChildren = false;
+ }
+ }
+ public override Render(HtmlTextWriter writer)
+ {
+ if(_doChildren) RenderChildren(writer);
+ else if(_doText) Page.Server.HtmlEncode(_innerText, writer);
+ else writer.Write(_innerHtml);
+ }
+ }
+}
diff --git a/mcs/class/System.Web/System.Web.UI.HtmlControls/HtmlControl.cs b/mcs/class/System.Web/System.Web.UI.HtmlControls/HtmlControl.cs
new file mode 100644
index 00000000000..d58f7c8a3ab
--- /dev/null
+++ b/mcs/class/System.Web/System.Web.UI.HtmlControls/HtmlControl.cs
@@ -0,0 +1,60 @@
+//
+// System.Web.UI.HtmlControls.HtmlControl.cs
+//
+// Author:
+// Bob Smith <bob@thestuff.net>
+//
+// (C) Bob Smith
+//
+
+using System;
+using System.Web;
+using System.Web.UI;
+
+namespace System.Web.UI.HtmlControls
+{
+ public abstract class HtmlControl : Control, IAttributeAccessor
+ {
+ private string _tagName = "span";
+//TODO: Is this correct, or is the StateBag really the ViewState?
+ private AttributeCollection _attributes = new AttributeCollection(new StateBag(true));
+ private bool _disabled = false;
+ public HtmlControl() {}
+ public HtmlControl(string tag)
+ {
+ if(tag != null && tag != "") _tagName = tag;
+ }
+ public AttributeCollection Attributes
+ {
+ get
+ {
+ return _attributes;
+ }
+ }
+ public bool Disabled
+ {
+ get
+ {
+ return _disabled;
+ }
+ set
+ {
+ _disabled = value;
+ }
+ }
+ public CssStyleCollection Style
+ {
+ get
+ {
+ return _attributes.CssStyle;
+ }
+ }
+ public virtual string TagName
+ {
+ get
+ {
+ return _tagName;
+ }
+ }
+ }
+}
diff --git a/mcs/class/System.Web/System.Web.UI.HtmlControls/HtmlGenericControl.cs b/mcs/class/System.Web/System.Web.UI.HtmlControls/HtmlGenericControl.cs
new file mode 100644
index 00000000000..b805e5c9008
--- /dev/null
+++ b/mcs/class/System.Web/System.Web.UI.HtmlControls/HtmlGenericControl.cs
@@ -0,0 +1,21 @@
+/
+// System.Web.UI.HtmlControls.HtmlGenericControl.cs
+//
+// Author:
+// Bob Smith <bob@thestuff.net>
+//
+// (C) Bob Smith
+//
+
+using System;
+using System.Web;
+using System.Web.UI;
+
+namespace System.Web.UI.HtmlControls
+{
+ public class HtmlGenericControl : HtmlContainerControl
+ {
+ public HtmlContainerControl() : base(); {}
+ public HtmlContainerControl(string tag) : base(tag) {}
+ }
+}
diff --git a/mcs/class/System.Web/System.Web.UI.HtmlControls/common.src b/mcs/class/System.Web/System.Web.UI.HtmlControls/common.src
new file mode 100644
index 00000000000..1aaec880fa9
--- /dev/null
+++ b/mcs/class/System.Web/System.Web.UI.HtmlControls/common.src
@@ -0,0 +1,3 @@
+HtmlContainerControl.cs
+HtmlControl.cs
+HtmlGenericControl.cs
diff --git a/mcs/class/System.Web/System.Web.UI.HtmlControls/unix.src b/mcs/class/System.Web/System.Web.UI.HtmlControls/unix.src
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/mcs/class/System.Web/System.Web.UI.HtmlControls/unix.src
diff --git a/mcs/class/System.Web/System.Web.UI.HtmlControls/windows.src b/mcs/class/System.Web/System.Web.UI.HtmlControls/windows.src
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/mcs/class/System.Web/System.Web.UI.HtmlControls/windows.src
diff --git a/mcs/class/System.Web/System.Web.UI/ChangeLog b/mcs/class/System.Web/System.Web.UI/ChangeLog
new file mode 100644
index 00000000000..90a38448249
--- /dev/null
+++ b/mcs/class/System.Web/System.Web.UI/ChangeLog
@@ -0,0 +1,13 @@
+2001-08-22 Bob Smith <bob@thestuff.net>
+
+ * LiteralControl.cs: Implemented.
+ * Control.cs: Even more implementation (Events). What a beast.
+
+2001-08-20 Bob Smith <bob@thestuff.net>
+
+ * Control.cs: More implementation. Not done yet. Shutter.
+
+2001-08-17 Bob Smith <bob@thestuff.net>
+
+ * Control.cs: Partial implementation.
+
diff --git a/mcs/class/System.Web/System.Web.UI/Control.cs b/mcs/class/System.Web/System.Web.UI/Control.cs
new file mode 100644
index 00000000000..3eca5383bc3
--- /dev/null
+++ b/mcs/class/System.Web/System.Web.UI/Control.cs
@@ -0,0 +1,333 @@
+//
+// System.Web.UI.Control.cs
+//
+// Author:
+// Bob Smith <bob@thestuff.net>
+//
+// (C) Bob Smith
+//
+
+//notes: view state only tracks changes after OnInit method is executed for the page request. You can read from it at any time, but cant write to it during rendering.
+//more notes: look at the private on* methods for initialization order. they will help.
+//even more notes: view state info in trackviewstate method description. read later.
+//Ok, enough notes: what the heck is different between enable view state, and track view state.
+
+//cycle:
+//init is called when control is first created.
+//load is called when control is loaded into a page
+//prerender is called when the server is about to render its page object
+//disposed/unload not sure but is last.
+
+//read this later. http://gotdotnet.com/quickstart/aspplus/
+
+using System;
+using System.Web;
+using System.ComponentModel;
+
+namespace System.Web.UI
+{
+ public class Control : IComponent, IDisposable, IParserAccessor, IDataBindingsAccessor
+ {
+ public event EventHandler DataBinding;
+ public event EventHandler Disposed;
+ public event EventHandler Init;
+ public event EventHandler Load;
+ public event EventHandler PreRender;
+ public event EventHandler Unload;
+ private string _clientId; //default to "ctrl#" where # is a static count of ctrls per page.
+ private string _userId = null;
+ private ControlCollection _controls;
+ private bool _enableViewState = true;
+ private Control _namingContainer;
+ private Page _page;
+ private Control _parent; //TODO: set default.
+ private ISite _site; //TODO: what default?
+ private bool _visible; //TODO: what default?
+ private HttpContext _context = null;
+ private bool _childControlsCreated = false;
+ private StateBag _viewState; //TODO: help me.
+ private bool _trackViewState = false; //TODO: I think this is right. Verify. Also modify other methods to use this.
+ private bool _viewStateIgnoreCase = true;
+ public Control()
+ {
+ _namingContainer = _parent;
+ _viewState = new StateBag(_viewStateIgnoreCase);
+ _events = new EventHandlerList();
+ _controls = this.CreateControlCollection(); //FIXME: this goes here?
+ }
+ public ~Control()
+ {
+ Dispose();
+ }
+ public virtual string ClientID
+ {
+ get
+ {
+ return _clientId;
+ }
+ }
+ public virtual ControlCollection Controls
+ {
+ get
+ {
+ return _controls;
+ }
+ }
+ public virtual bool EnableViewState
+ {
+ get
+ {
+ return _enableViewState;
+ }
+ set
+ {
+ _enableViewState = value;
+ }
+ }
+ public virtual string ID
+ {
+ get
+ {
+ if (_userId == null)
+ return _clientId;
+ else
+ return _userId;
+ }
+ set
+ {
+ _userId = value;
+ }
+ }
+ public virtual Control NamingContainer
+ {
+ get
+ {
+ return _namingContainer;
+ }
+ }
+ public virtual Page Page
+ {
+ get
+ {
+ return _page;
+ }
+ set
+ {
+ _page = value;
+ }
+ }
+ public virtual Control Parent
+ {
+ get
+ {
+ return _parent;
+ }
+ }
+ public ISite Site
+ {
+ get
+ {
+ return _site;
+ }
+ set
+ {
+ _site = value;
+ }
+ }
+ public virtual string TemplateSourceDirectory
+ {
+ get
+ {
+ return Context.Request.ApplicationPath;
+ }
+ }
+ public virtual string UniqueID
+ {
+ get
+ {
+ if (_namingContainer == null)
+ if (_userId == null)
+ return _clientId;
+ else
+ return _clientId + ":" + _userId;
+ else if (_userId == null)
+ return _namingContainer.UniqueID + ":" + _clientId;
+ return _namingContainer.UniqueID + ":" + _clientId + ":" + _userId;
+ }
+ }
+ public virtual bool Visible
+ {
+ get
+ {
+ return _visible;
+ }
+ set
+ {
+ _visible = value;
+ }
+ }
+ protected bool ChildControlsCreated
+ {
+ get
+ {
+ return _childControlsCreated;
+ }
+ set
+ {
+ _childControlsCreated = value;
+ }
+ }
+ protected virtual HttpContext Context
+ {
+ get
+ {
+ HttpContext context;
+ if (_context != null)
+ return _context;
+ if (_parent == null)
+ return HttpContext.Current;
+ context = _parent.Context;
+ if (context != null)
+ return context;
+ return HttpContext.Current;
+ }
+ }
+ protected EventHandlerList Events
+ {
+ get
+ {
+ EventHandlerList e = new EventHandlerList();
+ e.AddHandler(this, DataBinding);
+ e.AddHandler(this, Disposed);
+ e.AddHandler(this, Init);
+ e.AddHandler(this, Load);
+ e.AddHandler(this, PreRender);
+ e.AddHandler(this, Unload);
+ return e;
+ }
+ }
+ protected bool HasChildViewState
+ {
+ get
+ { //FIXME: Relook over this. not sure!
+ foreach (control c in _controls)
+ if (c.IsTrackingViewState) return true;
+ return false;
+ }
+ }
+ protected bool IsTrackingViewState
+ {
+ get
+ { //FIXME: ME TO!
+ return _enableViewState;
+ }
+ }
+ protected virtual StateBag ViewState
+ {
+ get
+ {
+ return _viewState;
+ }
+ }
+ protected virtual bool ViewStateIgnoresCase
+ {
+ get
+ {
+ return _viewStateIgnoreCase;
+ }
+ }
+ protected virtual void AddParsedSubObject(object obj)
+ {
+ _controls.Add(obj);
+ }
+ protected void BuildProfileTree(string parentId, bool calcViewState)
+ {
+ //TODO
+ }
+ protected void ClearChildViewState()
+ {
+ //TODO
+ //Not quite sure about this. an example clears children then calls this, so I think
+ //view state is local to the current object, not children.
+ }
+ protected virtual void CreateChildControls() {}
+ protected virtual ControlCollection CreateControlCollection()
+ {
+ _controls = new ControlCollection(this);
+ }
+ protected virtual void EnsureChildControls() {} //FIXME: I think this should be empty.
+ public virtual Control FindControl(string id)
+ {
+ int i;
+ for (i = 0; i < _controls.Count; i++)
+ if (_controls[i].ID == id) return _controls[i].ID;
+ return null;
+ }
+ protected virtual Control FindControl(string id, int pathOffset)
+ {
+ int i;
+ for (i = pathOffset; i < _controls.Count; i++)
+ if (_controls[i].ID == id) return _controls[i].ID;
+ return null;
+ }
+ protected virtual void LoadViewState(object savedState)
+ {
+ //TODO: What should I do by default?
+ }
+ protected string MapPathSecure(string virtualPath)
+ {
+ //TODO: Need to read up on security+web.
+ }
+ protected virtual bool OnBubbleEvent(object source, EventArgs args)
+ {
+ return false; //FIXME: It might throw "ItemCommand". not sure.
+ }
+ protected virtual void OnDataBinding(EventArgs e)
+ {
+ if (DataBinding != null) DataBinding(this, e);
+ }
+ protected virtual void OnInit(EventArgs e)
+ {
+ if (Init != null) Init(this, e);
+ }
+ protected virtual void OnPreRender(EventArgs e)
+ {
+ if (PreRender != null) PreRender(this, e);
+ }
+ protected virtual void OnUnload(EventArgs e)
+ {
+ if (Unload != null) Unload(this, e);
+ }
+ protected void RaiseBubbleEvent(object source, EventArgs args)
+ {
+ _parent.OnBubbleEvent(source, args); //FIXME: I think this is right. Check though.
+ }
+ protected virtual void Render(HtmlTextWriter writer) {} //FIXME: Default?
+ protected virtual void RenderChildren(HtmlTextWriter writer)
+ {
+ //if render method delegate is set, call it here. otherwise,
+ //render any child controls. just a for loop?
+ }
+ protected virtual object SaveViewState()
+ {
+ return ViewState;
+ }
+ protected virtual void TrackViewState()
+ {
+ _trackViewState = true;
+ }
+ public virtual void DataBind()
+ {
+//TODO: I think this recursively calls this method on its children.
+ }
+ public virtual void Dispose()
+ {
+ //TODO: nuke stuff.
+ if (Disposed != null) Disposed(this, e);
+ }
+
+
+
+
+ }
+}
diff --git a/mcs/class/System.Web/System.Web.UI/LiteralControl.cs b/mcs/class/System.Web/System.Web.UI/LiteralControl.cs
new file mode 100644
index 00000000000..55e01bee15a
--- /dev/null
+++ b/mcs/class/System.Web/System.Web.UI/LiteralControl.cs
@@ -0,0 +1,39 @@
+//
+// System.Web.UI.LiteralControl.cs
+//
+// Author:
+// Bob Smith <bob@thestuff.net>
+//
+// (C) Bob Smith
+//
+
+using System;
+using System.Web;
+
+namespace System.Web.UI
+{
+ public class LiteralControl : Control
+ {
+ private string _text = String.Empty;
+ public LiteralControl() {}
+ public LiteralControl(string text)
+ {
+ _text = text;
+ }
+ public virtual string Text
+ {
+ get
+ {
+ return _text;
+ }
+ set
+ {
+ _text = value;
+ }
+ }
+ public override Render(HtmlTextWriter writer)
+ {
+ writer.Write(_text);
+ }
+ }
+}
diff --git a/mcs/class/System.Web/System.Web/BeginEventHandler.cs b/mcs/class/System.Web/System.Web/BeginEventHandler.cs
new file mode 100644
index 00000000000..c2bd1ac2782
--- /dev/null
+++ b/mcs/class/System.Web/System.Web/BeginEventHandler.cs
@@ -0,0 +1,16 @@
+//
+// System.Web.BeginEventHandler.cs
+//
+// Author:
+// Bob Smith <bob@thestuff.net>
+//
+// (C) Bob Smith
+//
+
+namespace System.Web
+{
+ public delegate IAsyncResult BeginEventHandler(object sender,
+ EventArgs e,
+ AsyncCallback cb,
+ object extraData);
+}
diff --git a/mcs/class/System.Web/System.Web/ChangeLog b/mcs/class/System.Web/System.Web/ChangeLog
new file mode 100644
index 00000000000..153aa95e25e
--- /dev/null
+++ b/mcs/class/System.Web/System.Web/ChangeLog
@@ -0,0 +1,22 @@
+2001-08-16 Bob Smith <bob@thestuff.net>
+
+ * HttpCookieCollection.cs, HttpCookie.cs: Bug fixes.
+
+2001-08-09 Bob Smith <bob@thestuff.net>
+
+ * BeginEventHandler.cs: Implemented.
+ * EndEventHandler.cs: Implemented.
+ * HttpCacheability.cs: Implemented.
+ * HttpCacheRevalidation.cs: Implemented.
+ * HttpCacheValidateHandler.cs: Implemented.
+ * HttpCookieCollection.cs: Implemented.
+ * HttpCookie.cs: Implemented.
+ * HttpValidationStatus.cs: Implemented.
+ * HttpWorkerRequest.EndOfSendNotification.cs: Implemented.
+ * IHttpAsyncHandler.cs: Implemented.
+ * IHttpHandler.cs: Implemented.
+ * IHttpHandlerFactory.cs: Implemented.
+ * IHttpModule.cs: Implemented.
+ * ProcessShutdownReason.cs: Implemented.
+ * ProcessStatus.cs: Implemented.
+ * TraceMode.cs: Implemented.
diff --git a/mcs/class/System.Web/System.Web/EndEventHandler.cs b/mcs/class/System.Web/System.Web/EndEventHandler.cs
new file mode 100644
index 00000000000..cd7a51c222a
--- /dev/null
+++ b/mcs/class/System.Web/System.Web/EndEventHandler.cs
@@ -0,0 +1,13 @@
+//
+// System.Web.EndEventHandler.cs
+//
+// Author:
+// Bob Smith <bob@thestuff.net>
+//
+// (C) Bob Smith
+//
+
+namespace System.Web
+{
+ public delegate void EndEventHandler(IAsyncResult ar);
+}
diff --git a/mcs/class/System.Web/System.Web/HttpCacheRevalidation.cs b/mcs/class/System.Web/System.Web/HttpCacheRevalidation.cs
new file mode 100644
index 00000000000..c0a4038bfa5
--- /dev/null
+++ b/mcs/class/System.Web/System.Web/HttpCacheRevalidation.cs
@@ -0,0 +1,18 @@
+//
+// System.Web.HttpCacheRevalidation.cs
+//
+// Author:
+// Bob Smith <bob@thestuff.net>
+//
+// (C) Bob Smith
+//
+
+namespace System.Web
+{
+ public enum HttpCacheRevalidation
+ {
+ AllCaches,
+ None,
+ ProxyCaches
+ }
+} \ No newline at end of file
diff --git a/mcs/class/System.Web/System.Web/HttpCacheValidateHandler.cs b/mcs/class/System.Web/System.Web/HttpCacheValidateHandler.cs
new file mode 100644
index 00000000000..032aea39f6f
--- /dev/null
+++ b/mcs/class/System.Web/System.Web/HttpCacheValidateHandler.cs
@@ -0,0 +1,16 @@
+//
+// System.Web.HttpCacheValidateHandler.cs
+//
+// Author:
+// Bob Smith <bob@thestuff.net>
+//
+// (C) Bob Smith
+//
+
+namespace System.Web
+{
+ public delegate void HttpCacheValidateHandler(
+ HttpContext context,
+ object data,
+ ref HttpValidationStatus validationStatus);
+}
diff --git a/mcs/class/System.Web/System.Web/HttpCacheability.cs b/mcs/class/System.Web/System.Web/HttpCacheability.cs
new file mode 100644
index 00000000000..4a89bf89e9b
--- /dev/null
+++ b/mcs/class/System.Web/System.Web/HttpCacheability.cs
@@ -0,0 +1,19 @@
+//
+// System.Web.HttpCacheability.cs
+//
+// Author:
+// Bob Smith <bob@thestuff.net>
+//
+// (C) Bob Smith
+//
+
+namespace System.Web
+{
+ public enum HttpCacheability
+ {
+ NoCache,
+ Private,
+ Public,
+ Server
+ }
+} \ No newline at end of file
diff --git a/mcs/class/System.Web/System.Web/HttpCookie.cs b/mcs/class/System.Web/System.Web/HttpCookie.cs
new file mode 100644
index 00000000000..bc16a17cd67
--- /dev/null
+++ b/mcs/class/System.Web/System.Web/HttpCookie.cs
@@ -0,0 +1,117 @@
+//
+// System.Web.HttpCookie.cs
+//
+// Author:
+// Bob Smith <bob@thestuff.net>
+//
+// (C) Bob Smith
+//
+
+using System;
+using System.Collections.Specialized;
+
+namespace System.Web
+{
+ public sealed class HttpCookie
+ {
+ private string _name;
+ private string _value = null;
+ private string _domain; //TODO: default to some pref.
+ private DateTime _expires;
+ private string _path; //TODO: default is the current request path.
+ private bool _secure = false;
+ public HttpCookie(string name)
+ {
+ _name = name;
+ }
+ public HttpCookie(string name, string value)
+ {
+ _name = name;
+ _value = value;
+ }
+ public string Domain
+ {
+ get
+ {
+ return _domain;
+ }
+ set
+ {
+ _domain = value;
+ }
+ }
+ public DateTime Expires
+ {
+ get
+ {
+ return _expires;
+ }
+ set
+ {
+ _expires = value;
+ }
+ }
+ public bool HasKeys
+ {
+ get
+ {
+ return false; //TODO
+ }
+ }
+ public string this[string key]
+ {
+//TODO: get/set subcookie.
+ get {return "";}
+ set {}
+ }
+ public string Name
+ {
+ get
+ {
+ return _name;
+ }
+ set
+ {
+ _name = value;
+ }
+ }
+ public string Path
+ {
+ get
+ {
+ return _path;
+ }
+ set
+ {
+ _path = value;
+ }
+ }
+ public bool Secure
+ {
+ get
+ {
+ return _secure;
+ }
+ set
+ {
+ _secure = value;
+ }
+ }
+ public string Value
+ {
+ get
+ {
+ return _value;
+ }
+ set
+ {
+ _value = value;
+ }
+ }
+ public NameValueCollection Values
+ {
+//TODO
+ get {return null;}
+ }
+ }
+}
diff --git a/mcs/class/System.Web/System.Web/HttpCookieCollection.cs b/mcs/class/System.Web/System.Web/HttpCookieCollection.cs
new file mode 100644
index 00000000000..b13b38d1348
--- /dev/null
+++ b/mcs/class/System.Web/System.Web/HttpCookieCollection.cs
@@ -0,0 +1,70 @@
+//
+// System.Web.HttpCookieCollection.cs
+//
+// Author:
+// Bob Smith <bob@thestuff.net>
+//
+// (C) Bob Smith
+//
+
+using System;
+using System.Collections.Specialized;
+
+namespace System.Web
+{
+ public sealed class HttpCookieCollection : NameObjectCollectionBase
+ {
+ public HttpCookieCollection() {}
+ public string[] AllKeys
+ {
+ get
+ {
+ return this.BaseGetAllKeys();
+ }
+ }
+ public HttpCookie this[int index]
+ {
+ get
+ {
+ return (HttpCookie)(this.BaseGet(index));
+ }
+ }
+ public HttpCookie this[string name]
+ {
+ get
+ {
+ return (HttpCookie)(this.BaseGet(name));
+ }
+ }
+ public void Add(HttpCookie cookie)
+ {
+ this.BaseAdd(cookie.Name, cookie);
+ }
+ public void Clear()
+ {
+ this.BaseClear();
+ }
+ public void CopyTo(Array dest, int index)
+ {
+ int i;
+ HttpCookie cookie;
+ for(i=0; i<this.Count; i++)
+ {
+ cookie=this[i];
+ dest.SetValue(new HttpCookie(cookie.Name, cookie.Value), index+i);
+ }
+ }
+ public string GetKey(int index)
+ {
+ return this.BaseGetKey(index);
+ }
+ public void Remove(string name)
+ {
+ this.BaseRemove(name);
+ }
+ public void Set(HttpCookie cookie)
+ {
+ this.BaseSet(cookie.Name, cookie);
+ }
+ }
+}
diff --git a/mcs/class/System.Web/System.Web/HttpValidationStatus.cs b/mcs/class/System.Web/System.Web/HttpValidationStatus.cs
new file mode 100644
index 00000000000..6338b59d613
--- /dev/null
+++ b/mcs/class/System.Web/System.Web/HttpValidationStatus.cs
@@ -0,0 +1,18 @@
+//
+// System.Web.HttpValidationStatus.cs
+//
+// Author:
+// Bob Smith <bob@thestuff.net>
+//
+// (C) Bob Smith
+//
+
+namespace System.Web
+{
+ public enum HttpValidationStatus
+ {
+ IgnoreThisRequest,
+ Invalid,
+ Valid
+ }
+} \ No newline at end of file
diff --git a/mcs/class/System.Web/System.Web/HttpWorkerRequest.EndOfSendNotification.cs b/mcs/class/System.Web/System.Web/HttpWorkerRequest.EndOfSendNotification.cs
new file mode 100644
index 00000000000..d48edf0cce0
--- /dev/null
+++ b/mcs/class/System.Web/System.Web/HttpWorkerRequest.EndOfSendNotification.cs
@@ -0,0 +1,17 @@
+//
+// System.Web.HttpWorkerRequest.EndOfSendNotification.cs
+//
+// Author:
+// Bob Smith <bob@thestuff.net>
+//
+// (C) Bob Smith
+//
+
+namespace System.Web
+{
+ public class HttpWorkerRequest {
+ public delegate void EndOfSendNotification(
+ HttpWorkerRequest wr,
+ object extraData);
+ }
+}
diff --git a/mcs/class/System.Web/System.Web/IHttpAsyncHandler.cs b/mcs/class/System.Web/System.Web/IHttpAsyncHandler.cs
new file mode 100644
index 00000000000..42b13299c68
--- /dev/null
+++ b/mcs/class/System.Web/System.Web/IHttpAsyncHandler.cs
@@ -0,0 +1,19 @@
+//
+// System.Web.IHttpAsyncHandler.cs
+//
+// Author:
+// Bob Smith <bob@thestuff.net>
+//
+// (C) Bob Smith
+//
+
+namespace System.Web
+{
+ public interface IHttpAsyncHandler : IHttpHandler
+ {
+ IAsyncResult BeginProcessRequest(HttpContext context,
+ AsyncCallback cb,
+ object extraData);
+ void EndProcessRequest(IAsyncResult result);
+ }
+}
diff --git a/mcs/class/System.Web/System.Web/IHttpHandler.cs b/mcs/class/System.Web/System.Web/IHttpHandler.cs
new file mode 100644
index 00000000000..9cc39cf0281
--- /dev/null
+++ b/mcs/class/System.Web/System.Web/IHttpHandler.cs
@@ -0,0 +1,17 @@
+//
+// System.IHttpHandler.cs
+//
+// Author:
+// Bob Smith <bob@thestuff.net>
+//
+// (C) Bob Smith
+//
+
+namespace System.Web
+{
+ public interface IHttpHandler
+ {
+ bool IsReusable {get;}
+ void ProcessRequest(HttpContext context);
+ }
+}
diff --git a/mcs/class/System.Web/System.Web/IHttpHandlerFactory.cs b/mcs/class/System.Web/System.Web/IHttpHandlerFactory.cs
new file mode 100644
index 00000000000..836953d8a37
--- /dev/null
+++ b/mcs/class/System.Web/System.Web/IHttpHandlerFactory.cs
@@ -0,0 +1,20 @@
+//
+// System.Web.IHttpHandlerFactory.cs
+//
+// Author:
+// Bob Smith <bob@thestuff.net>
+//
+// (C) Bob Smith
+//
+
+namespace System.Web
+{
+ public interface IHttpHandlerFactory
+ {
+ IHttpHandler GetHandler(HttpContext context,
+ string requestType,
+ string url,
+ string pathTranslated);
+ void ReleaseHandler(IHttpHandler handler);
+ }
+}
diff --git a/mcs/class/System.Web/System.Web/IHttpModule.cs b/mcs/class/System.Web/System.Web/IHttpModule.cs
new file mode 100644
index 00000000000..a000b15049d
--- /dev/null
+++ b/mcs/class/System.Web/System.Web/IHttpModule.cs
@@ -0,0 +1,17 @@
+//
+// System.Web.IHttpModule.cs
+//
+// Author:
+// Bob Smith <bob@thestuff.net>
+//
+// (C) Bob Smith
+//
+
+namespace System.Web
+{
+ public interface IHttpModule
+ {
+ void Dispose();
+ void Init(HttpApplication context);
+ }
+}
diff --git a/mcs/class/System.Web/System.Web/NOTES b/mcs/class/System.Web/System.Web/NOTES
new file mode 100644
index 00000000000..311ff716f6c
--- /dev/null
+++ b/mcs/class/System.Web/System.Web/NOTES
@@ -0,0 +1,10 @@
+Request notes:
+It apears each http request has its own thread. Need to figure out how to deal with this with apache.
+
+Session notes:
+When a request is finished, the contents of Request.Session are serialized and dumped to the State Server.
+When a request is started, a new Request.Session is created, data is deserialized from the State Server, and the objects are placed back into Request.Session.
+The State Server is accessed via the SessionStateModule which is used for both session ID and state data management.
+HttpApplicationState instance is created the first time a url within the applications virtual directory is accessed. Its accessable through HttpContext.Application.
+HttpApplicationState needs to use lock/unlock explicitly.
+Not shared across machines or multiple processes.
diff --git a/mcs/class/System.Web/System.Web/ProcessShutdownReason.cs b/mcs/class/System.Web/System.Web/ProcessShutdownReason.cs
new file mode 100644
index 00000000000..1b8586ebc05
--- /dev/null
+++ b/mcs/class/System.Web/System.Web/ProcessShutdownReason.cs
@@ -0,0 +1,23 @@
+//
+// System.Web.ProcessShutdownReason.cs
+//
+// Author:
+// Bob Smith <bob@thestuff.net>
+//
+// (C) Bob Smith
+//
+
+namespace System.Web
+{
+ public enum ProcessShutdownReason
+ {
+ IdleTimeout,
+ MemoryLimitExceeded,
+ None,
+ PingFailed,
+ RequestQueueLimit,
+ RequestsLimit,
+ Timeout,
+ Unexpected
+ }
+} \ No newline at end of file
diff --git a/mcs/class/System.Web/System.Web/ProcessStatus.cs b/mcs/class/System.Web/System.Web/ProcessStatus.cs
new file mode 100644
index 00000000000..79066887e78
--- /dev/null
+++ b/mcs/class/System.Web/System.Web/ProcessStatus.cs
@@ -0,0 +1,19 @@
+//
+// System.Web.ProcessStatus.cs
+//
+// Author:
+// Bob Smith <bob@thestuff.net>
+//
+// (C) Bob Smith
+//
+
+namespace System.Web
+{
+ public enum ProcessStatus
+ {
+ Alive,
+ ShutDown,
+ ShuttingDown,
+ Terminated
+ }
+} \ No newline at end of file
diff --git a/mcs/class/System.Web/System.Web/TODO b/mcs/class/System.Web/System.Web/TODO
new file mode 100644
index 00000000000..fdc27344d3b
--- /dev/null
+++ b/mcs/class/System.Web/System.Web/TODO
@@ -0,0 +1,27 @@
+HttpClientCertificate
+HttpApplicationState
+HttpFileCollection
+HttpModuleCollection
+HttpException
+HttpCompileException
+HttpParseException
+HttpUnhandledException
+HttpWriter
+HttpCapabilitiesBase
+HttpBrowserCapabilities
+HttpApplication
+HttpCachePolicy
+HttpCacheVaryByHeaders
+HttpCacheVaryByParams
+HttpContext
+HttpPostedFile
+HttpRequest
+HttpResponse
+HttpRuntime
+HttpServerUtility
+HttpStaticObjectsCollection
+HttpUtility
+HttpWorkerRequest
+ProcessInfo
+ProcessModelInfo
+TraceContext
diff --git a/mcs/class/System.Web/System.Web/TraceMode.cs b/mcs/class/System.Web/System.Web/TraceMode.cs
new file mode 100644
index 00000000000..12549121110
--- /dev/null
+++ b/mcs/class/System.Web/System.Web/TraceMode.cs
@@ -0,0 +1,17 @@
+//
+// System.Web.TraceMode.cs
+//
+// Author:
+// Bob Smith <bob@thestuff.net>
+//
+// (C) Bob Smith
+//
+
+namespace System.Web
+{
+ public enum TraceMode
+ {
+ SortByCategory,
+ SortByTime
+ }
+}
diff --git a/mcs/class/System.Web/System.Web/common.src b/mcs/class/System.Web/System.Web/common.src
new file mode 100644
index 00000000000..d02c20264ba
--- /dev/null
+++ b/mcs/class/System.Web/System.Web/common.src
@@ -0,0 +1,11 @@
+BeginEventHandler.cs
+EndEventHandler.cs
+HttpCacheability.cs
+HttpCacheRevalidation.cs
+HttpCookieCollection.cs
+HttpCookie.cs
+HttpValidationStatus.cs
+HttpWorkerRequest.EndOfSendNotification.cs
+ProcessShutdownReason.cs
+ProcessStatus.cs
+TraceMode.cs
diff --git a/mcs/class/System.Web/System.Web/unix.src b/mcs/class/System.Web/System.Web/unix.src
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/mcs/class/System.Web/System.Web/unix.src
diff --git a/mcs/class/System.Web/System.Web/windows.src b/mcs/class/System.Web/System.Web/windows.src
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/mcs/class/System.Web/System.Web/windows.src
diff --git a/mcs/class/System.Web/Test/test.aspx b/mcs/class/System.Web/Test/test.aspx
new file mode 100644
index 00000000000..363fab9697f
--- /dev/null
+++ b/mcs/class/System.Web/Test/test.aspx
@@ -0,0 +1,29 @@
+<%@ page language="c#"%>
+<html>
+<head>
+<title>Test</title>
+<%Response.Write("Test");%>
+
+<script runat="server" language="c#">
+ void SubmitBtn_Click(Object sender, EventArgs e) {
+ Response.Write("Hi");
+ }
+</script>
+
+<form action="test.aspx" method="post" runat="server">
+<asp:button text="Click Me" OnClick="SubmitBtn_Click" runat="server"/>
+</form>
+
+<!-- output
+
+<html>
+<head>
+<title>Test</title>
+Test<form name="ctrl0" method="post" action="test.aspx" id="ctrl0">
+<input type="hidden" name="__VIEWSTATE" value="dDwtMTc0MDc5ODg1Mzs7Pg==" />
+
+<input type="submit" name="ctrl1" value="Click Me" />
+</form>
+
+
+--> \ No newline at end of file
diff --git a/mcs/class/System.Web/Test/test2.aspx b/mcs/class/System.Web/Test/test2.aspx
new file mode 100644
index 00000000000..0d8b0e5e947
--- /dev/null
+++ b/mcs/class/System.Web/Test/test2.aspx
@@ -0,0 +1,20 @@
+<%@ page language="c#" debug="true"%>
+<html>
+<head>
+<title>Test</title>
+<%Response.Write("Test");%>
+
+<script runat="server" language="c#">
+ void click(Object sender, EventArgs e) {
+ if(Object.Events != null)
+ Response.Write("1");
+ else
+ Response.Write("2");
+ }
+</script>
+
+<asp:label id="testing" runat="server"/>
+
+<form action="test.aspx" method="post" runat="server">
+<a OnServerClick="click" runat="server">test</a>
+</form>
diff --git a/mcs/class/System.Web/Test/test3.aspx b/mcs/class/System.Web/Test/test3.aspx
new file mode 100644
index 00000000000..d8776e45f48
--- /dev/null
+++ b/mcs/class/System.Web/Test/test3.aspx
@@ -0,0 +1,23 @@
+<%@ Page Debug="true" %>
+<html>
+<script runat=server language="vb">
+
+Sub AnchorBtn_Click(Source As Object, E as EventArgs)
+ Message.InnerText = Message.InnerHtml
+ End Sub
+
+ </script>
+
+<body>
+<form method=post runat=server>
+
+<a OnServerClick="AnchorBtn_Click" runat=server> Click here at your peril.</a>
+
+<h1>
+<span id="Message" runat=server><span id="Message2" runat=server>narf</span></span>
+</h1>
+
+</form>
+</body>
+</html>
+
diff --git a/mcs/class/System.Web/makefile b/mcs/class/System.Web/makefile
new file mode 100644
index 00000000000..2cab450711e
--- /dev/null
+++ b/mcs/class/System.Web/makefile
@@ -0,0 +1,17 @@
+DIRS= \
+ System.Web \
+ System.Web.Caching
+all:
+ @echo "You must use 'make windows' or 'make unix'."
+ @echo "'make unix' is broken for now."
+
+windows: make-list
+ $(CSC) /target:library /out:System.Web.dll /nowarn:1595 @list
+
+unix:
+ @echo "'make unix' is broken for now."
+
+make-list:
+ for i in $(DIRS); do \
+ cat $$i/common.src $$i/windows.src | sed "s/^/$$i\\\\/"; \
+ done > list
diff --git a/mcs/class/System.XML/.cvsignore b/mcs/class/System.XML/.cvsignore
new file mode 100644
index 00000000000..3be2b9a15a5
--- /dev/null
+++ b/mcs/class/System.XML/.cvsignore
@@ -0,0 +1,2 @@
+*.dll
+list
diff --git a/mcs/class/System.XML/System.Xml/Driver.cs b/mcs/class/System.XML/System.Xml/Driver.cs
new file mode 100644
index 00000000000..5d18ad29eec
--- /dev/null
+++ b/mcs/class/System.XML/System.Xml/Driver.cs
@@ -0,0 +1,57 @@
+// -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+//
+// Driver.cs
+//
+// Author:
+// Jason Diamond (jason@injektilo.org)
+//
+// (C) 2001 Jason Diamond http://injektilo.org/
+//
+
+using System;
+using System.Xml;
+
+public class Driver
+{
+ public static void Main(string[] args)
+ {
+ XmlReader xmlReader = null;
+
+ if (args.Length < 1)
+ {
+ xmlReader = new XmlTextReader(Console.In);
+ }
+ else
+ {
+ xmlReader = new XmlTextReader(args[0]);
+ }
+
+ while (xmlReader.Read())
+ {
+ Console.WriteLine("NodeType = {0}", xmlReader.NodeType);
+ Console.WriteLine(" Name = {0}", xmlReader.Name);
+ Console.WriteLine(" IsEmptyElement = {0}", xmlReader.IsEmptyElement);
+ Console.WriteLine(" HasAttributes = {0}", xmlReader.HasAttributes);
+ Console.WriteLine(" AttributeCount = {0}", xmlReader.AttributeCount);
+ Console.WriteLine(" HasValue = {0}", xmlReader.HasValue);
+ Console.WriteLine(" Value = {0}", xmlReader.Value);
+ Console.WriteLine(" Depth = {0}", xmlReader.Depth);
+
+ if (xmlReader.HasAttributes)
+ {
+ while (xmlReader.MoveToNextAttribute())
+ {
+ Console.WriteLine(" AttributeName = {0}", xmlReader.Name);
+ Console.WriteLine(" AttributeValue = {0}", xmlReader.Value);
+
+ while (xmlReader.ReadAttributeValue())
+ {
+ Console.WriteLine(" AttributeValueNodeType = {0}", xmlReader.NodeType);
+ Console.WriteLine(" AttributeValueName = {0}", xmlReader.Name);
+ Console.WriteLine(" AttributeValueValue = {0}", xmlReader.Value);
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/mcs/class/System.XML/System.Xml/IXmlLineInfo.cs b/mcs/class/System.XML/System.Xml/IXmlLineInfo.cs
new file mode 100644
index 00000000000..1c28509d4af
--- /dev/null
+++ b/mcs/class/System.XML/System.Xml/IXmlLineInfo.cs
@@ -0,0 +1,20 @@
+// -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+//
+// System.Xml.IXmlLineInfo.cs
+//
+// Author:
+// Jason Diamond (jason@injektilo.org)
+//
+// (C) 2001 Jason Diamond http://injektilo.org/
+//
+
+namespace System.Xml
+{
+ public interface IXmlLineInfo
+ {
+ int LineNumber { get; }
+ int LinePosition { get; }
+
+ bool HasLineInfo();
+ }
+}
diff --git a/mcs/class/System.XML/System.Xml/Profile.cs b/mcs/class/System.XML/System.Xml/Profile.cs
new file mode 100644
index 00000000000..d16049576d1
--- /dev/null
+++ b/mcs/class/System.XML/System.Xml/Profile.cs
@@ -0,0 +1,47 @@
+// -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+//
+// Profile.cs
+//
+// Author:
+// Jason Diamond (jason@injektilo.org)
+//
+// (C) 2001 Jason Diamond http://injektilo.org/
+//
+
+using System;
+using System.Xml;
+
+using System.IO;
+using System.Text;
+
+public class Profile
+{
+ public static void Main(string[] args)
+ {
+ XmlReader xmlReader = null;
+
+ if (args.Length < 1)
+ {
+ xmlReader = new XmlTextReader(Console.In);
+ }
+ else
+ {
+ xmlReader = new XmlTextReader(args[0]);
+ }
+
+ int nodes = 0;
+
+ DateTime start = DateTime.Now;
+
+ while (xmlReader.Read())
+ {
+ ++nodes;
+ }
+
+ DateTime end = DateTime.Now;
+
+ Console.WriteLine("time = {0}", end - start);
+
+ Console.WriteLine("nodes = {0}", nodes);
+ }
+}
diff --git a/mcs/class/System.XML/System.Xml/ReadState.cs b/mcs/class/System.XML/System.Xml/ReadState.cs
new file mode 100644
index 00000000000..373488ef51b
--- /dev/null
+++ b/mcs/class/System.XML/System.Xml/ReadState.cs
@@ -0,0 +1,21 @@
+// -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+//
+// System.Xml.ReadState.cs
+//
+// Author:
+// Jason Diamond (jason@injektilo.org)
+//
+// (C) 2001 Jason Diamond http://injektilo.org/
+//
+
+namespace System.Xml
+{
+ public enum ReadState
+ {
+ Closed,
+ EndOfFile,
+ Error,
+ Initial,
+ Interactive
+ }
+}
diff --git a/mcs/class/System.XML/System.Xml/Test.cs b/mcs/class/System.XML/System.Xml/Test.cs
new file mode 100644
index 00000000000..cac9d0c6ed7
--- /dev/null
+++ b/mcs/class/System.XML/System.Xml/Test.cs
@@ -0,0 +1,1147 @@
+// -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+//
+// System.Xml.Test.cs
+//
+// Author:
+// Jason Diamond (jason@injektilo.org)
+//
+// (C) 2001 Jason Diamond http://injektilo.org/
+//
+
+using System;
+using System.Diagnostics;
+using System.IO;
+
+using NUnit.Framework;
+
+namespace System.Xml
+{
+ public class Test : TestCase
+ {
+ public Test(string name) : base(name) { }
+
+ private void AssertStartDocument(XmlReader xmlReader)
+ {
+ Assert(xmlReader.ReadState == ReadState.Initial);
+ Assert(xmlReader.NodeType == XmlNodeType.None);
+ Assert(xmlReader.Depth == 0);
+ Assert(!xmlReader.EOF);
+ }
+
+ private void AssertNode(
+ XmlReader xmlReader,
+ XmlNodeType nodeType,
+ int depth,
+ bool isEmptyElement,
+ string name,
+ string value,
+ int attributeCount)
+ {
+ Assert(xmlReader.Read());
+ Assert(xmlReader.ReadState == ReadState.Interactive);
+ Assert(!xmlReader.EOF);
+
+ Assert(xmlReader.NodeType == nodeType);
+ Assert(xmlReader.Depth == depth);
+ Assert(xmlReader.IsEmptyElement == isEmptyElement);
+ Assert(xmlReader.Name == name);
+ Assert(xmlReader.HasValue == (value != String.Empty));
+ Assert(xmlReader.Value == value);
+ Assert(xmlReader.HasAttributes == (attributeCount > 0));
+ Assert(xmlReader.AttributeCount == attributeCount);
+ }
+
+ private void AssertAttribute(
+ XmlReader xmlReader,
+ string name,
+ string value)
+ {
+ Assert(xmlReader[name] == value);
+ Assert(xmlReader.GetAttribute(name) == value);
+ }
+
+ private void AssertEndDocument(XmlReader xmlReader)
+ {
+ Assert(!xmlReader.Read());
+ Assert(xmlReader.NodeType == XmlNodeType.None);
+ Assert(xmlReader.Depth == 0);
+ Assert(xmlReader.ReadState == ReadState.EndOfFile);
+ Assert(xmlReader.EOF);
+
+ xmlReader.Close();
+ Assert(xmlReader.ReadState == ReadState.Closed);
+ }
+
+ public void TestEmptyElement()
+ {
+ string xml = "<foo/>";
+ XmlReader xmlReader =
+ new XmlTextReader(new StringReader(xml));
+
+ AssertStartDocument(xmlReader);
+
+ AssertNode(
+ xmlReader, // xmlReader
+ XmlNodeType.Element, // nodeType
+ 0, // depth
+ true, // isEmptyElement
+ "foo", // name
+ String.Empty, // value
+ 0 // attributeCount
+ );
+
+ AssertEndDocument(xmlReader);
+ }
+
+ public void TestEmptyElementWithWhitespace()
+ {
+ string xml = "<foo />";
+ XmlReader xmlReader =
+ new XmlTextReader(new StringReader(xml));
+
+ AssertStartDocument(xmlReader);
+
+ AssertNode(
+ xmlReader, // xmlReader
+ XmlNodeType.Element, // nodeType
+ 0, //depth
+ true, // isEmptyElement
+ "foo", // name
+ String.Empty, // value
+ 0 // attributeCount
+ );
+
+ AssertEndDocument(xmlReader);
+ }
+
+ public void TestEmptyElementWithStartAndEndTag()
+ {
+ string xml = "<foo></foo>";
+ XmlReader xmlReader =
+ new XmlTextReader(new StringReader(xml));
+
+ AssertStartDocument(xmlReader);
+
+ AssertNode(
+ xmlReader, // xmlReader
+ XmlNodeType.Element, // nodeType
+ 0, //depth
+ false, // isEmptyElement
+ "foo", // name
+ String.Empty, // value
+ 0 // attributeCount
+ );
+
+ AssertNode(
+ xmlReader, // xmlReader
+ XmlNodeType.EndElement, // nodeType
+ 0, //depth
+ false, // isEmptyElement
+ "foo", // name
+ String.Empty, // value
+ 0 // attributeCount
+ );
+
+ AssertEndDocument(xmlReader);
+ }
+
+ public void TestEmptyElementWithStartAndEndTagWithWhitespace()
+ {
+ string xml = "<foo ></foo >";
+ XmlReader xmlReader =
+ new XmlTextReader(new StringReader(xml));
+
+ AssertStartDocument(xmlReader);
+
+ AssertNode(
+ xmlReader, // xmlReader
+ XmlNodeType.Element, // nodeType
+ 0, //depth
+ false, // isEmptyElement
+ "foo", // name
+ String.Empty, // value
+ 0 // attributeCount
+ );
+
+ AssertNode(
+ xmlReader, // xmlReader
+ XmlNodeType.EndElement, // nodeType
+ 0, //depth
+ false, // isEmptyElement
+ "foo", // name
+ String.Empty, // value
+ 0 // attributeCount
+ );
+
+ AssertEndDocument(xmlReader);
+ }
+
+ public void TestNestedEmptyTag()
+ {
+ string xml = "<foo><bar/></foo>";
+ XmlReader xmlReader =
+ new XmlTextReader(new StringReader(xml));
+
+ AssertStartDocument(xmlReader);
+
+ AssertNode(
+ xmlReader, // xmlReader
+ XmlNodeType.Element, // nodeType
+ 0, //depth
+ false, // isEmptyElement
+ "foo", // name
+ String.Empty, // value
+ 0 // attributeCount
+ );
+
+ AssertNode(
+ xmlReader, // xmlReader
+ XmlNodeType.Element, // nodeType
+ 1, //depth
+ true, // isEmptyElement
+ "bar", // name
+ String.Empty, // value
+ 0 // attributeCount
+ );
+
+ AssertNode(
+ xmlReader, // xmlReader
+ XmlNodeType.EndElement, // nodeType
+ 0, //depth
+ false, // isEmptyElement
+ "foo", // name
+ String.Empty, // value
+ 0 // attributeCount
+ );
+
+ AssertEndDocument(xmlReader);
+ }
+
+ public void TestNestedText()
+ {
+ string xml = "<foo>bar</foo>";
+ XmlReader xmlReader =
+ new XmlTextReader(new StringReader(xml));
+
+ AssertStartDocument(xmlReader);
+
+ AssertNode(
+ xmlReader, // xmlReader
+ XmlNodeType.Element, // nodeType
+ 0, //depth
+ false, // isEmptyElement
+ "foo", // name
+ String.Empty, // value
+ 0 // attributeCount
+ );
+
+ AssertNode(
+ xmlReader, // xmlReader
+ XmlNodeType.Text, // nodeType
+ 1, //depth
+ false, // isEmptyElement
+ String.Empty, // name
+ "bar", // value
+ 0 // attributeCount
+ );
+
+ AssertNode(
+ xmlReader, // xmlReader
+ XmlNodeType.EndElement, // nodeType
+ 0, //depth
+ false, // isEmptyElement
+ "foo", // name
+ String.Empty, // value
+ 0 // attributeCount
+ );
+
+ AssertEndDocument(xmlReader);
+ }
+
+ public void TestEmptyElementWithAttribute()
+ {
+ string xml = @"<foo bar=""baz""/>";
+ XmlReader xmlReader =
+ new XmlTextReader(new StringReader(xml));
+
+ AssertStartDocument(xmlReader);
+
+ AssertNode(
+ xmlReader, // xmlReader
+ XmlNodeType.Element, // nodeType
+ 0, //depth
+ true, // isEmptyElement
+ "foo", // name
+ String.Empty, // value
+ 1 // attributeCount
+ );
+
+ AssertAttribute(
+ xmlReader, // xmlReader
+ "bar", // name
+ "baz" // value
+ );
+
+ AssertEndDocument(xmlReader);
+ }
+
+ public void TestStartAndEndTagWithAttribute()
+ {
+ string xml = @"<foo bar='baz'></foo>";
+ XmlReader xmlReader =
+ new XmlTextReader(new StringReader(xml));
+
+ AssertStartDocument(xmlReader);
+
+ AssertNode(
+ xmlReader, // xmlReader
+ XmlNodeType.Element, // nodeType
+ 0, //depth
+ false, // isEmptyElement
+ "foo", // name
+ String.Empty, // value
+ 1 // attributeCount
+ );
+
+ AssertAttribute(
+ xmlReader, // xmlReader
+ "bar", // name
+ "baz" // value
+ );
+
+ AssertNode(
+ xmlReader, // xmlReader
+ XmlNodeType.EndElement, // nodeType
+ 0, //depth
+ false, // isEmptyElement
+ "foo", // name
+ String.Empty, // value
+ 0 // attributeCount
+ );
+
+ AssertEndDocument(xmlReader);
+ }
+
+ public void TestEmptyElementWithTwoAttributes()
+ {
+ string xml = @"<foo bar=""baz"" quux='quuux'/>";
+ XmlReader xmlReader =
+ new XmlTextReader(new StringReader(xml));
+
+ AssertStartDocument(xmlReader);
+
+ AssertNode(
+ xmlReader, // xmlReader
+ XmlNodeType.Element, // nodeType
+ 0, //depth
+ true, // isEmptyElement
+ "foo", // name
+ String.Empty, // value
+ 2 // attributeCount
+ );
+
+ AssertAttribute(
+ xmlReader, // xmlReader
+ "bar", // name
+ "baz" // value
+ );
+
+ AssertAttribute(
+ xmlReader, // xmlReader
+ "quux", // name
+ "quuux" // value
+ );
+
+ AssertEndDocument(xmlReader);
+ }
+
+ public void TestProcessingInstructionBeforeDocumentElement()
+ {
+ string xml = "<?foo bar?><baz/>";
+ XmlReader xmlReader =
+ new XmlTextReader(new StringReader(xml));
+
+ AssertStartDocument(xmlReader);
+
+ AssertNode(
+ xmlReader, // xmlReader
+ XmlNodeType.ProcessingInstruction, // nodeType
+ 0, //depth
+ false, // isEmptyElement
+ "foo", // name
+ "bar", // value
+ 0 // attributeCount
+ );
+
+ AssertNode(
+ xmlReader, // xmlReader
+ XmlNodeType.Element, // nodeType
+ 0, //depth
+ true, // isEmptyElement
+ "baz", // name
+ String.Empty, // value
+ 0 // attributeCount
+ );
+
+ AssertEndDocument(xmlReader);
+ }
+
+ public void TestCommentBeforeDocumentElement()
+ {
+ string xml = "<!--foo--><bar/>";
+ XmlReader xmlReader =
+ new XmlTextReader(new StringReader(xml));
+
+ AssertStartDocument(xmlReader);
+
+ AssertNode(
+ xmlReader, // xmlReader
+ XmlNodeType.Comment, // nodeType
+ 0, //depth
+ false, // isEmptyElement
+ String.Empty, // name
+ "foo", // value
+ 0 // attributeCount
+ );
+
+ AssertNode(
+ xmlReader, // xmlReader
+ XmlNodeType.Element, // nodeType
+ 0, //depth
+ true, // isEmptyElement
+ "bar", // name
+ String.Empty, // value
+ 0 // attributeCount
+ );
+
+ AssertEndDocument(xmlReader);
+ }
+
+ public void TestPredefinedEntities()
+ {
+ string xml = "<foo>&lt;&gt;&amp;&apos;&quot;</foo>";
+ XmlReader xmlReader =
+ new XmlTextReader(new StringReader(xml));
+
+ AssertStartDocument(xmlReader);
+
+ AssertNode(
+ xmlReader, // xmlReader
+ XmlNodeType.Element, // nodeType
+ 0, //depth
+ false, // isEmptyElement
+ "foo", // name
+ String.Empty, // value
+ 0 // attributeCount
+ );
+
+ AssertNode(
+ xmlReader, // xmlReader
+ XmlNodeType.Text, // nodeType
+ 1, //depth
+ false, // isEmptyElement
+ String.Empty, // name
+ "<>&'\"", // value
+ 0 // attributeCount
+ );
+
+ AssertNode(
+ xmlReader, // xmlReader
+ XmlNodeType.EndElement, // nodeType
+ 0, //depth
+ false, // isEmptyElement
+ "foo", // name
+ String.Empty, // value
+ 0 // attributeCount
+ );
+
+ AssertEndDocument(xmlReader);
+ }
+
+ public void TestEntityReference()
+ {
+ string xml = "<foo>&bar;</foo>";
+ XmlReader xmlReader =
+ new XmlTextReader(new StringReader(xml));
+
+ AssertStartDocument(xmlReader);
+
+ AssertNode(
+ xmlReader, // xmlReader
+ XmlNodeType.Element, // nodeType
+ 0, //depth
+ false, // isEmptyElement
+ "foo", // name
+ String.Empty, // value
+ 0 // attributeCount
+ );
+
+ AssertNode(
+ xmlReader, // xmlReader
+ XmlNodeType.EntityReference, // nodeType
+ 1, //depth
+ false, // isEmptyElement
+ "bar", // name
+ String.Empty, // value
+ 0 // attributeCount
+ );
+
+ AssertNode(
+ xmlReader, // xmlReader
+ XmlNodeType.EndElement, // nodeType
+ 0, //depth
+ false, // isEmptyElement
+ "foo", // name
+ String.Empty, // value
+ 0 // attributeCount
+ );
+
+ AssertEndDocument(xmlReader);
+ }
+
+ public void TestEntityReferenceInsideText()
+ {
+ string xml = "<foo>bar&baz;quux</foo>";
+ XmlReader xmlReader =
+ new XmlTextReader(new StringReader(xml));
+
+ AssertStartDocument(xmlReader);
+
+ AssertNode(
+ xmlReader, // xmlReader
+ XmlNodeType.Element, // nodeType
+ 0, //depth
+ false, // isEmptyElement
+ "foo", // name
+ String.Empty, // value
+ 0 // attributeCount
+ );
+
+ AssertNode(
+ xmlReader, // xmlReader
+ XmlNodeType.Text, // nodeType
+ 1, //depth
+ false, // isEmptyElement
+ String.Empty, // name
+ "bar", // value
+ 0 // attributeCount
+ );
+
+ AssertNode(
+ xmlReader, // xmlReader
+ XmlNodeType.EntityReference, // nodeType
+ 1, //depth
+ false, // isEmptyElement
+ "baz", // name
+ String.Empty, // value
+ 0 // attributeCount
+ );
+
+ AssertNode(
+ xmlReader, // xmlReader
+ XmlNodeType.Text, // nodeType
+ 1, //depth
+ false, // isEmptyElement
+ String.Empty, // name
+ "quux", // value
+ 0 // attributeCount
+ );
+
+ AssertNode(
+ xmlReader, // xmlReader
+ XmlNodeType.EndElement, // nodeType
+ 0, //depth
+ false, // isEmptyElement
+ "foo", // name
+ String.Empty, // value
+ 0 // attributeCount
+ );
+
+ AssertEndDocument(xmlReader);
+ }
+
+ public void TestCharacterReferences()
+ {
+ string xml = "<foo>&#70;&#x4F;&#x4f;</foo>";
+ XmlReader xmlReader =
+ new XmlTextReader(new StringReader(xml));
+
+ AssertStartDocument(xmlReader);
+
+ AssertNode(
+ xmlReader, // xmlReader
+ XmlNodeType.Element, // nodeType
+ 0, //depth
+ false, // isEmptyElement
+ "foo", // name
+ String.Empty, // value
+ 0 // attributeCount
+ );
+
+ AssertNode(
+ xmlReader, // xmlReader
+ XmlNodeType.Text, // nodeType
+ 1, //depth
+ false, // isEmptyElement
+ String.Empty, // name
+ "FOO", // value
+ 0 // attributeCount
+ );
+
+ AssertNode(
+ xmlReader, // xmlReader
+ XmlNodeType.EndElement, // nodeType
+ 0, //depth
+ false, // isEmptyElement
+ "foo", // name
+ String.Empty, // value
+ 0 // attributeCount
+ );
+
+ AssertEndDocument(xmlReader);
+ }
+
+ public void TestEntityReferenceInAttribute()
+ {
+ string xml = "<foo bar='&baz;'/>";
+ XmlReader xmlReader =
+ new XmlTextReader(new StringReader(xml));
+
+ AssertStartDocument(xmlReader);
+
+ AssertNode(
+ xmlReader, // xmlReader
+ XmlNodeType.Element, // nodeType
+ 0, //depth
+ true, // isEmptyElement
+ "foo", // name
+ String.Empty, // value
+ 1 // attributeCount
+ );
+
+ AssertAttribute(
+ xmlReader, // xmlReader
+ "bar", // name
+ "&baz;" // value
+ );
+
+ AssertEndDocument(xmlReader);
+ }
+
+ public void TestPredefinedEntitiesInAttribute()
+ {
+ string xml = "<foo bar='&lt;&gt;&amp;&apos;&quot;'/>";
+ XmlReader xmlReader =
+ new XmlTextReader(new StringReader(xml));
+
+ AssertStartDocument(xmlReader);
+
+ AssertNode(
+ xmlReader, // xmlReader
+ XmlNodeType.Element, // nodeType
+ 0, //depth
+ true, // isEmptyElement
+ "foo", // name
+ String.Empty, // value
+ 1 // attributeCount
+ );
+
+ AssertAttribute(
+ xmlReader, // xmlReader
+ "bar", // name
+ "<>&'\"" // value
+ );
+
+ AssertEndDocument(xmlReader);
+ }
+
+ public void TestCharacterReferencesInAttribute()
+ {
+ string xml = "<foo bar='&#70;&#x4F;&#x4f;'/>";
+ XmlReader xmlReader =
+ new XmlTextReader(new StringReader(xml));
+
+ AssertStartDocument(xmlReader);
+
+ AssertNode(
+ xmlReader, // xmlReader
+ XmlNodeType.Element, // nodeType
+ 0, //depth
+ true, // isEmptyElement
+ "foo", // name
+ String.Empty, // value
+ 1 // attributeCount
+ );
+
+ AssertAttribute(
+ xmlReader, // xmlReader
+ "bar", // name
+ "FOO" // value
+ );
+
+ AssertEndDocument(xmlReader);
+ }
+
+ public void TestCDATA()
+ {
+ string xml = "<foo><![CDATA[<>&]]></foo>";
+ XmlReader xmlReader =
+ new XmlTextReader(new StringReader(xml));
+
+ AssertStartDocument(xmlReader);
+
+ AssertNode(
+ xmlReader, // xmlReader
+ XmlNodeType.Element, // nodeType
+ 0, //depth
+ false, // isEmptyElement
+ "foo", // name
+ String.Empty, // value
+ 0 // attributeCount
+ );
+
+ AssertNode(
+ xmlReader, // xmlReader
+ XmlNodeType.CDATA, // nodeType
+ 1, //depth
+ false, // isEmptyElement
+ String.Empty, // name
+ "<>&", // value
+ 0 // attributeCount
+ );
+
+ AssertNode(
+ xmlReader, // xmlReader
+ XmlNodeType.EndElement, // nodeType
+ 0, //depth
+ false, // isEmptyElement
+ "foo", // name
+ String.Empty, // value
+ 0 // attributeCount
+ );
+
+ AssertEndDocument(xmlReader);
+ }
+
+// The following is #if'ed out because it's specific to the Mono
+// implementation and won't compile when testing Microsoft's code.
+// Feel free to turn it on if you want to test Mono's name tables.
+
+#if false
+
+ public void TestIsFirstNameChar()
+ {
+ for (int ch = 0; ch <= 0xFFFF; ++ch)
+ {
+ Assert(
+ XmlChar.IsFirstNameChar(ch) ==
+ IsFirstNameChar(ch));
+ }
+ }
+
+ public void TestIsNameChar()
+ {
+ for (int ch = 0; ch <= 0xFFFF; ++ch)
+ {
+ Assert(
+ XmlChar.IsNameChar(ch) ==
+ IsNameChar(ch));
+ }
+ }
+
+ private static bool IsFirstNameChar(int ch)
+ {
+ return
+ IsLetter(ch) ||
+ (ch == '_') ||
+ (ch == ':');
+ }
+
+ private static bool IsNameChar(int ch)
+ {
+ return
+ IsLetter(ch) ||
+ IsDigit(ch) ||
+ (ch == '.') ||
+ (ch == '-') ||
+ (ch == '_') ||
+ (ch == ':') ||
+ IsCombiningChar(ch) ||
+ IsExtender(ch);
+ }
+
+ private static bool IsLetter(int ch)
+ {
+ return
+ IsBaseChar(ch) ||
+ IsIdeographic(ch);
+ }
+
+ private static bool IsBaseChar(int ch)
+ {
+ return
+ (ch >= 0x0041 && ch <= 0x005A) ||
+ (ch >= 0x0061 && ch <= 0x007A) ||
+ (ch >= 0x00C0 && ch <= 0x00D6) ||
+ (ch >= 0x00D8 && ch <= 0x00F6) ||
+ (ch >= 0x00F8 && ch <= 0x00FF) ||
+ (ch >= 0x0100 && ch <= 0x0131) ||
+ (ch >= 0x0134 && ch <= 0x013E) ||
+ (ch >= 0x0141 && ch <= 0x0148) ||
+ (ch >= 0x014A && ch <= 0x017E) ||
+ (ch >= 0x0180 && ch <= 0x01C3) ||
+ (ch >= 0x01CD && ch <= 0x01F0) ||
+ (ch >= 0x01F4 && ch <= 0x01F5) ||
+ (ch >= 0x01FA && ch <= 0x0217) ||
+ (ch >= 0x0250 && ch <= 0x02A8) ||
+ (ch >= 0x02BB && ch <= 0x02C1) ||
+ (ch == 0x0386) ||
+ (ch >= 0x0388 && ch <= 0x038A) ||
+ (ch == 0x038C) ||
+ (ch >= 0x038E && ch <= 0x03A1) ||
+ (ch >= 0x03A3 && ch <= 0x03CE) ||
+ (ch >= 0x03D0 && ch <= 0x03D6) ||
+ (ch == 0x03DA) ||
+ (ch == 0x03DC) ||
+ (ch == 0x03DE) ||
+ (ch == 0x03E0) ||
+ (ch >= 0x03E2 && ch <= 0x03F3) ||
+ (ch >= 0x0401 && ch <= 0x040C) ||
+ (ch >= 0x040E && ch <= 0x044F) ||
+ (ch >= 0x0451 && ch <= 0x045C) ||
+ (ch >= 0x045E && ch <= 0x0481) ||
+ (ch >= 0x0490 && ch <= 0x04C4) ||
+ (ch >= 0x04C7 && ch <= 0x04C8) ||
+ (ch >= 0x04CB && ch <= 0x04CC) ||
+ (ch >= 0x04D0 && ch <= 0x04EB) ||
+ (ch >= 0x04EE && ch <= 0x04F5) ||
+ (ch >= 0x04F8 && ch <= 0x04F9) ||
+ (ch >= 0x0531 && ch <= 0x0556) ||
+ (ch == 0x0559) ||
+ (ch >= 0x0561 && ch <= 0x0586) ||
+ (ch >= 0x05D0 && ch <= 0x05EA) ||
+ (ch >= 0x05F0 && ch <= 0x05F2) ||
+ (ch >= 0x0621 && ch <= 0x063A) ||
+ (ch >= 0x0641 && ch <= 0x064A) ||
+ (ch >= 0x0671 && ch <= 0x06B7) ||
+ (ch >= 0x06BA && ch <= 0x06BE) ||
+ (ch >= 0x06C0 && ch <= 0x06CE) ||
+ (ch >= 0x06D0 && ch <= 0x06D3) ||
+ (ch == 0x06D5) ||
+ (ch >= 0x06E5 && ch <= 0x06E6) ||
+ (ch >= 0x0905 && ch <= 0x0939) ||
+ (ch == 0x093D) ||
+ (ch >= 0x0958 && ch <= 0x0961) ||
+ (ch >= 0x0985 && ch <= 0x098C) ||
+ (ch >= 0x098F && ch <= 0x0990) ||
+ (ch >= 0x0993 && ch <= 0x09A8) ||
+ (ch >= 0x09AA && ch <= 0x09B0) ||
+ (ch == 0x09B2) ||
+ (ch >= 0x09B6 && ch <= 0x09B9) ||
+ (ch >= 0x09DC && ch <= 0x09DD) ||
+ (ch >= 0x09DF && ch <= 0x09E1) ||
+ (ch >= 0x09F0 && ch <= 0x09F1) ||
+ (ch >= 0x0A05 && ch <= 0x0A0A) ||
+ (ch >= 0x0A0F && ch <= 0x0A10) ||
+ (ch >= 0x0A13 && ch <= 0x0A28) ||
+ (ch >= 0x0A2A && ch <= 0x0A30) ||
+ (ch >= 0x0A32 && ch <= 0x0A33) ||
+ (ch >= 0x0A35 && ch <= 0x0A36) ||
+ (ch >= 0x0A38 && ch <= 0x0A39) ||
+ (ch >= 0x0A59 && ch <= 0x0A5C) ||
+ (ch == 0x0A5E) ||
+ (ch >= 0x0A72 && ch <= 0x0A74) ||
+ (ch >= 0x0A85 && ch <= 0x0A8B) ||
+ (ch == 0x0A8D) ||
+ (ch >= 0x0A8F && ch <= 0x0A91) ||
+ (ch >= 0x0A93 && ch <= 0x0AA8) ||
+ (ch >= 0x0AAA && ch <= 0x0AB0) ||
+ (ch >= 0x0AB2 && ch <= 0x0AB3) ||
+ (ch >= 0x0AB5 && ch <= 0x0AB9) ||
+ (ch == 0x0ABD) ||
+ (ch == 0x0AE0) ||
+ (ch >= 0x0B05 && ch <= 0x0B0C) ||
+ (ch >= 0x0B0F && ch <= 0x0B10) ||
+ (ch >= 0x0B13 && ch <= 0x0B28) ||
+ (ch >= 0x0B2A && ch <= 0x0B30) ||
+ (ch >= 0x0B32 && ch <= 0x0B33) ||
+ (ch >= 0x0B36 && ch <= 0x0B39) ||
+ (ch == 0x0B3D) ||
+ (ch >= 0x0B5C && ch <= 0x0B5D) ||
+ (ch >= 0x0B5F && ch <= 0x0B61) ||
+ (ch >= 0x0B85 && ch <= 0x0B8A) ||
+ (ch >= 0x0B8E && ch <= 0x0B90) ||
+ (ch >= 0x0B92 && ch <= 0x0B95) ||
+ (ch >= 0x0B99 && ch <= 0x0B9A) ||
+ (ch == 0x0B9C) ||
+ (ch >= 0x0B9E && ch <= 0x0B9F) ||
+ (ch >= 0x0BA3 && ch <= 0x0BA4) ||
+ (ch >= 0x0BA8 && ch <= 0x0BAA) ||
+ (ch >= 0x0BAE && ch <= 0x0BB5) ||
+ (ch >= 0x0BB7 && ch <= 0x0BB9) ||
+ (ch >= 0x0C05 && ch <= 0x0C0C) ||
+ (ch >= 0x0C0E && ch <= 0x0C10) ||
+ (ch >= 0x0C12 && ch <= 0x0C28) ||
+ (ch >= 0x0C2A && ch <= 0x0C33) ||
+ (ch >= 0x0C35 && ch <= 0x0C39) ||
+ (ch >= 0x0C60 && ch <= 0x0C61) ||
+ (ch >= 0x0C85 && ch <= 0x0C8C) ||
+ (ch >= 0x0C8E && ch <= 0x0C90) ||
+ (ch >= 0x0C92 && ch <= 0x0CA8) ||
+ (ch >= 0x0CAA && ch <= 0x0CB3) ||
+ (ch >= 0x0CB5 && ch <= 0x0CB9) ||
+ (ch == 0x0CDE) ||
+ (ch >= 0x0CE0 && ch <= 0x0CE1) ||
+ (ch >= 0x0D05 && ch <= 0x0D0C) ||
+ (ch >= 0x0D0E && ch <= 0x0D10) ||
+ (ch >= 0x0D12 && ch <= 0x0D28) ||
+ (ch >= 0x0D2A && ch <= 0x0D39) ||
+ (ch >= 0x0D60 && ch <= 0x0D61) ||
+ (ch >= 0x0E01 && ch <= 0x0E2E) ||
+ (ch == 0x0E30) ||
+ (ch >= 0x0E32 && ch <= 0x0E33) ||
+ (ch >= 0x0E40 && ch <= 0x0E45) ||
+ (ch >= 0x0E81 && ch <= 0x0E82) ||
+ (ch == 0x0E84) ||
+ (ch >= 0x0E87 && ch <= 0x0E88) ||
+ (ch == 0x0E8A) ||
+ (ch == 0x0E8D) ||
+ (ch >= 0x0E94 && ch <= 0x0E97) ||
+ (ch >= 0x0E99 && ch <= 0x0E9F) ||
+ (ch >= 0x0EA1 && ch <= 0x0EA3) ||
+ (ch == 0x0EA5) ||
+ (ch == 0x0EA7) ||
+ (ch >= 0x0EAA && ch <= 0x0EAB) ||
+ (ch >= 0x0EAD && ch <= 0x0EAE) ||
+ (ch == 0x0EB0) ||
+ (ch >= 0x0EB2 && ch <= 0x0EB3) ||
+ (ch == 0x0EBD) ||
+ (ch >= 0x0EC0 && ch <= 0x0EC4) ||
+ (ch >= 0x0F40 && ch <= 0x0F47) ||
+ (ch >= 0x0F49 && ch <= 0x0F69) ||
+ (ch >= 0x10A0 && ch <= 0x10C5) ||
+ (ch >= 0x10D0 && ch <= 0x10F6) ||
+ (ch == 0x1100) ||
+ (ch >= 0x1102 && ch <= 0x1103) ||
+ (ch >= 0x1105 && ch <= 0x1107) ||
+ (ch == 0x1109) ||
+ (ch >= 0x110B && ch <= 0x110C) ||
+ (ch >= 0x110E && ch <= 0x1112) ||
+ (ch == 0x113C) ||
+ (ch == 0x113E) ||
+ (ch == 0x1140) ||
+ (ch == 0x114C) ||
+ (ch == 0x114E) ||
+ (ch == 0x1150) ||
+ (ch >= 0x1154 && ch <= 0x1155) ||
+ (ch == 0x1159) ||
+ (ch >= 0x115F && ch <= 0x1161) ||
+ (ch == 0x1163) ||
+ (ch == 0x1165) ||
+ (ch == 0x1167) ||
+ (ch == 0x1169) ||
+ (ch >= 0x116D && ch <= 0x116E) ||
+ (ch >= 0x1172 && ch <= 0x1173) ||
+ (ch == 0x1175) ||
+ (ch == 0x119E) ||
+ (ch == 0x11A8) ||
+ (ch == 0x11AB) ||
+ (ch >= 0x11AE && ch <= 0x11AF) ||
+ (ch >= 0x11B7 && ch <= 0x11B8) ||
+ (ch == 0x11BA) ||
+ (ch >= 0x11BC && ch <= 0x11C2) ||
+ (ch == 0x11EB) ||
+ (ch == 0x11F0) ||
+ (ch == 0x11F9) ||
+ (ch >= 0x1E00 && ch <= 0x1E9B) ||
+ (ch >= 0x1EA0 && ch <= 0x1EF9) ||
+ (ch >= 0x1F00 && ch <= 0x1F15) ||
+ (ch >= 0x1F18 && ch <= 0x1F1D) ||
+ (ch >= 0x1F20 && ch <= 0x1F45) ||
+ (ch >= 0x1F48 && ch <= 0x1F4D) ||
+ (ch >= 0x1F50 && ch <= 0x1F57) ||
+ (ch == 0x1F59) ||
+ (ch == 0x1F5B) ||
+ (ch == 0x1F5D) ||
+ (ch >= 0x1F5F && ch <= 0x1F7D) ||
+ (ch >= 0x1F80 && ch <= 0x1FB4) ||
+ (ch >= 0x1FB6 && ch <= 0x1FBC) ||
+ (ch == 0x1FBE) ||
+ (ch >= 0x1FC2 && ch <= 0x1FC4) ||
+ (ch >= 0x1FC6 && ch <= 0x1FCC) ||
+ (ch >= 0x1FD0 && ch <= 0x1FD3) ||
+ (ch >= 0x1FD6 && ch <= 0x1FDB) ||
+ (ch >= 0x1FE0 && ch <= 0x1FEC) ||
+ (ch >= 0x1FF2 && ch <= 0x1FF4) ||
+ (ch >= 0x1FF6 && ch <= 0x1FFC) ||
+ (ch == 0x2126) ||
+ (ch >= 0x212A && ch <= 0x212B) ||
+ (ch == 0x212E) ||
+ (ch >= 0x2180 && ch <= 0x2182) ||
+ (ch >= 0x3041 && ch <= 0x3094) ||
+ (ch >= 0x30A1 && ch <= 0x30FA) ||
+ (ch >= 0x3105 && ch <= 0x312C) ||
+ (ch >= 0xAC00 && ch <= 0xD7A3);
+ }
+
+ private static bool IsIdeographic(int ch)
+ {
+ return
+ (ch >= 0x4E00 && ch <= 0x9FA5) ||
+ (ch == 0x3007) ||
+ (ch >= 0x3021 && ch <= 0x3029);
+ }
+
+ private static bool IsDigit(int ch)
+ {
+ return
+ (ch >= 0x0030 && ch <= 0x0039) ||
+ (ch >= 0x0660 && ch <= 0x0669) ||
+ (ch >= 0x06F0 && ch <= 0x06F9) ||
+ (ch >= 0x0966 && ch <= 0x096F) ||
+ (ch >= 0x09E6 && ch <= 0x09EF) ||
+ (ch >= 0x0A66 && ch <= 0x0A6F) ||
+ (ch >= 0x0AE6 && ch <= 0x0AEF) ||
+ (ch >= 0x0B66 && ch <= 0x0B6F) ||
+ (ch >= 0x0BE7 && ch <= 0x0BEF) ||
+ (ch >= 0x0C66 && ch <= 0x0C6F) ||
+ (ch >= 0x0CE6 && ch <= 0x0CEF) ||
+ (ch >= 0x0D66 && ch <= 0x0D6F) ||
+ (ch >= 0x0E50 && ch <= 0x0E59) ||
+ (ch >= 0x0ED0 && ch <= 0x0ED9) ||
+ (ch >= 0x0F20 && ch <= 0x0F29);
+ }
+
+ private static bool IsCombiningChar(int ch)
+ {
+ return
+ (ch >= 0x0300 && ch <= 0x0345) ||
+ (ch >= 0x0360 && ch <= 0x0361) ||
+ (ch >= 0x0483 && ch <= 0x0486) ||
+ (ch >= 0x0591 && ch <= 0x05A1) ||
+ (ch >= 0x05A3 && ch <= 0x05B9) ||
+ (ch >= 0x05BB && ch <= 0x05BD) ||
+ (ch == 0x05BF) ||
+ (ch >= 0x05C1 && ch <= 0x05C2) ||
+ (ch == 0x05C4) ||
+ (ch >= 0x064B && ch <= 0x0652) ||
+ (ch == 0x0670) ||
+ (ch >= 0x06D6 && ch <= 0x06DC) ||
+ (ch >= 0x06DD && ch <= 0x06DF) ||
+ (ch >= 0x06E0 && ch <= 0x06E4) ||
+ (ch >= 0x06E7 && ch <= 0x06E8) ||
+ (ch >= 0x06EA && ch <= 0x06ED) ||
+ (ch >= 0x0901 && ch <= 0x0903) ||
+ (ch == 0x093C) ||
+ (ch >= 0x093E && ch <= 0x094C) ||
+ (ch == 0x094D) ||
+ (ch >= 0x0951 && ch <= 0x0954) ||
+ (ch >= 0x0962 && ch <= 0x0963) ||
+ (ch >= 0x0981 && ch <= 0x0983) ||
+ (ch == 0x09BC) ||
+ (ch == 0x09BE) ||
+ (ch == 0x09BF) ||
+ (ch >= 0x09C0 && ch <= 0x09C4) ||
+ (ch >= 0x09C7 && ch <= 0x09C8) ||
+ (ch >= 0x09CB && ch <= 0x09CD) ||
+ (ch == 0x09D7) ||
+ (ch >= 0x09E2 && ch <= 0x09E3) ||
+ (ch == 0x0A02) ||
+ (ch == 0x0A3C) ||
+ (ch == 0x0A3E) ||
+ (ch == 0x0A3F) ||
+ (ch >= 0x0A40 && ch <= 0x0A42) ||
+ (ch >= 0x0A47 && ch <= 0x0A48) ||
+ (ch >= 0x0A4B && ch <= 0x0A4D) ||
+ (ch >= 0x0A70 && ch <= 0x0A71) ||
+ (ch >= 0x0A81 && ch <= 0x0A83) ||
+ (ch == 0x0ABC) ||
+ (ch >= 0x0ABE && ch <= 0x0AC5) ||
+ (ch >= 0x0AC7 && ch <= 0x0AC9) ||
+ (ch >= 0x0ACB && ch <= 0x0ACD) ||
+ (ch >= 0x0B01 && ch <= 0x0B03) ||
+ (ch == 0x0B3C) ||
+ (ch >= 0x0B3E && ch <= 0x0B43) ||
+ (ch >= 0x0B47 && ch <= 0x0B48) ||
+ (ch >= 0x0B4B && ch <= 0x0B4D) ||
+ (ch >= 0x0B56 && ch <= 0x0B57) ||
+ (ch >= 0x0B82 && ch <= 0x0B83) ||
+ (ch >= 0x0BBE && ch <= 0x0BC2) ||
+ (ch >= 0x0BC6 && ch <= 0x0BC8) ||
+ (ch >= 0x0BCA && ch <= 0x0BCD) ||
+ (ch == 0x0BD7) ||
+ (ch >= 0x0C01 && ch <= 0x0C03) ||
+ (ch >= 0x0C3E && ch <= 0x0C44) ||
+ (ch >= 0x0C46 && ch <= 0x0C48) ||
+ (ch >= 0x0C4A && ch <= 0x0C4D) ||
+ (ch >= 0x0C55 && ch <= 0x0C56) ||
+ (ch >= 0x0C82 && ch <= 0x0C83) ||
+ (ch >= 0x0CBE && ch <= 0x0CC4) ||
+ (ch >= 0x0CC6 && ch <= 0x0CC8) ||
+ (ch >= 0x0CCA && ch <= 0x0CCD) ||
+ (ch >= 0x0CD5 && ch <= 0x0CD6) ||
+ (ch >= 0x0D02 && ch <= 0x0D03) ||
+ (ch >= 0x0D3E && ch <= 0x0D43) ||
+ (ch >= 0x0D46 && ch <= 0x0D48) ||
+ (ch >= 0x0D4A && ch <= 0x0D4D) ||
+ (ch == 0x0D57) ||
+ (ch == 0x0E31) ||
+ (ch >= 0x0E34 && ch <= 0x0E3A) ||
+ (ch >= 0x0E47 && ch <= 0x0E4E) ||
+ (ch == 0x0EB1) ||
+ (ch >= 0x0EB4 && ch <= 0x0EB9) ||
+ (ch >= 0x0EBB && ch <= 0x0EBC) ||
+ (ch >= 0x0EC8 && ch <= 0x0ECD) ||
+ (ch >= 0x0F18 && ch <= 0x0F19) ||
+ (ch == 0x0F35) ||
+ (ch == 0x0F37) ||
+ (ch == 0x0F39) ||
+ (ch == 0x0F3E) ||
+ (ch == 0x0F3F) ||
+ (ch >= 0x0F71 && ch <= 0x0F84) ||
+ (ch >= 0x0F86 && ch <= 0x0F8B) ||
+ (ch >= 0x0F90 && ch <= 0x0F95) ||
+ (ch == 0x0F97) ||
+ (ch >= 0x0F99 && ch <= 0x0FAD) ||
+ (ch >= 0x0FB1 && ch <= 0x0FB7) ||
+ (ch == 0x0FB9) ||
+ (ch >= 0x20D0 && ch <= 0x20DC) ||
+ (ch == 0x20E1) ||
+ (ch >= 0x302A && ch <= 0x302F) ||
+ (ch == 0x3099) ||
+ (ch == 0x309A);
+ }
+
+ private static bool IsExtender(int ch)
+ {
+ return
+ (ch == 0x00B7) ||
+ (ch == 0x02D0) ||
+ (ch == 0x02D1) ||
+ (ch == 0x0387) ||
+ (ch == 0x0640) ||
+ (ch == 0x0E46) ||
+ (ch == 0x0EC6) ||
+ (ch == 0x3005) ||
+ (ch >= 0x3031 && ch <= 0x3035) ||
+ (ch >= 0x309D && ch <= 0x309E) ||
+ (ch >= 0x30FC && ch <= 0x30FE);
+ }
+
+#endif
+
+ public void TestIsName()
+ {
+ Assert(XmlReader.IsName("foo"));
+ Assert(!XmlReader.IsName("1foo"));
+ Assert(!XmlReader.IsName(" foo"));
+ }
+
+ public void TestIsNameToken()
+ {
+ Assert(XmlReader.IsNameToken("foo"));
+ Assert(XmlReader.IsNameToken("1foo"));
+ Assert(!XmlReader.IsNameToken(" foo"));
+ }
+ }
+}
diff --git a/mcs/class/System.XML/System.Xml/WhitespaceHandling.cs b/mcs/class/System.XML/System.Xml/WhitespaceHandling.cs
new file mode 100644
index 00000000000..895bf8b2fb5
--- /dev/null
+++ b/mcs/class/System.XML/System.Xml/WhitespaceHandling.cs
@@ -0,0 +1,19 @@
+// -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+//
+// System.Xml.WhitespaceHandling.cs
+//
+// Author:
+// Jason Diamond (jason@injektilo.org)
+//
+// (C) 2001 Jason Diamond http://injektilo.org/
+//
+
+namespace System.Xml
+{
+ public enum WhitespaceHandling
+ {
+ All,
+ None,
+ Signifigant
+ }
+}
diff --git a/mcs/class/System.XML/System.Xml/XmlChar.cs b/mcs/class/System.XML/System.Xml/XmlChar.cs
new file mode 100644
index 00000000000..2ea00dd8572
--- /dev/null
+++ b/mcs/class/System.XML/System.Xml/XmlChar.cs
@@ -0,0 +1,200 @@
+// -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+//
+// System.Xml.XmlChar.cs
+//
+// Author:
+// Jason Diamond (jason@injektilo.org)
+//
+// (C) 2001 Jason Diamond http://injektilo.org/
+//
+
+namespace System.Xml
+{
+ internal class XmlChar
+ {
+ internal static bool IsWhitespace(int ch)
+ {
+ return ch == 0x20 || ch == 0x9 || ch == 0xD || ch == 0xA;
+ }
+
+ internal static bool IsFirstNameChar(int ch)
+ {
+ bool result = false;
+
+ if (ch >= 0 && ch <= 0xFFFF)
+ {
+ result = (nameBitmap[(firstNamePages[ch >> 8] << 3) + ((ch & 0xFF) >> 5)] & (1 << (ch & 0x1F))) != 0;
+ }
+
+ return result;
+ }
+
+ internal static bool IsNameChar(int ch)
+ {
+ bool result = false;
+
+ if (ch >= 0 && ch <= 0xFFFF)
+ {
+ result = (nameBitmap[(namePages[ch >> 8] << 3) + ((ch & 0xFF) >> 5)] & (1 << (ch & 0x1F))) != 0;
+ }
+
+ return result;
+ }
+
+ private static byte[] firstNamePages =
+ {
+ 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x00,
+ 0x00, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
+ 0x10, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x13,
+ 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x15, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x17,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x18,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ };
+
+ private static byte[] namePages =
+ {
+ 0x19, 0x03, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x00,
+ 0x00, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25,
+ 0x10, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x13,
+ 0x26, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x27, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x17,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x18,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ };
+
+ private static uint[] nameBitmap =
+ {
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0x00000000, 0x04000000, 0x87FFFFFE, 0x07FFFFFE,
+ 0x00000000, 0x00000000, 0xFF7FFFFF, 0xFF7FFFFF,
+ 0xFFFFFFFF, 0x7FF3FFFF, 0xFFFFFDFE, 0x7FFFFFFF,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFE00F, 0xFC31FFFF,
+ 0x00FFFFFF, 0x00000000, 0xFFFF0000, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xF80001FF, 0x00000003, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0xFFFFD740, 0xFFFFFFFB, 0x547F7FFF, 0x000FFFFD,
+ 0xFFFFDFFE, 0xFFFFFFFF, 0xDFFEFFFF, 0xFFFFFFFF,
+ 0xFFFF0003, 0xFFFFFFFF, 0xFFFF199F, 0x033FCFFF,
+ 0x00000000, 0xFFFE0000, 0x027FFFFF, 0xFFFFFFFE,
+ 0x0000007F, 0x00000000, 0xFFFF0000, 0x000707FF,
+ 0x00000000, 0x07FFFFFE, 0x000007FE, 0xFFFE0000,
+ 0xFFFFFFFF, 0x7CFFFFFF, 0x002F7FFF, 0x00000060,
+ 0xFFFFFFE0, 0x23FFFFFF, 0xFF000000, 0x00000003,
+ 0xFFF99FE0, 0x03C5FDFF, 0xB0000000, 0x00030003,
+ 0xFFF987E0, 0x036DFDFF, 0x5E000000, 0x001C0000,
+ 0xFFFBAFE0, 0x23EDFDFF, 0x00000000, 0x00000001,
+ 0xFFF99FE0, 0x23CDFDFF, 0xB0000000, 0x00000003,
+ 0xD63DC7E0, 0x03BFC718, 0x00000000, 0x00000000,
+ 0xFFFDDFE0, 0x03EFFDFF, 0x00000000, 0x00000003,
+ 0xFFFDDFE0, 0x03EFFDFF, 0x40000000, 0x00000003,
+ 0xFFFDDFE0, 0x03FFFDFF, 0x00000000, 0x00000003,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0xFFFFFFFE, 0x000D7FFF, 0x0000003F, 0x00000000,
+ 0xFEF02596, 0x200D6CAE, 0x0000001F, 0x00000000,
+ 0x00000000, 0x00000000, 0xFFFFFEFF, 0x000003FF,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0xFFFFFFFF, 0xFFFF003F, 0x007FFFFF,
+ 0x0007DAED, 0x50000000, 0x82315001, 0x002C62AB,
+ 0x40000000, 0xF580C900, 0x00000007, 0x02010800,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0x0FFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x03FFFFFF,
+ 0x3F3FFFFF, 0xFFFFFFFF, 0xAAFF3F3F, 0x3FFFFFFF,
+ 0xFFFFFFFF, 0x5FDFFFFF, 0x0FCF1FDC, 0x1FDC1FFF,
+ 0x00000000, 0x00004C40, 0x00000000, 0x00000000,
+ 0x00000007, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000080, 0x000003FE, 0xFFFFFFFE, 0xFFFFFFFF,
+ 0x001FFFFF, 0xFFFFFFFE, 0xFFFFFFFF, 0x07FFFFFF,
+ 0xFFFFFFE0, 0x00001FFF, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0x0000003F, 0x00000000, 0x00000000,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0x0000000F, 0x00000000, 0x00000000,
+ 0x00000000, 0x07FF6000, 0x87FFFFFE, 0x07FFFFFE,
+ 0x00000000, 0x00800000, 0xFF7FFFFF, 0xFF7FFFFF,
+ 0x00FFFFFF, 0x00000000, 0xFFFF0000, 0xFFFFFFFF,
+ 0xFFFFFFFF, 0xF80001FF, 0x00030003, 0x00000000,
+ 0xFFFFFFFF, 0xFFFFFFFF, 0x0000003F, 0x00000003,
+ 0xFFFFD7C0, 0xFFFFFFFB, 0x547F7FFF, 0x000FFFFD,
+ 0xFFFFDFFE, 0xFFFFFFFF, 0xDFFEFFFF, 0xFFFFFFFF,
+ 0xFFFF007B, 0xFFFFFFFF, 0xFFFF199F, 0x033FCFFF,
+ 0x00000000, 0xFFFE0000, 0x027FFFFF, 0xFFFFFFFE,
+ 0xFFFE007F, 0xBBFFFFFB, 0xFFFF0016, 0x000707FF,
+ 0x00000000, 0x07FFFFFE, 0x0007FFFF, 0xFFFF03FF,
+ 0xFFFFFFFF, 0x7CFFFFFF, 0xFFEF7FFF, 0x03FF3DFF,
+ 0xFFFFFFEE, 0xF3FFFFFF, 0xFF1E3FFF, 0x0000FFCF,
+ 0xFFF99FEE, 0xD3C5FDFF, 0xB080399F, 0x0003FFCF,
+ 0xFFF987E4, 0xD36DFDFF, 0x5E003987, 0x001FFFC0,
+ 0xFFFBAFEE, 0xF3EDFDFF, 0x00003BBF, 0x0000FFC1,
+ 0xFFF99FEE, 0xF3CDFDFF, 0xB0C0398F, 0x0000FFC3,
+ 0xD63DC7EC, 0xC3BFC718, 0x00803DC7, 0x0000FF80,
+ 0xFFFDDFEE, 0xC3EFFDFF, 0x00603DDF, 0x0000FFC3,
+ 0xFFFDDFEC, 0xC3EFFDFF, 0x40603DDF, 0x0000FFC3,
+ 0xFFFDDFEC, 0xC3FFFDFF, 0x00803DCF, 0x0000FFC3,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0xFFFFFFFE, 0x07FF7FFF, 0x03FF7FFF, 0x00000000,
+ 0xFEF02596, 0x3BFF6CAE, 0x03FF3F5F, 0x00000000,
+ 0x03000000, 0xC2A003FF, 0xFFFFFEFF, 0xFFFE03FF,
+ 0xFEBF0FDF, 0x02FE3FFF, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x1FFF0000, 0x00000002,
+ 0x000000A0, 0x003EFFFE, 0xFFFFFFFE, 0xFFFFFFFF,
+ 0x661FFFFF, 0xFFFFFFFE, 0xFFFFFFFF, 0x77FFFFFF
+ };
+ }
+}
diff --git a/mcs/class/System.XML/System.Xml/XmlNameTable.cs b/mcs/class/System.XML/System.Xml/XmlNameTable.cs
new file mode 100644
index 00000000000..4f0df67af64
--- /dev/null
+++ b/mcs/class/System.XML/System.Xml/XmlNameTable.cs
@@ -0,0 +1,20 @@
+// -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+//
+// System.Xml.XmlNameTable.cs
+//
+// Author:
+// Jason Diamond (jason@injektilo.org)
+//
+// (C) 2001 Jason Diamond http://injektilo.org/
+//
+
+namespace System.Xml
+{
+ public abstract class XmlNameTable
+ {
+ public abstract string Add(string name);
+ public abstract string Add(char[] buffer, int offset, int length);
+ public abstract string Get(string name);
+ public abstract string Get(char[] buffer, int offset, int length);
+ }
+}
diff --git a/mcs/class/System.XML/System.Xml/XmlNamespaceManager.cs b/mcs/class/System.XML/System.Xml/XmlNamespaceManager.cs
new file mode 100644
index 00000000000..2c9a4a0c738
--- /dev/null
+++ b/mcs/class/System.XML/System.Xml/XmlNamespaceManager.cs
@@ -0,0 +1,22 @@
+// -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+//
+// System.Xml.XmlNamespaceManager.cs
+//
+// Author:
+// Jason Diamond (jason@injektilo.org)
+//
+// (C) 2001 Jason Diamond http://injektilo.org/
+//
+
+using System.Collections;
+
+namespace System.Xml
+{
+ public class XmlNamespaceManager : IEnumerable
+ {
+ public IEnumerator GetEnumerator()
+ {
+ return null;
+ }
+ }
+}
diff --git a/mcs/class/System.XML/System.Xml/XmlNodeType.cs b/mcs/class/System.XML/System.Xml/XmlNodeType.cs
new file mode 100644
index 00000000000..a01c34ee65b
--- /dev/null
+++ b/mcs/class/System.XML/System.Xml/XmlNodeType.cs
@@ -0,0 +1,34 @@
+// -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+//
+// System.Xml.XmlNodeType.cs
+//
+// Author:
+// Jason Diamond (jason@injektilo.org)
+//
+// (C) 2001 Jason Diamond http://injektilo.org/
+//
+
+namespace System.Xml
+{
+ public enum XmlNodeType
+ {
+ Attribute,
+ CDATA,
+ Comment,
+ Document,
+ DocumentFragment,
+ DocumentType,
+ Element,
+ EndElement,
+ EndEntity,
+ Entity,
+ EntityReference,
+ None,
+ Notation,
+ ProcessingInstruction,
+ SignifigantWhitespace,
+ Text,
+ Whitespace,
+ XmlDeclaration
+ }
+}
diff --git a/mcs/class/System.XML/System.Xml/XmlParserContext.cs b/mcs/class/System.XML/System.Xml/XmlParserContext.cs
new file mode 100644
index 00000000000..a88f579c077
--- /dev/null
+++ b/mcs/class/System.XML/System.Xml/XmlParserContext.cs
@@ -0,0 +1,127 @@
+// -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+//
+// System.Xml.XmlParserContext.cs
+//
+// Author:
+// Jason Diamond (jason@injektilo.org)
+//
+// (C) 2001 Jason Diamond http://injektilo.org/
+//
+
+namespace System.Xml
+{
+ public class XmlParserContext
+ {
+ // constructors
+
+ public XmlParserContext(
+ XmlNameTable nameTable,
+ XmlNamespaceManager namespaceManager,
+ string xmlLang,
+ XmlSpace xmlSpace) :
+
+ this(
+ nameTable,
+ namespaceManager,
+ null,
+ null,
+ null,
+ null,
+ null,
+ xmlLang,
+ xmlSpace
+ )
+ {
+ }
+
+ public XmlParserContext(
+ XmlNameTable nameTable,
+ XmlNamespaceManager namespaceManager,
+ string docTypeName,
+ string publicID,
+ string systemID,
+ string internalSubset,
+ string baseURI,
+ string xmlLang,
+ XmlSpace xmlSpace)
+ {
+ this.nameTable = nameTable;
+ this.namespaceManager = namespaceManager;
+ this.docTypeName = docTypeName;
+ this.publicID = publicID;
+ this.systemID = systemID;
+ this.internalSubset = internalSubset;
+ this.baseURI = baseURI;
+ this.xmlLang = xmlLang;
+ this.xmlSpace = xmlSpace;
+ }
+
+ // properties
+
+ public string BaseURI
+ {
+ get { return baseURI; }
+ set { baseURI = value; }
+ }
+
+ public string DocTypeName
+ {
+ get { return docTypeName; }
+ set { docTypeName = value; }
+ }
+
+ public string InternalSubset
+ {
+ get { return internalSubset; }
+ set { internalSubset = value; }
+ }
+
+ public XmlNamespaceManager NamespaceManager
+ {
+ get { return namespaceManager; }
+ set { namespaceManager = value; }
+ }
+
+ public XmlNameTable NameTable
+ {
+ get { return nameTable; }
+ set { nameTable = nameTable; }
+ }
+
+ public string PublicId
+ {
+ get { return publicID; }
+ set { publicID = value; }
+ }
+
+ public string SystemId
+ {
+ get { return systemID; }
+ set { systemID = value; }
+ }
+
+ public string XmlLang
+ {
+ get { return xmlLang; }
+ set { xmlLang = value; }
+ }
+
+ public XmlSpace XmlSpace
+ {
+ get { return xmlSpace; }
+ set { xmlSpace = value; }
+ }
+
+ // privates
+
+ private string baseURI;
+ private string docTypeName;
+ private string internalSubset;
+ private XmlNamespaceManager namespaceManager;
+ private XmlNameTable nameTable;
+ private string publicID;
+ private string systemID;
+ private string xmlLang;
+ private XmlSpace xmlSpace;
+ }
+}
diff --git a/mcs/class/System.XML/System.Xml/XmlReader.cs b/mcs/class/System.XML/System.Xml/XmlReader.cs
new file mode 100644
index 00000000000..e386b819593
--- /dev/null
+++ b/mcs/class/System.XML/System.Xml/XmlReader.cs
@@ -0,0 +1,238 @@
+// -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+//
+// System.Xml.XmlReader.cs
+//
+// Author:
+// Jason Diamond (jason@injektilo.org)
+//
+// (C) 2001 Jason Diamond http://injektilo.org/
+//
+
+namespace System.Xml
+{
+ public abstract class XmlReader
+ {
+ // properties
+
+ public abstract int AttributeCount { get; }
+
+ public abstract string BaseURI { get; }
+
+ public virtual bool CanResolveEntity
+ {
+ get
+ {
+ return false;
+ }
+ }
+
+ public abstract int Depth { get; }
+
+ public abstract bool EOF { get; }
+
+ public virtual bool HasAttributes
+ {
+ get
+ {
+ return AttributeCount > 0;
+ }
+ }
+
+ public abstract bool HasValue { get; }
+
+ public abstract bool IsDefault { get; }
+
+ public abstract bool IsEmptyElement { get; }
+
+ public abstract string this[int i] { get; }
+
+ public abstract string this[string name] { get; }
+
+ public abstract string this[
+ string localName,
+ string namespaceName]
+ { get; }
+
+ public abstract string LocalName { get; }
+
+ public abstract string Name { get; }
+
+ public abstract string NamespaceURI { get; }
+
+ public abstract XmlNameTable NameTable { get; }
+
+ public abstract XmlNodeType NodeType { get; }
+
+ public abstract string Prefix { get; }
+
+ public abstract char QuoteChar { get; }
+
+ public abstract ReadState ReadState { get; }
+
+ public abstract string Value { get; }
+
+ public abstract string XmlLang { get; }
+
+ public abstract XmlSpace XmlSpace { get; }
+
+ // methods
+
+ public abstract void Close();
+
+ public abstract string GetAttribute(int i);
+
+ public abstract string GetAttribute(string name);
+
+ public abstract string GetAttribute(
+ string localName,
+ string namespaceName);
+
+ public static bool IsName(string s)
+ {
+ bool result = false;
+
+ if (s != null && s.Length > 0)
+ {
+ char[] chars = s.ToCharArray();
+
+ if (XmlChar.IsFirstNameChar(chars[0]))
+ {
+ int i = 1;
+ int n = chars.Length;
+
+ while (i < n && XmlChar.IsNameChar(chars[i]))
+ {
+ ++i;
+ }
+
+ result = i == n;
+ }
+ }
+
+ return result;
+ }
+
+ public static bool IsNameToken(string s)
+ {
+ bool result = false;
+
+ if (s != null && s.Length > 0)
+ {
+ char[] chars = s.ToCharArray();
+
+ int i = 0;
+ int n = chars.Length;
+
+ while (i < n && XmlChar.IsNameChar(chars[i]))
+ {
+ ++i;
+ }
+
+ result = i == n;
+ }
+
+ return result;
+ }
+
+ public virtual bool IsStartElement()
+ {
+ // TODO: implement me.
+ return false;
+ }
+
+ public virtual bool IsStartElement(string name)
+ {
+ // TODO: implement me.
+ return false;
+ }
+
+ public virtual bool IsStartElement(
+ string localName,
+ string namespaceName)
+ {
+ // TODO: implement me.
+ return false;
+ }
+
+ public abstract string LookupNamespace(string prefix);
+
+ public abstract void MoveToAttribute(int i);
+
+ public abstract bool MoveToAttribute(string name);
+
+ public abstract bool MoveToAttribute(
+ string localName,
+ string namespaceName);
+
+ public virtual XmlNodeType MoveToContent()
+ {
+ // TODO: implement me.
+ return XmlNodeType.None;
+ }
+
+ public abstract bool MoveToElement();
+
+ public abstract bool MoveToFirstAttribute();
+
+ public abstract bool MoveToNextAttribute();
+
+ public abstract bool Read();
+
+ public abstract bool ReadAttributeValue();
+
+ public virtual string ReadElementString()
+ {
+ // TODO: implement me.
+ return null;
+ }
+
+ public virtual string ReadElementString(string name)
+ {
+ // TODO: implement me.
+ return null;
+ }
+
+ public virtual string ReadElementString(
+ string localName,
+ string namespaceName)
+ {
+ // TODO: implement me.
+ return null;
+ }
+
+ public virtual void ReadEndElement()
+ {
+ // TODO: implement me.
+ }
+
+ public abstract string ReadInnerXml();
+
+ public abstract string ReadOuterXml();
+
+ public virtual void ReadStartElement()
+ {
+ // TODO: implement me.
+ }
+
+ public virtual void ReadStartElement(string name)
+ {
+ // TODO: implement me.
+ }
+
+ public virtual void ReadStartElement(
+ string localName,
+ string namespaceName)
+ {
+ // TODO: implement me.
+ }
+
+ public abstract string ReadString();
+
+ public abstract void ResolveEntity();
+
+ public virtual void Skip()
+ {
+ // TODO: implement me.
+ }
+ }
+}
diff --git a/mcs/class/System.XML/System.Xml/XmlResolver.cs b/mcs/class/System.XML/System.Xml/XmlResolver.cs
new file mode 100644
index 00000000000..9b3c541bacf
--- /dev/null
+++ b/mcs/class/System.XML/System.Xml/XmlResolver.cs
@@ -0,0 +1,29 @@
+// -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+//
+// System.Xml.XmlResolver.cs
+//
+// Author:
+// Jason Diamond (jason@injektilo.org)
+//
+// (C) 2001 Jason Diamond http://injektilo.org/
+//
+
+using System;
+using System.Net;
+
+namespace System.Xml
+{
+ public abstract class XmlResolver
+ {
+ public abstract ICredentials Credentials { set; }
+
+ public abstract object GetEntity(
+ Uri absoluteUri,
+ string role,
+ Type type);
+
+ public abstract Uri ResolveUri(
+ Uri baseUri,
+ string relativeUri);
+ }
+}
diff --git a/mcs/class/System.XML/System.Xml/XmlSpace.cs b/mcs/class/System.XML/System.Xml/XmlSpace.cs
new file mode 100644
index 00000000000..18f753ce584
--- /dev/null
+++ b/mcs/class/System.XML/System.Xml/XmlSpace.cs
@@ -0,0 +1,19 @@
+// -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+//
+// System.Xml.XmlSpace.cs
+//
+// Author:
+// Jason Diamond (jason@injektilo.org)
+//
+// (C) 2001 Jason Diamond http://injektilo.org/
+//
+
+namespace System.Xml
+{
+ public enum XmlSpace
+ {
+ Default,
+ None,
+ Preserve
+ }
+}
diff --git a/mcs/class/System.XML/System.Xml/XmlTextReader.cs b/mcs/class/System.XML/System.Xml/XmlTextReader.cs
new file mode 100644
index 00000000000..8fa9e7b266f
--- /dev/null
+++ b/mcs/class/System.XML/System.Xml/XmlTextReader.cs
@@ -0,0 +1,1254 @@
+// -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+//
+// System.Xml.XmlTextReader.cs
+//
+// Author:
+// Jason Diamond (jason@injektilo.org)
+//
+// (C) 2001 Jason Diamond http://injektilo.org/
+//
+
+// FIXME:
+// This can only parse basic XML: elements, attributes, processing
+// instructions, and comments are OK but there's no support for
+// namespaces yet.
+//
+// It barfs on DOCTYPE declarations.
+//
+// There's also no checking being done for either well-formedness
+// or validity.
+//
+// ParserContext and NameTables aren't being used yet.
+//
+// Some thought needs to be given to performance. There's too many
+// strings being allocated.
+//
+// None of the MoveTo methods have been implemented yet.
+//
+// LineNumber and LinePosition aren't being tracked.
+//
+// xml:space, xml:lang, and xml:base aren't being tracked.
+//
+// Depth isn't being tracked.
+
+using System;
+using System.Collections;
+using System.IO;
+using System.Net;
+using System.Text;
+
+namespace System.Xml
+{
+ public class XmlTextReader : XmlReader, IXmlLineInfo
+ {
+ // constructors
+
+ protected XmlTextReader()
+ {
+ Init();
+ }
+
+ public XmlTextReader(Stream input)
+ {
+ Init();
+ reader = new StreamReader(
+ input,
+ Encoding.UTF8,
+ true);
+ }
+
+ public XmlTextReader(string url)
+ {
+ Init();
+ WebClient client = new WebClient();
+ reader = new StreamReader(
+ client.OpenRead(url),
+ Encoding.UTF8,
+ true);
+ }
+
+ public XmlTextReader(TextReader input)
+ {
+ Init();
+ reader = input;
+ }
+
+ public XmlTextReader(Stream input, XmlNameTable nameTable)
+ {
+ // TODO: implement me.
+ throw new NotImplementedException();
+ }
+
+ public XmlTextReader(string baseURI, Stream input)
+ {
+ // TODO: implement me.
+ throw new NotImplementedException();
+ }
+
+ public XmlTextReader(string baseURI, TextReader input)
+ {
+ // TODO: implement me.
+ throw new NotImplementedException();
+ }
+
+ public XmlTextReader(string url, XmlNameTable nameTable)
+ {
+ // TODO: implement me.
+ throw new NotImplementedException();
+ }
+
+ public XmlTextReader(
+ TextReader input,
+ XmlNameTable nameTable)
+ {
+ // TODO: implement me.
+ throw new NotImplementedException();
+ }
+
+ public XmlTextReader(
+ Stream inputFragment,
+ XmlNodeType fragmentType,
+ XmlParserContext context)
+ {
+ // TODO: implement me.
+ throw new NotImplementedException();
+ }
+
+ public XmlTextReader(
+ string baseURI,
+ Stream input,
+ XmlNameTable nameTable)
+ {
+ // TODO: implement me.
+ throw new NotImplementedException();
+ }
+
+ public XmlTextReader(
+ string baseURI,
+ TextReader input,
+ XmlNameTable nameTable)
+ {
+ // TODO: implement me.
+ throw new NotImplementedException();
+ }
+
+ public XmlTextReader(
+ string fragment,
+ XmlNodeType fragmentType,
+ XmlParserContext context)
+ {
+ // TODO: implement me.
+ throw new NotImplementedException();
+ }
+
+ // properties
+
+ public override int AttributeCount
+ {
+ get
+ {
+ return attributes.Count;
+ }
+ }
+
+ public override string BaseURI
+ {
+ get
+ {
+ // TODO: implement me.
+ return null;
+ }
+ }
+
+ public override bool CanResolveEntity
+ {
+ get
+ {
+ // XmlTextReaders don't resolve entities.
+ return false;
+ }
+ }
+
+ public override int Depth
+ {
+ get
+ {
+ // TODO: implement me.
+ return depth > 0 ? depth : 0;
+ }
+ }
+
+ public Encoding Encoding
+ {
+ get
+ {
+ // TODO: implement me.
+ return null;
+ }
+ }
+
+ public override bool EOF
+ {
+ get
+ {
+ return
+ readState == ReadState.EndOfFile ||
+ readState == ReadState.Closed;
+ }
+ }
+
+ public override bool HasValue
+ {
+ get
+ {
+ return value != String.Empty;
+ }
+ }
+
+ public override bool IsDefault
+ {
+ get
+ {
+ // XmlTextReader does not expand default attributes.
+ return false;
+ }
+ }
+
+ public override bool IsEmptyElement
+ {
+ get
+ {
+ return isEmptyElement;
+ }
+ }
+
+ public override string this[int i]
+ {
+ get
+ {
+ return GetAttribute(i);
+ }
+ }
+
+ public override string this[string name]
+ {
+ get
+ {
+ return GetAttribute(name);
+ }
+ }
+
+ public override string this[
+ string localName,
+ string namespaceName]
+ {
+ get
+ {
+ return GetAttribute(localName, namespaceName);
+ }
+ }
+
+ public int LineNumber
+ {
+ get
+ {
+ // TODO: implement me.
+ return 0;
+ }
+ }
+
+ public int LinePosition
+ {
+ get
+ {
+ // TODO: implement me.
+ return 0;
+ }
+ }
+
+ public override string LocalName
+ {
+ get
+ {
+ // TODO: implement me.
+ return null;
+ }
+ }
+
+ public override string Name
+ {
+ get
+ {
+ return name;
+ }
+ }
+
+ public bool Namespaces
+ {
+ get
+ {
+ // TODO: implement me.
+ return false;
+ }
+
+ set
+ {
+ // TODO: implement me.
+ }
+ }
+
+ public override string NamespaceURI
+ {
+ get
+ {
+ // TODO: implement me.
+ return null;
+ }
+ }
+
+ public override XmlNameTable NameTable
+ {
+ get
+ {
+ // TODO: implement me.
+ return null;
+ }
+ }
+
+ public override XmlNodeType NodeType
+ {
+ get
+ {
+ return nodeType;
+ }
+ }
+
+ public bool Normalization
+ {
+ get
+ {
+ // TODO: implement me.
+ return false;
+ }
+
+ set
+ {
+ // TODO: implement me.
+ }
+ }
+
+ public override string Prefix
+ {
+ get
+ {
+ // TODO: implement me.
+ return null;
+ }
+ }
+
+ public override char QuoteChar
+ {
+ get
+ {
+ // TODO: implement me.
+ return '"';
+ }
+ }
+
+ public override ReadState ReadState
+ {
+ get
+ {
+ return readState;
+ }
+ }
+
+ public override string Value
+ {
+ get
+ {
+ return value;
+ }
+ }
+
+ public WhitespaceHandling WhitespaceHandling
+ {
+ get
+ {
+ // TODO: implement me.
+ return WhitespaceHandling.All;
+ }
+
+ set
+ {
+ // TODO: implement me.
+ }
+ }
+
+ public override string XmlLang
+ {
+ get
+ {
+ // TODO: implement me.
+ return null;
+ }
+ }
+
+ public XmlResolver XmlResolver
+ {
+ set
+ {
+ // TODO: implement me.
+ }
+ }
+
+ public override XmlSpace XmlSpace
+ {
+ get
+ {
+ // TODO: implement me.
+ return XmlSpace.Default;
+ }
+ }
+
+ // methods
+
+ public override void Close()
+ {
+ readState = ReadState.Closed;
+ }
+
+ public override string GetAttribute(int i)
+ {
+ // TODO: implement me.
+ return null;
+ }
+
+ public override string GetAttribute(string name)
+ {
+ return (string)attributes[name];
+ }
+
+ public override string GetAttribute(
+ string localName,
+ string namespaceName)
+ {
+ // TODO: implement me.
+ return null;
+ }
+
+ public TextReader GetRemainder()
+ {
+ // TODO: implement me.
+ return null;
+ }
+
+ // Why does this use explicit interface implementation?
+ bool IXmlLineInfo.HasLineInfo()
+ {
+ // TODO: implement me.
+ return false;
+ }
+
+ public override string LookupNamespace(string prefix)
+ {
+ // TODO: implement me.
+ return null;
+ }
+
+ public override void MoveToAttribute(int i)
+ {
+ // TODO: implement me.
+ }
+
+ public override bool MoveToAttribute(string name)
+ {
+ // TODO: implement me.
+ return false;
+ }
+
+ public override bool MoveToAttribute(
+ string localName,
+ string namespaceName)
+ {
+ // TODO: implement me.
+ return false;
+ }
+
+ public override bool MoveToElement()
+ {
+ // TODO: implement me.
+ return false;
+ }
+
+ public override bool MoveToFirstAttribute()
+ {
+ // TODO: implement me.
+ return false;
+ }
+
+ public override bool MoveToNextAttribute()
+ {
+ // TODO: implement me.
+ return false;
+ }
+
+ public override bool Read()
+ {
+ bool more = false;
+
+ readState = ReadState.Interactive;
+
+ more = ReadContent();
+
+ return more;
+ }
+
+ public override bool ReadAttributeValue()
+ {
+ // TODO: implement me.
+ return false;
+ }
+
+ public int ReadBase64(byte[] buffer, int offset, int length)
+ {
+ // TODO: implement me.
+ return 0;
+ }
+
+ public int ReadBinHex(byte[] buffer, int offset, int length)
+ {
+ // TODO: implement me.
+ return 0;
+ }
+
+ public int ReadChars(char[] buffer, int offset, int length)
+ {
+ // TODO: implement me.
+ return 0;
+ }
+
+ public override string ReadInnerXml()
+ {
+ // TODO: implement me.
+ return null;
+ }
+
+ public override string ReadOuterXml()
+ {
+ // TODO: implement me.
+ return null;
+ }
+
+ public override string ReadString()
+ {
+ // TODO: implement me.
+ return null;
+ }
+
+ public override void ResolveEntity()
+ {
+ // XmlTextReaders don't resolve entities.
+ throw new InvalidOperationException("XmlTextReaders don't resolve entities.");
+ }
+
+ // privates
+
+ private TextReader reader;
+ private ReadState readState;
+
+ private int depth;
+ private bool depthDown;
+
+ private XmlNodeType nodeType;
+ private string name;
+ private bool isEmptyElement;
+ private string value;
+ private Hashtable attributes;
+
+ private bool returnEntityReference;
+ private string entityReferenceName;
+
+ private char[] nameBuffer;
+ private int nameLength;
+ private int nameCapacity;
+ private const int initialNameCapacity = 256;
+
+ private char[] valueBuffer;
+ private int valueLength;
+ private int valueCapacity;
+ private const int initialValueCapacity = 8192;
+
+ private void Init()
+ {
+ readState = ReadState.Initial;
+
+ depth = -1;
+ depthDown = false;
+
+ nodeType = XmlNodeType.None;
+ name = String.Empty;
+ isEmptyElement = false;
+ value = String.Empty;
+ attributes = new Hashtable();
+
+ returnEntityReference = false;
+ entityReferenceName = String.Empty;
+
+ nameBuffer = new char[initialNameCapacity];
+ nameLength = 0;
+ nameCapacity = initialNameCapacity;
+
+ valueBuffer = new char[initialValueCapacity];
+ valueLength = 0;
+ valueCapacity = initialValueCapacity;
+ }
+
+ // Use this method rather than setting the properties
+ // directly so that all the necessary properties can
+ // be changed in harmony with each other. Maybe the
+ // fields should be in a seperate class to help enforce
+ // this.
+ private void SetProperties(
+ XmlNodeType nodeType,
+ string name,
+ bool isEmptyElement,
+ string value,
+ bool clearAttributes)
+ {
+ this.nodeType = nodeType;
+ this.name = name;
+ this.isEmptyElement = isEmptyElement;
+ this.value = value;
+
+ if (clearAttributes)
+ {
+ ClearAttributes();
+ }
+ }
+
+ private void AddAttribute(string name, string value)
+ {
+ attributes.Add(name, value);
+ }
+
+ private void ClearAttributes()
+ {
+ if (attributes.Count > 0)
+ {
+ attributes.Clear();
+ }
+ }
+
+ private int PeekChar()
+ {
+ return reader.Peek();
+ }
+
+ private int ReadChar()
+ {
+ return reader.Read();
+ }
+
+ // This should really keep track of some state so
+ // that it's not possible to have more than one document
+ // element or text outside of the document element.
+ private bool ReadContent()
+ {
+ bool more = false;
+
+ if (depthDown)
+ {
+ --depth;
+ }
+
+ if (returnEntityReference)
+ {
+ ++depth;
+ SetEntityReferenceProperties();
+ more = true;
+ }
+ else
+ {
+ switch (PeekChar())
+ {
+ case '<':
+ ReadChar();
+ ReadTag();
+ more = true;
+ break;
+ case -1:
+ readState = ReadState.EndOfFile;
+ SetProperties(
+ XmlNodeType.None, // nodeType
+ String.Empty, // name
+ false, // isEmptyElement
+ String.Empty, // value
+ true // clearAttributes
+ );
+ more = false;
+ break;
+ default:
+ ReadText();
+ more = true;
+ break;
+ }
+ }
+
+ return more;
+ }
+
+ private void SetEntityReferenceProperties()
+ {
+ SetProperties(
+ XmlNodeType.EntityReference, // nodeType
+ entityReferenceName, // name
+ false, // isEmptyElement
+ String.Empty, // value
+ true // clearAttributes
+ );
+
+ returnEntityReference = false;
+ entityReferenceName = String.Empty;
+ }
+
+ // The leading '<' has already been consumed.
+ private void ReadTag()
+ {
+ switch (PeekChar())
+ {
+ case '/':
+ ReadChar();
+ ReadEndTag();
+ break;
+ case '?':
+ ReadChar();
+ ReadProcessingInstruction();
+ break;
+ case '!':
+ ReadChar();
+ ReadDeclaration();
+ break;
+ default:
+ ReadStartTag();
+ break;
+ }
+ }
+
+ // The leading '<' has already been consumed.
+ private void ReadStartTag()
+ {
+ string name = ReadName();
+ SkipWhitespace();
+
+ bool isEmptyElement = false;
+
+ ClearAttributes();
+
+ if (XmlChar.IsFirstNameChar(PeekChar()))
+ {
+ ReadAttributes();
+ }
+
+ if (PeekChar() == '/')
+ {
+ ReadChar();
+ isEmptyElement = true;
+ depthDown = true;
+ }
+
+ Expect('>');
+
+ ++depth;
+
+ SetProperties(
+ XmlNodeType.Element, // nodeType
+ name, // name
+ isEmptyElement, // isEmptyElement
+ String.Empty, // value
+ false // clearAttributes
+ );
+ }
+
+ // The reader is positioned on the first character
+ // of the element's name.
+ private void ReadEndTag()
+ {
+ string name = ReadName();
+ SkipWhitespace();
+ Expect('>');
+
+ --depth;
+
+ SetProperties(
+ XmlNodeType.EndElement, // nodeType
+ name, // name
+ false, // isEmptyElement
+ String.Empty, // value
+ true // clearAttributes
+ );
+ }
+
+ private void AppendNameChar(int ch)
+ {
+ CheckNameCapacity();
+ nameBuffer[nameLength++] = (char)ch;
+ }
+
+ private void CheckNameCapacity()
+ {
+ if (nameLength == nameCapacity)
+ {
+ nameCapacity = nameCapacity * 2;
+ char[] oldNameBuffer = nameBuffer;
+ nameBuffer = new char[nameCapacity];
+ Array.Copy(oldNameBuffer, nameBuffer, nameLength);
+ }
+ }
+
+ private string CreateNameString()
+ {
+ return new String(nameBuffer, 0, nameLength);
+ }
+
+ private void AppendValueChar(int ch)
+ {
+ CheckValueCapacity();
+ valueBuffer[valueLength++] = (char)ch;
+ }
+
+ private void CheckValueCapacity()
+ {
+ if (valueLength == valueCapacity)
+ {
+ valueCapacity = valueCapacity * 2;
+ char[] oldValueBuffer = valueBuffer;
+ valueBuffer = new char[valueCapacity];
+ Array.Copy(oldValueBuffer, valueBuffer, valueLength);
+ }
+ }
+
+ private string CreateValueString()
+ {
+ return new String(valueBuffer, 0, valueLength);
+ }
+
+ // The reader is positioned on the first character
+ // of the text.
+ private void ReadText()
+ {
+ valueLength = 0;
+
+ int ch = PeekChar();
+
+ while (ch != '<' && ch != -1)
+ {
+ if (ch == '&')
+ {
+ ReadChar();
+
+ if (ReadReference(false))
+ {
+ break;
+ }
+ }
+ else
+ {
+ AppendValueChar(ReadChar());
+ }
+
+ ch = PeekChar();
+ }
+
+ if (returnEntityReference && valueLength == 0)
+ {
+ ++depth;
+ SetEntityReferenceProperties();
+ }
+ else
+ {
+ if (depth >= 0)
+ {
+ ++depth;
+ depthDown = true;
+ }
+
+ SetProperties(
+ XmlNodeType.Text, // nodeType
+ String.Empty, // name
+ false, // isEmptyElement
+ CreateValueString(), // value
+ true // clearAttributes
+ );
+ }
+ }
+
+ // The leading '&' has already been consumed.
+ // Returns true if the entity reference isn't a simple
+ // character reference or one of the predefined entities.
+ // This allows the ReadText method to break so that the
+ // next call to Read will return the EntityReference node.
+ private bool ReadReference(bool ignoreEntityReferences)
+ {
+ if (PeekChar() == '#')
+ {
+ ReadChar();
+ ReadCharacterReference();
+ }
+ else
+ {
+ ReadEntityReference(ignoreEntityReferences);
+ }
+
+ return returnEntityReference;
+ }
+
+ private void ReadCharacterReference()
+ {
+ int value = 0;
+
+ if (PeekChar() == 'x')
+ {
+ ReadChar();
+
+ while (PeekChar() != ';' && PeekChar() != -1)
+ {
+ int ch = ReadChar();
+
+ if (ch >= '0' && ch <= '9')
+ {
+ value = (value << 4) + ch - '0';
+ }
+ else if (ch >= 'A' && ch <= 'F')
+ {
+ value = (value << 4) + ch - 'A' + 10;
+ }
+ else if (ch >= 'a' && ch <= 'f')
+ {
+ value = (value << 4) + ch - 'a' + 10;
+ }
+ else
+ {
+ throw new Exception(
+ String.Format(
+ "invalid hexadecimal digit: {0} (#x{1:X})",
+ (char)ch,
+ ch));
+ }
+ }
+ }
+ else
+ {
+ while (PeekChar() != ';' && PeekChar() != -1)
+ {
+ int ch = ReadChar();
+
+ if (ch >= '0' && ch <= '9')
+ {
+ value = value * 10 + ch - '0';
+ }
+ else
+ {
+ throw new Exception(
+ String.Format(
+ "invalid decimal digit: {0} (#x{1:X})",
+ (char)ch,
+ ch));
+ }
+ }
+ }
+
+ ReadChar(); // ';'
+
+ AppendValueChar(value);
+ }
+
+ private void ReadEntityReference(bool ignoreEntityReferences)
+ {
+ nameLength = 0;
+
+ int ch = PeekChar();
+
+ while (ch != ';' && ch != -1)
+ {
+ AppendNameChar(ReadChar());
+ ch = PeekChar();
+ }
+
+ Expect(';');
+
+ string name = CreateNameString();
+
+ switch (name)
+ {
+ case "lt":
+ AppendValueChar('<');
+ break;
+ case "gt":
+ AppendValueChar('>');
+ break;
+ case "amp":
+ AppendValueChar('&');
+ break;
+ case "apos":
+ AppendValueChar('\'');
+ break;
+ case "quot":
+ AppendValueChar('"');
+ break;
+ default:
+ if (ignoreEntityReferences)
+ {
+ AppendValueChar('&');
+
+ foreach (char ch2 in name)
+ {
+ AppendValueChar(ch2);
+ }
+
+ AppendValueChar(';');
+ }
+ else
+ {
+ returnEntityReference = true;
+ entityReferenceName = name;
+ }
+ break;
+ }
+ }
+
+ // The reader is positioned on the first character of
+ // the attribute name.
+ private void ReadAttributes()
+ {
+ do
+ {
+ string name = ReadName();
+ SkipWhitespace();
+ Expect('=');
+ SkipWhitespace();
+ string value = ReadAttribute();
+ SkipWhitespace();
+
+ AddAttribute(name, value);
+ }
+ while (PeekChar() != '/' && PeekChar() != '>' && PeekChar() != -1);
+ }
+
+ // The reader is positioned on the quote character.
+ private string ReadAttribute()
+ {
+ int quoteChar = ReadChar();
+
+ if (quoteChar != '\'' && quoteChar != '\"')
+ {
+ throw new Exception("an attribute value was not quoted");
+ }
+
+ valueLength = 0;
+
+ while (PeekChar() != quoteChar)
+ {
+ int ch = ReadChar();
+
+ switch (ch)
+ {
+ case '<':
+ throw new Exception("attribute values cannot contain '<'");
+ case '&':
+ ReadReference(true);
+ break;
+ case -1:
+ throw new Exception("unexpected end of file in an attribute value");
+ default:
+ AppendValueChar(ch);
+ break;
+ }
+ }
+
+ ReadChar(); // quoteChar
+
+ return CreateValueString();
+ }
+
+ // The reader is positioned on the first character
+ // of the target.
+ private void ReadProcessingInstruction()
+ {
+ string target = ReadName();
+ SkipWhitespace();
+
+ valueLength = 0;
+
+ while (PeekChar() != -1)
+ {
+ int ch = ReadChar();
+
+ if (ch == '?' && PeekChar() == '>')
+ {
+ ReadChar();
+ break;
+ }
+
+ AppendValueChar((char)ch);
+ }
+
+ SetProperties(
+ XmlNodeType.ProcessingInstruction, // nodeType
+ target, // name
+ false, // isEmptyElement
+ CreateValueString(), // value
+ true // clearAttributes
+ );
+ }
+
+ // The reader is positioned on the first character after
+ // the leading '<!'.
+ private void ReadDeclaration()
+ {
+ int ch = PeekChar();
+
+ switch (ch)
+ {
+ case '-':
+ Expect('-');
+ Expect('-');
+ ReadComment();
+ break;
+ case '[':
+ ReadChar();
+ Expect('C');
+ Expect('D');
+ Expect('A');
+ Expect('T');
+ Expect('A');
+ Expect('[');
+ ReadCDATA();
+ break;
+ }
+ }
+
+ // The reader is positioned on the first character after
+ // the leading '<!--'.
+ private void ReadComment()
+ {
+ valueLength = 0;
+
+ while (PeekChar() != -1)
+ {
+ int ch = ReadChar();
+
+ if (ch == '-' && PeekChar() == '-')
+ {
+ ReadChar();
+
+ if (PeekChar() != '>')
+ {
+ throw new Exception("comments cannot contain '--'");
+ }
+
+ ReadChar();
+ break;
+ }
+
+ AppendValueChar((char)ch);
+ }
+
+ SetProperties(
+ XmlNodeType.Comment, // nodeType
+ String.Empty, // name
+ false, // isEmptyElement
+ CreateValueString(), // value
+ true // clearAttributes
+ );
+ }
+
+ // The reader is positioned on the first character after
+ // the leading '<![CDATA['.
+ private void ReadCDATA()
+ {
+ valueLength = 0;
+
+ while (PeekChar() != -1)
+ {
+ int ch = ReadChar();
+
+ if (ch == ']' && PeekChar() == ']')
+ {
+ ch = ReadChar(); // ']'
+
+ if (PeekChar() == '>')
+ {
+ ReadChar(); // '>'
+ break;
+ }
+ else
+ {
+ AppendValueChar(']');
+ AppendValueChar(']');
+ ch = ReadChar();
+ }
+ }
+
+ AppendValueChar((char)ch);
+ }
+
+ ++depth;
+
+ SetProperties(
+ XmlNodeType.CDATA, // nodeType
+ String.Empty, // name
+ false, // isEmptyElement
+ CreateValueString(), // value
+ true // clearAttributes
+ );
+ }
+
+ // The reader is positioned on the first character
+ // of the name.
+ private string ReadName()
+ {
+ if (!XmlChar.IsFirstNameChar(PeekChar()))
+ {
+ throw new Exception("a name did not start with a legal character");
+ }
+
+ nameLength = 0;
+
+ AppendNameChar(ReadChar());
+
+ while (XmlChar.IsNameChar(PeekChar()))
+ {
+ AppendNameChar(ReadChar());
+ }
+
+ return CreateNameString();
+ }
+
+ // Read the next character and compare it against the
+ // specified character.
+ private void Expect(int expected)
+ {
+ int ch = ReadChar();
+
+ if (ch != expected)
+ {
+ throw new Exception(String.Format(
+ "expected '{0}' ({1:X}) but found '{2}' ({3:X})",
+ (char)expected,
+ expected,
+ (char)ch,
+ ch));
+ }
+ }
+
+ // Does not consume the first non-whitespace character.
+ private void SkipWhitespace()
+ {
+ while (XmlChar.IsWhitespace(PeekChar()))
+ {
+ ReadChar();
+ }
+ }
+ }
+}
diff --git a/mcs/class/System.XML/System.Xml/common.src b/mcs/class/System.XML/System.Xml/common.src
new file mode 100644
index 00000000000..23146df6dd3
--- /dev/null
+++ b/mcs/class/System.XML/System.Xml/common.src
@@ -0,0 +1,12 @@
+IXmlLineInfo.cs
+ReadState.cs
+WhitespaceHandling.cs
+XmlChar.cs
+XmlNamespaceManager.cs
+XmlNameTable.cs
+XmlNodeType.cs
+XmlParserContext.cs
+XmlReader.cs
+XmlResolver.cs
+XmlSpace.cs
+XmlTextReader.cs
diff --git a/mcs/class/System.XML/System.Xml/unix.src b/mcs/class/System.XML/System.Xml/unix.src
new file mode 100755
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/mcs/class/System.XML/System.Xml/unix.src
diff --git a/mcs/class/System.XML/System.Xml/windows.src b/mcs/class/System.XML/System.Xml/windows.src
new file mode 100755
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/mcs/class/System.XML/System.Xml/windows.src
diff --git a/mcs/class/System.XML/makefile b/mcs/class/System.XML/makefile
new file mode 100644
index 00000000000..aaf25b4c1f9
--- /dev/null
+++ b/mcs/class/System.XML/makefile
@@ -0,0 +1,16 @@
+DIRS=System.Xml
+
+all:
+ @echo "You must use 'make windows' or 'make unix'."
+ @echo "'make unix' is broken for now."
+
+windows: make-list
+ $(CSC) /target:library /out:System.XML.dll /nowarn:1595 @list
+
+unix:
+ @echo "'make unix' is broken for now."
+
+make-list:
+ for i in $(DIRS); do \
+ cat $$i/common.src $$i/windows.src | sed "s/^/$$i\\\\/"; \
+ done > list
diff --git a/mcs/class/System/.cvsignore b/mcs/class/System/.cvsignore
new file mode 100644
index 00000000000..c5f30212276
--- /dev/null
+++ b/mcs/class/System/.cvsignore
@@ -0,0 +1,2 @@
+System.dll
+list
diff --git a/mcs/class/System/System.CodeDom.Compiler/ChangeLog b/mcs/class/System/System.CodeDom.Compiler/ChangeLog
new file mode 100755
index 00000000000..8462e3c2fc2
--- /dev/null
+++ b/mcs/class/System/System.CodeDom.Compiler/ChangeLog
@@ -0,0 +1,5 @@
+2001-07-15 Sean MacIsaac <macisaac@ximian.com>
+
+ * CodeGenerator.cs: moved using statement out of namespace
+ declaration.
+
diff --git a/mcs/class/System/System.CodeDom.Compiler/CodeGenerator.cs b/mcs/class/System/System.CodeDom.Compiler/CodeGenerator.cs
new file mode 100755
index 00000000000..00525b3bcd2
--- /dev/null
+++ b/mcs/class/System/System.CodeDom.Compiler/CodeGenerator.cs
@@ -0,0 +1,237 @@
+//
+// System.CodeDom.Compiler CodeGenerator class
+//
+// Author:
+// Miguel de Icaza (miguel@ximian.com)
+//
+// (C) 2001 Ximian, Inc.
+//
+
+using System.CodeDom;
+using System.Reflection;
+using System.IO;
+
+namespace System.CodeDom.Compiler {
+
+ public abstract class CodeGenerator : ICodeGenerator {
+ protected TextWriter output;
+
+ protected virtual void ContinueOnNewLine (string st)
+ {
+ }
+
+ CodeGenerator ()
+ {
+ indent = 8;
+ }
+
+ //
+ // Code Generation methods
+ //
+ protected abstract void GenerateArrayCreateExpression (CodeArrayCreateExpression e);
+ protected abstract void GenerateAssignStatement (CodeAssignStatement s);
+ protected abstract void GenerateAttachEventStatement (CodeAttachEventStatement s);
+ protected abstract void GenerateBaseReferenceExpression (CodeBaseReferenceExpression e);
+ protected abstract void GenerateBinaryOperatorExpression (CodeBinaryOperatorExpression x);
+ protected abstract void GenerateCastExpression (CodeCastExpression x);
+ protected abstract void GenerateClasses (CodeNamespace x);
+ protected abstract void GenerateCommentStatement (CodeCommentStatement x);
+ protected abstract void GenerateConstructor (CodeConstructor x, CodeTypeDeclaration c);
+ protected abstract void GenerateDelegateCreateExpression (CodeDelegateCreateExpression x);
+ protected abstract void GenerateDelegateInvokeExpression (CodeDelegateInvokeExpression x);
+ protected abstract void GenerateEvent (CodeMemberEvent x, CodeTypeDeclaration c);
+ protected abstract void GenerateExpression (CodeExpression x);
+ protected abstract void GenerateField (CodeMemberField x);
+ protected abstract void GenerateFieldReferenceExpression (CodeFieldReferenceExpression x);
+ protected abstract void GenerateIndexerExpression (CodeIndexerExpression x);
+ protected abstract void GenerateLinePragmaStart (CodeLinePragma x);
+ protected abstract void GenerateLinePragmaEnd (CodeLinePragma x);
+ protected abstract void GenerateMethod (CodeMemberMethod m, CodeTypeDeclaration c);
+ protected abstract void GenerateMethodInvokeExpression (CodeMethodInvokeExpression x);
+ protected abstract void GenerateMethodReturnStatement (CodeMethodReturnStatement x);
+ protected abstract void GenerateNamespace (CodeNamespace x);
+ protected abstract void GenerateNamespaceStart (CodeNamespace x);
+ protected abstract void GenerateNamespaceEnd (CodeNamespace x);
+ protected abstract void GenerateNamespaceImport (CodeNamespaceImport i);
+ protected abstract void GenerateNamespaceImports (CodeNamespace i);
+ protected abstract void GenerateObjectCreateExpression (CodeObjectCreateExpression x);
+ protected abstract void GenerateParameterDeclarationExpression (CodeParameterDeclarationExpression x);
+ protected abstract void GeneratePrimitiveExpression (CodePrimitiveExpression x);
+ protected abstract void GenerateProperty (CodeMemberProperty e, CodeTypeDeclaration c);
+ protected abstract void GeneratePropertyReferenceExpression (CodePropertyReferenceExpression x);
+ protected abstract void GenerateStatement (CodeStatement x);
+ protected abstract void GenerateStatementCollection (CodeStatementCollection x);
+ protected abstract void GenerateThisReferenceExpression (CodeThisReferenceExpression x);
+ protected abstract void GenerateThrowExceptionStatement (CodeThrowExceptionStatement x);
+ protected abstract void GenerateTryCatchFinallyStatement (CodeTryCatchFinallyStatement x);
+ protected abstract void GenerateTypeOfExpression (CodeTypeOfExpression x);
+ protected abstract void GenerateTypeReferenceExpression (CodeTypeReferenceExpression x);
+ protected abstract void GenerateVariableDeclarationStatement (CodeVariableDeclarationStatement x);
+
+ //
+ // Other members
+ //
+ protected abstract string GetNullToken ();
+
+ public abstract bool IsValidIdentifier (string value);
+
+ public static bool IsValidLanguateIndependentIdentifier (string value)
+ {
+ /* FIXME: implement */
+ return true;
+ }
+
+ //
+ // Output functions
+ //
+ protected virtual void OutputAttributeArgument (CodeAttributeArgument arg)
+ {
+ }
+
+ protected virtual void OutputDirection (FieldDirection dir)
+ {
+ }
+
+ protected virtual void OutputExpressionList (CodeExpressionCollection c)
+ {
+ }
+
+ protected virtual void OutputExpressionLIst (CodeExpressionCollection c, bool useNewlines)
+ {
+ }
+
+ protected virtual void OutputFieldScopeModifier (MemberAttributes attrs)
+ {
+ }
+
+ protected virtual void OutputIdentifier (string ident)
+ {
+ }
+
+ protected virtual void OutputMemberAccessModifier (MemberAttributes attrs)
+ {
+ }
+
+ protected virtual void OutputMemberScopeModifier (MemberAttributes attrs)
+ {
+ }
+
+ protected virtual void OutputOperator (CodeBinaryOperatorType op)
+ {
+ }
+
+ protected virtual void OutputParameters (CodeParameterDeclarationExpressionCollection pars)
+ {
+ }
+
+ protected virtual void OutputType (string typeRef)
+ {
+ }
+
+ protected virtual void OutputTypeAttributes (TypeAttributes attrs)
+ {
+ }
+
+ protected virtual void OutputTypeNamePair (string typeRef, string name)
+ {
+ }
+
+
+ protected abstract string QuoteLiteralString (string value);
+
+ public virtual void ValidateIdentifier (string value)
+ {
+ }
+
+ //
+ // Properties
+ //
+ protected string currentClassName;
+ protected string CurrentClassName {
+ get {
+ return currentClassName;
+ }
+ }
+
+ protected CodeTypeMember codeClassMember;
+ protected CodeTypeMember CurrentMember {
+ get {
+ return codeClassMember;
+ }
+ }
+
+ protected string CurrentMemberName {
+ get {
+ return codeClassMember.Name;
+ }
+ }
+
+ int indent;
+ protected int Indent {
+ get {
+ return indent;
+ }
+
+ set {
+ indent = value;
+ }
+ }
+
+ //
+ // This concept seems broken, I should not really be using
+ // a flag, I should be "probing" what is being generated.
+ // at least the Start/End
+ // functions should not be abstract, or abstract could
+ // have an implementation piece?
+ //
+ public bool isCurrentClass;
+ protected bool IsCurrentClass {
+ get {
+ return isCurrentClass;
+ }
+ }
+
+ public bool isCurrentDelegate;
+ protected bool IsCurrentDelegate {
+ get {
+ return isCurrentDelegate;
+ }
+ }
+ public bool isCurrentEnum;
+ protected bool IsCurrentEnum {
+ get {
+ return isCurrentEnum;
+ }
+ }
+ public bool isCurrentInterface;
+ protected bool IsCurrentInterface {
+ get {
+ return isCurrentInterface;
+ }
+ }
+
+ public bool isCurrentStruct;
+ protected bool IsCurrentStruct {
+ get {
+ return isCurrentStruct;
+ }
+ }
+
+ protected TextWriter Output {
+ get {
+ return output;
+ }
+
+ set {
+ output = value;
+ }
+ }
+
+ public abstract void GenerateCodeFromExpression (TextWriter output, CodeExpression expression);
+
+ public abstract void GenerateCodeFromNamespace (TextWriter output, CodeExpression expression);
+
+ public abstract void GenerateCodeFromStatement (TextWriter output, CodeStatement expression);
+
+ }
+}
diff --git a/mcs/class/System/System.CodeDom.Compiler/ICodeGenerator.cs b/mcs/class/System/System.CodeDom.Compiler/ICodeGenerator.cs
new file mode 100755
index 00000000000..3cdbb32c7f6
--- /dev/null
+++ b/mcs/class/System/System.CodeDom.Compiler/ICodeGenerator.cs
@@ -0,0 +1,30 @@
+//
+// System.CodeDom.Compiler ICodeGenerator Interface
+//
+// Author:
+// Miguel de Icaza (miguel@ximian.com)
+//
+// (C) 2001 Ximian, Inc.
+//
+
+namespace System.CodeDom.Compiler {
+ using System.CodeDom;
+ using System.IO;
+
+ public interface ICodeGenerator {
+
+
+ // <summary>
+ // Generates code for @expression on @output
+ // </summary>
+ void GenerateCodeFromExpression (TextWriter output, CodeExpression expression);
+
+ void GenerateCodeFromNamespace (TextWriter output, CodeExpression expression);
+
+ void GenerateCodeFromStatement (TextWriter output, CodeStatement expression);
+
+ bool IsValidIdentifier (string value);
+
+ void ValidateIdentifier (string value);
+ }
+}
diff --git a/mcs/class/System/System.CodeDom.Compiler/common.src b/mcs/class/System/System.CodeDom.Compiler/common.src
new file mode 100755
index 00000000000..d4a8e2b560f
--- /dev/null
+++ b/mcs/class/System/System.CodeDom.Compiler/common.src
@@ -0,0 +1,2 @@
+ICodeGenerator.cs
+CodeGenerator.cs
diff --git a/mcs/class/System/System.CodeDom.Compiler/unix.src b/mcs/class/System/System.CodeDom.Compiler/unix.src
new file mode 100755
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/mcs/class/System/System.CodeDom.Compiler/unix.src
diff --git a/mcs/class/System/System.CodeDom.Compiler/windows.src b/mcs/class/System/System.CodeDom.Compiler/windows.src
new file mode 100755
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/mcs/class/System/System.CodeDom.Compiler/windows.src
diff --git a/mcs/class/System/System.CodeDom/ChangeLog b/mcs/class/System/System.CodeDom/ChangeLog
new file mode 100644
index 00000000000..102e74825e3
--- /dev/null
+++ b/mcs/class/System/System.CodeDom/ChangeLog
@@ -0,0 +1,19 @@
+2001-07-15 Sean MacIsaac <macisaac@ximian.com>
+
+ * MemberAttributes.cs: Added so rest of classes would compile.
+
+ * FieldDirection.cs: Added so rest of classes would compile.
+
+ * CodeTypeMember.cs: Added so rest of classes would compile.
+
+ * CodeTypeDeclaration.cs: Added so rest of classes would compile.
+
+ * CodeObject.cs: Added so rest of classes would compile.
+
+ * CodeBinaryOperatorType.cs: Added so rest of classes would compile.
+
+2001-07-12 Sean MacIsaac <macisaac@ximian.com>
+
+ * All files implementing IList: Added IsFixedSize property.
+
+ * All files: Changed CodeDOM to CodeDom.
diff --git a/mcs/class/System/System.CodeDom/Code-X-Collection.cs b/mcs/class/System/System.CodeDom/Code-X-Collection.cs
new file mode 100755
index 00000000000..8e4731656b4
--- /dev/null
+++ b/mcs/class/System/System.CodeDom/Code-X-Collection.cs
@@ -0,0 +1,159 @@
+//
+// System.CodeDOM Code@CONTAINEE@Collection Class implementation
+//
+// Author:
+// Miguel de Icaza (miguel@ximian.com)
+//
+// (C) 2001 Ximian, Inc.
+//
+
+namespace System.CodeDOM {
+
+ using System.Collections;
+
+ public class Code@CONTAINEE@Collection : IList, ICollection, IEnumerable {
+
+ ArrayList @arrayname@;
+
+ //
+ // Constructors
+ //
+ public Code@CONTAINEE@Collection ()
+ {
+ @arrayname@ = new ArrayList ();
+ }
+
+ //
+ // Properties
+ //
+ public int Count {
+ get {
+ return @arrayname@.Count;
+ }
+ }
+
+ //
+ // Methods
+ //
+ public void Add (Code@CONTAINEE@ value)
+ {
+ @arrayname@.Add (value);
+ }
+
+ public void AddRange (Code@CONTAINEE@ [] values)
+ {
+ foreach (Code@CONTAINEE@ ca in values)
+ @arrayname@.Add (ca);
+
+ }
+
+ public void Clear ()
+ {
+ @arrayname@.Clear ();
+ }
+
+ private class Enumerator : IEnumerator {
+ private Code@CONTAINEE@Collection collection;
+ private int currentIndex = -1;
+
+ internal Enumerator (Code@CONTAINEE@Collection collection)
+ {
+ this.collection = collection;
+ }
+
+ public object Current {
+ get {
+ if (currentIndex == collection.Count)
+ throw new InvalidOperationException ();
+ return collection [currentIndex];
+ }
+ }
+
+ public bool MoveNext ()
+ {
+ if (currentIndex > collection.Count)
+ throw new InvalidOperationException ();
+ return ++currentIndex < collection.Count;
+ }
+
+ public void Reset ()
+ {
+ currentIndex = -1;
+ }
+ }
+
+ public IEnumerator GetEnumerator ()
+ {
+ return new Code@CONTAINEE@Collection.Enumerator (this);
+ }
+
+ //
+ // IList method implementations
+ //
+ public int Add (object value)
+ {
+ return @arrayname@.Add (value);
+ }
+
+ public bool Contains (Object value)
+ {
+ return @arrayname@.Contains (value);
+ }
+
+ public int IndexOf (Object value)
+ {
+ return @arrayname@.IndexOf (value);
+ }
+
+ public void Insert (int index, Object value)
+ {
+ @arrayname@ [index] = value;
+ }
+
+ public object this[int index] {
+ get {
+ return @arrayname@ [index];
+ }
+
+ set {
+ @arrayname@ [index] = value;
+ }
+ }
+
+ public void Remove (object value)
+ {
+ @arrayname@.Remove (value);
+ }
+
+ public void RemoveAt (int index)
+ {
+ @arrayname@.RemoveAt (index);
+ }
+
+ //
+ // ICollection method implementations
+ //
+ public void CopyTo (Array array, int index)
+ {
+ @arrayname@.CopyTo (array, index);
+ }
+
+ public object SyncRoot {
+ get {
+ return @arrayname@.SyncRoot;
+ }
+ }
+
+ public bool IsReadOnly {
+ get {
+ return false;
+ }
+ }
+
+ public bool IsSynchronized {
+ get {
+ return @arrayname@.IsSynchronized;
+ }
+ }
+ }
+}
diff --git a/mcs/class/System/System.CodeDom/CodeArrayCreateExpression.cs b/mcs/class/System/System.CodeDom/CodeArrayCreateExpression.cs
new file mode 100755
index 00000000000..17a4a455db3
--- /dev/null
+++ b/mcs/class/System/System.CodeDom/CodeArrayCreateExpression.cs
@@ -0,0 +1,89 @@
+//
+// System.CodeDom CodeArrayCreateExpression Class implementation
+//
+// Author:
+// Miguel de Icaza (miguel@ximian.com)
+//
+// (C) 2001 Ximian, Inc.
+//
+namespace System.CodeDom {
+
+ public class CodeArrayCreateExpression : CodeExpression {
+ string createType;
+ CodeExpressionCollection initializers;
+ CodeExpression sizeExpression;
+ int size;
+
+ //
+ // Constructors
+ //
+ public CodeArrayCreateExpression ()
+ {
+
+ }
+
+ public CodeArrayCreateExpression (string createType, CodeExpression size)
+ {
+ this.createType = createType;
+ this.sizeExpression = size;
+ }
+
+ public CodeArrayCreateExpression (string createType, int size)
+ {
+ this.createType = createType;
+ this.size = size;
+ }
+
+ public CodeArrayCreateExpression (string createType, CodeExpression [] initializers)
+ {
+ this.createType = createType;
+ this.initializers = new CodeExpressionCollection ();
+
+ this.initializers.AddRange (initializers);
+ }
+
+ //
+ // Properties
+ //
+ public CodeExpression SizeExpression {
+ get {
+ return sizeExpression;
+ }
+
+ set {
+ sizeExpression = value;
+ }
+ }
+
+ public int Size {
+ get {
+ return size;
+ }
+
+ set {
+ size = value;
+ }
+ }
+
+ public CodeExpressionCollection Initializers {
+ get {
+ return initializers;
+ }
+
+ set {
+ initializers = value;
+ }
+ }
+
+ public string CreateType {
+ get {
+ return createType;
+ }
+
+ set {
+ createType = value;
+ }
+ }
+ }
+}
+
diff --git a/mcs/class/System/System.CodeDom/CodeAssignStatement.cs b/mcs/class/System/System.CodeDom/CodeAssignStatement.cs
new file mode 100755
index 00000000000..0e1bb9750ad
--- /dev/null
+++ b/mcs/class/System/System.CodeDom/CodeAssignStatement.cs
@@ -0,0 +1,52 @@
+//
+// System.CodeDom CodeArrayCreateExpression Class implementation
+//
+// Author:
+// Miguel de Icaza (miguel@ximian.com)
+//
+// (C) 2001 Ximian, Inc.
+//
+
+namespace System.CodeDom {
+
+ public class CodeAssignStatement : CodeStatement {
+
+ CodeExpression left, right;
+
+ //
+ // Constructors
+ //
+ public CodeAssignStatement ()
+ {
+ }
+
+ public CodeAssignStatement (CodeExpression left, CodeExpression right)
+ {
+ this.left = left;
+ this.right = right;
+ }
+
+ //
+ // Properties
+ //
+ public CodeExpression Left {
+ get {
+ return left;
+ }
+
+ set {
+ left = value;
+ }
+ }
+
+ public CodeExpression Right {
+ get {
+ return right;
+ }
+
+ set {
+ right = value;
+ }
+ }
+ }
+}
diff --git a/mcs/class/System/System.CodeDom/CodeAttachEventStatement.cs b/mcs/class/System/System.CodeDom/CodeAttachEventStatement.cs
new file mode 100755
index 00000000000..d85a61d8ea9
--- /dev/null
+++ b/mcs/class/System/System.CodeDom/CodeAttachEventStatement.cs
@@ -0,0 +1,62 @@
+//
+// System.CodeDom CodeAttachEventStatement Class implementation
+//
+// Author:
+// Miguel de Icaza (miguel@ximian.com)
+//
+// (C) 2001 Ximian, Inc.
+//
+namespace System.CodeDom {
+
+ public class CodeAttachEventStatement : CodeStatement {
+ CodeExpression targetObject;
+ string eventName;
+ CodeExpression newListener;
+
+ public CodeAttachEventStatement ()
+ {
+ }
+
+ public CodeAttachEventStatement (CodeExpression targetObject,
+ string eventName,
+ CodeExpression newListener)
+ {
+ this.targetObject = targetObject;
+ this.eventName = eventName;
+ this.newListener = newListener;
+ }
+
+ //
+ // Properties
+ //
+ public string EventName {
+ get {
+ return eventName;
+ }
+
+ set {
+ eventName = value;
+ }
+ }
+
+ public CodeExpression NewListener {
+ get {
+ return newListener;
+ }
+
+ set {
+ newListener = value;
+ }
+ }
+
+ public CodeExpression TargetObject {
+ get {
+ return targetObject;
+ }
+
+ set {
+ targetObject = value;
+ }
+ }
+ }
+}
diff --git a/mcs/class/System/System.CodeDom/CodeAttributeArgument.cs b/mcs/class/System/System.CodeDom/CodeAttributeArgument.cs
new file mode 100755
index 00000000000..50fa7efcd6e
--- /dev/null
+++ b/mcs/class/System/System.CodeDom/CodeAttributeArgument.cs
@@ -0,0 +1,60 @@
+//
+// System.CodeDom CodeAttributeArgument Class implementation
+//
+// Author:
+// Miguel de Icaza (miguel@ximian.com)
+//
+// (C) 2001 Ximian, Inc.
+//
+
+namespace System.CodeDom {
+
+ public class CodeAttributeArgument {
+ string name;
+ CodeExpression val;
+
+ //
+ // Constructors
+ //
+ public CodeAttributeArgument ()
+ {
+ }
+
+ public CodeAttributeArgument (CodeExpression value)
+ {
+ }
+
+ public CodeAttributeArgument (string name, CodeExpression val)
+ {
+ this.name = name;
+ this.val = val;
+ }
+
+ //
+ // Properties
+ //
+
+ public string Name {
+ get {
+ return name;
+ }
+
+ set {
+ name = value;
+ }
+ }
+
+ public CodeExpression Value {
+ get {
+ return val;
+ }
+
+ set {
+ val = value;
+ }
+ }
+
+
+ }
+
+}
diff --git a/mcs/class/System/System.CodeDom/CodeAttributeArgumentCollection.cs b/mcs/class/System/System.CodeDom/CodeAttributeArgumentCollection.cs
new file mode 100755
index 00000000000..d318732320a
--- /dev/null
+++ b/mcs/class/System/System.CodeDom/CodeAttributeArgumentCollection.cs
@@ -0,0 +1,166 @@
+//
+// System.CodeDom CodeAttributeArgumentCollection Class implementation
+//
+// Author:
+// Miguel de Icaza (miguel@ximian.com)
+//
+// (C) 2001 Ximian, Inc.
+//
+
+namespace System.CodeDom {
+
+ using System.Collections;
+
+ public class CodeAttributeArgumentCollection : IList, ICollection, IEnumerable {
+
+ ArrayList attributeArgs;
+
+ //
+ // Constructors
+ //
+ public CodeAttributeArgumentCollection ()
+ {
+ attributeArgs = new ArrayList ();
+ }
+
+ //
+ // Properties
+ //
+ public int Count {
+ get {
+ return attributeArgs.Count;
+ }
+ }
+
+ public bool IsFixedSize {
+ get {
+ return true;
+ }
+ }
+
+ //
+ // Methods
+ //
+
+ public void Add (CodeAttributeArgument value)
+ {
+ attributeArgs.Add (value);
+ }
+
+ public void AddRange (CodeAttributeArgument [] values)
+ {
+ foreach (CodeAttributeArgument ca in values)
+ attributeArgs.Add (ca);
+
+ }
+
+ public void Clear ()
+ {
+ attributeArgs.Clear ();
+ }
+
+ private class Enumerator : IEnumerator {
+ private CodeAttributeArgumentCollection collection;
+ private int currentIndex = -1;
+
+ internal Enumerator (CodeAttributeArgumentCollection collection)
+ {
+ this.collection = collection;
+ }
+
+ public object Current {
+ get {
+ if (currentIndex == collection.Count)
+ throw new InvalidOperationException ();
+ return collection [currentIndex];
+ }
+ }
+
+ public bool MoveNext ()
+ {
+ if (currentIndex > collection.Count)
+ throw new InvalidOperationException ();
+ return ++currentIndex < collection.Count;
+ }
+
+ public void Reset ()
+ {
+ currentIndex = -1;
+ }
+ }
+
+ public IEnumerator GetEnumerator ()
+ {
+ return new CodeAttributeArgumentCollection.Enumerator (this);
+ }
+
+ //
+ // IList method implementations
+ //
+ public int Add (object value)
+ {
+ return attributeArgs.Add (value);
+ }
+
+ public bool Contains (Object value)
+ {
+ return attributeArgs.Contains (value);
+ }
+
+ public int IndexOf (Object value)
+ {
+ return attributeArgs.IndexOf (value);
+ }
+
+ public void Insert (int index, Object value)
+ {
+ attributeArgs [index] = value;
+ }
+
+ public object this[int index] {
+ get {
+ return attributeArgs [index];
+ }
+
+ set {
+ attributeArgs [index] = value;
+ }
+ }
+
+ public void Remove (object value)
+ {
+ attributeArgs.Remove (value);
+ }
+
+ public void RemoveAt (int index)
+ {
+ attributeArgs.RemoveAt (index);
+ }
+
+ //
+ // ICollection method implementations
+ //
+ public void CopyTo (Array array, int index)
+ {
+ attributeArgs.CopyTo (array, index);
+ }
+
+ public object SyncRoot {
+ get {
+ return attributeArgs.SyncRoot;
+ }
+ }
+
+ public bool IsReadOnly {
+ get {
+ return false;
+ }
+ }
+
+ public bool IsSynchronized {
+ get {
+ return attributeArgs.IsSynchronized;
+ }
+ }
+ }
+}
diff --git a/mcs/class/System/System.CodeDom/CodeAttributeBlock.cs b/mcs/class/System/System.CodeDom/CodeAttributeBlock.cs
new file mode 100755
index 00000000000..16ed71265ba
--- /dev/null
+++ b/mcs/class/System/System.CodeDom/CodeAttributeBlock.cs
@@ -0,0 +1,42 @@
+//
+// System.CodeDom CodeAttributeBlock Class implementation
+//
+// Author:
+// Miguel de Icaza (miguel@ximian.com)
+//
+// (C) 2001 Ximian, Inc.
+//
+
+namespace System.CodeDom {
+
+ public class CodeAttributeBlock {
+
+ CodeAttributeDeclarationCollection attributes;
+
+ //
+ // Constructors
+ //
+ public CodeAttributeBlock ()
+ {
+ }
+
+ public CodeAttributeBlock (CodeAttributeDeclaration [] attributes)
+ {
+ this.attributes = new CodeAttributeDeclarationCollection ();
+ this.attributes.AddRange (attributes);
+ }
+
+ //
+ // Prpoperties
+ //
+ public CodeAttributeDeclarationCollection Attributes {
+ get {
+ return attributes;
+ }
+
+ set {
+ attributes = value;
+ }
+ }
+ }
+}
diff --git a/mcs/class/System/System.CodeDom/CodeAttributeDeclaration.cs b/mcs/class/System/System.CodeDom/CodeAttributeDeclaration.cs
new file mode 100755
index 00000000000..8c9105ce236
--- /dev/null
+++ b/mcs/class/System/System.CodeDom/CodeAttributeDeclaration.cs
@@ -0,0 +1,60 @@
+//
+// System.CodeDom CodeAttributeDeclaration Class implementation
+//
+// Author:
+// Miguel de Icaza (miguel@ximian.com)
+//
+// (C) 2001 Ximian, Inc.
+//
+
+namespace System.CodeDom {
+
+ public class CodeAttributeDeclaration {
+
+ string name;
+ CodeAttributeArgumentCollection arguments;
+
+ //
+ // Constructors
+ //
+ public CodeAttributeDeclaration ()
+ {
+ }
+
+ public CodeAttributeDeclaration (string name)
+ {
+ this.name = name;
+ }
+
+ public CodeAttributeDeclaration (string name, CodeAttributeArgument [] arguments)
+ {
+ this.name = name;
+ this.arguments = new CodeAttributeArgumentCollection ();
+ this.arguments.AddRange (arguments);
+ }
+
+ //
+ // Properties
+ //
+ public CodeAttributeArgumentCollection Arguments {
+ get {
+ return arguments;
+ }
+
+ set {
+ arguments = value;
+ }
+ }
+
+ public string Name {
+ get {
+ return name;
+ }
+
+ set {
+ name = value;
+ }
+ }
+ }
+}
+
diff --git a/mcs/class/System/System.CodeDom/CodeAttributeDeclarationCollection.cs b/mcs/class/System/System.CodeDom/CodeAttributeDeclarationCollection.cs
new file mode 100755
index 00000000000..48aa3b48965
--- /dev/null
+++ b/mcs/class/System/System.CodeDom/CodeAttributeDeclarationCollection.cs
@@ -0,0 +1,165 @@
+//
+// System.CodeDom CodeAttributeDeclarationCollection Class implementation
+//
+// Author:
+// Miguel de Icaza (miguel@ximian.com)
+//
+// (C) 2001 Ximian, Inc.
+//
+
+namespace System.CodeDom {
+
+ using System.Collections;
+
+ public class CodeAttributeDeclarationCollection : IList, ICollection, IEnumerable {
+
+ ArrayList attributeDecls;
+
+ //
+ // Constructors
+ //
+ public CodeAttributeDeclarationCollection ()
+ {
+ attributeDecls = new ArrayList ();
+ }
+
+ //
+ // Properties
+ //
+ public int Count {
+ get {
+ return attributeDecls.Count;
+ }
+ }
+
+ public bool IsFixedSize {
+ get {
+ return true;
+ }
+ }
+
+ //
+ // Methods
+ //
+ public void Add (CodeAttributeDeclaration value)
+ {
+ attributeDecls.Add (value);
+ }
+
+ public void AddRange (CodeAttributeDeclaration [] values)
+ {
+ foreach (CodeAttributeDeclaration ca in values)
+ attributeDecls.Add (ca);
+
+ }
+
+ public void Clear ()
+ {
+ attributeDecls.Clear ();
+ }
+
+ private class Enumerator : IEnumerator {
+ private CodeAttributeDeclarationCollection collection;
+ private int currentIndex = -1;
+
+ internal Enumerator (CodeAttributeDeclarationCollection collection)
+ {
+ this.collection = collection;
+ }
+
+ public object Current {
+ get {
+ if (currentIndex == collection.Count)
+ throw new InvalidOperationException ();
+ return collection [currentIndex];
+ }
+ }
+
+ public bool MoveNext ()
+ {
+ if (currentIndex > collection.Count)
+ throw new InvalidOperationException ();
+ return ++currentIndex < collection.Count;
+ }
+
+ public void Reset ()
+ {
+ currentIndex = -1;
+ }
+ }
+
+ public IEnumerator GetEnumerator ()
+ {
+ return new CodeAttributeDeclarationCollection.Enumerator (this);
+ }
+
+ //
+ // IList method implementations
+ //
+ public int Add (object value)
+ {
+ return attributeDecls.Add (value);
+ }
+
+ public bool Contains (Object value)
+ {
+ return attributeDecls.Contains (value);
+ }
+
+ public int IndexOf (Object value)
+ {
+ return attributeDecls.IndexOf (value);
+ }
+
+ public void Insert (int index, Object value)
+ {
+ attributeDecls [index] = value;
+ }
+
+ public object this[int index] {
+ get {
+ return attributeDecls [index];
+ }
+
+ set {
+ attributeDecls [index] = value;
+ }
+ }
+
+ public void Remove (object value)
+ {
+ attributeDecls.Remove (value);
+ }
+
+ public void RemoveAt (int index)
+ {
+ attributeDecls.RemoveAt (index);
+ }
+
+ //
+ // ICollection method implementations
+ //
+ public void CopyTo (Array array, int index)
+ {
+ attributeDecls.CopyTo (array, index);
+ }
+
+ public object SyncRoot {
+ get {
+ return attributeDecls.SyncRoot;
+ }
+ }
+
+ public bool IsReadOnly {
+ get {
+ return false;
+ }
+ }
+
+ public bool IsSynchronized {
+ get {
+ return attributeDecls.IsSynchronized;
+ }
+ }
+ }
+}
diff --git a/mcs/class/System/System.CodeDom/CodeBaseReferenceExpression.cs b/mcs/class/System/System.CodeDom/CodeBaseReferenceExpression.cs
new file mode 100755
index 00000000000..dee01e013af
--- /dev/null
+++ b/mcs/class/System/System.CodeDom/CodeBaseReferenceExpression.cs
@@ -0,0 +1,15 @@
+//
+// System.CodeDom CodeBaseReferenceExpression Class implementation
+//
+// Author:
+// Miguel de Icaza (miguel@ximian.com)
+//
+// (C) 2001 Ximian, Inc.
+//
+
+namespace System.CodeDom {
+
+ public class CodeBaseReferenceExpression : CodeExpression {
+ public CodeBaseReferenceExpression () {}
+ }
+}
diff --git a/mcs/class/System/System.CodeDom/CodeBinaryOperatorExpression.cs b/mcs/class/System/System.CodeDom/CodeBinaryOperatorExpression.cs
new file mode 100755
index 00000000000..775b29bf90f
--- /dev/null
+++ b/mcs/class/System/System.CodeDom/CodeBinaryOperatorExpression.cs
@@ -0,0 +1,88 @@
+//
+// System.CodeDom CodeBinaryOperatorExpression Class implementation
+//
+// Author:
+// Miguel de Icaza (miguel@ximian.com)
+//
+// (C) 2001 Ximian, Inc.
+//
+
+namespace System.CodeDom {
+
+ public class CodeBinaryOperatorExpression : CodeExpression {
+
+ CodeExpression left, right;
+ CodeBinaryOperatorType oper;
+
+ public enum CodeBinaryOperatorType {
+ Add,
+ Substract,
+ Multiply,
+ Divide,
+ Modulus,
+ Assign,
+ IdentityInequality,
+ IdentityEquality,
+ ValueEquality,
+ BitwiseOr,
+ BitwiseAnd,
+ BooleanOr,
+ BooleanAnd,
+ LessThan,
+ LessThanOrEqual,
+ GreatherThan,
+ GreatherThanOrEqual,
+ }
+
+ //
+ // Constructors
+ //
+ public CodeBinaryOperatorExpression ()
+ {
+ }
+
+
+ public CodeBinaryOperatorExpression (CodeExpression left,
+ CodeBinaryOperatorType oper,
+ CodeExpression right)
+ {
+ this.left = left;
+ this.oper = oper;
+ this.right = right;
+ }
+
+ //
+ // Properties
+ //
+ public CodeExpression Left {
+ get {
+ return left;
+ }
+
+ set {
+ left = value;
+ }
+ }
+
+ public CodeExpression Right {
+ get {
+ return right;
+ }
+
+ set {
+ right = value;
+ }
+ }
+
+ public CodeBinaryOperatorType Operator {
+ get {
+ return oper;
+ }
+
+ set {
+ oper = value;
+ }
+ }
+ }
+}
+
diff --git a/mcs/class/System/System.CodeDom/CodeBinaryOperatorType.cs b/mcs/class/System/System.CodeDom/CodeBinaryOperatorType.cs
new file mode 100755
index 00000000000..eb2d31a02d4
--- /dev/null
+++ b/mcs/class/System/System.CodeDom/CodeBinaryOperatorType.cs
@@ -0,0 +1,30 @@
+//
+// System.CodeDom CodeBinaryOperatorType Enum implementation
+//
+// Author:
+// Sean MacIsaac (macisaac@ximian.com)
+//
+// (C) 2001 Ximian, Inc.
+//
+
+namespace System.CodeDom {
+ public enum CodeBinaryOperatorType {
+ Add,
+ Assign,
+ BitwiseAnd,
+ BitwiseOr,
+ BooleanAnd,
+ BooleanOr,
+ Divide,
+ GreaterThan,
+ GreaterThanOrEqual,
+ IdentityEquality,
+ IdentityInequality,
+ LessThan,
+ LessThanOrEqual,
+ Modulus,
+ Multiply,
+ Subtract,
+ ValueEquality
+ }
+}
diff --git a/mcs/class/System/System.CodeDom/CodeCastExpression.cs b/mcs/class/System/System.CodeDom/CodeCastExpression.cs
new file mode 100755
index 00000000000..3c3bef51042
--- /dev/null
+++ b/mcs/class/System/System.CodeDom/CodeCastExpression.cs
@@ -0,0 +1,52 @@
+//
+// System.CodeDom CodeCastExpression Class implementation
+//
+// Author:
+// Miguel de Icaza (miguel@ximian.com)
+//
+// (C) 2001 Ximian, Inc.
+//
+
+namespace System.CodeDom {
+
+ public class CodeCastExpression : CodeExpression {
+ string targetType;
+ CodeExpression expression;
+
+ //
+ // Constructors
+ //
+ public CodeCastExpression ()
+ {
+ }
+
+ public CodeCastExpression (string targetType, CodeExpression expression)
+ {
+ this.targetType = targetType;
+ this.expression = expression;
+ }
+
+ //
+ // Properties
+ //
+ public CodeExpression Expression {
+ get {
+ return expression;
+ }
+
+ set {
+ expression = value;
+ }
+ }
+
+ public string TargetType {
+ get {
+ return targetType;
+ }
+
+ set {
+ targetType = value;
+ }
+ }
+ }
+}
diff --git a/mcs/class/System/System.CodeDom/CodeCatchClause.cs b/mcs/class/System/System.CodeDom/CodeCatchClause.cs
new file mode 100755
index 00000000000..4af7a18f4a2
--- /dev/null
+++ b/mcs/class/System/System.CodeDom/CodeCatchClause.cs
@@ -0,0 +1,46 @@
+//
+// System.CodeDom CodeCatchClaus Class implementation
+//
+// Author:
+// Miguel de Icaza (miguel@ximian.com)
+//
+// (C) 2001 Ximian, Inc.
+//
+
+namespace System.CodeDom {
+
+ public class CodeCatchClause {
+
+ CodeParameterDeclarationExpression condition;
+ CodeStatementCollection statements;
+
+ public CodeCatchClause ()
+ {
+ this.statements = new CodeStatementCollection ();
+ }
+
+ public CodeCatchClause (CodeParameterDeclarationExpression condition,
+ CodeStatement [] statements)
+ {
+ this.condition = condition;
+ this.statements = new CodeStatementCollection ();
+ this.statements.AddRange (statements);
+ }
+
+ public CodeStatementCollection Statements {
+ get {
+ return statements;
+ }
+ }
+
+ public CodeParameterDeclarationExpression Condition {
+ get {
+ return condition;
+ }
+
+ set {
+ condition = value;
+ }
+ }
+ }
+}
diff --git a/mcs/class/System/System.CodeDom/CodeCatchClauseCollection.cs b/mcs/class/System/System.CodeDom/CodeCatchClauseCollection.cs
new file mode 100755
index 00000000000..7b4a284bac5
--- /dev/null
+++ b/mcs/class/System/System.CodeDom/CodeCatchClauseCollection.cs
@@ -0,0 +1,165 @@
+//
+// System.CodeDom CodeCatchClauseCollection Class implementation
+//
+// Author:
+// Miguel de Icaza (miguel@ximian.com)
+//
+// (C) 2001 Ximian, Inc.
+//
+
+namespace System.CodeDom {
+
+ using System.Collections;
+
+ public class CodeCatchClauseCollection : IList, ICollection, IEnumerable {
+
+ ArrayList catchClauses;
+
+ //
+ // Constructors
+ //
+ public CodeCatchClauseCollection ()
+ {
+ catchClauses = new ArrayList ();
+ }
+
+ //
+ // Properties
+ //
+ public int Count {
+ get {
+ return catchClauses.Count;
+ }
+ }
+
+ public bool IsFixedSize {
+ get {
+ return true;
+ }
+ }
+
+ //
+ // Methods
+ //
+ public void Add (CodeCatchClause value)
+ {
+ catchClauses.Add (value);
+ }
+
+ public void AddRange (CodeCatchClause [] values)
+ {
+ foreach (CodeCatchClause ca in values)
+ catchClauses.Add (ca);
+
+ }
+
+ public void Clear ()
+ {
+ catchClauses.Clear ();
+ }
+
+ private class Enumerator : IEnumerator {
+ private CodeCatchClauseCollection collection;
+ private int currentIndex = -1;
+
+ internal Enumerator (CodeCatchClauseCollection collection)
+ {
+ this.collection = collection;
+ }
+
+ public object Current {
+ get {
+ if (currentIndex == collection.Count)
+ throw new InvalidOperationException ();
+ return collection [currentIndex];
+ }
+ }
+
+ public bool MoveNext ()
+ {
+ if (currentIndex > collection.Count)
+ throw new InvalidOperationException ();
+ return ++currentIndex < collection.Count;
+ }
+
+ public void Reset ()
+ {
+ currentIndex = -1;
+ }
+ }
+
+ public IEnumerator GetEnumerator ()
+ {
+ return new CodeCatchClauseCollection.Enumerator (this);
+ }
+
+ //
+ // IList method implementations
+ //
+ public int Add (object value)
+ {
+ return catchClauses.Add (value);
+ }
+
+ public bool Contains (Object value)
+ {
+ return catchClauses.Contains (value);
+ }
+
+ public int IndexOf (Object value)
+ {
+ return catchClauses.IndexOf (value);
+ }
+
+ public void Insert (int index, Object value)
+ {
+ catchClauses [index] = value;
+ }
+
+ public object this[int index] {
+ get {
+ return catchClauses [index];
+ }
+
+ set {
+ catchClauses [index] = value;
+ }
+ }
+
+ public void Remove (object value)
+ {
+ catchClauses.Remove (value);
+ }
+
+ public void RemoveAt (int index)
+ {
+ catchClauses.RemoveAt (index);
+ }
+
+ //
+ // ICollection method implementations
+ //
+ public void CopyTo (Array array, int index)
+ {
+ catchClauses.CopyTo (array, index);
+ }
+
+ public object SyncRoot {
+ get {
+ return catchClauses.SyncRoot;
+ }
+ }
+
+ public bool IsReadOnly {
+ get {
+ return false;
+ }
+ }
+
+ public bool IsSynchronized {
+ get {
+ return catchClauses.IsSynchronized;
+ }
+ }
+ }
+}
diff --git a/mcs/class/System/System.CodeDom/CodeClass.cs b/mcs/class/System/System.CodeDom/CodeClass.cs
new file mode 100755
index 00000000000..146cfb474ea
--- /dev/null
+++ b/mcs/class/System/System.CodeDom/CodeClass.cs
@@ -0,0 +1,107 @@
+//
+// System.CodeDom CodeClass Class implementation
+//
+// Author:
+// Miguel de Icaza (miguel@ximian.com)
+//
+// (C) 2001 Ximian, Inc.
+//
+
+using System.Collections.Specialized;
+
+namespace System.CodeDom {
+ using System.Reflection;
+ using System.Collections;
+
+ public class CodeClass : CodeClassMember {
+ CodeClassMemberCollection members;
+ TypeAttributes attrs;
+ StringCollection baseTypes;
+ bool isClass, isEnum, isInterface, isStruct;
+
+ string name;
+
+ //
+ // Constructors
+ //
+ public CodeClass ()
+ {
+ }
+
+ public CodeClass (string name)
+ {
+ this.name = name;
+ }
+
+ //
+ // Properties
+ //
+ public TypeAttributes attributes {
+ get {
+ return attrs;
+ }
+
+ set {
+ attrs = value;
+ }
+ }
+
+ public StringCollection BaseTypes {
+ get {
+ return baseTypes;
+ }
+
+ set {
+ baseTypes = value;
+ }
+ }
+
+ public bool IsClass {
+ get {
+ return isClass;
+ }
+
+ set {
+ isClass = value;
+ }
+ }
+ public bool IsEnum {
+ get {
+ return isEnum;
+ }
+
+ set {
+ isEnum = value;
+ }
+ }
+
+ public bool IsInterface {
+ get {
+ return isInterface;
+ }
+
+ set {
+ isInterface = value;
+ }
+ }
+ public bool IsStruct {
+ get {
+ return isStruct;
+ }
+
+ set {
+ isStruct = value;
+ }
+ }
+
+ public CodeClassMemberCollection Members {
+ get {
+ return members;
+ }
+
+ set {
+ members = value;
+ }
+ }
+ }
+}
diff --git a/mcs/class/System/System.CodeDom/CodeClassCollection.cs b/mcs/class/System/System.CodeDom/CodeClassCollection.cs
new file mode 100755
index 00000000000..d38055a32b8
--- /dev/null
+++ b/mcs/class/System/System.CodeDom/CodeClassCollection.cs
@@ -0,0 +1,165 @@
+//
+// System.CodeDom CodeClassCollection Class implementation
+//
+// Author:
+// Miguel de Icaza (miguel@ximian.com)
+//
+// (C) 2001 Ximian, Inc.
+//
+
+namespace System.CodeDom {
+
+ using System.Collections;
+
+ public class CodeClassCollection : IList, ICollection, IEnumerable {
+
+ ArrayList classes;
+
+ //
+ // Constructors
+ //
+ public CodeClassCollection ()
+ {
+ classes = new ArrayList ();
+ }
+
+ //
+ // Properties
+ //
+ public int Count {
+ get {
+ return classes.Count;
+ }
+ }
+
+ public bool IsFixedSize {
+ get {
+ return true;
+ }
+ }
+
+ //
+ // Methods
+ //
+ public void Add (CodeClass value)
+ {
+ classes.Add (value);
+ }
+
+ public void AddRange (CodeClass [] values)
+ {
+ foreach (CodeClass ca in values)
+ classes.Add (ca);
+
+ }
+
+ public void Clear ()
+ {
+ classes.Clear ();
+ }
+
+ private class Enumerator : IEnumerator {
+ private CodeClassCollection collection;
+ private int currentIndex = -1;
+
+ internal Enumerator (CodeClassCollection collection)
+ {
+ this.collection = collection;
+ }
+
+ public object Current {
+ get {
+ if (currentIndex == collection.Count)
+ throw new InvalidOperationException ();
+ return collection [currentIndex];
+ }
+ }
+
+ public bool MoveNext ()
+ {
+ if (currentIndex > collection.Count)
+ throw new InvalidOperationException ();
+ return ++currentIndex < collection.Count;
+ }
+
+ public void Reset ()
+ {
+ currentIndex = -1;
+ }
+ }
+
+ public IEnumerator GetEnumerator ()
+ {
+ return new CodeClassCollection.Enumerator (this);
+ }
+
+ //
+ // IList method implementations
+ //
+ public int Add (object value)
+ {
+ return classes.Add (value);
+ }
+
+ public bool Contains (Object value)
+ {
+ return classes.Contains (value);
+ }
+
+ public int IndexOf (Object value)
+ {
+ return classes.IndexOf (value);
+ }
+
+ public void Insert (int index, Object value)
+ {
+ classes [index] = value;
+ }
+
+ public object this[int index] {
+ get {
+ return classes [index];
+ }
+
+ set {
+ classes [index] = value;
+ }
+ }
+
+ public void Remove (object value)
+ {
+ classes.Remove (value);
+ }
+
+ public void RemoveAt (int index)
+ {
+ classes.RemoveAt (index);
+ }
+
+ //
+ // ICollection method implementations
+ //
+ public void CopyTo (Array array, int index)
+ {
+ classes.CopyTo (array, index);
+ }
+
+ public object SyncRoot {
+ get {
+ return classes.SyncRoot;
+ }
+ }
+
+ public bool IsReadOnly {
+ get {
+ return false;
+ }
+ }
+
+ public bool IsSynchronized {
+ get {
+ return classes.IsSynchronized;
+ }
+ }
+ }
+}
diff --git a/mcs/class/System/System.CodeDom/CodeClassConstructor.cs b/mcs/class/System/System.CodeDom/CodeClassConstructor.cs
new file mode 100755
index 00000000000..a778cf5d82d
--- /dev/null
+++ b/mcs/class/System/System.CodeDom/CodeClassConstructor.cs
@@ -0,0 +1,17 @@
+//
+// System.CodeDom CodeClassConstructor Class implementation
+//
+// Author:
+// Miguel de Icaza (miguel@ximian.com)
+//
+// (C) 2001 Ximian, Inc.
+//
+
+namespace System.CodeDom {
+ public class CodeClassConstructor : CodeMemberMethod {
+
+ public CodeClassConstructor ()
+ {
+ }
+ }
+}
diff --git a/mcs/class/System/System.CodeDom/CodeClassDelegate.cs b/mcs/class/System/System.CodeDom/CodeClassDelegate.cs
new file mode 100755
index 00000000000..cf4be20b3fe
--- /dev/null
+++ b/mcs/class/System/System.CodeDom/CodeClassDelegate.cs
@@ -0,0 +1,52 @@
+//
+// System.CodeDom CodeClassDelegate Class implementation
+//
+// Author:
+// Miguel de Icaza (miguel@ximian.com)
+//
+// (C) 2001 Ximian, Inc.
+//
+
+namespace System.CodeDom {
+
+ public class CodeClassDelegate : CodeClass {
+ CodeParameterDeclarationExpressionCollection parameters;
+ string returnType;
+ string name;
+
+ //
+ // Constructors
+ //
+ public CodeClassDelegate ()
+ {
+ }
+
+ public CodeClassDelegate (string name)
+ {
+ this.name = name;
+ }
+
+ //
+ // Properties
+ //
+ public CodeParameterDeclarationExpressionCollection Parameters {
+ get {
+ return parameters;
+ }
+
+ set {
+ parameters = value;
+ }
+ }
+
+ public string ReturnType {
+ get {
+ return returnType;
+ }
+
+ set {
+ returnType = value;
+ }
+ }
+ }
+}
diff --git a/mcs/class/System/System.CodeDom/CodeClassMember.cs b/mcs/class/System/System.CodeDom/CodeClassMember.cs
new file mode 100755
index 00000000000..51d8b0476a7
--- /dev/null
+++ b/mcs/class/System/System.CodeDom/CodeClassMember.cs
@@ -0,0 +1,80 @@
+//
+// System.CodeDom CodeClassMember Class implementation
+//
+// Author:
+// Miguel de Icaza (miguel@ximian.com)
+//
+// (C) 2001 Ximian, Inc.
+//
+
+namespace System.CodeDom {
+
+ public class CodeClassMember : CodeStatement {
+ MemberAttributes attributes;
+ CodeAttributeBlock customAttributes;
+
+ string name;
+
+ //
+ // Yeah, this is a strange way of defining this
+ //
+ public enum MemberAttributes {
+ Abstract = 0x0001,
+ Final = 0x0002,
+ Override = 0x0004,
+ Const = 0x0005,
+ Assembly = 0x1000,
+ AccessMask = 0xf000,
+ FamANDAssem = 0x2000,
+ Family = 0x3000,
+ FamORAssem = 0x4000,
+ New = 0x0010,
+ Private = 0x5000,
+ Public = 0x6000,
+ ScopeMask = 0x000f,
+ Static = 0x0003,
+ VTableMask = 0x00f0
+ }
+
+ //
+ // Constructors
+ //
+ public CodeClassMember ()
+ {
+ }
+
+ //
+ // Properties
+ //
+
+ public MemberAttributes Attributes {
+ get {
+ return attributes;
+ }
+
+ set {
+ attributes = value;
+ }
+ }
+
+ public CodeAttributeBlock CustomAttributes {
+ get {
+ return customAttributes;
+ }
+
+ set {
+ customAttributes = value;
+ }
+ }
+
+ public string Name {
+ get {
+ return name;
+ }
+
+ set {
+ name = value;
+ }
+ }
+ }
+}
diff --git a/mcs/class/System/System.CodeDom/CodeClassMemberCollection.cs b/mcs/class/System/System.CodeDom/CodeClassMemberCollection.cs
new file mode 100755
index 00000000000..f081ad3a45b
--- /dev/null
+++ b/mcs/class/System/System.CodeDom/CodeClassMemberCollection.cs
@@ -0,0 +1,165 @@
+//
+// System.CodeDom CodeClassMemberCollection Class implementation
+//
+// Author:
+// Miguel de Icaza (miguel@ximian.com)
+//
+// (C) 2001 Ximian, Inc.
+//
+
+namespace System.CodeDom {
+
+ using System.Collections;
+
+ public class CodeClassMemberCollection : IList, ICollection, IEnumerable {
+
+ ArrayList classMembers;
+
+ //
+ // Constructors
+ //
+ public CodeClassMemberCollection ()
+ {
+ classMembers = new ArrayList ();
+ }
+
+ //
+ // Properties
+ //
+ public int Count {
+ get {
+ return classMembers.Count;
+ }
+ }
+
+ public bool IsFixedSize {
+ get {
+ return true;
+ }
+ }
+
+ //
+ // Methods
+ //
+ public void Add (CodeClassMember value)
+ {
+ classMembers.Add (value);
+ }
+
+ public void AddRange (CodeClassMember [] values)
+ {
+ foreach (CodeClassMember ca in values)
+ classMembers.Add (ca);
+
+ }
+
+ public void Clear ()
+ {
+ classMembers.Clear ();
+ }
+
+ private class Enumerator : IEnumerator {
+ private CodeClassMemberCollection collection;
+ private int currentIndex = -1;
+
+ internal Enumerator (CodeClassMemberCollection collection)
+ {
+ this.collection = collection;
+ }
+
+ public object Current {
+ get {
+ if (currentIndex == collection.Count)
+ throw new InvalidOperationException ();
+ return collection [currentIndex];
+ }
+ }
+
+ public bool MoveNext ()
+ {
+ if (currentIndex > collection.Count)
+ throw new InvalidOperationException ();
+ return ++currentIndex < collection.Count;
+ }
+
+ public void Reset ()
+ {
+ currentIndex = -1;
+ }
+ }
+
+ public IEnumerator GetEnumerator ()
+ {
+ return new CodeClassMemberCollection.Enumerator (this);
+ }
+
+ //
+ // IList method implementations
+ //
+ public int Add (object value)
+ {
+ return classMembers.Add (value);
+ }
+
+ public bool Contains (Object value)
+ {
+ return classMembers.Contains (value);
+ }
+
+ public int IndexOf (Object value)
+ {
+ return classMembers.IndexOf (value);
+ }
+
+ public void Insert (int index, Object value)
+ {
+ classMembers [index] = value;
+ }
+
+ public object this[int index] {
+ get {
+ return classMembers [index];
+ }
+
+ set {
+ classMembers [index] = value;
+ }
+ }
+
+ public void Remove (object value)
+ {
+ classMembers.Remove (value);
+ }
+
+ public void RemoveAt (int index)
+ {
+ classMembers.RemoveAt (index);
+ }
+
+ //
+ // ICollection method implementations
+ //
+ public void CopyTo (Array array, int index)
+ {
+ classMembers.CopyTo (array, index);
+ }
+
+ public object SyncRoot {
+ get {
+ return classMembers.SyncRoot;
+ }
+ }
+
+ public bool IsReadOnly {
+ get {
+ return false;
+ }
+ }
+
+ public bool IsSynchronized {
+ get {
+ return classMembers.IsSynchronized;
+ }
+ }
+ }
+}
diff --git a/mcs/class/System/System.CodeDom/CodeCommentStatement.cs b/mcs/class/System/System.CodeDom/CodeCommentStatement.cs
new file mode 100755
index 00000000000..9dba6528a70
--- /dev/null
+++ b/mcs/class/System/System.CodeDom/CodeCommentStatement.cs
@@ -0,0 +1,39 @@
+//
+// System.CodeDom CodeCommentStatement Class implementation
+//
+// Author:
+// Miguel de Icaza (miguel@ximian.com)
+//
+// (C) 2001 Ximian, Inc.
+//
+
+namespace System.CodeDom {
+
+ public class CodeCommentStatement : CodeStatement {
+ string text;
+
+ //
+ // Constructors
+ //
+ public CodeCommentStatement ()
+ {
+ }
+
+ public CodeCommentStatement (string text)
+ {
+ this.text = text;
+ }
+
+ string Text {
+ get {
+ return text;
+ }
+
+ set {
+ text = value;
+ }
+ }
+ }
+}
+
+
diff --git a/mcs/class/System/System.CodeDom/CodeConstructor.cs b/mcs/class/System/System.CodeDom/CodeConstructor.cs
new file mode 100755
index 00000000000..0d6a707ac15
--- /dev/null
+++ b/mcs/class/System/System.CodeDom/CodeConstructor.cs
@@ -0,0 +1,43 @@
+//
+// System.CodeDom CodeConstructor Class implementation
+//
+// Author:
+// Miguel de Icaza (miguel@ximian.com)
+//
+// (C) 2001 Ximian, Inc.
+//
+
+namespace System.CodeDom {
+
+ public class CodeConstructor : CodeMemberMethod {
+ CodeExpressionCollection baseConstructorArgs;
+ CodeExpressionCollection chainedConstructorArgs;
+
+ //
+ // Constructors
+ //
+ public CodeConstructor ()
+ {
+ }
+
+ public CodeExpressionCollection BaseConstructorArgs {
+ get {
+ return baseConstructorArgs;
+ }
+
+ set {
+ baseConstructorArgs = value;
+ }
+ }
+
+ public CodeExpressionCollection ChainedConstructorArgs {
+ get {
+ return chainedConstructorArgs;
+ }
+
+ set {
+ chainedConstructorArgs = value;
+ }
+ }
+ }
+}
diff --git a/mcs/class/System/System.CodeDom/CodeDelegateCreateExpression.cs b/mcs/class/System/System.CodeDom/CodeDelegateCreateExpression.cs
new file mode 100755
index 00000000000..1be84cc27ad
--- /dev/null
+++ b/mcs/class/System/System.CodeDom/CodeDelegateCreateExpression.cs
@@ -0,0 +1,66 @@
+//
+// System.CodeDom CodeDelegateCreateExpression Class implementation
+//
+// Author:
+// Miguel de Icaza (miguel@ximian.com)
+//
+// (C) 2001 Ximian, Inc.
+//
+
+namespace System.CodeDom {
+
+ public class CodeDelegateCreateExpression : CodeExpression {
+ string delegateType, methodName;
+ CodeExpression targetObject;
+
+ //
+ // Constructors
+ //
+ public CodeDelegateCreateExpression (string delegateType,
+ CodeExpression targetObject,
+ string methodName)
+ {
+ this.delegateType = delegateType;
+ this.targetObject = targetObject;
+ this.methodName = methodName;
+ }
+
+ public CodeDelegateCreateExpression ()
+ {
+ }
+
+ //
+ // Properties
+ //
+
+ string DelegateType {
+ get {
+ return delegateType;
+ }
+
+ set {
+ delegateType = value;
+ }
+ }
+
+ string MethodName {
+ get {
+ return methodName;
+ }
+
+ set {
+ methodName = value;
+ }
+ }
+
+ CodeExpression TargetObject {
+ get {
+ return targetObject;
+ }
+
+ set {
+ targetObject = value;
+ }
+ }
+ }
+}
diff --git a/mcs/class/System/System.CodeDom/CodeDelegateInvokeExpression.cs b/mcs/class/System/System.CodeDom/CodeDelegateInvokeExpression.cs
new file mode 100755
index 00000000000..9b918c4cd0b
--- /dev/null
+++ b/mcs/class/System/System.CodeDom/CodeDelegateInvokeExpression.cs
@@ -0,0 +1,59 @@
+//
+// System.CodeDom CodeDelegateInvokeExpression Class implementation
+//
+// Author:
+// Miguel de Icaza (miguel@ximian.com)
+//
+// (C) 2001 Ximian, Inc.
+//
+
+namespace System.CodeDom {
+
+ public class CodeDelegateInvokeExpression : CodeExpression {
+ CodeExpressionCollection parameters;
+ CodeExpression targetObject;
+
+ //
+ // Constructors
+ //
+ public CodeDelegateInvokeExpression ()
+ {
+ }
+
+ public CodeDelegateInvokeExpression (CodeExpression targetObject,
+ CodeExpression [] parameters)
+ {
+ this.targetObject = targetObject;
+ this.parameters = new CodeExpressionCollection ();
+ this.parameters.AddRange (parameters);
+ }
+
+ public CodeDelegateInvokeExpression (CodeExpression targetObject)
+ {
+ this.targetObject = targetObject;
+ }
+
+ //
+ // Properties
+ //
+ public CodeExpression TargetObject {
+ get {
+ return targetObject;
+ }
+
+ set {
+ targetObject = value;
+ }
+ }
+
+ public CodeExpressionCollection Parameters {
+ get {
+ return parameters;
+ }
+
+ set {
+ parameters = value;
+ }
+ }
+ }
+}
diff --git a/mcs/class/System/System.CodeDom/CodeDelegateInvokeStatement.cs b/mcs/class/System/System.CodeDom/CodeDelegateInvokeStatement.cs
new file mode 100755
index 00000000000..299e107a8ed
--- /dev/null
+++ b/mcs/class/System/System.CodeDom/CodeDelegateInvokeStatement.cs
@@ -0,0 +1,55 @@
+//
+// System.CodeDom CodeDelegateInvokeStatement Class implementation
+//
+// Author:
+// Miguel de Icaza (miguel@ximian.com)
+//
+// (C) 2001 Ximian, Inc.
+//
+
+namespace System.CodeDom {
+
+ public class CodeDelegateInvokeStatement : CodeStatement {
+ CodeStatementCollection parameters;
+ CodeStatement targetObject;
+ CodeDelegateInvokeExpression delegateInvoke;
+
+ //
+ // Constructors
+ //
+ public CodeDelegateInvokeStatement ()
+ {
+ }
+
+ public CodeDelegateInvokeStatement (CodeStatement targetObject)
+ {
+ this.targetObject = targetObject;
+ }
+
+ public CodeDelegateInvokeStatement (CodeDelegateInvokeExpression delegateInvoke)
+ {
+ this.delegateInvoke = delegateInvoke;
+ }
+
+ public CodeDelegateInvokeStatement (CodeStatement targetObject,
+ CodeStatement [] parameters)
+ {
+ this.targetObject = targetObject;
+ this.parameters = new CodeStatementCollection ();
+ this.parameters.AddRange (parameters);
+ }
+
+ //
+ // Properties
+ //
+ public CodeDelegateInvokeExpression DelegateInvoke {
+ get {
+ return delegateInvoke;
+ }
+
+ set {
+ delegateInvoke = value;
+ }
+ }
+ }
+}
diff --git a/mcs/class/System/System.CodeDom/CodeDetachEventStatement.cs b/mcs/class/System/System.CodeDom/CodeDetachEventStatement.cs
new file mode 100755
index 00000000000..5998b73cf2d
--- /dev/null
+++ b/mcs/class/System/System.CodeDom/CodeDetachEventStatement.cs
@@ -0,0 +1,62 @@
+//
+// System.CodeDom CodeDetachEventStatement Class implementation
+//
+// Author:
+// Miguel de Icaza (miguel@ximian.com)
+//
+// (C) 2001 Ximian, Inc.
+//
+
+namespace System.CodeDom {
+
+ public class CodeDetachEventStatement : CodeStatement {
+ string eventName;
+ CodeExpression targetObject, newListener;
+
+ //
+ // Constructors
+ //
+ public CodeDetachEventStatement ()
+ {
+ }
+
+ public CodeDetachEventStatement (CodeExpression targetObject,
+ string eventName,
+ CodeExpression newListener)
+ {
+ this.targetObject = targetObject;
+ this.eventName = eventName;
+ this.newListener = newListener;
+ }
+
+ public string EventName {
+ get {
+ return eventName;
+ }
+
+ set {
+ eventName = value;
+ }
+ }
+
+ public CodeExpression TargetObject {
+ get {
+ return targetObject;
+ }
+
+ set {
+ targetObject = value;
+ }
+ }
+
+ public CodeExpression NewListener {
+ get {
+ return newListener;
+ }
+
+ set {
+ newListener = value;
+ }
+ }
+ }
+}
diff --git a/mcs/class/System/System.CodeDom/CodeExpression.cs b/mcs/class/System/System.CodeDom/CodeExpression.cs
new file mode 100755
index 00000000000..f140c9d0d5e
--- /dev/null
+++ b/mcs/class/System/System.CodeDom/CodeExpression.cs
@@ -0,0 +1,35 @@
+//
+// System.CodeDom CodeExpression Class implementation
+//
+// Author:
+// Miguel de Icaza (miguel@ximian.com)
+//
+// (C) 2001 Ximian, Inc.
+//
+
+namespace System.CodeDom {
+
+ public class CodeExpression {
+ object userData;
+
+ //
+ // Constructors
+ //
+ public CodeExpression ()
+ {
+ }
+
+ //
+ // Properties
+ //
+ public object UserData {
+ get {
+ return userData;
+ }
+
+ set {
+ userData = value;
+ }
+ }
+ }
+}
diff --git a/mcs/class/System/System.CodeDom/CodeExpressionCollection.cs b/mcs/class/System/System.CodeDom/CodeExpressionCollection.cs
new file mode 100755
index 00000000000..10622c3b0e4
--- /dev/null
+++ b/mcs/class/System/System.CodeDom/CodeExpressionCollection.cs
@@ -0,0 +1,165 @@
+//
+// System.CodeDom CodeExpressionCollection Class implementation
+//
+// Author:
+// Miguel de Icaza (miguel@ximian.com)
+//
+// (C) 2001 Ximian, Inc.
+//
+
+namespace System.CodeDom {
+
+ using System.Collections;
+
+ public class CodeExpressionCollection : IList, ICollection, IEnumerable {
+
+ ArrayList expressions;
+
+ //
+ // Constructors
+ //
+ public CodeExpressionCollection ()
+ {
+ expressions = new ArrayList ();
+ }
+
+ //
+ // Properties
+ //
+ public int Count {
+ get {
+ return expressions.Count;
+ }
+ }
+
+ public bool IsFixedSize {
+ get {
+ return true;
+ }
+ }
+
+ //
+ // Methods
+ //
+ public void Add (CodeExpression value)
+ {
+ expressions.Add (value);
+ }
+
+ public void AddRange (CodeExpression [] values)
+ {
+ foreach (CodeExpression ca in values)
+ expressions.Add (ca);
+
+ }
+
+ public void Clear ()
+ {
+ expressions.Clear ();
+ }
+
+ private class Enumerator : IEnumerator {
+ private CodeExpressionCollection collection;
+ private int currentIndex = -1;
+
+ internal Enumerator (CodeExpressionCollection collection)
+ {
+ this.collection = collection;
+ }
+
+ public object Current {
+ get {
+ if (currentIndex == collection.Count)
+ throw new InvalidOperationException ();
+ return collection [currentIndex];
+ }
+ }
+
+ public bool MoveNext ()
+ {
+ if (currentIndex > collection.Count)
+ throw new InvalidOperationException ();
+ return ++currentIndex < collection.Count;
+ }
+
+ public void Reset ()
+ {
+ currentIndex = -1;
+ }
+ }
+
+ public IEnumerator GetEnumerator ()
+ {
+ return new CodeExpressionCollection.Enumerator (this);
+ }
+
+ //
+ // IList method implementations
+ //
+ public int Add (object value)
+ {
+ return expressions.Add (value);
+ }
+
+ public bool Contains (Object value)
+ {
+ return expressions.Contains (value);
+ }
+
+ public int IndexOf (Object value)
+ {
+ return expressions.IndexOf (value);
+ }
+
+ public void Insert (int index, Object value)
+ {
+ expressions [index] = value;
+ }
+
+ public object this[int index] {
+ get {
+ return expressions [index];
+ }
+
+ set {
+ expressions [index] = value;
+ }
+ }
+
+ public void Remove (object value)
+ {
+ expressions.Remove (value);
+ }
+
+ public void RemoveAt (int index)
+ {
+ expressions.RemoveAt (index);
+ }
+
+ //
+ // ICollection method implementations
+ //
+ public void CopyTo (Array array, int index)
+ {
+ expressions.CopyTo (array, index);
+ }
+
+ public object SyncRoot {
+ get {
+ return expressions.SyncRoot;
+ }
+ }
+
+ public bool IsReadOnly {
+ get {
+ return false;
+ }
+ }
+
+ public bool IsSynchronized {
+ get {
+ return expressions.IsSynchronized;
+ }
+ }
+ }
+}
diff --git a/mcs/class/System/System.CodeDom/CodeFieldReferenceExpression.cs b/mcs/class/System/System.CodeDom/CodeFieldReferenceExpression.cs
new file mode 100755
index 00000000000..66581e84f22
--- /dev/null
+++ b/mcs/class/System/System.CodeDom/CodeFieldReferenceExpression.cs
@@ -0,0 +1,71 @@
+//
+// System.CodeDom CodeFieldReferenceExpression Class implementation
+//
+// Author:
+// Miguel de Icaza (miguel@ximian.com)
+//
+// (C) 2001 Ximian, Inc.
+//
+
+namespace System.CodeDom {
+
+ public class CodeFieldReferenceExpression : CodeExpression {
+ CodeExpression targetObject;
+ string fieldName;
+ FieldDirection direction;
+
+ public enum FieldDirection {
+ In,
+ Out,
+ Ref
+ }
+
+ //
+ // Constructors
+ //
+ public CodeFieldReferenceExpression ()
+ {
+ }
+
+ public CodeFieldReferenceExpression (CodeExpression targetObject,
+ string fieldName)
+ {
+ this.targetObject = targetObject;
+ this.fieldName = fieldName;
+ }
+
+ //
+ // Properties
+ //
+ public FieldDirection Direction {
+ get {
+ return direction;
+ }
+
+ set {
+ direction = value;
+ }
+ }
+
+ public string FieldName {
+ get {
+ return fieldName;
+ }
+
+ set {
+ fieldName = value;
+ }
+ }
+
+ public CodeExpression TargetObject {
+ get {
+ return targetObject;
+ }
+
+ set {
+ targetObject = value;
+ }
+ }
+
+ }
+}
diff --git a/mcs/class/System/System.CodeDom/CodeForLoopStatement.cs b/mcs/class/System/System.CodeDom/CodeForLoopStatement.cs
new file mode 100755
index 00000000000..c0b0a46ea53
--- /dev/null
+++ b/mcs/class/System/System.CodeDom/CodeForLoopStatement.cs
@@ -0,0 +1,78 @@
+//
+// System.CodeDom CodeForLoopStatement Class implementation
+//
+// Author:
+// Miguel de Icaza (miguel@ximian.com)
+//
+// (C) 2001 Ximian, Inc.
+//
+
+namespace System.CodeDom {
+
+ public class CodeForLoopStatement : CodeExpression {
+ CodeStatement initStatement, incrementStatement;
+ CodeExpression testExpression;
+ CodeStatementCollection statements;
+
+ //
+ // Constructors
+ //
+ public CodeForLoopStatement ()
+ {
+ statements = new CodeStatementCollection ();
+ }
+
+ public CodeForLoopStatement (CodeStatement initStatement,
+ CodeExpression testExpression,
+ CodeStatement incrementStatement,
+ CodeStatement [] statements)
+ {
+ this.initStatement = initStatement;
+ this.testExpression = testExpression;
+ this.incrementStatement = incrementStatement;
+ this.statements = new CodeStatementCollection ();
+ this.statements.AddRange (statements);
+ }
+
+ //
+ // Properties
+ //
+
+ public CodeStatement InitStatement {
+ get {
+ return initStatement;
+ }
+
+ set {
+ initStatement = value;
+ }
+ }
+
+ public CodeStatement IncrementStatement {
+ get {
+ return incrementStatement;
+ }
+
+ set {
+ incrementStatement = value;
+ }
+ }
+
+ public CodeStatementCollection Statements {
+ get {
+ return statements;
+ }
+ }
+
+ public CodeExpression TestExpression {
+ get {
+ return testExpression;
+ }
+
+ set {
+ testExpression = value;
+ }
+ }
+ }
+}
+
diff --git a/mcs/class/System/System.CodeDom/CodeIfStatement.cs b/mcs/class/System/System.CodeDom/CodeIfStatement.cs
new file mode 100755
index 00000000000..4ca158416b6
--- /dev/null
+++ b/mcs/class/System/System.CodeDom/CodeIfStatement.cs
@@ -0,0 +1,73 @@
+//
+// System.CodeDom CodeIfStatement Class implementation
+//
+// Author:
+// Miguel de Icaza (miguel@ximian.com)
+//
+// (C) 2001 Ximian, Inc.
+//
+
+namespace System.CodeDom {
+
+ public class CodeIfStatement : CodeStatement {
+
+ CodeExpression condition;
+ CodeStatementCollection trueStatements;
+ CodeStatementCollection falseStatements;
+
+ //
+ // Constructors
+ //
+ public CodeIfStatement ()
+ {
+ trueStatements = new CodeStatementCollection ();
+ falseStatements = new CodeStatementCollection ();
+ }
+
+ public CodeIfStatement (CodeExpression condition, CodeStatement [] trueStatements)
+ {
+ this.condition = condition;
+ this.trueStatements = new CodeStatementCollection ();
+ this.trueStatements.AddRange (trueStatements);
+ this.falseStatements = new CodeStatementCollection ();
+ }
+
+ public CodeIfStatement (CodeExpression condition,
+ CodeStatement [] trueStatements,
+ CodeStatement [] falseStatements)
+ {
+ this.condition = condition;
+
+ this.trueStatements = new CodeStatementCollection ();
+ this.trueStatements.AddRange (trueStatements);
+
+ this.falseStatements = new CodeStatementCollection ();
+ this.falseStatements.AddRange (falseStatements);
+ }
+
+ //
+ // Properties
+ //
+ public CodeExpression Condition {
+ get {
+ return condition;
+ }
+
+ set {
+ condition = value;
+ }
+ }
+
+ public CodeStatementCollection FalseStatements {
+ get {
+ return falseStatements;
+ }
+ }
+
+ public CodeStatementCollection TrueStatements {
+ get {
+ return trueStatements;
+ }
+ }
+ }
+}
diff --git a/mcs/class/System/System.CodeDom/CodeIndexerExpression.cs b/mcs/class/System/System.CodeDom/CodeIndexerExpression.cs
new file mode 100755
index 00000000000..8dbc95b44a2
--- /dev/null
+++ b/mcs/class/System/System.CodeDom/CodeIndexerExpression.cs
@@ -0,0 +1,34 @@
+//
+// System.CodeDom CodeFieldReferenceExpression Class implementation
+//
+// Author:
+// Miguel de Icaza (miguel@ximian.com)
+//
+// (C) 2001 Ximian, Inc.
+//
+
+namespace System.CodeDom {
+
+ public class CodeIndexerExpression : CodeExpression {
+ CodeExpression targetObject;
+ CodeExpression index;
+
+ //
+ // Constructors
+ //
+ public CodeIndexerExpression ()
+ {
+ }
+
+ public CodeIndexerExpression (CodeExpression targetObject, CodeExpression index)
+ {
+ this.index = index;
+ this.targetObject = targetObject;
+ }
+
+ //
+ // Properties
+ //
+ }
+}
+
diff --git a/mcs/class/System/System.CodeDom/CodeLinePragma.cs b/mcs/class/System/System.CodeDom/CodeLinePragma.cs
new file mode 100755
index 00000000000..d83a9f6c8c5
--- /dev/null
+++ b/mcs/class/System/System.CodeDom/CodeLinePragma.cs
@@ -0,0 +1,50 @@
+//
+// System.CodeDom CodeLinePragma Class implementation
+//
+// Author:
+// Miguel de Icaza (miguel@ximian.com)
+//
+// (C) 2001 Ximian, Inc.
+//
+using System;
+
+namespace System.CodeDom {
+
+ // <summary>
+ // Use objects of this class to keep track of locations where
+ // statements are defined
+ // </summary>
+ public class CodeLinePragma {
+ string fileName;
+ int lineNumber;
+
+ public CodeLinePragma (string fileName, int lineNumber)
+ {
+ this.fileName = fileName;
+ this.lineNumber = lineNumber;
+ }
+
+ //
+ // Properties
+ //
+ public string FileName {
+ get {
+ return fileName;
+ }
+
+ set {
+ fileName = value;
+ }
+ }
+
+ public int LineNumber {
+ get {
+ return lineNumber;
+ }
+
+ set {
+ lineNumber = value;
+ }
+ }
+ }
+}
diff --git a/mcs/class/System/System.CodeDom/CodeLiteralClassMember.cs b/mcs/class/System/System.CodeDom/CodeLiteralClassMember.cs
new file mode 100755
index 00000000000..0733b786a7f
--- /dev/null
+++ b/mcs/class/System/System.CodeDom/CodeLiteralClassMember.cs
@@ -0,0 +1,40 @@
+//
+// System.CodeDom CodeLiteralClassMember Class implementation
+//
+// Author:
+// Miguel de Icaza (miguel@ximian.com)
+//
+// (C) 2001 Ximian, Inc.
+//
+
+namespace System.CodeDom {
+
+ public class CodeLiteralClassMember : CodeClassMember {
+ string text;
+
+ //
+ // Constructors
+ //
+ public CodeLiteralClassMember ()
+ {
+ }
+
+ public CodeLiteralClassMember (string text)
+ {
+ this.text = text;
+ }
+
+ //
+ // Properties
+ //
+ string Text {
+ get {
+ return text;
+ }
+
+ set {
+ text = value;
+ }
+ }
+ }
+}
diff --git a/mcs/class/System/System.CodeDom/CodeLiteralExpression.cs b/mcs/class/System/System.CodeDom/CodeLiteralExpression.cs
new file mode 100755
index 00000000000..36ca6908b2c
--- /dev/null
+++ b/mcs/class/System/System.CodeDom/CodeLiteralExpression.cs
@@ -0,0 +1,40 @@
+//
+// System.CodeDom CodeLiteralExpression Class implementation
+//
+// Author:
+// Miguel de Icaza (miguel@ximian.com)
+//
+// (C) 2001 Ximian, Inc.
+//
+
+namespace System.CodeDom {
+
+ public class CodeLiteralExpression : CodeExpression {
+ string val;
+
+ //
+ // Constructors
+ //
+ public CodeLiteralExpression ()
+ {
+ }
+
+ public CodeLiteralExpression (string value)
+ {
+ val = value;
+ }
+
+ //
+ // Properties
+ //
+ string Value {
+ get {
+ return val;
+ }
+
+ set {
+ val = value;
+ }
+ }
+ }
+}
diff --git a/mcs/class/System/System.CodeDom/CodeLiteralNamespace.cs b/mcs/class/System/System.CodeDom/CodeLiteralNamespace.cs
new file mode 100755
index 00000000000..7cbf4c46b9e
--- /dev/null
+++ b/mcs/class/System/System.CodeDom/CodeLiteralNamespace.cs
@@ -0,0 +1,48 @@
+//
+// System.CodeDom CodeLiteralNamespace Class implementation
+//
+// Author:
+// Miguel de Icaza (miguel@ximian.com)
+//
+// (C) 2001 Ximian, Inc.
+//
+
+namespace System.CodeDom {
+
+ public class CodeLiteralNamespace : CodeNamespace {
+ CodeLinePragma linePragma;
+ string value;
+
+ //
+ // Constructors
+ //
+ public CodeLiteralNamespace (string value)
+ {
+ this.value = value;
+ }
+
+ //
+ // Properties
+ //
+ string Value {
+ get {
+ return value;
+ }
+
+ set {
+ this.value = value;
+ }
+ }
+
+ CodeLinePragma LinePragma {
+ get {
+ return linePragma;
+ }
+
+ set {
+ linePragma = value;
+ }
+ }
+ }
+}
+
diff --git a/mcs/class/System/System.CodeDom/CodeLiteralStatement.cs b/mcs/class/System/System.CodeDom/CodeLiteralStatement.cs
new file mode 100755
index 00000000000..63e1fec6bbb
--- /dev/null
+++ b/mcs/class/System/System.CodeDom/CodeLiteralStatement.cs
@@ -0,0 +1,36 @@
+//
+// System.CodeDom CodeLiteralStatement Class implementation
+//
+// Author:
+// Miguel de Icaza (miguel@ximian.com)
+//
+// (C) 2001 Ximian, Inc.
+//
+
+namespace System.CodeDom {
+
+ public class CodeLiteralStatement : CodeStatement {
+ string value;
+
+ //
+ // Constructors
+ //
+ public CodeLiteralStatement (string value)
+ {
+ this.value = value;
+ }
+
+ //
+ // Properties
+ //
+ string Value {
+ get {
+ return value;
+ }
+
+ set {
+ this.value = value;
+ }
+ }
+ }
+}
diff --git a/mcs/class/System/System.CodeDom/CodeMemberEvent.cs b/mcs/class/System/System.CodeDom/CodeMemberEvent.cs
new file mode 100755
index 00000000000..46f1fee42d9
--- /dev/null
+++ b/mcs/class/System/System.CodeDom/CodeMemberEvent.cs
@@ -0,0 +1,50 @@
+//
+// System.CodeDom CodeMemberEvent Class implementation
+//
+// Author:
+// Miguel de Icaza (miguel@ximian.com)
+//
+// (C) 2001 Ximian, Inc.
+//
+
+namespace System.CodeDom {
+
+ public class CodeMemberEvent : CodeClassMember {
+ string implementsType, type;
+ bool privateImplements;
+
+ public CodeMemberEvent ()
+ {
+ }
+
+ public string ImplementsType {
+ get {
+ return implementsType;
+ }
+
+ set {
+ implementsType = value;
+ }
+ }
+
+ public bool PrivateImplements {
+ get {
+ return privateImplements;
+ }
+
+ set {
+ privateImplements = value;
+ }
+ }
+
+ public string Type {
+ get {
+ return type;
+ }
+
+ set {
+ type = value;
+ }
+ }
+ }
+}
diff --git a/mcs/class/System/System.CodeDom/CodeMemberField.cs b/mcs/class/System/System.CodeDom/CodeMemberField.cs
new file mode 100755
index 00000000000..ac8b1d3ab79
--- /dev/null
+++ b/mcs/class/System/System.CodeDom/CodeMemberField.cs
@@ -0,0 +1,49 @@
+//
+// System.CodeDom CodeMemberField Class implementation
+//
+// Author:
+// Miguel de Icaza (miguel@ximian.com)
+//
+// (C) 2001 Ximian, Inc.
+//
+
+namespace System.CodeDom {
+
+ public class CodeMemberField : CodeClassMember {
+ CodeExpression initExpression;
+ string type, name;
+
+ public CodeMemberField ()
+ {
+ }
+
+ public CodeMemberField (string type, string name)
+ {
+ this.type = type;
+ this.name = name;
+ }
+
+ //
+ // Properties
+ //
+ public CodeExpression InitExpression {
+ get {
+ return initExpression;
+ }
+
+ set {
+ initExpression = value;
+ }
+ }
+
+ public string Type {
+ get {
+ return type;
+ }
+
+ set {
+ type = name;
+ }
+ }
+ }
+}
diff --git a/mcs/class/System/System.CodeDom/CodeMemberMethod.cs b/mcs/class/System/System.CodeDom/CodeMemberMethod.cs
new file mode 100755
index 00000000000..aa417a2aeee
--- /dev/null
+++ b/mcs/class/System/System.CodeDom/CodeMemberMethod.cs
@@ -0,0 +1,73 @@
+//
+// System.CodeDom CodeMemberMethod Class implementation
+//
+// Author:
+// Miguel de Icaza (miguel@ximian.com)
+//
+// (C) 2001 Ximian, Inc.
+//
+
+namespace System.CodeDom {
+
+ public class CodeMemberMethod : CodeClassMember {
+ CodeParameterDeclarationExpressionCollection parameters;
+ CodeStatementCollection statements;
+ string implementsType;
+ string returnType;
+ bool privateImplements;
+
+ public CodeMemberMethod ()
+ {
+ }
+
+ public string ImplementsType {
+ get {
+ return implementsType;
+ }
+
+ set {
+ implementsType = value;
+ }
+ }
+
+ public bool PrivateImplements {
+ get {
+ return privateImplements;
+ }
+
+ set {
+ privateImplements = value;
+ }
+ }
+
+ public string ReturnType {
+ get {
+ return returnType;
+ }
+
+ set {
+ returnType = value;
+ }
+ }
+
+ public CodeParameterDeclarationExpressionCollection Parameters {
+ get {
+ return parameters;
+ }
+
+ set {
+ parameters = value;
+ }
+ }
+
+ public CodeStatementCollection Statements {
+ get {
+ return statements;
+ }
+
+ set {
+ statements = value;
+ }
+ }
+ }
+}
diff --git a/mcs/class/System/System.CodeDom/CodeMemberProperty.cs b/mcs/class/System/System.CodeDom/CodeMemberProperty.cs
new file mode 100755
index 00000000000..8889de098a0
--- /dev/null
+++ b/mcs/class/System/System.CodeDom/CodeMemberProperty.cs
@@ -0,0 +1,108 @@
+//
+// System.CodeDom CodeMemberProperty Class implementation
+//
+// Author:
+// Miguel de Icaza (miguel@ximian.com)
+//
+// (C) 2001 Ximian, Inc.
+//
+
+namespace System.CodeDom {
+
+ public class CodeMemberProperty : CodeClassMember {
+ CodeParameterDeclarationExpressionCollection parameters;
+ CodeStatementCollection getStatements, setStatements;
+ bool hasGet, hasSet;
+ string implementsType, type;
+ bool privateImplements;
+
+ public CodeMemberProperty ()
+ {
+ }
+
+ //
+ // Properties
+ //
+
+ public string ImplementsType {
+ get {
+ return implementsType;
+ }
+
+ set {
+ implementsType = value;
+ }
+ }
+
+ public bool PrivateImplements {
+ get {
+ return privateImplements;
+ }
+
+ set {
+ privateImplements = value;
+ }
+ }
+
+ public CodeParameterDeclarationExpressionCollection Parameters {
+ get {
+ return parameters;
+ }
+
+ set {
+ parameters = value;
+ }
+ }
+
+ public CodeStatementCollection SetStatements {
+ get {
+ return setStatements;
+ }
+
+ set {
+ setStatements = value;
+ }
+ }
+
+ public CodeStatementCollection GetStatements {
+ get {
+ return getStatements;
+ }
+
+ set {
+ getStatements = value;
+ }
+ }
+
+ public string Type {
+ get {
+ return type;
+ }
+
+ set {
+ type = value;
+ }
+ }
+
+ public bool HasGet {
+ get {
+ return hasGet;
+ }
+
+ set {
+ hasGet = value;
+ }
+ }
+
+ public bool HasSet {
+ get {
+ return hasSet;
+ }
+
+ set {
+ hasSet = value;
+ }
+ }
+ }
+}
+
diff --git a/mcs/class/System/System.CodeDom/CodeMethodInvokeExpression.cs b/mcs/class/System/System.CodeDom/CodeMethodInvokeExpression.cs
new file mode 100755
index 00000000000..cb51ff9b5d4
--- /dev/null
+++ b/mcs/class/System/System.CodeDom/CodeMethodInvokeExpression.cs
@@ -0,0 +1,68 @@
+//
+// System.CodeDom CodeMethodInvokeExpression Class implementation
+//
+// Author:
+// Miguel de Icaza (miguel@ximian.com)
+//
+// (C) 2001 Ximian, Inc.
+//
+
+namespace System.CodeDom {
+
+ public class CodeMethodInvokeExpression : CodeExpression {
+ string methodName;
+ CodeExpression targetObject;
+ CodeExpressionCollection parameters;
+
+ //
+ // Constructors
+ //
+ public CodeMethodInvokeExpression () {}
+
+ public CodeMethodInvokeExpression (CodeExpression targetObject, string methodName)
+ {
+ this.targetObject = targetObject;
+ this.methodName = methodName;
+ }
+
+ public CodeMethodInvokeExpression (CodeExpression targetObject,
+ string methodName,
+ CodeExpression [] parameters)
+ {
+ this.targetObject = targetObject;
+ this.methodName = methodName;
+ this.parameters = new CodeExpressionCollection ();
+ this.parameters.AddRange (parameters);
+ }
+
+ public string MethodName {
+ get {
+ return methodName;
+ }
+
+ set {
+ methodName = value;
+ }
+ }
+
+ public CodeExpressionCollection Parameters {
+ get {
+ return parameters;
+ }
+
+ set {
+ parameters = value;
+ }
+ }
+
+ public CodeExpression TargetObject {
+ get {
+ return targetObject;
+ }
+
+ set {
+ targetObject = value;
+ }
+ }
+ }
+}
diff --git a/mcs/class/System/System.CodeDom/CodeMethodInvokeStatement.cs b/mcs/class/System/System.CodeDom/CodeMethodInvokeStatement.cs
new file mode 100755
index 00000000000..519e4164ad5
--- /dev/null
+++ b/mcs/class/System/System.CodeDom/CodeMethodInvokeStatement.cs
@@ -0,0 +1,84 @@
+//
+// System.CodeDom CodeMethodInvokeStatement Class implementation
+//
+// Author:
+// Miguel de Icaza (miguel@ximian.com)
+//
+// (C) 2001 Ximian, Inc.
+//
+
+namespace System.CodeDom {
+
+ public class CodeMethodInvokeStatement : CodeStatement {
+ string methodName;
+ CodeExpression targetObject;
+ CodeExpressionCollection parameters;
+ CodeMethodInvokeExpression methodInvoke;
+
+ //
+ // Constructors
+ //
+ public CodeMethodInvokeStatement () {}
+
+ public CodeMethodInvokeStatement (CodeMethodInvokeExpression methodInvoke)
+ {
+ this.methodInvoke = methodInvoke;
+ }
+
+ public CodeMethodInvokeStatement (CodeExpression targetObject, string methodName)
+ {
+ this.targetObject = targetObject;
+ this.methodName = methodName;
+ }
+
+ public CodeMethodInvokeStatement (CodeExpression targetObject,
+ string methodName,
+ CodeExpression [] parameters)
+ {
+ this.targetObject = targetObject;
+ this.methodName = methodName;
+ this.parameters = new CodeExpressionCollection ();
+ this.parameters.AddRange (parameters);
+ }
+
+ public string MethodName {
+ get {
+ return methodName;
+ }
+
+ set {
+ methodName = value;
+ }
+ }
+
+ public CodeExpressionCollection Parameters {
+ get {
+ return parameters;
+ }
+
+ set {
+ parameters = value;
+ }
+ }
+
+ public CodeExpression TargetObject {
+ get {
+ return targetObject;
+ }
+
+ set {
+ targetObject = value;
+ }
+ }
+
+ public CodeMethodInvokeExpression MethodInvoke {
+ get {
+ return methodInvoke;
+ }
+
+ set {
+ methodInvoke = value;
+ }
+ }
+ }
+}
diff --git a/mcs/class/System/System.CodeDom/CodeMethodReturnStatement.cs b/mcs/class/System/System.CodeDom/CodeMethodReturnStatement.cs
new file mode 100755
index 00000000000..02d51b42410
--- /dev/null
+++ b/mcs/class/System/System.CodeDom/CodeMethodReturnStatement.cs
@@ -0,0 +1,12 @@
+//
+// System.CodeDom CodeMethodReturnStatement class implementation
+//
+// Author:
+// Sean MacIsaac (macisaac@ximian.com)
+//
+// (C) 2001 Ximian, Inc.
+//
+
+public class CodeMethodReturnStatement : CodeStatement {
+
+}
diff --git a/mcs/class/System/System.CodeDom/CodeNamespace.cs b/mcs/class/System/System.CodeDom/CodeNamespace.cs
new file mode 100755
index 00000000000..0794653cfd8
--- /dev/null
+++ b/mcs/class/System/System.CodeDom/CodeNamespace.cs
@@ -0,0 +1,92 @@
+//
+// System.CodeDom CodeNamespace Class implementation
+//
+// Author:
+// Miguel de Icaza (miguel@ximian.com)
+//
+// (C) 2001 Ximian, Inc.
+//
+
+namespace System.CodeDom {
+
+ public class CodeNamespace {
+ CodeClassCollection classes;
+ CodeNamespaceImportCollection imports;
+ bool allowLateBound, requireVariableDeclaration;
+ string name;
+ object userData;
+
+ public CodeNamespace ()
+ {
+ }
+
+ public CodeNamespace (string name)
+ {
+ this.name = name;
+ }
+
+ //
+ // Properties
+ //
+
+ public bool AllowLateBound {
+ get {
+ return allowLateBound;
+ }
+
+ set {
+ allowLateBound = value;
+ }
+ }
+
+ public CodeClassCollection Classes {
+ get {
+ return classes;
+ }
+
+ set {
+ classes = value;
+ }
+ }
+
+ public CodeNamespaceImportCollection Imports {
+ get {
+ return imports;
+ }
+
+ set {
+ imports = value;
+ }
+ }
+
+ public string Name {
+ get {
+ return name;
+ }
+
+ set {
+ name = value;
+ }
+ }
+
+ public bool RequireVariableDeclaration {
+ get {
+ return requireVariableDeclaration;
+ }
+
+ set {
+ requireVariableDeclaration = value;
+ }
+ }
+
+ public object UserData {
+ get {
+ return userData;
+ }
+
+ set {
+ userData = value;
+ }
+ }
+ }
+}
diff --git a/mcs/class/System/System.CodeDom/CodeNamespaceImport.cs b/mcs/class/System/System.CodeDom/CodeNamespaceImport.cs
new file mode 100755
index 00000000000..d13767c588e
--- /dev/null
+++ b/mcs/class/System/System.CodeDom/CodeNamespaceImport.cs
@@ -0,0 +1,36 @@
+//
+// System.CodeDom CodeNamespaceImport Class implementation
+//
+// Author:
+// Miguel de Icaza (miguel@ximian.com)
+//
+// (C) 2001 Ximian, Inc.
+//
+
+namespace System.CodeDom {
+
+ public class CodeNamespaceImport : CodeStatement {
+ string nameSpace;
+
+ public CodeNamespaceImport () {}
+
+ public CodeNamespaceImport (string nameSpace)
+ {
+ this.nameSpace = nameSpace;
+ }
+
+ //
+ // Properties
+ //
+
+ public string Namespace {
+ get {
+ return nameSpace;
+ }
+
+ set {
+ nameSpace = value;
+ }
+ }
+ }
+}
diff --git a/mcs/class/System/System.CodeDom/CodeNamespaceImportCollection.cs b/mcs/class/System/System.CodeDom/CodeNamespaceImportCollection.cs
new file mode 100755
index 00000000000..d65ee247c4d
--- /dev/null
+++ b/mcs/class/System/System.CodeDom/CodeNamespaceImportCollection.cs
@@ -0,0 +1,165 @@
+//
+// System.CodeDom CodeNamespaceImportCollection Class implementation
+//
+// Author:
+// Miguel de Icaza (miguel@ximian.com)
+//
+// (C) 2001 Ximian, Inc.
+//
+
+namespace System.CodeDom {
+
+ using System.Collections;
+
+ public class CodeNamespaceImportCollection : IList, ICollection, IEnumerable {
+
+ ArrayList namespaceImports;
+
+ //
+ // Constructors
+ //
+ public CodeNamespaceImportCollection ()
+ {
+ namespaceImports = new ArrayList ();
+ }
+
+ //
+ // Properties
+ //
+ public int Count {
+ get {
+ return namespaceImports.Count;
+ }
+ }
+
+ public bool IsFixedSize {
+ get {
+ return true;
+ }
+ }
+
+ //
+ // Methods
+ //
+ public void Add (CodeNamespaceImport value)
+ {
+ namespaceImports.Add (value);
+ }
+
+ public void AddRange (CodeNamespaceImport [] values)
+ {
+ foreach (CodeNamespaceImport ca in values)
+ namespaceImports.Add (ca);
+
+ }
+
+ public void Clear ()
+ {
+ namespaceImports.Clear ();
+ }
+
+ private class Enumerator : IEnumerator {
+ private CodeNamespaceImportCollection collection;
+ private int currentIndex = -1;
+
+ internal Enumerator (CodeNamespaceImportCollection collection)
+ {
+ this.collection = collection;
+ }
+
+ public object Current {
+ get {
+ if (currentIndex == collection.Count)
+ throw new InvalidOperationException ();
+ return collection [currentIndex];
+ }
+ }
+
+ public bool MoveNext ()
+ {
+ if (currentIndex > collection.Count)
+ throw new InvalidOperationException ();
+ return ++currentIndex < collection.Count;
+ }
+
+ public void Reset ()
+ {
+ currentIndex = -1;
+ }
+ }
+
+ public IEnumerator GetEnumerator ()
+ {
+ return new CodeNamespaceImportCollection.Enumerator (this);
+ }
+
+ //
+ // IList method implementations
+ //
+ public int Add (object value)
+ {
+ return namespaceImports.Add (value);
+ }
+
+ public bool Contains (Object value)
+ {
+ return namespaceImports.Contains (value);
+ }
+
+ public int IndexOf (Object value)
+ {
+ return namespaceImports.IndexOf (value);
+ }
+
+ public void Insert (int index, Object value)
+ {
+ namespaceImports [index] = value;
+ }
+
+ public object this[int index] {
+ get {
+ return namespaceImports [index];
+ }
+
+ set {
+ namespaceImports [index] = value;
+ }
+ }
+
+ public void Remove (object value)
+ {
+ namespaceImports.Remove (value);
+ }
+
+ public void RemoveAt (int index)
+ {
+ namespaceImports.RemoveAt (index);
+ }
+
+ //
+ // ICollection method implementations
+ //
+ public void CopyTo (Array array, int index)
+ {
+ namespaceImports.CopyTo (array, index);
+ }
+
+ public object SyncRoot {
+ get {
+ return namespaceImports.SyncRoot;
+ }
+ }
+
+ public bool IsReadOnly {
+ get {
+ return false;
+ }
+ }
+
+ public bool IsSynchronized {
+ get {
+ return namespaceImports.IsSynchronized;
+ }
+ }
+ }
+}
diff --git a/mcs/class/System/System.CodeDom/CodeObject.cs b/mcs/class/System/System.CodeDom/CodeObject.cs
new file mode 100755
index 00000000000..b2c38638f96
--- /dev/null
+++ b/mcs/class/System/System.CodeDom/CodeObject.cs
@@ -0,0 +1,12 @@
+//
+// System.CodeDom CodeObject class implementation
+//
+// Author:
+// Sean MacIsaac (macisaac@ximian.com)
+//
+// (C) 2001 Ximian, Inc.
+//
+
+public class CodeObject {
+
+}
diff --git a/mcs/class/System/System.CodeDom/CodeObjectCreateExpression.cs b/mcs/class/System/System.CodeDom/CodeObjectCreateExpression.cs
new file mode 100755
index 00000000000..421d2aa29de
--- /dev/null
+++ b/mcs/class/System/System.CodeDom/CodeObjectCreateExpression.cs
@@ -0,0 +1,54 @@
+//
+// System.CodeDom CodeObjectCreateExpression Class implementation
+//
+// Author:
+// Miguel de Icaza (miguel@ximian.com)
+//
+// (C) 2001 Ximian, Inc.
+//
+
+namespace System.CodeDom {
+
+ public class CodeObjectCreateExpression : CodeExpression {
+ string createType;
+ CodeExpressionCollection parameters;
+
+ public CodeObjectCreateExpression () {}
+
+ public CodeObjectCreateExpression (string createType)
+ {
+ this.createType = createType;
+ }
+
+ public CodeObjectCreateExpression (string createType, CodeExpression [] parameters)
+ {
+ this.createType = createType;
+ this.parameters = new CodeExpressionCollection ();
+ this.parameters.AddRange (parameters);
+ }
+
+ //
+ // Properties
+ //
+ public string CreateType {
+ get {
+ return createType;
+ }
+
+ set {
+ createType = value;
+ }
+ }
+
+ public CodeExpressionCollection Parameters {
+ get {
+ return parameters;
+ }
+
+ set {
+ parameters = value;
+ }
+ }
+
+ }
+}
diff --git a/mcs/class/System/System.CodeDom/CodeParameterDeclarationExpression.cs b/mcs/class/System/System.CodeDom/CodeParameterDeclarationExpression.cs
new file mode 100755
index 00000000000..93f4b0ee7b0
--- /dev/null
+++ b/mcs/class/System/System.CodeDom/CodeParameterDeclarationExpression.cs
@@ -0,0 +1,68 @@
+//
+// System.CodeDom CodeParameterDeclarationExpression Class implementation
+//
+// Author:
+// Miguel de Icaza (miguel@ximian.com)
+//
+// (C) 2001 Ximian, Inc.
+//
+
+namespace System.CodeDom {
+
+ public class CodeParameterDeclarationExpression : CodeExpression {
+ FieldDirection direction;
+ CodeAttributeBlock customAttributes;
+ string type, name;
+
+ public CodeParameterDeclarationExpression ()
+ {
+ }
+
+ public CodeParameterDeclarationExpression (string type, string name)
+ {
+ this.type = type;
+ this.name = name;
+ }
+
+ public string Type {
+ get {
+ return type;
+ }
+
+ set {
+ type = value;
+ }
+ }
+
+ public string Name {
+ get {
+ return name;
+ }
+
+ set {
+ name = value;
+ }
+ }
+
+ public CodeAttributeBlock CustomAttributes {
+ get {
+ return customAttributes;
+ }
+
+ set {
+ customAttributes = value;
+ }
+ }
+
+ public FieldDirection Direction {
+ get {
+ return direction;
+ }
+
+ set {
+ direction = value;
+ }
+ }
+ }
+}
+
diff --git a/mcs/class/System/System.CodeDom/CodeParameterDeclarationExpressionCollection.cs b/mcs/class/System/System.CodeDom/CodeParameterDeclarationExpressionCollection.cs
new file mode 100755
index 00000000000..970e9ec78e7
--- /dev/null
+++ b/mcs/class/System/System.CodeDom/CodeParameterDeclarationExpressionCollection.cs
@@ -0,0 +1,165 @@
+//
+// System.CodeDom CodeParameterDeclarationExpressionCollection Class implementation
+//
+// Author:
+// Miguel de Icaza (miguel@ximian.com)
+//
+// (C) 2001 Ximian, Inc.
+//
+
+namespace System.CodeDom {
+
+ using System.Collections;
+
+ public class CodeParameterDeclarationExpressionCollection : IList, ICollection, IEnumerable {
+
+ ArrayList parameterDeclExprs;
+
+ //
+ // Constructors
+ //
+ public CodeParameterDeclarationExpressionCollection ()
+ {
+ parameterDeclExprs = new ArrayList ();
+ }
+
+ //
+ // Properties
+ //
+ public int Count {
+ get {
+ return parameterDeclExprs.Count;
+ }
+ }
+
+ public bool IsFixedSize {
+ get {
+ return true;
+ }
+ }
+
+ //
+ // Methods
+ //
+ public void Add (CodeParameterDeclarationExpression value)
+ {
+ parameterDeclExprs.Add (value);
+ }
+
+ public void AddRange (CodeParameterDeclarationExpression [] values)
+ {
+ foreach (CodeParameterDeclarationExpression ca in values)
+ parameterDeclExprs.Add (ca);
+
+ }
+
+ public void Clear ()
+ {
+ parameterDeclExprs.Clear ();
+ }
+
+ private class Enumerator : IEnumerator {
+ private CodeParameterDeclarationExpressionCollection collection;
+ private int currentIndex = -1;
+
+ internal Enumerator (CodeParameterDeclarationExpressionCollection collection)
+ {
+ this.collection = collection;
+ }
+
+ public object Current {
+ get {
+ if (currentIndex == collection.Count)
+ throw new InvalidOperationException ();
+ return collection [currentIndex];
+ }
+ }
+
+ public bool MoveNext ()
+ {
+ if (currentIndex > collection.Count)
+ throw new InvalidOperationException ();
+ return ++currentIndex < collection.Count;
+ }
+
+ public void Reset ()
+ {
+ currentIndex = -1;
+ }
+ }
+
+ public IEnumerator GetEnumerator ()
+ {
+ return new CodeParameterDeclarationExpressionCollection.Enumerator (this);
+ }
+
+ //
+ // IList method implementations
+ //
+ public int Add (object value)
+ {
+ return parameterDeclExprs.Add (value);
+ }
+
+ public bool Contains (Object value)
+ {
+ return parameterDeclExprs.Contains (value);
+ }
+
+ public int IndexOf (Object value)
+ {
+ return parameterDeclExprs.IndexOf (value);
+ }
+
+ public void Insert (int index, Object value)
+ {
+ parameterDeclExprs [index] = value;
+ }
+
+ public object this[int index] {
+ get {
+ return parameterDeclExprs [index];
+ }
+
+ set {
+ parameterDeclExprs [index] = value;
+ }
+ }
+
+ public void Remove (object value)
+ {
+ parameterDeclExprs.Remove (value);
+ }
+
+ public void RemoveAt (int index)
+ {
+ parameterDeclExprs.RemoveAt (index);
+ }
+
+ //
+ // ICollection method implementations
+ //
+ public void CopyTo (Array array, int index)
+ {
+ parameterDeclExprs.CopyTo (array, index);
+ }
+
+ public object SyncRoot {
+ get {
+ return parameterDeclExprs.SyncRoot;
+ }
+ }
+
+ public bool IsReadOnly {
+ get {
+ return false;
+ }
+ }
+
+ public bool IsSynchronized {
+ get {
+ return parameterDeclExprs.IsSynchronized;
+ }
+ }
+ }
+}
diff --git a/mcs/class/System/System.CodeDom/CodePrimitiveExpression.cs b/mcs/class/System/System.CodeDom/CodePrimitiveExpression.cs
new file mode 100755
index 00000000000..98d64e3ae0a
--- /dev/null
+++ b/mcs/class/System/System.CodeDom/CodePrimitiveExpression.cs
@@ -0,0 +1,33 @@
+//
+// System.CodeDom CodePrimitiveExpression Class implementation
+//
+// Author:
+// Miguel de Icaza (miguel@ximian.com)
+//
+// (C) 2001 Ximian, Inc.
+//
+
+namespace System.CodeDom {
+
+ public class CodePrimitiveExpression : CodeExpression {
+ object value;
+
+ public CodePrimitiveExpression () {}
+
+ public CodePrimitiveExpression (Object value)
+ {
+ this.value = value;
+ }
+
+ public object Value {
+ get {
+ return value;
+ }
+
+ set {
+ this.value = value;
+ }
+ }
+ }
+}
+
diff --git a/mcs/class/System/System.CodeDom/CodePropertyReferenceExpression.cs b/mcs/class/System/System.CodeDom/CodePropertyReferenceExpression.cs
new file mode 100755
index 00000000000..13f4471ce0c
--- /dev/null
+++ b/mcs/class/System/System.CodeDom/CodePropertyReferenceExpression.cs
@@ -0,0 +1,59 @@
+//
+// System.CodeDom CodePropertyReferenceExpression Class implementation
+//
+// Author:
+// Miguel de Icaza (miguel@ximian.com)
+//
+// (C) 2001 Ximian, Inc.
+//
+
+namespace System.CodeDom {
+
+ public class CodePropertyReferenceExpression : CodeExpression {
+ CodeExpressionCollection parameters;
+ CodeExpression targetObject;
+ string propertyName;
+
+ public CodePropertyReferenceExpression () {}
+
+ public CodePropertyReferenceExpression (CodeExpression targetObject,
+ string propertyName)
+ {
+ this.targetObject = targetObject;
+ this.propertyName = propertyName;
+ }
+
+ //
+ // Properties
+ //
+ public CodeExpressionCollection Parameter {
+ get {
+ return parameters;
+ }
+
+ set {
+ parameters = value;
+ }
+ }
+
+ public string PropertyName {
+ get {
+ return propertyName;
+ }
+
+ set {
+ propertyName = value;
+ }
+ }
+
+ public CodeExpression TargetObject {
+ get {
+ return targetObject;
+ }
+
+ set {
+ targetObject = value;
+ }
+ }
+ }
+}
diff --git a/mcs/class/System/System.CodeDom/CodeStatement.cs b/mcs/class/System/System.CodeDom/CodeStatement.cs
new file mode 100755
index 00000000000..400a4854b4d
--- /dev/null
+++ b/mcs/class/System/System.CodeDom/CodeStatement.cs
@@ -0,0 +1,12 @@
+//
+// System.CodeDom CodeStatement class implementation
+//
+// Author:
+// Sean MacIsaac (macisaac@ximian.com)
+//
+// (C) 2001 Ximian, Inc.
+//
+
+public class CodeStatement : CodeObject {
+
+}
diff --git a/mcs/class/System/System.CodeDom/CodeStatementCollection.cs b/mcs/class/System/System.CodeDom/CodeStatementCollection.cs
new file mode 100755
index 00000000000..6a70aeafd2a
--- /dev/null
+++ b/mcs/class/System/System.CodeDom/CodeStatementCollection.cs
@@ -0,0 +1,165 @@
+//
+// System.CodeDom CodeStatementCollection Class implementation
+//
+// Author:
+// Miguel de Icaza (miguel@ximian.com)
+//
+// (C) 2001 Ximian, Inc.
+//
+
+namespace System.CodeDom {
+
+ using System.Collections;
+
+ public class CodeStatementCollection : IList, ICollection, IEnumerable {
+
+ ArrayList statements;
+
+ //
+ // Constructors
+ //
+ public CodeStatementCollection ()
+ {
+ statements = new ArrayList ();
+ }
+
+ //
+ // Properties
+ //
+ public int Count {
+ get {
+ return statements.Count;
+ }
+ }
+
+ public bool IsFixedSize {
+ get {
+ return true;
+ }
+ }
+
+ //
+ // Methods
+ //
+ public void Add (CodeStatement value)
+ {
+ statements.Add (value);
+ }
+
+ public void AddRange (CodeStatement [] values)
+ {
+ foreach (CodeStatement ca in values)
+ statements.Add (ca);
+
+ }
+
+ public void Clear ()
+ {
+ statements.Clear ();
+ }
+
+ private class Enumerator : IEnumerator {
+ private CodeStatementCollection collection;
+ private int currentIndex = -1;
+
+ internal Enumerator (CodeStatementCollection collection)
+ {
+ this.collection = collection;
+ }
+
+ public object Current {
+ get {
+ if (currentIndex == collection.Count)
+ throw new InvalidOperationException ();
+ return collection [currentIndex];
+ }
+ }
+
+ public bool MoveNext ()
+ {
+ if (currentIndex > collection.Count)
+ throw new InvalidOperationException ();
+ return ++currentIndex < collection.Count;
+ }
+
+ public void Reset ()
+ {
+ currentIndex = -1;
+ }
+ }
+
+ public IEnumerator GetEnumerator ()
+ {
+ return new CodeStatementCollection.Enumerator (this);
+ }
+
+ //
+ // IList method implementations
+ //
+ public int Add (object value)
+ {
+ return statements.Add (value);
+ }
+
+ public bool Contains (Object value)
+ {
+ return statements.Contains (value);
+ }
+
+ public int IndexOf (Object value)
+ {
+ return statements.IndexOf (value);
+ }
+
+ public void Insert (int index, Object value)
+ {
+ statements [index] = value;
+ }
+
+ public object this[int index] {
+ get {
+ return statements [index];
+ }
+
+ set {
+ statements [index] = value;
+ }
+ }
+
+ public void Remove (object value)
+ {
+ statements.Remove (value);
+ }
+
+ public void RemoveAt (int index)
+ {
+ statements.RemoveAt (index);
+ }
+
+ //
+ // ICollection method implementations
+ //
+ public void CopyTo (Array array, int index)
+ {
+ statements.CopyTo (array, index);
+ }
+
+ public object SyncRoot {
+ get {
+ return statements.SyncRoot;
+ }
+ }
+
+ public bool IsReadOnly {
+ get {
+ return false;
+ }
+ }
+
+ public bool IsSynchronized {
+ get {
+ return statements.IsSynchronized;
+ }
+ }
+ }
+}
diff --git a/mcs/class/System/System.CodeDom/CodeThisReferenceExpression.cs b/mcs/class/System/System.CodeDom/CodeThisReferenceExpression.cs
new file mode 100755
index 00000000000..4084e04f7b2
--- /dev/null
+++ b/mcs/class/System/System.CodeDom/CodeThisReferenceExpression.cs
@@ -0,0 +1,16 @@
+//
+// System.CodeDom CodeParameterDeclarationExpression Class implementation
+//
+// Author:
+// Miguel de Icaza (miguel@ximian.com)
+//
+// (C) 2001 Ximian, Inc.
+//
+
+namespace System.CodeDom {
+
+ public class CodeThisReferenceExpression : CodeExpression {
+ public CodeThisReferenceExpression () { }
+ }
+}
+
diff --git a/mcs/class/System/System.CodeDom/CodeThrowExceptionStatement.cs b/mcs/class/System/System.CodeDom/CodeThrowExceptionStatement.cs
new file mode 100755
index 00000000000..4b3071515be
--- /dev/null
+++ b/mcs/class/System/System.CodeDom/CodeThrowExceptionStatement.cs
@@ -0,0 +1,31 @@
+//
+// System.CodeDom CodeThrowExceptionStatement Class implementation
+//
+// Author:
+// Miguel de Icaza (miguel@ximian.com)
+//
+// (C) 2001 Ximian, Inc.
+//
+
+namespace System.CodeDom {
+
+ public class CodeThrowExceptionStatement : CodeStatement {
+ CodeExpression toThrow;
+
+ public CodeThrowExceptionStatement () {}
+ public CodeThrowExceptionStatement (CodeExpression toThrow)
+ {
+ this.toThrow = toThrow;
+ }
+
+ public CodeExpression ToThrow {
+ get {
+ return toThrow;
+ }
+
+ set {
+ toThrow = value;
+ }
+ }
+ }
+}
diff --git a/mcs/class/System/System.CodeDom/CodeTryCatchFinallyStatement.cs b/mcs/class/System/System.CodeDom/CodeTryCatchFinallyStatement.cs
new file mode 100755
index 00000000000..2ad078a9d4e
--- /dev/null
+++ b/mcs/class/System/System.CodeDom/CodeTryCatchFinallyStatement.cs
@@ -0,0 +1,70 @@
+//
+// System.CodeDom CodeTryCatchFinallyStatement Class implementation
+//
+// Author:
+// Miguel de Icaza (miguel@ximian.com)
+//
+// (C) 2001 Ximian, Inc.
+//
+
+namespace System.CodeDom {
+
+ public class CodeTryCatchFinallyStatement : CodeStatement {
+ CodeStatementCollection tryStatements, finallyStatements;
+ CodeCatchClauseCollection catchClauses;
+
+ public CodeTryCatchFinallyStatement () {}
+
+ public CodeTryCatchFinallyStatement (CodeStatement [] tryStatements,
+ CodeCatchClause [] catchClauses)
+ {
+ this.tryStatements = new CodeStatementCollection ();
+ this.catchClauses = new CodeCatchClauseCollection ();
+
+ this.tryStatements.AddRange (tryStatements);
+ this.catchClauses.AddRange (catchClauses);
+ }
+
+ public CodeTryCatchFinallyStatement (CodeStatement [] tryStatements,
+ CodeCatchClause [] catchClauses,
+ CodeStatement [] finallyStatements)
+ {
+ this.tryStatements = new CodeStatementCollection ();
+ this.catchClauses = new CodeCatchClauseCollection ();
+ this.finallyStatements = new CodeStatementCollection ();
+
+ this.tryStatements.AddRange (tryStatements);
+ this.catchClauses.AddRange (catchClauses);
+ this.finallyStatements.AddRange (finallyStatements);
+ }
+
+ public CodeStatementCollection FinallyStatements{
+ get {
+ return finallyStatements;
+ }
+
+ set {
+ finallyStatements = value;
+ }
+ }
+
+ public CodeStatementCollection TryStatements {
+ get {
+ return tryStatements;
+ }
+
+ set {
+ tryStatements = value;
+ }
+ }
+ public CodeCatchClauseCollection CatchClauses {
+ get {
+ return catchClauses;
+ }
+
+ set {
+ catchClauses = value;
+ }
+ }
+ }
+}
diff --git a/mcs/class/System/System.CodeDom/CodeTypeDeclaration.cs b/mcs/class/System/System.CodeDom/CodeTypeDeclaration.cs
new file mode 100755
index 00000000000..acbe14bda67
--- /dev/null
+++ b/mcs/class/System/System.CodeDom/CodeTypeDeclaration.cs
@@ -0,0 +1,11 @@
+//
+// System.CodeDom CodeTypeDeclaration Class implementation
+//
+// Author:
+// Sean MacIsaac (macisaac@ximian.com)
+//
+// (C) 2001 Ximian, Inc.
+//
+
+public class CodeTypeDeclaration : CodeTypeMember {
+}
diff --git a/mcs/class/System/System.CodeDom/CodeTypeMember.cs b/mcs/class/System/System.CodeDom/CodeTypeMember.cs
new file mode 100755
index 00000000000..5bcbb09b5de
--- /dev/null
+++ b/mcs/class/System/System.CodeDom/CodeTypeMember.cs
@@ -0,0 +1,21 @@
+//
+// System.CodeDom CodeTypeMember Class implementation
+//
+// Author:
+// Sean MacIsaac (macisaac@ximian.com)
+//
+// (C) 2001 Ximian, Inc.
+//
+
+public class CodeTypeMember : CodeObject {
+ private string name;
+
+ public string Name {
+ get {
+ return name;
+ }
+ set {
+ name = value;
+ }
+ }
+}
diff --git a/mcs/class/System/System.CodeDom/CodeTypeOfExpression.cs b/mcs/class/System/System.CodeDom/CodeTypeOfExpression.cs
new file mode 100755
index 00000000000..3a496f95923
--- /dev/null
+++ b/mcs/class/System/System.CodeDom/CodeTypeOfExpression.cs
@@ -0,0 +1,32 @@
+//
+// System.CodeDom CodeTypeOfExpression Class implementation
+//
+// Author:
+// Miguel de Icaza (miguel@ximian.com)
+//
+// (C) 2001 Ximian, Inc.
+//
+
+namespace System.CodeDom {
+
+ public class CodeTypeOfExpression : CodeExpression {
+ string type;
+
+ public CodeTypeOfExpression () {}
+
+ public CodeTypeOfExpression (string type)
+ {
+ this.type = type;
+ }
+
+ public string Type {
+ get {
+ return type;
+ }
+
+ set {
+ type = value;
+ }
+ }
+ }
+}
diff --git a/mcs/class/System/System.CodeDom/CodeTypeReferenceExpression.cs b/mcs/class/System/System.CodeDom/CodeTypeReferenceExpression.cs
new file mode 100755
index 00000000000..8fcbc04ef77
--- /dev/null
+++ b/mcs/class/System/System.CodeDom/CodeTypeReferenceExpression.cs
@@ -0,0 +1,32 @@
+//
+// System.CodeDom CodeTypeReferenceExpression Class implementation
+//
+// Author:
+// Miguel de Icaza (miguel@ximian.com)
+//
+// (C) 2001 Ximian, Inc.
+//
+
+namespace System.CodeDom {
+
+ public class CodeTypeReferenceExpression : CodeExpression {
+ string type;
+
+ public CodeTypeReferenceExpression () {}
+
+ public CodeTypeReferenceExpression (string type)
+ {
+ this.type = type;
+ }
+
+ public string Type {
+ get {
+ return type;
+ }
+
+ set {
+ type = value;
+ }
+ }
+ }
+}
diff --git a/mcs/class/System/System.CodeDom/CodeVariableDeclarationStatement.cs b/mcs/class/System/System.CodeDom/CodeVariableDeclarationStatement.cs
new file mode 100755
index 00000000000..faff810835f
--- /dev/null
+++ b/mcs/class/System/System.CodeDom/CodeVariableDeclarationStatement.cs
@@ -0,0 +1,62 @@
+//
+// System.CodeDom CodeVariableDeclarationStatement Class implementation
+//
+// Author:
+// Miguel de Icaza (miguel@ximian.com)
+//
+// (C) 2001 Ximian, Inc.
+//
+
+namespace System.CodeDom {
+
+ public class CodeVariableDeclarationStatement : CodeStatement {
+ CodeExpression initExpression;
+ string type, name;
+
+ public CodeVariableDeclarationStatement () {}
+
+ public CodeVariableDeclarationStatement (string type, string name)
+ {
+ this.type = type;
+ this.name = name;
+ }
+
+ public CodeVariableDeclarationStatement (string type, string name,
+ CodeExpression initExpression)
+ {
+ this.type = type;
+ this.name = name;
+ this.initExpression = initExpression;
+ }
+
+ public CodeExpression InitExpression {
+ get {
+ return initExpression;
+ }
+
+ set {
+ initExpression = value;
+ }
+ }
+
+ public string Name {
+ get {
+ return name;
+ }
+
+ set {
+ name = value;
+ }
+ }
+
+ public string Type {
+ get {
+ return type;
+ }
+
+ set {
+ type = value;
+ }
+ }
+ }
+}
diff --git a/mcs/class/System/System.CodeDom/FieldDirection.cs b/mcs/class/System/System.CodeDom/FieldDirection.cs
new file mode 100755
index 00000000000..669bf377c4a
--- /dev/null
+++ b/mcs/class/System/System.CodeDom/FieldDirection.cs
@@ -0,0 +1,14 @@
+//
+// System.CodeDom FieldDirection Enum implementation
+//
+// Author:
+// Sean MacIsaac (macisaac@ximian.com)
+//
+// (C) 2001 Ximian, Inc.
+//
+
+namespace System.CodeDom {
+ public enum FieldDirection {
+ In, Out, Ref
+ }
+}
diff --git a/mcs/class/System/System.CodeDom/MemberAttributes.cs b/mcs/class/System/System.CodeDom/MemberAttributes.cs
new file mode 100755
index 00000000000..d851f92f5d6
--- /dev/null
+++ b/mcs/class/System/System.CodeDom/MemberAttributes.cs
@@ -0,0 +1,29 @@
+//
+// System.CodeDom MemberAttributes Enum implementation
+//
+// Author:
+// Sean MacIsaac (macisaac@ximian.com)
+//
+// (C) 2001 Ximian, Inc.
+//
+
+namespace System.CodeDom {
+ public enum MemberAttributes {
+ Abstract,
+ AccessMask,
+ Assembly,
+ Const,
+ Family,
+ FamilyAndAssembly,
+ FamilyOrAssembly,
+ Final,
+ New,
+ Overloaded,
+ Override,
+ Private,
+ Public,
+ ScopeMask,
+ Static,
+ VTableMask
+ }
+}
diff --git a/mcs/class/System/System.CodeDom/common.src b/mcs/class/System/System.CodeDom/common.src
new file mode 100755
index 00000000000..2818230866c
--- /dev/null
+++ b/mcs/class/System/System.CodeDom/common.src
@@ -0,0 +1,65 @@
+CodeArrayCreateExpression.cs
+CodeAssignStatement.cs
+CodeAttachEventStatement.cs
+CodeAttributeArgument.cs
+CodeAttributeArgumentCollection.cs
+CodeAttributeBlock.cs
+CodeAttributeDeclaration.cs
+CodeAttributeDeclarationCollection.cs
+CodeBaseReferenceExpression.cs
+CodeBinaryOperatorExpression.cs
+CodeBinaryOperatorType.cs
+CodeCastExpression.cs
+CodeCatchClause.cs
+CodeCatchClauseCollection.cs
+CodeClass.cs
+CodeClassCollection.cs
+CodeClassConstructor.cs
+CodeClassDelegate.cs
+CodeClassMember.cs
+CodeClassMemberCollection.cs
+CodeCommentStatement.cs
+CodeConstructor.cs
+CodeDelegateCreateExpression.cs
+CodeDelegateInvokeExpression.cs
+CodeDelegateInvokeStatement.cs
+CodeDetachEventStatement.cs
+CodeExpression.cs
+CodeExpressionCollection.cs
+CodeFieldReferenceExpression.cs
+CodeForLoopStatement.cs
+CodeIfStatement.cs
+CodeIndexerExpression.cs
+CodeLinePragma.cs
+CodeLiteralClassMember.cs
+CodeLiteralExpression.cs
+CodeLiteralNamespace.cs
+CodeLiteralStatement.cs
+CodeMemberEvent.cs
+CodeMemberField.cs
+CodeMemberMethod.cs
+CodeMemberProperty.cs
+CodeMethodInvokeExpression.cs
+CodeMethodInvokeStatement.cs
+CodeMethodReturnStatement.cs
+CodeNamespace.cs
+CodeNamespaceImport.cs
+CodeNamespaceImportCollection.cs
+CodeObject.cs
+CodeObjectCreateExpression.cs
+CodeParameterDeclarationExpression.cs
+CodeParameterDeclarationExpressionCollection.cs
+CodePrimitiveExpression.cs
+CodePropertyReferenceExpression.cs
+CodeStatement.cs
+CodeStatementCollection.cs
+CodeThisReferenceExpression.cs
+CodeThrowExceptionStatement.cs
+CodeTryCatchFinallyStatement.cs
+CodeTypeDeclaration.cs
+CodeTypeMember.cs
+CodeTypeOfExpression.cs
+CodeTypeReferenceExpression.cs
+CodeVariableDeclarationStatement.cs
+FieldDirection.cs
+MemberAttributes.cs
diff --git a/mcs/class/System/System.CodeDom/unix.src b/mcs/class/System/System.CodeDom/unix.src
new file mode 100755
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/mcs/class/System/System.CodeDom/unix.src
diff --git a/mcs/class/System/System.CodeDom/windows.src b/mcs/class/System/System.CodeDom/windows.src
new file mode 100755
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/mcs/class/System/System.CodeDom/windows.src
diff --git a/mcs/class/System/System.Collections.Specialized/BitVector32.cs b/mcs/class/System/System.Collections.Specialized/BitVector32.cs
new file mode 100644
index 00000000000..e04a44d7234
--- /dev/null
+++ b/mcs/class/System/System.Collections.Specialized/BitVector32.cs
@@ -0,0 +1,67 @@
+//
+// System.Collections.Specialized.BitVector32.cs
+//
+// Author:
+// Miguel de Icaza (miguel@ximian.com)
+//
+// (C) Ximian, Inc. http://www.ximian.com
+//
+
+namespace System.Collections.Specialized {
+
+ public struct BitVector32 {
+ int value;
+
+ public struct Section {
+ public short maxval;
+ }
+
+ public static Section CreateSection (short maxval)
+ {
+ Section s = new Section();
+
+ // FIXME: Imeplemtn me
+
+ return s;
+ }
+
+ public static int CreateMask ()
+ {
+ return 1;
+ }
+
+ public static int CreateMask (int prev)
+ {
+ return prev << 1;
+ }
+
+ public BitVector32 (BitVector32 source)
+ {
+ value = source.value;
+ }
+
+ public BitVector32 (int init)
+ {
+ value = init;
+ }
+
+ public override bool Equals (object o)
+ {
+ if (!(o is BitVector32))
+ return false;
+
+ return value == ((BitVector32) o).value;
+ }
+
+ public override int GetHashCode ()
+ {
+ return 0;
+ }
+
+ public int Data {
+ get {
+ return value;
+ }
+ }
+ }
+}
diff --git a/mcs/class/System/System.Collections.Specialized/ChangeLog b/mcs/class/System/System.Collections.Specialized/ChangeLog
new file mode 100755
index 00000000000..bc349c8bbd7
--- /dev/null
+++ b/mcs/class/System/System.Collections.Specialized/ChangeLog
@@ -0,0 +1,19 @@
+2001-08-22 John Barnette <jbarn@httcb.net>
+ * StringDictionary.cs:
+ Initial working implementation.
+ * ListDictionary.cs:
+ Initial working implementation.
+
+2001-07-17 John Barnette <jbarn@httcb.net>
+ * StringCollection.cs:
+ Implemented and working according to spec.
+ * StringIterator.cs:
+ (ADDED) Implemented and working according to spec.
+ * StringCollectionTest.cs:
+ (ADDED) Initial revision contains 17 tests; all of 'em
+ run correctly. More complicated tests to follow.
+
+2001-07-15 Sean MacIsaac <macisaac@ximian.com>
+
+ * StringCollection.cs: Added so that CodeDom.* would compile.
+
diff --git a/mcs/class/System/System.Collections.Specialized/ListDictionary.cs b/mcs/class/System/System.Collections.Specialized/ListDictionary.cs
new file mode 100644
index 00000000000..47f52ea11f8
--- /dev/null
+++ b/mcs/class/System/System.Collections.Specialized/ListDictionary.cs
@@ -0,0 +1,432 @@
+namespace System.Collections.Specialized
+{
+ public class ListDictionary : IDictionary, ICollection, IEnumerable
+ {
+ private int count;
+ private int modCount;
+ private ListEntry root;
+ private IComparer comparer;
+
+
+ public ListDictionary()
+ {
+ count = 0;
+ modCount = 0;
+ comparer = null;
+ root = null;
+ }
+
+ public ListDictionary(IComparer comparer) : this()
+ {
+ this.comparer = comparer;
+ }
+
+ private bool AreEqual(object obj1, object obj2)
+ {
+ if (comparer != null) {
+ if (comparer.Compare(obj1, obj2) == 0) {
+ return true;
+ }
+ } else {
+ if (obj1.Equals(obj2)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ private ListEntry FindEntry(object key)
+ {
+ if (key == null) {
+ throw new ArgumentNullException("Attempted lookup for a null key.");
+ }
+
+ if (root == null) {
+ return null;
+ } else {
+ ListEntry entry = root;
+
+ while (entry != null) {
+ if (AreEqual(key, entry.key)) {
+ return entry;
+ }
+
+ entry = entry.next;
+ }
+ }
+
+ return null;
+ }
+
+ private void AddImpl(object key, object value)
+ {
+ if (key == null) {
+ throw new ArgumentNullException("Attempted add with a null key.");
+ }
+
+ if (root == null) {
+ root = new ListEntry();
+ root.key = key;
+ root.value = value;
+ } else {
+ ListEntry entry = root;
+
+ while (entry != null) {
+ if (AreEqual(key, entry.key)) {
+ throw new ArgumentException("Duplicate key in add.");
+ }
+
+ if (entry.next == null) {
+ break;
+ }
+
+ entry = entry.next;
+ }
+
+ entry.next = new ListEntry();
+ entry.next.key = key;
+ entry.next.value = value;
+ }
+
+ count++;
+ modCount++;
+ }
+
+ // IEnumerable Interface
+ IEnumerator IEnumerable.GetEnumerator()
+ {
+ return new ListEntryEnumerator(this);
+ }
+
+ // ICollection Interface
+ public int Count
+ {
+ get {
+ return count;
+ }
+ }
+
+ public bool IsSynchronized
+ {
+ get {
+ return false;
+ }
+ }
+
+ public object SyncRoot
+ {
+ get {
+ return this;
+ }
+ }
+
+ public void CopyTo(Array array, int index)
+ {
+ // FIXME
+ }
+
+ // IDictionary Interface
+ public bool IsFixedSize
+ {
+ get {
+ return false;
+ }
+ }
+
+ public bool IsReadOnly
+ {
+ get {
+ return false;
+ }
+ }
+
+ // Indexer
+ public object this[object key]
+ {
+ get {
+ ListEntry entry = FindEntry(key);
+ return entry == null ? entry : entry.value;
+ }
+
+ set {
+ ListEntry entry = FindEntry(key);
+
+ if (entry != null) {
+ entry.value = value;
+ count++;
+ modCount++;
+ } else {
+ AddImpl(key, value);
+ }
+ }
+ }
+
+ public ICollection Keys
+ {
+ get {
+ return new ListEntryCollection(this, true);
+ }
+ }
+
+ public ICollection Values
+ {
+ get {
+ return new ListEntryCollection(this, false);
+ }
+ }
+
+ public void Add(object key, object value)
+ {
+ AddImpl(key, value);
+ }
+
+ public void Clear()
+ {
+ root = null;
+ count = 0;
+ modCount++;
+ }
+
+ public bool Contains(object key)
+ {
+ return FindEntry(key) != null ? true : false;
+ }
+
+ IDictionaryEnumerator IDictionary.GetEnumerator()
+ {
+ return new ListEntryEnumerator(this);
+ }
+
+ public void Remove(object key)
+ {
+ ListEntry entry = root;
+
+ for (ListEntry prev = null; entry != null; prev = entry, entry = entry.next) {
+ if (AreEqual(key, entry.key)) {
+ if (prev != null) {
+ prev.next = entry.next;
+ } else {
+ root = entry.next;
+ }
+
+ entry.value = null;
+ count--;
+ modCount++;
+ }
+ }
+ }
+
+
+ private class ListEntry
+ {
+ public object key = null;
+ public object value = null;
+ public ListEntry next = null;
+ }
+
+
+ private class ListEntryEnumerator : IEnumerator, IDictionaryEnumerator
+ {
+ private ListDictionary dict;
+ private bool isAtStart;
+ private ListEntry current;
+ private int version;
+
+ public ListEntryEnumerator(ListDictionary dict)
+ {
+ this.dict = dict;
+ version = dict.modCount;
+ Reset();
+ }
+
+ private void FailFast()
+ {
+ if (version != dict.modCount) {
+ throw new InvalidOperationException(
+ "The ListDictionary's contents changed after this enumerator was instantiated.");
+ }
+ }
+
+ public bool MoveNext()
+ {
+ FailFast();
+
+ if (isAtStart) {
+ current = dict.root;
+ isAtStart = false;
+ } else {
+ current = current.next;
+ }
+
+ return current != null ? true : false;
+ }
+
+ public void Reset()
+ {
+ FailFast();
+
+ isAtStart = true;
+ current = null;
+ }
+
+ public object Current
+ {
+ get {
+ FailFast();
+
+ if (isAtStart || current == null) {
+ throw new InvalidOperationException(
+ "Enumerator is positioned before the collection's first element or after the last element.");
+ }
+
+ return new DictionaryEntry(current.key, current.value);
+ }
+ }
+
+ // IDictionaryEnumerator
+ public DictionaryEntry Entry
+ {
+ get {
+ FailFast();
+ return (DictionaryEntry) Current;
+ }
+ }
+
+ public object Key
+ {
+ get {
+ FailFast();
+
+ if (isAtStart || current == null) {
+ throw new InvalidOperationException(
+ "Enumerator is positioned before the collection's first element or after the last element.");
+ }
+
+ return current.key;
+ }
+ }
+
+ public object Value
+ {
+ get {
+ FailFast();
+
+ if (isAtStart || current == null) {
+ throw new InvalidOperationException(
+ "Enumerator is positioned before the collection's first element or after the last element.");
+ }
+
+ return current.value;
+ }
+ }
+ }
+
+ private class ListEntryCollection : ICollection
+ {
+ private ListDictionary dict;
+ private bool isKeyList;
+
+ public ListEntryCollection(ListDictionary dict, bool isKeyList)
+ {
+ this.dict = dict;
+ this.isKeyList = isKeyList;
+ }
+
+ // ICollection Interface
+ public int Count
+ {
+ get {
+ return dict.Count;
+ }
+ }
+
+ public bool IsSynchronized
+ {
+ get {
+ return false;
+ }
+ }
+
+ public object SyncRoot
+ {
+ get {
+ return dict.SyncRoot;
+ }
+ }
+
+ public void CopyTo(Array array, int index)
+ {
+ // FIXME
+ }
+
+ // IEnumerable Interface
+ public IEnumerator GetEnumerator()
+ {
+ return new ListEntryCollectionEnumerator(dict, isKeyList);
+ }
+
+ private class ListEntryCollectionEnumerator : IEnumerator
+ {
+ private ListDictionary dict;
+ private bool isKeyList;
+ private bool isAtStart;
+ private int version;
+ private ListEntry current;
+
+ public ListEntryCollectionEnumerator(ListDictionary dict, bool isKeyList)
+ {
+ this.dict = dict;
+ this.isKeyList = isKeyList;
+ isAtStart = true;
+ version = dict.modCount;
+ }
+
+ private void FailFast()
+ {
+ if (version != dict.modCount) {
+ throw new InvalidOperationException(
+ "The Collection's contents changed after this " +
+ "enumerator was instantiated.");
+ }
+ }
+
+ public object Current
+ {
+ get {
+ FailFast();
+
+ if (isAtStart || current == null) {
+ throw new InvalidOperationException(
+ "Enumerator is positioned before the collection's " +
+ "first element or after the last element.");
+ }
+
+ return isKeyList ? current.key : current.value;
+ }
+ }
+
+ public bool MoveNext()
+ {
+ FailFast();
+
+ if (isAtStart) {
+ current = dict.root;
+ isAtStart = false;
+ } else {
+ current = current.next;
+ }
+
+ return current != null ? true : false;
+ }
+
+ public void Reset()
+ {
+ FailFast();
+ isAtStart = true;
+ current = null;
+ }
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/mcs/class/System/System.Collections.Specialized/NameValueCollection.cs b/mcs/class/System/System.Collections.Specialized/NameValueCollection.cs
new file mode 100644
index 00000000000..23ba45db960
--- /dev/null
+++ b/mcs/class/System/System.Collections.Specialized/NameValueCollection.cs
@@ -0,0 +1,362 @@
+/**
+ * System.Collections.Specialized.NamaValueCollection class implementation
+ *
+ * Author: Gleb Novodran
+ */
+// created on 7/21/2001 at 5:15 PM
+using System;
+using System.Collections;
+using System.Collections.Specialized;
+using System.Runtime.Serialization;
+using System.Text;
+
+namespace System.Collections.Specialized{
+ public class NameValueCollection : NameObjectCollectionBase
+ {
+ string[] cachedAllKeys = null;
+ string[] cachedAll = null;
+
+ //--------------------- Constructors -----------------------------
+
+ /// <summary> SDK: Initializes a new instance of the NameValueCollection class that is empty,
+ /// has the default initial capacity and uses the default case-insensitive hash code provider and the default case-insensitive comparer.
+ /// </summary>
+ public NameValueCollection() : base()
+ {
+
+ }
+
+ /// <summary> SDK: Initializes a new instance of the NameValueCollection class that is empty,
+ /// has the specified initial capacity and uses the default case-insensitive hash code provider and the default case-insensitive comparer.
+ ///</summary>
+ public NameValueCollection( int capacity ) : base(capacity)
+ {
+
+ }
+
+ /// <summary> SDK: Copies the entries from the specified NameValueCollection to a new
+ /// NameValueCollection with the same initial capacity as the number of entries copied
+ /// and using the same case-insensitive hash code provider and the same case-insensitive
+ /// comparer as the source collection.
+ /// </summary>
+ /// TODO: uncomment constructor below after it will be possible to compile NameValueCollection and
+ /// NameObjectCollectionBase to the same assembly
+
+/* public NameValueCollection( NameValueCollection col ) : base(col.HashCodeProvider,col.Comparer)
+ {
+ if (col==null)
+ throw new ArgumentNullException("Null argument is not allowed");
+ Add(col);
+ }
+*/
+ ///<summary>SDK: Initializes a new instance of the NameValueCollection class that is empty,
+ ///has the default initial capacity and uses the specified hash code provider and
+ ///the specified comparer.</summary>
+ public NameValueCollection( IHashCodeProvider hashProvider, IComparer comparer )
+ : base(hashProvider, comparer)
+ {
+
+ }
+
+ /// <summary>
+ /// SDK: Copies the entries from the specified NameValueCollection to a new NameValueCollection
+ /// with the specified initial capacity or the same initial capacity as the number of entries
+ /// copied, whichever is greater, and using the default case-insensitive hash code provider and
+ /// the default case-insensitive comparer.
+ /// </summary>
+ /// TODO: uncomment constructor below after it will be possible to compile NameValueCollection and
+ /// NameObjectCollectionBase to the same assembly
+
+/* public NameValueCollection( int capacity, NameValueCollection col )
+ : base(capacity, col.get_HashCodeProvider(),col.Comparer)
+ {
+ if (col==null)
+ throw new ArgumentNullException("Null argument is not allowed");
+ Add(col);
+ }
+*/
+ /// <summary>
+ /// SDK: Initializes a new instance of the NameValueCollection class that is serializable
+ /// and uses the specified System.Runtime.Serialization.SerializationInfo and
+ /// System.Runtime.Serialization.StreamingContext.
+ /// </summary>
+ protected NameValueCollection( SerializationInfo info, StreamingContext context )
+ :base(info, context)
+ {
+
+ }
+
+ /// <summary>
+ /// SDK: Initializes a new instance of the NameValueCollection class that is empty,
+ /// has the specified initial capacity and uses the specified hash code provider and
+ /// the specified comparer.
+ /// </summary>
+ public NameValueCollection( int capacity, IHashCodeProvider hashProvider, IComparer comparer )
+ :base(capacity, hashProvider, comparer)
+ {
+
+ }
+
+ //----------------------- Public Instance Properties -------------------------------
+
+
+ ///<summary> SDK:
+ /// Gets all the keys in the NameValueCollection.
+ /// The arrays returned by AllKeys are cached for better performance and are
+ /// automatically refreshed when the collection changes. A derived class can
+ /// invalidate the cached version by calling InvalidateCachedArrays, thereby
+ /// forcing the arrays to be recreated.
+ /// </summary>
+ public virtual string[] AllKeys
+ {
+ get {
+ if (cachedAllKeys==null)
+ cachedAllKeys = BaseGetAllKeys();
+ return this.cachedAllKeys;
+ }
+ }
+
+ public string this[ int index ]
+ {
+ get{
+ return this.Get(index);
+ }
+ }
+
+ public string this[ string name ] {
+ get{
+ return this.Get(name);
+ }
+ set{
+ this.Set(name,value);
+ }
+ }
+
+/////////////////////////////// Public Instance Methods //////////////////////////////
+
+ /// <summary> SDK: Copies the entries in the specified NameValueCollection
+ /// to the current NameValueCollection.</summary>
+ /// LAMESPEC: see description that comes this Add(string, string)
+
+ public void Add( NameValueCollection c ){
+
+ if (this.IsReadOnly)
+ throw new NotSupportedException("Collection is read-only");
+ if (c==null)
+ throw new ArgumentNullException();
+
+ InvalidateCachedArrays();
+ ArrayList values = null;
+
+ int max = c.Count;
+ for(int i=0; i<max; i++){
+ values=(ArrayList)BaseGet(c.GetKey(i));
+ if (values==null)
+ values = new ArrayList();
+ values.AddRange((ArrayList)c.BaseGet(i));
+ }
+
+ }
+
+
+ /// <summary> SDK: Adds an entry with the specified name and value to the
+ /// NameValueCollection. </summary>
+ ///
+ /// LAMESPEC:
+ /// in SDK doc: If the same value already exists under the same key in the collection,
+ /// the new value overwrites the old value.
+ /// however the Microsoft implemenatation in this case just adds one more value
+ /// in other words after
+ /// <code>
+ /// NameValueCollection nvc;
+ /// nvc.Add("LAZY","BASTARD")
+ /// nvc.Add("LAZY","BASTARD")
+ /// </code>
+ /// nvc.Get("LAZY") will be "BASTARD,BASTARD" instead of "BASTARD"
+
+ public virtual void Add( string name, string val )
+ {
+
+ if (this.IsReadOnly)
+ throw new NotSupportedException("Collection is read-only");
+
+ InvalidateCachedArrays();
+ ArrayList values = (ArrayList)BaseGet(name);
+ if (values==null){
+ values = new ArrayList();
+ if (val!=null)
+ values.Add(val);
+ BaseAdd(name,values);
+ }
+ else {
+ if (val!=null)
+ values.Add(val);
+ }
+
+ }
+
+ /// <summary> SDK: Invalidates the cached arrays and removes all entries from
+ /// the NameValueCollection.</summary>
+
+ public void Clear(){
+ if (this.IsReadOnly)
+ throw new NotSupportedException("Collection is read-only");
+ InvalidateCachedArrays();
+ BaseClear();
+ }
+
+ /// <summary> SDK: Copies the entire NameValueCollection to a compatible one-dimensional Array,
+ /// starting at the specified index of the target array.</summary>
+
+ public void CopyTo( Array dest, int index )
+ {
+ if (dest==null)
+ throw new ArgumentNullException("Null argument - dest");
+ if (index<0)
+ throw new ArgumentOutOfRangeException("index is less than 0");
+// throw new Exception("Not implemented yet");
+
+ //TODO: add implementation here
+ if (cachedAll==null)
+ RefreshCachedAll();
+ cachedAll.CopyTo(dest, index);
+ }
+ protected void RefreshCachedAll()
+ {
+ this.cachedAll=null;
+ int max = this.Count;
+ cachedAll = new string[max];
+ for(int i=0;i<max;i++){
+ cachedAll[i] = this.Get(i);
+ }
+
+ }
+
+ /// <summary> SDK: Gets the values at the specified index of the NameValueCollection combined
+ /// into one comma-separated list.</summary>
+
+ public virtual string Get( int index )
+ {
+ ArrayList values = (ArrayList)BaseGet(index);
+ // if index is out of range BaseGet throws an ArgumentOutOfRangeException
+
+ return AsSingleString(values);
+
+ }
+
+ /**
+ * SDK: Gets the values associated with the specified key from the NameValueCollection
+ * combined into one comma-separated list.
+ */
+ public virtual string Get( string name )
+ {
+ ArrayList values = (ArrayList)BaseGet(name);
+/* if (values==null)
+ Console.WriteLine("BaseGet returned null");*/
+ return AsSingleString(values);
+// -------------------------------------------------------------
+
+ }
+ /// <summary></summary>
+ private static string AsSingleString(ArrayList values)
+ {
+ const char separator = ',';
+
+ if (values==null)
+ return null;
+ int max = values.Count;
+
+ if (max==0)
+ return null;
+ //TODO: reimplement this
+ StringBuilder sb = new StringBuilder((string)values[0]);
+ for (int i=1; i<max; i++){
+ sb.Append(separator);
+ sb.Append(values[i]);
+ }
+
+ return sb.ToString();
+ }
+
+
+ /// <summary>SDK: Gets the key at the specified index of the NameValueCollection.</summary>
+ public virtual string GetKey( int index )
+ {
+ return BaseGetKey(index);
+ }
+
+
+ /// <summary>SDK: Gets the values at the specified index of the NameValueCollection.</summary>
+
+ public virtual string[] GetValues( int index )
+ {
+ ArrayList values = (ArrayList)BaseGet(index);
+
+ return AsStringArray(values);
+ }
+
+
+ public virtual string[] GetValues( string name )
+ {
+ ArrayList values = (ArrayList)BaseGet(name);
+
+ return AsStringArray(values);
+ }
+
+ private static string[] AsStringArray(ArrayList values){
+
+ int max = values.Count;//get_Count();
+ if (max==0)
+ return null;
+
+ string[] valArray =new string[max];
+ values.CopyTo(valArray);
+ return valArray;
+ }
+
+
+ /// <summary>
+ /// SDK: Gets a value indicating whether the NameValueCollection contains keys that
+ /// are not a null reference
+ /// </summary>
+
+ public bool HasKeys()
+ {
+ return BaseHasKeys();
+ }
+
+ public virtual void Remove( string name )
+ {
+ if (this.IsReadOnly)
+ throw new NotSupportedException("Collection is read-only");
+ InvalidateCachedArrays();
+ BaseRemove(name);
+
+ }
+
+ /// <summary>
+ /// Sets the value of an entry in the NameValueCollection.
+ /// </summary>
+ public virtual void Set( string name, string value )
+ {
+ if (this.IsReadOnly)
+ throw new NotSupportedException("Collection is read-only");
+ InvalidateCachedArrays();
+
+ ArrayList values = new ArrayList();
+ values.Add(value);
+ BaseSet(name,values);
+
+ }
+
+
+//---------------------- Protected Instance Methods ----------------------
+
+ protected void InvalidateCachedArrays()
+ {
+ cachedAllKeys = null;
+ cachedAll = null;
+ }
+
+ }
+}
diff --git a/mcs/class/System/System.Collections.Specialized/StringCollection.cs b/mcs/class/System/System.Collections.Specialized/StringCollection.cs
new file mode 100755
index 00000000000..d1c8410030d
--- /dev/null
+++ b/mcs/class/System/System.Collections.Specialized/StringCollection.cs
@@ -0,0 +1,292 @@
+/* System.Collections.Specialized.StringCollection.cs
+ * Authors:
+ * John Barnette (jbarn@httcb.net)
+ * Sean MacIsaac (macisaac@ximian.com)
+ *
+ * Copyright (C) 2001 John Barnette
+ * (C) Ximian, Inc. http://www.ximian.com
+ *
+ * NOTES:
+ * I bet Microsoft uses ArrayList as a backing store for this; I wonder what
+ * the performance difference will be.
+*/
+
+using System;
+
+namespace System.Collections.Specialized {
+ public class StringCollection : IList, ICollection, IEnumerable {
+ private static int InitialCapacity = 11;
+ private static float CapacityMultiplier = 2.0f;
+
+ private int count;
+ private int modCount;
+
+ private string[] entries;
+
+ // Public Constructor
+ public StringCollection() {
+ entries = new string[InitialCapacity];
+ count = 0;
+ modCount = 0;
+ }
+
+ // Public Instance Properties
+ public int Count {
+ get { return count; }
+ }
+
+ public bool IsFixedSize {
+ get { return false; }
+ }
+
+ public bool IsReadOnly {
+ get { return false; }
+ }
+
+ public bool IsSynchronized {
+ get { return false; }
+ }
+
+ object IList.this[int index] {
+ get { return this[index]; }
+ set { this[index] = value.ToString(); }
+ }
+
+ public string this[int index] {
+ get {
+ if (index < 0 || index >= count) {
+ throw new ArgumentOutOfRangeException("index");
+ }
+
+ return entries[index];
+ }
+
+ set {
+ if (index < 0 || index >= count) {
+ throw new ArgumentOutOfRangeException("index");
+ }
+
+ modCount++;
+ entries[index] = value;
+ }
+ }
+
+ public object SyncRoot {
+ get { return this; }
+ }
+
+
+ // Public Instance Methods
+
+ int IList.Add(object value) {
+ return Add(value.ToString());
+ }
+
+ public int Add(string value) {
+ modCount++;
+ Resize(count + 1);
+ int index = count++;
+ entries[index] = value;
+
+ return index;
+ }
+
+ public void AddRange(string[] value) {
+ int numEntries = value.Length;
+
+ modCount++;
+ Resize(count + numEntries);
+ Array.Copy(value, 0, entries, count, numEntries);
+ count += numEntries;
+ }
+
+ public void Clear() {
+ modCount++;
+ count = 0;
+ }
+
+ bool IList.Contains(object value) {
+ return Contains(value.ToString());
+ }
+
+ public bool Contains(string value) {
+ foreach (string entry in entries) {
+ if (value.Equals(entry)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ void ICollection.CopyTo(Array array, int index) {
+ if (array == null) {
+ throw new ArgumentNullException("array");
+ } else if (index < 0) {
+ throw new ArgumentOutOfRangeException("index");
+ } else if (array.Rank > 1) {
+ throw new ArgumentException("array");
+ } else if (index >= array.Length) {
+ throw new ArgumentException("index");
+ } else if (array.Length - index < count) {
+ throw new ArgumentException("array");
+ }
+
+ Array.Copy(entries, 0, array, index, count);
+ }
+
+ public void CopyTo(string[] array, int index) {
+ if (array == null) {
+ throw new ArgumentNullException("array");
+ } else if (index < 0) {
+ throw new ArgumentOutOfRangeException("index");
+ } else if (array.Rank > 1) {
+ throw new ArgumentException("array");
+ } else if (index >= array.Length) {
+ throw new ArgumentException("index");
+ } else if (array.Length - index < count) {
+ throw new ArgumentException("array");
+ }
+
+ Array.Copy(entries, 0, array, index, count);
+ }
+
+ IEnumerator IEnumerable.GetEnumerator() {
+ return new InternalEnumerator(this);
+ }
+
+ public StringEnumerator GetEnumerator() {
+ return new StringEnumerator(this);
+ }
+
+ int IList.IndexOf(object value) {
+ return IndexOf(value.ToString());
+ }
+
+ public int IndexOf(string value) {
+ for (int i = 0; i < count; i++) {
+ if (value.Equals(entries[i])) {
+ return i;
+ }
+ }
+
+ return -1;
+ }
+
+ void IList.Insert(int index, object value) {
+ Insert(index, value.ToString());
+ }
+
+ public void Insert(int index, string value) {
+ if (index < 0 || index > count) {
+ throw new ArgumentOutOfRangeException("index");
+ }
+
+ modCount++;
+ Resize(count + 1);
+ Array.Copy(entries, index, entries, index + 1, count - index);
+ entries[index] = value;
+ count++;
+ }
+
+
+ void IList.Remove(object value) {
+ Remove(value.ToString());
+ }
+
+ public void Remove(string value) {
+ for (int i = 0; i < count; i++) {
+ if (value.Equals(entries[i])) {
+ RemoveAt(i);
+ return;
+ }
+ }
+ }
+
+ public void RemoveAt(int index) {
+ if (index < 0 || index >= count) {
+ throw new ArgumentOutOfRangeException("index");
+ }
+
+ int remaining = count - index - 1;
+
+ modCount++;
+
+ if (remaining > 0) {
+ Array.Copy(entries, index + 1, entries, index, remaining);
+ }
+
+ count--;
+ entries[count] = null;
+ }
+
+
+ // Private Instance Methods
+
+ private void Resize(int minSize) {
+ int oldSize = entries.Length;
+
+ if (minSize > oldSize) {
+ string[] oldEntries = entries;
+ int newSize = (int) (oldEntries.Length * CapacityMultiplier);
+
+ if (newSize < minSize) newSize = minSize;
+ entries = new string[newSize];
+ Array.Copy(oldEntries, 0, entries, 0, count);
+ }
+ }
+
+
+ // Private classes
+
+ private class InternalEnumerator : IEnumerator {
+ private StringCollection data;
+ private int index;
+ private int myModCount;
+
+ public InternalEnumerator(StringCollection data) {
+ this.data = data;
+ myModCount = data.modCount;
+ index = -1;
+ }
+
+
+ // Public Instance Properties
+
+ public object Current {
+ get {
+ if (myModCount != data.modCount) {
+ throw new InvalidOperationException();
+ } else if (index < 0 || index > data.count - 1) {
+ throw new InvalidOperationException();
+ }
+
+ return data[index];
+ }
+ }
+
+
+ // Public Instance Methods
+
+ public bool MoveNext() {
+ if (myModCount != data.modCount) {
+ throw new InvalidOperationException();
+ }
+
+ if (++index >= data.count - 1) {
+ return false;
+ }
+
+ return true;
+ }
+
+ public void Reset() {
+ if (myModCount != data.modCount) {
+ throw new InvalidOperationException();
+ }
+
+ index = -1;
+ }
+ }
+ }
+}
diff --git a/mcs/class/System/System.Collections.Specialized/StringDictionary.cs b/mcs/class/System/System.Collections.Specialized/StringDictionary.cs
new file mode 100644
index 00000000000..2e5bc2bfe10
--- /dev/null
+++ b/mcs/class/System/System.Collections.Specialized/StringDictionary.cs
@@ -0,0 +1,97 @@
+namespace System.Collections.Specialized
+{
+ public class StringDictionary : IEnumerable
+ {
+ protected Hashtable table;
+
+ public StringDictionary()
+ {
+ table = new Hashtable();
+ }
+
+ // Public Instance Properties
+
+ public virtual int Count
+ {
+ get {
+ return table.Count;
+ }
+ }
+
+ public virtual bool IsSynchronized
+ {
+ get {
+ return false;
+ }
+ }
+
+ public virtual string this[string key]
+ {
+ get {
+ return (string) table[key.ToLower()];
+ }
+
+ set {
+ table[key.ToLower()] = value;
+ }
+ }
+
+ public virtual ICollection Keys
+ {
+ get {
+ return table.Keys;
+ }
+ }
+
+ public virtual ICollection Values
+ {
+ get {
+ return table.Values;
+ }
+ }
+
+ public virtual object SyncRoot
+ {
+ get {
+ return table.SyncRoot;
+ }
+ }
+
+ // Public Instance Methods
+
+ public virtual void Add(string key, string value)
+ {
+ table.Add(key.ToLower(), value);
+ }
+
+ public virtual void Clear()
+ {
+ table.Clear();
+ }
+
+ public virtual bool ContainsKey(string key)
+ {
+ return table.ContainsKey(key.ToLower());
+ }
+
+ public virtual bool ContainsValue(string value)
+ {
+ return table.ContainsValue(value);
+ }
+
+ public virtual void CopyTo(Array array, int index)
+ {
+ table.CopyTo(array, index);
+ }
+
+ public virtual IEnumerator GetEnumerator()
+ {
+ return table.GetEnumerator();
+ }
+
+ public virtual void Remove(string key)
+ {
+ table.Remove(key.ToLower());
+ }
+ }
+} \ No newline at end of file
diff --git a/mcs/class/System/System.Collections.Specialized/StringEnumerator.cs b/mcs/class/System/System.Collections.Specialized/StringEnumerator.cs
new file mode 100644
index 00000000000..8be9d7c5a6e
--- /dev/null
+++ b/mcs/class/System/System.Collections.Specialized/StringEnumerator.cs
@@ -0,0 +1,36 @@
+/* System.Collections.Specialized.StringEnumerator.cs
+ * Authors:
+ * John Barnette (jbarn@httcb.net)
+ *
+ * Copyright (C) 2001 John Barnette
+*/
+
+namespace System.Collections.Specialized {
+ public class StringEnumerator {
+ private StringCollection coll;
+ private IEnumerator enumerable;
+
+ // assembly-scoped constructor
+ internal StringEnumerator(StringCollection coll) {
+ this.coll = coll;
+ this.enumerable = ((IEnumerable)coll).GetEnumerator();
+ }
+
+ // Public Instance Properties
+
+ public string Current {
+ get { return (string) enumerable.Current; }
+ }
+
+
+ // Public Instance Methods
+
+ public bool MoveNext() {
+ return enumerable.MoveNext();
+ }
+
+ public void Reset() {
+ enumerable.Reset();
+ }
+ }
+}
diff --git a/mcs/class/System/System.Collections.Specialized/common.src b/mcs/class/System/System.Collections.Specialized/common.src
new file mode 100755
index 00000000000..5695cbc5315
--- /dev/null
+++ b/mcs/class/System/System.Collections.Specialized/common.src
@@ -0,0 +1,5 @@
+BitVector32.cs
+ListDictionary.cs
+StringCollection.cs
+StringDictionary.cs
+StringEnumerator.cs
diff --git a/mcs/class/System/System.Collections.Specialized/unix.src b/mcs/class/System/System.Collections.Specialized/unix.src
new file mode 100755
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/mcs/class/System/System.Collections.Specialized/unix.src
diff --git a/mcs/class/System/System.Collections.Specialized/windows.src b/mcs/class/System/System.Collections.Specialized/windows.src
new file mode 100755
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/mcs/class/System/System.Collections.Specialized/windows.src
diff --git a/mcs/class/System/System.ComponentModel/ChangeLog b/mcs/class/System/System.ComponentModel/ChangeLog
new file mode 100644
index 00000000000..f7b907d7dbf
--- /dev/null
+++ b/mcs/class/System/System.ComponentModel/ChangeLog
@@ -0,0 +1,13 @@
+2001-08-21 Nick Drochak <ndrochak@gol.com>
+
+ * Component.cs: Eliminated compile errors by removing redundant fields and
+ using the ISite member instead. Also raised the Disposed event, but not
+ sure if it's correct now. Look for FIXME in the comments.
+
+2001-08-02 Miguel de Icaza <miguel@ximian.com>
+
+ * EventHandlerList.cs: New file.
+
+ * Container.cs, Component.cs, IContainer.cs, IComponent.cs,
+ ComponentCollection.cs, ISite.cs: New classes
+
diff --git a/mcs/class/System/System.ComponentModel/Component.cs b/mcs/class/System/System.ComponentModel/Component.cs
new file mode 100644
index 00000000000..9c76657a402
--- /dev/null
+++ b/mcs/class/System/System.ComponentModel/Component.cs
@@ -0,0 +1,122 @@
+//
+// System.ComponentModel.Component.cs
+//
+// Author:
+// Miguel de Icaza (miguel@ximian.com)
+//
+// (C) Ximian, Inc. http://www.ximian.com
+//
+
+using System;
+
+namespace System.ComponentModel {
+
+ // <summary>
+ // Component class.
+ // </summary>
+ //
+ // <remarks>
+ // Longer description
+ // </remarks>
+ public class Component : MarshalByRefObject, IComponent, IDisposable {
+
+ EventHandlerList event_handlers;
+ ISite mySite;
+
+ // <summary>
+ // Component Constructor
+ // </summary>
+ public Component ()
+ {
+ event_handlers = null;
+ }
+
+ // <summary>
+ // Get IContainer of this Component
+ // </summary>
+ public IContainer Container {
+ get {
+ return mySite.Container;
+ }
+ }
+
+ protected bool DesignMode {
+ get {
+ return mySite.DesignMode;
+ }
+ }
+
+ protected EventHandlerList Events {
+ get {
+ // Note: space vs. time tradeoff
+ // We create the object here if it's never be accessed before. This potentially
+ // saves space. However, we must check each time the propery is accessed to
+ // determine whether we need to create the object, which increases overhead.
+ // We could put the creation in the contructor, but that would waste space
+ // if it were never used. However, accessing this property would be faster.
+ if (null == event_handlers)
+ {
+ event_handlers = new EventHandlerList();
+ }
+ return event_handlers;
+ }
+ }
+
+ public virtual ISite Site {
+ get {
+ return mySite;
+ }
+
+ set {
+ mySite = value;
+ }
+ }
+
+ ~Component()
+ {
+ // FIXME: Not sure this is correct.
+ Dispose(true);
+ Disposed(this, EventArgs.Empty);
+ }
+
+ // <summary>
+ // Dispose resources used by this component
+ // </summary>
+ public virtual void Dispose ()
+ {
+ // FIXME: Not sure this is correct.
+ Dispose(false);
+ Disposed(this, EventArgs.Empty);
+ }
+
+ // <summary>
+ // Controls disposal of resources used by this.
+ // </summary>
+ //
+ // <param name="release_all"> Controls which resources are released</param>
+ //
+ // <remarks>
+ // if release_all is set to true, both managed and unmanaged
+ // resources should be released. If release_all is set to false,
+ // only unmanaged resources should be disposed
+ // </remarks>
+ protected virtual void Dispose (bool release_all)
+ {
+ }
+
+ // <summary>
+ // Implements the IServiceProvider interface
+ // </summary>
+ protected virtual object GetService (Type service)
+ {
+ // FIXME: Not sure what this should do.
+ return null;
+ }
+
+ // <summary>
+ // FIXME: Figure out this one.
+ // </summary>
+ public event EventHandler Disposed;
+ }
+
+}
diff --git a/mcs/class/System/System.ComponentModel/ComponentCollection.cs b/mcs/class/System/System.ComponentModel/ComponentCollection.cs
new file mode 100644
index 00000000000..e78fffaac5a
--- /dev/null
+++ b/mcs/class/System/System.ComponentModel/ComponentCollection.cs
@@ -0,0 +1,20 @@
+//
+// System.ComponentModel.ComponentCollection.cs
+//
+// Author:
+// Miguel de Icaza (miguel@ximian.com)
+//
+// (C) Ximian, Inc. http://www.ximian.com
+//
+
+namespace System.ComponentModel {
+
+ public class ComponentCollection { // FIXME: ReadOnlyCollectionBase
+
+ public void Dispose ()
+ {
+ }
+
+ }
+}
+
diff --git a/mcs/class/System/System.ComponentModel/Container.cs b/mcs/class/System/System.ComponentModel/Container.cs
new file mode 100644
index 00000000000..06710ee9ebe
--- /dev/null
+++ b/mcs/class/System/System.ComponentModel/Container.cs
@@ -0,0 +1,153 @@
+//
+// System.ComponentModel.Container.cs
+//
+// Author:
+// Miguel de Icaza (miguel@ximian.com)
+//
+// (C) Ximian, Inc. http://www.ximian.com
+//
+
+namespace System.ComponentModel {
+
+ // <summary>
+ // Container class: encapsulates components.
+ // </summary>
+ //
+ // <remarks>
+ //
+ // </remarks>
+ public class Container : IContainer, IDisposable {
+ ComponentCollection cc;
+
+ // <summary>
+ // Auxiliary class to support the default behaviour of CreateSite
+ // </summary>
+ //
+ // <remarks>
+ // This is an internal class that is used to provide a
+ // default implementation of an ISite class. Container
+ // is just a default implementation of IContainer, and
+ // provides this as a way of getting started
+ // </remarks>
+
+ class DefaultSite : ISite {
+ IComponent component;
+ IContainer container;
+ string name;
+
+ public DefaultSite (string name, IComponent component, IContainer container)
+ {
+ this.component = component;
+ this.container = container;
+ this.name = name;
+ }
+
+ public IComponent Component {
+ get {
+ return component;
+ }
+ }
+
+ public IContainer Container {
+ get {
+ return container;
+ }
+ }
+
+ public bool DesignMode {
+ get {
+ // FIXME: should we provide a way to set
+ // this value?
+ return false;
+ }
+ }
+
+ public string Name {
+ get {
+ return name;
+ }
+
+ set {
+ name = value;
+ }
+ }
+
+ public virtual object GetService (Type t)
+ {
+ // FIXME: do not know what this is supposed to do.
+ return null;
+ }
+ }
+
+ // <summary>
+ // Container constructor
+ // </summary>
+ public Container ()
+ {
+ }
+
+ public virtual ComponentCollection Components {
+ get {
+ return cc;
+ }
+ }
+
+ // <summary>
+ // Adds an IComponent to the Container
+ // </summary>
+ public virtual void Add (IComponent component)
+ {
+ // FIXME: Add this component to the ComponentCollection.cc
+ }
+
+ // <summary>
+ // Adds an IComponent to the Container. With a name binding.
+ // </summary>
+ public virtual void Add (IComponent component, string name)
+ {
+ // FIXME: Add this component to the ComponentCollection.cc
+ }
+
+ // <summary>
+ // Returns an ISite for a component.
+ // <summary>
+ protected virtual ISite CreateSite (IComponent component, string name)
+ {
+ return new DefaultSite (name, component, this);
+ }
+
+ public virtual void Dispose ()
+ {
+ Dispose (true);
+ GC.SuppressFinalize (this);
+ }
+
+ bool disposed = false;
+
+ public virtual void Dispose (bool release_all)
+ {
+ if (disposed)
+ return;
+
+ if (release_all){
+ cc.Dispose ();
+ cc = null;
+ }
+
+ disposed = true;
+ }
+
+ protected virtual object GetService (Type service)
+ {
+ // FIXME: Not clear what GetService does.
+
+ return null;
+ }
+
+ public virtual void Remove (IComponent component)
+ {
+ // FIXME: Add this component to the ComponentCollection.cc
+ }
+ }
+
+}
diff --git a/mcs/class/System/System.ComponentModel/EventHandlerList.cs b/mcs/class/System/System.ComponentModel/EventHandlerList.cs
new file mode 100644
index 00000000000..2c610702f40
--- /dev/null
+++ b/mcs/class/System/System.ComponentModel/EventHandlerList.cs
@@ -0,0 +1,64 @@
+//
+// System.ComponentModel.EventHandlerList.cs
+//
+// Author:
+// Miguel de Icaza (miguel@ximian.com)
+//
+// (C) Ximian, Inc. http://www.ximian.com
+//
+
+using System;
+using System.Collections;
+
+namespace System.ComponentModel {
+
+ // <summary>
+ // List of Event delegates.
+ // </summary>
+ //
+ // <remarks>
+ // Longer description
+ // </remarks>
+ public class EventHandlerList : IDisposable {
+ Hashtable table;
+
+ public EventHandlerList ()
+ {
+ }
+
+ public Delegate this [object key] {
+ get {
+ if (table == null)
+ return null;
+
+ return (Delegate) table [key];
+ }
+
+ set {
+ if (table == null)
+ table = new Hashtable ();
+
+ table.Add (key, value);
+ }
+ }
+
+ public void AddHandler (object key, Delegate value)
+ {
+ if (table == null)
+ table = new Hashtable ();
+
+ table.Add (key, value);
+ }
+
+ public void RemoveHandler (object key, Delegate value)
+ {
+ table.Remove (key);
+ }
+
+ public void Dispose ()
+ {
+ table = null;
+ }
+ }
+
+}
diff --git a/mcs/class/System/System.ComponentModel/IComponent.cs b/mcs/class/System/System.ComponentModel/IComponent.cs
new file mode 100644
index 00000000000..8b8fece74f1
--- /dev/null
+++ b/mcs/class/System/System.ComponentModel/IComponent.cs
@@ -0,0 +1,20 @@
+//
+// System.ComponentModel.IComponent.cs
+//
+// Author:
+// Miguel de Icaza (miguel@ximian.com)
+//
+// (C) Ximian, Inc. http://www.ximian.com
+//
+
+namespace System.ComponentModel {
+
+ public interface IComponent : IDisposable {
+
+ ISite Site {
+ get; set;
+ }
+
+ event EventHandler Disposed;
+ }
+}
diff --git a/mcs/class/System/System.ComponentModel/IContainer.cs b/mcs/class/System/System.ComponentModel/IContainer.cs
new file mode 100644
index 00000000000..fb5d34f1ab6
--- /dev/null
+++ b/mcs/class/System/System.ComponentModel/IContainer.cs
@@ -0,0 +1,24 @@
+//
+// System.ComponentModel.IContainer.cs
+//
+// Author:
+// Miguel de Icaza (miguel@ximian.com)
+//
+// (C) Ximian, Inc. http://www.ximian.com
+//
+
+namespace System.ComponentModel {
+
+ public interface IContainer {
+
+ ComponentCollection Components {
+ get;
+ }
+
+ void Add (IComponent component);
+
+ void Add (IComponent component, string name);
+
+ void Remove (IComponent component);
+ }
+}
diff --git a/mcs/class/System/System.ComponentModel/ISite.cs b/mcs/class/System/System.ComponentModel/ISite.cs
new file mode 100644
index 00000000000..0a7e09e8252
--- /dev/null
+++ b/mcs/class/System/System.ComponentModel/ISite.cs
@@ -0,0 +1,21 @@
+//
+// System.ComponentModel.Component.cs
+//
+// Author:
+// Miguel de Icaza (miguel@ximian.com)
+//
+// (C) Ximian, Inc. http://www.ximian.com
+//
+
+namespace System.ComponentModel {
+
+ public interface ISite : IServiceProvider {
+ IComponent Component { get; }
+
+ IContainer Container { get; }
+
+ bool DesignMode { get; }
+
+ string Name { get; set; }
+ }
+}
diff --git a/mcs/class/System/System.ComponentModel/common.src b/mcs/class/System/System.ComponentModel/common.src
new file mode 100644
index 00000000000..9800938d281
--- /dev/null
+++ b/mcs/class/System/System.ComponentModel/common.src
@@ -0,0 +1,7 @@
+Component.cs
+ComponentCollection.cs
+Container.cs
+EventHandlerList.cs
+IComponent.cs
+IContainer.cs
+ISite.cs
diff --git a/mcs/class/System/System.ComponentModel/unix.src b/mcs/class/System/System.ComponentModel/unix.src
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/mcs/class/System/System.ComponentModel/unix.src
diff --git a/mcs/class/System/System.ComponentModel/windows.src b/mcs/class/System/System.ComponentModel/windows.src
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/mcs/class/System/System.ComponentModel/windows.src
diff --git a/mcs/class/System/System.Configuration/ConfigurationException.cs b/mcs/class/System/System.Configuration/ConfigurationException.cs
new file mode 100644
index 00000000000..356410405a0
--- /dev/null
+++ b/mcs/class/System/System.Configuration/ConfigurationException.cs
@@ -0,0 +1,179 @@
+//
+// System.Configuration.ConfigurationException.cs
+//
+// Author:
+// Christopher Podurgiel (cpodurgiel@msn.com)
+//
+// (C) Ximian, Inc. http://www.ximian.com
+//
+
+using System;
+using System.Xml;
+
+namespace System.Configuration
+{
+
+ /// <summary>
+ /// ConfigurationException class.
+ /// </summary>
+ /// <remarks>
+ /// Longer description
+ /// </remarks>
+ public class ConfigurationException : SystemException
+ {
+
+ private static string _stringBareMessage;
+ private static string _stringFilename;
+ private static int _intLine;
+ private static string _stringMessage;
+
+ /// <summary>
+ /// ConfigurationException Constructor.
+ /// </summary>
+ public ConfigurationException ()
+ {
+ _stringBareMessage = null;
+ _stringFilename = null;
+ _intLine = 0;
+ _stringMessage = null;
+ }
+
+ /// <summary>
+ /// ConfigurationException Constructor.
+ /// </summary>
+ public ConfigurationException (string message)
+ {
+ _stringBareMessage = message;
+ _stringFilename = null;
+ _intLine = 0;
+ _stringMessage = null;
+ }
+
+ /// <summary>
+ /// ConfigurationException Constructor.
+ /// </summary>
+ public ConfigurationException (string message, Exception inner)
+ {
+ _stringBareMessage = message + " " + inner.ToString();
+ _stringFilename = null;
+ _intLine = 0;
+ _stringMessage = null;
+ }
+
+ /// <summary>
+ /// ConfigurationException Constructor.
+ /// </summary>
+ public ConfigurationException (string message, XmlNode node)
+ {
+ _stringBareMessage = message;
+ _stringFilename = GetXmlNodeFilename(node);
+ _intLine = GetXmlNodeLineNumber(node);
+ _stringMessage = _stringFilename + " " + _intLine;
+ }
+
+ /// <summary>
+ /// ConfigurationException Constructor.
+ /// </summary>
+ public ConfigurationException (string message, Exception inner, XmlNode node)
+ {
+ _stringBareMessage = message + " " + inner.ToString();
+ _stringFilename = GetXmlNodeFilename(node);
+ _intLine = GetXmlNodeLineNumber(node);
+ _stringMessage = _stringFilename + " " + _intLine;
+ }
+
+ /// <summary>
+ /// ConfigurationException Constructor.
+ /// </summary>
+ public ConfigurationException (string message, string filename, int line)
+ {
+ _stringBareMessage = message;
+ _stringFilename = filename;
+ _intLine = line;
+ _stringMessage = _stringFilename + " " + _intLine;
+ }
+
+ /// <summary>
+ /// ConfigurationException Constructor.
+ /// </summary>
+ public ConfigurationException (string message, Exception inner, string filename, int line)
+ {
+ _stringBareMessage = message + " " + inner.ToString();
+ _stringFilename = filename;
+ _intLine = line;
+ _stringMessage = _stringFilename + " " + _intLine;
+ }
+
+
+
+ /// <summary>
+ /// Returns the name of the file containing the configuration section node.
+ /// </summary>
+ /// <param name="node"></param>
+ /// <returns></returns>
+ public static string GetXmlNodeFilename(XmlNode node)
+ {
+ _stringFilename = node.OwnerDocument.Name;
+ return _stringFilename;
+ }
+
+ /// <summary>
+ /// Returns the line number containing the configuration section node.
+ /// </summary>
+ /// <param name="node"></param>
+ /// <returns></returns>
+ public static int GetXmlNodeLineNumber(XmlNode node)
+ {
+
+ //FIXME: not sure how this should work.
+ return 0;
+ }
+
+
+ /// <summary>
+ /// Gets the base error message.
+ /// </summary>
+ public string BareMessage
+ {
+ get
+ {
+ return _stringBareMessage;
+ }
+ }
+
+ /// <summary>
+ /// Gets the name of the configuration file where the error occurred.
+ /// </summary>
+ public string Filename
+ {
+ get
+ {
+ return _stringFilename;
+ }
+ }
+
+ /// <summary>
+ /// Returns the line number where the error occurred.
+ /// </summary>
+ public int Line
+ {
+ get
+ {
+ return _intLine;
+ }
+ }
+
+ /// <summary>
+ /// Gets a string containing the concatenated file name and line number where the error occurred.
+ /// </summary>
+ public override string Message
+ {
+ get
+ {
+ return _stringMessage;
+ }
+ }
+ }
+}
+
+
diff --git a/mcs/class/System/System.Configuration/ConfigurationSettings.cs b/mcs/class/System/System.Configuration/ConfigurationSettings.cs
new file mode 100644
index 00000000000..86fcb9a764f
--- /dev/null
+++ b/mcs/class/System/System.Configuration/ConfigurationSettings.cs
@@ -0,0 +1,60 @@
+//
+// System.Configuration.ConfigurationSettings.cs
+//
+// Author:
+// Christopher Podurgiel (cpodurgiel@msn.com)
+//
+// (C) Ximian, Inc. http://www.ximian.com
+//
+
+using System;
+using System.Collections.Specialized;
+
+namespace System.Configuration
+{
+ /// <summary>
+ /// Component class.
+ /// </summary>
+ /// <remarks>
+ /// Longer description
+ /// </remarks>
+
+ public sealed class ConfigurationSettings
+ {
+
+ private NameValueCollection appsettings;
+
+
+ /// <summary>
+ /// ConfigurationSettings Constructor.
+ /// </summary>
+ public ConfigurationSettings ()
+ {
+ appsettings = new NameValueCollection();
+ }
+
+ /// <summary>
+ /// Returns configuration settings for a user-defined configuration section.
+ /// </summary>
+ /// <param name="sectionName"></param>
+ /// <returns></returns>
+ public static object GetConfig( string sectionName)
+ {
+ //FIXME: Not sure how to determine the correct .config file to parse.
+ return null;
+ }
+
+ /// <summary>
+ /// Get the Application Configuration Settings.
+ /// </summary>
+ public NameValueCollection AppSettings
+ {
+ get
+ {
+ return appsettings;
+ }
+ }
+ }
+}
+
+
diff --git a/mcs/class/System/System.Configuration/IConfigurationSectionHandler.cs b/mcs/class/System/System.Configuration/IConfigurationSectionHandler.cs
new file mode 100644
index 00000000000..444ce757f23
--- /dev/null
+++ b/mcs/class/System/System.Configuration/IConfigurationSectionHandler.cs
@@ -0,0 +1,30 @@
+//
+// System.Configuration.IConfigurationSectionHandler.cs
+//
+// Author:
+// Christopher Podurgiel (cpodurgiel@msn.com)
+//
+// (C) Ximian, Inc. http://www.ximian.com
+//
+using System;
+using System.Xml;
+
+namespace System.Configuration
+{
+ /// <summary>
+ /// Summary description for IConfigurationSectionHandler.
+ /// </summary>
+ public interface IConfigurationSectionHandler
+ {
+ /// <summary>
+ /// Creates a new configuration handler and adds the specified configuration object to the collection.
+ /// </summary>
+ /// <param name="parent">Composed from the configuration settings in a corresponding parent configuration section.</param>
+ /// <param name="configContext">Provides access to the virtual path for which the configuration section handler computes configuration values. Normally this parameter is reserved and is null.</param>
+ /// <param name="section">The XML node that contains the configuration information to be handled. section provides direct access to the XML contents of the configuration section.</param>
+ /// <returns></returns>
+ object Create(object parent, object configContext, XmlNode section);
+ }
+}
+
+
diff --git a/mcs/class/System/System.Configuration/IgnoreSectionHandler.cs b/mcs/class/System/System.Configuration/IgnoreSectionHandler.cs
new file mode 100644
index 00000000000..9147c23f310
--- /dev/null
+++ b/mcs/class/System/System.Configuration/IgnoreSectionHandler.cs
@@ -0,0 +1,45 @@
+//
+// System.Configuration.IgnoreSectionHandler.cs
+//
+// Author:
+// Christopher Podurgiel (cpodurgiel@msn.com)
+//
+// (C) Ximian, Inc. http://www.ximian.com
+//
+
+using System;
+using System.Xml;
+
+namespace System.Configuration
+{
+ /// <summary>
+ /// Summary description for IgnoreSectionHandler.
+ /// </summary>
+ public class IgnoreSectionHandler : IConfigurationSectionHandler
+ {
+ /// <summary>
+ /// IgnoreSectionHandler Constructor
+ /// </summary>
+ public IgnoreSectionHandler()
+ {
+ //
+ // TODO: Add constructor logic here
+ //
+ }
+
+ /// <summary>
+ /// Creates a new configuration handler and adds the specified configuration object to the collection.
+ /// </summary>
+ /// <param name="parent">Composed from the configuration settings in a corresponding parent configuration section.</param>
+ /// <param name="configContext">Provides access to the virtual path for which the configuration section handler computes configuration values. Normally this parameter is reserved and is null.</param>
+ /// <param name="section">The XML node that contains the configuration information to be handled. section provides direct access to the XML contents of the configuration section.</param>
+ /// <returns></returns>
+ public virtual object Create(object parent, object configContext, XmlNode section)
+ {
+ //FIXME: Add Implemetation code here.
+ return null;
+ }
+ }
+}
+
+
diff --git a/mcs/class/System/System.Configuration/NameValueSectionHandler.cs b/mcs/class/System/System.Configuration/NameValueSectionHandler.cs
new file mode 100644
index 00000000000..4f4cc9a1f7f
--- /dev/null
+++ b/mcs/class/System/System.Configuration/NameValueSectionHandler.cs
@@ -0,0 +1,70 @@
+//
+// System.Configuration.NameValueSectionHandler.cs
+//
+// Author:
+// Christopher Podurgiel (cpodurgiel@msn.com)
+//
+// (C) Ximian, Inc. http://www.ximian.com
+//
+using System;
+using System.Xml;
+
+namespace System.Configuration
+{
+ /// <summary>
+ /// Summary description for NameValueSectionHandler.
+ /// </summary>
+ public class NameValueSectionHandler : IConfigurationSectionHandler
+ {
+
+ private static string _stringKey;
+ private static string _stringValue;
+
+ /// <summary>
+ /// NameValueSectionHandler Constructor
+ /// </summary>
+ public NameValueSectionHandler()
+ {
+ _stringKey = "key";
+ _stringValue = "value";
+ }
+
+ /// <summary>
+ /// Creates a new configuration handler and adds the specified configuration object to the collection.
+ /// </summary>
+ /// <param name="parent">Composed from the configuration settings in a corresponding parent configuration section.</param>
+ /// <param name="configContext">Provides access to the virtual path for which the configuration section handler computes configuration values. Normally this parameter is reserved and is null.</param>
+ /// <param name="section">The XML node that contains the configuration information to be handled. section provides direct access to the XML contents of the configuration section.</param>
+ /// <returns></returns>
+ public object Create(object parent, object context, XmlNode section)
+ {
+ //FIXME: Add Implemetation code here.
+ return null;
+ }
+
+ /// <summary>
+ /// Gets the name of the key in the key-value pair.
+ /// </summary>
+ protected virtual string KeyAttributeName
+ {
+ get
+ {
+ return _stringKey;
+ }
+ }
+
+ /// <summary>
+ /// Gets the value for the key in the key-value pair.
+ /// </summary>
+ protected virtual string ValueAttributeName
+ {
+ get
+ {
+ return _stringValue;
+ }
+ }
+
+ }
+}
+
+
diff --git a/mcs/class/System/System.Configuration/common.src b/mcs/class/System/System.Configuration/common.src
new file mode 100644
index 00000000000..15655daf677
--- /dev/null
+++ b/mcs/class/System/System.Configuration/common.src
@@ -0,0 +1,5 @@
+ConfigurationException.cs
+ConfigurationSettings.cs
+IConfigurationSectionHandler.cs
+IgnoreSectionHandler.cs
+NameValueSectionHandler.cs
diff --git a/mcs/class/System/System.Configuration/unix.src b/mcs/class/System/System.Configuration/unix.src
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/mcs/class/System/System.Configuration/unix.src
diff --git a/mcs/class/System/System.Configuration/windows.src b/mcs/class/System/System.Configuration/windows.src
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/mcs/class/System/System.Configuration/windows.src
diff --git a/mcs/class/System/System.Net.Sockets/AddressFamily.cs b/mcs/class/System/System.Net.Sockets/AddressFamily.cs
new file mode 100644
index 00000000000..4bffe9685f8
--- /dev/null
+++ b/mcs/class/System/System.Net.Sockets/AddressFamily.cs
@@ -0,0 +1,46 @@
+//
+// System.Net.Sockets.AddressFamily.cs
+//
+// Author:
+// Andrew Sutton
+//
+// (C) Andrew Sutton
+//
+
+namespace System.Net.Sockets
+{
+ public enum AddressFamily
+ {
+ AppleTalk,
+ Atm,
+ Banyan,
+ Ccitt,
+ Chaos,
+ Cluster,
+ DataKit,
+ DataLink,
+ DecNet,
+ Ecma,
+ FireFox,
+ HyperChannel,
+ Ieee12844,
+ ImpLink,
+ InterNetwork,
+ InterNetworkV6,
+ Ipx,
+ Irda,
+ Iso,
+ Lat,
+ Max,
+ NetBios,
+ NetworkDesigners,
+ NS,
+ Osi,
+ Pup,
+ Sna,
+ Unix,
+ Unknown,
+ Unspecified,
+ VoiceView
+ }
+} \ No newline at end of file
diff --git a/mcs/class/System/System.Net.Sockets/LingerOption.cs b/mcs/class/System/System.Net.Sockets/LingerOption.cs
new file mode 100644
index 00000000000..220921078ac
--- /dev/null
+++ b/mcs/class/System/System.Net.Sockets/LingerOption.cs
@@ -0,0 +1,62 @@
+//
+// System.Net.Sockets.LingerOption.cs
+//
+// Author:
+// Andrew Sutton
+//
+// (C) Andrew Sutton
+//
+
+using System;
+
+namespace System.Net.Sockets
+{
+ // <remarks>
+ // Encapsulates a linger option.
+ // </remarks>
+ public class LingerOption
+ {
+ protected bool enabled;
+ protected int seconds;
+
+ public LingerOption (bool enable, int secs)
+ {
+ enabled = enable;
+ seconds = secs;
+ }
+
+ public bool Enabled
+ {
+ get { return enabled; }
+ set { enabled = value; }
+ }
+
+ public int LingerTime
+ {
+ get { return seconds; }
+ set { seconds = value; }
+ }
+
+ public override bool Equals (object o)
+ {
+ return (enabled == o.enabled) && (seconds == o.seconds);
+ }
+
+ public override int GetHashCode()
+ {
+ return seconds;
+ }
+
+ public string ToString()
+ {
+ string ret;
+ if (enabled) {
+ ret = "off";
+ }
+ else {
+ ret = seconds.ToString();
+ }
+ return ret;
+ }
+ }
+} \ No newline at end of file
diff --git a/mcs/class/System/System.Net.Sockets/MulticastOption.cs b/mcs/class/System/System.Net.Sockets/MulticastOption.cs
new file mode 100644
index 00000000000..6f88dde2565
--- /dev/null
+++ b/mcs/class/System/System.Net.Sockets/MulticastOption.cs
@@ -0,0 +1,61 @@
+//
+// System.Net.Sockets.MulticastOption.cs
+//
+// Author:
+// Andrew Sutton
+//
+// (C) Andrew Sutton
+//
+
+using System;
+using System.Net;
+
+namespace System.Net.Sockets
+{
+ // <remarks>
+ // Encapsulates a multicast option
+ // </remarks>
+ public class MulticastOption
+ {
+ protected IPAddress group;
+ protected IPAddress local;
+
+ public MulticastOption (IPAddress grp)
+ {
+ group = grp;
+ }
+
+ public MulticastOption (IPAddress grp, IPAddress addr)
+ {
+ group = grp;
+ local = addr;
+ }
+
+ public IPAddress Group
+ {
+ get { return group; }
+ set { group = value; }
+ }
+
+ public IPAddress LocalAddress
+ {
+ get { return local; }
+ set { local = value; }
+ }
+
+ public override bool Equals (object o)
+ {
+ return false;
+ }
+
+ public override int GetHashCode()
+ {
+ return group.GetHashCode();
+ }
+
+ public override string ToString()
+ {
+ return group.ToString() + " " + local.ToString();
+ }
+ }
+}
diff --git a/mcs/class/System/System.Net.Sockets/NetworkStream.cs b/mcs/class/System/System.Net.Sockets/NetworkStream.cs
new file mode 100644
index 00000000000..ad13c410145
--- /dev/null
+++ b/mcs/class/System/System.Net.Sockets/NetworkStream.cs
@@ -0,0 +1,17 @@
+//
+// System.Net.Sockets.NetworkStream.cs
+//
+// Author:
+// Andrew Sutton
+//
+// (C) Andrew Sutton
+//
+
+using System.IO;
+
+namespace System.Net.Sockets
+{
+ public class NetworkStream : Stream
+ {
+ }
+}
diff --git a/mcs/class/System/System.Net.Sockets/ProtocolFamily.cs b/mcs/class/System/System.Net.Sockets/ProtocolFamily.cs
new file mode 100644
index 00000000000..3b0777e6e54
--- /dev/null
+++ b/mcs/class/System/System.Net.Sockets/ProtocolFamily.cs
@@ -0,0 +1,46 @@
+//
+// System.Net.Sockets.ProtocolFamily.cs
+//
+// Author:
+// Andrew Sutton
+//
+// (C) Andrew Sutton
+//
+
+namespace System.Net.Sockets
+{
+ public enum ProtocolFamily
+ {
+ AppleTalk,
+ Atm,
+ Banyan,
+ Ccitt,
+ Chaos,
+ Cluster,
+ DataKit,
+ DataLink,
+ DecNet,
+ Ecma,
+ FireFox,
+ HyperChannel,
+ Ieee12844,
+ ImpLink,
+ InterNetwork,
+ InterNetworkV6,
+ Ipx,
+ Irda,
+ Iso,
+ Lat,
+ Max,
+ NetBios,
+ NetworkDesigners,
+ NS,
+ Osi,
+ Pup,
+ Sna,
+ Unix,
+ Unknown,
+ Unspecified,
+ VoiceView
+ }
+}
diff --git a/mcs/class/System/System.Net.Sockets/ProtocolType.cs b/mcs/class/System/System.Net.Sockets/ProtocolType.cs
new file mode 100644
index 00000000000..fd62ab1a15f
--- /dev/null
+++ b/mcs/class/System/System.Net.Sockets/ProtocolType.cs
@@ -0,0 +1,30 @@
+//
+// System.Net.Sockets.ProtocolType.cs
+//
+// Author:
+// Andrew Sutton
+//
+// (C) Andrew Sutton
+//
+
+namespace System.Net.Sockets
+{
+ public enum ProtocolType
+ {
+ Ggp,
+ Icmp,
+ Idp,
+ Igmp,
+ Ip,
+ Ipx,
+ ND,
+ Pup,
+ Raw,
+ Spx,
+ SpxII,
+ Tcp,
+ Udp,
+ Unknown,
+ Unspecified
+ }
+} \ No newline at end of file
diff --git a/mcs/class/System/System.Net.Sockets/SelectMode.cs b/mcs/class/System/System.Net.Sockets/SelectMode.cs
new file mode 100644
index 00000000000..a2075ae718d
--- /dev/null
+++ b/mcs/class/System/System.Net.Sockets/SelectMode.cs
@@ -0,0 +1,18 @@
+//
+// System.Net.Sockets.SelectMode.cs
+//
+// Author:
+// Andrew Sutton
+//
+// (C) Andrew Sutton
+//
+
+namespace System.Net.Sockets
+{
+ public enum SelectMode
+ {
+ SelectError,
+ SelectRead,
+ SelectWrite
+ }
+} \ No newline at end of file
diff --git a/mcs/class/System/System.Net.Sockets/Socket.cs b/mcs/class/System/System.Net.Sockets/Socket.cs
new file mode 100644
index 00000000000..6f9349c3d90
--- /dev/null
+++ b/mcs/class/System/System.Net.Sockets/Socket.cs
@@ -0,0 +1,21 @@
+//
+// System.Net.Sockets.Socket.cs
+//
+// Author:
+// Andrew Sutton
+//
+// (C) Andrew Sutton
+//
+
+using System;
+using System.Net;
+
+namespace System.Net.Sockets
+{
+ public class Socket : IDisposable
+ {
+ public Socket (AddressFamily af, SocketType type, ProtocolType prot)
+ {
+ }
+ }
+} \ No newline at end of file
diff --git a/mcs/class/System/System.Net.Sockets/SocketException.cs b/mcs/class/System/System.Net.Sockets/SocketException.cs
new file mode 100644
index 00000000000..5c2c03ea445
--- /dev/null
+++ b/mcs/class/System/System.Net.Sockets/SocketException.cs
@@ -0,0 +1,103 @@
+//
+// System.Net.Sockets.NetworkStream.cs
+//
+// Author:
+// Andrew Sutton
+//
+// (C) Andrew Sutton
+//
+using System;
+
+namespace System.Net.Sockets
+{
+ // <remarks>
+ // A socket exception. Does this REALLY need to
+ // be derived from Win32Exception? It seems a
+ // little lame.
+ //
+ // This needs some work...
+ // </remarks>
+ public class SocketException : Exception
+ {
+ protected int error_code;
+ protected int native_code;
+ protected string help_link;
+ protected string message;
+
+ public SocketException ()
+ {
+ error_code = 0;
+ }
+
+ public SocketException (int error)
+ {
+ error_code = error;
+ }
+
+ public SocketException (SerializationInfo info, StreamingContext cxt)
+ {
+ }
+
+ public override int ErrorCode
+ {
+ get { return error_code; }
+ }
+
+ public override string HelpLink
+ {
+ get { return help_link; }
+ set { help_link = value; }
+ }
+
+ public override Exception InnerException
+ {
+ get { return inner_exception }
+ }
+
+ public override string Message
+ {
+ get { return message; }
+ }
+
+ public override int NativeErrorCode
+ {
+ get { return native_code; }
+ }
+
+ public override string Source
+ {
+ get { return source; }
+ }
+
+ public override string StackTrace
+ {
+ get { return stack_trace; }
+ }
+
+ public override MethodBase TargetSite
+ {
+ get { return target_site; }
+ }
+
+ protected override int HResult
+ {
+ get { return hresult; }
+ set { hresult = value; }
+ }
+
+ public override int GetHashCode()
+ {
+ return native_code;
+ }
+
+ public override void GetObjectData( SerializationInfo info, StreamingContext cxt )
+ {
+ // TODO: fill this in
+ }
+
+ public override string ToString()
+ {
+ return error_code + " " + help_link;
+ }
+ }
+}
diff --git a/mcs/class/System/System.Net.Sockets/SocketFlags.cs b/mcs/class/System/System.Net.Sockets/SocketFlags.cs
new file mode 100644
index 00000000000..6e5f088f6a1
--- /dev/null
+++ b/mcs/class/System/System.Net.Sockets/SocketFlags.cs
@@ -0,0 +1,21 @@
+//
+// System.Net.Sockets.SocketFlags.cs
+//
+// Author:
+// Andrew Sutton
+//
+// (C) Andrew Sutton
+//
+
+namespace System.Net.Sockets
+{
+ public enum SocketFlags
+ {
+ DontRoute,
+ MaxIOVectorLength,
+ None,
+ OutOfBand,
+ Partial,
+ Peek
+ }
+} \ No newline at end of file
diff --git a/mcs/class/System/System.Net.Sockets/SocketOptionLevel.cs b/mcs/class/System/System.Net.Sockets/SocketOptionLevel.cs
new file mode 100644
index 00000000000..99ade7717ee
--- /dev/null
+++ b/mcs/class/System/System.Net.Sockets/SocketOptionLevel.cs
@@ -0,0 +1,19 @@
+//
+// System.Net.Sockets.SocketOptionLevel.cs
+//
+// Author:
+// Andrew Sutton
+//
+// (C) Andrew Sutton
+//
+
+namespace System.Net.Sockets
+{
+ public enum SocketOptionLevel
+ {
+ Ip,
+ Socket,
+ Tcp,
+ Udp
+ }
+} \ No newline at end of file
diff --git a/mcs/class/System/System.Net.Sockets/SocketOptionName.cs b/mcs/class/System/System.Net.Sockets/SocketOptionName.cs
new file mode 100644
index 00000000000..ed5a2caf2ba
--- /dev/null
+++ b/mcs/class/System/System.Net.Sockets/SocketOptionName.cs
@@ -0,0 +1,54 @@
+//
+// System.Net.Sockets.SocketOptionName.cs
+//
+// Author:
+// Andrew Sutton
+//
+// (C) Andrew Sutton
+//
+
+namespace System.Net.Sockets
+{
+ public enum SocketOptionName
+ {
+ AcceptConnection,
+ AddMembership,
+ AddSourceMembership,
+ BlockSource,
+ Broadcast,
+ BsdUrgent,
+ ChecksumCoverage,
+ Debug,
+ DontFragment,
+ DontLinger,
+ DontRoute,
+ DropMembership,
+ DropSourceMembership,
+ Error,
+ ExclusiveAddress,
+ Expedited,
+ HeaderIncluded,
+ IPOptions,
+ IPTimeToLive,
+ KeepAlive,
+ Linger,
+ MaxConnections,
+ MulticastUnterface,
+ MulticastLoopback,
+ MulticastTimeToLive,
+ NoChecksum,
+ NoDelay,
+ OutOfBandInline,
+ PacketInformation,
+ ReceiveBuffer,
+ ReceiveLowWater,
+ ReceiveTimeout,
+ SendBuffer,
+ SendLowWater,
+ SendTimeout,
+ Type,
+ TypeOfService,
+ UnblockSource,
+ UseLoopback
+ }
+} \ No newline at end of file
diff --git a/mcs/class/System/System.Net.Sockets/SocketShutdown.cs b/mcs/class/System/System.Net.Sockets/SocketShutdown.cs
new file mode 100644
index 00000000000..e6f304dc010
--- /dev/null
+++ b/mcs/class/System/System.Net.Sockets/SocketShutdown.cs
@@ -0,0 +1,18 @@
+//
+// System.Net.Sockets.SocketShutdown.cs
+//
+// Author:
+// Andrew Sutton
+//
+// (C) Andrew Sutton
+//
+
+namespace System.Net.Sockets
+{
+ public enum SocketShutdown
+ {
+ Both,
+ Receive,
+ Send
+ }
+} \ No newline at end of file
diff --git a/mcs/class/System/System.Net.Sockets/SocketType.cs b/mcs/class/System/System.Net.Sockets/SocketType.cs
new file mode 100644
index 00000000000..7968fbe7a71
--- /dev/null
+++ b/mcs/class/System/System.Net.Sockets/SocketType.cs
@@ -0,0 +1,21 @@
+//
+// System.Net.Sockets.SocketType.cs
+//
+// Author:
+// Andrew Sutton
+//
+// (C) Andrew Sutton
+//
+
+namespace System.Net.Sockets
+{
+ public enum SocketType
+ {
+ Dgram,
+ Raw,
+ Rdm,
+ Seqpacket,
+ Stream,
+ Unknown
+ }
+} \ No newline at end of file
diff --git a/mcs/class/System/System.Net.Sockets/common.src b/mcs/class/System/System.Net.Sockets/common.src
new file mode 100644
index 00000000000..6397057dba9
--- /dev/null
+++ b/mcs/class/System/System.Net.Sockets/common.src
@@ -0,0 +1,10 @@
+AddressFamily.cs
+MulticastOption.cs
+ProtocolFamily.cs
+ProtocolType.cs
+SelectMode.cs
+SocketFlags.cs
+SocketOptionLevel.cs
+SocketOptionName.cs
+SocketShutdown.cs
+SocketType.cs
diff --git a/mcs/class/System/System.Net.Sockets/unix.src b/mcs/class/System/System.Net.Sockets/unix.src
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/mcs/class/System/System.Net.Sockets/unix.src
diff --git a/mcs/class/System/System.Net.Sockets/windows.src b/mcs/class/System/System.Net.Sockets/windows.src
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/mcs/class/System/System.Net.Sockets/windows.src
diff --git a/mcs/class/System/System.Net/AuthenticationManager.cs b/mcs/class/System/System.Net/AuthenticationManager.cs
index d1c3e48b291..fd723a11005 100755
--- a/mcs/class/System/System.Net/AuthenticationManager.cs
+++ b/mcs/class/System/System.Net/AuthenticationManager.cs
@@ -7,6 +7,8 @@
// (C) Ximian, Inc. http://www.ximian.com
//
+using System.Collections;
+
namespace System.Net {
public class AuthenticationManager {
@@ -15,41 +17,34 @@ namespace System.Net {
public static IEnumerator RegisteredModules {
get {
- if (!modules)
+ if (modules == null)
modules = new ArrayList ();
- return modules;
+ return modules as IEnumerator;
}
}
public static Authorization PreAuthenticate (WebRequest request,
- ICredentialLookup credentials)
+ ICredentials credentials)
{
// FIXME: implement
+ return null;
}
public static void Register (IAuthenticationModule authenticationModule)
{
- if (!modules)
+ if (modules == null)
modules = new ArrayList ();
modules.Add (authenticationModule);
}
- public static Authorization Respond (WebHeaders ResponseHeaders,
- WebRequest Request,
- ICredentialLookup credentials)
- {
- // FIXME: implement
- return null;
- }
-
public static void Unregister (IAuthenticationModule authenticationModule)
{
// FIXME: implement
}
- pubilc static void Unregister (string authenticationScheme)
+ public static void Unregister (string authenticationScheme)
{
// FIXME: implement
}
diff --git a/mcs/class/System/System.Net/Authorization.cs b/mcs/class/System/System.Net/Authorization.cs
index e3866b0119e..60e8c889f22 100755
--- a/mcs/class/System/System.Net/Authorization.cs
+++ b/mcs/class/System/System.Net/Authorization.cs
@@ -27,7 +27,7 @@ namespace System.Net {
public bool Complete {
get {
- return finished;
+ return complete;
}
}
diff --git a/mcs/class/System/System.Net/ChangeLog b/mcs/class/System/System.Net/ChangeLog
new file mode 100644
index 00000000000..241bc2a2fbb
--- /dev/null
+++ b/mcs/class/System/System.Net/ChangeLog
@@ -0,0 +1,13 @@
+2001-07-12 Sean MacIsaac <macisaac@ximian.com>
+
+ * Authorization.cs: Fixed compiler error.
+
+ * IAuthenticationModule.cs: Changes for Beta2.
+
+ * IPAddress.cs: Internal storage changed to be uint not int.
+
+ * IPEndPoint.cs: Fixed compiler error.
+
+ * EndPoint.cs: Fixed compiler error.
+
+ * AuthenticationManager.cs: Fixed typo.
diff --git a/mcs/class/System/System.Net/EndPoint.cs b/mcs/class/System/System.Net/EndPoint.cs
index d35cad86757..9078f4d1bdc 100755
--- a/mcs/class/System/System.Net/EndPoint.cs
+++ b/mcs/class/System/System.Net/EndPoint.cs
@@ -12,18 +12,21 @@ namespace System.Net {
public class EndPoint {
public virtual EndPoint Create (SocketAddress address)
{
+ return null;
}
public virtual SocketAddress Serialize ()
{
+ return null;
}
protected EndPoint ()
{
}
- public int AddressFamily {
- virtual get {
+ public virtual int AddressFamily {
+ get {
+ return 0;
}
}
diff --git a/mcs/class/System/System.Net/IAuthenticationModule.cs b/mcs/class/System/System.Net/IAuthenticationModule.cs
index 089cdd9d930..15119f74da3 100755
--- a/mcs/class/System/System.Net/IAuthenticationModule.cs
+++ b/mcs/class/System/System.Net/IAuthenticationModule.cs
@@ -23,8 +23,8 @@ namespace System.Net {
bool CanRespond (string challenge);
- Authorization PreAuthenticate (WebRequest request, ICredentialLookup credentials);
+ Authorization PreAuthenticate (WebRequest request, ICredentials credentials);
- Authorization Respond (string challenge, WebRequest request, ICredentialLookup credentials);
+ Authorization Respond (string challenge, WebRequest request, ICredentials credentials);
}
}
diff --git a/mcs/class/System/System.Net/ICredentialLookup.cs b/mcs/class/System/System.Net/ICredentialLookup.cs
index 3e68efe955a..82bf3579822 100755
--- a/mcs/class/System/System.Net/ICredentialLookup.cs
+++ b/mcs/class/System/System.Net/ICredentialLookup.cs
@@ -10,8 +10,6 @@ namespace System.Net {
// <remarks>
// Base authentication interface for Web clients.
// </remarks>
- public interface ICredential {
-
- NetworkCredential GetCredential (string uri, string AuthType);
+ public interface ICredentials {
}
}
diff --git a/mcs/class/System/System.Net/IPAdress.cs b/mcs/class/System/System.Net/IPAdress.cs
index fc4e2d8e79f..5255744a013 100755
--- a/mcs/class/System/System.Net/IPAdress.cs
+++ b/mcs/class/System/System.Net/IPAdress.cs
@@ -13,17 +13,17 @@ namespace System.Net {
// Encapsulates an IP Address.
// </remarks>
public class IPAddress {
- public int Address;
+ public uint address;
- public const int InaddrAny = 0;
- public const int InaddrBroadcast = 0xffffffff;
- public const int InaddrLoopback = 0x7f000001;
- public const int InaddrNone = 0xffffffff;
+ public const uint InaddrAny = 0;
+ public const uint InaddrBroadcast = 0xffffffff;
+ public const uint InaddrLoopback = 0x7f000001;
+ public const uint InaddrNone = 0xffffffff;
// <summary>
// Constructor from a 32-bit constant.
// </summary>
- public IPAddress (int address)
+ public IPAddress (uint address)
{
this.address = address;
}
@@ -33,13 +33,14 @@ namespace System.Net {
// </summary>
public IPAddress (string ip)
{
- string ips = ip.Split (".");
- int i, a = 0;
+ string[] ips = ip.Split (new char[] {'.'});
+ int i;
+ uint a = 0;
- for (i = 0; i < ips.Count; i++)
- a = (a << 8) | (ips [i].ToInt16 ());
+ for (i = 0; i < ips.Length; i++)
+ a = (a << 8) | (UInt16.Parse(ips [i]));
- Address = a;
+ address = a;
}
// <summary>
@@ -49,7 +50,7 @@ namespace System.Net {
// <returns></returns>
public static bool IsLoopback (IPAddress addr)
{
- return addr.Address == InaddrLoopback;
+ return addr.address == InaddrLoopback;
}
// <summary>
@@ -58,13 +59,13 @@ namespace System.Net {
// </summary>
public override string ToString ()
{
- System.Net.IPAddress.ToString (Address);
+ return ToString (address);
}
// <summary>
// Returns this object rendered in a quad-dotted notation
// </summary>
- public static string ToString (int addr)
+ public static string ToString (uint addr)
{
return (addr >> 24).ToString () + "." +
((addr >> 16) & 0xff).ToString () + "." +
@@ -75,13 +76,18 @@ namespace System.Net {
// <returns>
// Whether both objects are equal.
// </returns>
- public override bool Equal (object other)
+ public override bool Equals (object other)
{
- if (typeof (other) is System.Net.IPAddress){
- return Address == ((System.Net.IPAddress) other).Address;
+ if (other is System.Net.IPAddress){
+ return address == ((System.Net.IPAddress) other).address;
}
return false;
}
+
+ public override int GetHashCode ()
+ {
+ return (int)address;
+ }
}
}
diff --git a/mcs/class/System/System.Net/IPEndPoint.cs b/mcs/class/System/System.Net/IPEndPoint.cs
index 3d3809faade..e4d2bcf1582 100755
--- a/mcs/class/System/System.Net/IPEndPoint.cs
+++ b/mcs/class/System/System.Net/IPEndPoint.cs
@@ -15,7 +15,15 @@ namespace System.Net {
public const int MaxPort = 65535;
public const int MinPort = 0;
- public short Port;
+ private int port;
+ public int Port {
+ get {
+ return port;
+ }
+ set {
+ port = value;
+ }
+ }
public IPEndPoint (IPAddress address, int port)
{
@@ -23,15 +31,16 @@ namespace System.Net {
Port = port;
}
- public IPEndPoint (int iaddr, int port)
+ public IPEndPoint (long iaddr, int port)
{
- IPAddress address = new IPAddress (iaddr);
+ IPAddress address = new IPAddress ((uint)iaddr);
- IPEndPoint (address, port);
+ Address = address;
+ this.port = port;
}
- public int AddressFamily {
- override get {
+ public override int AddressFamily {
+ get {
return 2;
}
}
diff --git a/mcs/class/System/System.Net/common.src b/mcs/class/System/System.Net/common.src
new file mode 100755
index 00000000000..676af108ee1
--- /dev/null
+++ b/mcs/class/System/System.Net/common.src
@@ -0,0 +1,5 @@
+Authorization.cs
+EndPoint.cs
+IPAdress.cs
+IPEndPoint.cs
+SocketAddress.cs
diff --git a/mcs/class/System/System.Net/unix.src b/mcs/class/System/System.Net/unix.src
new file mode 100755
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/mcs/class/System/System.Net/unix.src
diff --git a/mcs/class/System/System.Net/windows.src b/mcs/class/System/System.Net/windows.src
new file mode 100755
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/mcs/class/System/System.Net/windows.src
diff --git a/mcs/class/System/System/Uri.cs b/mcs/class/System/System/Uri.cs
new file mode 100755
index 00000000000..edfc82cc144
--- /dev/null
+++ b/mcs/class/System/System/Uri.cs
@@ -0,0 +1,315 @@
+//
+// System.Uri
+//
+// Author:
+// Garrett Rooney (rooneg@electricjellyfish.net)
+//
+// (C) 2001 Garrett Rooney
+//
+
+using System.Runtime.Serialization;
+
+namespace System {
+
+ public class Uri : MarshalByRefObject, ISerializable {
+
+ private string path = "";
+ private string host = "";
+ private string fragment = "";
+ private string scheme = "";
+ private string port = "";
+ private string query = "";
+
+ // FIXME: is this correct?
+ private bool userEscaped = false;
+
+ public static readonly string SchemeDelimiter = "://";
+ public static readonly string UriSchemeFile = "file";
+ public static readonly string UriSchemeFtp = "ftp";
+ public static readonly string UriSchemeGopher = "gopher";
+ public static readonly string UriSchemeHttp = "http";
+ public static readonly string UriSchemeHttps = "https";
+ public static readonly string UriSchemeMailto = "mailto";
+ public static readonly string UriSchemeNntp = "nntp";
+
+ // the details table holds random info about the types of uri's
+ private struct detail {
+ public string scheme;
+ public string port;
+ public string delimiter;
+
+ public detail(string s, string p, string d) {
+ scheme = s;
+ port = p;
+ delimiter = d;
+ }
+ };
+
+ static detail[] details = new detail[] {
+ new detail(UriSchemeFile, "-1", SchemeDelimiter),
+ new detail(UriSchemeFtp, "23", SchemeDelimiter),
+ new detail(UriSchemeGopher, "70", SchemeDelimiter),
+ new detail(UriSchemeHttp, "80", SchemeDelimiter),
+ new detail(UriSchemeHttps, "223", SchemeDelimiter),
+ new detail(UriSchemeMailto, "25", ":"),
+ new detail(UriSchemeNntp, "119", SchemeDelimiter)
+ };
+
+ public static UriHostNameType CheckHostName(string name) {
+ throw new NotImplementedException();
+ }
+
+ public static bool CheckSchemeName(string schemeName) {
+ throw new NotImplementedException();
+ }
+
+ public static int FromHex(char digit) {
+ throw new NotImplementedException();
+ }
+
+ public static string HexEscape(char character) {
+ throw new NotImplementedException();
+ }
+
+ public static char HexUnescape(string pattern, ref int index) {
+ throw new NotImplementedException();
+ }
+
+ public static bool IsHexDigit(char character) {
+ throw new NotImplementedException();
+ }
+
+ public static bool IsHexEncoding(string pattern, int index) {
+ throw new NotImplementedException();
+ }
+
+ private void Parse(string uri) {
+ int i;
+
+ // figure out the scheme
+ int colon = uri.IndexOf(':');
+ if (colon == -1 || colon == uri.Length) {
+ throw new UriFormatException();
+ } else {
+ string s = uri.Substring(0, colon).ToLower();
+ uri = uri.Remove(0, colon);
+ for (i = 0; i < details.Length; i++) {
+ if (details[i].scheme == s) {
+ scheme = details[i].scheme;
+
+ // assume default port. if
+ // they specify one it'll get
+ // set later on.
+ port = details[i].port;
+ break;
+ }
+ }
+ if (i == details.Length) {
+ throw new UriFormatException();
+ }
+ }
+
+ // get rid of the delimiter
+ uri = uri.Remove(0, details[i].delimiter.Length);
+
+ parseHost(uri);
+ }
+
+ private void parseHost(string uri) {
+
+ // FIXME: this doesn't handle IPv6 addresses correctly
+ for (int i = 0; i < uri.Length; i++) {
+ switch (uri[i]) {
+ case ':':
+ host = uri.Substring(0, i);
+ parsePort(uri.Remove(0, i + 1));
+ return;
+ case '/':
+ host = uri.Substring(0, i);
+ parsePath(uri.Remove(0, i + 1));
+ return;
+ case '?':
+ case '#':
+ throw new UriFormatException();
+ default:
+ break;
+ }
+ }
+
+ host = uri;
+ }
+
+ private void parsePort(string uri) {
+
+ for (int i = 0; i < uri.Length; i++) {
+ switch (uri[i]) {
+ case '/':
+ port = uri.Substring(0, i);
+ parsePath(uri.Remove(0, i + 1));
+ return;
+ case '?':
+ case '#':
+ throw new UriFormatException();
+ default:
+ // FIXME: should this check if
+ // uri[i] is a number?
+ break;
+ }
+ }
+
+ port = uri;
+ }
+
+ private void parsePath(string uri) {
+
+ for (int i = 0; i < uri.Length; i++) {
+ switch (uri[i]) {
+ case '#':
+ path = uri.Substring(0, i);
+ fragment = uri.Remove(0, i + 1);
+ return;
+ case '?':
+ path = uri.Substring(0, i);
+ query = uri.Remove(0, i + 1);
+ return;
+ default:
+ break;
+ }
+ }
+
+ path = uri;
+ }
+
+ public Uri(string uri) {
+ Parse(uri);
+ }
+
+ protected Uri(SerializationInfo serializationInfo,
+ StreamingContext streamingContext) {
+ throw new NotImplementedException();
+ }
+
+ public Uri(string uri, bool dontEscape) {
+ userEscaped = dontEscape;
+ Parse(uri);
+ }
+
+ public Uri(Uri baseUri, string relativeUri) {
+ throw new NotImplementedException();
+ }
+
+ public Uri(Uri baseUri, string relativeUri, bool dontEscape) {
+ userEscaped = dontEscape;
+
+ throw new NotImplementedException();
+ }
+
+ public string AbsolutePath { get { return path; } }
+
+ public string AbsoluteUri {
+ get { throw new NotImplementedException(); }
+ }
+
+ public string Authority { get { return host + ":" + port; } }
+
+ public string Fragment { get { return fragment; } }
+
+ public string Host { get { return host; } }
+
+ public UriHostNameType HostNameType {
+ get { throw new NotImplementedException(); }
+ }
+
+ public bool IsDefaultPort {
+ get {
+ for (int i = 0; i < details.Length; i++) {
+ if (details[i].scheme == scheme) {
+ if (details[i].port == port) {
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+ }
+
+ public bool IsFile {
+ get {
+ if (scheme == UriSchemeFile)
+ return true;
+ else
+ return false;
+ }
+ }
+
+ // FIXME: should check IPv6
+ public bool IsLoopback {
+ get {
+ if (host == "localhost" || host == "127.0.0.1")
+ return true;
+ else
+ return false;
+ }
+ }
+
+ public bool IsUnc {
+ get { throw new NotImplementedException(); }
+ }
+
+ public string LocalPath {
+ get { throw new NotImplementedException(); }
+ }
+
+ public string PathAndQuery {
+ get { return path + "?" + query; }
+ }
+
+ public string Port { get { return port; } }
+
+ public string Query { get { return query; } }
+
+ public string Scheme { get { return scheme; } }
+
+ // FIXME: what the hell are segments?
+ public string[] Segments {
+ get { throw new NotImplementedException(); }
+ }
+
+ public bool UserEscaped { get { return userEscaped; } }
+
+ public string UserInfo {
+ get { throw new NotImplementedException(); }
+ }
+
+ public override bool Equals(object compared) {
+ throw new NotImplementedException();
+ }
+
+ public override int GetHashCode() {
+ throw new NotImplementedException();
+ }
+
+ public string GetLeftPart(UriPartial part) {
+ throw new NotImplementedException();
+ }
+
+ public string MakeRelative(Uri toUri) {
+ throw new NotImplementedException();
+ }
+
+ public override string ToString() {
+ throw new NotImplementedException();
+ }
+
+ public void GetObjectData(SerializationInfo info,
+ StreamingContext context)
+ {
+ // FIXME: Implement me. yes, it is public because it implements ISerializable
+ }
+
+ protected static string EscapeString(string str) {
+ throw new NotImplementedException();
+ }
+ }
+}
diff --git a/mcs/class/System/System/UriFormatException.cs b/mcs/class/System/System/UriFormatException.cs
new file mode 100755
index 00000000000..f572dcb4447
--- /dev/null
+++ b/mcs/class/System/System/UriFormatException.cs
@@ -0,0 +1,33 @@
+//
+// System.UriFormatException.cs
+//
+// Author:
+// Scott Sanders (scott@stonecobra.com)
+//
+// (C) 2001 Scott Sanders
+//
+
+using System.Runtime.Serialization;
+
+namespace System {
+
+ public class UriFormatException : Exception {
+
+ // Constructors
+ public UriFormatException ()
+ : base ("Invalid URI format")
+ {
+ }
+
+ public UriFormatException (string message)
+ : base (message)
+ {
+ }
+
+ protected UriFormatException( SerializationInfo info, StreamingContext context)
+ : base ("UriFormatException: Please implement me")
+ {
+ //TODO - Implement me... The Beta2 docs say nothing about what this method does
+ }
+ }
+}
diff --git a/mcs/class/System/System/UriHostNameType.cs b/mcs/class/System/System/UriHostNameType.cs
new file mode 100755
index 00000000000..1b1c6faf8c7
--- /dev/null
+++ b/mcs/class/System/System/UriHostNameType.cs
@@ -0,0 +1,21 @@
+//
+// System.UriHostNameType.cs
+//
+// Author:
+// Miguel de Icaza (miguel@ximian.com)
+//
+// (C) 2001 Ximian, Inc.
+//
+
+using System;
+
+namespace System {
+
+ public enum UriHostNameType {
+ Basic,
+ Dns,
+ IPv4,
+ IPv6,
+ Unknown
+ };
+}
diff --git a/mcs/class/System/System/UriPartial.cs b/mcs/class/System/System/UriPartial.cs
new file mode 100755
index 00000000000..1412e455d8e
--- /dev/null
+++ b/mcs/class/System/System/UriPartial.cs
@@ -0,0 +1,19 @@
+//
+// System.UriPartial.cs
+//
+// Author:
+// Miguel de Icaza (miguel@ximian.com)
+//
+// (C) 2001 Ximian, Inc.
+//
+
+using System;
+
+namespace System {
+
+ public enum UriPartial {
+ Scheme,
+ Authority,
+ Path
+ };
+}
diff --git a/mcs/class/System/System/common.src b/mcs/class/System/System/common.src
new file mode 100755
index 00000000000..e368c9e8299
--- /dev/null
+++ b/mcs/class/System/System/common.src
@@ -0,0 +1,4 @@
+Uri.cs
+UriFormatException.cs
+UriHostNameType.cs
+UriPartial.cs
diff --git a/mcs/class/System/System/unix.src b/mcs/class/System/System/unix.src
new file mode 100755
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/mcs/class/System/System/unix.src
diff --git a/mcs/class/System/System/windows.src b/mcs/class/System/System/windows.src
new file mode 100755
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/mcs/class/System/System/windows.src
diff --git a/mcs/class/System/Test/NameValueCollectionTest.cs b/mcs/class/System/Test/NameValueCollectionTest.cs
new file mode 100644
index 00000000000..1e50a12b3f2
--- /dev/null
+++ b/mcs/class/System/Test/NameValueCollectionTest.cs
@@ -0,0 +1,178 @@
+// created on 7/21/2001 at 2:36 PM
+
+
+
+using System;
+using System.Collections;
+using System.Collections.Specialized;
+using System.Text;
+
+using NUnit.Framework;
+
+
+
+namespace Testsuite.System.Collections.Specialized {
+
+
+ /// <summary>Microsoft NameValueCollection test.</summary>
+ public class NameValueCollectionTest {
+ public static ITest Suite {
+ get {
+ TestSuite suite= new TestSuite("All NameValueCollection Tests");
+ suite.AddTest(BasicOperationsTest.Suite);
+ return suite;
+ }
+ }
+ }
+
+
+
+
+ public class BasicOperationsTest : TestCase {
+
+ protected NameValueCollection nvc;
+ private static Random rnd;
+
+ public BasicOperationsTest(String name) : base(name) {}
+
+ protected override void SetUp() {
+ nvc = new NameValueCollection();
+ rnd=new Random();
+ }
+
+ public static ITest Suite {
+ get {
+ return new TestSuite(typeof(BasicOperationsTest));
+ }
+ }
+
+
+
+ private void SetDefaultData() {
+ nvc.Clear();
+ nvc.Add("k1","this");
+ nvc.Add("k2","test");
+ nvc.Add("k3","is");
+ nvc.Add("k4","silly");
+ }
+ private static string FormatForPrinting(NameValueCollection nv)
+ {
+ if (nv==null)
+ return null;
+ int max = nv.Count;
+ StringBuilder sb = new StringBuilder("-\t-Key-\t-Value-\n");
+ for (int i=0; i<max; i++){
+
+ sb.Append("\t"+nv.GetKey(i)+"\t"+nv[i]+"\n");
+ }
+ return sb.ToString();
+ }
+
+
+ public void TestAddRemoveClearSetGet()
+ {
+ nvc.Clear();
+ Assert(nvc.Count==0&& !nvc.HasKeys());
+
+ SetDefaultData();
+ Assert(nvc.Count==4);
+ Assert("Get operation returns wrong result.\n"+FormatForPrinting(nvc),(nvc.Get(0).Equals("this"))&&(nvc.Get("k1").Equals("this")));
+
+
+ nvc.Add("k2","programmer");
+ Assert(nvc["k2"].Equals("test,programmer"));
+
+ nvc["k2"]="project";
+ nvc.Add("k2","project");
+ Assert(nvc.Count==4);
+ Assert("Wrong effect of add(samekey,samevalue)\n"+FormatForPrinting(nvc),nvc["k2"].Equals("project"));
+ // TODO: add Remove test
+ nvc.Remove("k4");
+ Assert("wrong nvc.Count="+nvc.Count,nvc.Count==3);
+ Assert(nvc["k4"]==null);
+
+ NameValueCollection nvc1 = new NameValueCollection();
+ nvc1["k1"]="these";
+ nvc1["k5"]="!";
+ nvc.Add(nvc1);
+ Assert(FormatForPrinting(nvc)+"Count is wrong after Add(nvc1) Count="+nvc.Count,nvc.Count==4);
+ Assert("Values are wrong after Add(nvc1)",(nvc["k1"].Equals("this,these"))&&(nvc["k5"].Equals("!")));
+
+ nvc.Set("k3","accomplished");
+ Assert("Wrong result of Set operation",nvc["k3"].Equals("accomplished"));
+
+ }
+
+ public void TestGetKeyGetValues()
+ {
+ SetDefaultData();
+ Assert(nvc.GetKey(0).Equals("k1"));
+ string[] values = nvc.GetValues(0);
+ Assert(values[0].Equals("this"));
+
+ }
+
+ public void TestCopyTo() {
+ SetDefaultData();
+ string[] entries=new string[nvc.Count];
+ nvc.CopyTo(entries,0);
+ //Message(FormatForPrinting(nvc));
+ //Assert("Not an entry.",entries[0] is DictionaryEntry);
+ }
+
+ public void TestUnderHeavyLoad() {
+
+ //TODO: add memory and time measurement
+
+ nvc.Clear();
+ int max=10000;
+ String[] cache=new String[max*2];
+ int n=0;
+
+ for (int i=0;i<max;i++) {
+ int id=rnd.Next()&0xFFFF;
+ String key=""+id+"-key-"+id;
+ String val="value-"+id;
+ if (nvc[key]==null) {
+ nvc[key]=val;
+ cache[n]=key;
+ cache[n+max]=val;
+ n++;
+ }
+ }
+
+ Assert(nvc.Count==n);
+
+ for (int i=0;i<n;i++) {
+ String key=cache[i];
+ String val=nvc[key] as String;
+ String err="nvc[\""+key+"\"]=\""+val+
+ "\", expected \""+cache[i+max]+"\"";
+ Assert(err,val!=null && val.Equals(cache[i+max]));
+ }
+
+ int r1=(n/3);
+ int r2=r1+(n/5);
+
+ for (int i=r1;i<r2;i++) {
+ nvc.Remove(cache[i]);
+ }
+
+
+ for (int i=0;i<n;i++) {
+ if (i>=r1 && i<r2) {
+ Assert(nvc[cache[i]]==null);
+ } else {
+ String key=cache[i];
+ String val=nvc[key] as String;
+ String err="ht[\""+key+"\"]=\""+val+
+ "\", expected \""+cache[i+max]+"\"";
+ Assert(err,val!=null && val.Equals(cache[i+max]));
+ }
+ }
+
+ }
+
+ }
+}
+
diff --git a/mcs/class/System/Test/StringCollectionTest.cs b/mcs/class/System/Test/StringCollectionTest.cs
new file mode 100644
index 00000000000..33a1bffc00e
--- /dev/null
+++ b/mcs/class/System/Test/StringCollectionTest.cs
@@ -0,0 +1,152 @@
+/* System.Collections.Specialized.StringCollection.cs
+ * Authors:
+ * John Barnette (jbarn@httcb.net)
+ *
+ * Copyright (C) 2001 John Barnette
+*/
+
+using NUnit.Framework;
+
+namespace System.Collections.Specialized {
+ public class StringCollectionTest : TestCase {
+ private StringCollection sc;
+ string[] strings = {
+ "foo",
+ "bar",
+ "baz",
+ "john",
+ "paul",
+ "george",
+ "ringo"
+ };
+
+ public StringCollectionTest(string name) : base(name) {}
+
+ protected override void SetUp() {
+ sc = new StringCollection();
+ sc.AddRange(strings);
+ }
+
+ // Simple Tests
+
+ public void TestSimpleCount() {
+ Assert(sc.Count == 7);
+ }
+
+ public void TestSimpleIsFixedSize() {
+ Assert(!sc.IsFixedSize);
+ }
+
+ public void TestSimpleIsReadOnly() {
+ Assert(!sc.IsReadOnly);
+ }
+
+ public void TestSimpleIsSynchronized() {
+ Assert(!sc.IsSynchronized);
+ }
+
+ public void TestSimpleItemGet() {
+ for(int i = 0; i < strings.Length; i++) {
+ Assert(strings[i].Equals(sc[i]));
+ }
+ }
+
+ public void TestSimpleItemSet() {
+ sc[0] = "bob";
+ Assert(sc[0].Equals("bob"));
+ }
+
+ public void TestSimpleSyncRoot() {
+ Assert(sc.Equals(sc.SyncRoot));
+ }
+
+ public void TestSimpleAdd() {
+ int index = sc.Add("chuck");
+ Assert(index == strings.Length);
+ Assert(sc[strings.Length].Equals("chuck"));
+
+ }
+
+ public void TestSimpleAddRange() {
+ string[] newStrings = {
+ "peter",
+ "paul",
+ "mary"
+ };
+
+ int index = sc.Count;
+ sc.AddRange(newStrings);
+
+ Assert(sc.Count == index + newStrings.Length);
+
+ for (int i = 0; i+index <= sc.Count-1; i++) {
+ Assert(newStrings[i].Equals(sc[i+index]));
+ }
+ }
+
+ public void TestSimpleClear() {
+ sc.Clear();
+ Assert(sc.Count == 0);
+ }
+
+ public void TestSimpleContains() {
+ Assert(sc.Contains(strings[0]));
+ Assert(!sc.Contains("NOT CONTAINED"));
+ }
+
+ public void TestSimpleCopyTo() {
+ string[] copyArray = new string[sc.Count];
+ sc.CopyTo(copyArray, 0);
+ for (int i = 0; i < copyArray.Length; i++) {
+ Assert(copyArray[i] == sc[i]);
+ }
+ }
+
+ public void TestSimpleGetEnumerator() {
+ int index = 0;
+ foreach(string s in sc) {
+ Assert(s.Equals(strings[index]));
+ index++;
+ }
+ }
+
+ public void TestSimpleIndexOf() {
+ Assert(sc.IndexOf(strings[0]) == 0);
+ }
+
+ public void TestSimpleInsert() {
+ int index = 3;
+ int oldCount = sc.Count;
+ string before = sc[index - 1];
+ string current = sc[index];
+ string after = sc[index + 1];
+ string newStr = "paco";
+
+ sc.Insert(index, newStr);
+
+ Assert(sc.Count == oldCount + 1);
+ Assert(sc[index].Equals(newStr));
+ Assert(sc[index-1].Equals(before));
+ Assert(sc[index+1].Equals(current));
+ Assert(sc[index+2].Equals(after));
+ }
+
+ public void TestSimpleRemove() {
+ int oldCount = sc.Count;
+ sc.Remove(strings[0]);
+ Assert(oldCount == sc.Count + 1);
+ Assert(!sc.Contains(strings[0]));
+ }
+
+ public void TestSimpleRemoveAt() {
+ int index = 3;
+ int oldCount = sc.Count;
+ string after = sc[index+1];
+
+ sc.RemoveAt(index);
+ Assert(oldCount == sc.Count + 1);
+ Assert(sc[index].Equals(after));
+ }
+
+ }
+}
diff --git a/mcs/class/System/makefile b/mcs/class/System/makefile
new file mode 100644
index 00000000000..79792c462fe
--- /dev/null
+++ b/mcs/class/System/makefile
@@ -0,0 +1,16 @@
+DIRS=System System.CodeDom System.CodeDom.Compiler System.ComponentModel System.Configuration System.Net System.Net.Sockets System.Collections.Specialized
+
+all:
+ @echo "You must use 'make windows' or 'make unix'."
+ @echo "'make unix' is broken for now."
+
+windows: make-list
+ $(CSC) /target:library /out:System.dll /nowarn:1595 @list
+
+unix:
+ @echo "'make unix' is broken for now."
+
+make-list:
+ for i in $(DIRS); do \
+ cat $$i/common.src $$i/windows.src | sed "s/^/$$i\\\\/"; \
+ done > list
diff --git a/mcs/class/corlib/.cvsignore b/mcs/class/corlib/.cvsignore
new file mode 100644
index 00000000000..9c62b85cbd8
--- /dev/null
+++ b/mcs/class/corlib/.cvsignore
@@ -0,0 +1,3 @@
+corlib.dll
+list
+listmono
diff --git a/mcs/class/corlib/System.Collections/ArrayList.cs b/mcs/class/corlib/System.Collections/ArrayList.cs
new file mode 100644
index 00000000000..3bae5112abd
--- /dev/null
+++ b/mcs/class/corlib/System.Collections/ArrayList.cs
@@ -0,0 +1,462 @@
+// -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+//
+// System.Collections.ArrayList
+//
+// Author:
+// Vladimir Vukicevic (vladimir@pobox.com)
+//
+// (C) 2001 Vladimir Vukicevic
+//
+
+using System;
+
+namespace System.Collections {
+
+ public class ArrayList : IList, ICollection, IEnumerable, ICloneable {
+ // constructors
+
+ public ArrayList () {
+ dataArray = new object[capacity];
+ }
+
+ public ArrayList (ICollection c) {
+ }
+
+ public ArrayList (int capacity) {
+ dataArray = new object[capacity];
+ this.capacity = capacity;
+ }
+
+ private ArrayList (object[] dataArray, int count, int capacity,
+ bool fixedSize, bool readOnly, bool synchronized)
+ {
+ this.dataArray = dataArray;
+ this.count = count;
+ this.capacity = capacity;
+ this.fixedSize = fixedSize;
+ this.readOnly = readOnly;
+ this.synchronized = synchronized;
+ }
+
+ public static ArrayList ReadOnly (ArrayList list) {
+ throw new NotImplementedException ("System.Collections.ArrayList.ReadOnly");
+ }
+
+ public static ArrayList ReadOnly (IList list) {
+ throw new NotImplementedException ("System.Collections.ArrayList.ReadOnly");
+ }
+
+ public static ArrayList Synchronized (ArrayList list) {
+ throw new NotImplementedException ("System.Collections.ArrayList.Synchronized");
+ }
+
+ public static ArrayList Synchronized (IList list) {
+ throw new NotImplementedException ("System.Collections.ArrayList.Synchronized");
+ }
+
+ public static ArrayList FixedSize (ArrayList list) {
+ throw new NotImplementedException ("System.Collections.ArrayList.FixedSize");
+ }
+
+ public static ArrayList FixedSize (IList list) {
+ throw new NotImplementedException ("System.Collections.ArrayList.FixedSize");
+ }
+
+ public static ArrayList Repeat (object value, int count) {
+ ArrayList al = new ArrayList (count);
+ for (int i = 0; i < count; i++) {
+ al.dataArray[i] = value;
+ }
+ al.count = count;
+
+ return al;
+ }
+
+ public static ArrayList Adapter (IList list) {
+ throw new NotImplementedException ("System.Collections.ArrayList.Adapter");
+ }
+
+ // properties
+
+ private bool fixedSize = false;
+ private bool readOnly = false;
+ private bool synchronized = false;
+
+ private int count = 0;
+ private int capacity = 16;
+
+ private object[] dataArray;
+
+ private void copyDataArray (object[] outArray) {
+ for (int i = 0; i < count; i++) {
+ outArray[i] = dataArray[i];
+ }
+ }
+
+ private void setSize (int newSize) {
+ if (newSize == capacity) {
+ return;
+ }
+
+ // note that this assumes that we've already sanity-checked
+ // the new size
+ object[] newDataArray = new object[newSize];
+ copyDataArray (newDataArray);
+ dataArray = newDataArray;
+
+ capacity = newSize;
+ }
+
+ // note that this DOES NOT update count
+ private void shiftElements (int startIndex, int numshift) {
+ if (numshift == 0) {
+ return;
+ }
+
+ if (count + numshift > capacity) {
+ setSize (capacity * 2);
+ shiftElements (startIndex, numshift);
+ } else {
+ if (numshift > 0) {
+ int numelts = count - startIndex;
+ for (int i = numelts-1; i >= 0; i--) {
+ dataArray[startIndex + numshift + i] = dataArray[startIndex + i];
+ }
+
+ for (int i = startIndex; i < startIndex + numshift; i++) {
+ dataArray[i] = null;
+ }
+ } else {
+ int numelts = count - startIndex + numshift;
+ for (int i = startIndex; i < numelts; i++) {
+ dataArray[i] = dataArray[i - numshift];
+ }
+ for (int i = count + numshift; i < count; i++) {
+ dataArray[i] = null;
+ }
+ }
+ }
+ }
+
+ public virtual int Capacity {
+ get {
+ return capacity;
+ }
+
+ set {
+ if (readOnly) {
+ throw new NotSupportedException
+ ("Collection is read-only.");
+ }
+
+ if (value < count) {
+ throw new ArgumentOutOfRangeException
+ ("ArrayList Capacity being set to less than Count");
+ }
+
+ if (fixedSize && value != capacity) {
+ throw new NotSupportedException
+ ("Collection is fixed size.");
+ }
+
+ setSize (value);
+ }
+ }
+
+ public virtual int Count {
+ get {
+ return count;
+ }
+ }
+
+ public virtual bool IsFixedSize {
+ get {
+ return fixedSize;
+ }
+ }
+
+ public virtual bool IsReadOnly {
+ get {
+ return readOnly;
+ }
+ }
+
+ public virtual bool IsSynchronized {
+ get {
+ return synchronized;
+ }
+ }
+
+ public virtual object this[int index] {
+ get {
+ if (index < 0) {
+ throw new ArgumentOutOfRangeException ("index < 0");
+ }
+
+ if (index >= count) {
+ throw new ArgumentOutOfRangeException ("index out of range");
+ }
+
+ return dataArray[index];
+ }
+ set {
+ if (index < 0) {
+ throw new ArgumentOutOfRangeException ("index < 0");
+ }
+ // FIXME -- should setting an index implicitly extend the array?
+ // the docs aren't clear -- I'm assuming not, since the exception
+ // is listed for both get and set
+ if (index >= count) {
+ throw new ArgumentOutOfRangeException ("index out of range");
+ }
+
+ if (readOnly) {
+ throw new NotSupportedException ("Collection is read-only.");
+ }
+
+ dataArray[index] = value;
+ }
+ }
+
+ public virtual object SyncRoot {
+ get {
+ throw new NotImplementedException ("System.Collections.ArrayList.SyncRoot.get");
+ }
+ }
+
+
+ // methods
+
+ public virtual int Add (object value) {
+ if (readOnly) {
+ throw new NotSupportedException ("Collection is read-only.");
+ }
+
+ if (count + 1 >= capacity) {
+ setSize (capacity * 2);
+ }
+
+ dataArray[count++] = value;
+ return count-1;
+ }
+
+ public virtual void AddRange (ICollection c) {
+ throw new NotImplementedException ("System.Collections.ArrayList.AddRange");
+ }
+
+ public virtual int BinarySearch (object value) {
+ throw new NotImplementedException ("System.Collections.ArrayList.BinarySearch");
+ }
+
+ public virtual int BinarySearch (object value, IComparer comparer) {
+ throw new NotImplementedException ("System.Collections.ArrayList.BinarySearch");
+ }
+
+ public virtual int BinarySearch (int index, int count,
+ object value, IComparer comparer) {
+ throw new NotImplementedException ("System.Collections.ArrayList.BinarySearch");
+ }
+
+ public virtual void Clear () {
+ count = 0;
+ setSize(capacity);
+ }
+
+ public virtual object Clone () {
+ return new ArrayList (dataArray, count, capacity,
+ fixedSize, readOnly, synchronized);
+ }
+
+ public virtual bool Contains (object item) {
+ for (int i = 0; i < count; i++) {
+ if (Object.Equals (dataArray[i], item)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ public virtual void CopyTo (Array array) {
+ }
+
+ public virtual void CopyTo (Array array, int arrayIndex) {
+ }
+
+ public virtual void CopyTo (int index, Array array,
+ int arrayIndex, int count) {
+ }
+
+ public virtual IEnumerator GetEnumerator () {
+ return null;
+ }
+
+ public virtual IEnumerator GetEnumerator (int index, int count) {
+ return null;
+ }
+
+ public virtual ArrayList GetRange (int index, int count) {
+ return null;
+ }
+
+ public virtual int IndexOf (object value) {
+ return IndexOf (value, 0, count);
+ }
+
+ public virtual int IndexOf (object value, int startIndex) {
+ return IndexOf (value, startIndex, count - startIndex);
+ }
+
+ public virtual int IndexOf (object value, int startIndex, int count) {
+ if (startIndex < 0 || startIndex + count > this.count || count < 0) {
+ throw new ArgumentOutOfRangeException ("IndexOf arguments out of range");
+ }
+ for (int i = startIndex; i < (startIndex + count); i++) {
+ if (Object.Equals (dataArray[i], value)) {
+ return i;
+ }
+ }
+
+ return -1;
+ }
+
+ public virtual void Insert (int index, object value) {
+ if (readOnly) {
+ throw new NotSupportedException
+ ("Collection is read-only.");
+ }
+
+ if (fixedSize) {
+ throw new NotSupportedException
+ ("Collection is fixed size.");
+ }
+
+ if (index < 0 || index >= count) {
+ throw new ArgumentOutOfRangeException ("index < 0 or index >= count");
+ }
+
+ shiftElements (index, 1);
+ dataArray[index] = value;
+ count++;
+ }
+
+ public virtual void InsertRange (int index, ICollection c) {
+ }
+
+ public virtual int LastIndexOf (object value) {
+ return LastIndexOf (value, 0, count);
+ }
+
+ public virtual int LastIndexOf (object value, int startIndex) {
+ return LastIndexOf (value, startIndex, count - startIndex);
+ }
+
+ public virtual int LastIndexOf (object value, int StartIndex,
+ int count)
+ {
+ for (int i = count - 1; i >= 0; i--) {
+ if (Object.Equals (dataArray[i], value)) {
+ return i;
+ }
+ }
+
+ return -1;
+ }
+
+ public virtual void Remove (object obj) {
+ int objIndex = IndexOf (obj);
+
+ if (objIndex == -1) {
+ // shouldn't an exception be thrown here??
+ // the MS docs don't indicate one, and testing
+ // with the MS .net framework doesn't indicate one
+ return;
+ }
+
+ RemoveRange (objIndex, 1);
+ }
+
+ public virtual void RemoveAt (int index) {
+ RemoveRange (index, 1);
+ }
+
+ public virtual void RemoveRange (int index, int count) {
+ if (readOnly) {
+ throw new NotSupportedException
+ ("Collection is read-only.");
+ }
+
+ if (fixedSize) {
+ throw new NotSupportedException
+ ("Collection is fixed size.");
+ }
+
+ if (index < 0 || index >= this.count || index + count > this.count) {
+ throw new ArgumentOutOfRangeException
+ ("index/count out of range");
+ }
+
+ shiftElements (index, - count);
+ this.count -= count;
+ }
+
+ public virtual void Reverse () {
+ Reverse (0, count);
+ }
+
+ public virtual void Reverse (int index, int count) {
+ if (readOnly) {
+ throw new NotSupportedException
+ ("Collection is read-only.");
+ }
+
+ if (index < 0 || index + count > this.count) {
+ throw new ArgumentOutOfRangeException
+ ("index/count out of range");
+ }
+
+ Array.Reverse (dataArray, index, count);
+ }
+
+ public virtual void SetRange (int index, ICollection c) {
+ }
+
+ public virtual void Sort () {
+ Sort (0, count, null);
+ }
+
+ public virtual void Sort (IComparer comparer) {
+ Sort (0, count, comparer);
+ }
+
+ public virtual void Sort (int index, int count, IComparer comparer) {
+ if (readOnly) {
+ throw new NotSupportedException
+ ("Collection is read-only.");
+ }
+
+ if (index < 0 || index + count > this.count) {
+ throw new ArgumentOutOfRangeException
+ ("index/count out of range");
+ }
+
+ Array.Sort (dataArray, index, count, comparer);
+ }
+
+ public virtual object[] ToArray() {
+ object[] outArray = new object[count];
+ Array.Copy (dataArray, outArray, count);
+ return outArray;
+ }
+
+ public virtual Array ToArray (Type type) {
+ Array outArray = Array.CreateInstance (type, count);
+ Array.Copy (dataArray, outArray, count);
+ return outArray;
+ }
+
+ public virtual void TrimToSize () {
+ // FIXME: implement this
+ }
+ }
+}
diff --git a/mcs/class/corlib/System.Collections/BitArray.cs b/mcs/class/corlib/System.Collections/BitArray.cs
new file mode 100644
index 00000000000..1851ccf69da
--- /dev/null
+++ b/mcs/class/corlib/System.Collections/BitArray.cs
@@ -0,0 +1,501 @@
+using System;
+
+namespace System.Collections
+{
+ // do we really need to specify IEnumerable since ICollection extends it?
+ public class BitArray : ICollection, IEnumerable, ICloneable
+ {
+ private Int32[] m_array;
+ private int m_length;
+ private int m_modCount = 0;
+
+ private static void clearJunk(Int32[] arr, int numbits)
+ {
+ int numjunkbits = 32 - (numbits%32);
+ UInt32 mask = (~0U >> numjunkbits);
+ arr[arr.Length - 1] &= (int)mask;
+ }
+
+ private static int bitsToInts(int bits)
+ {
+ int retval = bits/32;
+ if (bits % 32 != 0)
+ retval++;
+
+ return retval;
+ }
+
+ private static int bitsToBytes(int bits)
+ {
+ int retval = bits/8;
+ if (bits % 8 != 0)
+ retval++;
+
+ return retval;
+ }
+
+
+ private void setBit(int bitIndex, bool value)
+ {
+ int index = bitIndex/32;
+ int shift = bitIndex%32;
+
+ Int32 theBit = 1 << shift;
+
+ if(value)
+ m_array[index] |= theBit;
+ else
+ m_array[index] &= ~theBit;
+
+ m_modCount++;
+ }
+
+ private bool getBit(int bitIndex)
+ {
+ int index = bitIndex/32;
+ int shift = bitIndex%32;
+
+ Int32 theBit = m_array[index] & (1 << shift);
+
+ return (theBit == 0) ? false : true;
+ }
+
+ private byte getByte(int byteIndex)
+ {
+ int index = byteIndex/4;
+ int shift = (byteIndex%4)*8;
+
+ Int32 theByte = m_array[index] & (0xff << shift);
+
+ return (byte)((theByte >> shift)&0xff);
+ }
+
+ private void setByte(int byteIndex, byte value)
+ {
+ int index = byteIndex/4;
+ int shift = (byteIndex%4)*8;
+
+ Int32 orig = m_array[index];
+
+ // clear the byte
+ orig &= ~(0xff << shift);
+ // or in the new byte
+ orig |= value << shift;
+
+ m_array[index] = orig;
+
+ m_modCount++;
+ }
+
+ /* --- Constructors --- */
+ public BitArray(BitArray orig)
+ {
+ m_length = orig.m_length;
+
+ int numInts = bitsToInts(m_length);
+ m_array = new Int32[numInts];
+ Array.Copy(orig.m_array, m_array, numInts);
+ }
+
+ public BitArray(bool[] bits)
+ {
+ m_length = bits.Length;
+
+ int numInts = bitsToInts(m_length);
+ m_array = new Int32[numInts];
+ for (int i=0; i < bits.Length; i++)
+ setBit(i, bits[i]);
+ }
+
+ public BitArray(byte[] bytes)
+ {
+ m_length = bytes.Length * 8;
+
+ m_array = new Int32[bitsToInts(m_length)];
+ for (int i=0; i < bytes.Length; i++)
+ setByte(i, bytes[i]);
+ }
+
+ public BitArray(int capacity)
+ {
+ m_length = capacity;
+ m_array = new Int32[bitsToInts(m_length)];
+ }
+
+ public BitArray(int[] words)
+ {
+ int arrlen = words.Length;
+ m_length = arrlen*32;
+ m_array = new Int32[arrlen];
+ Array.Copy(words, m_array, arrlen);
+ }
+
+ public BitArray(int capacity, bool value) : this(capacity)
+ {
+ if (value)
+ {
+ // FIXME: Maybe you can create an array pre filled?
+ for (int i = 0; i < m_array.Length; i++)
+ m_array[i] = ~0;
+ }
+ }
+
+ private BitArray(Int32 [] array, int length)
+ {
+ m_array = array;
+ m_length = length;
+ }
+
+
+ /* --- Public properties --- */
+ public virtual int Count
+ {
+ get
+ {
+ return m_length;
+ }
+ }
+
+ public virtual bool IsReadOnly
+ {
+ get
+ {
+ return false;
+ }
+ }
+
+ public virtual bool IsSynchronized
+ {
+ get
+ {
+ return false;
+ }
+ }
+
+ public virtual bool this[int index]
+ {
+ get
+ {
+ return Get(index);
+ }
+ set
+ {
+ Set(index, value);
+ }
+
+ }
+
+ public virtual int Length
+ {
+ get
+ {
+ return m_length;
+ }
+ set
+ {
+ if (value < 0)
+ throw new ArgumentOutOfRangeException();
+
+ int newLen = value;
+ if (m_length != newLen)
+ {
+ int numints = bitsToInts(newLen);
+ Int32 [] newArr = new Int32[numints];
+ int copylen = (numints > m_array.Length ? m_array.Length : numints);
+ Array.Copy(m_array, newArr, copylen);
+
+ // clear out the junk bits at the end:
+ clearJunk(newArr, newLen);
+
+ // set the internal state
+ m_array = newArr;
+ m_length = newLen;
+ m_modCount++;
+ }
+ }
+ }
+
+ public virtual object SyncRoot
+ {
+ get
+ {
+ return this;
+ }
+ }
+
+ /* --- Public methods --- */
+ public BitArray And(BitArray operand)
+ {
+ if (operand == null)
+ throw new ArgumentNullException();
+ if (operand.m_length != m_length)
+ throw new ArgumentException();
+
+ Int32 [] newarr = new Int32[m_array.Length];
+ for (int i=0; i < m_array.Length; i++)
+ newarr[i] = m_array[i] & operand.m_array[i];
+
+ return new BitArray(newarr, m_length);
+ }
+
+ public object Clone()
+ {
+ // FIXME: according to the doc, this should be a shallow copy.
+ // But the MS implementation seems to do a deep copy.
+ return new BitArray((Int32 [])m_array.Clone(), m_length);
+ }
+
+ public void CopyTo(Array array, int index)
+ {
+ if (array == null)
+ throw new ArgumentNullException();
+ if (index < 0)
+ throw new ArgumentOutOfRangeException();
+
+ // FIXME: Throw ArgumentException if array is multidimensional
+ if (index >= array.Length)
+ throw new ArgumentException();
+
+ // in each case, check to make sure enough space in array
+
+ if (array is bool[])
+ {
+ if (index + m_length >= array.Length)
+ throw new ArgumentException();
+
+ bool [] barray = (bool []) array;
+
+ // Copy the bits into the array
+ for (int i = 0; i < m_length; i++)
+ barray[index + i] = getBit(i);
+ }
+ else if (array is byte[])
+ {
+ int numbytes = bitsToBytes(m_length);
+ if (index + numbytes >= array.Length)
+ throw new ArgumentException();
+
+ byte [] barray = (byte []) array;
+ // Copy the bytes into the array
+ for (int i = 0; i < numbytes; i++)
+ barray[index + i] = getByte(i);
+ }
+ else if (array is int[])
+ {
+ int numints = bitsToInts(m_length);
+ if (index + numints >= array.Length)
+ throw new ArgumentException();
+ Array.Copy(m_array, 0, array, index, numints);
+ }
+ else
+ {
+ throw new InvalidCastException();
+ }
+ }
+
+
+ /*
+ * All this code for nothing... Apparently, The MS BitArray doesn't
+ * override Equals!
+ *public override bool Equals(object obj)
+ {
+ // If it's not a BitArray, then it can't be equal to us.
+ if (!(obj is BitArray))
+ return false;
+
+ // If the references are equal, then clearly the instances are equal
+ if (this == obj)
+ return true;
+
+ // If its length is different, than it can't be equal.
+ BitArray b = (BitArray) obj;
+ if (m_length != b.m_length)
+ return false;
+
+
+ // Now compare the bits.
+ // This is a little tricky, because if length doesn't divide 32,
+ // then we shouldn't compare the unused bits in the last element
+ // of m_array.
+
+ // Compare all full ints. If any differ, then we are not equal.
+ int numints = m_length/32;
+ for (int i = 0; i < numints; i++)
+ {
+ if (b.m_array[i] != m_array[i])
+ return false;
+ }
+
+ // Compare the left over bits (if any)
+ int extrabits = m_length%32;
+ if (extrabits != 0)
+ {
+ // our mask is the "extrabits" least significant bits set to 1.
+ UInt32 comparemask = ~0U >> (32 - extrabits);
+
+ // numints is rounded down, so it's safe to use as an index here,
+ // as long as extrabits > 0.
+ if ((b.m_array[numints] & comparemask)
+ != (m_array[numints] & comparemask))
+ return false;
+ }
+
+ // We passed through all the above, so we are equal.
+ return true;
+
+ }
+ * End comment out of Equals()
+ */
+
+ public bool Get(int index)
+ {
+ if (index < 0 || index >= m_length)
+ throw new ArgumentOutOfRangeException();
+ return getBit(index);
+ }
+
+ public IEnumerator GetEnumerator()
+ {
+ return new BitArrayEnumerator(this);
+ }
+
+ /*
+ * Since MS doesn't appear to override Equals/GetHashCode, we don't.
+ *public override int GetHashCode()
+ {
+ // We could make this a constant time function
+ // by just picking a constant number of bits, spread out
+ // evenly across the entire array. For now, this will suffice.
+
+ int retval = m_length;
+
+ // Add in each array element, except for the leftover bits.
+ int numints = m_length/32;
+ for (int i = 0; i < numints; i++)
+ retval += (int)m_array[i];
+
+ // That's enough. Adding in the leftover bits is tiring.
+
+ return retval;
+ }
+ * End comment out of GetHashCode()
+ */
+
+ public BitArray Not()
+ {
+ Int32 [] newarr = new Int32[m_array.Length];
+ for (int i=0; i < m_array.Length; i++)
+ newarr[i] = ~m_array[i];
+
+ return new BitArray(newarr, m_length);
+ }
+
+ public BitArray Or(BitArray operand)
+ {
+ if (operand == null)
+ throw new ArgumentNullException();
+ if (operand.m_length != m_length)
+ throw new ArgumentException();
+
+ Int32 [] newarr = new Int32[m_array.Length];
+ for (int i=0; i < m_array.Length; i++)
+ newarr[i] = m_array[i] | operand.m_array[i];
+
+ return new BitArray(newarr, m_length);
+ }
+
+ public void Set(int index, bool value)
+ {
+ if (index < 0 || index >= m_length)
+ throw new ArgumentOutOfRangeException();
+ setBit(index, value);
+ }
+
+ public void SetAll(bool value)
+ {
+ if (value)
+ {
+ for (int i = 0; i < m_array.Length; i++)
+ m_array[i] = ~0;
+
+ // clear out the junk bits that we might have set
+ clearJunk(m_array, m_length);
+ }
+ else
+ Array.Clear(m_array, 0, m_array.Length);
+
+
+ m_modCount++;
+ }
+
+ public BitArray Xor(BitArray operand)
+ {
+ if (operand == null)
+ throw new ArgumentNullException();
+ if (operand.m_length != m_length)
+ throw new ArgumentException();
+
+ Int32 [] newarr = new Int32[m_array.Length];
+ for (int i=0; i < m_array.Length; i++)
+ newarr[i] = m_array[i] ^ operand.m_array[i];
+
+ return new BitArray(newarr, m_length);
+ }
+
+ ~BitArray()
+ {
+ }
+
+ class BitArrayEnumerator : IEnumerator
+ {
+ BitArray m_bitArray;
+ private bool m_current;
+ private int m_index;
+ private int m_max;
+ private int m_modCount;
+
+ public BitArrayEnumerator(BitArray ba)
+ {
+ m_index = -1;
+ m_bitArray = ba;
+ m_max = ba.m_length;
+ m_modCount = ba.m_modCount;
+ }
+
+ public object Current
+ {
+ get
+ {
+ if (m_index < 0 || m_index >= m_max)
+ throw new InvalidOperationException();
+ return m_current;
+ }
+ }
+
+ public bool MoveNext()
+ {
+ if (m_modCount != m_bitArray.m_modCount)
+ throw new InvalidOperationException();
+
+ if (m_index + 1 >= m_max)
+ return false;
+
+ m_index++;
+ m_current = m_bitArray[m_index];
+ return true;
+ }
+
+ public void Reset()
+ {
+ if (m_modCount != m_bitArray.m_modCount)
+ throw new InvalidOperationException();
+ m_index = -1;
+ }
+ }
+ }
+}
+
+
+
+
+
diff --git a/mcs/class/corlib/System.Collections/CaseInsensitiveComparer.cs b/mcs/class/corlib/System.Collections/CaseInsensitiveComparer.cs
new file mode 100644
index 00000000000..4a572780a02
--- /dev/null
+++ b/mcs/class/corlib/System.Collections/CaseInsensitiveComparer.cs
@@ -0,0 +1,82 @@
+//
+// System.Collections.CaseInsensitiveComparer
+//
+// Author:
+// Sergey Chaban (serge@wildwestsoftware.com)
+//
+
+
+
+using System;
+using System.Collections;
+
+
+
+namespace System.Collections {
+
+ public class CaseInsensitiveComparer : IComparer {
+
+ private static CaseInsensitiveComparer singleton;
+
+
+ // Class constructor
+
+ static CaseInsensitiveComparer ()
+ {
+ singleton=new CaseInsensitiveComparer ();
+ }
+
+
+ // Public instance constructor
+
+ public CaseInsensitiveComparer ()
+ {
+ }
+
+
+
+ //
+ // Public static properties
+ //
+
+ public static CaseInsensitiveComparer Default {
+ get {
+ return singleton;
+ }
+ }
+
+
+ //
+ // Instance methods
+ //
+
+ public override string ToString ()
+ {
+ return "mono::System.Collections.CaseInsensitiveComparer";
+ }
+
+
+ //
+ // IComparer
+ //
+
+ public int Compare (object a, object b)
+ {
+ string str1 = a as string;
+ string str2 = b as string;
+
+
+ int res = 0;
+
+ if (str1 != null && str2 != null) {
+ res = String.Compare (str1, str2, true);
+ }
+
+ return res;
+ }
+
+
+
+ } // CaseInsensitiveComparer
+}
+
diff --git a/mcs/class/corlib/System.Collections/CaseInsensitiveHashCodeProvider.cs b/mcs/class/corlib/System.Collections/CaseInsensitiveHashCodeProvider.cs
new file mode 100644
index 00000000000..dcc15ef04a6
--- /dev/null
+++ b/mcs/class/corlib/System.Collections/CaseInsensitiveHashCodeProvider.cs
@@ -0,0 +1,96 @@
+//
+// System.Collections.CaseInsensitiveHashCodeProvider
+//
+// Author:
+// Sergey Chaban (serge@wildwestsoftware.com)
+//
+
+
+
+using System;
+using System.Collections;
+
+
+
+namespace System.Collections {
+
+ public class CaseInsensitiveHashCodeProvider : IHashCodeProvider {
+
+ private static CaseInsensitiveHashCodeProvider singleton;
+
+
+ // Class constructor
+
+ static CaseInsensitiveHashCodeProvider ()
+ {
+ singleton=new CaseInsensitiveHashCodeProvider ();
+ }
+
+
+
+ // Public instance constructor
+
+ public CaseInsensitiveHashCodeProvider ()
+ {
+ }
+
+
+
+ //
+ // Public static properties
+ //
+
+ public static CaseInsensitiveHashCodeProvider Default {
+ get {
+ return singleton;
+ }
+ }
+
+
+ //
+ // Instance methods
+ //
+
+ public override string ToString ()
+ {
+ return "mono::System.Collections.CaseInsensitiveHashCodeProvider";
+ }
+
+
+ //
+ // IHashCodeProvider
+ //
+
+ public virtual int GetHashCode (object obj)
+ {
+ if (obj == null) {
+ throw new ArgumentNullException ("obj is null");
+ }
+
+ string str = obj as string;
+
+ if (str == null) {
+ // FIXME:
+ return 0;
+ }
+
+ int h = 0;
+ char c;
+
+ if (str.Length > 0) {
+ for (int i = 0;i<str.Length;i++) {
+ c = str [i];
+
+ if (Char.IsLetter (c))
+ c = Char.ToLower (c);
+
+ h = h * 31 + c;
+ }
+ }
+
+ return h;
+ }
+
+ } // CaseInsensitiveHashCodeProvider
+}
+
diff --git a/mcs/class/corlib/System.Collections/ChangeLog b/mcs/class/corlib/System.Collections/ChangeLog
new file mode 100644
index 00000000000..b3faf65e7fb
--- /dev/null
+++ b/mcs/class/corlib/System.Collections/ChangeLog
@@ -0,0 +1,93 @@
+2001-08-10 Dietmar Maurer <dietmar@ximian.com>
+
+ * common.src: removed duplicate entries
+
+2001-08-08 Nick Drochak <ndrochak@gol.com>
+
+ * ReadOnlyCollectionBase.cs: Initialized private member.
+ * CollectionBase.cs: Initialized private member.
+ * common.src : Added ReadOnlyCollectionBase.cs and CollectionBase.cs
+ * /mcs/class/makefile: Used $(SYSTEMROOT) instead of hard coded //c/winnt
+ * /mcs/makefile: Used $(SYSTEMROOT) instead of hard coded //c/winnt
+
+2001-08-08 Nick Drochak <nick@jobdragon.com>
+
+ * CollectionBase.cs: Add
+ * ReadOnlyCollectionBase.cs: Add
+ * CollectionBaseTest.cs: Add
+ * ReadOnlyCollectionBaseTest.cs: Add
+
+2001-07-31 Garrett Rooney <rooneg@electricjellyfish.net>
+
+ * StackTest.cs: Add Test case for System.Collections.Stack.
+ Contributed by Chris Hynes <chrish@assistedsolutions.com>
+
+2001-07-30 Garrett Rooney <rooneg@electricjellyfish.net>
+
+ * Stack.cs: Clone() doesn't need to check if it's synchronized, since
+ we override it in SyncStack anyway...
+
+ * Stack.cs: Pop() now shrinks the array if we drop below 1/4 full, to
+ avoid using massive amounts of memory that are not necessary. We only
+ drop to half the current size, which I hope will avoid the 'ping-pong'
+ effect.
+
+ * Stack.cs: SyncStack.IsReadOnly should return stack.IsReadOnly
+ instead of just returning false, since we may have a ReadOnly wrapper
+ in the future (although i can't imagine why). Thanks to David
+ Menestrina <dmenest@yahoo.com> for pointing this out.
+
+2001-07-23 Sergey Chaban <serge@wildwestsoftware.com>
+
+ * Hashtable.cs: Fixed bug in Clear(), the Count wasn't zeroed.
+ From now, Clear() increases modification count.
+ Fixed HCP bug in GetHash(object) - hcp.GetHashCode() was used
+ instead of hcp.GetHashCode(key). This was resulted in the
+ insanely long lookup times when HashCodeProvider was used to
+ construct Hashtable. Added thread-safe wrapper.
+
+2001-07-16 David Menestrina <dmenest@yahoo.com>
+
+ * BitArray.cs: Add
+ * BitArrayTest.cs: Add
+
+2001-07-18 Miguel de Icaza <miguel@ximian.com>
+
+ * IDictionary.cs (Collections): IDictionary implements ICollection
+ as well. Thanks Sergey!
+
+2001-07-18 Garrett Rooney <rooneg@electricjellyfish.net>
+
+ * Stack.cs Removed unnecessary locking from many methods of
+ SyncStack, removed SyncEnumerator because it was unnecessary,
+ added a modCount member to Stack and Stack.Enumerator, to
+ ensure that the Stack has not been modified out form under the
+ Enumerator, and changed the Enumerator to use a reference to the
+ stack rather than copying over the contents array.
+
+2001-07-17 David Menestrina <dmenest@yahoo.com>
+
+ * Added implementation of BitArray.
+
+2001-07-17 Miguel de Icaza <miguel@ximian.com>
+
+ * Hashtable.cs: Removed call to d.Count in the Hashtable
+ constructor that takes an IDictionary as IDictionary does not
+ provide a Count field.
+
+2001-07-15 Sean MacIsaac <macisaac@ximian.com>
+
+ * IDictionary.cs: Clear was clear.
+
+2001-07-13 Miguel de Icaza <miguel@ximian.com>
+
+ * All files: Renamespace things to System.
+
+2001-07-05 Vladimir Vukicevic <vladimir@ximian.com>
+
+ * ArrayList.cs: initial checkin and implementation
+
+ * ICollection.cs, IComprarer.cs, IDictionary.cs,
+ IDictionaryEnumerator.cs, IEnumerable.cs, IHashCodeProvider.cs,
+ IList.cs: initial checkin
+
diff --git a/mcs/class/corlib/System.Collections/CollectionBase.cs b/mcs/class/corlib/System.Collections/CollectionBase.cs
new file mode 100644
index 00000000000..63eb71dd867
--- /dev/null
+++ b/mcs/class/corlib/System.Collections/CollectionBase.cs
@@ -0,0 +1,131 @@
+//
+// System.Collections.CollectionBase.cs
+//
+// Author:
+// Nick Drochak II (ndrochak@gol.com)
+//
+// (C) 2001 Nick Drochak II
+//
+
+using System;
+
+namespace System.Collections {
+
+ public abstract class CollectionBase : IList, ICollection, IEnumerable {
+
+ // private instance properties
+ private System.Collections.ArrayList myList;
+
+ // public instance properties
+ public virtual int Count { get { return InnerList.Count; } }
+
+ // Public Instance Methods
+ public virtual System.Collections.IEnumerator GetEnumerator() { return InnerList.GetEnumerator(); }
+ public virtual void Clear() {
+ OnClear();
+ InnerList.Clear();
+ OnClearComplete();
+ }
+ public virtual void RemoveAt (int index) {
+ InnerList.RemoveAt(index);
+ }
+
+ // Protected Instance Constructors
+ protected CollectionBase() {
+ this.myList = new System.Collections.ArrayList();
+ }
+
+ // Protected Instance Properties
+ protected System.Collections.ArrayList InnerList {get { return this.myList; } }
+ protected System.Collections.IList List {get { return this; } }
+
+ // Protected Instance Methods
+ protected virtual void OnClear() { }
+ protected virtual void OnClearComplete() { }
+
+ protected virtual void OnInsert(int index, object value) { }
+ protected virtual void OnInsertComplete(int index, object value) { }
+
+ protected virtual void OnRemove(int index, object value) { }
+ protected virtual void OnRemoveComplete(int index, object value) { }
+
+ protected virtual void OnSet(int index, object oldValue, object newValue) { }
+ protected virtual void OnSetComplete(int index, object oldValue, object newValue) { }
+
+ protected virtual void OnValidate(object value) {
+ if (null == value) {
+ throw new System.ArgumentNullException("CollectionBase.OnValidate: Invalid parameter value passed to method: null");
+ }
+ }
+
+ // ICollection methods
+ void ICollection.CopyTo(Array array, int index) {
+ lock (InnerList) { InnerList.CopyTo(array, index); }
+ }
+ object ICollection.SyncRoot {
+ get { return InnerList.SyncRoot; }
+ }
+ bool ICollection.IsSynchronized {
+ get { return InnerList.IsSynchronized; }
+ }
+
+ // IList methods
+ int IList.Add (object value) {
+ int newPosition;
+ OnValidate(value);
+ newPosition = InnerList.Count;
+ OnInsert(newPosition, value);
+ InnerList.Add(value);
+ OnInsertComplete(newPosition, value);
+ return newPosition;
+ }
+
+ bool IList.Contains (object value) {
+ return InnerList.Contains(value);
+ }
+
+ int IList.IndexOf (object value) {
+ return InnerList.IndexOf(value);
+ }
+
+ void IList.Insert (int index, object value) {
+ OnValidate(value);
+ OnInsert(index, value);
+ InnerList.Insert(index, value);
+ OnInsertComplete(index, value);
+ }
+
+ void IList.Remove (object value) {
+ int removeIndex;
+ OnValidate(value);
+ removeIndex = InnerList.IndexOf(value);
+ OnRemove(removeIndex, value);
+ InnerList.Remove(value);
+ OnRemoveComplete(removeIndex, value);
+ }
+
+ // IList properties
+ bool IList.IsFixedSize {
+ get { return InnerList.IsFixedSize; }
+ }
+
+ bool IList.IsReadOnly {
+ get { return InnerList.IsReadOnly; }
+ }
+
+ object IList.this[int index] {
+ get { return InnerList[index]; }
+ set {
+ object oldValue;
+ // make sure we have been given a valid value
+ OnValidate(value);
+ // save a reference to the object that is in the list now
+ oldValue = InnerList[index];
+
+ OnSet(index, oldValue, value);
+ InnerList[index] = value;
+ OnSetComplete(index, oldValue, value);
+ }
+ }
+ }
+}
diff --git a/mcs/class/corlib/System.Collections/Comparer.cs b/mcs/class/corlib/System.Collections/Comparer.cs
new file mode 100644
index 00000000000..ba8cf94cd5a
--- /dev/null
+++ b/mcs/class/corlib/System.Collections/Comparer.cs
@@ -0,0 +1,65 @@
+//
+// System.Collections.Comparer
+//
+// Author:
+// Sergey Chaban (serge@wildwestsoftware.com)
+//
+
+
+
+using System;
+using System.Collections;
+
+
+
+namespace System.Collections {
+
+ public sealed class Comparer : IComparer {
+
+ public static readonly Comparer Default;
+
+
+ // Class constructor
+
+ static Comparer ()
+ {
+ Default=new Comparer ();
+ }
+
+
+
+ // Public instance constructor
+
+ private Comparer ()
+ {
+ }
+
+
+
+ // IComparer
+
+ public int Compare (object a, object b)
+ {
+ int res=0;
+
+ if (a is IComparable) {
+ res = (a as IComparable).CompareTo (b);
+ } else if (b is IComparable) {
+ res = (b as IComparable).CompareTo (a);
+ } else {
+ throw new ArgumentException ("Neither a nor b IComparable");
+ }
+
+
+ return res;
+ }
+
+
+
+ public override string ToString ()
+ {
+ return "mono::System.Collections.Comparer";
+ }
+
+ }
+}
diff --git a/mcs/class/corlib/System.Collections/Hashtable.cs b/mcs/class/corlib/System.Collections/Hashtable.cs
new file mode 100644
index 00000000000..b964d755075
--- /dev/null
+++ b/mcs/class/corlib/System.Collections/Hashtable.cs
@@ -0,0 +1,985 @@
+//
+// System.Collections.Hashtable
+//
+// Author:
+// Sergey Chaban (serge@wildwestsoftware.com)
+//
+
+
+
+using System;
+using System.Collections;
+
+
+// TODO: 1. Interfaces to implement: ISerializable and IDeserializationCallback;
+// 2. Meaningfull error messages for all exceptions.
+// Probably we should use ResourceSet to translate
+// error codes to messages.
+
+
+namespace System.Collections {
+
+ public class Hashtable : IDictionary, ICollection,
+ IEnumerable, ICloneable
+ {
+
+ internal struct Slot {
+ internal Object key;
+
+ internal Object value;
+
+ // Hashcode. Chains are also marked through this.
+ internal int hashMix;
+ }
+
+ //
+ // Private data
+ //
+
+ private readonly static int CHAIN_MARKER = ~Int32.MaxValue;
+ private readonly static int ALLOC_GRAIN = 0x2F;
+
+ // Used as indicator for the removed parts of a chain.
+ private readonly static Object REMOVED_MARKER = new Object ();
+
+
+ private int inUse;
+ private int modificationCount;
+ private float loadFactor;
+ private Slot [] table;
+ private int threshold;
+
+ private IHashCodeProvider hcpRef;
+ private IComparer comparerRef;
+
+ public static int [] primeTbl = {};
+
+
+ // Class constructor
+
+ static Hashtable () {
+ // NOTE: Precalculate primes table.
+ // This precalculated table of primes is intended
+ // to speed-up allocations/resize for relatively
+ // small tables.
+ // I'm not sure whether it's a good idea or not.
+ // Also I am in doubt as for the quality of this
+ // particular implementation, probably the increment
+ // shouldn't be linear? Consider this as a hack
+ // or as a placeholder for future improvements.
+ int size = 0x2000/ALLOC_GRAIN;
+ primeTbl = new int [size];
+ for (int x = 53, i = 0;i<size;x+= ALLOC_GRAIN, i++) {
+ primeTbl [i] = CalcPrime (x);
+ }
+ }
+
+
+ //
+ // Constructors
+ //
+
+ public Hashtable () : this (0, 1.0f) {}
+
+
+ public Hashtable (int capacity, float loadFactor, IHashCodeProvider hcp, IComparer comparer) {
+ if (capacity<0)
+ throw new ArgumentOutOfRangeException ("negative capacity");
+
+ if (loadFactor<0.1 || loadFactor>1)
+ throw new ArgumentOutOfRangeException ("load factor");
+
+ if (capacity == 0) ++capacity;
+ this.loadFactor = 0.75f*loadFactor;
+ int size = (int) (capacity/this.loadFactor);
+ size = ToPrime (size);
+ this.SetTable (new Slot [size]);
+
+ this.hcp = hcp;
+ this.comparer = comparer;
+
+ this.inUse = 0;
+ this.modificationCount = 0;
+
+ }
+
+ public Hashtable (int capacity, float loadFactor) :
+ this (capacity, loadFactor, null, null)
+ {
+ }
+
+ public Hashtable (int capacity) : this (capacity, 1.0f)
+ {
+ }
+
+ public Hashtable (int capacity,
+ IHashCodeProvider hcp,
+ IComparer comparer)
+ : this (capacity, 1.0f, hcp, comparer)
+ {
+ }
+
+
+ public Hashtable (IDictionary d, float loadFactor,
+ IHashCodeProvider hcp, IComparer comparer)
+ : this (d!=null ? d.Count : 0,
+ loadFactor, hcp, comparer)
+ {
+
+ if (d == null)
+ throw new ArgumentNullException ("dictionary");
+
+ IDictionaryEnumerator it = d.GetEnumerator ();
+ while (it.MoveNext ()) {
+ Add (it.Key, it.Value);
+ }
+
+ }
+
+ public Hashtable (IDictionary d, float loadFactor)
+ : this (d, loadFactor, null, null)
+ {
+ }
+
+
+ public Hashtable (IDictionary d) : this (d, 1.0f)
+ {
+ }
+
+ public Hashtable (IDictionary d, IHashCodeProvider hcp, IComparer comparer)
+ : this (d, 1.0f, hcp, comparer)
+ {
+ }
+
+ public Hashtable (IHashCodeProvider hcp, IComparer comparer)
+ : this (1, 1.0f, hcp, comparer)
+ {
+ }
+
+ //
+ // Properties
+ //
+
+ protected IComparer comparer {
+ set {
+ comparerRef = value;
+ }
+ get {
+ return comparerRef;
+ }
+ }
+
+ protected IHashCodeProvider hcp {
+ set {
+ hcpRef = value;
+ }
+ get {
+ return hcpRef;
+ }
+ }
+
+ // ICollection
+
+ public virtual int Count {
+ get {
+ return inUse;
+ }
+ }
+
+ public virtual bool IsSynchronized {
+ get {
+ return false;
+ }
+ }
+
+ public virtual Object SyncRoot {
+ get {
+ return this;
+ }
+ }
+
+
+
+ // IDictionary
+
+ public virtual bool IsFixedSize {
+ get {
+ return false;
+ }
+ }
+
+
+ public virtual bool IsReadOnly {
+ get {
+ return false;
+ }
+ }
+
+ public virtual ICollection Keys {
+ get {
+ return new HashKeys (this);
+ }
+ }
+
+ public virtual ICollection Values {
+ get {
+ return new HashValues (this);
+ }
+ }
+
+
+
+ public virtual Object this [Object key] {
+ get {
+ return GetImpl (key);
+ }
+ set {
+ PutImpl (key, value, true);
+ }
+ }
+
+
+
+
+ //
+ // Interface methods
+ //
+
+
+ // IEnumerable
+
+ IEnumerator IEnumerable.GetEnumerator ()
+ {
+ return new Enumerator (this, EnumeratorMode.KEY_MODE);
+ }
+
+
+ // ICollection
+ public virtual void CopyTo (Array array, int arrayIndex)
+ {
+ IDictionaryEnumerator it = GetEnumerator ();
+ int i = arrayIndex;
+
+ while (it.MoveNext ()) {
+ array.SetValue (it.Entry, i++);
+ }
+ }
+
+
+ // IDictionary
+
+ public virtual void Add (Object key, Object value)
+ {
+ PutImpl (key, value, false);
+ }
+
+ public virtual void Clear ()
+ {
+ for (int i = 0;i<table.Length;i++) {
+ table [i].key = null;
+ table [i].value = null;
+ table [i].hashMix = 0;
+ }
+
+ inUse = 0;
+ modificationCount++;
+ }
+
+ public virtual bool Contains (Object key)
+ {
+ return (Find (key) >= 0);
+ }
+
+ public virtual IDictionaryEnumerator GetEnumerator ()
+ {
+ return new Enumerator (this, EnumeratorMode.KEY_MODE);
+ }
+
+ public virtual void Remove (Object key)
+ {
+ int i = Find (key);
+ Slot [] table = this.table;
+ if (i >= 0) {
+ int h = table [i].hashMix;
+ h &= CHAIN_MARKER;
+ table [i].hashMix = h;
+ table [i].key = (h != 0)
+ ? REMOVED_MARKER
+ : null;
+ table [i].value = null;
+ --inUse;
+ ++modificationCount;
+ }
+ }
+
+
+
+
+ public virtual bool ContainsKey (object key)
+ {
+ return Contains (key);
+ }
+
+ public virtual bool ContainsValue (object value)
+ {
+ int size = this.table.Length;
+ Slot [] table = this.table;
+
+ for (int i = 0; i < size; i++) {
+ Slot entry = table [i];
+ if (entry.key != null && entry.key!= REMOVED_MARKER
+ && value.Equals (entry.value)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+
+ // ICloneable
+
+ public virtual object Clone ()
+ {
+ Hashtable ht = new Hashtable (Count, hcp, comparer);
+ ht.modificationCount = this.modificationCount;
+ ht.inUse = this.inUse;
+ ht.AdjustThreshold ();
+
+ // FIXME: maybe it's faster to simply
+ // copy the back-end array?
+
+ IDictionaryEnumerator it = GetEnumerator ();
+ while (it.MoveNext ()) {
+ ht [it.Key] = it.Value;
+ }
+
+ return ht;
+ }
+
+
+
+ // TODO: public virtual void GetObjectData (SerializationInfo info, StreamingContext context) {}
+ // TODO: public virtual void OnDeserialization (object sender);
+
+
+ public override string ToString ()
+ {
+ // FIXME: What's it supposed to do?
+ // Maybe print out some internals here? Anyway.
+ return "mono::System.Collections.Hashtable";
+ }
+
+
+ /// <summary>
+ /// Returns a synchronized (thread-safe)
+ /// wrapper for the Hashtable.
+ /// </summary>
+ public static Hashtable Synchronized (Hashtable table)
+ {
+ return new SynchedHashtable (table);
+ }
+
+
+
+ //
+ // Protected instance methods
+ //
+
+ /// <summary>Returns the hash code for the specified key.</summary>
+ protected virtual int GetHash (Object key)
+ {
+ IHashCodeProvider hcp = this.hcp;
+ return (hcp!= null)
+ ? hcp.GetHashCode (key)
+ : key.GetHashCode ();
+ }
+
+ /// <summary>
+ /// Compares a specific Object with a specific key
+ /// in the Hashtable.
+ /// </summary>
+ protected virtual bool KeyEquals (Object item, Object key)
+ {
+ IComparer c = this.comparer;
+ if (c!= null)
+ return (c.Compare (item, key) == 0);
+ else
+ return item.Equals (key);
+ }
+
+
+
+ //
+ // Private instance methods
+ //
+
+ private void AdjustThreshold ()
+ {
+ int size = table.Length;
+
+ threshold = (int) (size*loadFactor);
+ if (this.threshold >= size)
+ threshold = size-1;
+ }
+
+ private void SetTable (Slot [] table)
+ {
+ if (table == null)
+ throw new ArgumentNullException ("table");
+
+ this.table = table;
+ AdjustThreshold ();
+ }
+
+ private Object GetImpl (Object key)
+ {
+ int i = Find (key);
+
+ if (i >= 0)
+ return table [i].value;
+ else
+ return null;
+ }
+
+
+ private int Find (Object key)
+ {
+ if (key == null)
+ throw new ArgumentNullException ("null key");
+
+ uint size = (uint) this.table.Length;
+ int h = this.GetHash (key) & Int32.MaxValue;
+ uint spot = (uint)h;
+ uint step = (uint) ((h >> 5)+1) % (size-1)+1;
+ Slot[] table = this.table;
+
+ for (int i = 0; i < size;i++) {
+ int indx = (int) (spot % size);
+ Slot entry = table [indx];
+ Object k = entry.key;
+ if (k == null)
+ return -1;
+ if ((entry.hashMix & Int32.MaxValue) == h
+ && this.KeyEquals (key, k)) {
+ return indx;
+ }
+
+ if ((entry.hashMix & CHAIN_MARKER) == 0)
+ return -1;
+
+ spot+= step;
+ }
+ return -1;
+ }
+
+
+ private void Rehash ()
+ {
+ int oldSize = this.table.Length;
+
+ // From the SDK docs:
+ // Hashtable is automatically increased
+ // to the smallest prime number that is larger
+ // than twice the current number of Hashtable buckets
+ uint newSize = (uint)ToPrime ((oldSize<<1)|1);
+
+
+ Slot [] newTable = new Slot [newSize];
+ Slot [] table = this.table;
+
+ for (int i = 0;i<oldSize;i++) {
+ Slot s = table [i];
+ if (s.key!= null) {
+ int h = s.hashMix & Int32.MaxValue;
+ uint spot = (uint)h;
+ uint step = ((uint) (h>>5)+1)% (newSize-1)+1;
+ for (uint j = spot%newSize;;spot+= step, j = spot%newSize) {
+ // No check for REMOVED_MARKER here,
+ // because the table is just allocated.
+ if (newTable [j].key == null) {
+ newTable [j].key = s.key;
+ newTable [j].value = s.value;
+ newTable [j].hashMix |= h;
+ break;
+ } else {
+ newTable [j].hashMix |= CHAIN_MARKER;
+ }
+ }
+ }
+ }
+
+ ++this.modificationCount;
+
+ this.SetTable (newTable);
+ }
+
+
+ private void PutImpl (Object key, Object value, bool overwrite)
+ {
+ if (key == null)
+ throw new ArgumentNullException ("null key");
+
+ uint size = (uint)this.table.Length;
+ if (this.inUse >= this.threshold) {
+ this.Rehash ();
+ size = (uint)this.table.Length;
+ }
+
+ int h = this.GetHash (key) & Int32.MaxValue;
+ uint spot = (uint)h;
+ uint step = (uint) ((spot>>5)+1)% (size-1)+1;
+ Slot [] table = this.table;
+ Slot entry;
+
+ int freeIndx = -1;
+ for (int i = 0; i < size; i++) {
+ int indx = (int) (spot % size);
+ entry = table [indx];
+
+ if (freeIndx == -1
+ && entry.key == REMOVED_MARKER
+ && (entry.hashMix & CHAIN_MARKER)!= 0)
+ freeIndx = indx;
+
+ if (entry.key == null ||
+ (entry.key == REMOVED_MARKER
+ && (entry.hashMix & CHAIN_MARKER)!= 0)) {
+
+ if (freeIndx == -1)
+ freeIndx = indx;
+ break;
+ }
+
+ if ((entry.hashMix & Int32.MaxValue) == h && KeyEquals (key, entry.key)) {
+ if (overwrite) {
+ table [indx].value = value;
+ ++this.modificationCount;
+ } else {
+ // Handle Add ():
+ // An entry with the same key already exists in the Hashtable.
+ throw new ArgumentException ("Key duplication");
+ }
+ return;
+ }
+
+ if (freeIndx == -1) {
+ table [indx].hashMix |= CHAIN_MARKER;
+ }
+
+ spot+= step;
+
+ }
+
+ if (freeIndx!= -1) {
+ table [freeIndx].key = key;
+ table [freeIndx].value = value;
+ table [freeIndx].hashMix |= h;
+
+ ++this.inUse;
+ ++this.modificationCount;
+ }
+
+ }
+
+ private void CopyToArray (Array arr, int i,
+ EnumeratorMode mode)
+ {
+ IEnumerator it = new Enumerator (this, mode);
+
+ while (it.MoveNext ()) {
+ arr.SetValue (it.Current, i++);
+ }
+ }
+
+
+
+ //
+ // Private static methods
+ //
+ private static bool TestPrime (int x)
+ {
+ if ((x & 1) != 0) {
+ for (int n = 3; n< (int)Math.Sqrt (x); n += 2) {
+ if ((x % n) == 0)
+ return false;
+ }
+ return true;
+ }
+ // There is only one even prime - 2.
+ return (x == 2);
+ }
+
+ private static int CalcPrime (int x)
+ {
+ for (int i = (x & (~1))-1; i< Int32.MaxValue; i += 2) {
+ if (TestPrime (i)) return i;
+ }
+ return x;
+ }
+
+ private static int ToPrime (int x)
+ {
+ for (int i = x/ALLOC_GRAIN; i < primeTbl.Length; i++) {
+ if (x <= primeTbl [i])
+ return primeTbl [i];
+ }
+ return CalcPrime (x);
+ }
+
+
+
+
+ //
+ // Inner classes
+ //
+
+ public enum EnumeratorMode : int {KEY_MODE = 0, VALUE_MODE};
+
+ protected sealed class Enumerator : IDictionaryEnumerator, IEnumerator {
+
+ private Hashtable host;
+ private int stamp;
+ private int pos;
+ private int size;
+ private EnumeratorMode mode;
+
+ private Object currentKey;
+ private Object currentValue;
+
+ private readonly static string xstr = "Hashtable.Enumerator: snapshot out of sync.";
+
+ public Enumerator (Hashtable host, EnumeratorMode mode) {
+ this.host = host;
+ stamp = host.modificationCount;
+ size = host.table.Length;
+ this.mode = mode;
+ Reset ();
+ }
+
+ public Enumerator (Hashtable host)
+ : this (host, EnumeratorMode.KEY_MODE) {}
+
+
+ private void FailFast ()
+ {
+ if (host.modificationCount!= stamp) {
+ throw new InvalidOperationException (xstr);
+ }
+ }
+
+ public void Reset ()
+ {
+ FailFast ();
+
+ pos = -1;
+ currentKey = null;
+ currentValue = null;
+ }
+
+ public bool MoveNext ()
+ {
+ FailFast ();
+
+ if (pos < size) {
+ while (++pos < size) {
+ Slot entry = host.table [pos];
+
+ if (entry.key != null && entry.key != REMOVED_MARKER) {
+ currentKey = entry.key;
+ currentValue = entry.value;
+ return true;
+ }
+ }
+ }
+
+ currentKey = null;
+ currentValue = null;
+ return false;
+ }
+
+ public DictionaryEntry Entry
+ {
+ get {
+ FailFast ();
+ return new DictionaryEntry (currentKey, currentValue);
+ }
+ }
+
+ public Object Key {
+ get {
+ FailFast ();
+ return currentKey;
+ }
+ }
+
+ public Object Value {
+ get {
+ FailFast ();
+ return currentValue;
+ }
+ }
+
+ public Object Current {
+ get {
+ FailFast ();
+ return (mode == EnumeratorMode.KEY_MODE)
+ ? currentKey
+ : currentValue;
+ }
+ }
+ }
+
+
+
+ protected class HashKeys : ICollection, IEnumerable {
+
+ private Hashtable host;
+ private int count;
+
+ public HashKeys (Hashtable host) {
+ if (host == null)
+ throw new ArgumentNullException ();
+
+ this.host = host;
+ this.count = host.Count;
+ }
+
+ // ICollection
+
+ public virtual int Count {
+ get {
+ return count;
+ }
+ }
+
+ public virtual bool IsSynchronized {
+ get {
+ return host.IsSynchronized;
+ }
+ }
+
+ public virtual Object SyncRoot {
+ get {return host.SyncRoot;}
+ }
+
+ public virtual void CopyTo (Array array, int arrayIndex)
+ {
+ host.CopyToArray (array, arrayIndex, EnumeratorMode.KEY_MODE);
+ }
+
+ // IEnumerable
+
+ public virtual IEnumerator GetEnumerator ()
+ {
+ return new Hashtable.Enumerator (host, EnumeratorMode.KEY_MODE);
+ }
+ }
+
+
+ protected class HashValues : ICollection, IEnumerable {
+
+ private Hashtable host;
+ private int count;
+
+ public HashValues (Hashtable host) {
+ if (host == null)
+ throw new ArgumentNullException ();
+
+ this.host = host;
+ this.count = host.Count;
+ }
+
+ // ICollection
+
+ public virtual int Count {
+ get {
+ return count;
+ }
+ }
+
+ public virtual bool IsSynchronized {
+ get {
+ return host.IsSynchronized;
+ }
+ }
+
+ public virtual Object SyncRoot {
+ get {
+ return host.SyncRoot;
+ }
+ }
+
+ public virtual void CopyTo (Array array, int arrayIndex)
+ {
+ host.CopyToArray (array, arrayIndex, EnumeratorMode.VALUE_MODE);
+ }
+
+ // IEnumerable
+
+ public virtual IEnumerator GetEnumerator ()
+ {
+ return new Hashtable.Enumerator (host, EnumeratorMode.VALUE_MODE);
+ }
+ }
+
+
+
+ protected class SynchedHashtable : Hashtable, IEnumerable {
+
+ private Hashtable host;
+
+ public SynchedHashtable (Hashtable host) {
+ if (host == null)
+ throw new ArgumentNullException ();
+
+ this.host = host;
+ }
+
+ // ICollection
+
+ public override int Count {
+ get {
+ return host.Count;
+ }
+ }
+
+ public override bool IsSynchronized {
+ get {
+ return true;
+ }
+ }
+
+ public override Object SyncRoot {
+ get {
+ return host.SyncRoot;
+ }
+ }
+
+
+
+ // IDictionary
+
+ public override bool IsFixedSize {
+ get {
+ return host.IsFixedSize;
+ }
+ }
+
+
+ public override bool IsReadOnly {
+ get {
+ return host.IsReadOnly;
+ }
+ }
+
+ public override ICollection Keys {
+ get {
+ ICollection keys = null;
+ lock (host.SyncRoot) {
+ keys = host.Keys;
+ }
+ return keys;
+ }
+ }
+
+ public override ICollection Values {
+ get {
+ ICollection vals = null;
+ lock (host.SyncRoot) {
+ vals = host.Values;
+ }
+ return vals;
+ }
+ }
+
+
+
+ public override Object this [Object key] {
+ get {
+ return host.GetImpl (key);
+ }
+ set {
+ lock (host.SyncRoot) {
+ host.PutImpl (key, value, true);
+ }
+ }
+ }
+
+ // IEnumerable
+
+ IEnumerator IEnumerable.GetEnumerator ()
+ {
+ return new Enumerator (host, EnumeratorMode.KEY_MODE);
+ }
+
+
+
+
+ // ICollection
+
+ public override void CopyTo (Array array, int arrayIndex)
+ {
+ host.CopyTo (array, arrayIndex);
+ }
+
+
+ // IDictionary
+
+ public override void Add (Object key, Object value)
+ {
+ lock (host.SyncRoot) {
+ host.PutImpl (key, value, false);
+ }
+ }
+
+ public override void Clear ()
+ {
+ lock (host.SyncRoot) {
+ host.Clear ();
+ }
+ }
+
+ public override bool Contains (Object key)
+ {
+ return (host.Find (key) >= 0);
+ }
+
+ public override IDictionaryEnumerator GetEnumerator ()
+ {
+ return new Enumerator (host, EnumeratorMode.KEY_MODE);
+ }
+
+ public override void Remove (Object key)
+ {
+ lock (host.SyncRoot) {
+ host.Remove (key);
+ }
+ }
+
+
+
+ public override bool ContainsKey (object key)
+ {
+ return host.Contains (key);
+ }
+
+ public override bool ContainsValue (object value)
+ {
+ return host.ContainsValue (value);
+ }
+
+
+ // ICloneable
+
+ public override object Clone ()
+ {
+ return (host.Clone () as Hashtable);
+ }
+
+ } // SynchedHashtable
+
+
+ } // Hashtable
+
+}
+
diff --git a/mcs/class/corlib/System.Collections/HashtableTest.cs b/mcs/class/corlib/System.Collections/HashtableTest.cs
new file mode 100644
index 00000000000..ae962f50e65
--- /dev/null
+++ b/mcs/class/corlib/System.Collections/HashtableTest.cs
@@ -0,0 +1,156 @@
+// TODO: add tests for Comparer and HashCodeProvider
+
+
+// NOTE: add MCS prefix to Hashtable.cs to use this test.
+
+
+using System;
+using MCS.System.Collections;
+using System.Collections;
+
+using NUnit.Framework;
+
+
+
+namespace Testsuite.System.Collections {
+
+
+ /// <summary>Hashtable test.</summary>
+ public class HashtableTest {
+ public static ITest Suite {
+ get {
+ TestSuite suite= new TestSuite("All Hashtable Tests");
+ suite.AddTest(BasicOperationsTest.Suite);
+ return suite;
+ }
+ }
+ }
+
+
+
+
+ public class BasicOperationsTest : TestCase {
+
+ protected MCS.System.Collections.Hashtable ht;
+ private static Random rnd;
+
+ public BasicOperationsTest(String name) : base(name) {}
+
+ protected override void SetUp() {
+ ht=new MCS.System.Collections.Hashtable();
+ rnd=new Random();
+ }
+
+ public static ITest Suite {
+ get {
+ return new TestSuite(typeof(BasicOperationsTest));
+ }
+ }
+
+
+
+ private void SetDefaultData() {
+ ht.Clear();
+ ht.Add("k1","another");
+ ht.Add("k2","yet");
+ ht.Add("k3","hashtable");
+ }
+
+
+ public void TestAddRemoveClear() {
+ ht.Clear();
+ Assert(ht.Count==0);
+
+ SetDefaultData();
+ Assert(ht.Count==3);
+
+ bool thrown=false;
+ try {
+ ht.Add("k2","cool");
+ } catch (ArgumentException) {thrown=true;}
+ Assert("Must throw ArgumentException!",thrown);
+
+ ht["k2"]="cool";
+ Assert(ht.Count==3);
+ Assert(ht["k2"].Equals("cool"));
+
+ }
+
+ public void TestCopyTo() {
+ SetDefaultData();
+ Object[] entries=new Object[ht.Count];
+ ht.CopyTo(entries,0);
+ Assert("Not an entry.",entries[0] is DictionaryEntry);
+ }
+
+
+ public void TestUnderHeavyLoad() {
+ Console.WriteLine("Testing "+ht);
+ ht.Clear();
+ int max=100000;
+ String[] cache=new String[max*2];
+ int n=0;
+
+ for (int i=0;i<max;i++) {
+ int id=rnd.Next()&0xFFFF;
+ String key=""+id+"-key-"+id;
+ String val="value-"+id;
+ if (ht[key]==null) {
+ ht[key]=val;
+ cache[n]=key;
+ cache[n+max]=val;
+ n++;
+ }
+ }
+
+ Assert(ht.Count==n);
+
+ for (int i=0;i<n;i++) {
+ String key=cache[i];
+ String val=ht[key] as String;
+ String err="ht[\""+key+"\"]=\""+val+
+ "\", expected \""+cache[i+max]+"\"";
+ Assert(err,val!=null && val.Equals(cache[i+max]));
+ }
+
+ int r1=(n/3);
+ int r2=r1+(n/5);
+
+ for (int i=r1;i<r2;i++) {
+ ht.Remove(cache[i]);
+ }
+
+
+ for (int i=0;i<n;i++) {
+ if (i>=r1 && i<r2) {
+ Assert(ht[cache[i]]==null);
+ } else {
+ String key=cache[i];
+ String val=ht[key] as String;
+ String err="ht[\""+key+"\"]=\""+val+
+ "\", expected \""+cache[i+max]+"\"";
+ Assert(err,val!=null && val.Equals(cache[i+max]));
+ }
+ }
+
+ ICollection keys=ht.Keys;
+ int nKeys=0;
+ foreach (Object key in keys) {
+ Assert((key as String) != null);
+ nKeys++;
+ }
+ Assert(nKeys==ht.Count);
+
+
+ ICollection vals=ht.Values;
+ int nVals=0;
+ foreach (Object val in vals) {
+ Assert((val as String) != null);
+ nVals++;
+ }
+ Assert(nVals==ht.Count);
+
+ }
+
+ }
+}
diff --git a/mcs/class/corlib/System.Collections/ICollection.cs b/mcs/class/corlib/System.Collections/ICollection.cs
new file mode 100644
index 00000000000..2189931cae8
--- /dev/null
+++ b/mcs/class/corlib/System.Collections/ICollection.cs
@@ -0,0 +1,24 @@
+// -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+//
+// System.Collections.ICollection
+//
+// Author:
+// Vladimir Vukicevic (vladimir@pobox.com)
+//
+// (C) 2001 Vladimir Vukicevic
+//
+
+using System;
+
+namespace System.Collections {
+
+ public interface ICollection : IEnumerable {
+ int Count { get; }
+
+ bool IsSynchronized { get; }
+
+ object SyncRoot { get; }
+
+ void CopyTo (Array array, int index);
+ }
+}
diff --git a/mcs/class/corlib/System.Collections/IComparer.cs b/mcs/class/corlib/System.Collections/IComparer.cs
new file mode 100644
index 00000000000..3d1ee2ef609
--- /dev/null
+++ b/mcs/class/corlib/System.Collections/IComparer.cs
@@ -0,0 +1,19 @@
+// -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+//
+// System.Collections.IComparer
+//
+// Author:
+// Vladimir Vukicevic (vladimir@pobox.com)
+//
+// (C) 2001 Vladimir Vukicevic
+//
+
+using System;
+
+namespace System.Collections {
+
+ public interface IComparer {
+ int Compare (object x, object y);
+ }
+
+}
diff --git a/mcs/class/corlib/System.Collections/IDictionary.cs b/mcs/class/corlib/System.Collections/IDictionary.cs
new file mode 100644
index 00000000000..a03ab07d904
--- /dev/null
+++ b/mcs/class/corlib/System.Collections/IDictionary.cs
@@ -0,0 +1,40 @@
+// -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+//
+// System.Collections.IDictionary
+//
+// Author:
+// Vladimir Vukicevic (vladimir@pobox.com)
+//
+// (C) 2001 Vladimir Vukicevic
+//
+
+using System;
+
+namespace System.Collections {
+
+ public interface IDictionary : ICollection {
+ // properties
+
+ bool IsFixedSize { get; }
+
+ bool IsReadOnly { get; }
+
+ object this[object key] { get; set; }
+
+ ICollection Keys { get; }
+
+ ICollection Values { get; }
+
+ // methods
+
+ void Add (object key, object value);
+
+ void Clear ();
+
+ bool Contains (object key);
+
+ new IDictionaryEnumerator GetEnumerator ();
+
+ void Remove (object key);
+ }
+}
diff --git a/mcs/class/corlib/System.Collections/IDictionaryEnumerator.cs b/mcs/class/corlib/System.Collections/IDictionaryEnumerator.cs
new file mode 100644
index 00000000000..fb1998d55f0
--- /dev/null
+++ b/mcs/class/corlib/System.Collections/IDictionaryEnumerator.cs
@@ -0,0 +1,20 @@
+// -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+//
+// System.Collections.IDictionaryEnumerator
+//
+// Author:
+// Vladimir Vukicevic (vladimir@pobox.com)
+//
+// (C) 2001 Vladimir Vukicevic
+//
+
+using System;
+
+namespace System.Collections {
+
+ public interface IDictionaryEnumerator : IEnumerator {
+ DictionaryEntry Entry { get; }
+ object Key { get; }
+ object Value { get; }
+ }
+}
diff --git a/mcs/class/corlib/System.Collections/IEnumerable.cs b/mcs/class/corlib/System.Collections/IEnumerable.cs
new file mode 100644
index 00000000000..de0a57475dc
--- /dev/null
+++ b/mcs/class/corlib/System.Collections/IEnumerable.cs
@@ -0,0 +1,18 @@
+// -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+//
+// System.Collections.IEnumerable
+//
+// Author:
+// Vladimir Vukicevic (vladimir@pobox.com)
+//
+// (C) 2001 Vladimir Vukicevic
+//
+
+using System;
+
+namespace System.Collections {
+
+ public interface IEnumerable {
+ IEnumerator GetEnumerator();
+ }
+}
diff --git a/mcs/class/corlib/System.Collections/IEnumerator.cs b/mcs/class/corlib/System.Collections/IEnumerator.cs
new file mode 100644
index 00000000000..06d250c8b7e
--- /dev/null
+++ b/mcs/class/corlib/System.Collections/IEnumerator.cs
@@ -0,0 +1,22 @@
+//
+// System.Collections.IEnumerator
+//
+// Author:
+// Vladimir Vukicevic (vladimir@pobox.com)
+//
+// (C) 2001 Vladimir Vukicevic
+//
+
+using System;
+
+namespace System.Collections {
+
+ public interface IEnumerator {
+ object Current { get; }
+
+ bool MoveNext ();
+
+ void Reset ();
+ }
+
+}
diff --git a/mcs/class/corlib/System.Collections/IHashCodeProvider.cs b/mcs/class/corlib/System.Collections/IHashCodeProvider.cs
new file mode 100644
index 00000000000..15fc4df45bf
--- /dev/null
+++ b/mcs/class/corlib/System.Collections/IHashCodeProvider.cs
@@ -0,0 +1,18 @@
+// -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+//
+// System.Collections.IHashCodeProvider
+//
+// Author:
+// Vladimir Vukicevic (vladimir@pobox.com)
+//
+// (C) 2001 Vladimir Vukicevic
+//
+
+using System;
+
+namespace System.Collections {
+
+ public interface IHashCodeProvider {
+ int GetHashCode (object obj);
+ }
+}
diff --git a/mcs/class/corlib/System.Collections/IList.cs b/mcs/class/corlib/System.Collections/IList.cs
new file mode 100644
index 00000000000..e039a8358c3
--- /dev/null
+++ b/mcs/class/corlib/System.Collections/IList.cs
@@ -0,0 +1,40 @@
+// -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+//
+// System.Collections.IList
+//
+// Author:
+// Vladimir Vukicevic (vladimir@pobox.com)
+//
+// (C) 2001 Vladimir Vukicevic
+//
+
+using System;
+
+namespace System.Collections {
+
+ public interface IList : ICollection, IEnumerable {
+ // properties
+
+ bool IsFixedSize { get; }
+
+ bool IsReadOnly { get; }
+
+ object this[int index] { get; set; }
+
+ // methods
+
+ int Add (object value);
+
+ void Clear ();
+
+ bool Contains (object value);
+
+ int IndexOf (object value);
+
+ void Insert (int index, object value);
+
+ void Remove (object value);
+
+ void RemoveAt (int index);
+ }
+}
diff --git a/mcs/class/corlib/System.Collections/Queue.cs b/mcs/class/corlib/System.Collections/Queue.cs
new file mode 100644
index 00000000000..fb7a5c502af
--- /dev/null
+++ b/mcs/class/corlib/System.Collections/Queue.cs
@@ -0,0 +1,325 @@
+//
+// System.Collections.Queue
+//
+// Author:
+// Ricardo Fernández Pascual
+//
+// (C) 2001 Ricardo Fernández Pascual
+//
+
+using System;
+using System.Collections;
+
+namespace System.Collections {
+
+ public class Queue : ICollection, IEnumerable, ICloneable {
+
+ private object[] contents;
+ private int head = 0; // points to the first used slot
+ private int count = 0;
+ private int capacity = 16;
+ private float growFactor = 2.0F;
+ private int modCount = 0;
+
+ public Queue () {
+ contents = new object[capacity];
+ }
+
+ public Queue (ICollection collection) {
+ capacity = collection.Count;
+ contents = new object[capacity];
+ count = capacity;
+ collection.CopyTo (contents, 0);
+ }
+
+ public Queue (int initialCapacity) {
+ capacity = initialCapacity;
+ contents = new object[capacity];
+ }
+
+ public Queue (int initialCapacity, float growFactor) {
+ capacity = initialCapacity;
+ contents = new object[capacity];
+ // LAMESPEC: The spec says nothing, but I think this
+ // should throw an exception if growFactor <= 1.0
+ this.growFactor = growFactor;
+ }
+
+ // from ICollection
+
+ public virtual int Count {
+ get { return count; }
+ }
+
+ public virtual bool IsSynchronized {
+ get { return false; }
+ }
+
+ public virtual object SyncRoot {
+ get { return this; }
+ }
+
+ public virtual void CopyTo (Array array, int index) {
+ if (array == null) {
+ throw new ArgumentNullException ();
+ }
+
+ if (index < 0) {
+ throw new ArgumentOutOfRangeException ();
+ }
+
+ if (array.Rank > 1
+ || index >= array.Length
+ || count > array.Length - index) {
+ throw new ArgumentException ();
+ }
+
+ // copy the contents of the circular array
+ Array.Copy (contents, head, array, index,
+ Math.Max (count, capacity - head));
+ if (count > capacity - head)
+ Array.Copy (contents, 0, array,
+ index + capacity - head,
+ count - (capacity - head));
+ }
+
+ // from IEnumerable
+
+ public virtual IEnumerator GetEnumerator () {
+ return new QueueEnumerator (this);
+ }
+
+ // from ICloneable
+
+ public virtual object Clone () {
+ Queue newQueue;
+
+ newQueue = new Queue (); // FIXME: improve this...
+
+ newQueue.contents = (object[]) this.contents.clone ();
+ newQueue.head = this.head;
+ newQueue.count = this.count;
+ newQueue.capacity = this.capacity;
+ newQueue.growFactor = this.growFactor;
+
+ return newQueue;
+ }
+
+ // FIXME: should override Equals?
+
+ // from Queue spec
+
+ public virtual bool IsReadOnly {
+ get { return false; }
+ }
+
+ public virtual void Clear () {
+ modCount++;
+ head = 0;
+ count = 0;
+ // FIXME: Should allocate a new contents array?
+ // Should null the current array?
+ }
+
+ public virtual bool Contains (object obj) {
+ int tail = head + count;
+ if (obj == null) {
+ for (int i = head; i < tail; i++) {
+ if (contents[i % capacity] == null)
+ return true;
+ }
+ } else {
+ for (int i = head; i < tail; i++) {
+ if (obj.Equals (contents[i % capacity]))
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public virtual object Dequeue ()
+ {
+ modCount++;
+ if (count < 1)
+ throw new InvalidOperationException ();
+ object result = contents[head];
+ head = (head + 1) % capacity;
+ count--;
+ return result;
+ }
+
+ public virtual void Enqueue (object obj) {
+ modCount++;
+ if (count == capacity)
+ grow ();
+ contents[(head + count) % capacity] = obj;
+ count++;
+ }
+
+ public virtual object Peek () {
+ if (count < 1)
+ throw new InvalidOperationException ();
+ return contents[head];
+ }
+
+ public static Queue Synchronized (Queue queue) {
+ if (queue == null) {
+ throw new ArgumentNullException ();
+ }
+ return new SyncQueue (queue);
+ }
+
+ public virtual object[] ToArray () {
+ object[] ret = new object[count];
+ CopyTo (ret, 0);
+ return ret;
+ }
+
+ // private methods
+
+ private void grow () {
+ int newCapacity = capacity * 2;
+ int newContents = new object[newCapacity];
+ CopyTo (newContents, 0);
+ contents = newContents;
+ head = 0;
+ }
+
+ // private classes
+
+ private class SyncQueue : Queue {
+ Queue queue;
+
+ internal SyncQueue (Queue queue) {
+ this.queue = queue;
+ }
+
+ public override int Count {
+ get {
+ lock (queue) {
+ return queue.count;
+ }
+ }
+ }
+
+ public override bool IsSynchronized {
+ get {
+ lock (queue) {
+ return queue.IsSynchronized;
+ }
+ }
+ }
+
+ public override object SyncRoot {
+ get {
+ return queue.SyncRoot;
+ }
+ }
+
+ public override void CopyTo (Array array, int index) {
+ lock (queue) {
+ queue.CopyTo (array, index);
+ }
+ }
+
+ public override IEnumerator GetEnumerator () {
+ lock (queue) {
+ return queue.GetEnumerator ();
+ }
+ }
+
+ public override object Clone () {
+ lock (queue) {
+ return queue.Clone ();
+ }
+ }
+
+ public override bool IsReadOnly {
+ get {
+ lock (queue) {
+ return queue.IsReadOnly;
+ }
+ }
+ }
+
+ public override void Clear () {
+ lock (queue) {
+ queue.Clear ();
+ }
+ }
+
+ public override bool Contains (object obj) {
+ lock (queue) {
+ return queue.Contains (obj);
+ }
+ }
+
+ public override object Dequeue () {
+ lock (queue) {
+ return queue.Dequeue ();
+ }
+ }
+
+ public override void Enqueue (object obj) {
+ lock (queue) {
+ queue.Enqueue (obj);
+ }
+ }
+
+ public override object Peek () {
+ lock (queue) {
+ return queue.Peek ();
+ }
+ }
+
+ public override object[] ToArray () {
+ lock (queue) {
+ return queue.ToArray ();
+ }
+ }
+ }
+
+ private class QueueEnumerator : IEnumerator {
+ Queue queue;
+ private int modCount;
+ private int current;
+
+ internal QueueEnumerator (Queue q) {
+ queue = q;
+ modCount = q.modCount;
+ current = -1; // one element before the head
+ }
+
+ public virtual object Current {
+ get {
+ if (modCount != queue.modCount
+ || current < 0
+ || current >= queue.count)
+ throw new InvalidOperationException ();
+ return queue.contents[(queue.head + current) % queue.capacity];
+ }
+ }
+
+ public virtual bool MoveNext () {
+ if (modCount != queue.modCount) {
+ throw new InvalidOperationException ();
+ }
+
+ if (current >= queue.count) {
+ return false;
+ } else {
+ current++;
+ return true;
+ }
+ }
+
+ public virtual void Reset () {
+ if (modCount != queue.modCount) {
+ throw new InvalidOperationException();
+ }
+ current = -1;
+ }
+ }
+ }
+}
+
diff --git a/mcs/class/corlib/System.Collections/ReadOnlyCollectionBase.cs b/mcs/class/corlib/System.Collections/ReadOnlyCollectionBase.cs
new file mode 100644
index 00000000000..89544feabdc
--- /dev/null
+++ b/mcs/class/corlib/System.Collections/ReadOnlyCollectionBase.cs
@@ -0,0 +1,44 @@
+//
+// System.Collections.ReadOnlyCollectionBase.cs
+//
+// Author:
+// Nick Drochak II (ndrochak@gol.com)
+//
+// (C) 2001 Nick Drochak II
+//
+
+using System;
+
+namespace System.Collections {
+
+ public abstract class ReadOnlyCollectionBase : ICollection, IEnumerable {
+
+ // private instance properties
+ private System.Collections.ArrayList myList;
+
+ // public instance properties
+ public virtual int Count { get { return InnerList.Count; } }
+
+ // Public Instance Methods
+ public virtual System.Collections.IEnumerator GetEnumerator() { return InnerList.GetEnumerator(); }
+
+ // Protected Instance Constructors
+ protected ReadOnlyCollectionBase() {
+ this.myList = new System.Collections.ArrayList();
+ }
+
+ // Protected Instance Properties
+ protected virtual System.Collections.ArrayList InnerList {get { return this.myList; } }
+
+ // ICollection methods
+ void ICollection.CopyTo(Array array, int index) {
+ lock (InnerList) { InnerList.CopyTo(array, index); }
+ }
+ object ICollection.SyncRoot {
+ get { return InnerList.SyncRoot; }
+ }
+ bool ICollection.IsSynchronized {
+ get { return InnerList.IsSynchronized; }
+ }
+ }
+}
diff --git a/mcs/class/corlib/System.Collections/SortedList.cs b/mcs/class/corlib/System.Collections/SortedList.cs
new file mode 100644
index 00000000000..f01b164b54c
--- /dev/null
+++ b/mcs/class/corlib/System.Collections/SortedList.cs
@@ -0,0 +1,864 @@
+//
+// System.Collections.SortedList
+//
+// Author:
+// Sergey Chaban (serge@wildwestsoftware.com)
+//
+
+
+using System;
+using System.Collections;
+
+
+namespace System.Collections {
+
+ /// <summary>
+ /// Represents a collection of associated keys and values
+ /// that are sorted by the keys and are accessible by key
+ /// and by index.
+ /// </summary>
+ public class SortedList : IDictionary, ICollection,
+ IEnumerable, ICloneable {
+
+
+ internal struct Slot {
+ internal Object key;
+ internal Object value;
+ }
+
+ private readonly static int INITIAL_SIZE = 16;
+
+ public enum EnumeratorMode : int {KEY_MODE = 0, VALUE_MODE}
+
+ private int inUse;
+ private int modificationCount;
+ private Slot[] table;
+ private IComparer comparer;
+
+
+
+ //
+ // Constructors
+ //
+ public SortedList () : this (INITIAL_SIZE)
+ {
+ }
+
+ public SortedList (int initialCapacity)
+ : this (null, initialCapacity)
+ {
+ }
+
+ public SortedList (IComparer comparer, int initialCapacity)
+ {
+ this.comparer = comparer;
+ InitTable (initialCapacity);
+ }
+
+ public SortedList (IComparer comparer)
+ : this (comparer, 0)
+ {
+ }
+
+
+ public SortedList (IDictionary d) : this (d, null)
+ {
+ }
+
+ public SortedList (IDictionary d, IComparer comparer)
+ {
+ if (d == null)
+ throw new ArgumentNullException ("dictionary");
+
+ InitTable (d.Count);
+ this.comparer = comparer;
+
+ IDictionaryEnumerator it = d.GetEnumerator ();
+ while (it.MoveNext ()) {
+ if (it.Key is IComparable) {
+ Add (it.Key, it.Value);
+ } else {
+ throw new InvalidCastException("!IComparable");
+ }
+ }
+ }
+
+
+
+
+ //
+ // Properties
+ //
+
+
+ // ICollection
+
+ public virtual int Count {
+ get {
+ return inUse;
+ }
+ }
+
+ public virtual bool IsSynchronized {
+ get {
+ return false;
+ }
+ }
+
+ public virtual Object SyncRoot {
+ get {
+ return this;
+ }
+ }
+
+
+ // IDictionary
+
+ public virtual bool IsFixedSize {
+ get {
+ return false;
+ }
+ }
+
+
+ public virtual bool IsReadOnly {
+ get {
+ return false;
+ }
+ }
+
+ public virtual ICollection Keys {
+ get {
+ return new ListKeys (this);
+ }
+ }
+
+ public virtual ICollection Values {
+ get {
+ return new ListValues (this);
+ }
+ }
+
+
+
+ public virtual Object this [Object key] {
+ get {
+ return GetImpl (key);
+ }
+ set {
+ PutImpl (key, value, true);
+ }
+ }
+
+
+
+
+ public virtual int Capacity {
+ get {
+ return table.Length;
+ }
+ set {
+ Slot [] table = this.table;
+ int current = table.Length;
+
+ if (inUse > value)
+ throw new ArgumentOutOfRangeException("capacity too small");
+
+ if (value > current) {
+ Slot [] newTable = new Slot [value];
+ Array.Copy (table, newTable, current);
+ this.table = newTable;
+ }
+ }
+ }
+
+
+
+ //
+ // Public instance methods.
+ //
+
+
+ // IEnumerable
+
+ IEnumerator IEnumerable.GetEnumerator ()
+ {
+ return new Enumerator (this, EnumeratorMode.KEY_MODE);
+ }
+
+
+ // IDictionary
+
+ public virtual void Add (object key, object value)
+ {
+ PutImpl (key, value, false);
+ }
+
+
+ public virtual void Clear ()
+ {
+ this.table = new Slot [Capacity];
+ inUse = 0;
+ modificationCount++;
+ }
+
+ public virtual bool Contains (object key)
+ {
+ return (Find (key) >= 0);
+ }
+
+
+ public virtual IDictionaryEnumerator GetEnumerator ()
+ {
+ return new Enumerator (this, EnumeratorMode.KEY_MODE);
+ }
+
+ public virtual void Remove (object key)
+ {
+ int i = IndexOfKey (key);
+ if (i >= 0) RemoveAt (i);
+ }
+
+
+ // ICollection
+
+ public virtual void CopyTo (Array array, int arrayIndex)
+ {
+ IDictionaryEnumerator it = GetEnumerator ();
+ int i = arrayIndex;
+
+ while (it.MoveNext ()) {
+ array.SetValue (it.Entry, i++);
+ }
+ }
+
+
+
+ // ICloneable
+
+ public virtual object Clone ()
+ {
+ SortedList sl = new SortedList (this, comparer);
+ sl.modificationCount = this.modificationCount;
+ return sl;
+ }
+
+
+
+
+ //
+ // SortedList
+ //
+
+ public virtual IList GetKeyList ()
+ {
+ return new ListKeys (this);
+ }
+
+
+ public virtual IList GetValueList ()
+ {
+ return new ListValues (this);
+ }
+
+
+ public virtual void RemoveAt (int index)
+ {
+ Slot [] table = this.table;
+ int cnt = Count;
+ if (index >= 0 && index < cnt) {
+ if (index != cnt - 1) {
+ Array.Copy (table, index+1, table, index, cnt-1);
+ } else {
+ table [index].key = null;
+ table [index].value = null;
+ }
+ --inUse;
+ ++modificationCount;
+ } else {
+ throw new ArgumentOutOfRangeException("index out of range");
+ }
+ }
+
+
+
+
+
+ public virtual int IndexOfKey (object key)
+ {
+ int indx = Find (key);
+ return (indx | (indx >> 31));
+ }
+
+
+ public virtual int IndexOfValue (object value)
+ {
+ Slot [] table = this.table;
+ int len = table.Length;
+
+ for (int i=0; i < len; i++) {
+ if (table[i].value.Equals (value)) {
+ return i;
+ }
+ }
+
+ return -1;
+ }
+
+
+ public virtual bool ContainsKey (object key)
+ {
+ return Contains (key);
+ }
+
+
+ public virtual bool ContainsValue (object value)
+ {
+ return IndexOfValue (value) >= 0;
+ }
+
+
+ public virtual object GetByIndex (int index)
+ {
+ if (index >= 0 && index < Count) {
+ return table [index].value;
+ } else {
+ throw new ArgumentOutOfRangeException("index out of range");
+ }
+ }
+
+
+ public virtual void SetByIndex (int index, object value)
+ {
+ if (index >= 0 && index < Count) {
+ table [index].value = value;
+ } else {
+ throw new ArgumentOutOfRangeException("index out of range");
+ }
+ }
+
+
+ public virtual object GetKey (int index)
+ {
+ if (index >= 0 && index < Count) {
+ return table [index].key;
+ } else {
+ throw new ArgumentOutOfRangeException("index out of range");
+ }
+ }
+
+
+
+ public virtual void TrimToSize ()
+ {
+ // From Beta2:
+ // Trimming an empty SortedList sets the capacity
+ // of the SortedList to the default capacity,
+ // not zero.
+ if (Count == 0) Resize (INITIAL_SIZE, false);
+ else Resize (Count, true);
+ }
+
+
+
+ public override string ToString ()
+ {
+ return "mono::System.Collections.SortedList";
+ }
+
+
+
+ //
+ // Private methods
+ //
+
+
+ private void Resize (int n, bool copy)
+ {
+ Slot [] table = this.table;
+ Slot [] newTable = new Slot [n];
+ if (copy) Array.Copy (table, 0, newTable, 0, n);
+ this.table = newTable;
+ }
+
+
+ private void EnsureCapacity (int n, int free)
+ {
+ Slot [] table = this.table;
+ Slot [] newTable = null;
+ int cap = Capacity;
+ bool gap = (free >=0 && free < Count);
+
+ if (n > cap) {
+ newTable = new Slot [n << 1];
+ }
+
+ if (newTable != null) {
+ if (gap) {
+ int copyLen = free;
+ if (copyLen > 0) {
+ Array.Copy (table, 0, newTable, 0, copyLen);
+ }
+ copyLen = Count - free;
+ if (copyLen > 0) {
+ Array.Copy (table, free, newTable, free+1, copyLen);
+ }
+ } else {
+ // Just a resizing, copy the entire table.
+ Array.Copy (table, newTable, Count);
+ }
+ this.table = newTable;
+ } else if (gap) {
+ Array.Copy (table, free, table, free+1, Count - free);
+ }
+ }
+
+
+ private void PutImpl (object key, object value, bool overwrite)
+ {
+ if (key == null)
+ throw new ArgumentNullException ("null key");
+
+ Slot [] table = this.table;
+ int freeIndx = Find (key);
+
+
+ if (freeIndx >= 0) {
+ if (!overwrite)
+ throw new ArgumentException("element already exists");
+
+ table [freeIndx].value = value;
+ return;
+ }
+
+ freeIndx = ~freeIndx;
+
+ if (freeIndx > Capacity + 1)
+ throw new Exception ("SortedList::internal error ("+key+", "+value+") at ["+freeIndx+"]");
+
+
+ EnsureCapacity (Count+1, freeIndx);
+
+ table = this.table;
+ table [freeIndx].key = key;
+ table [freeIndx].value = value;
+
+ ++inUse;
+ ++modificationCount;
+
+ }
+
+
+ private object GetImpl (object key)
+ {
+ int i = Find (key);
+
+ if (i >= 0)
+ return table [i].value;
+ else
+ return null;
+ }
+
+
+ private void InitTable (int capacity)
+ {
+ int size = (capacity + 1) & (~1);
+ if (size < INITIAL_SIZE) size = INITIAL_SIZE;
+ this.table = new Slot [size];
+ this.inUse = 0;
+ this.modificationCount = 0;
+ }
+
+
+ private void CopyToArray (Array arr, int i,
+ EnumeratorMode mode)
+ {
+ IEnumerator it = new Enumerator (this, mode);
+
+ while (it.MoveNext ()) {
+ arr.SetValue (it.Current, i++);
+ }
+ }
+
+
+ private int Find (object key)
+ {
+ Slot [] table = this.table;
+ int len = Count;
+
+ if (len == 0) return ~0;
+
+ IComparer comparer = (this.comparer == null)
+ ? Comparer.Default
+ : this.comparer;
+
+ int left = 0;
+ int right = len-1;
+
+ while (left <= right) {
+ int guess = (left + right) >> 1;
+
+ int cmp = comparer.Compare (key, table[guess].key);
+
+ if (cmp == 0) return guess;
+
+ cmp &= ~Int32.MaxValue;
+
+ if (cmp == 0) left = guess+1;
+ else right = guess-1;
+ }
+
+ return ~left;
+ }
+
+
+
+ //
+ // Inner classes
+ //
+
+
+ protected sealed class Enumerator : IDictionaryEnumerator,
+ IEnumerator {
+
+ private SortedList host;
+ private int stamp;
+ private int pos;
+ private int size;
+ private EnumeratorMode mode;
+
+ private object currentKey;
+ private object currentValue;
+
+ private readonly static string xstr = "SortedList.Enumerator: snapshot out of sync.";
+
+ public Enumerator (SortedList host, EnumeratorMode mode)
+ {
+ this.host = host;
+ stamp = host.modificationCount;
+ size = host.Count;
+ this.mode = mode;
+ Reset ();
+ }
+
+ public Enumerator (SortedList host)
+ : this (host, EnumeratorMode.KEY_MODE)
+ {
+ }
+
+
+ private void FailFast ()
+ {
+ if (host.modificationCount != stamp) {
+ throw new InvalidOperationException (xstr);
+ }
+ }
+
+ public void Reset ()
+ {
+ FailFast ();
+
+ pos = -1;
+ currentKey = null;
+ currentValue = null;
+ }
+
+ public bool MoveNext ()
+ {
+ FailFast ();
+
+ Slot [] table = host.table;
+
+ if (++pos < size) {
+ Slot entry = table [pos];
+
+ currentKey = entry.key;
+ currentValue = entry.value;
+ return true;
+ }
+
+ currentKey = null;
+ currentValue = null;
+ return false;
+ }
+
+ public DictionaryEntry Entry
+ {
+ get {
+ FailFast ();
+ return new DictionaryEntry (currentKey,
+ currentValue);
+ }
+ }
+
+ public Object Key {
+ get {
+ FailFast ();
+ return currentKey;
+ }
+ }
+
+ public Object Value {
+ get {
+ FailFast ();
+ return currentValue;
+ }
+ }
+
+ public Object Current {
+ get {
+ FailFast ();
+ return (mode == EnumeratorMode.KEY_MODE)
+ ? currentKey
+ : currentValue;
+ }
+ }
+ }
+
+
+ protected class ListKeys : IList, IEnumerable {
+
+ private SortedList host;
+
+
+ public ListKeys (SortedList host)
+ {
+ if (host == null)
+ throw new ArgumentNullException ();
+
+ this.host = host;
+ }
+
+ //
+ // ICollection
+ //
+
+ public virtual int Count {
+ get {
+ return host.Count;
+ }
+ }
+
+ public virtual bool IsSynchronized {
+ get {
+ return host.IsSynchronized;
+ }
+ }
+
+ public virtual Object SyncRoot {
+ get {
+ return host.SyncRoot;
+ }
+ }
+
+ public virtual void CopyTo (Array array, int arrayIndex)
+ {
+ host.CopyToArray (array, arrayIndex, EnumeratorMode.KEY_MODE);
+ }
+
+
+ //
+ // IList
+ //
+
+ public virtual bool IsFixedSize {
+ get {
+ return true;
+ }
+ }
+
+ public virtual bool IsReadOnly {
+ get {
+ return true;
+ }
+ }
+
+
+ public virtual object this [int index] {
+ get {
+ return host.GetKey (index);
+ }
+ set {
+ throw new NotSupportedException("attempt to modify a key");
+ }
+ }
+
+ public virtual int Add (object value)
+ {
+ throw new NotSupportedException("IList::Add not supported");
+ }
+
+ public virtual void Clear ()
+ {
+ throw new NotSupportedException("IList::Clear not supported");
+ }
+
+ public virtual bool Contains (object key)
+ {
+ return host.Contains (key);
+ }
+
+
+ public virtual int IndexOf (object key)
+ {
+ return host.IndexOfKey (key);
+ }
+
+
+ public virtual void Insert (int index, object value)
+ {
+ throw new NotSupportedException("IList::Insert not supported");
+ }
+
+
+ public virtual void Remove (object value)
+ {
+ throw new NotSupportedException("IList::Remove not supported");
+ }
+
+
+ public virtual void RemoveAt (int index)
+ {
+ throw new NotSupportedException("IList::RemoveAt not supported");
+ }
+
+
+ //
+ // IEnumerable
+ //
+
+ public virtual IEnumerator GetEnumerator ()
+ {
+ return new SortedList.Enumerator (host, EnumeratorMode.KEY_MODE);
+ }
+
+
+ }
+
+
+ protected class ListValues : IList, IEnumerable {
+
+ private SortedList host;
+
+
+ public ListValues (SortedList host)
+ {
+ if (host == null)
+ throw new ArgumentNullException ();
+
+ this.host = host;
+ }
+
+ //
+ // ICollection
+ //
+
+ public virtual int Count {
+ get {
+ return host.Count;
+ }
+ }
+
+ public virtual bool IsSynchronized {
+ get {
+ return host.IsSynchronized;
+ }
+ }
+
+ public virtual Object SyncRoot {
+ get {
+ return host.SyncRoot;
+ }
+ }
+
+ public virtual void CopyTo (Array array, int arrayIndex)
+ {
+ host.CopyToArray (array, arrayIndex, EnumeratorMode.VALUE_MODE);
+ }
+
+
+ //
+ // IList
+ //
+
+ public virtual bool IsFixedSize {
+ get {
+ return true;
+ }
+ }
+
+ public virtual bool IsReadOnly {
+ get {
+ return true;
+ }
+ }
+
+
+ public virtual object this [int index] {
+ get {
+ return host.GetByIndex (index);
+ }
+ set {
+ // FIXME: It seems (according to tests)
+ // that modifications are allowed
+ // in Beta2.
+ // ? host.SetByIndex (index, value);
+ throw new NotSupportedException("attempt to modify a value");
+ }
+ }
+
+ public virtual int Add (object value)
+ {
+ throw new NotSupportedException("IList::Add not supported");
+ }
+
+ public virtual void Clear ()
+ {
+ throw new NotSupportedException("IList::Clear not supported");
+ }
+
+ public virtual bool Contains (object value)
+ {
+ return host.ContainsValue (value);
+ }
+
+
+ public virtual int IndexOf (object value)
+ {
+ return host.IndexOfValue (value);
+ }
+
+
+ public virtual void Insert (int index, object value)
+ {
+ throw new NotSupportedException("IList::Insert not supported");
+ }
+
+
+ public virtual void Remove (object value)
+ {
+ throw new NotSupportedException("IList::Remove not supported");
+ }
+
+
+ public virtual void RemoveAt (int index)
+ {
+ throw new NotSupportedException("IList::RemoveAt not supported");
+ }
+
+
+ //
+ // IEnumerable
+ //
+
+ public virtual IEnumerator GetEnumerator ()
+ {
+ return new SortedList.Enumerator (host, EnumeratorMode.VALUE_MODE);
+ }
+
+
+ }
+
+ } // SortedList
+
+} // System.Collections
diff --git a/mcs/class/corlib/System.Collections/Stack.cs b/mcs/class/corlib/System.Collections/Stack.cs
new file mode 100644
index 00000000000..f6e04320741
--- /dev/null
+++ b/mcs/class/corlib/System.Collections/Stack.cs
@@ -0,0 +1,315 @@
+//
+// System.Collections.Stack
+//
+// Author:
+// Garrett Rooney (rooneg@electricjellyfish.net)
+//
+// (C) 2001 Garrett Rooney
+//
+
+namespace System.Collections {
+
+ public class Stack : ICollection, IEnumerable, ICloneable {
+
+ // properties
+ private object[] contents;
+ private int current = -1;
+ private int count = 0;
+ private int capacity = 16;
+ private int modCount = 0;
+
+ private void Resize(int ncapacity) {
+ object[] ncontents = new object[ncapacity];
+
+ Array.Copy(contents, ncontents, count);
+
+ capacity = ncapacity;
+ contents = ncontents;
+ }
+
+ public Stack() {
+ contents = new object[capacity];
+ }
+
+ public Stack(ICollection collection) {
+ capacity = collection.Count;
+ contents = new object[capacity];
+ current = capacity - 1;
+ count = capacity;
+
+ collection.CopyTo(contents, 0);
+ }
+
+ public Stack(int c) {
+ capacity = c;
+ contents = new object[capacity];
+ }
+
+ private class SyncStack : Stack {
+
+ Stack stack;
+
+ public SyncStack(Stack s) {
+ stack = s;
+ }
+
+ public override int Count {
+ get {
+ lock (stack) {
+ return stack.Count;
+ }
+ }
+ }
+
+ public override bool IsReadOnly {
+ get {
+ lock (stack) {
+ return stack.IsReadOnly;
+ }
+ }
+ }
+
+ public override bool IsSynchronized {
+ get { return true; }
+ }
+
+ public override object SyncRoot {
+ get { return stack.SyncRoot; }
+ }
+
+ public override void Clear() {
+ lock(stack) { stack.Clear(); }
+ }
+
+ public override object Clone() {
+ lock (stack) {
+ return Stack.Synchronized((Stack)stack.Clone());
+ }
+ }
+
+ public override bool Contains(object obj) {
+ lock (stack) { return stack.Contains(obj); }
+ }
+
+ public override void CopyTo(Array array, int index) {
+ lock (stack) { stack.CopyTo(array, index); }
+ }
+
+ public override IEnumerator GetEnumerator() {
+ lock (stack) {
+ return new Enumerator(stack);
+ }
+ }
+
+ public override object Peek() {
+ lock (stack) { return stack.Peek(); }
+ }
+
+ public override object Pop() {
+ lock (stack) { return stack.Pop(); }
+ }
+
+ public override void Push(object obj) {
+ lock (stack) { stack.Push(obj); }
+ }
+
+ public override object[] ToArray() {
+ lock (stack) { return stack.ToArray(); }
+ }
+ }
+
+ public static Stack Synchronized(Stack s) {
+ if (s == null) {
+ throw new ArgumentNullException();
+ }
+
+ return new SyncStack(s);
+ }
+
+ public virtual int Count {
+ get { return count; }
+ }
+
+ public virtual bool IsReadOnly {
+ get { return false; }
+ }
+
+ public virtual bool IsSynchronized {
+ get { return false; }
+ }
+
+ public virtual object SyncRoot {
+ get { return this; }
+ }
+
+ public virtual void Clear() {
+ modCount++;
+
+ for (int i = 0; i < count; i++) {
+ contents[i] = null;
+ }
+
+ count = 0;
+ current = -1;
+ }
+
+ public virtual object Clone() {
+ Stack stack;
+
+ stack = new Stack();
+
+ stack.current = current;
+ stack.contents = contents;
+ stack.count = count;
+ stack.capacity = capacity;
+
+ return stack;
+ }
+
+ public virtual bool Contains(object obj) {
+ if (count == 0)
+ return false;
+
+ for (int i = 0; i < count; i++) {
+ if (contents[i].Equals(obj))
+ return true;
+ }
+
+ return false;
+ }
+
+ public virtual void CopyTo (Array array, int index) {
+ if (array == null) {
+ throw new ArgumentNullException();
+ }
+
+ if (index < 0) {
+ throw new ArgumentOutOfRangeException();
+ }
+
+ if (array.Rank > 1 ||
+ index >= array.Length ||
+ count > array.Length - index) {
+ throw new ArgumentException();
+ }
+
+ for (int i = current; i != -1; i--) {
+ array.SetValue(contents[i],
+ count - (i + 1) + index);
+ }
+ }
+
+ private class Enumerator : IEnumerator {
+
+ Stack stack;
+ private int modCount;
+ private int current;
+
+ internal Enumerator(Stack s) {
+ // this is odd. it seems that you need to
+ // start one further ahead than current, since
+ // MoveNext() gets called first when using an
+ // Enumeration...
+ stack = s;
+ modCount = s.modCount;
+ current = s.current + 1;
+ }
+
+ public virtual object Current {
+ get {
+ if (modCount != stack.modCount
+ || current == -1
+ || current > stack.count)
+ throw new InvalidOperationException();
+ return stack.contents[current];
+ }
+ }
+
+ public virtual bool MoveNext() {
+ if (modCount != stack.modCount
+ || current == -1) {
+ throw new InvalidOperationException();
+ }
+
+ current--;
+
+ if (current == -1) {
+ return false;
+ } else {
+ return true;
+ }
+ }
+
+ public virtual void Reset() {
+ if (modCount != stack.modCount) {
+ throw new InvalidOperationException();
+ }
+
+ // start one ahead of stack.current, so the
+ // first MoveNext() will put us at the top
+ current = stack.current + 1;
+ }
+ }
+
+ public virtual IEnumerator GetEnumerator() {
+ return new Enumerator(this);
+ }
+
+ public virtual object Peek() {
+ if (current == -1) {
+ throw new InvalidOperationException();
+ } else {
+ return contents[current];
+ }
+ }
+
+ public virtual object Pop() {
+ if (current == -1) {
+ throw new InvalidOperationException();
+ } else {
+ modCount++;
+
+ object ret = contents[current];
+
+ count--;
+ current--;
+
+ // if we're down to capacity/4, go back to a
+ // lower array size. this should keep us from
+ // sucking down huge amounts of memory when
+ // putting large numbers of items in the Stack.
+ // if we're lower than 16, don't bother, since
+ // it will be more trouble than it's worth.
+ if (count <= (capacity/4) && count > 16) {
+ Resize(capacity/2);
+ }
+
+ return ret;
+ }
+ }
+
+ public virtual void Push(Object o) {
+ modCount++;
+
+ if (capacity == count) {
+ Resize(capacity * 2);
+ }
+
+ count++;
+ current++;
+
+ contents[current] = o;
+ }
+
+ public virtual object[] ToArray() {
+ object[] ret = new object[count];
+
+ Array.Copy(contents, ret, count);
+
+ // ret needs to be in LIFO order
+ Array.Reverse(ret);
+
+ return ret;
+ }
+ }
+}
diff --git a/mcs/class/corlib/System.Collections/common.src b/mcs/class/corlib/System.Collections/common.src
new file mode 100755
index 00000000000..ed60a71bbbd
--- /dev/null
+++ b/mcs/class/corlib/System.Collections/common.src
@@ -0,0 +1,15 @@
+ArrayList.cs
+BitArray.cs
+CollectionBase.cs
+Hashtable.cs
+ICollection.cs
+IComparer.cs
+IDictionary.cs
+IDictionaryEnumerator.cs
+IEnumerable.cs
+IEnumerator.cs
+IHashCodeProvider.cs
+IList.cs
+ReadOnlyCollectionBase.cs
+Stack.cs
+SortedList.cs
diff --git a/mcs/class/corlib/System.Collections/unix.src b/mcs/class/corlib/System.Collections/unix.src
new file mode 100755
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/mcs/class/corlib/System.Collections/unix.src
diff --git a/mcs/class/corlib/System.Collections/windows.src b/mcs/class/corlib/System.Collections/windows.src
new file mode 100755
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/mcs/class/corlib/System.Collections/windows.src
diff --git a/mcs/class/corlib/System.Configuration.Assemblies/AssemblyHash.cs b/mcs/class/corlib/System.Configuration.Assemblies/AssemblyHash.cs
new file mode 100644
index 00000000000..70f539377ce
--- /dev/null
+++ b/mcs/class/corlib/System.Configuration.Assemblies/AssemblyHash.cs
@@ -0,0 +1,70 @@
+
+//
+// AssemblyHash.cs
+//
+// Implementation of the
+// System.Configuration.Assemblies.AssemblyHash
+// class for the Mono Class Library
+//
+// Author:
+// Tomas Restrepo (tomasr@mvps.org)
+//
+
+namespace System.Configuration.Assemblies {
+
+ public struct AssemblyHash : System.ICloneable
+ {
+ private AssemblyHashAlgorithm _algorithm;
+ private byte[] _value;
+
+ public static readonly AssemblyHash Empty =
+ new AssemblyHash(AssemblyHashAlgorithm.None,null);
+
+
+ //
+ // properties
+ //
+ public AssemblyHashAlgorithm Algorithm {
+ get { return _algorithm; }
+ set { _algorithm = value; }
+ }
+
+
+ //
+ // construction
+ //
+ public AssemblyHash ( AssemblyHashAlgorithm algorithm, byte[] value )
+ {
+ _algorithm = algorithm;
+ _value = null;
+ if ( value != null )
+ {
+ int size = value.Length;
+ _value = new byte[size];
+ System.Array.Copy ( value, _value, size );
+ }
+ }
+
+ public AssemblyHash ( byte[] value )
+ : this(AssemblyHashAlgorithm.SHA1, value)
+ {
+ }
+
+ public object Clone()
+ {
+ return new AssemblyHash(_algorithm,_value);
+ }
+
+ public byte[] GetValue()
+ {
+ return _value;
+ }
+ public void SetValue ( byte[] value )
+ {
+ _value = value;
+ }
+
+ } // class AssemblyHash
+
+} // namespace System.Configuration.Assemblies
+
diff --git a/mcs/class/corlib/System.Configuration.Assemblies/AssemblyHashAlgorithm.cs b/mcs/class/corlib/System.Configuration.Assemblies/AssemblyHashAlgorithm.cs
new file mode 100644
index 00000000000..9473a3689ba
--- /dev/null
+++ b/mcs/class/corlib/System.Configuration.Assemblies/AssemblyHashAlgorithm.cs
@@ -0,0 +1,22 @@
+
+//
+// AssemblyHashAlgorithm.cs
+//
+// Implementation of the
+// System.Configuration.Assemblies.AssemblyHashAlgorithm
+// enumeration for the Mono Class Library
+//
+// Written by Tomas Restrepo (tomasr@mvps.org)
+//
+
+namespace System.Configuration.Assemblies {
+
+ public enum AssemblyHashAlgorithm
+ {
+ None = 0x00000000,
+ MD5 = 0x00008003,
+ SHA1 = 0x00008004,
+ } // enum AssemblyHashAlgorithm
+
+} // namespace System.Configuration.Assemblies
+
diff --git a/mcs/class/corlib/System.Configuration.Assemblies/AssemblyVersionCompatibility.cs b/mcs/class/corlib/System.Configuration.Assemblies/AssemblyVersionCompatibility.cs
new file mode 100644
index 00000000000..9b216268186
--- /dev/null
+++ b/mcs/class/corlib/System.Configuration.Assemblies/AssemblyVersionCompatibility.cs
@@ -0,0 +1,23 @@
+
+//
+// AssemblyVersionCompatibility.cs
+//
+// Implementation of the
+// System.Configuration.Assemblies.AssemblyVersionCompatibility
+// enumeration for the Mono Class Library
+//
+// Written by Tomas Restrepo (tomasr@mvps.org)
+//
+
+namespace System.Configuration.Assemblies {
+
+ public enum AssemblyVersionCompatibility
+ {
+ SameMachine = 0x00000001,
+ SameProcess = 0x00000002,
+ SameDomain = 0x00000003,
+
+ } // enum AssemblyHashAlgorithm
+
+} // namespace System.Configuration.Assemblies
+
diff --git a/mcs/class/corlib/System.Configuration.Assemblies/ChangeLog b/mcs/class/corlib/System.Configuration.Assemblies/ChangeLog
new file mode 100644
index 00000000000..d9e7f8ea889
--- /dev/null
+++ b/mcs/class/corlib/System.Configuration.Assemblies/ChangeLog
@@ -0,0 +1,6 @@
+2001-07-13 Tomas Restrepo (tomasr@mvps.org)
+
+ * AssemblyHash finished
+ * AssemblyHashAlgorithm finished
+ * AssemblyVersion finished
+ \ No newline at end of file
diff --git a/mcs/class/corlib/System.Configuration.Assemblies/common.src b/mcs/class/corlib/System.Configuration.Assemblies/common.src
new file mode 100644
index 00000000000..f733f120da6
--- /dev/null
+++ b/mcs/class/corlib/System.Configuration.Assemblies/common.src
@@ -0,0 +1,3 @@
+AssemblyHash.cs
+AssemblyHashAlgorithm.cs
+AssemblyVersionCompatibility.cs
diff --git a/mcs/class/corlib/System.Configuration.Assemblies/unix.src b/mcs/class/corlib/System.Configuration.Assemblies/unix.src
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/mcs/class/corlib/System.Configuration.Assemblies/unix.src
diff --git a/mcs/class/corlib/System.Configuration.Assemblies/windows.src b/mcs/class/corlib/System.Configuration.Assemblies/windows.src
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/mcs/class/corlib/System.Configuration.Assemblies/windows.src
diff --git a/mcs/class/corlib/System.Diagnostics/BooleanSwitch.cs b/mcs/class/corlib/System.Diagnostics/BooleanSwitch.cs
new file mode 100644
index 00000000000..184245b6b6b
--- /dev/null
+++ b/mcs/class/corlib/System.Diagnostics/BooleanSwitch.cs
@@ -0,0 +1,48 @@
+//
+// System.Diagnostics.BooleanSwitch.cs
+//
+// Author:
+// John R. Hicks (angryjohn69@nc.rr.com)
+//
+// (C) 2001
+//
+
+namespace System.Diagnostics
+{
+ /// <summary>
+ /// Provides a simple on/off switch that controls debuggina
+ /// and tracing output
+ /// </summary>
+ public class BooleanSwitch : Switch
+ {
+ private bool enabled = false;
+
+ /// <summary>
+ /// Initializes a new instance
+ /// </summary>
+ public BooleanSwitch(string displayName, string description)
+ : base(displayName, description)
+ {
+ }
+
+ // =================== Properties ===================
+
+ /// <summary>
+ /// Specifies whether the switch is enabled or disabled
+ /// </summary>
+ public bool Enabled
+ {
+ get
+ {
+ return enabled;
+ }
+ set
+ {
+ enabled = value;
+ }
+ }
+
+ // ================= Event Handlers =================
+
+ }
+}
diff --git a/mcs/class/corlib/System.Diagnostics/ChangeLog b/mcs/class/corlib/System.Diagnostics/ChangeLog
new file mode 100644
index 00000000000..adaa706ff42
--- /dev/null
+++ b/mcs/class/corlib/System.Diagnostics/ChangeLog
@@ -0,0 +1,3 @@
+2001-08-21 Nick Drochak <ndrochak@gol.com>
+
+ * Implemented ConditionalAttribute.cs and DebuggableAttribute.cs
diff --git a/mcs/class/corlib/System.Diagnostics/ConditionalAttribute.cs b/mcs/class/corlib/System.Diagnostics/ConditionalAttribute.cs
new file mode 100644
index 00000000000..1fd89a0f06d
--- /dev/null
+++ b/mcs/class/corlib/System.Diagnostics/ConditionalAttribute.cs
@@ -0,0 +1,28 @@
+//
+// System.Collections.DebuggableAttribute.cs
+//
+// Author:
+// Nick Drochak II (ndrochak@gol.com)
+//
+// (C) 2001 Nick Drochak II
+//
+
+namespace System.Diagnostics
+{
+
+ public sealed class ConditionalAttribute : System.Attribute
+ {
+
+ private string myCondition;
+
+ // Public Instance Constructors
+ public ConditionalAttribute(string conditionString)
+ {
+ myCondition = conditionString;
+ }
+
+ // Public Instance Properties
+ public string ConditionString { get { return myCondition; }
+ }
+ }
+}
diff --git a/mcs/class/corlib/System.Diagnostics/DebuggableAttribute.cs b/mcs/class/corlib/System.Diagnostics/DebuggableAttribute.cs
new file mode 100644
index 00000000000..68d0958b04e
--- /dev/null
+++ b/mcs/class/corlib/System.Diagnostics/DebuggableAttribute.cs
@@ -0,0 +1,28 @@
+//
+// System.Collections.DebuggableAttribute.cs
+//
+// Author:
+// Nick Drochak II (ndrochak@gol.com)
+//
+// (C) 2001 Nick Drochak II
+//
+
+namespace System.Diagnostics {
+
+ public sealed class DebuggableAttribute : System.Attribute {
+
+ private bool JITTrackingEnabledFlag;
+ private bool JITOptimizerDisabledFlag;
+
+ // Public Instance Constructors
+ public DebuggableAttribute(bool isJITTrackingEnabled, bool isJITOptimizerDisabled) {
+ JITTrackingEnabledFlag = isJITTrackingEnabled;
+ JITOptimizerDisabledFlag = isJITOptimizerDisabled;
+ }
+
+ // Public Instance Properties
+ public bool IsJITTrackingEnabled { get { return JITTrackingEnabledFlag; } }
+
+ public bool IsJITOptimizerDisabled { get { return JITOptimizerDisabledFlag; } }
+ }
+}
diff --git a/mcs/class/corlib/System.Diagnostics/Switch.cs b/mcs/class/corlib/System.Diagnostics/Switch.cs
new file mode 100644
index 00000000000..6021783b0ec
--- /dev/null
+++ b/mcs/class/corlib/System.Diagnostics/Switch.cs
@@ -0,0 +1,93 @@
+//
+// System.Diagnostics.Switch.cs
+//
+// Author:
+// John R. Hicks (angryjohn69@nc.rr.com)
+//
+// (C) 2001
+//
+
+namespace System.Diagnostics
+{
+ /// <summary>
+ /// Abstract base class to create new debugging and tracing switches
+ /// </summary>
+ public abstract class Switch
+ {
+ private string desc = "";
+ private string display_name = "";
+ private int iSwitch;
+
+ // ================= Constructors ===================
+ /// <summary>
+ /// Initialize a new instance
+ /// </summary>
+ protected Switch(string displayName, string description)
+ {
+ display_name = displayName;
+ desc = description;
+ }
+
+ /// <summary>
+ /// Allows an Object to attempt to free resources and
+ /// perform cleanup before the Object is reclaimed
+ /// by the Garbage Collector
+ /// </summary>
+ ~Switch()
+ {
+ }
+
+ // ================ Instance Methods ================
+
+ // ==================== Properties ==================
+
+ /// <summary>
+ /// Returns a description of the switch
+ /// </summary>
+ public string Description
+ {
+ get
+ {
+ return desc;
+ }
+ }
+
+ /// <summary>
+ /// Returns a name used to identify the switch
+ /// </summary>
+ public string DisplayName
+ {
+ get
+ {
+ return display_name;
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the current setting for this switch
+ /// </summary>
+ protected int SwitchSetting
+ {
+ get
+ {
+ return iSwitch;
+ }
+ set
+ {
+ if(iSwitch != value)
+ {
+
+ }
+ iSwitch = value;
+ }
+ }
+
+ /// <summary>
+ /// Raises the SwitchSettingChanged event
+ /// </summary>
+ protected virtual void OnSwitchSettingChanged()
+ {
+ // TODO: implement me
+ }
+ }
+}
diff --git a/mcs/class/corlib/System.Diagnostics/TraceLevel.cs b/mcs/class/corlib/System.Diagnostics/TraceLevel.cs
new file mode 100644
index 00000000000..592518840d6
--- /dev/null
+++ b/mcs/class/corlib/System.Diagnostics/TraceLevel.cs
@@ -0,0 +1,15 @@
+//
+// System.Diagnostics.TraceLevel.cs Enumeration
+//
+// Author:
+// John R. Hicks (angryjohn69@nc.rr.com)
+//
+// (C) 2001
+
+namespace System.Diagnostics
+{
+ /// <summary>
+ /// Specifies what messages to output for the Debug, Trace and TraceSwitch classes.
+ /// </summary>
+ public enum TraceLevel {Error, Info, Off, Verbose, Warning}
+}
diff --git a/mcs/class/corlib/System.Diagnostics/TraceSwitch.cs b/mcs/class/corlib/System.Diagnostics/TraceSwitch.cs
new file mode 100644
index 00000000000..4b64d80e6ce
--- /dev/null
+++ b/mcs/class/corlib/System.Diagnostics/TraceSwitch.cs
@@ -0,0 +1,97 @@
+//
+// System.Diagnostics.TraceSwtich.cs
+//
+// Author:
+// John R. Hicks (angryjohn69@nc.rr.com)
+//
+// (C) 2001
+//
+
+namespace System.Diagnostics
+{
+ /// <summary>
+ /// Multi-level switch to provide tracing and debug output without
+ /// recompiling.
+ /// </summary>
+ public class TraceSwitch : Switch
+ {
+ private TraceLevel level;
+ private bool traceError = false;
+ private bool traceInfo = false;
+ private bool traceVerbose = false;
+ private bool traceWarning = false;
+
+ /// <summary>
+ /// Initializes a new instance
+ /// </summary>
+ /// <param name="displayName">Name for the switch</param>
+ /// <param name="description">Description of the switch</param>
+ public TraceSwitch(string displayName, string description)
+ : base(displayName, description)
+ {
+ }
+
+ /// <summary>
+ /// Gets or sets the trace level that specifies the messages to
+ /// output for tracing and debugging.
+ /// </summary>
+ public TraceLevel Level
+ {
+ get
+ {
+ return level;
+ }
+ set
+ {
+ level = value;
+ }
+
+ }
+
+ /// <summary>
+ /// Gets a value indicating whether the Level is set to Error,
+ /// Warning, Info, or Verbose.
+ /// </summary>
+ public bool TraceError
+ {
+ get
+ {
+ return traceError;
+ }
+ }
+
+ /// <summary>
+ /// Gets a value indicating whether the Level is set to Info or Verbose.
+ /// </summary>
+ public bool TraceInfo
+ {
+ get
+ {
+ return traceInfo;
+ }
+ }
+
+ /// <summary>
+ /// Gets a value indicating whether the Level is set to Verbose.
+ /// </summary>
+ public bool TraceVerbose
+ {
+ get
+ {
+ return traceVerbose;
+ }
+ }
+
+ /// <summary>
+ /// Gets a value indicating whether the Level is set to
+ /// Warning, Info, or Verbose.
+ /// </summary>
+ public bool TraceWarning
+ {
+ get
+ {
+ return traceWarning;
+ }
+ }
+ }
+}
diff --git a/mcs/class/corlib/System.Diagnostics/common.src b/mcs/class/corlib/System.Diagnostics/common.src
new file mode 100644
index 00000000000..53afd2cc3d2
--- /dev/null
+++ b/mcs/class/corlib/System.Diagnostics/common.src
@@ -0,0 +1,6 @@
+BooleanSwitch.cs
+ConditionalAttribute.cs
+DebuggableAttribute.cs
+Switch.cs
+TraceLevel.cs
+TraceSwitch.cs
diff --git a/mcs/class/corlib/System.Diagnostics/unix.src b/mcs/class/corlib/System.Diagnostics/unix.src
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/mcs/class/corlib/System.Diagnostics/unix.src
diff --git a/mcs/class/corlib/System.Diagnostics/windows.src b/mcs/class/corlib/System.Diagnostics/windows.src
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/mcs/class/corlib/System.Diagnostics/windows.src
diff --git a/mcs/class/corlib/System.Globalization/Calendar.cs b/mcs/class/corlib/System.Globalization/Calendar.cs
new file mode 100644
index 00000000000..f29d1c3e303
--- /dev/null
+++ b/mcs/class/corlib/System.Globalization/Calendar.cs
@@ -0,0 +1,58 @@
+//
+// System.Globalization.Calendar.cs
+//
+// Nick made it. (nick@ximian.com)
+//
+// (C) Ximian, Inc. http://www.ximian.com/
+//
+
+namespace System.Globalization
+{
+ public abstract class Calendar
+ {
+ protected Calendar ();
+
+ public const int CurrentEra;
+
+ public abstract int[] Eras {get;}
+ public virtual int TwoDigitYearMax {get; set;}
+
+ public virtual DateTime AddDays ( DateTime time, int days );
+ public virtual DateTime AddHours ( DateTime time, int hours );
+ public virtual DateTime AddMilliseconds ( DateTime time, double milliseconds );
+ public virtual DateTime AddMinutes ( DateTime time, int minutes );
+ public virtual DateTime AddMonths ( DateTime time, int months );
+ public virtual DateTime AddSeconds ( DateTime time, int seconds );
+ public virtual DateTime AddWeeks ( DateTime time, int weeks );
+ public virtual DateTime AddYears ( DateTime time, int years );
+
+
+ public abstract int GetDayOfMonth ( DateTime time );
+ public abstract DayOfWeek GetDayOfWeek ( DateTime time );
+ public abstract GetDayOfYear ( DateTime time );
+ public virtual int GetDaysInMonth ( int year, int month );
+ public abstract int GetDaysInMonth ( int year, int month, int era );
+ public virtual int GetDaysInYear ( int year );
+ public abstract int GetDaysInYear ( int year, int era );
+ public abstract int GetEra ( DateTime time );
+ public virtual int GetHour ( DateTime time );
+ public virtual double GetMilliseconds ( DateTime time );
+ public virtual int GetMinute ( DateTime time );
+ public abstract int GetMonth ( DateTime time );
+ public virtual int GetMonthsInYear ( int year );
+ public abstract int GetMonthsInYear ( int year, int era );
+ public virtual int GetSecond ( DateTime time );
+ public virtual int GetWeekOfYear ( DateTime time, CalendarWeekRule rule, DayOfWeek firstDayOfWeek );
+ public abstract int GetYear ( DateTime time );
+ public virtual bool IsLeapDay ( int year, int month, int day );
+ public abstract bool IsLeapDay ( int year, int month, int day, int era );
+ public virtual bool IsLeapMonth ( int year, int month );
+ public abstract bool IsLeapMonth ( int year, int month, int era );
+ public virtual bool IsLeapYear ( int year );
+ public abstract bool IsLeapYear ( int year, int era );
+ public virtual DateTime ToDateTime ( int year, int month, int day, int hour, int minute, int second, int millisecond );
+ public abstract DateTime ToDateTime ( int year, int month, int date, int hour, int minute, int second, int millisecond, int era );
+ public virtual int ToFourDigitYear ( int year );
+ }
+}
+
diff --git a/mcs/class/corlib/System.Globalization/ChangeLog b/mcs/class/corlib/System.Globalization/ChangeLog
new file mode 100644
index 00000000000..d029e001544
--- /dev/null
+++ b/mcs/class/corlib/System.Globalization/ChangeLog
@@ -0,0 +1,12 @@
+2001-07-24 Derek Holden <dholden@draper.com>
+
+ * NumberStyles.cs: Added ECMA values for Allow types and default
+ styles.
+
+2001-07-18 Michael Lambert <michaellambert@email.com>
+
+ * DateTimeStyles.cs, NumberStyles.cs: Add.
+
+2001-07-06 Joe Shaw <joe@ximian.com>
+
+ * UnicodeCategory.cs: Added.
diff --git a/mcs/class/corlib/System.Globalization/DateTimeStyles.cs b/mcs/class/corlib/System.Globalization/DateTimeStyles.cs
new file mode 100644
index 00000000000..946288d9648
--- /dev/null
+++ b/mcs/class/corlib/System.Globalization/DateTimeStyles.cs
@@ -0,0 +1,27 @@
+//------------------------------------------------------------------------------
+//
+// System.Globalization.DateTimeStyles.cs
+//
+// Copyright (C) 2001 Michael Lambert, All Rights Reserved
+//
+// Author: Michael Lambert, michaellambert@email.com
+// Created: Thu 07/18/2001
+//
+//------------------------------------------------------------------------------
+
+namespace System.Globalization
+{
+
+
+public enum DateTimeStyles
+{
+ AllowInnerWhite,
+ AllowLeadingWhite,
+ AllowTrailingWhite,
+ AllowWhiteSpaces,
+ NoCurrentDateDefault,
+ None,
+}
+
+
+} // Namespace
diff --git a/mcs/class/corlib/System.Globalization/NumberFormatInfo.cs b/mcs/class/corlib/System.Globalization/NumberFormatInfo.cs
new file mode 100644
index 00000000000..e335ca001bb
--- /dev/null
+++ b/mcs/class/corlib/System.Globalization/NumberFormatInfo.cs
@@ -0,0 +1,691 @@
+//
+// System.Globalization.NumberFormatInfo.cs
+//
+// Author:
+// Derek Holden (dholden@draper.com)
+//
+// (C) Ximian, Inc. http://www.ximian.com
+//
+
+//
+// NumberFormatInfo. One can only assume it is the class gottten
+// back from a GetFormat() method from an IFormatProvider /
+// IFormattable implementer. There are some discrepencies with the
+// ECMA spec and the SDK docs, surprisingly. See my conversation
+// with myself on it at:
+// http://lists.ximian.com/archives/public/mono-list/2001-July/000794.html
+//
+// Other than that this is totally ECMA compliant.
+//
+
+namespace System.Globalization {
+
+ public sealed class NumberFormatInfo : ICloneable, IFormatProvider {
+ private bool readOnly;
+
+ // Currency Related Format Info
+ private int currencyDecimalDigits;
+ private string currencyDecimalSeparator;
+ private string currencyGroupSeparator;
+ private int[] currencyGroupSizes;
+ private int currencyNegativePattern;
+ private int currencyPositivePattern;
+ private string currencySymbol;
+
+ private string naNSymbol;
+ private string negativeInfinitySymbol;
+ private string negativeSign;
+
+ // Number Related Format Info
+ private int numberDecimalDigits;
+ private string numberDecimalSeparator;
+ private string numberGroupSeparator;
+ private int[] numberGroupSizes;
+ private int numberNegativePattern;
+
+ // Percent Related Format Info
+ private int percentDecimalDigits;
+ private string percentDecimalSeparator;
+ private string percentGroupSeparator;
+ private int[] percentGroupSizes;
+ private int percentNegativePattern;
+ private int percentPositivePattern;
+ private string percentSymbol;
+
+ private string perMilleSymbol;
+ private string positiveInfinitySymbol;
+ private string positiveSign;
+
+ public NumberFormatInfo ()
+ {
+ readOnly = false;
+
+ // Currency Related Format Info
+ currencyDecimalDigits = 2;
+ currencyDecimalSeparator = ".";
+ currencyGroupSeparator = ",";
+ currencyGroupSizes = new int[1] { 3 };
+ currencyNegativePattern = 0;
+ currencyPositivePattern = 0;
+ currencySymbol = "$";
+
+ naNSymbol = "NaN";
+ negativeInfinitySymbol = "-Infinity";
+ negativeSign = "-";
+
+ // Number Related Format Info
+ numberDecimalDigits = 2;
+ numberDecimalSeparator = ".";
+ numberGroupSeparator = ",";
+ numberGroupSizes = new int[1] { 3 };
+ numberNegativePattern = 0;
+
+ // Percent Related Format Info
+ percentDecimalDigits = 2;
+ percentDecimalSeparator = ".";
+ percentGroupSeparator = ",";
+ percentGroupSizes = new int[1] { 3 };
+ percentNegativePattern = 0;
+ percentPositivePattern = 0;
+ percentSymbol= "%";
+
+ perMilleSymbol = "\u2030";
+ positiveInfinitySymbol = "Infinity";
+ positiveSign = "+";
+ }
+
+ // =========== Currency Format Properties =========== //
+
+ public int CurrencyDecimalDigits {
+ get {
+ return currencyDecimalDigits;
+ }
+
+ set {
+ if (value < 0 || value > 99)
+ throw new ArgumentOutOfRangeException
+ ("The value specified for the property is less than 0 or greater than 99");
+
+ if (readOnly)
+ throw new InvalidOperationException
+ ("The current instance is read-only and a set operation was attempted");
+
+ currencyDecimalDigits = value;
+ }
+ }
+
+ public string CurrencyDecimalSeparator {
+ get {
+ return currencyDecimalSeparator;
+ }
+
+ set {
+ if (value == null)
+ throw new ArgumentNullException
+ ("The value specified for the property is a null reference");
+
+ if (readOnly)
+ throw new InvalidOperationException
+ ("The current instance is read-only and a set operation was attempted");
+
+ currencyDecimalSeparator = value;
+ }
+ }
+
+
+ public string CurrencyGroupSeparator {
+ get {
+ return currencyGroupSeparator;
+ }
+
+ set {
+ if (value == null)
+ throw new ArgumentNullException
+ ("The value specified for the property is a null reference");
+
+ if (readOnly)
+ throw new InvalidOperationException
+ ("The current instance is read-only and a set operation was attempted");
+
+ currencyGroupSeparator = value;
+ }
+ }
+
+ public int[] CurrencyGroupSizes {
+ get {
+ return currencyGroupSizes;
+ }
+
+ set {
+ if (value == null || value.Length == 0)
+ throw new ArgumentNullException
+ ("The value specified for the property is a null reference");
+
+ if (readOnly)
+ throw new InvalidOperationException
+ ("The current instance is read-only and a set operation was attempted");
+
+ // All elements except last need to be in range 1 - 9, last can be 0.
+ int last = value.Length - 1;
+
+ for (int i = 0; i < last; i++)
+ if (value[i] < 1 || value[i] > 9)
+ throw new ArgumentOutOfRangeException
+ ("One of the elements in the array specified is not between 1 and 9");
+
+ if (value[last] < 0 || value[last] > 9)
+ throw new ArgumentOutOfRangeException
+ ("Last element in the array specified is not between 0 and 9");
+
+ currencyGroupSizes = (int[]) value.Clone();
+ }
+ }
+
+ public int CurrencyNegativePattern {
+ get {
+ // See ECMA NumberFormatInfo page 8
+ return currencyNegativePattern;
+ }
+
+ set {
+ if (value < 0 || value > 15)
+ throw new ArgumentOutOfRangeException
+ ("The value specified for the property is less than 0 or greater than 15");
+
+ if (readOnly)
+ throw new InvalidOperationException
+ ("The current instance is read-only and a set operation was attempted");
+
+ currencyNegativePattern = value;
+ }
+ }
+
+ public int CurrencyPostivePattern {
+ get {
+ // See ECMA NumberFormatInfo page 11
+ return currencyPositivePattern;
+ }
+
+ set {
+ if (value < 0 || value > 3)
+ throw new ArgumentOutOfRangeException
+ ("The value specified for the property is less than 0 or greater than 3");
+
+ if (readOnly)
+ throw new InvalidOperationException
+ ("The current instance is read-only and a set operation was attempted");
+
+ currencyPositivePattern = value;
+ }
+ }
+
+ public string CurrencySymbol {
+ get {
+ return currencySymbol;
+ }
+
+ set {
+ if (value == null)
+ throw new ArgumentNullException
+ ("The value specified for the property is a null reference");
+
+ if (readOnly)
+ throw new InvalidOperationException
+ ("The current instance is read-only and a set operation was attempted");
+
+ currencySymbol = value;
+ }
+ }
+
+ // =========== Static Read-Only Properties =========== //
+
+ public static NumberFormatInfo CurrentInfo {
+ get {
+ // This should be culture specific
+ NumberFormatInfo nfi = new NumberFormatInfo ();
+ nfi.readOnly = true;
+ return nfi;
+ }
+ }
+
+ public static NumberFormatInfo InvariantInfo {
+ get {
+ // This uses invariant info, which is same as in the constructor
+ NumberFormatInfo nfi = new NumberFormatInfo ();
+ nfi.readOnly = true;
+ return nfi;
+ }
+ }
+
+ public bool IsReadOnly {
+ get {
+ return readOnly;
+ }
+ }
+
+
+
+ public string NaNSymbol {
+ get {
+ return naNSymbol;
+ }
+
+ set {
+ if (value == null)
+ throw new ArgumentNullException
+ ("The value specified for the property is a null reference");
+
+ if (readOnly)
+ throw new InvalidOperationException
+ ("The current instance is read-only and a set operation was attempted");
+
+ naNSymbol = value;
+ }
+ }
+
+ public string NegativeInfinitySymbol {
+ get {
+ return negativeInfinitySymbol;
+ }
+
+ set {
+ if (value == null)
+ throw new ArgumentNullException
+ ("The value specified for the property is a null reference");
+
+ if (readOnly)
+ throw new InvalidOperationException
+ ("The current instance is read-only and a set operation was attempted");
+
+ negativeInfinitySymbol = value;
+ }
+ }
+
+ public string NegativeSign {
+ get {
+ return negativeSign;
+ }
+
+ set {
+ if (value == null)
+ throw new ArgumentNullException
+ ("The value specified for the property is a null reference");
+
+ if (readOnly)
+ throw new InvalidOperationException
+ ("The current instance is read-only and a set operation was attempted");
+
+ negativeSign = value;
+ }
+ }
+
+ // =========== Number Format Properties =========== //
+
+ public int NumberDecimalDigits {
+ get {
+ return numberDecimalDigits;
+ }
+
+ set {
+ if (value < 0 || value > 99)
+ throw new ArgumentOutOfRangeException
+ ("The value specified for the property is less than 0 or greater than 99");
+
+ if (readOnly)
+ throw new InvalidOperationException
+ ("The current instance is read-only and a set operation was attempted");
+
+ numberDecimalDigits = value;
+ }
+ }
+
+ public string NumberDecimalSeparator {
+ get {
+ return numberDecimalSeparator;
+ }
+
+ set {
+ if (value == null)
+ throw new ArgumentNullException
+ ("The value specified for the property is a null reference");
+
+ if (readOnly)
+ throw new InvalidOperationException
+ ("The current instance is read-only and a set operation was attempted");
+
+ numberDecimalSeparator = value;
+ }
+ }
+
+
+ public string NumberGroupSeparator {
+ get {
+ return numberGroupSeparator;
+ }
+
+ set {
+ if (value == null)
+ throw new ArgumentNullException
+ ("The value specified for the property is a null reference");
+
+ if (readOnly)
+ throw new InvalidOperationException
+ ("The current instance is read-only and a set operation was attempted");
+
+ numberGroupSeparator = value;
+ }
+ }
+
+ public int[] NumberGroupSizes {
+ get {
+ return numberGroupSizes;
+ }
+
+ set {
+ if (value == null || value.Length == 0)
+ throw new ArgumentNullException
+ ("The value specified for the property is a null reference");
+
+ if (readOnly)
+ throw new InvalidOperationException
+ ("The current instance is read-only and a set operation was attempted");
+
+ // All elements except last need to be in range 1 - 9, last can be 0.
+ int last = value.Length - 1;
+
+ for (int i = 0; i < last; i++)
+ if (value[i] < 1 || value[i] > 9)
+ throw new ArgumentOutOfRangeException
+ ("One of the elements in the array specified is not between 1 and 9");
+
+ if (value[last] < 0 || value[last] > 9)
+ throw new ArgumentOutOfRangeException
+ ("Last element in the array specified is not between 0 and 9");
+
+ numberGroupSizes = (int[]) value.Clone();
+ }
+ }
+
+ public int NumberNegativePattern {
+ get {
+ // See ECMA NumberFormatInfo page 27
+ return numberNegativePattern;
+ }
+
+ set {
+ if (value < 0 || value > 4)
+ throw new ArgumentOutOfRangeException
+ ("The value specified for the property is less than 0 or greater than 15");
+
+ if (readOnly)
+ throw new InvalidOperationException
+ ("The current instance is read-only and a set operation was attempted");
+
+ numberNegativePattern = value;
+ }
+ }
+
+ // =========== Percent Format Properties =========== //
+
+ public int PercentDecimalDigits {
+ get {
+ return percentDecimalDigits;
+ }
+
+ set {
+ if (value < 0 || value > 99)
+ throw new ArgumentOutOfRangeException
+ ("The value specified for the property is less than 0 or greater than 99");
+
+ if (readOnly)
+ throw new InvalidOperationException
+ ("The current instance is read-only and a set operation was attempted");
+
+ percentDecimalDigits = value;
+ }
+ }
+
+ public string PercentDecimalSeparator {
+ get {
+ return percentDecimalSeparator;
+ }
+
+ set {
+ if (value == null)
+ throw new ArgumentNullException
+ ("The value specified for the property is a null reference");
+
+ if (readOnly)
+ throw new InvalidOperationException
+ ("The current instance is read-only and a set operation was attempted");
+
+ percentDecimalSeparator = value;
+ }
+ }
+
+
+ public string PercentGroupSeparator {
+ get {
+ return percentGroupSeparator;
+ }
+
+ set {
+ if (value == null)
+ throw new ArgumentNullException
+ ("The value specified for the property is a null reference");
+
+ if (readOnly)
+ throw new InvalidOperationException
+ ("The current instance is read-only and a set operation was attempted");
+
+ percentGroupSeparator = value;
+ }
+ }
+
+ public int[] PercentGroupSizes {
+ get {
+ return percentGroupSizes;
+ }
+
+ set {
+ if (value == null || value.Length == 0)
+ throw new ArgumentNullException
+ ("The value specified for the property is a null reference");
+
+ if (readOnly)
+ throw new InvalidOperationException
+ ("The current instance is read-only and a set operation was attempted");
+
+ // All elements except last need to be in range 1 - 9, last can be 0.
+ int last = value.Length - 1;
+
+ for (int i = 0; i < last; i++)
+ if (value[i] < 1 || value[i] > 9)
+ throw new ArgumentOutOfRangeException
+ ("One of the elements in the array specified is not between 1 and 9");
+
+ if (value[last] < 0 || value[last] > 9)
+ throw new ArgumentOutOfRangeException
+ ("Last element in the array specified is not between 0 and 9");
+
+ percentGroupSizes = (int[]) value.Clone();
+ }
+ }
+
+ public int PercentNegativePattern {
+ get {
+ // See ECMA NumberFormatInfo page 8
+ return percentNegativePattern;
+ }
+
+ set {
+ if (value < 0 || value > 2)
+ throw new ArgumentOutOfRangeException
+ ("The value specified for the property is less than 0 or greater than 15");
+
+ if (readOnly)
+ throw new InvalidOperationException
+ ("The current instance is read-only and a set operation was attempted");
+
+ percentNegativePattern = value;
+ }
+ }
+
+ public int PercentPostivePattern {
+ get {
+ // See ECMA NumberFormatInfo page 11
+ return percentPositivePattern;
+ }
+
+ set {
+ if (value < 0 || value > 2)
+ throw new ArgumentOutOfRangeException
+ ("The value specified for the property is less than 0 or greater than 3");
+
+ if (readOnly)
+ throw new InvalidOperationException
+ ("The current instance is read-only and a set operation was attempted");
+
+ percentPositivePattern = value;
+ }
+ }
+
+ public string PercentSymbol {
+ get {
+ return percentSymbol;
+ }
+
+ set {
+ if (value == null)
+ throw new ArgumentNullException
+ ("The value specified for the property is a null reference");
+
+ if (readOnly)
+ throw new InvalidOperationException
+ ("The current instance is read-only and a set operation was attempted");
+
+ percentSymbol = value;
+ }
+ }
+
+ public string PerMilleSymbol {
+ get {
+ return perMilleSymbol;
+ }
+
+ set {
+ if (value == null)
+ throw new ArgumentNullException
+ ("The value specified for the property is a null reference");
+
+ if (readOnly)
+ throw new InvalidOperationException
+ ("The current instance is read-only and a set operation was attempted");
+
+ perMilleSymbol = value;
+ }
+ }
+
+ public string PositiveInfinitySymbol {
+ get {
+ return positiveInfinitySymbol;
+ }
+
+ set {
+ if (value == null)
+ throw new ArgumentNullException
+ ("The value specified for the property is a null reference");
+
+ if (readOnly)
+ throw new InvalidOperationException
+ ("The current instance is read-only and a set operation was attempted");
+
+ positiveInfinitySymbol = value;
+ }
+ }
+
+ public string PositiveSign {
+ get {
+ return positiveSign;
+ }
+
+ set {
+ if (value == null)
+ throw new ArgumentNullException
+ ("The value specified for the property is a null reference");
+
+ if (readOnly)
+ throw new InvalidOperationException
+ ("The current instance is read-only and a set operation was attempted");
+
+ positiveSign = value;
+ }
+ }
+
+ public object GetFormat (Type formatType)
+ {
+ // LAMESPEC: ECMA says we implement IFormatProvider, but doesn't define this
+ //
+ // From the .NET Framework SDK
+ //
+ // Parameters: formatType The Type of the formatting service required.
+ //
+ // Return Value: The current instance of the NumberFormatInfo class, if formatType
+ // is the same as the type of the current instance; otherwise, a null reference
+ //
+ // Remarks: This method is invoked by the Format(String, IFormatProvider) method
+ // supported by the base data types when this instance is passed as the
+ // IFormatProvider parameter. It implements IFormatProvider.GetFormat.
+
+ if (formatType.Equals(this)) // LAMESPEC: Should this be IsInstanceOfType?
+ return this;
+ else return null;
+ }
+
+ public object Clone ()
+ {
+ NumberFormatInfo clone = new NumberFormatInfo ();
+
+ clone.readOnly = this.readOnly;
+
+ clone.currencyDecimalDigits = this.currencyDecimalDigits;
+ clone.currencyDecimalSeparator = String.Copy (this.currencyDecimalSeparator);
+ clone.currencyGroupSeparator = String.Copy (this.currencyGroupSeparator);
+ clone.currencyGroupSizes = (int[]) this.currencyGroupSizes.Clone();
+ clone.currencyNegativePattern = this.currencyNegativePattern;
+ clone.currencyPositivePattern = this.currencyPositivePattern;
+ clone.currencySymbol = String.Copy (this.currencySymbol);
+
+ clone.naNSymbol = String.Copy (this.naNSymbol);
+ clone.negativeInfinitySymbol = String.Copy (this.negativeInfinitySymbol);
+ clone.negativeSign = String.Copy (this.negativeSign);
+
+ clone.numberDecimalDigits = this.numberDecimalDigits;
+ clone.numberDecimalSeparator = String.Copy (this.numberDecimalSeparator);
+ clone.numberGroupSeparator = String.Copy (this.numberGroupSeparator);
+ clone.numberGroupSizes = (int[]) this.numberGroupSizes.Clone();
+ clone.numberNegativePattern = this.numberNegativePattern;
+
+ clone.percentDecimalDigits = this.percentDecimalDigits;
+ clone.percentDecimalSeparator = String.Copy (this.percentDecimalSeparator);
+ clone.percentGroupSeparator = String.Copy (this.percentGroupSeparator);
+ clone.percentGroupSizes = (int []) this.percentGroupSizes.Clone();
+ clone.percentNegativePattern = this.percentNegativePattern;
+ clone.percentPositivePattern = this.percentPositivePattern;
+ clone.percentSymbol = String.Copy (this.percentSymbol);
+
+ clone.perMilleSymbol = String.Copy (this.perMilleSymbol);
+ clone.positiveInfinitySymbol = String.Copy (this.positiveInfinitySymbol);
+ clone.positiveSign = String.Copy (this.positiveSign);
+
+ return clone;
+ }
+
+ public static NumberFormatInfo ReadOnly (NumberFormatInfo nfi)
+ {
+ NumberFormatInfo copy = (NumberFormatInfo)nfi.Clone();
+ copy.readOnly = true;
+ return copy;
+ }
+ }
+}
diff --git a/mcs/class/corlib/System.Globalization/NumberStyles.cs b/mcs/class/corlib/System.Globalization/NumberStyles.cs
new file mode 100644
index 00000000000..9d16b716be0
--- /dev/null
+++ b/mcs/class/corlib/System.Globalization/NumberStyles.cs
@@ -0,0 +1,45 @@
+//------------------------------------------------------------------------------
+//
+// System.Globalization.NumberStyles.cs
+//
+// Copyright (C) 2001 Michael Lambert, All Rights Reserved
+//
+// Author: Michael Lambert, michaellambert@email.com
+// Created: Thu 07/18/2001
+//
+// Modified: 7/20/01, Derek Holden (dholden@draper.com)
+// Added ECMA values for allows and masks for data types
+//
+//------------------------------------------------------------------------------
+
+namespace System.Globalization {
+
+ public enum NumberStyles
+ {
+ None = 0x00000000,
+ AllowLeadingWhite = 0x00000001,
+ AllowTrailingWhite = 0x00000002,
+ AllowLeadingSign = 0x00000004,
+ AllowTrailingSign = 0x00000008,
+ AllowParentheses = 0x00000010,
+ AllowDecimalPoint = 0x00000020,
+ AllowThousands = 0x00000040,
+ AllowExponent = 0x00000080,
+ AllowCurrencySymbol = 0x00000100,
+ AllowHexSpecifier = 0x00000200,
+
+ Integer = ( AllowLeadingWhite | AllowTrailingWhite | AllowLeadingSign ),
+ HexNumber = ( AllowLeadingWhite | AllowTrailingWhite | AllowHexSpecifier ),
+ Number = ( AllowLeadingWhite | AllowTrailingWhite | AllowLeadingSign |
+ AllowTrailingSign | AllowDecimalPoint | AllowThousands ),
+ Float = ( AllowLeadingWhite | AllowTrailingWhite | AllowLeadingSign |
+ AllowDecimalPoint | AllowExponent ),
+ Currency = ( AllowLeadingWhite | AllowTrailingWhite | AllowLeadingSign |
+ AllowTrailingSign | AllowParentheses | AllowDecimalPoint |
+ AllowThousands | AllowCurrencySymbol ),
+ Any = ( AllowLeadingWhite | AllowTrailingWhite | AllowLeadingSign |
+ AllowTrailingSign | AllowParentheses | AllowDecimalPoint |
+ AllowThousands | AllowExponent | AllowCurrencySymbol ),
+ }
+
+} // Namespace
diff --git a/mcs/class/corlib/System.Globalization/UnicodeCategory.cs b/mcs/class/corlib/System.Globalization/UnicodeCategory.cs
new file mode 100644
index 00000000000..2cedb95b02d
--- /dev/null
+++ b/mcs/class/corlib/System.Globalization/UnicodeCategory.cs
@@ -0,0 +1,44 @@
+//
+// System.Globalization.UnicodeCategory.cs
+//
+// Author:
+// Joe Shaw (joe@ximian.com)
+//
+// (C) 2001 Ximian, Inc. http://www.ximian.com
+//
+
+namespace System.Globalization {
+
+ public enum UnicodeCategory {
+ UppercaseLetter = 0,
+ LowercaseLetter = 1,
+ TitlecaseLetter = 2,
+ ModifierLetter = 3,
+ OtherLetter = 4,
+ NonSpacingMark = 5,
+ SpaceCombiningMark = 6,
+ EnclosingMark = 7,
+ DecimalDigitNumber = 8,
+ LetterNumber = 9,
+ OtherNumber = 10,
+ SpaceSeperator = 11,
+ LineSeperator = 12,
+ ParagraphSeperator = 13,
+ Control = 14,
+ Format = 15,
+ Surrogate = 16,
+ PrivateUse = 17,
+ ConnectorPunctuation = 18,
+ DashPunctuation = 19,
+ OpenPunctuation = 20,
+ ClosePunctuation = 21,
+ InitialQuotePunctuation = 22,
+ FinalQuotePunctuation = 23,
+ OtherPunctuation = 24,
+ MathSymbol = 25,
+ CurrencySymbol = 26,
+ ModifierSymbol = 27,
+ OtherSymbol = 28,
+ OtherNotAssigned = 29,
+ }
+} \ No newline at end of file
diff --git a/mcs/class/corlib/System.Globalization/common.src b/mcs/class/corlib/System.Globalization/common.src
new file mode 100755
index 00000000000..5fc9299f05d
--- /dev/null
+++ b/mcs/class/corlib/System.Globalization/common.src
@@ -0,0 +1,3 @@
+DateTimeStyles.cs
+NumberStyles.cs
+UnicodeCategory.cs
diff --git a/mcs/class/corlib/System.Globalization/unix.src b/mcs/class/corlib/System.Globalization/unix.src
new file mode 100755
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/mcs/class/corlib/System.Globalization/unix.src
diff --git a/mcs/class/corlib/System.Globalization/windows.src b/mcs/class/corlib/System.Globalization/windows.src
new file mode 100755
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/mcs/class/corlib/System.Globalization/windows.src
diff --git a/mcs/class/corlib/System.IO/ChangeLog b/mcs/class/corlib/System.IO/ChangeLog
new file mode 100644
index 00000000000..131c4bbe600
--- /dev/null
+++ b/mcs/class/corlib/System.IO/ChangeLog
@@ -0,0 +1,18 @@
+2001-07-18 Michael Lambert <michaellambert@email.com>
+
+ *SeekOrigin.cs.cs, FileShare.cs, FileMode.cs, FileAccess.cs: Add.
+
+2001-07-19 Marcin Szczepanski <marcins@zipworld.com.au>
+
+ * System.IO.MemoryStream.cs: Added. Had quite a few cases of
+ "LAMESPEC", but the tests work against the MS implementation so
+ the major functions are right (ie. Read/Write/Seek). Some more
+ tests required for the various constructors and exceptions.
+
+2001-07-16 Marcin Szczepanski <marcins@zipworld.com.au>
+
+ * StringReader.cs, StringWriter.cs, TextReader.cs, TextWriter.cs:
+ New class implemenations.
+
+ * StringReaderTest.cs, StringWriterTest.cs: Test suite for the above.
+
diff --git a/mcs/class/corlib/System.IO/Directory.cs b/mcs/class/corlib/System.IO/Directory.cs
new file mode 100644
index 00000000000..28665809cb2
--- /dev/null
+++ b/mcs/class/corlib/System.IO/Directory.cs
@@ -0,0 +1,173 @@
+//------------------------------------------------------------------------------
+//
+// System.IO.Directory.cs
+//
+// Copyright (C) 2001 Moonlight Enterprises, All Rights Reserved
+//
+// Author: Jim Richardson, develop@wtfo-guru.com
+// Created: Monday, August 13, 2001
+//
+//------------------------------------------------------------------------------
+
+using System;
+
+namespace System.IO
+{
+ /// <summary>
+ ///
+ /// </summary>
+ public sealed class Directory : Object
+ {
+
+ /// <summary>
+ /// Creates all directories not existing in path
+ /// </summary>
+ public static DirectoryInfo CreateDirectory(string path)
+ {
+ return null;
+ }
+ /// <summary>
+ /// Delete an empty directory
+ /// </summary>
+ public static void Delete(string path)
+ {
+ }
+ /// <summary>
+ /// Delete a directory, and contents if bRecurse is true
+ /// </summary>
+ public static void Delete(string path, bool bRecurse)
+ {
+ }
+ /// <summary>
+ /// Returns true if directory exists on disk
+ /// </summary>
+ public static bool Exists(string path)
+ {
+ return false;
+ }
+ /// <summary>
+ /// Returns the date and time the directory specified by path was created
+ /// </summary>
+ public static DateTime GetCreationTime(string path)
+ {
+ return DateTime.MinValue;
+ }
+ /// <summary>
+ /// Returns the date and time the directory specified by path was created
+ /// </summary>
+ public static string GetCurrentDirectory()
+ {
+ return null;
+ }
+ /// <summary>
+ /// Returns an array of directories in the directory specified by path
+ /// </summary>
+ public static string[] GetDirectories(string path)
+ {
+ return null;
+ }
+ /// <summary>
+ /// Returns an array of directories in the directory specified by path
+ /// matching the filter specified by mask
+ /// </summary>
+ public static string[] GetDirectories(string path, string mask)
+ {
+ return null;
+ }
+ /// <summary>
+ /// Returns the root of the specified path
+ /// </summary>
+ public static string GetDirectoryRoot(string path)
+ {
+ return null;
+ }
+ /// <summary>
+ /// Returns an array of files in the directory specified by path
+ /// </summary>
+ public static string[] GetFiles(string path)
+ {
+ return null;
+ }
+ /// <summary>
+ /// Returns an array of files in the directory specified by path
+ /// matching the filter specified by mask
+ /// </summary>
+ public static string[] GetFiles(string path, string mask)
+ {
+ return null;
+ }
+ /// <summary>
+ /// Returns an array of filesystementries in the directory specified by path
+ /// </summary>
+ public static string[] GetFileSystemEntries(string path)
+ {
+ return null;
+ }
+ /// <summary>
+ /// Returns an array of filesystementries in the directory specified by path
+ /// matching the filter specified by mask
+ /// </summary>
+ public static string[] GetFileSystemEntries(string path, string mask)
+ {
+ return null;
+ }
+ /// <summary>
+ /// Returns the date and time the directory specified by path was last accessed
+ /// </summary>
+ public static DateTime GetLastAccessTime(string path)
+ {
+ return DateTime.MinValue;
+ }
+ /// <summary>
+ /// Returns the date and time the directory specified by path was last modified
+ /// </summary>
+ public static DateTime GetLastWriteTime(string path)
+ {
+ return DateTime.MinValue;
+ }
+ /// <summary>
+ /// Returns an array of logical drives on this system
+ /// </summary>
+ public static string[] GetLogicalDrives()
+ {
+ return null;
+ }
+ /// <summary>
+ /// Returns the parent directory of the directory specified by path
+ /// </summary>
+ public static DirectoryInfo GetParent(string path)
+ {
+ return null;
+ }
+ /// <summary>
+ /// Moves a directory and its contents
+ /// </summary>
+ public static void Move(string srcDirName, string destDirName)
+ {
+ }
+ /// <summary>
+ /// Sets the creation time of the directory specified by path
+ /// </summary>
+ public static void SetCreationTime(string path, DateTime creationTime)
+ {
+ }
+ /// <summary>
+ /// Sets the current directory to the directory specified by path
+ /// </summary>
+ public static void SetCurrentDirectory(string path)
+ {
+ }
+ /// <summary>
+ /// Sets the last access time of the directory specified by path
+ /// </summary>
+ public static void SetLastAccessTime(string path, DateTime accessTime)
+ {
+ }
+ /// <summary>
+ /// Sets the last write time of the directory specified by path
+ /// </summary>
+ public static void SetLastWriteTime(string path, DateTime modifiedTime)
+ {
+ }
+ }
+}
diff --git a/mcs/class/corlib/System.IO/DirectoryInfo.cs b/mcs/class/corlib/System.IO/DirectoryInfo.cs
new file mode 100644
index 00000000000..eae327bb9c8
--- /dev/null
+++ b/mcs/class/corlib/System.IO/DirectoryInfo.cs
@@ -0,0 +1,128 @@
+//------------------------------------------------------------------------------
+//
+// System.IO.DirectoryInfo.cs
+//
+// Copyright (C) 2001 Moonlight Enterprises, All Rights Reserved
+//
+// Author: Jim Richardson, develop@wtfo-guru.com
+// Created: Monday, August 13, 2001
+//
+//------------------------------------------------------------------------------
+
+using System;
+
+namespace System.IO
+{
+ /// <summary>
+ ///
+ /// </summary>
+ public sealed class DirectoryInfo : FileSystemInfo
+ {
+
+ public DirectoryInfo()
+ {
+ //
+ // TODO: Add constructor logic here
+ //
+ }
+
+ public override bool Exists
+ {
+ get
+ {
+ return false;
+ }
+ }
+
+ public override string Name
+ {
+ get
+ { //TODO: Implement this as per the documenation
+ return FullPath;
+ }
+ }
+
+ public DirectoryInfo Root
+ {
+ get
+ {
+ return null;
+ }
+ }
+
+ public void Create()
+ {
+ }
+
+ DirectoryInfo CreateSubdirectory(string path)
+ {
+ return null;
+ }
+
+ public override void Delete()
+ {
+ Directory.Delete(FullPath);
+ }
+
+ public void Delete(bool bRecurse)
+ {
+ Directory.Delete(FullPath, bRecurse);
+ }
+
+ /// <summary>
+ /// Returns an array of DirectoryInfos for subdirectories
+ /// </summary>
+ public DirectoryInfo[] GetDirectories()
+ {
+ return null;
+ }
+ /// <summary>
+ /// Returns an array of DirectoryInfos
+ /// matching the filter specified by mask
+ /// </summary>
+ public static DirectoryInfo[] GetDirectories(string mask)
+ {
+ return null;
+ }
+ /// <summary>
+ /// Returns an array of FileInfo for subdirectories
+ /// </summary>
+ public FileInfo[] GetFiles()
+ {
+ return null;
+ }
+ /// <summary>
+ /// Returns an array of FileInfo
+ /// matching the filter specified by mask
+ /// </summary>
+ public static FileInfo[] GetFiles(string mask)
+ {
+ return null;
+ }
+ /// <summary>
+ /// Returns an array of FileSystemInfo for subdirectories
+ /// </summary>
+ public FileSystemInfo[] GetFileSystemInfos()
+ {
+ return null;
+ }
+ /// <summary>
+ /// Returns an array of FileSystemInfo
+ /// matching the filter specified by mask
+ /// </summary>
+ public static FileSystemInfo[] GetFileSystemInfos(string mask)
+ {
+ return null;
+ }
+
+ public void MoveTo(string destDirName)
+ {
+ Directory.Move(FullName, destDirName);
+ }
+
+ public override string ToString()
+ {
+ return FullName;
+ }
+ }
+}
diff --git a/mcs/class/corlib/System.IO/FileAccess.cs b/mcs/class/corlib/System.IO/FileAccess.cs
new file mode 100644
index 00000000000..c89c4aa3ccd
--- /dev/null
+++ b/mcs/class/corlib/System.IO/FileAccess.cs
@@ -0,0 +1,22 @@
+//------------------------------------------------------------------------------
+//
+// System.IO.FileAccess.cs
+//
+// Copyright (C) 2001 Michael Lambert, All Rights Reserved
+//
+// Author: Michael Lambert, michaellambert@email.com
+// Created: Thu 07/18/2001
+//
+//------------------------------------------------------------------------------
+
+namespace System.IO
+{
+
+public enum FileAccess
+{
+ Read,
+ ReadWrite,
+ Write,
+}
+
+} // Namespace
diff --git a/mcs/class/corlib/System.IO/FileAttributes.cs b/mcs/class/corlib/System.IO/FileAttributes.cs
new file mode 100644
index 00000000000..1d712e614ac
--- /dev/null
+++ b/mcs/class/corlib/System.IO/FileAttributes.cs
@@ -0,0 +1,33 @@
+//------------------------------------------------------------------------------
+//
+// System.IO.FileAttributes.cs
+//
+// Copyright (C) 2001 Moonlight Enterprises, All Rights Reserved
+//
+// Author: Jim Richardson, develop@wtfo-guru.com
+// Created: Monday, August 13, 2001
+//
+//------------------------------------------------------------------------------
+
+
+namespace System.IO
+{
+ public enum FileAttributes
+ {
+ Archive,
+ Compressed,
+ Device, // Reserved for future use.
+ Directory,
+ Encrypted,
+ Hidden,
+ Normal,
+ NotContentIndexed,
+ Offline,
+ ReadOnly,
+ ReparsePoint,
+ SparseFile,
+ System,
+ Temporary
+ }
+
+} \ No newline at end of file
diff --git a/mcs/class/corlib/System.IO/FileInfo.cs b/mcs/class/corlib/System.IO/FileInfo.cs
new file mode 100644
index 00000000000..89ee1fe797b
--- /dev/null
+++ b/mcs/class/corlib/System.IO/FileInfo.cs
@@ -0,0 +1,142 @@
+//------------------------------------------------------------------------------
+//
+// System.IO.FileInfo.cs
+//
+// Copyright (C) 2001 Moonlight Enterprises, All Rights Reserved
+//
+// Author: Jim Richardson, develop@wtfo-guru.com
+// Created: Monday, August 13, 2001
+//
+//------------------------------------------------------------------------------
+
+using System;
+
+namespace System.IO
+{
+ /// <summary>
+ ///
+ /// </summary>
+ public sealed class FileInfo : FileSystemInfo
+ {
+ public FileInfo()
+ {
+ //
+ // TODO: Add constructor logic here
+ //
+ }
+
+ public override bool Exists
+ {
+ get
+ {
+ return false;
+ }
+ }
+
+ public override string Name
+ {
+ get
+ { //TODO: Implement this as per the documenation
+ return FullPath;
+ }
+ }
+
+ /// <summary>
+ /// Gets the parent directory info
+ /// </summary>
+ public DirectoryInfo Directory
+ {
+ get
+ {
+ return null;
+ }
+ }
+
+ /// <summary>
+ /// Get the path of the file
+ /// </summary>
+ public string DirectoryName
+ {
+ get
+ {
+ return null;
+ }
+ }
+
+ /// <summary>
+ /// Get the length of the file
+ /// </summary>
+ public long Length
+ {
+ get
+ {
+ return 0;
+ }
+ }
+
+ /* TODO: Uncomment / implement as classes become available
+ public StreamWriter AppendText()
+ {
+ }
+
+
+ public FileStream Create()
+ {
+ return null;
+ }
+
+ public StreamWriter CreateText()
+ {
+ return null;
+ }
+
+ public FileStream Open(FileMode mode)
+ {
+ return Open(mode, FileAccess.ReadWrite);
+ }
+
+ public FileStream Open(FileMode mode, FileAccess access)
+ {
+ return Open(mode, access, FileShare.None);
+ }
+
+ public FileStream Open(FileMode mode, FileAccess access, FileShare share)
+ {
+ return null;
+ }
+
+ public FileStream OpenRead()
+ { // TODO: find out what default share should be
+ return Open(FileMode.Open, FileAccess.Read, FileShare.Read);
+ }
+
+ public StreamReader OpenText()
+ {
+ return null;
+ }
+
+ public FileStream OpenWrite()
+ {
+ return Open(FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None);
+ }
+ */
+
+ public FileInfo CopyTo(string destFile)
+ {
+ return CopyTo(destFile, false);
+ }
+
+ public FileInfo CopyTo(string destFile, bool bOverwrite)
+ {
+ return null;
+ }
+
+ public override void Delete()
+ {
+ }
+
+ public void MoveTo(string destName)
+ {
+ }
+ }
+}
diff --git a/mcs/class/corlib/System.IO/FileMode.cs b/mcs/class/corlib/System.IO/FileMode.cs
new file mode 100644
index 00000000000..334b9564fa9
--- /dev/null
+++ b/mcs/class/corlib/System.IO/FileMode.cs
@@ -0,0 +1,25 @@
+//------------------------------------------------------------------------------
+//
+// System.IO.FileMode.cs
+//
+// Copyright (C) 2001 Michael Lambert, All Rights Reserved
+//
+// Author: Michael Lambert, michaellambert@email.com
+// Created: Thu 07/18/2001
+//
+//------------------------------------------------------------------------------
+
+namespace System.IO
+{
+
+public enum FileMode
+{
+ Append,
+ Create,
+ CreateNew,
+ Open,
+ OpenOrCreate,
+ Truncate,
+}
+
+} // Namespace
diff --git a/mcs/class/corlib/System.IO/FileShare.cs b/mcs/class/corlib/System.IO/FileShare.cs
new file mode 100644
index 00000000000..50a255612b7
--- /dev/null
+++ b/mcs/class/corlib/System.IO/FileShare.cs
@@ -0,0 +1,23 @@
+//------------------------------------------------------------------------------
+//
+// System.IO.FileShare.cs
+//
+// Copyright (C) 2001 Michael Lambert, All Rights Reserved
+//
+// Author: Michael Lambert, michaellambert@email.com
+// Created: Thu 07/18/2001
+//
+//------------------------------------------------------------------------------
+
+namespace System.IO
+{
+
+public enum FileShare
+{
+ None,
+ Read,
+ ReadWrite,
+ Write,
+}
+
+} // Namespace
diff --git a/mcs/class/corlib/System.IO/FileStream.cs b/mcs/class/corlib/System.IO/FileStream.cs
new file mode 100644
index 00000000000..12df5f5ad0d
--- /dev/null
+++ b/mcs/class/corlib/System.IO/FileStream.cs
@@ -0,0 +1,242 @@
+//
+// System.IO/FileStream.cs
+//
+// Author:
+// Dietmar Maurer (dietmar@ximian.com)
+//
+// (C) 2001 Ximian, Inc. http://www.ximian.com
+//
+using System;
+using System.Runtime.InteropServices;
+using Unix;
+
+// fixme: I do not know how to handle errno when calling PInvoke functions
+// fixme: emit the correct exceptions everywhere
+
+namespace System.IO
+{
+
+ class FileStream : Stream
+ {
+
+ private IntPtr fd;
+ private FileAccess acc;
+ private bool owner;
+
+ private int getUnixFlags (FileMode mode, FileAccess access)
+ {
+ int flags = 0;
+
+ switch (access) {
+ case FileAccess.Read:
+ flags = Wrapper.O_RDONLY;
+ break;
+ case FileAccess.Write:
+ flags = Wrapper.O_WRONLY;
+ break;
+ case FileAccess.ReadWrite:
+ flags = Wrapper.O_RDWR;
+ break;
+ }
+
+ switch (mode) {
+ case FileMode.Append:
+ flags |= Wrapper.O_APPEND;
+ break;
+ case FileMode.Create:
+ flags |= Wrapper.O_CREAT;
+ break;
+ case FileMode.CreateNew:
+ flags |= Wrapper.O_CREAT | Wrapper.O_EXCL;
+ break;
+ case FileMode.Open:
+ break;
+ case FileMode.OpenOrCreate:
+ flags |= Wrapper.O_CREAT;
+ break;
+ case FileMode.Truncate:
+ flags |= Wrapper.O_TRUNC;
+ break;
+ }
+
+ return flags;
+ }
+
+ public FileStream (IntPtr fd, FileAccess access)
+ : this (fd, access, true, 0, false) {}
+
+ public FileStream (IntPtr fd, FileAccess access, bool ownsHandle)
+ : this (fd, access, ownsHandle, 0, false) {}
+
+ public FileStream (IntPtr fd, FileAccess access, bool ownsHandle, int bufferSize)
+ : this (fd, access, ownsHandle, bufferSize, false) {}
+
+ public FileStream (IntPtr fd, FileAccess access, bool ownsHandle,
+ int bufferSize, bool isAsync)
+ {
+ fd = fd;
+ acc = access;
+ owner = ownsHandle;
+ }
+
+ public FileStream (string name, FileMode mode)
+ : this (name, mode, FileAccess.ReadWrite, FileShare.ReadWrite, 0, false) {}
+
+ public FileStream (string name, FileMode mode, FileAccess access)
+ : this (name, mode, access, FileShare.ReadWrite, 0, false) {}
+
+ public FileStream (string name, FileMode mode, FileAccess access, FileShare share)
+ : this (name, mode, access, share, 0, false) {}
+
+ public FileStream (string name, FileMode mode, FileAccess access,
+ FileShare share, int buferSize)
+ : this (name, mode, access, share, 0, false) {}
+
+ // fixme: implement all share, buffer, async
+ public FileStream (string name, FileMode mode, FileAccess access, FileShare share,
+ int buferSize, bool useAsync)
+ {
+ int flags = getUnixFlags (mode, access);
+
+ if ((int)(fd = Wrapper.open (name, flags, 0x1a4)) == -1)
+ throw new IOException();
+
+ acc = access;
+ owner = true;
+ }
+
+ public override bool CanRead
+ {
+ get {
+ switch (acc) {
+ case FileAccess.Read:
+ case FileAccess.ReadWrite:
+ return true;
+ case FileAccess.Write:
+ default:
+ return false;
+ }
+ }
+ }
+
+ public override bool CanSeek
+ {
+ get {
+ // fixme: not alway true
+ return true;
+ }
+ }
+
+ public override bool CanWrite
+ {
+ get {
+ switch (acc) {
+ case FileAccess.Write:
+ case FileAccess.ReadWrite:
+ return true;
+ default:
+ return false;
+ }
+ }
+ }
+
+ unsafe public override long Length
+ {
+ get {
+ stat fs;
+
+ Wrapper.fstat (fd, &fs);
+ return fs.st_size;
+ }
+ }
+
+ public override long Position
+ {
+ get {
+ return Wrapper.seek (fd, 0, Wrapper.SEEK_CUR);
+ }
+ set {
+ Wrapper.seek (fd, value, Wrapper.SEEK_SET);
+ }
+ }
+
+ public override void Flush ()
+ {
+ }
+
+ public override void Close ()
+ {
+ if (owner && Wrapper.close (fd) != 0)
+ throw new IOException();
+ }
+
+ public unsafe override int Read (byte[] buffer,
+ int offset,
+ int count)
+ {
+ int res;
+
+ fixed (void *p = &buffer [offset]) {
+ res = Wrapper.read (fd, p, count);
+ }
+
+ return res;
+ }
+
+ public unsafe override int ReadByte ()
+ {
+ byte val;
+
+ if (Wrapper.read (fd, &val, 1) != 1)
+ throw new IOException();
+
+ return val;
+ }
+
+ public override long Seek (long offset,
+ SeekOrigin origin)
+ {
+ int off = (int)offset;
+
+ switch (origin) {
+ case SeekOrigin.End:
+ return Wrapper.seek (fd, Wrapper.SEEK_END, off);
+ case SeekOrigin.Current:
+ return Wrapper.seek (fd, Wrapper.SEEK_CUR, off);
+ default:
+ return Wrapper.seek (fd, Wrapper.SEEK_SET, off);
+ }
+ }
+
+ public override void SetLength (long value)
+ {
+ int res;
+
+ if ((res = Wrapper.ftruncate (fd, value)) == -1)
+ throw new IOException();
+
+
+ }
+
+ public unsafe override void Write (byte[] buffer,
+ int offset,
+ int count)
+ {
+ int res;
+
+ fixed (void *p = &buffer [offset]) {
+ res = Wrapper.write (fd, p, count);
+ }
+
+ if (res != count)
+ throw new IOException();
+ }
+
+ public unsafe override void WriteByte (byte value)
+ {
+ if (Wrapper.write (fd, &value, 1) != 1)
+ throw new IOException();
+ }
+
+ }
+}
diff --git a/mcs/class/corlib/System.IO/FileSystemInfo.cs b/mcs/class/corlib/System.IO/FileSystemInfo.cs
new file mode 100644
index 00000000000..f339f954e03
--- /dev/null
+++ b/mcs/class/corlib/System.IO/FileSystemInfo.cs
@@ -0,0 +1,135 @@
+//------------------------------------------------------------------------------
+//
+// System.IO.FileSystemInfo.cs
+//
+// Copyright (C) 2001 Moonlight Enterprises, All Rights Reserved
+//
+// Author: Jim Richardson, develop@wtfo-guru.com
+// Created: Monday, August 13, 2001
+//
+//------------------------------------------------------------------------------
+
+using System;
+
+namespace System.IO
+{
+ /// <summary>
+ ///
+ /// </summary>
+ public abstract class FileSystemInfo : MarshalByRefObject
+ {
+ private FileAttributes itsAttributes;
+ private DateTime itsCreated;
+ private DateTime itsLastAccess;
+ private DateTime itsLastWrite;
+ //private string itsFullName;
+ protected string FullPath;
+ protected string OriginalPath;
+
+ public FileSystemInfo()
+ {
+ //
+ // TODO: Add constructor logic here
+ //
+ }
+
+ public FileAttributes Attributes
+ {
+ get
+ {
+ return itsAttributes;
+ }
+ set
+ {
+ itsAttributes = value;
+ }
+ }
+
+ public DateTime CreationTime
+ {
+ get
+ {
+ return itsCreated;
+ }
+ set
+ {
+ itsCreated = value;
+ }
+ }
+
+ public abstract bool Exists {get;}
+ public abstract string Name {get;}
+ public abstract void Delete();
+
+ /// <summary>
+ /// Get the extension of this item
+ /// </summary>
+ public string Extension
+ {
+ get
+ {
+ return Path.GetExtension(FullPath);
+ }
+ }
+
+ public string FullName
+ {
+ get
+ {
+ return FullPath;
+ }
+ }
+
+ public DateTime LastAccessTime
+ {
+ get
+ {
+ return itsLastAccess;
+ }
+ }
+
+ public DateTime LastWriteTime
+ {
+ get
+ {
+ return itsLastWrite;
+ }
+ }
+
+ public override int GetHashCode()
+ {
+ return FullPath.GetHashCode();
+ }
+
+ public override bool Equals(object obj)
+ {
+ return false;
+ }
+
+ new public static bool Equals(object obj1, object obj2)
+ {
+ return false;
+ }
+
+ public void Refresh()
+ {
+ }
+
+ /* TODO: determine if we need these
+ public override ObjRef CreateObjRef(Type requestedType)
+ {
+ return null;
+ }
+
+ /*public object GetLifeTimeService ()
+ {
+ return null;
+ }
+
+ public override object InitializeLifeTimeService ()
+ {
+ return null;
+ }
+ */
+ }
+}
diff --git a/mcs/class/corlib/System.IO/MemoryStream.cs b/mcs/class/corlib/System.IO/MemoryStream.cs
new file mode 100644
index 00000000000..ce2a5e9c82a
--- /dev/null
+++ b/mcs/class/corlib/System.IO/MemoryStream.cs
@@ -0,0 +1,403 @@
+//
+// System.IO.MemoryStream
+//
+// Author: Marcin Szczepanski (marcins@zipworld.com.au)
+//
+// TODO: Clarify some of the lamespec issues
+//
+
+namespace System.IO {
+ public class MemoryStream : Stream {
+ private bool canRead;
+ private bool canSeek;
+ private bool canWrite;
+
+ private bool allowGetBuffer;
+
+ private int capacity;
+
+ private byte[] internalBuffer;
+
+ private int initialLength;
+ private bool expandable;
+
+ private bool streamClosed = false;
+
+ private long position = 0;
+
+ public MemoryStream() {
+ canRead = true;
+ canSeek = true;
+ canWrite = true;
+
+ capacity = 0;
+
+ internalBuffer = new byte[0];
+
+ allowGetBuffer = true;
+ expandable = true;
+ }
+
+ public MemoryStream( byte[] buffer ) {
+ InternalConstructor( buffer, 0, buffer.Length, true, false );
+ }
+
+ public MemoryStream( int capacity ) {
+
+ canRead = true;
+ canSeek = true;
+ canWrite = true;
+
+ this.capacity = capacity;
+ initialLength = capacity;
+ internalBuffer = new byte[ capacity ];
+
+ expandable = true;
+ allowGetBuffer = true;
+ }
+
+ public MemoryStream( byte[] buffer, bool writeable ) {
+ if( buffer == null ) {
+ throw new ArgumentNullException();
+ }
+
+ InternalConstructor( buffer, 0, buffer.Length, writeable, true );
+
+ }
+
+ public MemoryStream( byte[] buffer, int index, int count ) {
+ if( buffer == null ) {
+ throw new ArgumentNullException();
+ }
+
+ InternalConstructor( buffer, index, count, true, false );
+ }
+
+ public MemoryStream( byte[] buffer, int index, int count, bool writeable ) {
+
+ if( buffer == null ) {
+ throw new ArgumentNullException();
+ }
+
+ InternalConstructor( buffer, index, count, writeable, true );
+ }
+
+ public MemoryStream( byte[] buffer, int index, int count, bool writeable, bool publicallyVisible ) {
+ InternalConstructor( buffer, index, count, writeable, publicallyVisible );
+ }
+
+ private void InternalConstructor( byte[] buffer, int index, int count, bool writeable, bool publicallyVisible ) {
+
+ if( buffer == null ) {
+ throw new ArgumentNullException();
+ } else if ( index < 0 || count < 0 ) {
+ throw new ArgumentOutOfRangeException();
+ } else if ( buffer.Length - index < count ) {
+ throw new ArgumentException();
+ }
+
+ // LAMESPEC: The spec says to throw an UnauthorisedAccessException if
+ // publicallyVisibile is fale?! Doesn't that defy the point of having
+ // it there in the first place. I'll leave it out for now.
+
+ canRead = true;
+ canSeek = true;
+ canWrite = writeable;
+
+ initialLength = count;
+
+ internalBuffer = new byte[ count ];
+ capacity = count;
+
+ Array.Copy( buffer, index, internalBuffer, 0, count );
+
+ allowGetBuffer = publicallyVisible;
+ expandable = false;
+ }
+
+ public override bool CanRead {
+ get {
+ return this.canRead;
+ }
+ }
+
+ public override bool CanSeek {
+ get {
+ return this.canSeek;
+ }
+ }
+
+ public override bool CanWrite {
+ get {
+ return this.canWrite;
+ }
+ }
+
+ public virtual int Capacity {
+ get {
+ return this.capacity;
+ }
+
+ set {
+ if( value < 0 || value < capacity ) {
+ throw new ArgumentOutOfRangeException( "New capacity cannot be negative or less than the current capacity" );
+ } else if( !expandable ) {
+ throw new NotSupportedException( "Cannot expand this MemoryStream" );
+ }
+
+ byte[] newBuffer = new byte[ value ];
+ Array.Copy( internalBuffer, 0, newBuffer, 0, capacity );
+ capacity = value;
+ }
+ }
+
+ public override long Length {
+ get {
+ // LAMESPEC: The spec says to throw an IOException if the
+ // stream is closed and an ObjectDisposedException if
+ // "methods were called after the stream was closed". What
+ // is the difference?
+
+ if( streamClosed ) {
+ throw new IOException( "MemoryStream is closed" );
+ }
+
+ return internalBuffer.Length;
+ }
+ }
+
+ public override long Position {
+ get {
+ if( streamClosed ) {
+ throw new IOException( "MemoryStream is closed" );
+ }
+
+ return position;
+ }
+
+ set {
+
+ if( position < 0 ) {
+ throw new ArgumentOutOfRangeException( "Position cannot be negative" );
+ } else if( streamClosed ) {
+ throw new IOException( "MemoryStream is closed" );
+ }
+
+ position = value;
+
+ if( position > internalBuffer.Length + 1 ) {
+ position = internalBuffer.Length + 1;
+ }
+ }
+ }
+
+ public override void Close() {
+ if( streamClosed ) {
+ throw new IOException( "MemoryStream already closed" );
+ }
+
+ streamClosed = true;
+ Dispose( true );
+ }
+
+ protected override void Dispose( bool disposing ) { }
+
+ public override void Flush() { }
+
+ public virtual byte[] GetBuffer() {
+ if( !allowGetBuffer ) {
+ throw new UnauthorizedAccessException();
+ }
+
+ return internalBuffer;
+ }
+
+ public override int Read( byte[] buffer, int offset, int count ) {
+ if( buffer == null ) {
+ throw new ArgumentNullException();
+ } else if( offset < 0 || count < 0 ) {
+ throw new ArgumentOutOfRangeException();
+ } else if( internalBuffer.Length - offset < count ) {
+ throw new ArgumentException();
+ } else if ( streamClosed ) {
+ throw new ObjectDisposedException( "MemoryStream" );
+ }
+
+ long ReadTo;
+
+ if( position + count > internalBuffer.Length ) {
+ ReadTo = internalBuffer.Length;
+ } else {
+ ReadTo = position + (long)count;
+ }
+
+ Array.Copy( internalBuffer, (int)position, buffer, offset, (int)(ReadTo - position) );
+
+ int bytesRead = (int)(ReadTo - position);
+
+ position = ReadTo;
+
+ return bytesRead;
+ }
+
+ public override int ReadByte( ) {
+ if( streamClosed ) {
+ throw new ObjectDisposedException( "MemoryStream" );
+ }
+
+
+ // LAMESPEC: What happens if we're at the end of the stream? It's unspecified in the
+ // docs but tests against the MS impl. show it returns -1
+ //
+
+ if( position >= internalBuffer.Length ) {
+ return -1;
+ } else {
+ return internalBuffer[ position++ ];
+ }
+ }
+
+ public override long Seek( long offset, SeekOrigin loc ) {
+ long refPoint;
+
+ if( streamClosed ) {
+ throw new ObjectDisposedException( "MemoryStream" );
+ }
+
+ switch( loc ) {
+ case SeekOrigin.Begin:
+ refPoint = 0;
+ break;
+ case SeekOrigin.Current:
+ refPoint = position;
+ break;
+ case SeekOrigin.End:
+ refPoint = internalBuffer.Length;
+ break;
+ default:
+ throw new ArgumentException( "Invalid SeekOrigin" );
+ }
+
+ // LAMESPEC: My goodness, how may LAMESPECs are there in this
+ // class! :) In the spec for the Position property it's stated
+ // "The position must not be more than one byte beyond the end of the stream."
+ // In the spec for seek it says "Seeking to any location beyond the length of the
+ // stream is supported." That's a contradiction i'd say.
+ // I guess seek can go anywhere but if you use position it may get moved back.
+
+ if( refPoint + offset < 0 ) {
+ throw new IOException( "Attempted to seek before start of MemoryStream" );
+ } else if( offset > internalBuffer.Length ) {
+ throw new ArgumentOutOfRangeException( "Offset cannot be greater than length of MemoryStream" );
+ }
+
+ position = refPoint + offset;
+
+ return position;
+ }
+
+
+ public override void SetLength( long value ) {
+ if( streamClosed ) {
+ throw new ObjectDisposedException( "MemoryStream" );
+ } else if( !expandable && value > capacity ) {
+ throw new NotSupportedException( "Expanding this MemoryStream is not supported" );
+ } else if( !canWrite ) {
+ throw new IOException( "Cannot write to this MemoryStream" );
+ } else if( value < 0 ) {
+
+ // LAMESPEC: AGAIN! It says to throw this exception if value is
+ // greater than "the maximum length of the MemoryStream". I haven't
+ // seen anywhere mention what the maximum length of a MemoryStream is and
+ // since we're this far this memory stream is expandable.
+
+ throw new ArgumentOutOfRangeException();
+ }
+
+ byte[] newBuffer;
+ newBuffer = new byte[ value ];
+
+ if( value < capacity ) {
+ // truncate
+ Array.Copy( internalBuffer, 0, newBuffer, 0, (int)value );
+ } else {
+ // expand
+ Array.Copy( internalBuffer, 0, newBuffer, 0, internalBuffer.Length );
+ }
+ internalBuffer = newBuffer;
+ capacity = (int)value;
+
+ }
+
+
+ public virtual byte[] ToArray() {
+
+ if( streamClosed ) {
+ throw new ArgumentException( "The MemoryStream has been closed" );
+ }
+
+ byte[] outBuffer = new byte[capacity];
+ Array.Copy( internalBuffer, 0, outBuffer, 0, capacity);
+ return outBuffer;
+ }
+
+ // LAMESPEC: !! It says that "offset" is "offset in buffer at which
+ // to begin writing", I presume this should be "offset in buffer at which
+ // to begin reading"
+
+ public override void Write( byte[] buffer, int offset, int count ) {
+ if( buffer == null ) {
+ throw new ArgumentNullException();
+ } else if( !canWrite ) {
+ throw new NotSupportedException();
+ } else if( buffer.Length - offset < count ) {
+ throw new ArgumentException();
+ } else if( offset < 0 || count < 0 ) {
+ throw new ArgumentOutOfRangeException();
+ } else if( streamClosed ) {
+ throw new ObjectDisposedException( "MemoryStream" );
+ }
+
+ if( position + count > capacity ) {
+ if( expandable ) {
+ // expand the buffer
+ SetLength( position + count );
+ } else {
+ // only write as many bytes as will fit
+ count = (int)((long)capacity - position);
+ }
+ }
+
+ Array.Copy( buffer, offset, internalBuffer, (int)position, count );
+ position += count;
+
+ }
+
+
+ public override void WriteByte( byte value ) {
+ if( streamClosed ) {
+ throw new ObjectDisposedException( "MemoryStream" );
+ }
+
+ if( position >= capacity ) {
+ SetLength( capacity + 1 );
+ }
+
+ internalBuffer[ position++ ] = value;
+ }
+
+
+ public virtual void WriteTo( Stream stream ) {
+ if( stream == null ) {
+ throw new ArgumentNullException();
+ }
+
+ stream.Write( internalBuffer, 0, internalBuffer.Length );
+
+ }
+
+
+ }
+
+
+}
diff --git a/mcs/class/corlib/System.IO/Path.cs b/mcs/class/corlib/System.IO/Path.cs
new file mode 100644
index 00000000000..47bafb327e5
--- /dev/null
+++ b/mcs/class/corlib/System.IO/Path.cs
@@ -0,0 +1,270 @@
+//------------------------------------------------------------------------------
+//
+// System.IO.Path.cs
+//
+// Copyright (C) 2001 Moonlight Enterprises, All Rights Reserved
+//
+// Author: Jim Richardson, develop@wtfo-guru.com
+// Created: Saturday, August 11, 2001
+//
+//------------------------------------------------------------------------------
+
+using System;
+
+namespace System.IO
+{
+ public class Path : Object
+ {
+ public static readonly char AltDirectorySeparatorChar = '\\'; // TODO: verify this
+ public static readonly char DirectorySeparatorChar = '/';
+ public static readonly char[] InvalidPathChars = { '\0' }; // TODO: research invalid chars
+ public static readonly char PathSeparator = ';'; // might be a space for unix/linux
+ public static readonly char VolumeSeparatorChar = '/';
+
+ private static readonly char[] PathSeparatorChars = { DirectorySeparatorChar,
+ AltDirectorySeparatorChar,
+ VolumeSeparatorChar };
+
+ // class methods
+ public static string ChangeExtension(string path, string extension)
+ {
+ if(path == null)
+ {
+ return null;
+ }
+
+ int iExt = findExtension(path);
+
+ if(iExt < 0)
+ {
+ return extension == null ? path : path + extension;
+ }
+ else if(iExt > 0)
+ {
+ string temp = path.Substring(0, iExt);
+ if(extension != null)
+ {
+ return temp + extension;
+ }
+ return temp;
+ }
+
+ return extension;
+ }
+
+ public static string Combine(string path1, string path2)
+ {
+ if(path1 == null || path2 == null)
+ {
+ return null;
+ }
+
+ throwEmptyIf(path2);
+
+ // TODO: Check for invalid DirectoryInfo characters
+ // although I don't think it is necesary for linux
+
+ // TODO: Verify functionality further after NUnit tests written
+ // since the documentation was rather sketchy
+
+ if(IsPathRooted(path2))
+ {
+ if(path1.Equals(string.Empty))
+ {
+ return path2;
+ }
+ throw new ArgumentException("Rooted path");
+ }
+
+ string dirSep = new string(DirectorySeparatorChar, 1);
+ string altSep = new string(AltDirectorySeparatorChar, 1);
+
+ bool b1 = path1.EndsWith(dirSep) || path1.EndsWith(dirSep);
+ bool b2 = path2.StartsWith(dirSep) || path2.StartsWith(altSep);
+ if(b1 && b2)
+ {
+ throw new ArgumentException("Invalid combination");
+ }
+
+ if(!b1 && !b2)
+ {
+ return path1 + dirSep + path2;
+ }
+
+ return path1 + path2;
+ }
+
+ public static string GetDirectoryName(string path)
+ {
+ if(path == null)
+ {
+ return null;
+ }
+ throwEmptyIf(path);
+ throwWhiteSpaceOnlyIf(path);
+ throwInvalidPathCharsIf(path);
+
+ if(path.Length > 2)
+ {
+ int nLast = path.LastIndexOfAny(PathSeparatorChars, path.Length - 2);
+
+ if(nLast > 0)
+ {
+ return path.Substring(0, nLast);
+ }
+ }
+ return path;
+ }
+
+ public static string GetExtension(string path)
+ {
+ if(path == null)
+ {
+ return string.Empty;
+ }
+
+ throwEmptyIf(path);
+ throwWhiteSpaceOnlyIf(path);
+
+ int iExt = findExtension(path);
+ int iLastSep = path.LastIndexOfAny( PathSeparatorChars );
+
+ if(iExt > -1)
+ { // okay it has an extension
+ return path.Substring(iExt);
+ }
+ return string.Empty;
+ }
+
+ public static string GetFileName(string path)
+ {
+ if(path == null)
+ {
+ return string.Empty;
+ }
+
+ throwEmptyIf(path);
+ throwWhiteSpaceOnlyIf(path);
+
+ int nLast = path.LastIndexOfAny(PathSeparatorChars);
+
+ if(nLast > 0)
+ {
+ return path.Substring(nLast + 1);
+ }
+
+ return nLast == 0 ? null : path;
+ }
+
+ public static string GetFileNameWithoutExtension(string path)
+ {
+ return ChangeExtension(GetFileName(path), null);
+ }
+
+ public static string GetFullPath(string path)
+ {
+ if(path != null)
+ {
+ //TODO: figure out what the equivilent linux api to
+ // windoze ::GetCurrentDirectory() is and PInvoke it
+ return path;
+ }
+ return null;
+ }
+
+ public static string GetPathRoot(string path)
+ {
+ if(path != null ||
+ (path.StartsWith(new string(DirectorySeparatorChar, 1)) ||
+ path.StartsWith(new string(AltDirectorySeparatorChar, 1))))
+ {
+ return path.Substring(0, 1);
+ }
+ return null;
+ }
+
+ public static string GetTempFileName()
+ {
+ //TODO: Implement method
+ return string.Empty;
+ }
+
+ /// <summary>
+ /// Returns the path of the current systems temp directory
+ /// </summary>
+ public static string GetTempPath()
+ { // TODO: This might vary with distribution and there
+ // might be an api to provide it. Research is needed
+ return "/tmp";
+ }
+
+ public static bool HasExtension(string path)
+ {
+ throwNullIf(path);
+ throwEmptyIf(path);
+ throwWhiteSpaceOnlyIf(path);
+
+ return findExtension(path) > -1;
+ }
+
+ public static bool IsPathRooted(string path)
+ {
+ return path.StartsWith(new string(VolumeSeparatorChar,1));
+ }
+
+ // private class methods
+
+ private static int findExtension(string path)
+ { // method should return the index of the path extension
+ // start or -1 if no valid extension
+ if(path != null)
+ {
+ int iLastDot = path.LastIndexOf(".");
+ int iLastSep = path.LastIndexOfAny( PathSeparatorChars );
+
+ if(iLastDot > iLastSep)
+ {
+ return iLastDot;
+ }
+ }
+ return -1;
+ }
+
+ private static void throwNullIf(string path)
+ {
+ if(path == null)
+ {
+ throw new ArgumentNullException();
+ }
+ }
+
+ private static void throwEmptyIf(string path)
+ {
+ if(path != null && path.Length == 0)
+ {
+ throw new ArgumentException("Empty string");
+ }
+ }
+
+ private static void throwWhiteSpaceOnlyIf(string path)
+ {
+ if(path != null)
+ {
+ string temp = path;
+ temp.Trim();
+ if(temp.Length == 0)
+ {
+ throw new ArgumentException("Whitespace only string");
+ }
+ }
+ }
+
+ private static void throwInvalidPathCharsIf(string path)
+ {
+ if(path != null && path.IndexOfAny(InvalidPathChars) > -1)
+ {
+ throw new ArgumentException("Invalid path characters");
+ }
+ }
+ }
+}
diff --git a/mcs/class/corlib/System.IO/SeekOrigin.cs b/mcs/class/corlib/System.IO/SeekOrigin.cs
new file mode 100644
index 00000000000..710e0ce10d3
--- /dev/null
+++ b/mcs/class/corlib/System.IO/SeekOrigin.cs
@@ -0,0 +1,22 @@
+//------------------------------------------------------------------------------
+//
+// System.IO.SeekOrigin.cs
+//
+// Copyright (C) 2001 Michael Lambert, All Rights Reserved
+//
+// Author: Michael Lambert, michaellambert@email.com
+// Created: Thu 07/18/2001
+//
+//------------------------------------------------------------------------------
+
+namespace System.IO
+{
+
+public enum SeekOrigin
+{
+ Begin,
+ Current,
+ End,
+}
+
+} // Namespace
diff --git a/mcs/class/corlib/System.IO/Stream.cs b/mcs/class/corlib/System.IO/Stream.cs
new file mode 100755
index 00000000000..3edc9173fcc
--- /dev/null
+++ b/mcs/class/corlib/System.IO/Stream.cs
@@ -0,0 +1,203 @@
+//
+// System.IO/Stream.cs
+//
+// Author:
+// Dietmar Maurer (dietmar@ximian.com)
+//
+// (C) 2001 Ximian, Inc. http://www.ximian.com
+//
+
+namespace System.IO
+{
+
+ public abstract class Stream : MarshalByRefObject, IDisposable
+ {
+ // public static readonly Stream Null;
+
+ static Stream ()
+ {
+ //Null = new NullStream ();
+ }
+
+ protected Stream ()
+ {
+ }
+
+ public abstract bool CanRead
+ {
+ get;
+ }
+
+ public abstract bool CanSeek
+ {
+ get;
+ }
+
+ public abstract bool CanWrite
+ {
+ get;
+ }
+
+ public abstract long Length
+ {
+ get;
+ }
+
+ public abstract long Position
+ {
+ get;
+ set;
+ }
+
+
+ public virtual void Close ()
+ {
+ Flush ();
+ }
+
+ public virtual void Dispose ()
+ {
+ }
+
+ protected virtual void Dispose (bool disposing)
+ {
+ }
+
+ ~Stream ()
+ {
+ }
+
+ public abstract void Flush ();
+
+ public abstract int Read (byte[] buffer,
+ int offset,
+ int count);
+
+ public virtual int ReadByte ()
+ {
+ byte[] buffer = new byte [1];
+
+ if (Read (buffer, 0, 1) == 1)
+ return buffer [0];
+
+ return -1;
+ }
+
+ public abstract long Seek (long offset,
+ SeekOrigin origin);
+
+ public abstract void SetLength (long value);
+
+ public abstract void Write (byte[] buffer,
+ int offset,
+ int count);
+
+ public virtual void WriteByte (byte value)
+ {
+ byte[] buffer = new byte [1];
+
+ buffer [0] = value;
+
+ Write (buffer, 0, 1);
+ }
+ }
+
+ class NullStream : Stream
+ {
+ private long position = 0;
+ private long length = System.Int64.MaxValue;
+
+ public override bool CanRead
+ {
+ get {
+ return true;
+ }
+ }
+
+ public override bool CanSeek
+ {
+ get {
+ return true;
+ }
+ }
+
+ public override bool CanWrite
+ {
+ get {
+ return true;
+ }
+ }
+
+ public override long Length
+ {
+ get {
+ return length;
+ }
+ }
+
+ public override long Position
+ {
+ get {
+ return position;
+ }
+ set {
+ position = value;
+ }
+ }
+
+ public override void Flush ()
+ {
+ }
+
+ public override int Read (byte[] buffer,
+ int offset,
+ int count)
+ {
+ int max = offset + count;
+
+ for (int i = offset; i < max; i++)
+ buffer [i] = 0;
+
+ return count;
+ }
+
+ public override int ReadByte ()
+ {
+ return 0;
+ }
+
+ public override long Seek (long offset,
+ SeekOrigin origin)
+ {
+ switch (origin) {
+ case SeekOrigin.Begin:
+ position = offset;
+ break;
+ case SeekOrigin.Current:
+ position = position + offset;
+ break;
+ case SeekOrigin.End:
+ position = Length - offset;
+ break;
+ }
+
+ return position;
+ }
+
+ public override void SetLength (long value)
+ {
+ length = value;
+ }
+
+ public override void Write (byte[] buffer,
+ int offset,
+ int count)
+ {
+ }
+
+ public override void WriteByte (byte value)
+ {
+ }
+
+ }
+}
diff --git a/mcs/class/corlib/System.IO/StringReader.cs b/mcs/class/corlib/System.IO/StringReader.cs
new file mode 100644
index 00000000000..713327a3797
--- /dev/null
+++ b/mcs/class/corlib/System.IO/StringReader.cs
@@ -0,0 +1,130 @@
+//
+// System.IO.StringReader
+//
+// Author: Marcin Szczepanski (marcins@zipworld.com.au)
+//
+
+
+using System;
+
+namespace System.IO {
+ public class StringReader : TextReader {
+
+ protected string source;
+ protected char[] sourceChars;
+
+ protected int nextChar;
+ protected int sourceLength;
+
+ public StringReader( string s ) {
+ this.source = s;
+ nextChar = 0;
+ sourceLength = s.Length;
+ sourceChars = s.ToCharArray();
+ }
+
+ public override void Close() {
+ Dispose( true );
+ }
+
+ protected override void Dispose( bool disposing ) {
+ return;
+ }
+
+ public override int Peek() {
+ if( nextChar > sourceLength ) {
+ return -1;
+ } else {
+ return (int)source[ nextChar ];
+ }
+ }
+
+ public override int Read() {
+ if( nextChar > sourceLength ) {
+ return -1;
+ } else {
+ return (int)source[ nextChar++ ];
+ }
+ }
+
+
+ // The method will read up to count characters from the StringReader
+ // into the buffer character array starting at position index. Returns
+ // the actual number of characters read, or zero if the end of the string
+ // has been reached and no characters are read.
+
+ public override int Read( char[] buffer, int index, int count ) {
+
+ if( buffer == null ) {
+ throw new ArgumentNullException();
+ } else if( buffer.Length - index < count ) {
+ throw new ArgumentException();
+ } else if( index < 0 || count < 0 ) {
+ throw new ArgumentOutOfRangeException();
+ }
+
+ int charsToRead;
+
+ if( nextChar + count > sourceLength ) {
+ charsToRead = sourceLength - nextChar;
+ } else {
+ charsToRead = count;
+ }
+
+ Array.Copy(sourceChars, nextChar, buffer, index, charsToRead );
+
+ nextChar += count;
+
+ return charsToRead;
+ }
+
+ public override string ReadLine() {
+ // Reads until next \r or \n or \r\n, otherwise return null
+
+ // LAMESPEC:
+ // The Beta 2 SDK help says that the ReadLine method returns
+ // "The next line from the input stream [...] A line is defined as a sequence of
+ // characters followed by a carriage return (\r), a line feed (\n), or a carriage
+ // return immediately followed by a line feed (\r\n). [...]
+ // The returned value is a null reference if the end of the input stream has been reached."
+ //
+ // HOWEVER, the MS implementation returns the rest of the string if no \r and/or \n is found
+ // in the string
+
+
+ int nextCR = source.IndexOf( '\r', nextChar );
+ int nextLF = source.IndexOf( '\n', nextChar );
+
+ if( nextCR == -1 && nextLF == -1 ) {
+ return ReadToEnd();
+ }
+
+ if( nextChar > sourceLength ) return null;
+
+ int readTo;
+
+ if( nextCR == -1 ) {
+ readTo = nextLF;
+ } else {
+ readTo = nextCR;
+ }
+
+ string nextLine = source.Substring( nextChar, readTo - nextChar );
+
+ if( nextLF == nextCR + 1 ) {
+ nextChar = readTo + 2;
+ } else {
+ nextChar = readTo + 1;
+ }
+
+ return nextLine;
+ }
+
+ public override string ReadToEnd() {
+ string toEnd = source.Substring( nextChar, sourceLength - nextChar );
+ nextChar = sourceLength;
+ return toEnd;
+ }
+
+ }
+}
diff --git a/mcs/class/corlib/System.IO/StringWriter.cs b/mcs/class/corlib/System.IO/StringWriter.cs
new file mode 100644
index 00000000000..0d0ff0bfee1
--- /dev/null
+++ b/mcs/class/corlib/System.IO/StringWriter.cs
@@ -0,0 +1,81 @@
+//
+// System.IO.StringWriter
+//
+// Author: Marcin Szczepanski (marcins@zipworld.com.au)
+//
+
+using System.Text;
+
+namespace System.IO {
+ public class StringWriter : TextWriter {
+
+ protected StringBuilder internalString;
+
+ private IFormatProvider internalFormatProvider;
+
+ public StringWriter() {
+ internalString = new StringBuilder();
+ }
+
+ public StringWriter( IFormatProvider formatProvider ) {
+ internalFormatProvider = formatProvider;
+ }
+
+ public StringWriter( StringBuilder sb ) {
+ internalString = sb;
+ }
+
+ public StringWriter( StringBuilder sb, IFormatProvider formatProvider ) {
+ internalString = sb;
+ internalFormatProvider = formatProvider;
+ }
+
+ public override System.Text.Encoding Encoding {
+ get {
+ // TODO: Implement
+ return null;
+ }
+ }
+
+ public override void Close() {
+ Dispose( true );
+ }
+
+ protected override void Dispose( bool disposing ) { }
+
+ public virtual StringBuilder GetStringBuilder() {
+ return internalString;
+ }
+
+ public override string ToString() {
+ return internalString.ToString();
+ }
+
+ public override void Write( char value ) {
+ internalString.Append( value );
+ }
+
+ public override void Write( string value ) {
+ internalString.Append( value );
+ }
+
+ public override void Write( char[] buffer, int index, int count ) {
+ if( buffer == null ) {
+ throw new ArgumentNullException();
+ } else if( index < 0 || count < 0 ) {
+ throw new ArgumentOutOfRangeException();
+ } else if( index > buffer.Length || index + count > buffer.Length ) {
+ throw new ArgumentException();
+ }
+
+ char[] writeBuffer = new char[ count ];
+
+ Array.Copy( buffer, index, writeBuffer, 0, count );
+
+ internalString.Append( writeBuffer );
+ }
+
+ }
+}
+
+ \ No newline at end of file
diff --git a/mcs/class/corlib/System.IO/TextReader.cs b/mcs/class/corlib/System.IO/TextReader.cs
new file mode 100644
index 00000000000..972a87ca815
--- /dev/null
+++ b/mcs/class/corlib/System.IO/TextReader.cs
@@ -0,0 +1,64 @@
+//
+// System.IO.TextWriter
+//
+// Author: Marcin Szczepanski (marcins@zipworld.com.au)
+//
+// TODO: Implement the Thread Safe stuff
+//
+
+using System;
+
+namespace System.IO {
+ public abstract class TextReader : MarshalByRefObject, IDisposable {
+
+ protected TextReader() { }
+
+ public static readonly TextReader Null;
+
+ public virtual void Close() {
+ Dispose(true);
+ }
+
+ void System.IDisposable.Dispose() {
+ Dispose(true);
+ }
+
+ protected virtual void Dispose( bool disposing ) {
+ return;
+ }
+
+ public virtual int Peek() {
+ return -1;
+ }
+
+ public virtual int Read() {
+ return -1;
+ }
+
+
+ // LAMESPEC: The Beta2 docs say this should be Read( out char[] ...
+ // whereas the MS implementation is just Read( char[] ... )
+ // Not sure which one is right, we'll see in Beta3 :)
+
+ public virtual int Read( char[] buffer, int index, int count ) {
+ return 1;
+ }
+
+ public virtual int ReadBlock( char[] buffer, int index, int count ) {
+ return 1;
+ }
+
+ public virtual string ReadLine() {
+ return String.Empty;
+ }
+
+ public virtual string ReadToEnd() {
+ return String.Empty;
+ }
+
+ public static TextReader Synchronised( TextReader reader ) {
+ // TODO: Implement
+ return Null;
+ }
+ }
+}
diff --git a/mcs/class/corlib/System.IO/TextWriter.cs b/mcs/class/corlib/System.IO/TextWriter.cs
new file mode 100644
index 00000000000..502437715b1
--- /dev/null
+++ b/mcs/class/corlib/System.IO/TextWriter.cs
@@ -0,0 +1,104 @@
+//
+// System.IO.TextWriter
+//
+// Author: Marcin Szczepanski (marcins@zipworld.com.au)
+//
+// TODO: Implement the Thread Safe stuff
+
+namespace System.IO {
+ public abstract class TextWriter : MarshalByRefObject, IDisposable {
+
+ protected TextWriter() { }
+
+ protected TextWriter( IFormatProvider formatProvider ) {
+ InternalFormatProvider = formatProvider;
+ }
+
+ protected char[] coreNewLine;
+
+ protected IFormatProvider InternalFormatProvider;
+
+ public static readonly TextWriter Null;
+
+ public abstract System.Text.Encoding Encoding { get; }
+
+ public virtual IFormatProvider FormatProvider {
+ get {
+ return InternalFormatProvider;
+ }
+ }
+
+ public virtual string NewLine {
+ get {
+ return new String(coreNewLine);
+ }
+
+ set {
+ coreNewLine = value.ToCharArray();
+ }
+ }
+
+ public virtual void Close() {
+ Dispose( true );
+ }
+
+ protected virtual void Dispose( bool disposing ) { }
+
+ void System.IDisposable.Dispose() {
+ Dispose(true);
+ }
+
+
+ protected virtual void Flush() { }
+
+ public static TextWriter Synchronised( TextWriter writer ) {
+ // TODO: Implement.
+
+ return Null;
+ }
+
+ public virtual void Write( bool value ) { }
+ public virtual void Write( char value ) { }
+ public virtual void Write( char[] value ) { }
+ public virtual void Write( decimal value ) { }
+ public virtual void Write( double value ) { }
+ public virtual void Write( int value ) { }
+ public virtual void Write( long value ) { }
+ public virtual void Write( object value ) { }
+ public virtual void Write( float value ) { }
+ public virtual void Write( string value ) { }
+ public virtual void Write( uint value ) { }
+ public virtual void Write( ulong value ) { }
+ public virtual void Write( string format, object arg0 ) { }
+ public virtual void Write( string format, params object[] arg ) { }
+ public virtual void Write( char[] buffer, int index, int count ) { }
+ public virtual void Write( string format, object arg0, object arg1 ) { }
+ public virtual void Write( string format, object arg0, object arg1, object arg2 ) { }
+
+ public virtual void WriteLine() { }
+ public virtual void WriteLine( bool value ) { }
+ public virtual void WriteLine( char value ) { }
+ public virtual void WriteLine( char[] value ) { }
+ public virtual void WriteLine( decimal value ) { }
+ public virtual void WriteLine( double value ) { }
+ public virtual void WriteLine( int value ) { }
+ public virtual void WriteLine( long value ) { }
+ public virtual void WriteLine( object value ) { }
+ public virtual void WriteLine( float value ) { }
+ public virtual void WriteLine( string value ) { }
+ public virtual void WriteLine( uint value ) { }
+ public virtual void WriteLine( ulong value ) { }
+ public virtual void WriteLine( string format, object arg0 ) { }
+ public virtual void WriteLine( string format, params object[] arg ) { }
+ public virtual void WriteLine( char[] buffer, int index, int count ) { }
+ public virtual void WriteLine( string format, object arg0, object arg1 ) { }
+ public virtual void WriteLine( string format, object arg0, object arg1, object arg2 ) { }
+
+
+ }
+}
+
+
+
+
+
diff --git a/mcs/class/corlib/System.IO/common.src b/mcs/class/corlib/System.IO/common.src
new file mode 100644
index 00000000000..3c7826bb813
--- /dev/null
+++ b/mcs/class/corlib/System.IO/common.src
@@ -0,0 +1,11 @@
+FileAccess.cs
+FileMode.cs
+FileShare.cs
+MemoryStream.cs
+SeekOrigin.cs
+StringReader.cs
+StringWriter.cs
+TextReader.cs
+TextWriter.cs
+Stream.cs
+FileStream.cs
diff --git a/mcs/class/corlib/System.IO/unix.src b/mcs/class/corlib/System.IO/unix.src
new file mode 100755
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/mcs/class/corlib/System.IO/unix.src
diff --git a/mcs/class/corlib/System.IO/windows.src b/mcs/class/corlib/System.IO/windows.src
new file mode 100755
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/mcs/class/corlib/System.IO/windows.src
diff --git a/mcs/class/corlib/System.Reflection/BindingFlags.cs b/mcs/class/corlib/System.Reflection/BindingFlags.cs
new file mode 100644
index 00000000000..e6487cce969
--- /dev/null
+++ b/mcs/class/corlib/System.Reflection/BindingFlags.cs
@@ -0,0 +1,36 @@
+//------------------------------------------------------------------------------
+//
+// System.Reflection.BindingFlags.cs
+//
+// Copyright (C) 2001 Michael Lambert, All Rights Reserved
+//
+// Author: Michael Lambert, michaellambert@email.com
+// Created: Thu 07/18/2001
+//
+//------------------------------------------------------------------------------
+
+namespace System.Reflection
+{
+
+public enum BindingFlags
+{
+ CreateInstance,
+ DeclaredOnly,
+ Default,
+ ExactBinding,
+ GetField,
+ GetProperty,
+ IgnoreCase,
+ Instance,
+ InvokeMethod,
+ NonPublic,
+ OptionalParamBinding,
+ Public,
+ SetField,
+ SetProperty,
+ Static,
+ SuppressChangeType,
+}
+
+
+} // Namespace
diff --git a/mcs/class/corlib/System.Reflection/ChangeLog b/mcs/class/corlib/System.Reflection/ChangeLog
new file mode 100644
index 00000000000..3f67105fd41
--- /dev/null
+++ b/mcs/class/corlib/System.Reflection/ChangeLog
@@ -0,0 +1,3 @@
+2001-07-18 Michael Lambert <michaellambert@email.com>
+
+ * BindingFlags.cs: Add.
diff --git a/mcs/class/corlib/System.Reflection/DefaultMemberAttribute.cs b/mcs/class/corlib/System.Reflection/DefaultMemberAttribute.cs
new file mode 100644
index 00000000000..166780e4eb2
--- /dev/null
+++ b/mcs/class/corlib/System.Reflection/DefaultMemberAttribute.cs
@@ -0,0 +1,26 @@
+//
+// System.Reflection.DefaultMemberAttribute.cs
+//
+// Author:
+// Miguel de Icaza (miguel@ximian.com)
+//
+// (C) Ximian, Inc. http://www.ximian.com
+//
+
+namespace System.Reflection {
+
+ public sealed class DefaultMemberAttribute : Attribute {
+ string member_name;
+
+ public DefaultMemberAttribute (string member_name)
+ {
+ this.member_name = member_name;
+ }
+
+ public string MemberName {
+ get {
+ return member_name;
+ }
+ }
+ }
+}
diff --git a/mcs/class/corlib/System.Reflection/common.src b/mcs/class/corlib/System.Reflection/common.src
new file mode 100644
index 00000000000..ae31dcbb932
--- /dev/null
+++ b/mcs/class/corlib/System.Reflection/common.src
@@ -0,0 +1,2 @@
+BindingFlags.cs
+DefaultMemberAttribute.cs
diff --git a/mcs/class/corlib/System.Reflection/unix.src b/mcs/class/corlib/System.Reflection/unix.src
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/mcs/class/corlib/System.Reflection/unix.src
diff --git a/mcs/class/corlib/System.Reflection/windows.src b/mcs/class/corlib/System.Reflection/windows.src
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/mcs/class/corlib/System.Reflection/windows.src
diff --git a/mcs/class/corlib/System.Runtime.CompilerServices/ChangeLog b/mcs/class/corlib/System.Runtime.CompilerServices/ChangeLog
new file mode 100644
index 00000000000..a9c48bf1c4c
--- /dev/null
+++ b/mcs/class/corlib/System.Runtime.CompilerServices/ChangeLog
@@ -0,0 +1,3 @@
+2001-07-18 Michael Lambert <michaellambert@email.com>
+
+ * MethodCodeType.cs, MethodImplOptions.cs: Add.
diff --git a/mcs/class/corlib/System.Runtime.CompilerServices/MethodCodeType.cs b/mcs/class/corlib/System.Runtime.CompilerServices/MethodCodeType.cs
new file mode 100644
index 00000000000..3608120e516
--- /dev/null
+++ b/mcs/class/corlib/System.Runtime.CompilerServices/MethodCodeType.cs
@@ -0,0 +1,23 @@
+//------------------------------------------------------------------------------
+//
+// System.Runtime.CompilerServices.MethodCodeType.cs
+//
+// Copyright (C) 2001 Michael Lambert, All Rights Reserved
+//
+// Author: Michael Lambert, michaellambert@email.com
+// Created: Thu 07/18/2001
+//
+//------------------------------------------------------------------------------
+
+namespace System.Runtime.CompilerServices
+{
+
+public enum MethodCodeType
+{
+ IL,
+ Native,
+ OPTIL,
+ Runtime,
+}
+
+} // Namespace
diff --git a/mcs/class/corlib/System.Runtime.CompilerServices/MethodImplOptions.cs b/mcs/class/corlib/System.Runtime.CompilerServices/MethodImplOptions.cs
new file mode 100644
index 00000000000..1f43dbe901e
--- /dev/null
+++ b/mcs/class/corlib/System.Runtime.CompilerServices/MethodImplOptions.cs
@@ -0,0 +1,26 @@
+//------------------------------------------------------------------------------
+//
+// System.Runtime.CompilerServices.MethodImplOptions.cs
+//
+// Copyright (C) 2001 Michael Lambert, All Rights Reserved
+//
+// Author: Michael Lambert, michaellambert@email.com
+// Created: Mon 07/18/2001
+//
+//------------------------------------------------------------------------------
+
+namespace System.Runtime.CompilerServices
+{
+
+public enum MethodImplOptions
+{
+ ForwardRef,
+ InternalCall,
+ NoInlining,
+ PreserveSig,
+ Synchronized,
+ Unmanaged,
+}
+
+
+} // Namespace
diff --git a/mcs/class/corlib/System.Runtime.CompilerServices/common.src b/mcs/class/corlib/System.Runtime.CompilerServices/common.src
new file mode 100644
index 00000000000..0744a82a5e7
--- /dev/null
+++ b/mcs/class/corlib/System.Runtime.CompilerServices/common.src
@@ -0,0 +1 @@
+MethodCodeType.cs
diff --git a/mcs/class/corlib/System.Runtime.CompilerServices/unix.src b/mcs/class/corlib/System.Runtime.CompilerServices/unix.src
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/mcs/class/corlib/System.Runtime.CompilerServices/unix.src
diff --git a/mcs/class/corlib/System.Runtime.CompilerServices/windows.src b/mcs/class/corlib/System.Runtime.CompilerServices/windows.src
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/mcs/class/corlib/System.Runtime.CompilerServices/windows.src
diff --git a/mcs/class/corlib/System.Runtime.InteropServices/CallingConvention.cs b/mcs/class/corlib/System.Runtime.InteropServices/CallingConvention.cs
new file mode 100644
index 00000000000..95aa47975bc
--- /dev/null
+++ b/mcs/class/corlib/System.Runtime.InteropServices/CallingConvention.cs
@@ -0,0 +1,24 @@
+//------------------------------------------------------------------------------
+//
+// System.Runtime.InteropServices.CallingConvention.cs
+//
+// Copyright (C) 2001 Michael Lambert, All Rights Reserved
+//
+// Author: Michael Lambert, michaellambert@email.com
+// Created: Thu 07/18/2001
+//
+//------------------------------------------------------------------------------
+
+namespace System.Runtime.InteropServices
+{
+
+public enum CallingConvention
+{
+ Cdecl,
+ FastCall,
+ StdCall,
+ ThisCall,
+ Winapi,
+}
+
+} // Namespace
diff --git a/mcs/class/corlib/System.Runtime.InteropServices/ChangeLog b/mcs/class/corlib/System.Runtime.InteropServices/ChangeLog
new file mode 100644
index 00000000000..c8397e767eb
--- /dev/null
+++ b/mcs/class/corlib/System.Runtime.InteropServices/ChangeLog
@@ -0,0 +1,7 @@
+2001-07-20 Miguel de Icaza <miguel@ximian.com>
+
+ * OutAttribute.cs: New file.
+
+2001-07-18 Michael Lambert <michaellambert@email.com>
+
+ * CallingConvention.cs.cs, CharSet.cs, GCHandleType.cs, LayoutKind.cs: Add.
diff --git a/mcs/class/corlib/System.Runtime.InteropServices/CharSet.cs b/mcs/class/corlib/System.Runtime.InteropServices/CharSet.cs
new file mode 100644
index 00000000000..c874d939ce8
--- /dev/null
+++ b/mcs/class/corlib/System.Runtime.InteropServices/CharSet.cs
@@ -0,0 +1,23 @@
+//------------------------------------------------------------------------------
+//
+// System.Runtime.InteropServices.SystemEnums.cs
+//
+// Copyright (C) 2001 Michael Lambert, All Rights Reserved
+//
+// Author: Michael Lambert, michaellambert@email.com
+// Created: Thu 07/18/2001
+//
+//------------------------------------------------------------------------------
+
+namespace System.Runtime.InteropServices
+{
+
+public enum CharSet
+{
+ Ansi,
+ Auto,
+ None,
+ Unicode,
+}
+
+} // Namespace
diff --git a/mcs/class/corlib/System.Runtime.InteropServices/GCHandleType.cs b/mcs/class/corlib/System.Runtime.InteropServices/GCHandleType.cs
new file mode 100644
index 00000000000..de9e456e335
--- /dev/null
+++ b/mcs/class/corlib/System.Runtime.InteropServices/GCHandleType.cs
@@ -0,0 +1,21 @@
+//------------------------------------------------------------------------------
+//
+// System.Runtime.InteropServices.GCHandleType.cs
+//
+// Copyright (C) 2001 Michael Lambert, All Rights Reserved
+//
+// Author: Michael Lambert, michaellambert@email.com
+// Created: Thu 07/18/2001
+//
+//------------------------------------------------------------------------------
+
+namespace System.Runtime.InteropServices
+{
+
+public enum GCHandleType
+{
+ Normal,
+ Pinned,
+}
+
+} // Namespace
diff --git a/mcs/class/corlib/System.Runtime.InteropServices/LayoutKind.cs b/mcs/class/corlib/System.Runtime.InteropServices/LayoutKind.cs
new file mode 100644
index 00000000000..b43f84197c7
--- /dev/null
+++ b/mcs/class/corlib/System.Runtime.InteropServices/LayoutKind.cs
@@ -0,0 +1,22 @@
+//------------------------------------------------------------------------------
+//
+// System.Runtime.InteropServices.LayoutKind.cs
+//
+// Copyright (C) 2001 Michael Lambert, All Rights Reserved
+//
+// Author: Michael Lambert, michaellambert@email.com
+// Created: Thu 07/18/2001
+//
+//------------------------------------------------------------------------------
+
+namespace System.Runtime.InteropServices
+{
+
+public enum LayoutKind
+{
+ Auto,
+ Explicit,
+ Sequential,
+}
+
+} // Namespace
diff --git a/mcs/class/corlib/System.Runtime.InteropServices/OutAttribute.cs b/mcs/class/corlib/System.Runtime.InteropServices/OutAttribute.cs
new file mode 100644
index 00000000000..9b3e028337a
--- /dev/null
+++ b/mcs/class/corlib/System.Runtime.InteropServices/OutAttribute.cs
@@ -0,0 +1,25 @@
+//
+// System.Runtime.InteropServices.OutAttribute.cs
+//
+// Author:
+// Miguel de Icaza (miguel@ximian.com)
+//
+// (C) Ximian, Inc. http://www.ximian.com
+//
+
+namespace System.Runtime.InteropServices {
+
+ public sealed class OutAttribute : Attribute {
+
+ public OutAttribute ()
+ {
+ }
+
+ public override object TypeId {
+ get {
+ // TODO: Implement me
+ return null;
+ }
+ }
+ }
+}
diff --git a/mcs/class/corlib/System.Runtime.InteropServices/common.src b/mcs/class/corlib/System.Runtime.InteropServices/common.src
new file mode 100644
index 00000000000..f6232d21b99
--- /dev/null
+++ b/mcs/class/corlib/System.Runtime.InteropServices/common.src
@@ -0,0 +1,5 @@
+CallingConvention.cs
+CharSet.cs
+GCHandleType.cs
+LayoutKind.cs
+OutAttribute.cs
diff --git a/mcs/class/corlib/System.Runtime.InteropServices/unix.src b/mcs/class/corlib/System.Runtime.InteropServices/unix.src
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/mcs/class/corlib/System.Runtime.InteropServices/unix.src
diff --git a/mcs/class/corlib/System.Runtime.InteropServices/windows.src b/mcs/class/corlib/System.Runtime.InteropServices/windows.src
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/mcs/class/corlib/System.Runtime.InteropServices/windows.src
diff --git a/mcs/class/corlib/System.Runtime.Remoting/ObjRef.cs b/mcs/class/corlib/System.Runtime.Remoting/ObjRef.cs
new file mode 100644
index 00000000000..0d511c889be
--- /dev/null
+++ b/mcs/class/corlib/System.Runtime.Remoting/ObjRef.cs
@@ -0,0 +1,65 @@
+//
+// System.Runtime.Remoting.ObjRef.cs
+//
+// Author:
+// Miguel de Icaza (miguel@ximian.com)
+//
+// (C) Ximian, Inc. http://www.ximian.com
+//
+//
+// FIXME: This is just a skeleton for practical purposes.
+//
+
+using System;
+
+namespace System.Runtime.Remoting {
+
+ public class ObjRef : IObjectReference, ISerializable {
+ MarshalByRefObject mbr;
+ SerializationInfo si;
+ Type type;
+
+ public ObjRef ()
+ {
+ }
+
+ public ObjRef (MarshalByRefObject mbr, Type type)
+ {
+ this.mbr = mbr;
+ this.type = type;
+ }
+
+ public ObjRef (SerializationInfo si, StreamingContext sc)
+ {
+ // FIXME: Implement.
+ //
+ // This encarnates the object from serialized data.
+ }
+
+ public virtual void GetObjectData (SerializationInfo si, StreamingContext sc)
+ {
+ // FIXME:
+ }
+
+ public virtual object GetRealObject (StreamingContext sc)
+ {
+ // FIXME:
+
+ return null;
+ }
+
+ public bool IsFromThisAppDomain ()
+ {
+ // FIXME:
+
+ return true;
+ }
+
+ public bool IsFromThisProcess ()
+ {
+ // FIXME:
+
+ return true;
+ }
+ }
+}
diff --git a/mcs/class/corlib/System.Runtime.Serialization/ChangeLog b/mcs/class/corlib/System.Runtime.Serialization/ChangeLog
new file mode 100644
index 00000000000..3b5b0a0d8d7
--- /dev/null
+++ b/mcs/class/corlib/System.Runtime.Serialization/ChangeLog
@@ -0,0 +1,9 @@
+2001-07-20 Miguel de Icaza <miguel@ximian.com>
+
+ * SerializationInfo.cs: New file.
+
+ * IFormatterConverter.cs: New file.
+
+ * ISerializable.cs: New file.
+
+
diff --git a/mcs/class/corlib/System.Runtime.Serialization/IFormatterConverter.cs b/mcs/class/corlib/System.Runtime.Serialization/IFormatterConverter.cs
new file mode 100644
index 00000000000..190b379a33c
--- /dev/null
+++ b/mcs/class/corlib/System.Runtime.Serialization/IFormatterConverter.cs
@@ -0,0 +1,32 @@
+//
+// System.Runtime.Serialization.IFormatterConverter.cs
+//
+// Author:
+// Miguel de Icaza (miguel@ximian.com)
+//
+// (C) Ximian, Inc. http://www.ximian.com
+//
+//
+
+namespace System.Runtime.Serialization {
+ public interface IFormatterConverter {
+ object Convert (object o, Type t);
+ object Convert (object o, TypeCode tc);
+
+ bool ToBoolean (object o);
+ byte ToByte (object o);
+ char ToChar (object o);
+ DateTime ToDateTime (object o);
+ Decimal ToDecimal (object o);
+ double ToDouble (object o);
+ Int16 ToInt16 (object o);
+ Int32 ToInt32 (object o);
+ Int64 ToInt64 (object o);
+ sbyte ToSByte (object o);
+ float ToSingle (object o);
+ string ToString (object o);
+ UInt16 ToUInt16 (object o);
+ UInt32 ToUInt32 (object o);
+ UInt64 ToUInt64 (object o);
+ }
+}
diff --git a/mcs/class/corlib/System.Runtime.Serialization/IObjectReference.cs b/mcs/class/corlib/System.Runtime.Serialization/IObjectReference.cs
new file mode 100644
index 00000000000..59f5a0200b4
--- /dev/null
+++ b/mcs/class/corlib/System.Runtime.Serialization/IObjectReference.cs
@@ -0,0 +1,16 @@
+//
+// System.Runtime.Serialization.IObjectReference.cs
+//
+// Author:
+// Miguel de Icaza (miguel@ximian.com)
+//
+// (C) Ximian, Inc. http://www.ximian.com
+//
+
+namespace System.Runtime.Serialization {
+
+ public interface IObjectReference {
+ object GetRealObject (StreamingContext context);
+ }
+}
+
diff --git a/mcs/class/corlib/System.Runtime.Serialization/ISerializable.cs b/mcs/class/corlib/System.Runtime.Serialization/ISerializable.cs
new file mode 100644
index 00000000000..64773514eba
--- /dev/null
+++ b/mcs/class/corlib/System.Runtime.Serialization/ISerializable.cs
@@ -0,0 +1,15 @@
+//
+// System.Runtime.Serialization.ISerializable.cs
+//
+// Author:
+// Miguel de Icaza (miguel@ximian.com)
+//
+// (C) Ximian, Inc. http://www.ximian.com
+//
+//
+
+namespace System.Runtime.Serialization {
+ public interface ISerializable {
+ void GetObjectData (SerializationInfo info, StreamingContext context);
+ }
+}
diff --git a/mcs/class/corlib/System.Runtime.Serialization/SerializationInfo.cs b/mcs/class/corlib/System.Runtime.Serialization/SerializationInfo.cs
new file mode 100644
index 00000000000..34ae3ef81f2
--- /dev/null
+++ b/mcs/class/corlib/System.Runtime.Serialization/SerializationInfo.cs
@@ -0,0 +1,49 @@
+//
+// System.Runtime.Serialization.SerializationInfo.cs
+//
+// Author:
+// Miguel de Icaza (miguel@ximian.com)
+//
+// (C) Ximian, Inc. http://www.ximian.com
+//
+// TODO: This is just a skeleton to get corlib to compile.
+//
+
+namespace System.Runtime.Serialization {
+
+ public sealed class SerializationInfo {
+ Type type;
+ IFormatterConverter converter;
+
+ public SerializationInfo (Type type, IFormatterConverter converter)
+ {
+ this.type = type;
+ this.converter = converter;
+ }
+
+ public string AssemblyName {
+ get {
+ return "TODO: IMPLEMENT ME";
+ }
+
+ set {
+ }
+ }
+
+ public string FullTypeName {
+ get {
+ return "TODO: IMLEMENT ME";
+ }
+
+ set {
+ }
+ }
+
+
+ public int MemberCount {
+ get {
+ return 0;
+ }
+ }
+ }
+}
diff --git a/mcs/class/corlib/System.Runtime.Serialization/StreamingContext.cs b/mcs/class/corlib/System.Runtime.Serialization/StreamingContext.cs
new file mode 100644
index 00000000000..9a5d8eed2a5
--- /dev/null
+++ b/mcs/class/corlib/System.Runtime.Serialization/StreamingContext.cs
@@ -0,0 +1,59 @@
+//
+// System.Runtime.Serialization.StreamingContext.cs
+//
+// Author:
+// Miguel de Icaza (miguel@ximian.com)
+//
+// (C) Ximian, Inc. http://www.ximian.com
+//
+
+namespace System.Runtime.Serialization {
+
+ public struct StreamingContext {
+ StreamingContextStates state;
+ object additional;
+
+ public StreamingContext (StreamingContextStates state)
+ {
+ this.state = state;
+ additional = null;
+ }
+
+ public StreamingContext (StreamingContextStates state, object additional)
+ {
+ this.state = state;
+ this.additional = additional;
+ }
+
+ public object Context {
+ get {
+ return additional;
+ }
+ }
+
+ public StreamingContextStates {
+ get {
+ return state;
+ }
+ }
+
+ public bool Equals (Object o)
+ {
+ StreamingContext other;
+
+ if (!(o is StreamingContext))
+ return false;
+
+ other = (StreamingContext) o;
+
+ return (other.state == this.state) && (other.additional == this.additional);
+ }
+
+ public int GetHashCode ()
+ {
+ // FIXME: Improve this? Is this worth it?
+
+ return o.GetHashCode ();
+ }
+ }
+}
diff --git a/mcs/class/corlib/System.Runtime.Serialization/StreamingContextStates.cs b/mcs/class/corlib/System.Runtime.Serialization/StreamingContextStates.cs
new file mode 100644
index 00000000000..47bc4c92d5b
--- /dev/null
+++ b/mcs/class/corlib/System.Runtime.Serialization/StreamingContextStates.cs
@@ -0,0 +1,23 @@
+//
+// System.Runtime.Serialization.StreamingContextStates.cs
+//
+// Author:
+// Miguel de Icaza (miguel@ximian.com)
+//
+// (C) Ximian, Inc. http://www.ximian.com
+//
+
+namespace System.Runtime.Serialization {
+
+ public enum StreamingContextStates {
+ All,
+ Clone,
+ CrossAppDomain,
+ CrossMachine,
+ CrossProcess,
+ File,
+ Other,
+ Persistence,
+ Remoting
+ }
+}
diff --git a/mcs/class/corlib/System.Runtime.Serialization/common.src b/mcs/class/corlib/System.Runtime.Serialization/common.src
new file mode 100644
index 00000000000..8801d312d56
--- /dev/null
+++ b/mcs/class/corlib/System.Runtime.Serialization/common.src
@@ -0,0 +1,3 @@
+IFormatterConverter.cs
+ISerializable.cs
+SerializationInfo.cs
diff --git a/mcs/class/corlib/System.Runtime.Serialization/mono.src b/mcs/class/corlib/System.Runtime.Serialization/mono.src
new file mode 100644
index 00000000000..a7a110db50a
--- /dev/null
+++ b/mcs/class/corlib/System.Runtime.Serialization/mono.src
@@ -0,0 +1 @@
+SerializationInfo.cs
diff --git a/mcs/class/corlib/System.Runtime.Serialization/unix.src b/mcs/class/corlib/System.Runtime.Serialization/unix.src
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/mcs/class/corlib/System.Runtime.Serialization/unix.src
diff --git a/mcs/class/corlib/System.Runtime.Serialization/windows.src b/mcs/class/corlib/System.Runtime.Serialization/windows.src
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/mcs/class/corlib/System.Runtime.Serialization/windows.src
diff --git a/mcs/class/corlib/System.Security.Cryptography.Test/ChangeLog b/mcs/class/corlib/System.Security.Cryptography.Test/ChangeLog
new file mode 100644
index 00000000000..904037a87a3
--- /dev/null
+++ b/mcs/class/corlib/System.Security.Cryptography.Test/ChangeLog
@@ -0,0 +1,8 @@
+2001-08-01 Matthew S. Ford <Matthew.S.Ford@Rose-Hulman.Edu>
+
+ * MD5Test.cs: Initial version.
+ * SHA1Test.cs: Initial version.
+ * SHA256Test.cs: Initial version.
+ * SHA384Test.cs: Initial version.
+ * SHA512Test.cs: Initial version.
+
diff --git a/mcs/class/corlib/System.Security.Cryptography.Test/MD5Test.cs b/mcs/class/corlib/System.Security.Cryptography.Test/MD5Test.cs
new file mode 100644
index 00000000000..2ad6db01e52
--- /dev/null
+++ b/mcs/class/corlib/System.Security.Cryptography.Test/MD5Test.cs
@@ -0,0 +1,83 @@
+//
+// System.Security.Cryptography.Test MD5 NUnit test classes.
+//
+// Authors:
+// Matthew S. Ford (Matthew.S.Ford@Rose-Hulman.Edu)
+//
+// Copyright 2001 by Matthew S. Ford.
+//
+
+
+using NUnit.Framework;
+using System;
+using System.Security.Cryptography;
+using System.Text;
+
+namespace System.Security.Cryptography.Test {
+ public class MD5HashingTest : TestCase {
+ byte[] _dataToHash;
+ byte[] _expectedHash;
+
+ public MD5HashingTest (string name, byte[] dataToHash, byte[] expectedHash) : base(name) {
+ _dataToHash = dataToHash;
+ _expectedHash = expectedHash;
+ }
+
+ public static bool ArrayEquals (byte[] arr1, byte[] arr2) {
+ int i;
+ if (arr1.GetLength(0) != arr2.GetLength(0))
+ return false;
+
+ for (i=0; i<arr1.GetLength(0); i++) {
+ if (arr1[i] != arr2[i])
+ return false;
+ }
+
+ return true;
+ }
+
+ protected override void RunTest () {
+ MD5 md5 = new MD5CryptoServiceProvider ();
+ byte[] hash;
+
+ hash = md5.ComputeHash (_dataToHash);
+
+ Assert (ArrayEquals (hash, _expectedHash));
+ }
+
+ }
+
+ public class MD5TestSet {
+ public MD5TestSet () {
+
+ }
+
+ public static void Main () {
+
+ }
+
+ public static ITest Suite {
+ get {
+ TestSuite suite = new TestSuite ();
+
+ byte[] hash0 = {0xD4, 0x1D, 0x8C, 0xD9, 0x8F, 0x00, 0xB2, 0x04, 0xE9, 0x80, 0x09, 0x98, 0xEC, 0xF8, 0x42, 0x7E};
+ suite.AddTest (new MD5HashingTest ("(blank hash)", new byte[0], hash0));
+
+ byte[] hash1 = {0x0C, 0xC1, 0x75, 0xB9, 0xC0, 0xF1, 0xB6, 0xA8, 0x31, 0xC3, 0x99, 0xE2, 0x69, 0x77, 0x26, 0x61};
+ suite.AddTest (new MD5HashingTest ("a", Encoding.UTF8.GetBytes("a"), hash1));
+
+ byte[] hash2 = {0x90, 0x01, 0x50, 0x98, 0x3C, 0xD2, 0x4F, 0xB0, 0xD6, 0x96, 0x3F, 0x7D, 0x28, 0xE1, 0x7F, 0x72};
+ suite.AddTest (new MD5HashingTest ("abc", Encoding.UTF8.GetBytes("abc"), hash2));
+
+ byte[] hash3 = {0xC3, 0xFC, 0xD3, 0xD7, 0x61, 0x92, 0xE4, 0x00, 0x7D, 0xFB, 0x49, 0x6C, 0xCA, 0x67, 0xE1, 0x3B};
+ suite.AddTest (new MD5HashingTest ("abcdefghijklmnopqrstuvwxyz", Encoding.UTF8.GetBytes("abcdefghijklmnopqrstuvwxyz"), hash3));
+
+ byte[] hash4 = {0xd1, 0x74, 0xab, 0x98, 0xd2, 0x77, 0xd9, 0xf5, 0xa5, 0x61, 0x1c, 0x2c, 0x9f, 0x41, 0x9d, 0x9f};
+ suite.AddTest (new MD5HashingTest ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", Encoding.UTF8.GetBytes("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"), hash4));
+
+ return suite;
+ }
+ }
+ }
+}
+
diff --git a/mcs/class/corlib/System.Security.Cryptography.Test/SHA1Test.cs b/mcs/class/corlib/System.Security.Cryptography.Test/SHA1Test.cs
new file mode 100644
index 00000000000..7493bed891c
--- /dev/null
+++ b/mcs/class/corlib/System.Security.Cryptography.Test/SHA1Test.cs
@@ -0,0 +1,82 @@
+//
+// System.Security.Cryptography.Test SHA1 NUnit test classes.
+//
+// Author:
+// Matthew S. Ford (Matthew.S.Ford@Rose-Hulman.Edu)
+//
+// Copyright 2001 by Matthew S. Ford.
+//
+
+using NUnit.Framework;
+using System;
+using System.Security.Cryptography;
+using System.Text;
+
+namespace System.Security.Cryptography.Test {
+ public class SHA1HashingTest : TestCase {
+ byte[] _dataToHash;
+ byte[] _expectedHash;
+
+ public SHA1HashingTest (string name, byte[] dataToHash, byte[] expectedHash) : base(name) {
+ _dataToHash = dataToHash;
+ _expectedHash = expectedHash;
+ }
+
+ public static bool ArrayEquals (byte[] arr1, byte[] arr2) {
+ int i;
+ if (arr1.GetLength(0) != arr2.GetLength(0))
+ return false;
+
+ for (i=0; i<arr1.GetLength(0); i++) {
+ if (arr1[i] != arr2[i])
+ return false;
+ }
+
+ return true;
+ }
+
+ protected override void RunTest () {
+ SHA1 sha = new SHA1CryptoServiceProvider ();
+ byte[] hash;
+
+ hash = sha.ComputeHash (_dataToHash);
+
+ Assert (ArrayEquals (hash, _expectedHash));
+ }
+
+ }
+
+ public class SHA1TestSet {
+ public SHA1TestSet () {
+
+ }
+
+ public static void Main () {
+
+ }
+
+ public static ITest Suite {
+ get {
+ TestSuite suite = new TestSuite ();
+
+ byte[] hash0 = {0xDA, 0x39, 0xA3, 0xEE, 0x5E, 0x6B, 0x4B, 0x0D, 0x32, 0x55, 0xBF, 0xEF, 0x95, 0x60, 0x18, 0x90, 0xAF, 0xD8, 0x07, 0x09};
+ suite.AddTest (new SHA1HashingTest ("(blank hash)", new byte[0], hash0));
+
+ byte[] hash1 = {0x86, 0xF7, 0xE4, 0x37, 0xFA, 0xA5, 0xA7, 0xFC, 0xE1, 0x5D, 0x1D, 0xDC, 0xB9, 0xEA, 0xEA, 0xEA, 0x37, 0x76, 0x67, 0xB8};
+ suite.AddTest (new SHA1HashingTest ("a", Encoding.UTF8.GetBytes("a"), hash1));
+
+ byte[] hash2 = {0xA9, 0x99, 0x3E, 0x36, 0x47, 0x06, 0x81, 0x6A, 0xBA, 0x3E, 0x25, 0x71, 0x78, 0x50, 0xC2, 0x6C, 0x9C, 0xD0, 0xD8, 0x9D};
+ suite.AddTest (new SHA1HashingTest ("abc", Encoding.UTF8.GetBytes("abc"), hash2));
+
+ byte[] hash3 = {0x32, 0xD1, 0x0C, 0x7B, 0x8C, 0xF9, 0x65, 0x70, 0xCA, 0x04, 0xCE, 0x37, 0xF2, 0xA1, 0x9D, 0x84, 0x24, 0x0D, 0x3A, 0x89};
+ suite.AddTest (new SHA1HashingTest ("abcdefghijklmnopqrstuvwxyz", Encoding.UTF8.GetBytes("abcdefghijklmnopqrstuvwxyz"), hash3));
+
+ byte[] hash4 = {0x84, 0x98, 0x3E, 0x44, 0x1C, 0x3B, 0xD2, 0x6E, 0xBA, 0xAE, 0x4A, 0xA1, 0xF9, 0x51, 0x29, 0xE5, 0xE5, 0x46, 0x70, 0xF1};
+ suite.AddTest (new SHA1HashingTest ("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", Encoding.UTF8.GetBytes("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"), hash4));
+
+ return suite;
+ }
+ }
+ }
+}
+
diff --git a/mcs/class/corlib/System.Security.Cryptography.Test/SHA256Test.cs b/mcs/class/corlib/System.Security.Cryptography.Test/SHA256Test.cs
new file mode 100644
index 00000000000..33a6411ad1b
--- /dev/null
+++ b/mcs/class/corlib/System.Security.Cryptography.Test/SHA256Test.cs
@@ -0,0 +1,82 @@
+//
+// System.Security.Cryptography.Test SHA256 NUnit test classes.
+//
+// Author:
+// Matthew S. Ford (Matthew.S.Ford@Rose-Hulman.Edu)
+//
+// Copyright 2001 by Matthew S. Ford.
+//
+
+using NUnit.Framework;
+using System;
+using System.Security.Cryptography;
+using System.Text;
+
+namespace System.Security.Cryptography.Test {
+ public class SHA256HashingTest : TestCase {
+ byte[] _dataToHash;
+ byte[] _expectedHash;
+
+ public SHA256HashingTest (string name, byte[] dataToHash, byte[] expectedHash) : base(name) {
+ _dataToHash = dataToHash;
+ _expectedHash = expectedHash;
+ }
+
+ public static bool ArrayEquals (byte[] arr1, byte[] arr2) {
+ int i;
+ if (arr1.GetLength(0) != arr2.GetLength(0))
+ return false;
+
+ for (i=0; i<arr1.GetLength(0); i++) {
+ if (arr1[i] != arr2[i])
+ return false;
+ }
+
+ return true;
+ }
+
+ protected override void RunTest () {
+ SHA256 sha = new SHA256Managed ();
+ byte[] hash;
+
+ hash = sha.ComputeHash (_dataToHash);
+
+ Assert (ArrayEquals (hash, _expectedHash));
+ }
+
+ }
+
+ public class SHA256TestSet {
+ public SHA256TestSet () {
+
+ }
+
+ public static void Main () {
+
+ }
+
+ public static ITest Suite {
+ get {
+ TestSuite suite = new TestSuite ();
+
+ byte[] hash0 = {0xBA, 0x78, 0x16, 0xBF, 0x8F, 0x01, 0xCF, 0xEA, 0x41, 0x41, 0x40, 0xDE, 0x5D, 0xAE, 0x22, 0x23, 0xB0, 0x03, 0x61, 0xA3, 0x96, 0x17, 0x7A, 0x9C, 0xB4, 0x10, 0xFF, 0x61, 0xF2, 0x00, 0x15, 0xAD};
+ suite.AddTest (new SHA256HashingTest ("abc", Encoding.UTF8.GetBytes("abc"), hash0));
+
+ byte[] hash1 = {0x24, 0x8D, 0x6A, 0x61, 0xD2, 0x06, 0x38, 0xB8, 0xE5, 0xC0, 0x26, 0x93, 0x0C, 0x3E, 0x60, 0x39, 0xA3, 0x3C, 0xE4, 0x59, 0x64, 0xFF, 0x21, 0x67, 0xF6, 0xEC, 0xED, 0xD4, 0x19, 0xDB, 0x06, 0xC1};
+ suite.AddTest (new SHA256HashingTest ("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", Encoding.UTF8.GetBytes("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"), hash1));
+
+ //byte[] hash2 = {};
+ //suite.AddTest (new SHA256HashingTest ("abc", Encoding.UTF8.GetBytes("abc"), hash2));
+
+ //byte[] hash3 = {};
+ //suite.AddTest (new SHA256HashingTest ("abcdefghijklmnopqrstuvwxyz", Encoding.UTF8.GetBytes("abcdefghijklmnopqrstuvwxyz"), hash3));
+
+ //byte[] hash4 = {};
+ //suite.AddTest (new SHA256HashingTest ("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", Encoding.UTF8.GetBytes("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"), hash4));
+
+ return suite;
+ }
+ }
+ }
+}
+
diff --git a/mcs/class/corlib/System.Security.Cryptography.Test/SHA384Test.cs b/mcs/class/corlib/System.Security.Cryptography.Test/SHA384Test.cs
new file mode 100644
index 00000000000..b928b1b0e03
--- /dev/null
+++ b/mcs/class/corlib/System.Security.Cryptography.Test/SHA384Test.cs
@@ -0,0 +1,82 @@
+//
+// System.Security.Cryptography.Test SHA384 NUnit test classes.
+//
+// Author:
+// Matthew S. Ford (Matthew.S.Ford@Rose-Hulman.Edu)
+//
+// Copyright 2001 by Matthew S. Ford.
+//
+
+using NUnit.Framework;
+using System;
+using System.Security.Cryptography;
+using System.Text;
+
+namespace System.Security.Cryptography.Test {
+ public class SHA384HashingTest : TestCase {
+ byte[] _dataToHash;
+ byte[] _expectedHash;
+
+ public SHA384HashingTest (string name, byte[] dataToHash, byte[] expectedHash) : base(name) {
+ _dataToHash = dataToHash;
+ _expectedHash = expectedHash;
+ }
+
+ public static bool ArrayEquals (byte[] arr1, byte[] arr2) {
+ int i;
+ if (arr1.GetLength(0) != arr2.GetLength(0))
+ return false;
+
+ for (i=0; i<arr1.GetLength(0); i++) {
+ if (arr1[i] != arr2[i])
+ return false;
+ }
+
+ return true;
+ }
+
+ protected override void RunTest () {
+ SHA384 sha = new SHA384Managed ();
+ byte[] hash;
+
+ hash = sha.ComputeHash (_dataToHash);
+
+ Assert (ArrayEquals (hash, _expectedHash));
+ }
+
+ }
+
+ public class SHA384TestSet {
+ public SHA384TestSet () {
+
+ }
+
+ public static void Main () {
+
+ }
+
+ public static ITest Suite {
+ get {
+ TestSuite suite = new TestSuite ();
+
+ byte[] hash0 = {0xCB, 0x00, 0x75, 0x3F, 0x45, 0xA3, 0x5E, 0x8B, 0xB5, 0xA0, 0x3D, 0x69, 0x9A, 0xC6, 0x50, 0x07, 0x27, 0x2C, 0x32, 0xAB, 0x0E, 0xDE, 0xD1, 0x63, 0x1A, 0x8B, 0x60, 0x5A, 0x43, 0xFF, 0x5B, 0xED, 0x80, 0x86, 0x07, 0x2B, 0xA1, 0xE7, 0xCC, 0x23, 0x58, 0xBA, 0xEC, 0xA1, 0x34, 0xC8, 0x25, 0xA7};
+ suite.AddTest (new SHA384HashingTest ("abc", Encoding.UTF8.GetBytes("abc"), hash0));
+
+ byte[] hash1 = {0x09, 0x33, 0x0C, 0x33, 0xF7, 0x11, 0x47, 0xE8, 0x3D, 0x19, 0x2F, 0xC7, 0x82, 0xCD, 0x1B, 0x47, 0x53, 0x11, 0x1B, 0x17, 0x3B, 0x3B, 0x05, 0xD2, 0x2F, 0xA0, 0x80, 0x86, 0xE3, 0xB0, 0xF7, 0x12, 0xFC, 0xC7, 0xC7, 0x1A, 0x55, 0x7E, 0x2D, 0xB9, 0x66, 0xC3, 0xE9, 0xFA, 0x91, 0x74, 0x60, 0x39};
+ suite.AddTest (new SHA384HashingTest ("abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", Encoding.UTF8.GetBytes("abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"), hash1));
+
+ //byte[] hash2 = {};
+ //suite.AddTest (new SHA384HashingTest ("abc", Encoding.UTF8.GetBytes("abc"), hash2));
+
+ //byte[] hash3 = {};
+ //suite.AddTest (new SHA384HashingTest ("abcdefghijklmnopqrstuvwxyz", Encoding.UTF8.GetBytes("abcdefghijklmnopqrstuvwxyz"), hash3));
+
+ //byte[] hash4 = {};
+ //suite.AddTest (new SHA384HashingTest ("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", Encoding.UTF8.GetBytes("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"), hash4));
+
+ return suite;
+ }
+ }
+ }
+}
+
diff --git a/mcs/class/corlib/System.Security.Cryptography.Test/SHA512Test.cs b/mcs/class/corlib/System.Security.Cryptography.Test/SHA512Test.cs
new file mode 100644
index 00000000000..fb61c648e4e
--- /dev/null
+++ b/mcs/class/corlib/System.Security.Cryptography.Test/SHA512Test.cs
@@ -0,0 +1,82 @@
+//
+// System.Security.Cryptography.Test SHA512 NUnit test classes.
+//
+// Author:
+// Matthew S. Ford (Matthew.S.Ford@Rose-Hulman.Edu)
+//
+// Copyright 2001 by Matthew S. Ford.
+//
+
+using NUnit.Framework;
+using System;
+using System.Security.Cryptography;
+using System.Text;
+
+namespace System.Security.Cryptography.Test {
+ public class SHA512HashingTest : TestCase {
+ byte[] _dataToHash;
+ byte[] _expectedHash;
+
+ public SHA512HashingTest (string name, byte[] dataToHash, byte[] expectedHash) : base(name) {
+ _dataToHash = dataToHash;
+ _expectedHash = expectedHash;
+ }
+
+ public static bool ArrayEquals (byte[] arr1, byte[] arr2) {
+ int i;
+ if (arr1.GetLength(0) != arr2.GetLength(0))
+ return false;
+
+ for (i=0; i<arr1.GetLength(0); i++) {
+ if (arr1[i] != arr2[i])
+ return false;
+ }
+
+ return true;
+ }
+
+ protected override void RunTest () {
+ SHA512 sha = new SHA512Managed ();
+ byte[] hash;
+
+ hash = sha.ComputeHash (_dataToHash);
+
+ Assert (ArrayEquals (hash, _expectedHash));
+ }
+
+ }
+
+ public class SHA512TestSet {
+ public SHA512TestSet () {
+
+ }
+
+ public static void Main () {
+
+ }
+
+ public static ITest Suite {
+ get {
+ TestSuite suite = new TestSuite ();
+
+ byte[] hash0 = {0xDD, 0xAF, 0x35, 0xA1, 0x93, 0x61, 0x7A, 0xBA, 0xCC, 0x41, 0x73, 0x49, 0xAE, 0x20, 0x41, 0x31, 0x12, 0xE6, 0xFA, 0x4E, 0x89, 0xA9, 0x7E, 0xA2, 0x0A, 0x9E, 0xEE, 0xE6, 0x4B, 0x55, 0xD3, 0x9A, 0x21, 0x92, 0x99, 0x2A, 0x27, 0x4F, 0xC1, 0xA8, 0x36, 0xBA, 0x3C, 0x23, 0xA3, 0xFE, 0xEB, 0xBD, 0x45, 0x4D, 0x44, 0x23, 0x64, 0x3C, 0xE8, 0x0E, 0x2A, 0x9A, 0xC9, 0x4F, 0xA5, 0x4C, 0xA4, 0x9F};
+ suite.AddTest (new SHA512HashingTest ("abc", Encoding.UTF8.GetBytes("abc"), hash0));
+
+ byte[] hash1 = {0x8E, 0x95, 0x9B, 0x75, 0xDA, 0xE3, 0x13, 0xDA, 0x8C, 0xF4, 0xF7, 0x28, 0x14, 0xFC, 0x14, 0x3F, 0x8F, 0x77, 0x79, 0xC6, 0xEB, 0x9F, 0x7F, 0xA1, 0x72, 0x99, 0xAE, 0xAD, 0xB6, 0x88, 0x90, 0x18, 0x50, 0x1D, 0x28, 0x9E, 0x49, 0x00, 0xF7, 0xE4, 0x33, 0x1B, 0x99, 0xDE, 0xC4, 0xB5, 0x43, 0x3A, 0xC7, 0xD3, 0x29, 0xEE, 0xB6, 0xDD, 0x26, 0x54, 0x5E, 0x96, 0xE5, 0x5B, 0x87, 0x6B, 0xE9, 0x09};
+ suite.AddTest (new SHA512HashingTest ("abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", Encoding.UTF8.GetBytes("abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"), hash1));
+
+ //byte[] hash2 = {};
+ //suite.AddTest (new SHA512HashingTest ("abc", Encoding.UTF8.GetBytes("abc"), hash2));
+
+ //byte[] hash3 = {};
+ //suite.AddTest (new SHA512HashingTest ("abcdefghijklmnopqrstuvwxyz", Encoding.UTF8.GetBytes("abcdefghijklmnopqrstuvwxyz"), hash3));
+
+ //byte[] hash4 = {};
+ //suite.AddTest (new SHA512HashingTest ("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", Encoding.UTF8.GetBytes("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"), hash4));
+
+ return suite;
+ }
+ }
+ }
+}
+
diff --git a/mcs/class/corlib/System.Security.Cryptography.Test/ToBase64TransformTest.cs b/mcs/class/corlib/System.Security.Cryptography.Test/ToBase64TransformTest.cs
new file mode 100644
index 00000000000..b9d3c962bc0
--- /dev/null
+++ b/mcs/class/corlib/System.Security.Cryptography.Test/ToBase64TransformTest.cs
@@ -0,0 +1,230 @@
+//
+// ToBase64TransformTest
+//
+// Author:
+// Sergey Chaban (serge@wildwestsoftware.com)
+//
+
+using System;
+using System.Security.Cryptography;
+
+using NUnit.Framework;
+
+
+namespace System.Security.Cryptography.Test {
+
+ /// <summary>
+ /// ToBase64Transform test suite.
+ /// </summary>
+ public class ToBase64TransformTest {
+
+ public static ITest Suite {
+ get {
+ TestSuite suite = new TestSuite("ToBase64Transform tests");
+ suite.AddTest(ToBase64TransformTestCase.Suite);
+ return suite;
+ }
+ }
+
+
+ public class ToBase64TransformTestCase : TestCase {
+
+ public ToBase64TransformTestCase (String name) : base(name)
+ {
+ }
+
+ protected override void SetUp ()
+ {
+ }
+
+ public static ITest Suite
+ {
+ get {
+ Console.WriteLine("Testing " + (new ToBase64Transform ()));
+ return new TestSuite(typeof(ToBase64TransformTestCase));
+ }
+ }
+
+
+
+
+ //
+ // Tests
+ //
+
+ public void TestProperties ()
+ {
+ ToBase64Transform encoder = new ToBase64Transform ();
+
+ Assert ("Wrong input block size!", encoder.InputBlockSize == 3);
+ Assert ("Wrong output block size!", encoder.OutputBlockSize == 4);
+ Assert ("Should be unable to transform multiple blocks!", !encoder.CanTransformMultipleBlocks);
+
+ }
+
+
+/*
+// FIXME: Well, according to Beta2 docs an exception should be thrown here,
+// since "data size is not valid". Nothing happens in Beta2 though.
+// So just ignore this for now.
+
+ public void TestException ()
+ {
+ ToBase64Transform encoder = new ToBase64Transform ();
+
+ byte [] res = new byte [4];
+ bool thrown = false;
+ try {
+ encoder.TransformBlock (new byte [] {1,2,3,4,5},0,5,res,0);
+ } catch (CryptographicException) {
+ thrown = true;
+ }
+ Assert (thrown);
+ }
+*/
+
+
+ public void TestFullBlockEncoding ()
+ {
+ ToBase64Transform encoder = new ToBase64Transform ();
+ byte [] res = new byte [encoder.OutputBlockSize];
+
+ foreach (Base64TestCase testCase in fullBlockTests) {
+ Base64TestCase tmp = new Base64TestCase ();
+ tmp.flat = testCase.flat;
+ int n = encoder.TransformBlock (testCase.GetFlat(),0,3,res,0);
+ AssertEquals(n, encoder.OutputBlockSize);
+ tmp.SetEncoded(res);
+ AssertEquals(testCase,tmp);
+ }
+
+ }
+
+
+
+ public void TestFinalBlockEncoding ()
+ {
+ ToBase64Transform encoder = new ToBase64Transform ();
+
+ foreach (Base64TestCase testCase in finalBlockTests) {
+ Base64TestCase tmp = new Base64TestCase ();
+ tmp.flat = testCase.flat;
+ byte [] res = encoder.TransformFinalBlock (testCase.GetFlat(),0,testCase.flat.Length);
+ tmp.SetEncoded(res);
+ AssertEquals(testCase,tmp);
+ }
+
+ }
+
+
+ Base64TestCase [] fullBlockTests = {
+ new Base64TestCase("ABC","QUJD"),
+ new Base64TestCase("123","MTIz"),
+ new Base64TestCase(new byte [] {125,24,215},"fRjX")
+ };
+
+
+ Base64TestCase [] finalBlockTests = {
+ new Base64TestCase("AB","QUI="),
+ new Base64TestCase("1","MQ=="),
+ new Base64TestCase(new byte [] {125,24},"fRg=")
+ };
+
+
+
+
+
+
+ //
+ // Test helper
+ //
+ private class Base64TestCase {
+ public string flat;
+ public string encoded;
+
+ public Base64TestCase () : this ("","")
+ {
+ }
+
+ public Base64TestCase (Base64TestCase that)
+ {
+ this.flat = that.flat;
+ this.encoded = that.encoded;
+ }
+
+ public Base64TestCase (byte [] flat, string encoded)
+ {
+ SetFlat (flat);
+ this.encoded = encoded;
+ }
+
+ public Base64TestCase (string flat, string encoded)
+ {
+ this.flat = flat;
+ this.encoded = encoded;
+ }
+
+ public void SetEncoded (byte [] encoded)
+ {
+ String enc="";
+
+ for (int i = 0; i < encoded.Length; i++)
+ enc += (char) encoded[i];
+
+ this.encoded = enc;
+ }
+
+ public void SetFlat (byte [] flat)
+ {
+ String flt="";
+
+ for (int i=0; i < flat.Length; i++)
+ flt += (char) flat[i];
+
+ this.flat = flt;
+ }
+
+ public byte [] GetFlat ()
+ {
+ byte [] res = new byte [flat.Length];
+ for (int i = 0; i < flat.Length; i++)
+ res [i] = (byte) flat [i];
+ return res;
+ }
+
+ public static bool operator == (Base64TestCase t1, Base64TestCase t2)
+ {
+ return (t1.flat.Equals (t2.flat) &&
+ t1.encoded.Equals (t2.encoded));
+ }
+
+ public static bool operator != (Base64TestCase t1, Base64TestCase t2)
+ {
+ return !(t1 == t2);
+ }
+
+ public override bool Equals (object o)
+ {
+ return (o is Base64TestCase)
+ && (this == (o as Base64TestCase));
+ }
+
+ public override int GetHashCode ()
+ {
+ return flat.GetHashCode () ^ (encoded.GetHashCode () << 2);
+ }
+
+ public override string ToString ()
+ {
+ return "Flat = " + flat + ", encoded = " + encoded;
+ }
+ }
+
+ } // ToBase64TransformTestCase
+
+
+
+
+ } // ToBase64TransformTest
+
+} // System.Security.Cryptography.Test
diff --git a/mcs/class/corlib/System.Security.Cryptography/ChangeLog b/mcs/class/corlib/System.Security.Cryptography/ChangeLog
new file mode 100644
index 00000000000..2796ccff57a
--- /dev/null
+++ b/mcs/class/corlib/System.Security.Cryptography/ChangeLog
@@ -0,0 +1,31 @@
+2001-08-20 Sergey Chaban <serge@wildwestsoftware.com>
+
+ * DES.cs encryption core is about 30% faster than previous version.
+ * DESCryptoServiceProvider.cs added PKCS-5 padding.
+
+2001-08-09 Sergey Chaban <serge@wildwestsoftware.com>
+
+ * ToBase64Transform.cs: Base64Table now supports both encoding
+ and decoding tables. As a result Table was renamed to EncodeTable
+ and DecodeTable was added.
+ * FromBase64Transform.cs: Initial check-in.
+ * DES.cs: Initial check-in.
+ * DESCryptoServiceProvider.cs: Initial check-in.
+
+2001-08-01 Matthew S. Ford <Matthew.S.Ford@Rose-Hulman.Edu>
+
+ * CipherMode.cs: Initial version.
+ * CryptoStreamMode.cs: Initial version.
+ * HashAlgorithm.cs: Initial version.
+ * ICryptoTransform.cs: Initial version.
+ * KeySizes.cs: Initial version.
+ * MD5.cs: Initial version.
+ * MD5CryptoServiceProvider.cs: Initial version.
+ * PaddingMode.cs: Initial version.
+ * SHA1.cs: Initial version.
+ * SHA1CryptoServiceProvider.cs: Initial version.
+ * SHA256.cs: Initial version.
+ * SHA256Managed.cs: Initial version.
+ * SHA384.cs: Initial version.
+ * SHA512.cs: Initial version.
+
diff --git a/mcs/class/corlib/System.Security.Cryptography/CipherMode.cs b/mcs/class/corlib/System.Security.Cryptography/CipherMode.cs
new file mode 100644
index 00000000000..e2cab26df53
--- /dev/null
+++ b/mcs/class/corlib/System.Security.Cryptography/CipherMode.cs
@@ -0,0 +1,24 @@
+//
+// System.Security.Cryptography CipherMode enumeration
+//
+// Authors:
+// Matthew S. Ford (Matthew.S.Ford@Rose-Hulman.Edu)
+//
+// Copyright 2001 by Matthew S. Ford.
+//
+
+
+namespace System.Security.Cryptography {
+
+ /// <summary>
+ /// Block cipher modes of operation.
+ /// </summary>
+ public enum CipherMode {
+ CBC, // Cipher Block Chaining
+ CFB, // Cipher Feedback
+ CTS, // Cipher Text Stealing
+ ECB, // Electronic Codebook
+ OFB // Output Feedback
+ }
+}
+
diff --git a/mcs/class/corlib/System.Security.Cryptography/CryptoStreamMode.cs b/mcs/class/corlib/System.Security.Cryptography/CryptoStreamMode.cs
new file mode 100644
index 00000000000..6e08107b7d2
--- /dev/null
+++ b/mcs/class/corlib/System.Security.Cryptography/CryptoStreamMode.cs
@@ -0,0 +1,20 @@
+//
+// System.Security.Cryptography CryptoStreamMode enumeration
+//
+// Authors:
+// Matthew S. Ford (Matthew.S.Ford@Rose-Hulman.Edu)
+//
+// Copyright 2001 by authors.
+//
+
+namespace System.Security.Cryptography {
+
+ /// <summary>
+ /// FIXME (the comment): Whether the crypto-stream is in read mode or write mode?
+ /// </summary>
+ public enum CryptoStreamMode {
+ Read,
+ Write
+ }
+}
+
diff --git a/mcs/class/corlib/System.Security.Cryptography/DES.cs b/mcs/class/corlib/System.Security.Cryptography/DES.cs
new file mode 100644
index 00000000000..b6a83356420
--- /dev/null
+++ b/mcs/class/corlib/System.Security.Cryptography/DES.cs
@@ -0,0 +1,585 @@
+//
+// System.Security.Cryptography.DES
+//
+// Author:
+// Sergey Chaban (serge@wildwestsoftware.com)
+//
+
+using System;
+using System.Security.Cryptography;
+
+// References: FIPS PUB 46-3
+
+namespace System.Security.Cryptography {
+
+ internal sealed class DESCore {
+
+ internal static readonly int KEY_BIT_SIZE = 64;
+ internal static readonly int KEY_BYTE_SIZE = KEY_BIT_SIZE / 8;
+ internal static readonly int BLOCK_BIT_SIZE = 64;
+ internal static readonly int BLOCK_BYTE_SIZE = BLOCK_BIT_SIZE / 8;
+
+ private byte [] keySchedule;
+ private byte [] byteBuff;
+ private uint [] dwordBuff;
+
+ internal delegate void DESCall (byte [] block, byte [] output);
+
+
+ // Ek(Ek(m)) = m
+ internal static ulong [] weakKeys = {
+ 0x0101010101010101, /* 0000000 0000000 */
+ 0xFEFEFEFEFEFEFEFE, /* FFFFFFF FFFFFFF */
+ 0x1F1F1F1FE0E0E0E0, /* 0000000 FFFFFFF */
+ 0xE0E0E0E01F1F1F1F /* FFFFFFF 0000000 */
+ };
+
+ // Ek1(Ek2(m)) = m
+ internal static ulong [] semiweakKeys = {
+ 0x01FE01FE01FE01FE, 0xFE01FE01FE01FE01,
+ 0x1FE01FE00EF10EF1, 0xE01FE01FF10EF10E,
+ 0x01E001E001F101F1, 0xE001E001F101F101,
+ 0x1FFE1FFE0EFE0EFE, 0xFE1FFE1FFE0EFE0E,
+ 0x011F011F010E010E, 0x1F011F010E010E01,
+ 0xE0FEE0FEF1FEF1FE, 0xFEE0FEE0FEF1FEF1
+ };
+
+
+
+ // S-boxes from FIPS 46-3, Appendix 1, page 17
+ private static byte [] sBoxes = {
+ /* S1 */
+ 14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7,
+ 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8,
+ 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0,
+ 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13,
+
+ /* S2 */
+ 15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10,
+ 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5,
+ 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15,
+ 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9,
+
+ /* S3 */
+ 10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8,
+ 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1,
+ 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7,
+ 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12,
+
+ /* S4 */
+ 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15,
+ 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9,
+ 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4,
+ 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14,
+
+ /* S5 */
+ 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9,
+ 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6,
+ 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14,
+ 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3,
+
+ /* S6 */
+ 12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11,
+ 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8,
+ 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6,
+ 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13,
+
+ /* S7 */
+ 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1,
+ 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6,
+ 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2,
+ 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12,
+
+ /* S8 */
+ 13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7,
+ 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2,
+ 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8,
+ 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11
+ };
+
+
+ // P table from page 15, also in Appendix 1, page 18
+ private static byte [] pTab = {
+ 16-1, 7-1, 20-1, 21-1,
+ 29-1, 12-1, 28-1, 17-1,
+ 1-1, 15-1, 23-1, 26-1,
+ 5-1, 18-1, 31-1, 10-1,
+ 2-1, 8-1, 24-1, 14-1,
+ 32-1, 27-1, 3-1, 9-1,
+ 19-1, 13-1, 30-1, 6-1,
+ 22-1, 11-1, 4-1, 25-1
+ };
+
+
+ // Permuted choice 1 table, PC-1, page 19
+ // Translated to zero-based format.
+ private static byte [] PC1 = {
+ 57-1, 49-1, 41-1, 33-1, 25-1, 17-1, 9-1,
+ 1-1, 58-1, 50-1, 42-1, 34-1, 26-1, 18-1,
+ 10-1, 2-1, 59-1, 51-1, 43-1, 35-1, 27-1,
+ 19-1, 11-1, 3-1, 60-1, 52-1, 44-1, 36-1,
+
+ 63-1, 55-1, 47-1, 39-1, 31-1, 23-1, 15-1,
+ 7-1, 62-1, 54-1, 46-1, 38-1, 30-1, 22-1,
+ 14-1, 6-1, 61-1, 53-1, 45-1, 37-1, 29-1,
+ 21-1, 13-1, 5-1, 28-1, 20-1, 12-1, 4-1
+ };
+
+
+ private static byte [] leftRot = {
+ 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1
+ };
+
+ private static byte [] leftRotTotal;
+
+
+
+ // Permuted choice 2 table, PC-2, page 21
+ // Translated to zero-based format.
+ private static byte [] PC2 = {
+ 14-1, 17-1, 11-1, 24-1, 1-1, 5-1,
+ 3-1, 28-1, 15-1, 6-1, 21-1, 10-1,
+ 23-1, 19-1, 12-1, 4-1, 26-1, 8-1,
+ 16-1, 7-1, 27-1, 20-1, 13-1, 2-1,
+ 41-1, 52-1, 31-1, 37-1, 47-1, 55-1,
+ 30-1, 40-1, 51-1, 45-1, 33-1, 48-1,
+ 44-1, 49-1, 39-1, 56-1, 34-1, 53-1,
+ 46-1, 42-1, 50-1, 36-1, 29-1, 32-1
+ };
+
+
+ // Initial permutation IP, page 10.
+ // Transposed to 0-based format.
+ private static byte [] ipBits = {
+ 58-1, 50-1, 42-1, 34-1, 26-1, 18-1, 10-1, 2-1,
+ 60-1, 52-1, 44-1, 36-1, 28-1, 20-1, 12-1, 4-1,
+ 62-1, 54-1, 46-1, 38-1, 30-1, 22-1, 14-1, 6-1,
+ 64-1, 56-1, 48-1, 40-1, 32-1, 24-1, 16-1, 8-1,
+ 57-1, 49-1, 41-1, 33-1, 25-1, 17-1, 9-1, 1-1,
+ 59-1, 51-1, 43-1, 35-1, 27-1, 19-1, 11-1, 3-1,
+ 61-1, 53-1, 45-1, 37-1, 29-1, 21-1, 13-1, 5-1,
+ 63-1, 55-1, 47-1, 39-1, 31-1, 23-1, 15-1, 7-1
+ };
+
+
+ // Final permutation FP = IP^(-1), page 10.
+ // Transposed to 0-based format.
+ private static byte [] fpBits = {
+ 40-1, 8-1, 48-1, 16-1, 56-1, 24-1, 64-1, 32-1,
+ 39-1, 7-1, 47-1, 15-1, 55-1, 23-1, 63-1, 31-1,
+ 38-1, 6-1, 46-1, 14-1, 54-1, 22-1, 62-1, 30-1,
+ 37-1, 5-1, 45-1, 13-1, 53-1, 21-1, 61-1, 29-1,
+ 36-1, 4-1, 44-1, 12-1, 52-1, 20-1, 60-1, 28-1,
+ 35-1, 3-1, 43-1, 11-1, 51-1, 19-1, 59-1, 27-1,
+ 34-1, 2-1, 42-1, 10-1, 50-1, 18-1, 58-1, 26-1,
+ 33-1, 1-1, 41-1, 9-1, 49-1, 17-1, 57-1, 25-1
+ };
+
+
+
+ private static uint [] spBoxes;
+ private static int [] ipTab;
+ private static int [] fpTab;
+
+
+ static DESCore ()
+ {
+ spBoxes = new uint [64 * 8];
+
+ int [] pBox = new int [32];
+
+ for (int p = 0; p < 32; p++) {
+ for (int i = 0; i < 32; i++) {
+ if (p == pTab [i]) {
+ pBox [p] = i;
+ break;
+ }
+ }
+ }
+
+
+ for (int s = 0; s < 8; s++) { // for each S-box
+ int sOff = s << 6;
+
+ for (int i = 0; i < 64; i++) { // inputs
+ uint sp=0;
+
+ int indx = (i & 0x20) | ((i & 1) << 4) | ((i >> 1) & 0xF);
+
+ for (int j = 0; j < 4; j++) { // for each bit in the output
+ if ((sBoxes [sOff + indx] & (8 >> j)) != 0) {
+ sp |= (uint) (1 << (31 - pBox [(s << 2) + j]));
+ }
+ }
+
+ spBoxes [sOff + i] = sp;
+ }
+ }
+
+
+ leftRotTotal = new byte [leftRot.Length];
+
+
+ for (int i = 0; i < leftRot.Length; i++) {
+ int r = 0;
+ for (int j = 0; j <= i; r += leftRot [j++]);
+ leftRotTotal [i] = (byte) r;
+ }
+
+
+ InitPermutationTable (ipBits, out ipTab);
+ InitPermutationTable (fpBits, out fpTab);
+
+ } // class constructor
+
+
+
+ // Default constructor.
+ internal DESCore ()
+ {
+ keySchedule = new byte [KEY_BYTE_SIZE * 16];
+ byteBuff = new byte [BLOCK_BYTE_SIZE];
+ dwordBuff = new uint [BLOCK_BYTE_SIZE / 4];
+ }
+
+
+
+
+ private static void InitPermutationTable (byte [] pBits, out int [] permTab)
+ {
+ permTab = new int [8*2 * 8*2 * (64/32)];
+
+ for (int i = 0; i < 16; i++) {
+ for (int j = 0; j < 16; j++) {
+ int offs = (i << 5) + (j << 1);
+ for (int n = 0; n < 64; n++) {
+ int bitNum = (int) pBits [n];
+ if ((bitNum >> 2 == i) &&
+ 0 != (j & (8 >> (bitNum & 3)))) {
+ permTab [offs + (n >> (3+2))] |= (int) ((0x80808080 & (0xFF << (n & (3 << 3)))) >> (n & 7));
+ }
+ }
+ }
+ }
+ }
+
+
+
+ internal static ulong PackKey (byte [] key)
+ {
+ ulong res = 0;
+ for (int i = 0, sh = 8*KEY_BYTE_SIZE; (sh = sh - 8) >= 0; i++) {
+ res |= (ulong) key [i] << sh;
+ }
+ return res;
+ }
+
+
+
+ internal static byte [] UnpackKey (ulong key)
+ {
+ byte [] res = new byte [KEY_BYTE_SIZE];
+ for (int i = 0, sh = 8*KEY_BYTE_SIZE; (sh = sh - 8) >= 0; i++) {
+ res [i] = (byte) (key >> sh);
+ }
+ return res;
+ }
+
+
+
+ internal static bool IsValidKeySize (byte [] key)
+ {
+ return (key.Length == KEY_BYTE_SIZE);
+ }
+
+
+
+ private uint CipherFunct(uint r, int n)
+ {
+ uint res = 0;
+ byte [] subkey = keySchedule;
+ int i = n << 3;
+
+ uint rt = (r >> 1) | (r << 31); // ROR32(r)
+ res |= spBoxes [0*64 + (((rt >> 26) ^ subkey [i++]) & 0x3F)];
+ res |= spBoxes [1*64 + (((rt >> 22) ^ subkey [i++]) & 0x3F)];
+ res |= spBoxes [2*64 + (((rt >> 18) ^ subkey [i++]) & 0x3F)];
+ res |= spBoxes [3*64 + (((rt >> 14) ^ subkey [i++]) & 0x3F)];
+ res |= spBoxes [4*64 + (((rt >> 10) ^ subkey [i++]) & 0x3F)];
+ res |= spBoxes [5*64 + (((rt >> 6) ^ subkey [i++]) & 0x3F)];
+ res |= spBoxes [6*64 + (((rt >> 2) ^ subkey [i++]) & 0x3F)];
+ rt = (r << 1) | (r >> 31); // ROL32(r)
+ res |= spBoxes [7*64 + ((rt ^ subkey [i]) & 0x3F)];
+
+ return res;
+ }
+
+
+ private static void Permutation (byte [] input, byte [] _output, int [] permTab, bool preSwap)
+ {
+
+ if (preSwap) BSwap (input);
+
+ byte [] output = _output;
+
+ int offs1 = (((int)(input [0]) >> 4)) << 1;
+ int offs2 = (1 << 5) + ((((int)input [0]) & 0xF) << 1);
+
+ int d1 = permTab [offs1++] | permTab [offs2++];
+ int d2 = permTab [offs1] | permTab [offs2];
+
+
+ int max = BLOCK_BYTE_SIZE << 1;
+ for (int i = 2, indx = 1; i < max; i += 2, indx++) {
+ int ii = (int) input [indx];
+ offs1 = (i << 5) + ((ii >> 4) << 1);
+ offs2 = ((i + 1) << 5) + ((ii & 0xF) << 1);
+
+ d1 |= permTab [offs1++] | permTab [offs2++];
+ d2 |= permTab [offs1] | permTab [offs2];
+ }
+
+ if (preSwap) {
+ output [0] = (byte) (d1);
+ output [1] = (byte) (d1 >> 8);
+ output [2] = (byte) (d1 >> 16);
+ output [3] = (byte) (d1 >> 24);
+ output [4] = (byte) (d2);
+ output [5] = (byte) (d2 >> 8);
+ output [6] = (byte) (d2 >> 16);
+ output [7] = (byte) (d2 >> 24);
+ } else {
+ output [0] = (byte) (d1 >> 24);
+ output [1] = (byte) (d1 >> 16);
+ output [2] = (byte) (d1 >> 8);
+ output [3] = (byte) (d1);
+ output [4] = (byte) (d2 >> 24);
+ output [5] = (byte) (d2 >> 16);
+ output [6] = (byte) (d2 >> 8);
+ output [7] = (byte) (d2);
+ }
+ }
+
+
+
+
+ private static void BSwap (byte [] byteBuff)
+ {
+ byte t;
+
+ t = byteBuff [0];
+ byteBuff [0] = byteBuff [3];
+ byteBuff [3] = t;
+
+ t = byteBuff [1];
+ byteBuff [1] = byteBuff [2];
+ byteBuff [2] = t;
+
+ t = byteBuff [4];
+ byteBuff [4] = byteBuff [7];
+ byteBuff [7] = t;
+
+ t = byteBuff [5];
+ byteBuff [5] = byteBuff [6];
+ byteBuff [6] = t;
+ }
+
+
+
+ internal void SetKey (byte [] key)
+ {
+ // NOTE: see Fig. 3, Key schedule calculation, at page 20.
+
+ Array.Clear (keySchedule, 0, keySchedule.Length);
+
+ int keyBitSize = PC1.Length;
+
+ byte [] keyPC1 = new byte [keyBitSize]; // PC1-permuted key
+ byte [] keyRot = new byte [keyBitSize]; // PC1 & rotated
+
+ int indx = 0;
+
+ foreach (byte bitPos in PC1) {
+ keyPC1 [indx++] = (byte)((key [(int)bitPos >> 3] >> (7 ^ (bitPos & 7))) & 1);
+ }
+
+
+
+
+ int j;
+ for (int i = 0; i < KEY_BYTE_SIZE*2; i++) {
+ int b = keyBitSize >> 1;
+
+ for (j = 0; j < b; j++) {
+ int s = j + (int) leftRotTotal [i];
+ keyRot [j] = keyPC1 [s < b ? s : s - b];
+ }
+
+ for (j = b; j < keyBitSize; j++) {
+ int s = j + (int) leftRotTotal [i];
+ keyRot [j] = keyPC1 [s < keyBitSize ? s : s - b];
+ }
+
+ int keyOffs = i * KEY_BYTE_SIZE;
+
+ j = 0;
+ foreach (byte bitPos in PC2) {
+ if (keyRot [(int)bitPos] != 0) {
+ keySchedule [keyOffs + (j/6)] |= (byte) (0x80 >> ((j % 6) + 2));
+ }
+ j++;
+ }
+ }
+
+ }
+
+
+
+ internal void Encrypt (byte [] block, byte [] output)
+ {
+ byte [] dest = (output == null ? block : output);
+
+ byte [] byteBuff = this.byteBuff;
+ uint [] dwordBuff = this.dwordBuff;
+
+ Permutation (block, byteBuff, ipTab, false);
+
+ Buffer.BlockCopy (byteBuff, 0, dwordBuff, 0, BLOCK_BYTE_SIZE);
+
+ uint d0 = dwordBuff[0];
+ uint d1 = dwordBuff[1];
+
+ // 16 rounds
+ d0 ^= CipherFunct (d1, 0);
+ d1 ^= CipherFunct (d0, 1);
+ d0 ^= CipherFunct (d1, 2);
+ d1 ^= CipherFunct (d0, 3);
+ d0 ^= CipherFunct (d1, 4);
+ d1 ^= CipherFunct (d0, 5);
+ d0 ^= CipherFunct (d1, 6);
+ d1 ^= CipherFunct (d0, 7);
+ d0 ^= CipherFunct (d1, 8);
+ d1 ^= CipherFunct (d0, 9);
+ d0 ^= CipherFunct (d1, 10);
+ d1 ^= CipherFunct (d0, 11);
+ d0 ^= CipherFunct (d1, 12);
+ d1 ^= CipherFunct (d0, 13);
+ d0 ^= CipherFunct (d1, 14);
+ d1 ^= CipherFunct (d0, 15);
+
+
+ dwordBuff [0] = d1;
+ dwordBuff [1] = d0;
+ Buffer.BlockCopy (dwordBuff, 0, byteBuff, 0, BLOCK_BYTE_SIZE);
+
+ Permutation (byteBuff, dest, fpTab, true);
+ }
+
+
+ internal void Decrypt (byte [] block, byte [] output)
+ {
+ byte [] dest = (output == null ? block : output);
+
+ byte [] byteBuff = this.byteBuff;
+ uint [] dwordBuff = this.dwordBuff;
+
+ Permutation (block, byteBuff, ipTab, false);
+
+ Buffer.BlockCopy (byteBuff, 0, dwordBuff, 0, BLOCK_BYTE_SIZE);
+
+ uint d1 = dwordBuff [0];
+ uint d0 = dwordBuff [1];
+
+ // 16 rounds in reverse order
+ d1 ^= CipherFunct (d0, 15);
+ d0 ^= CipherFunct (d1, 14);
+ d1 ^= CipherFunct (d0, 13);
+ d0 ^= CipherFunct (d1, 12);
+ d1 ^= CipherFunct (d0, 11);
+ d0 ^= CipherFunct (d1, 10);
+ d1 ^= CipherFunct (d0, 9);
+ d0 ^= CipherFunct (d1, 8);
+ d1 ^= CipherFunct (d0, 7);
+ d0 ^= CipherFunct (d1, 6);
+ d1 ^= CipherFunct (d0, 5);
+ d0 ^= CipherFunct (d1, 4);
+ d1 ^= CipherFunct (d0, 3);
+ d0 ^= CipherFunct (d1, 2);
+ d1 ^= CipherFunct (d0, 1);
+ d0 ^= CipherFunct (d1, 0);
+
+ dwordBuff [0] = d0;
+ dwordBuff [1] = d1;
+
+
+ Buffer.BlockCopy (dwordBuff, 0, byteBuff, 0, BLOCK_BYTE_SIZE);
+
+ Permutation (byteBuff, dest, fpTab, true);
+ }
+
+
+ } // DESCore
+
+
+
+
+ public abstract class DES : SymmetricAlgorithm {
+ private byte [] key;
+
+ public DES ()
+ {
+ }
+
+ public static new DES Create()
+ {
+ // TODO: implement
+ return null;
+ }
+
+ public static new DES Create(string name)
+ {
+ // TODO: implement
+ return null;
+ }
+
+
+ public static bool IsWeakKey (byte [] rgbKey)
+ {
+ if (!DESCore.IsValidKeySize (rgbKey)) {
+ throw new CryptographicException ();
+ }
+
+ ulong lk = DESCore.PackKey (rgbKey);
+ foreach (ulong wk in DESCore.weakKeys) {
+ if (lk == wk) return true;
+ }
+ return false;
+ }
+
+
+ public static bool IsSemiWeakKey (byte [] rgbKey)
+ {
+ if (!DESCore.IsValidKeySize (rgbKey)) {
+ throw new CryptographicException ();
+ }
+
+ ulong lk = DESCore.PackKey (rgbKey);
+ foreach (ulong swk in DESCore.semiweakKeys) {
+ if (lk == swk) return true;
+ }
+ return false;
+ }
+
+ public override byte[] Key {
+ get {
+ return this.key;
+ }
+ set {
+ this.key = new byte [DESCore.KEY_BYTE_SIZE];
+ Array.Copy (value, 0, this.key, 0, DESCore.KEY_BYTE_SIZE);
+ }
+ }
+
+ } // DES
+
+} // System.Security.Cryptography
diff --git a/mcs/class/corlib/System.Security.Cryptography/DESCryptoServiceProvider.cs b/mcs/class/corlib/System.Security.Cryptography/DESCryptoServiceProvider.cs
new file mode 100644
index 00000000000..4188b2231e8
--- /dev/null
+++ b/mcs/class/corlib/System.Security.Cryptography/DESCryptoServiceProvider.cs
@@ -0,0 +1,248 @@
+//
+// System.Security.Cryptography.DESCryptoServiceProvider
+//
+// Author:
+// Sergey Chaban (serge@wildwestsoftware.com)
+//
+
+
+
+using System;
+using System.Security.Cryptography;
+
+
+namespace System.Security.Cryptography {
+
+
+ internal class DESTransformBase : ICryptoTransform {
+
+ internal enum Mode : int {
+ ENCRYPTOR = 0,
+ DECRYPTOR = 1
+ }
+
+ protected delegate void Filter (byte [] workBuff);
+
+ private DESCore core;
+
+ private DESCore.DESCall cryptFn;
+ private Filter preprocess;
+ private Filter postprocess;
+
+ private byte [] iv;
+ private byte [] tmpBlock;
+
+ protected DESTransformBase (Mode mode, byte [] key, byte [] iv)
+ {
+ core = new DESCore ();
+
+ if (mode == Mode.ENCRYPTOR) {
+ cryptFn = new DESCore.DESCall (core.Encrypt);
+ preprocess = new Filter (this.EncPreprocess);
+ postprocess = new Filter (this.EncPostprocess);
+ } else {
+ cryptFn = new DESCore.DESCall (core.Decrypt);
+ preprocess = new Filter (this.DecPreprocess);
+ postprocess = new Filter (this.DecPostprocess);
+ }
+
+ core.SetKey (key);
+ this.iv = new byte [DESCore.BLOCK_BYTE_SIZE];
+ Array.Copy (iv, 0, this.iv, 0, DESCore.BLOCK_BYTE_SIZE);
+
+ tmpBlock = new byte [DESCore.BLOCK_BYTE_SIZE];
+ }
+
+
+ public virtual bool CanTransformMultipleBlocks {
+ get {
+ return true;
+ }
+ }
+
+
+ public virtual int InputBlockSize {
+ get {
+ return DESCore.BLOCK_BYTE_SIZE;
+ }
+ }
+
+ public virtual int OutputBlockSize {
+ get {
+ return DESCore.BLOCK_BYTE_SIZE;
+ }
+ }
+
+ private void EncPreprocess (byte [] workBuff)
+ {
+ byte [] iv = this.iv;
+ for (int i = 0; i < DESCore.BLOCK_BYTE_SIZE; i++) {
+ workBuff [i] ^= iv [i];
+ }
+ }
+
+ private void EncPostprocess (byte [] workBuff)
+ {
+ Array.Copy (workBuff, 0, iv, 0, DESCore.BLOCK_BYTE_SIZE);
+ }
+
+
+ private void DecPreprocess (byte [] workBuff)
+ {
+ Array.Copy (workBuff, 0, tmpBlock, 0, DESCore.BLOCK_BYTE_SIZE);
+ }
+
+ private void DecPostprocess (byte [] workBuff)
+ {
+ EncPreprocess (workBuff);
+ Array.Copy (tmpBlock, 0, iv, 0, DESCore.BLOCK_BYTE_SIZE);
+ }
+
+
+
+ private void Transform (byte [] workBuff)
+ {
+ preprocess (workBuff);
+ cryptFn (workBuff, null);
+ postprocess (workBuff);
+ }
+
+
+ public virtual int TransformBlock (byte [] inputBuffer, int inputOffset, int inputCount, byte [] outputBuffer, int outputOffset)
+ {
+ if ((inputCount & (DESCore.BLOCK_BYTE_SIZE-1)) != 0)
+ throw new CryptographicException ("Invalid input block size.");
+
+ if (outputOffset + inputCount > outputBuffer.Length)
+ throw new CryptographicException ("Insufficient output buffer size.");
+
+ int step = InputBlockSize;
+ int offs = inputOffset;
+ int full = inputCount / step;
+
+ byte [] workBuff = new byte [step];
+
+ for (int i = 0; i < full; i++) {
+ Array.Copy (inputBuffer, offs, workBuff, 0, step);
+ Transform (workBuff);
+ Array.Copy (workBuff, 0, outputBuffer, outputOffset, step);
+ offs += step;
+ outputOffset += step;
+ }
+
+ return (full * step);
+ }
+
+
+ public virtual byte [] TransformFinalBlock (byte [] inputBuffer, int inputOffset, int inputCount)
+ {
+ // TODO: add decryption support
+
+ int num = (inputCount + DESCore.BLOCK_BYTE_SIZE) & (~(DESCore.BLOCK_BYTE_SIZE-1));
+ byte [] res = new byte [num];
+ int full = num - DESCore.BLOCK_BYTE_SIZE;
+
+ TransformBlock (inputBuffer, inputOffset, full, res, 0);
+
+ int rem = inputCount & (DESCore.BLOCK_BYTE_SIZE-1);
+
+ // PKCS-5 padding
+ for (int i = num; --i >= (num - rem);) {
+ res [i] = (byte) rem;
+ }
+
+ Array.Copy (inputBuffer, inputOffset + full, res, full, rem);
+
+ // the last padded block will be transformed in-place
+ TransformBlock (res, full, DESCore.BLOCK_BYTE_SIZE, res, full);
+
+ /*
+ byte [] workBuff = new byte [DESCore.BLOCK_BYTE_SIZE];
+ Array.Copy (res, full, workBuff, 0, DESCore.BLOCK_BYTE_SIZE);
+ preprocess (workBuff);
+ cryptFn (workBuff, null);
+ Array.Copy (workBuff, 0, res, full, DESCore.BLOCK_BYTE_SIZE);
+ */
+
+ return res;
+ }
+
+
+ } // DESTransformBase
+
+
+ internal sealed class DESEncryptor : DESTransformBase {
+ internal DESEncryptor (byte [] key, byte [] iv)
+ : base (DESTransformBase.Mode.ENCRYPTOR, key, iv)
+ {
+ }
+ } // DESEncryptor
+
+
+ internal sealed class DESDecryptor : DESTransformBase {
+ internal DESDecryptor (byte [] key, byte [] iv)
+ : base (DESTransformBase.Mode.DECRYPTOR, key, iv)
+ {
+ }
+ } // DESDecryptor
+
+
+ public class DESCryptoServiceProvider {
+ private byte [] iv;
+ private byte [] key;
+
+ public DESCryptoServiceProvider ()
+ {
+ }
+
+
+ //
+ // Factories
+ //
+
+ public virtual ICryptoTransform CreateEncryptor()
+ {
+ return new DESEncryptor (key, iv);
+ }
+
+ public virtual ICryptoTransform CreateDecryptor()
+ {
+ return new DESDecryptor (key, iv);
+ }
+
+
+
+ // FIXME: Ought to be in DES.cs
+
+ public /*override*/ byte[] Key {
+ get {
+ return this.key;
+ }
+ set {
+ this.key = new byte [DESCore.KEY_BYTE_SIZE];
+ Array.Copy (value, 0, this.key, 0, DESCore.KEY_BYTE_SIZE);
+ }
+ }
+
+ public virtual byte[] IV {
+ get {
+ return this.iv;
+ }
+ set {
+ this.iv = new byte [DESCore.KEY_BYTE_SIZE];
+ Array.Copy (value, 0, this.iv, 0, DESCore.KEY_BYTE_SIZE);
+ }
+ }
+
+
+
+
+
+ public override string ToString ()
+ {
+ return "mono::System.Security.Cryptography.DESCryptoServiceProvider";
+ }
+
+ } // DESCryptoServiceProvider
+
+} // System.Security.Cryptography
diff --git a/mcs/class/corlib/System.Security.Cryptography/FromBase64Transform.cs b/mcs/class/corlib/System.Security.Cryptography/FromBase64Transform.cs
new file mode 100644
index 00000000000..16a2f597a8f
--- /dev/null
+++ b/mcs/class/corlib/System.Security.Cryptography/FromBase64Transform.cs
@@ -0,0 +1,264 @@
+//
+// System.Security.Cryptography.FromBase64Transform
+//
+// Author:
+// Sergey Chaban (serge@wildwestsoftware.com)
+//
+
+using System;
+using System.Security.Cryptography;
+
+
+namespace System.Security.Cryptography {
+
+ public enum FromBase64TransformMode : int {
+ IgnoreWhiteSpaces,
+ DoNotIgnoreWhiteSpaces
+ }
+
+ public class FromBase64Transform : ICryptoTransform {
+
+ private FromBase64TransformMode mode;
+ private byte [] accumulator;
+ private byte [] filterBuffer;
+ private int accPtr;
+
+
+ /// <summary>
+ /// Creates a new instance of the decoder
+ /// with the default transformation mode (IgnoreWhiteSpaces).
+ /// </summary>
+ public FromBase64Transform ()
+ : this (FromBase64TransformMode.IgnoreWhiteSpaces)
+ {
+ }
+
+
+ /// <summary>
+ /// Creates a new instance of the decoder
+ /// with the specified transformation mode.
+ /// </summary>
+ public FromBase64Transform (FromBase64TransformMode mode)
+ {
+ this.mode = mode;
+ accumulator = new byte [4];
+ filterBuffer = new byte [4];
+ accPtr = 0;
+ }
+
+
+ /// <summary>
+ /// </summary>
+ public virtual bool CanTransformMultipleBlocks {
+ get {
+ return false;
+ }
+ }
+
+
+ /// <summary>
+ /// Returns the input block size for the Base64 decoder.
+ /// </summary>
+ /// <remarks>
+ /// The input block size for Base64 decoder is always 1 byte.
+ /// </remarks>
+ public virtual int InputBlockSize {
+ get {
+ return 1;
+ }
+ }
+
+
+ /// <summary>
+ /// Returns the output block size for the Base64 decoder.
+ /// </summary>
+ /// <remarks>
+ /// The value returned by this property is always 3.
+ /// </remarks>
+ public virtual int OutputBlockSize {
+ get {
+ return 3;
+ }
+ }
+
+
+
+ private int Filter (byte [] buffer, int offset, int count)
+ {
+ int end = offset + count;
+ int len = filterBuffer.Length;
+ int ptr = 0;
+ byte [] filter = this.filterBuffer;
+
+ for (int i = offset; i < end; i++) {
+ byte b = buffer [i];
+ if (!Char.IsWhiteSpace ((char) b)) {
+ if (ptr >= len) {
+ len <<= 1;
+ this.filterBuffer = new byte [len];
+ Array.Copy(filter, 0, this.filterBuffer, 0, len >> 1);
+ filter = this.filterBuffer;
+ }
+ filter [ptr++] = b;
+ }
+ }
+
+ return ptr;
+ }
+
+
+
+
+ private int DoTransform (byte [] inputBuffer,
+ int inputOffset,
+ int inputCount,
+ byte [] outputBuffer,
+ int outputOffset)
+ {
+ int full = inputCount >> 2;
+ if (full == 0) return 0;
+
+ int rem = 0;
+
+ if (inputBuffer[inputCount - 1] == (byte)'=') {
+ ++rem;
+ --full;
+ }
+
+ if (inputBuffer[inputCount - 2] == (byte)'=') ++rem;
+
+ byte [] lookup = Base64Table.DecodeTable;
+ int b0,b1,b2,b3;
+
+ for (int i = 0; i < full; i++) {
+ b0 = lookup [inputBuffer [inputOffset++]];
+ b1 = lookup [inputBuffer [inputOffset++]];
+ b2 = lookup [inputBuffer [inputOffset++]];
+ b3 = lookup [inputBuffer [inputOffset++]];
+
+ outputBuffer [outputOffset++] = (byte) ((b0 << 2) | (b1 >> 4));
+ outputBuffer [outputOffset++] = (byte) ((b1 << 4) | (b2 >> 2));
+ outputBuffer [outputOffset++] = (byte) ((b2 << 6) | b3);
+ }
+
+ int res = full * 3;
+
+ switch (rem) {
+ case 0:
+ break;
+ case 1:
+ b0 = lookup [inputBuffer [inputOffset++]];
+ b1 = lookup [inputBuffer [inputOffset++]];
+ b2 = lookup [inputBuffer [inputOffset++]];
+ outputBuffer [outputOffset++] = (byte) ((b0 << 2) | (b1 >> 4));
+ outputBuffer [outputOffset++] = (byte) ((b1 << 4) | (b2 >> 2));
+ res += 2;
+ break;
+ case 2:
+ b0 = lookup [inputBuffer [inputOffset++]];
+ b1 = lookup [inputBuffer [inputOffset++]];
+ outputBuffer [outputOffset++] = (byte) ((b0 << 2) | (b1 >> 4));
+ ++res;
+ break;
+ default:
+ break;
+ }
+
+ return res;
+ }
+
+
+ /// <summary>
+ /// </summary>
+ public virtual int TransformBlock (byte [] inputBuffer,
+ int inputOffset,
+ int inputCount,
+ byte [] outputBuffer,
+ int outputOffset)
+ {
+ int n;
+ byte [] src;
+ int srcOff;
+ int res = 0;
+
+ if (mode == FromBase64TransformMode.IgnoreWhiteSpaces) {
+ n = Filter (inputBuffer, inputOffset, inputCount);
+ src = filterBuffer;
+ srcOff = 0;
+ } else {
+ n = inputCount;
+ src = inputBuffer;
+ srcOff = inputOffset;
+ }
+
+
+ int count = accPtr + n;
+
+ if (count < 4) {
+ Array.Copy (src, srcOff, accumulator, accPtr, n);
+ accPtr = count;
+ } else {
+ byte [] tmpBuff = new byte [count];
+ Array.Copy (accumulator, 0, tmpBuff, 0, accPtr);
+ Array.Copy (src, srcOff, tmpBuff, accPtr, n);
+ accPtr = count & 3;
+ Array.Copy (src, srcOff + (n - accPtr), accumulator, 0, accPtr);
+ res = DoTransform (tmpBuff, 0, count & (~3), outputBuffer, outputOffset);
+ }
+
+
+ return res;
+ }
+
+
+
+
+
+ /// <summary>
+ /// </summary>
+ public virtual byte [] TransformFinalBlock (byte [] inputBuffer,
+ int inputOffset,
+ int inputCount)
+ {
+ byte [] src;
+ int srcOff;
+ int n;
+
+ if (mode == FromBase64TransformMode.IgnoreWhiteSpaces) {
+ n = Filter (inputBuffer, inputOffset, inputCount);
+ src = filterBuffer;
+ srcOff = 0;
+ } else {
+ n = inputCount;
+ src = inputBuffer;
+ srcOff = inputOffset;
+ }
+
+
+ int dataLen = accPtr + n;
+ byte [] tmpBuf = new byte [dataLen];
+
+ int resLen = ((dataLen) >> 2) * 3;
+ byte [] res = new byte [resLen];
+
+ Array.Copy (accumulator, 0, tmpBuf, 0, accPtr);
+ Array.Copy (src, srcOff, tmpBuf, accPtr, n);
+
+ DoTransform (tmpBuf, 0, dataLen, res, 0);
+
+ accPtr = 0;
+ return res;
+ }
+
+
+
+ /// <summary>
+ /// </summary>
+ public override string ToString ()
+ {
+ return "mono::System.Security.Cryptography.FromBase64Transform";
+ }
+
+ } // FromBase64Transform
+
+} // System.Security.Cryptography
diff --git a/mcs/class/corlib/System.Security.Cryptography/HashAlgorithm.cs b/mcs/class/corlib/System.Security.Cryptography/HashAlgorithm.cs
new file mode 100644
index 00000000000..14f6512dd4a
--- /dev/null
+++ b/mcs/class/corlib/System.Security.Cryptography/HashAlgorithm.cs
@@ -0,0 +1,153 @@
+//
+// System.Security.Cryptography HashAlgorithm Class implementation
+//
+// Authors:
+// Matthew S. Ford (Matthew.S.Ford@Rose-Hulman.Edu)
+//
+// Copyright 2001 by Matthew S. Ford.
+//
+
+
+using System.Security.Cryptography;
+
+namespace System.Security.Cryptography {
+ public abstract class HashAlgorithm : ICryptoTransform {
+ protected byte[] HashValue; // Caches the hash after it is calculated. Accessed through the Hash property.
+ protected int HashSizeValue; // The size of the hash in bits.
+ protected int State; // nonzero when in use; zero when not in use
+
+ /// <summary>
+ /// Called from constructor of derived class.
+ /// </summary>
+ protected HashAlgorithm () {
+
+ }
+
+
+ /// <summary>
+ /// FIXME: Always true for hashes?
+ /// Get whether or not the hash can transform multiple blocks at a time.
+ /// </summary>
+ public virtual bool CanTransformMultipleBlocks {
+ get {
+ return true;
+ }
+ }
+
+ /// <summary>
+ /// Computes the entire hash of all the bytes in the byte array.
+ /// </summary>
+ public virtual byte[] ComputeHash (byte[] input) {
+ // inputData = input.Clone();
+ HashCore (input, 0, input.Length);
+ HashValue = HashFinal ();
+ Initialize ();
+
+ return HashValue;
+ }
+
+ /// <summary>
+ /// Creates the default implementation of the default hash algorithm (SHA1).
+ /// </summary>
+ public static HashAlgorithm Create () {
+ return SHA1.Create ();
+ }
+
+ /// <summary>
+ /// Creates a specific implementation of the general hash idea.
+ /// </summary>
+ /// <param name="st">FIXME: No clue. Specifies which derived class to create.</param>
+ public static HashAlgorithm Create (string st) {
+ return Create ();
+ }
+
+ /// <summary>
+ /// Gets the previously computed hash.
+ /// </summary>
+ public virtual byte[] Hash {
+ get {
+ return HashValue;
+ }
+ }
+
+ /// <summary>
+ /// When overridden in a derived class, drives the hashing function.
+ /// </summary>
+ /// <param name="rgb"></param>
+ /// <param name="start"></param>
+ /// <param name="size"></param>
+ protected abstract void HashCore (byte[] rgb, int start, int size);
+
+ /// <summary>
+ /// When overridden in a derived class, this pads and hashes whatever data might be left in the buffers and then returns the hash created.
+ /// </summary>
+ protected abstract byte[] HashFinal ();
+
+ /// <summary>
+ /// Returns the size in bits of the hash.
+ /// </summary>
+ public virtual int HashSize {
+ get {
+ return HashSizeValue;
+ }
+ }
+
+ /// <summary>
+ /// When overridden in a derived class, initializes the object to prepare for hashing.
+ /// </summary>
+ public abstract void Initialize ();
+
+ /// <summary>
+ /// FIXME: Not quire valid for the hashes? Returns 1?
+ /// </summary>
+ public virtual int InputBlockSize {
+ get {
+ return 1;
+ }
+ }
+
+ /// <summary>
+ /// FIXME: Not quire valid for the hashes? Returns 1?
+ /// </summary>
+ public virtual int OutputBlockSize {
+ get {
+ return 1;
+ }
+ }
+
+ /// <summary>
+ /// Used for stream chaining. Computes hash as data passes through it.
+ /// </summary>
+ /// <param name="inputBuffer">The buffer from which to grab the data to be copied.</param>
+ /// <param name="inputOffset">The offset into the input buffer to start reading at.</param>
+ /// <param name="inputCount">The number of bytes to be copied.</param>
+ /// <param name="outputBuffer">The buffer to write the copied data to.</param>
+ /// <param name="outputOffset">At what point in the outputBuffer to write the data at.</param>
+ public int TransformBlock (byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset) {
+
+ Buffer.BlockCopy (inputBuffer, inputOffset, outputBuffer, outputOffset, inputCount);
+ HashCore (inputBuffer, inputOffset, inputCount);
+
+ return inputCount;
+ }
+
+ /// <summary>
+ /// Used for stream chaining. Computes hash as data passes through it. Finishes off the hash.
+ /// </summary>
+ /// <param name="inputBuffer">The buffer from which to grab the data to be copied.</param>
+ /// <param name="inputOffset">The offset into the input buffer to start reading at.</param>
+ /// <param name="inputCount">The number of bytes to be copied.</param>
+ public byte[] TransformFinalBlock (byte[] inputBuffer, int inputOffset, int inputCount) {
+ byte[] outputBuffer = new byte[inputCount];
+
+ Buffer.BlockCopy (inputBuffer, inputOffset, outputBuffer, 0, inputCount);
+
+ HashCore (inputBuffer, inputOffset, inputCount);
+ HashValue = HashFinal ();
+ Initialize ();
+
+ return outputBuffer;
+ }
+ }
+}
+
diff --git a/mcs/class/corlib/System.Security.Cryptography/ICryptoTransform.cs b/mcs/class/corlib/System.Security.Cryptography/ICryptoTransform.cs
new file mode 100644
index 00000000000..f3d1f0e0df8
--- /dev/null
+++ b/mcs/class/corlib/System.Security.Cryptography/ICryptoTransform.cs
@@ -0,0 +1,49 @@
+//
+// System.Security.Cryptography ICryptoTransform interface
+//
+// Authors:
+// Matthew S. Ford (Matthew.S.Ford@Rose-Hulman.Edu)
+//
+// Copyright 2001 by Matthew S. Ford.
+//
+
+
+using System.Security.Cryptography;
+
+namespace System.Security.Cryptography {
+
+ /// <summary>
+ /// Crytographic functions that can process a stream of bytes implement this interface.
+ /// This works by stringing together one or more ICryptoTransform classes with a stream.
+ /// Data is passed from one to the next without the need of outside buffering/intervention.
+ /// </summary>
+ public interface ICryptoTransform {
+
+ /// <summary>
+ /// Whether the function can transform multiple blocks at a time.
+ /// </summary>
+ bool CanTransformMultipleBlocks {get;}
+
+ /// <summary>
+ /// Size of input blocks for the function.
+ /// </summary>
+ int InputBlockSize {get;}
+
+ /// <summary>
+ /// Size of the output blocks of the function.
+ /// </summary>
+ int OutputBlockSize {get;}
+
+ /// <summary>
+ /// FIXME: Process some data. A block at a time? Less than a block at a time?
+ /// </summary>
+ int TransformBlock (byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset);
+
+ /// <summary>
+ /// Processes the final part of the data. Also finalizes the function if needed.
+ /// </summary>
+ byte[] TransformFinalBlock (byte[] inputBuffer, int inputOffset, int inputCount);
+
+ }
+}
+
diff --git a/mcs/class/corlib/System.Security.Cryptography/KeySizes.cs b/mcs/class/corlib/System.Security.Cryptography/KeySizes.cs
new file mode 100644
index 00000000000..5fef7ec0908
--- /dev/null
+++ b/mcs/class/corlib/System.Security.Cryptography/KeySizes.cs
@@ -0,0 +1,61 @@
+//
+// System.Security.Cryptography KeySizes Class implementation
+//
+// Author:
+// Matthew S. Ford (Matthew.S.Ford@Rose-Hulman.Edu)
+//
+// Copyright 2001 by Matthew S. Ford.
+//
+
+
+namespace System.Security.Cryptography {
+
+ /// <summary>
+ /// This class represents valid ranges of key sizes for ciphers. It is also used to represent block sizes in the same fashion for block ciphers.
+ /// </summary>
+ public class KeySizes {
+ private int _maxSize;
+ private int _minSize;
+ private int _skipSize;
+
+ /// <summary>
+ /// Creates a new KeySizes object.
+ /// </summary>
+ /// <param name="minSize">The minimum size key allowed for this cipher.</param>
+ /// <param name="maxSize">The maximum size key allowed for this cipher.</param>
+ /// <param name="skipSize">The jump/skip between the valid key sizes.</param>
+ public KeySizes (int minSize, int maxSize, int skipSize) {
+ _maxSize = maxSize;
+ _minSize = minSize;
+ _skipSize = skipSize;
+ }
+
+ /// <summary>
+ /// Returns the maximum valid key size;
+ /// </summary>
+ public int MaxSize {
+ get {
+ return _maxSize;
+ }
+ }
+
+ /// <summary>
+ /// Returns the minimum valid key size;
+ /// </summary>
+ public int MinSize {
+ get {
+ return _minSize;
+ }
+ }
+
+ /// <summary>
+ /// Returns the skip between valid key sizes;
+ /// </summary>
+ public int SkipSize {
+ get {
+ return _skipSize;
+ }
+ }
+ }
+}
+
diff --git a/mcs/class/corlib/System.Security.Cryptography/MD5.cs b/mcs/class/corlib/System.Security.Cryptography/MD5.cs
new file mode 100644
index 00000000000..934769edf97
--- /dev/null
+++ b/mcs/class/corlib/System.Security.Cryptography/MD5.cs
@@ -0,0 +1,43 @@
+//
+// System.Security.Cryptography MD5 Class implementation
+//
+// Authors:
+// Matthew S. Ford (Matthew.S.Ford@Rose-Hulman.Edu)
+//
+// Copyright 2001 by Matthew S. Ford.
+//
+
+
+using System.Security.Cryptography;
+
+namespace System.Security.Cryptography {
+
+ /// <summary>
+ /// Common base class for all derived MD5 iplementations.
+ /// </summary>
+ public abstract class MD5 : HashAlgorithm {
+
+ /// <summary>
+ /// Called from constructor of derived class.
+ /// </summary>
+ protected MD5 () {
+
+ }
+
+ /// <summary>
+ /// Creates the default derived class.
+ /// </summary>
+ public static new MD5 Create () {
+ return new MD5CryptoServiceProvider();
+ }
+
+ /// <summary>
+ /// Creates a new derived implementation.
+ /// </summary>
+ /// <param name="st">FIXME: No clue. Specifies which derived class to create?</param>
+ public static new MD5 Create (string st) {
+ return Create();
+ }
+ }
+}
+
diff --git a/mcs/class/corlib/System.Security.Cryptography/MD5CryptoServiceProvider.cs b/mcs/class/corlib/System.Security.Cryptography/MD5CryptoServiceProvider.cs
new file mode 100644
index 00000000000..5d8d8f2d1f4
--- /dev/null
+++ b/mcs/class/corlib/System.Security.Cryptography/MD5CryptoServiceProvider.cs
@@ -0,0 +1,482 @@
+//
+// System.Security.Cryptography MD5CryptoServiceProvider Class implementation
+//
+// Authors:
+// Matthew S. Ford (Matthew.S.Ford@Rose-Hulman.Edu)
+//
+// Copyright 2001 by Matthew S. Ford.
+//
+
+
+using System.Security.Cryptography;
+
+namespace System.Security.Cryptography {
+
+ /// <summary>
+ /// C# implementation of the MD5 cryptographic hash function.
+ /// </summary>
+ public class MD5CryptoServiceProvider : MD5 {
+ private const int BLOCK_SIZE_BYTES = 64;
+ private const int HASH_SIZE_BYTES = 16;
+ private const int HASH_SIZE_BITS = 128;
+ protected uint[] _H;
+ protected uint count;
+ private byte[] _ProcessingBuffer; // Used to start data when passed less than a block worth.
+ private int _ProcessingBufferCount; // Counts how much data we have stored that still needs processed.
+
+ /// <summary>
+ /// Creates a new MD5CryptoServiceProvider.
+ /// </summary>
+ public MD5CryptoServiceProvider () {
+ _H = new uint[4];
+ HashSizeValue = HASH_SIZE_BITS;
+ _ProcessingBuffer = new byte[BLOCK_SIZE_BYTES];
+
+ Initialize();
+ }
+
+ /// <summary>
+ /// Drives the hashing function.
+ /// </summary>
+ /// <param name="rgb">Byte array containing the data to hash.</param>
+ /// <param name="start">Where in the input buffer to start.</param>
+ /// <param name="size">Size in bytes of the data in the buffer to hash.</param>
+ protected override void HashCore (byte[] rgb, int start, int size) {
+ int i;
+ State = 1;
+
+ if (_ProcessingBufferCount != 0) {
+ if (size < (BLOCK_SIZE_BYTES - _ProcessingBufferCount)) {
+ System.Buffer.BlockCopy (rgb, start, _ProcessingBuffer, _ProcessingBufferCount, size);
+ _ProcessingBufferCount += size;
+ return;
+ }
+ else {
+ i = (BLOCK_SIZE_BYTES - _ProcessingBufferCount);
+ System.Buffer.BlockCopy (rgb, start, _ProcessingBuffer, _ProcessingBufferCount, i);
+ ProcessBlock (_ProcessingBuffer, 0);
+ _ProcessingBufferCount = 0;
+ start += i;
+ size -= i;
+ }
+ }
+
+ for (i=0; i<size-size%BLOCK_SIZE_BYTES; i += BLOCK_SIZE_BYTES) {
+ ProcessBlock (rgb, start+i);
+ }
+
+ if (size%BLOCK_SIZE_BYTES != 0) {
+ System.Buffer.BlockCopy (rgb, size-size%BLOCK_SIZE_BYTES+start, _ProcessingBuffer, 0, size%BLOCK_SIZE_BYTES);
+ _ProcessingBufferCount = size%BLOCK_SIZE_BYTES;
+ }
+ }
+
+ /// <summary>
+ /// This finalizes the hash. Takes the data from the chaining variables and returns it.
+ /// </summary>
+ protected override byte[] HashFinal () {
+ byte[] hash = new byte[16];
+ int i, j;
+
+ ProcessFinalBlock(_ProcessingBuffer, 0, _ProcessingBufferCount);
+
+ for (i=0; i<4; i++) {
+ for (j=0; j<4; j++) {
+ hash[i*4+j] = (byte)(_H[i] >> j*8);
+ }
+ }
+
+ return hash;
+ }
+
+ /// <summary>
+ /// Resets the class after use. Called automatically after hashing is done.
+ /// </summary>
+ public override void Initialize () {
+ count = 0;
+ _ProcessingBufferCount = 0;
+
+ _H[0] = 0x67452301;
+ _H[1] = 0xefcdab89;
+ _H[2] = 0x98badcfe;
+ _H[3] = 0x10325476;
+ }
+
+ /// <summary>
+ /// This is the meat of the hash function. It is what processes each block one at a time.
+ /// </summary>
+ /// <param name="inputBuffer">Byte array to process data from.</param>
+ /// <param name="inputOffset">Where in the byte array to start processing.</param>
+ private void ProcessBlock(byte[] inputBuffer, int inputOffset) {
+ uint[] buff = new uint[16];
+ uint a, b, c, d;
+ int i;
+
+ count += BLOCK_SIZE_BYTES;
+
+ for (i=0; i<16; i++) {
+ buff[i] = (uint)(inputBuffer[inputOffset+4*i])
+ | (((uint)(inputBuffer[inputOffset+4*i+1])) << 8)
+ | (((uint)(inputBuffer[inputOffset+4*i+2])) << 16)
+ | (((uint)(inputBuffer[inputOffset+4*i+3])) << 24);
+ }
+
+ a = _H[0];
+ b = _H[1];
+ c = _H[2];
+ d = _H[3];
+
+ // This function was unrolled because it seems to be doubling our performance with current compiler/VM.
+ // Possibly roll up if this changes.
+
+
+ // ---- Round 1 --------
+
+ a += (((c ^ d) & b) ^ d) + (uint) Constants.C0 + buff [0];
+ a = (a << 7) | (a >> 25);
+ a += b;
+
+ d += (((b ^ c) & a) ^ c) + (uint) Constants.C1 + buff [1];
+ d = (d << 12) | (d >> 20);
+ d += a;
+
+ c += (((a ^ b) & d) ^ b) + (uint) Constants.C2 + buff [2];
+ c = (c << 17) | (c >> 15);
+ c += d;
+
+ b += (((d ^ a) & c) ^ a) + (uint) Constants.C3 + buff [3];
+ b = (b << 22) | (b >> 10);
+ b += c;
+
+ a += (((c ^ d) & b) ^ d) + (uint) Constants.C4 + buff [4];
+ a = (a << 7) | (a >> 25);
+ a += b;
+
+ d += (((b ^ c) & a) ^ c) + (uint) Constants.C5 + buff [5];
+ d = (d << 12) | (d >> 20);
+ d += a;
+
+ c += (((a ^ b) & d) ^ b) + (uint) Constants.C6 + buff [6];
+ c = (c << 17) | (c >> 15);
+ c += d;
+
+ b += (((d ^ a) & c) ^ a) + (uint) Constants.C7 + buff [7];
+ b = (b << 22) | (b >> 10);
+ b += c;
+
+ a += (((c ^ d) & b) ^ d) + (uint) Constants.C8 + buff [8];
+ a = (a << 7) | (a >> 25);
+ a += b;
+
+ d += (((b ^ c) & a) ^ c) + (uint) Constants.C9 + buff [9];
+ d = (d << 12) | (d >> 20);
+ d += a;
+
+ c += (((a ^ b) & d) ^ b) + (uint) Constants.C10 + buff [10];
+ c = (c << 17) | (c >> 15);
+ c += d;
+
+ b += (((d ^ a) & c) ^ a) + (uint) Constants.C11 + buff [11];
+ b = (b << 22) | (b >> 10);
+ b += c;
+
+ a += (((c ^ d) & b) ^ d) + (uint) Constants.C12 + buff [12];
+ a = (a << 7) | (a >> 25);
+ a += b;
+
+ d += (((b ^ c) & a) ^ c) + (uint) Constants.C13 + buff [13];
+ d = (d << 12) | (d >> 20);
+ d += a;
+
+ c += (((a ^ b) & d) ^ b) + (uint) Constants.C14 + buff [14];
+ c = (c << 17) | (c >> 15);
+ c += d;
+
+ b += (((d ^ a) & c) ^ a) + (uint) Constants.C15 + buff [15];
+ b = (b << 22) | (b >> 10);
+ b += c;
+
+
+ // ---- Round 2 --------
+
+ a += (((b ^ c) & d) ^ c) + (uint) Constants.C16 + buff [1];
+ a = (a << 5) | (a >> 27);
+ a += b;
+
+ d += (((a ^ b) & c) ^ b) + (uint) Constants.C17 + buff [6];
+ d = (d << 9) | (d >> 23);
+ d += a;
+
+ c += (((d ^ a) & b) ^ a) + (uint) Constants.C18 + buff [11];
+ c = (c << 14) | (c >> 18);
+ c += d;
+
+ b += (((c ^ d) & a) ^ d) + (uint) Constants.C19 + buff [0];
+ b = (b << 20) | (b >> 12);
+ b += c;
+
+ a += (((b ^ c) & d) ^ c) + (uint) Constants.C20 + buff [5];
+ a = (a << 5) | (a >> 27);
+ a += b;
+
+ d += (((a ^ b) & c) ^ b) + (uint) Constants.C21 + buff [10];
+ d = (d << 9) | (d >> 23);
+ d += a;
+
+ c += (((d ^ a) & b) ^ a) + (uint) Constants.C22 + buff [15];
+ c = (c << 14) | (c >> 18);
+ c += d;
+
+ b += (((c ^ d) & a) ^ d) + (uint) Constants.C23 + buff [4];
+ b = (b << 20) | (b >> 12);
+ b += c;
+
+ a += (((b ^ c) & d) ^ c) + (uint) Constants.C24 + buff [9];
+ a = (a << 5) | (a >> 27);
+ a += b;
+
+ d += (((a ^ b) & c) ^ b) + (uint) Constants.C25 + buff [14];
+ d = (d << 9) | (d >> 23);
+ d += a;
+
+ c += (((d ^ a) & b) ^ a) + (uint) Constants.C26 + buff [3];
+ c = (c << 14) | (c >> 18);
+ c += d;
+
+ b += (((c ^ d) & a) ^ d) + (uint) Constants.C27 + buff [8];
+ b = (b << 20) | (b >> 12);
+ b += c;
+
+ a += (((b ^ c) & d) ^ c) + (uint) Constants.C28 + buff [13];
+ a = (a << 5) | (a >> 27);
+ a += b;
+
+ d += (((a ^ b) & c) ^ b) + (uint) Constants.C29 + buff [2];
+ d = (d << 9) | (d >> 23);
+ d += a;
+
+ c += (((d ^ a) & b) ^ a) + (uint) Constants.C30 + buff [7];
+ c = (c << 14) | (c >> 18);
+ c += d;
+
+ b += (((c ^ d) & a) ^ d) + (uint) Constants.C31 + buff [12];
+ b = (b << 20) | (b >> 12);
+ b += c;
+
+
+ // ---- Round 3 --------
+
+ a += (b ^ c ^ d) + (uint) Constants.C32 + buff [5];
+ a = (a << 4) | (a >> 28);
+ a += b;
+
+ d += (a ^ b ^ c) + (uint) Constants.C33 + buff [8];
+ d = (d << 11) | (d >> 21);
+ d += a;
+
+ c += (d ^ a ^ b) + (uint) Constants.C34 + buff [11];
+ c = (c << 16) | (c >> 16);
+ c += d;
+
+ b += (c ^ d ^ a) + (uint) Constants.C35 + buff [14];
+ b = (b << 23) | (b >> 9);
+ b += c;
+
+ a += (b ^ c ^ d) + (uint) Constants.C36 + buff [1];
+ a = (a << 4) | (a >> 28);
+ a += b;
+
+ d += (a ^ b ^ c) + (uint) Constants.C37 + buff [4];
+ d = (d << 11) | (d >> 21);
+ d += a;
+
+ c += (d ^ a ^ b) + (uint) Constants.C38 + buff [7];
+ c = (c << 16) | (c >> 16);
+ c += d;
+
+ b += (c ^ d ^ a) + (uint) Constants.C39 + buff [10];
+ b = (b << 23) | (b >> 9);
+ b += c;
+
+ a += (b ^ c ^ d) + (uint) Constants.C40 + buff [13];
+ a = (a << 4) | (a >> 28);
+ a += b;
+
+ d += (a ^ b ^ c) + (uint) Constants.C41 + buff [0];
+ d = (d << 11) | (d >> 21);
+ d += a;
+
+ c += (d ^ a ^ b) + (uint) Constants.C42 + buff [3];
+ c = (c << 16) | (c >> 16);
+ c += d;
+
+ b += (c ^ d ^ a) + (uint) Constants.C43 + buff [6];
+ b = (b << 23) | (b >> 9);
+ b += c;
+
+ a += (b ^ c ^ d) + (uint) Constants.C44 + buff [9];
+ a = (a << 4) | (a >> 28);
+ a += b;
+
+ d += (a ^ b ^ c) + (uint) Constants.C45 + buff [12];
+ d = (d << 11) | (d >> 21);
+ d += a;
+
+ c += (d ^ a ^ b) + (uint) Constants.C46 + buff [15];
+ c = (c << 16) | (c >> 16);
+ c += d;
+
+ b += (c ^ d ^ a) + (uint) Constants.C47 + buff [2];
+ b = (b << 23) | (b >> 9);
+ b += c;
+
+
+ // ---- Round 4 --------
+
+ a += (((~d) | b) ^ c) + (uint) Constants.C48 + buff [0];
+ a = (a << 6) | (a >> 26);
+ a += b;
+
+ d += (((~c) | a) ^ b) + (uint) Constants.C49 + buff [7];
+ d = (d << 10) | (d >> 22);
+ d += a;
+
+ c += (((~b) | d) ^ a) + (uint) Constants.C50 + buff [14];
+ c = (c << 15) | (c >> 17);
+ c += d;
+
+ b += (((~a) | c) ^ d) + (uint) Constants.C51 + buff [5];
+ b = (b << 21) | (b >> 11);
+ b += c;
+
+ a += (((~d) | b) ^ c) + (uint) Constants.C52 + buff [12];
+ a = (a << 6) | (a >> 26);
+ a += b;
+
+ d += (((~c) | a) ^ b) + (uint) Constants.C53 + buff [3];
+ d = (d << 10) | (d >> 22);
+ d += a;
+
+ c += (((~b) | d) ^ a) + (uint) Constants.C54 + buff [10];
+ c = (c << 15) | (c >> 17);
+ c += d;
+
+ b += (((~a) | c) ^ d) + (uint) Constants.C55 + buff [1];
+ b = (b << 21) | (b >> 11);
+ b += c;
+
+ a += (((~d) | b) ^ c) + (uint) Constants.C56 + buff [8];
+ a = (a << 6) | (a >> 26);
+ a += b;
+
+ d += (((~c) | a) ^ b) + (uint) Constants.C57 + buff [15];
+ d = (d << 10) | (d >> 22);
+ d += a;
+
+ c += (((~b) | d) ^ a) + (uint) Constants.C58 + buff [6];
+ c = (c << 15) | (c >> 17);
+ c += d;
+
+ b += (((~a) | c) ^ d) + (uint) Constants.C59 + buff [13];
+ b = (b << 21) | (b >> 11);
+ b += c;
+
+ a += (((~d) | b) ^ c) + (uint) Constants.C60 + buff [4];
+ a = (a << 6) | (a >> 26);
+ a += b;
+
+ d += (((~c) | a) ^ b) + (uint) Constants.C61 + buff [11];
+ d = (d << 10) | (d >> 22);
+ d += a;
+
+ c += (((~b) | d) ^ a) + (uint) Constants.C62 + buff [2];
+ c = (c << 15) | (c >> 17);
+ c += d;
+
+ b += (((~a) | c) ^ d) + (uint) Constants.C63 + buff [9];
+ b = (b << 21) | (b >> 11);
+ b += c;
+
+
+ _H[0] += a;
+ _H[1] += b;
+ _H[2] += c;
+ _H[3] += d;
+ }
+
+ /// <summary>
+ /// Pads and then processes the final block.
+ /// </summary>
+ /// <param name="inputBuffer">Buffer to grab data from.</param>
+ /// <param name="inputOffset">Position in buffer in bytes to get data from.</param>
+ /// <param name="inputCount">How much data in bytes in the buffer to use.</param>
+ private void ProcessFinalBlock(byte[] inputBuffer, int inputOffset, int inputCount) {
+ byte[] fooBuffer;
+ int paddingSize;
+ int i;
+ uint size;
+
+ paddingSize = (int)(56 - (inputCount + count) % BLOCK_SIZE_BYTES);
+
+ if (paddingSize < 1)
+ paddingSize += BLOCK_SIZE_BYTES;
+
+
+ fooBuffer = new byte[inputCount+paddingSize+8];
+
+ for (i=0; i<inputCount; i++) {
+ fooBuffer[i] = inputBuffer[i+inputOffset];
+ }
+
+ fooBuffer[inputCount] = 0x80;
+ for (i=inputCount+1; i<inputCount+paddingSize; i++) {
+ fooBuffer[i] = 0x00;
+ }
+
+ size = (uint)(count+inputCount);
+ size *= 8;
+ fooBuffer[inputCount+paddingSize] = (byte)((size) >> 0);
+ fooBuffer[inputCount+paddingSize+1] = (byte)((size) >> 8);
+ fooBuffer[inputCount+paddingSize+2] = (byte)((size) >> 16);
+ fooBuffer[inputCount+paddingSize+3] = (byte)((size) >> 24);
+
+ fooBuffer[inputCount+paddingSize+4] = 0x00;
+ fooBuffer[inputCount+paddingSize+5] = 0x00;
+ fooBuffer[inputCount+paddingSize+6] = 0x00;
+ fooBuffer[inputCount+paddingSize+7] = 0x00;
+
+ ProcessBlock(fooBuffer, 0);
+
+ if (inputCount+paddingSize+8 == 128) {
+ ProcessBlock(fooBuffer, 64);
+ }
+ }
+
+ private enum Constants : uint {
+ C0 = 0xd76aa478, C1 = 0xe8c7b756, C2 = 0x242070db,
+ C3 = 0xc1bdceee, C4 = 0xf57c0faf, C5 = 0x4787c62a,
+ C6 = 0xa8304613, C7 = 0xfd469501, C8 = 0x698098d8,
+ C9 = 0x8b44f7af,C10 = 0xffff5bb1,C11 = 0x895cd7be,
+ C12 = 0x6b901122,C13 = 0xfd987193,C14 = 0xa679438e,
+ C15 = 0x49b40821,C16 = 0xf61e2562,C17 = 0xc040b340,
+ C18 = 0x265e5a51,C19 = 0xe9b6c7aa,C20 = 0xd62f105d,
+ C21 = 0x02441453,C22 = 0xd8a1e681,C23 = 0xe7d3fbc8,
+ C24 = 0x21e1cde6,C25 = 0xc33707d6,C26 = 0xf4d50d87,
+ C27 = 0x455a14ed,C28 = 0xa9e3e905,C29 = 0xfcefa3f8,
+ C30 = 0x676f02d9,C31 = 0x8d2a4c8a,C32 = 0xfffa3942,
+ C33 = 0x8771f681,C34 = 0x6d9d6122,C35 = 0xfde5380c,
+ C36 = 0xa4beea44,C37 = 0x4bdecfa9,C38 = 0xf6bb4b60,
+ C39 = 0xbebfbc70,C40 = 0x289b7ec6,C41 = 0xeaa127fa,
+ C42 = 0xd4ef3085,C43 = 0x04881d05,C44 = 0xd9d4d039,
+ C45 = 0xe6db99e5,C46 = 0x1fa27cf8,C47 = 0xc4ac5665,
+ C48 = 0xf4292244,C49 = 0x432aff97,C50 = 0xab9423a7,
+ C51 = 0xfc93a039,C52 = 0x655b59c3,C53 = 0x8f0ccc92,
+ C54 = 0xffeff47d,C55 = 0x85845dd1,C56 = 0x6fa87e4f,
+ C57 = 0xfe2ce6e0,C58 = 0xa3014314,C59 = 0x4e0811a1,
+ C60 = 0xf7537e82,C61 = 0xbd3af235,C62 = 0x2ad7d2bb,
+ C63 = 0xeb86d391
+ }
+
+ }
+}
+
diff --git a/mcs/class/corlib/System.Security.Cryptography/PaddingMode.cs b/mcs/class/corlib/System.Security.Cryptography/PaddingMode.cs
new file mode 100644
index 00000000000..a5641974b2e
--- /dev/null
+++ b/mcs/class/corlib/System.Security.Cryptography/PaddingMode.cs
@@ -0,0 +1,21 @@
+//
+// System.Security.Cryptography PaddingMode enumeration
+//
+// Authors:
+// Matthew S. Ford (Matthew.S.Ford@Rose-Hulman.Edu)
+//
+// Copyright 2001 by Matthew S. Ford.
+//
+
+
+namespace System.Security.Cryptography {
+
+ /// <summary>
+ /// How to pad the message processed by block ciphers when they don't come out to the being the size of the block.
+ /// </summary>
+ public enum PaddingMode {
+ PKCS7, // Each byte contains the value of the number of padding bytes.
+ Zeros // Append zeros to the message.
+ }
+}
+
diff --git a/mcs/class/corlib/System.Security.Cryptography/SHA1.cs b/mcs/class/corlib/System.Security.Cryptography/SHA1.cs
new file mode 100644
index 00000000000..f3b16db7c2c
--- /dev/null
+++ b/mcs/class/corlib/System.Security.Cryptography/SHA1.cs
@@ -0,0 +1,43 @@
+//
+// System.Security.Cryptography SHA1 Class implementation
+//
+// Authors:
+// Matthew S. Ford (Matthew.S.Ford@Rose-Hulman.Edu)
+//
+// Copyright 2001 by Matthew S. Ford.
+//
+
+
+using System.Security.Cryptography;
+
+namespace System.Security.Cryptography {
+
+ /// <summary>
+ /// Common base class for all derived SHA1 iplementations.
+ /// </summary>
+ public abstract class SHA1 : HashAlgorithm {
+ /// <summary>
+ /// Called from constructor of derived class.
+ /// </summary>
+ protected SHA1 () {
+
+ }
+
+
+ /// <summary>
+ /// Creates the default derived class.
+ /// </summary>
+ public static new SHA1 Create () {
+ return new SHA1CryptoServiceProvider();
+ }
+
+ /// <summary>
+ /// Creates a new derived class.
+ /// </summary>
+ /// <param name="st">FIXME: No clue. Specifies which derived class to create?</param>
+ public static new SHA1 Create (string st) {
+ return Create();
+ }
+ }
+}
+
diff --git a/mcs/class/corlib/System.Security.Cryptography/SHA1CryptoServiceProvider.cs b/mcs/class/corlib/System.Security.Cryptography/SHA1CryptoServiceProvider.cs
new file mode 100644
index 00000000000..4d84f6f0da6
--- /dev/null
+++ b/mcs/class/corlib/System.Security.Cryptography/SHA1CryptoServiceProvider.cs
@@ -0,0 +1,455 @@
+//
+// System.Security.Cryptography SHA1CryptoServiceProvider Class implementation
+//
+// Author:
+// Matthew S. Ford (Matthew.S.Ford@Rose-Hulman.Edu)
+//
+// Copyright 2001 by Matthew S. Ford.
+//
+
+
+using System.Security.Cryptography;
+
+namespace System.Security.Cryptography {
+
+ /// <summary>
+ /// C# implementation of the SHA1 cryptographic hash function.
+ /// LAMESPEC?: Basically the same thing as SHA1Managed except for how its implemented.
+ /// </summary>
+ public class SHA1CryptoServiceProvider : SHA1 {
+ private const int BLOCK_SIZE_BYTES = 64;
+ private const int HASH_SIZE_BYTES = 20;
+ private const int HASH_SIZE_BITS = 160;
+ protected uint[] _H; // these are my chaining variables
+ protected uint count;
+ private byte[] _ProcessingBuffer; // Used to start data when passed less than a block worth.
+ private int _ProcessingBufferCount; // Counts how much data we have stored that still needs processed.
+
+ /// <summary>
+ /// Creates a new SHA1CryptoServiceProvider.
+ /// </summary>
+ public SHA1CryptoServiceProvider () {
+ _H = new uint[5];
+ HashSizeValue = HASH_SIZE_BITS;
+ _ProcessingBuffer = new byte[BLOCK_SIZE_BYTES];
+
+ Initialize();
+ }
+
+ /// <summary>
+ /// Drives the hashing function.
+ /// </summary>
+ /// <param name="rgb">Byte array containing the data to hash.</param>
+ /// <param name="start">Where in the input buffer to start.</param>
+ /// <param name="size">Size in bytes of the data in the buffer to hash.</param>
+ protected override void HashCore (byte[] rgb, int start, int size) {
+ int i;
+ State = 1;
+
+ if (_ProcessingBufferCount != 0) {
+ if (size < (BLOCK_SIZE_BYTES - _ProcessingBufferCount)) {
+ System.Buffer.BlockCopy (rgb, start, _ProcessingBuffer, _ProcessingBufferCount, size);
+ _ProcessingBufferCount += size;
+ return;
+ }
+ else {
+ i = (BLOCK_SIZE_BYTES - _ProcessingBufferCount);
+ System.Buffer.BlockCopy (rgb, start, _ProcessingBuffer, _ProcessingBufferCount, i);
+ ProcessBlock (_ProcessingBuffer, 0);
+ _ProcessingBufferCount = 0;
+ start += i;
+ size -= i;
+ }
+ }
+
+ for (i=0; i<size-size%BLOCK_SIZE_BYTES; i += BLOCK_SIZE_BYTES) {
+ ProcessBlock (rgb, start+i);
+ }
+
+ if (size%BLOCK_SIZE_BYTES != 0) {
+ System.Buffer.BlockCopy (rgb, size-size%BLOCK_SIZE_BYTES+start, _ProcessingBuffer, 0, size%BLOCK_SIZE_BYTES);
+ _ProcessingBufferCount = size%BLOCK_SIZE_BYTES;
+ }
+ }
+
+ /// <summary>
+ /// This finalizes the hash. Takes the data from the chaining variables and returns it.
+ /// </summary>
+ protected override byte[] HashFinal () {
+ byte[] hash = new byte[20];
+ int i, j;
+
+ ProcessFinalBlock(_ProcessingBuffer, 0, _ProcessingBufferCount);
+
+ for (i=0; i<5; i++) {
+ for (j=0; j<4; j++) {
+ hash[i*4+j] = (byte)(_H[i] >> (8*(3-j)));
+ }
+ }
+
+ State = 0;
+ return hash;
+ }
+
+
+ /// <summary>
+ /// Resets the class after use. Called automatically after hashing is done.
+ /// </summary>
+ public override void Initialize () {
+ count = 0;
+ _ProcessingBufferCount = 0;
+
+ _H[0] = 0x67452301;
+ _H[1] = 0xefcdab89;
+ _H[2] = 0x98badcfe;
+ _H[3] = 0x10325476;
+ _H[4] = 0xC3D2E1F0;
+ }
+
+ /// <summary>
+ /// This is the meat of the hash function. It is what processes each block one at a time.
+ /// </summary>
+ /// <param name="inputBuffer">Byte array to process data from.</param>
+ /// <param name="inputOffset">Where in the byte array to start processing.</param>
+ private void ProcessBlock(byte[] inputBuffer, int inputOffset) {
+ uint[] buff = new uint[80];
+ uint a, b, c, d, e;
+ int i;
+
+ count += BLOCK_SIZE_BYTES;
+
+ for (i=0; i<16; i++) {
+ buff[i] = ((uint)(inputBuffer[inputOffset+4*i]) << 24)
+ | ((uint)(inputBuffer[inputOffset+4*i+1]) << 16)
+ | ((uint)(inputBuffer[inputOffset+4*i+2]) << 8)
+ | ((uint)(inputBuffer[inputOffset+4*i+3]));
+ }
+
+ for (i=16; i<80; i++) {
+ buff[i] = ((buff[i-3] ^ buff[i-8] ^ buff[i-14] ^ buff[i-16]) << 1)
+ | ((buff[i-3] ^ buff[i-8] ^ buff[i-14] ^ buff[i-16]) >> 31);
+ }
+
+ a = _H[0];
+ b = _H[1];
+ c = _H[2];
+ d = _H[3];
+ e = _H[4];
+
+
+ // This function was unrolled because it seems to be doubling our performance with current compiler/VM.
+ // Possibly roll up if this changes.
+
+ // ---- Round 1 --------
+
+ e += ((a << 5) | (a >> 27)) + (((c ^ d) & b) ^ d) + 0x5A827999 + buff[0];
+ b = (b << 30) | (b >> 2);
+
+ d += ((e << 5) | (e >> 27)) + (((b ^ c) & a) ^ c) + 0x5A827999 + buff[1];
+ a = (a << 30) | (a >> 2);
+
+ c += ((d << 5) | (d >> 27)) + (((a ^ b) & e) ^ b) + 0x5A827999 + buff[2];
+ e = (e << 30) | (e >> 2);
+
+ b += ((c << 5) | (c >> 27)) + (((e ^ a) & d) ^ a) + 0x5A827999 + buff[3];
+ d = (d << 30) | (d >> 2);
+
+ a += ((b << 5) | (b >> 27)) + (((d ^ e) & c) ^ e) + 0x5A827999 + buff[4];
+ c = (c << 30) | (c >> 2);
+
+ e += ((a << 5) | (a >> 27)) + (((c ^ d) & b) ^ d) + 0x5A827999 + buff[5];
+ b = (b << 30) | (b >> 2);
+
+ d += ((e << 5) | (e >> 27)) + (((b ^ c) & a) ^ c) + 0x5A827999 + buff[6];
+ a = (a << 30) | (a >> 2);
+
+ c += ((d << 5) | (d >> 27)) + (((a ^ b) & e) ^ b) + 0x5A827999 + buff[7];
+ e = (e << 30) | (e >> 2);
+
+ b += ((c << 5) | (c >> 27)) + (((e ^ a) & d) ^ a) + 0x5A827999 + buff[8];
+ d = (d << 30) | (d >> 2);
+
+ a += ((b << 5) | (b >> 27)) + (((d ^ e) & c) ^ e) + 0x5A827999 + buff[9];
+ c = (c << 30) | (c >> 2);
+
+ e += ((a << 5) | (a >> 27)) + (((c ^ d) & b) ^ d) + 0x5A827999 + buff[10];
+ b = (b << 30) | (b >> 2);
+
+ d += ((e << 5) | (e >> 27)) + (((b ^ c) & a) ^ c) + 0x5A827999 + buff[11];
+ a = (a << 30) | (a >> 2);
+
+ c += ((d << 5) | (d >> 27)) + (((a ^ b) & e) ^ b) + 0x5A827999 + buff[12];
+ e = (e << 30) | (e >> 2);
+
+ b += ((c << 5) | (c >> 27)) + (((e ^ a) & d) ^ a) + 0x5A827999 + buff[13];
+ d = (d << 30) | (d >> 2);
+
+ a += ((b << 5) | (b >> 27)) + (((d ^ e) & c) ^ e) + 0x5A827999 + buff[14];
+ c = (c << 30) | (c >> 2);
+
+ e += ((a << 5) | (a >> 27)) + (((c ^ d) & b) ^ d) + 0x5A827999 + buff[15];
+ b = (b << 30) | (b >> 2);
+
+ d += ((e << 5) | (e >> 27)) + (((b ^ c) & a) ^ c) + 0x5A827999 + buff[16];
+ a = (a << 30) | (a >> 2);
+
+ c += ((d << 5) | (d >> 27)) + (((a ^ b) & e) ^ b) + 0x5A827999 + buff[17];
+ e = (e << 30) | (e >> 2);
+
+ b += ((c << 5) | (c >> 27)) + (((e ^ a) & d) ^ a) + 0x5A827999 + buff[18];
+ d = (d << 30) | (d >> 2);
+
+ a += ((b << 5) | (b >> 27)) + (((d ^ e) & c) ^ e) + 0x5A827999 + buff[19];
+ c = (c << 30) | (c >> 2);
+
+
+
+ // ---- Round 2 --------
+
+ e += ((a << 5) | (a >> 27)) + (b ^ c ^ d) + 0x6ED9EBA1 + buff[20];
+ b = (b << 30) | (b >> 2);
+
+ d += ((e << 5) | (e >> 27)) + (a ^ b ^ c) + 0x6ED9EBA1 + buff[21];
+ a = (a << 30) | (a >> 2);
+
+ c += ((d << 5) | (d >> 27)) + (e ^ a ^ b) + 0x6ED9EBA1 + buff[22];
+ e = (e << 30) | (e >> 2);
+
+ b += ((c << 5) | (c >> 27)) + (d ^ e ^ a) + 0x6ED9EBA1 + buff[23];
+ d = (d << 30) | (d >> 2);
+
+ a += ((b << 5) | (b >> 27)) + (c ^ d ^ e) + 0x6ED9EBA1 + buff[24];
+ c = (c << 30) | (c >> 2);
+
+ e += ((a << 5) | (a >> 27)) + (b ^ c ^ d) + 0x6ED9EBA1 + buff[25];
+ b = (b << 30) | (b >> 2);
+
+ d += ((e << 5) | (e >> 27)) + (a ^ b ^ c) + 0x6ED9EBA1 + buff[26];
+ a = (a << 30) | (a >> 2);
+
+ c += ((d << 5) | (d >> 27)) + (e ^ a ^ b) + 0x6ED9EBA1 + buff[27];
+ e = (e << 30) | (e >> 2);
+
+ b += ((c << 5) | (c >> 27)) + (d ^ e ^ a) + 0x6ED9EBA1 + buff[28];
+ d = (d << 30) | (d >> 2);
+
+ a += ((b << 5) | (b >> 27)) + (c ^ d ^ e) + 0x6ED9EBA1 + buff[29];
+ c = (c << 30) | (c >> 2);
+
+ e += ((a << 5) | (a >> 27)) + (b ^ c ^ d) + 0x6ED9EBA1 + buff[30];
+ b = (b << 30) | (b >> 2);
+
+ d += ((e << 5) | (e >> 27)) + (a ^ b ^ c) + 0x6ED9EBA1 + buff[31];
+ a = (a << 30) | (a >> 2);
+
+ c += ((d << 5) | (d >> 27)) + (e ^ a ^ b) + 0x6ED9EBA1 + buff[32];
+ e = (e << 30) | (e >> 2);
+
+ b += ((c << 5) | (c >> 27)) + (d ^ e ^ a) + 0x6ED9EBA1 + buff[33];
+ d = (d << 30) | (d >> 2);
+
+ a += ((b << 5) | (b >> 27)) + (c ^ d ^ e) + 0x6ED9EBA1 + buff[34];
+ c = (c << 30) | (c >> 2);
+
+ e += ((a << 5) | (a >> 27)) + (b ^ c ^ d) + 0x6ED9EBA1 + buff[35];
+ b = (b << 30) | (b >> 2);
+
+ d += ((e << 5) | (e >> 27)) + (a ^ b ^ c) + 0x6ED9EBA1 + buff[36];
+ a = (a << 30) | (a >> 2);
+
+ c += ((d << 5) | (d >> 27)) + (e ^ a ^ b) + 0x6ED9EBA1 + buff[37];
+ e = (e << 30) | (e >> 2);
+
+ b += ((c << 5) | (c >> 27)) + (d ^ e ^ a) + 0x6ED9EBA1 + buff[38];
+ d = (d << 30) | (d >> 2);
+
+ a += ((b << 5) | (b >> 27)) + (c ^ d ^ e) + 0x6ED9EBA1 + buff[39];
+ c = (c << 30) | (c >> 2);
+
+
+
+ // ---- Round 3 --------
+
+ e += ((a << 5) | (a >> 27)) + ((b&c) | (b&d) | (c&d)) + 0x8F1BBCDC + buff[40];
+ b = (b << 30) | (b >> 2);
+
+ d += ((e << 5) | (e >> 27)) + ((a&b) | (a&c) | (b&c)) + 0x8F1BBCDC + buff[41];
+ a = (a << 30) | (a >> 2);
+
+ c += ((d << 5) | (d >> 27)) + ((e&a) | (e&b) | (a&b)) + 0x8F1BBCDC + buff[42];
+ e = (e << 30) | (e >> 2);
+
+ b += ((c << 5) | (c >> 27)) + ((d&e) | (d&a) | (e&a)) + 0x8F1BBCDC + buff[43];
+ d = (d << 30) | (d >> 2);
+
+ a += ((b << 5) | (b >> 27)) + ((c&d) | (c&e) | (d&e)) + 0x8F1BBCDC + buff[44];
+ c = (c << 30) | (c >> 2);
+
+ e += ((a << 5) | (a >> 27)) + ((b&c) | (b&d) | (c&d)) + 0x8F1BBCDC + buff[45];
+ b = (b << 30) | (b >> 2);
+
+ d += ((e << 5) | (e >> 27)) + ((a&b) | (a&c) | (b&c)) + 0x8F1BBCDC + buff[46];
+ a = (a << 30) | (a >> 2);
+
+ c += ((d << 5) | (d >> 27)) + ((e&a) | (e&b) | (a&b)) + 0x8F1BBCDC + buff[47];
+ e = (e << 30) | (e >> 2);
+
+ b += ((c << 5) | (c >> 27)) + ((d&e) | (d&a) | (e&a)) + 0x8F1BBCDC + buff[48];
+ d = (d << 30) | (d >> 2);
+
+ a += ((b << 5) | (b >> 27)) + ((c&d) | (c&e) | (d&e)) + 0x8F1BBCDC + buff[49];
+ c = (c << 30) | (c >> 2);
+
+ e += ((a << 5) | (a >> 27)) + ((b&c) | (b&d) | (c&d)) + 0x8F1BBCDC + buff[50];
+ b = (b << 30) | (b >> 2);
+
+ d += ((e << 5) | (e >> 27)) + ((a&b) | (a&c) | (b&c)) + 0x8F1BBCDC + buff[51];
+ a = (a << 30) | (a >> 2);
+
+ c += ((d << 5) | (d >> 27)) + ((e&a) | (e&b) | (a&b)) + 0x8F1BBCDC + buff[52];
+ e = (e << 30) | (e >> 2);
+
+ b += ((c << 5) | (c >> 27)) + ((d&e) | (d&a) | (e&a)) + 0x8F1BBCDC + buff[53];
+ d = (d << 30) | (d >> 2);
+
+ a += ((b << 5) | (b >> 27)) + ((c&d) | (c&e) | (d&e)) + 0x8F1BBCDC + buff[54];
+ c = (c << 30) | (c >> 2);
+
+ e += ((a << 5) | (a >> 27)) + ((b&c) | (b&d) | (c&d)) + 0x8F1BBCDC + buff[55];
+ b = (b << 30) | (b >> 2);
+
+ d += ((e << 5) | (e >> 27)) + ((a&b) | (a&c) | (b&c)) + 0x8F1BBCDC + buff[56];
+ a = (a << 30) | (a >> 2);
+
+ c += ((d << 5) | (d >> 27)) + ((e&a) | (e&b) | (a&b)) + 0x8F1BBCDC + buff[57];
+ e = (e << 30) | (e >> 2);
+
+ b += ((c << 5) | (c >> 27)) + ((d&e) | (d&a) | (e&a)) + 0x8F1BBCDC + buff[58];
+ d = (d << 30) | (d >> 2);
+
+ a += ((b << 5) | (b >> 27)) + ((c&d) | (c&e) | (d&e)) + 0x8F1BBCDC + buff[59];
+ c = (c << 30) | (c >> 2);
+
+
+
+ // ---- Round 4 --------
+
+ e += ((a << 5) | (a >> 27)) + (b ^ c ^ d) + 0xCA62C1D6 + buff[60];
+ b = (b << 30) | (b >> 2);
+
+ d += ((e << 5) | (e >> 27)) + (a ^ b ^ c) + 0xCA62C1D6 + buff[61];
+ a = (a << 30) | (a >> 2);
+
+ c += ((d << 5) | (d >> 27)) + (e ^ a ^ b) + 0xCA62C1D6 + buff[62];
+ e = (e << 30) | (e >> 2);
+
+ b += ((c << 5) | (c >> 27)) + (d ^ e ^ a) + 0xCA62C1D6 + buff[63];
+ d = (d << 30) | (d >> 2);
+
+ a += ((b << 5) | (b >> 27)) + (c ^ d ^ e) + 0xCA62C1D6 + buff[64];
+ c = (c << 30) | (c >> 2);
+
+ e += ((a << 5) | (a >> 27)) + (b ^ c ^ d) + 0xCA62C1D6 + buff[65];
+ b = (b << 30) | (b >> 2);
+
+ d += ((e << 5) | (e >> 27)) + (a ^ b ^ c) + 0xCA62C1D6 + buff[66];
+ a = (a << 30) | (a >> 2);
+
+ c += ((d << 5) | (d >> 27)) + (e ^ a ^ b) + 0xCA62C1D6 + buff[67];
+ e = (e << 30) | (e >> 2);
+
+ b += ((c << 5) | (c >> 27)) + (d ^ e ^ a) + 0xCA62C1D6 + buff[68];
+ d = (d << 30) | (d >> 2);
+
+ a += ((b << 5) | (b >> 27)) + (c ^ d ^ e) + 0xCA62C1D6 + buff[69];
+ c = (c << 30) | (c >> 2);
+
+ e += ((a << 5) | (a >> 27)) + (b ^ c ^ d) + 0xCA62C1D6 + buff[70];
+ b = (b << 30) | (b >> 2);
+
+ d += ((e << 5) | (e >> 27)) + (a ^ b ^ c) + 0xCA62C1D6 + buff[71];
+ a = (a << 30) | (a >> 2);
+
+ c += ((d << 5) | (d >> 27)) + (e ^ a ^ b) + 0xCA62C1D6 + buff[72];
+ e = (e << 30) | (e >> 2);
+
+ b += ((c << 5) | (c >> 27)) + (d ^ e ^ a) + 0xCA62C1D6 + buff[73];
+ d = (d << 30) | (d >> 2);
+
+ a += ((b << 5) | (b >> 27)) + (c ^ d ^ e) + 0xCA62C1D6 + buff[74];
+ c = (c << 30) | (c >> 2);
+
+ e += ((a << 5) | (a >> 27)) + (b ^ c ^ d) + 0xCA62C1D6 + buff[75];
+ b = (b << 30) | (b >> 2);
+
+ d += ((e << 5) | (e >> 27)) + (a ^ b ^ c) + 0xCA62C1D6 + buff[76];
+ a = (a << 30) | (a >> 2);
+
+ c += ((d << 5) | (d >> 27)) + (e ^ a ^ b) + 0xCA62C1D6 + buff[77];
+ e = (e << 30) | (e >> 2);
+
+ b += ((c << 5) | (c >> 27)) + (d ^ e ^ a) + 0xCA62C1D6 + buff[78];
+ d = (d << 30) | (d >> 2);
+
+ a += ((b << 5) | (b >> 27)) + (c ^ d ^ e) + 0xCA62C1D6 + buff[79];
+ c = (c << 30) | (c >> 2);
+
+
+ _H[0] += a;
+ _H[1] += b;
+ _H[2] += c;
+ _H[3] += d;
+ _H[4] += e;
+ }
+
+ /// <summary>
+ /// Pads and then processes the final block.
+ /// Non-standard.
+ /// </summary>
+ /// <param name="inputBuffer">Buffer to grab data from.</param>
+ /// <param name="inputOffset">Position in buffer in bytes to get data from.</param>
+ /// <param name="inputCount">How much data in bytes in the buffer to use.</param>
+ private void ProcessFinalBlock(byte[] inputBuffer, int inputOffset, int inputCount) {
+ byte[] fooBuffer;
+ int paddingSize;
+ int i;
+ uint size;
+
+ paddingSize = (int)(56 - (inputCount + count) % BLOCK_SIZE_BYTES);
+
+ if (paddingSize < 1)
+ paddingSize += BLOCK_SIZE_BYTES;
+
+ fooBuffer = new byte[inputCount+paddingSize+8];
+
+ for (i=0; i<inputCount; i++) {
+ fooBuffer[i] = inputBuffer[i+inputOffset];
+ }
+
+ fooBuffer[inputCount] = 0x80;
+ for (i=inputCount+1; i<inputCount+paddingSize; i++) {
+ fooBuffer[i] = 0x00;
+ }
+
+ size = (uint)(count+inputCount);
+ size *= 8; // I deal in bytes. They algorythm deals in bits.
+
+ fooBuffer[inputCount+paddingSize] = 0x00;
+ fooBuffer[inputCount+paddingSize+1] = 0x00;
+ fooBuffer[inputCount+paddingSize+2] = 0x00;
+ fooBuffer[inputCount+paddingSize+3] = 0x00;
+
+ fooBuffer[inputCount+paddingSize+4] = (byte)((size) >> 24);
+ fooBuffer[inputCount+paddingSize+5] = (byte)((size) >> 16);
+ fooBuffer[inputCount+paddingSize+6] = (byte)((size) >> 8);
+ fooBuffer[inputCount+paddingSize+7] = (byte)((size) >> 0);
+
+ ProcessBlock(fooBuffer, 0);
+
+ if (inputCount+paddingSize+8 == 128) {
+ ProcessBlock(fooBuffer, 64);
+ }
+ }
+ }
+}
+
diff --git a/mcs/class/corlib/System.Security.Cryptography/SHA256.cs b/mcs/class/corlib/System.Security.Cryptography/SHA256.cs
new file mode 100644
index 00000000000..1408719e515
--- /dev/null
+++ b/mcs/class/corlib/System.Security.Cryptography/SHA256.cs
@@ -0,0 +1,44 @@
+//
+// System.Security.Cryptography SHA256 Class implementation
+//
+// Authors:
+// Matthew S. Ford (Matthew.S.Ford@Rose-Hulman.Edu)
+//
+// Copyright 2001 by Matthew S. Ford.
+//
+
+
+using System.Security.Cryptography;
+
+namespace System.Security.Cryptography {
+
+ /// <summary>
+ /// Common base class for all derived SHA256 iplementations.
+ /// Abstract.
+ /// </summary>
+ public abstract class SHA256 : HashAlgorithm {
+
+ /// <summary>
+ /// Called from constructor of derived class.
+ /// </summary>
+ protected SHA256 () {
+
+ }
+
+ /// <summary>
+ /// Creates the default derived class.
+ /// </summary>
+ public static new SHA256 Create () {
+ return new SHA256Managed ();
+ }
+
+ /// <summary>
+ /// Creates a new derived class.
+ /// </summary>
+ /// <param name="st">FIXME: No clue. Specifies which derived class to create?</param>
+ public static new SHA256 Create (string st) {
+ return Create ();
+ }
+ }
+}
+
diff --git a/mcs/class/corlib/System.Security.Cryptography/SHA256Managed.cs b/mcs/class/corlib/System.Security.Cryptography/SHA256Managed.cs
new file mode 100644
index 00000000000..8f71227b272
--- /dev/null
+++ b/mcs/class/corlib/System.Security.Cryptography/SHA256Managed.cs
@@ -0,0 +1,290 @@
+//
+// System.Security.Cryptography SHA256Managed Class implementation
+//
+// Author:
+// Matthew S. Ford (Matthew.S.Ford@Rose-Hulman.Edu)
+//
+// (C) 2001
+//
+
+
+using System.Security.Cryptography;
+
+namespace System.Security.Cryptography {
+
+ /// <summary>
+ /// C# implementation of the SHA1 cryptographic hash function.
+ /// LAMESPEC?: Basically the same thing as SHA1Managed except for how its implemented.
+ /// </summary>
+ public class SHA256Managed : SHA256 {
+ private const int BLOCK_SIZE_BYTES = 64;
+ private const int HASH_SIZE_BYTES = 32;
+ private const int HASH_SIZE_BITS = 256;
+ protected uint[] _H;
+ private uint[] K;
+ protected uint count;
+ private byte[] _ProcessingBuffer; // Used to start data when passed less than a block worth.
+ private int _ProcessingBufferCount; // Counts how much data we have stored that still needs processed.
+
+ /// <summary>
+ /// Creates a new SHA256Managed class.
+ /// </summary>
+ public SHA256Managed () {
+ _H = new uint[8];
+ HashSizeValue = HASH_SIZE_BITS;
+ _ProcessingBuffer = new byte[BLOCK_SIZE_BYTES];
+
+ K = new uint[64];
+ K[0] = 0x428A2F98; K[1] = 0x71374491; K[2] = 0xB5C0FBCF; K[3] = 0xE9B5DBA5;
+ K[4] = 0x3956C25B; K[5] = 0x59F111F1; K[6] = 0x923F82A4; K[7] = 0xAB1C5ED5;
+ K[8] = 0xD807AA98; K[9] = 0x12835B01; K[10] = 0x243185BE; K[11] = 0x550C7DC3;
+ K[12] = 0x72BE5D74; K[13] = 0x80DEB1FE; K[14] = 0x9BDC06A7; K[15] = 0xC19BF174;
+ K[16] = 0xE49B69C1; K[17] = 0xEFBE4786; K[18] = 0x0FC19DC6; K[19] = 0x240CA1CC;
+ K[20] = 0x2DE92C6F; K[21] = 0x4A7484AA; K[22] = 0x5CB0A9DC; K[23] = 0x76F988DA;
+ K[24] = 0x983E5152; K[25] = 0xA831C66D; K[26] = 0xB00327C8; K[27] = 0xBF597FC7;
+ K[28] = 0xC6E00BF3; K[29] = 0xD5A79147; K[30] = 0x06CA6351; K[31] = 0x14292967;
+ K[32] = 0x27B70A85; K[33] = 0x2E1B2138; K[34] = 0x4D2C6DFC; K[35] = 0x53380D13;
+ K[36] = 0x650A7354; K[37] = 0x766A0ABB; K[38] = 0x81C2C92E; K[39] = 0x92722C85;
+ K[40] = 0xA2BFE8A1; K[41] = 0xA81A664B; K[42] = 0xC24B8B70; K[43] = 0xC76C51A3;
+ K[44] = 0xD192E819; K[45] = 0xD6990624; K[46] = 0xF40E3585; K[47] = 0x106AA070;
+ K[48] = 0x19A4C116; K[49] = 0x1E376C08; K[50] = 0x2748774C; K[51] = 0x34B0BCB5;
+ K[52] = 0x391C0CB3; K[53] = 0x4ED8AA4A; K[54] = 0x5B9CCA4F; K[55] = 0x682E6FF3;
+ K[56] = 0x748F82EE; K[57] = 0x78A5636F; K[58] = 0x84C87814; K[59] = 0x8CC70208;
+ K[60] = 0x90BEFFFA; K[61] = 0xA4506CEB; K[62] = 0xBEF9A3F7; K[63] = 0xC67178F2;
+
+ Initialize();
+ }
+
+
+ /// <summary>
+ /// Internal function handling a subset of the algorithm.
+ /// </summary>
+ private uint Ch (uint u, uint v, uint w) {
+ return (u&v) ^ (~u&w);
+ }
+
+ /// <summary>
+ /// Internal function handling a subset of the algorithm.
+ /// </summary>
+ private uint Maj (uint u, uint v, uint w) {
+ return (u&v) ^ (u&w) ^ (v&w);
+ }
+
+ /// <summary>
+ /// Internal function handling a subset of the algorithm.
+ /// </summary>
+ private uint Ro0 (uint x) {
+ return ((x >> 7) | (x << 25))
+ ^ ((x >> 18) | (x << 14))
+ ^ (x >> 3);
+ }
+
+ /// <summary>
+ /// Internal function handling a subset of the algorithm.
+ /// </summary>
+ private uint Ro1 (uint x) {
+ return ((x >> 17) | (x << 15))
+ ^ ((x >> 19) | (x << 13))
+ ^ (x >> 10);
+ }
+
+ /// <summary>
+ /// Internal function handling a subset of the algorithm.
+ /// </summary>
+ private uint Sig0 (uint x) {
+ return ((x >> 2) | (x << 30))
+ ^ ((x >> 13) | (x << 19))
+ ^ ((x >> 22) | (x << 10));
+ }
+
+ /// <summary>
+ /// Internal function handling a subset of the algorithm.
+ /// </summary>
+ private uint Sig1 (uint x) {
+ return ((x >> 6) | (x << 26))
+ ^ ((x >> 11) | (x << 21))
+ ^ ((x >> 25) | (x << 7));
+ }
+
+ /// <summary>
+ /// Drives the hashing function.
+ /// </summary>
+ /// <param name="rgb">Byte array containing the data to hash.</param>
+ /// <param name="start">Where in the input buffer to start.</param>
+ /// <param name="size">Size in bytes of the data in the buffer to hash.</param>
+ protected override void HashCore (byte[] rgb, int start, int size) {
+ int i;
+ State = 1;
+
+ if (_ProcessingBufferCount != 0) {
+ if (size < (BLOCK_SIZE_BYTES - _ProcessingBufferCount)) {
+ System.Buffer.BlockCopy (rgb, start, _ProcessingBuffer, _ProcessingBufferCount, size);
+ _ProcessingBufferCount += size;
+ return;
+ }
+ else {
+ i = (BLOCK_SIZE_BYTES - _ProcessingBufferCount);
+ System.Buffer.BlockCopy (rgb, start, _ProcessingBuffer, _ProcessingBufferCount, i);
+ ProcessBlock (_ProcessingBuffer, 0);
+ _ProcessingBufferCount = 0;
+ start += i;
+ size -= i;
+ }
+ }
+
+ for (i=0; i<size-size%BLOCK_SIZE_BYTES; i += BLOCK_SIZE_BYTES) {
+ ProcessBlock (rgb, start+i);
+ }
+
+ if (size%BLOCK_SIZE_BYTES != 0) {
+ System.Buffer.BlockCopy (rgb, size-size%BLOCK_SIZE_BYTES+start, _ProcessingBuffer, 0, size%BLOCK_SIZE_BYTES);
+ _ProcessingBufferCount = size%BLOCK_SIZE_BYTES;
+ }
+ }
+
+ /// <summary>
+ /// This finalizes the hash. Takes the data from the chaining variables and returns it.
+ /// </summary>
+ protected override byte[] HashFinal () {
+ byte[] hash = new byte[32];
+ int i, j;
+
+ ProcessFinalBlock(_ProcessingBuffer, 0, _ProcessingBufferCount);
+
+ for (i=0; i<8; i++) {
+ for (j=0; j<4; j++) {
+ hash[i*4+j] = (byte)(_H[i] >> (24-j*8));
+ }
+ }
+
+ State = 0;
+ return hash;
+ }
+
+ /// <summary>
+ /// Resets the class after use. Called automatically after hashing is done.
+ /// </summary>
+ public override void Initialize () {
+ count = 0;
+ _ProcessingBufferCount = 0;
+
+ _H[0] = 0x6A09E667;
+ _H[1] = 0xBB67AE85;
+ _H[2] = 0x3C6EF372;
+ _H[3] = 0xA54FF53A;
+ _H[4] = 0x510E527F;
+ _H[5] = 0x9B05688C;
+ _H[6] = 0x1F83D9AB;
+ _H[7] = 0x5BE0CD19;
+ }
+
+ /// <summary>
+ /// This is the meat of the hash function. It is what processes each block one at a time.
+ /// </summary>
+ /// <param name="inputBuffer">Byte array to process data from.</param>
+ /// <param name="inputOffset">Where in the byte array to start processing.</param>
+ public void ProcessBlock(byte[] inputBuffer, int inputOffset) {
+ uint a, b, c, d, e, f, g, h;
+ uint t1, t2;
+ int i;
+ uint[] buff;
+
+ count += BLOCK_SIZE_BYTES;
+
+ buff = new uint[64];
+
+ for (i=0; i<16; i++) {
+ buff[i] = ((uint)(inputBuffer[inputOffset+4*i]) << 24)
+ | ((uint)(inputBuffer[inputOffset+4*i+1]) << 16)
+ | ((uint)(inputBuffer[inputOffset+4*i+2]) << 8)
+ | ((uint)(inputBuffer[inputOffset+4*i+3]));
+ }
+
+
+ for (i=16; i<64; i++) {
+ buff[i] = Ro1(buff[i-2]) + buff[i-7] + Ro0(buff[i-15]) + buff[i-16];
+ }
+
+ a = _H[0];
+ b = _H[1];
+ c = _H[2];
+ d = _H[3];
+ e = _H[4];
+ f = _H[5];
+ g = _H[6];
+ h = _H[7];
+
+ for (i=0; i<64; i++) {
+ t1 = h + Sig1(e) + Ch(e,f,g) + K[i] + buff[i];
+ t2 = Sig0(a) + Maj(a,b,c);
+ h = g;
+ g = f;
+ f = e;
+ e = d + t1;
+ d = c;
+ c = b;
+ b = a;
+ a = t1 + t2;
+ }
+
+ _H[0] += a;
+ _H[1] += b;
+ _H[2] += c;
+ _H[3] += d;
+ _H[4] += e;
+ _H[5] += f;
+ _H[6] += g;
+ _H[7] += h;
+ }
+
+ /// <summary>
+ /// Pads and then processes the final block.
+ /// Non-standard.
+ /// </summary>
+ /// <param name="inputBuffer">Buffer to grab data from.</param>
+ /// <param name="inputOffset">Position in buffer in bytes to get data from.</param>
+ /// <param name="inputCount">How much data in bytes in the buffer to use.</param>
+ public void ProcessFinalBlock(byte[] inputBuffer, int inputOffset, int inputCount) {
+ byte[] fooBuffer;
+ int paddingSize;
+ int i;
+ uint size;
+
+ paddingSize = (int)(56 - (inputCount + count) % BLOCK_SIZE_BYTES);
+
+ if (paddingSize < 1)
+ paddingSize += BLOCK_SIZE_BYTES;
+
+ fooBuffer = new byte[inputCount+paddingSize+8];
+
+ for (i=0; i<inputCount; i++) {
+ fooBuffer[i] = inputBuffer[i+inputOffset];
+ }
+
+ fooBuffer[inputCount] = 0x80;
+ for (i=inputCount+1; i<inputCount+paddingSize; i++) {
+ fooBuffer[i] = 0x00;
+ }
+
+ size = (uint)(count+inputCount);
+ size *= 8;
+
+ fooBuffer[inputCount+paddingSize] = 0x00;
+ fooBuffer[inputCount+paddingSize+1] = 0x00;
+ fooBuffer[inputCount+paddingSize+2] = 0x00;
+ fooBuffer[inputCount+paddingSize+3] = 0x00;
+
+ fooBuffer[inputCount+paddingSize+4] = (byte)((size) >> 24);
+ fooBuffer[inputCount+paddingSize+5] = (byte)((size) >> 16);
+ fooBuffer[inputCount+paddingSize+6] = (byte)((size) >> 8);
+ fooBuffer[inputCount+paddingSize+7] = (byte)((size) >> 0);
+
+ ProcessBlock(fooBuffer, 0);
+
+ if (inputCount+paddingSize+8 == 128) {
+ ProcessBlock(fooBuffer, 64);
+ }
+ }
+ }
+}
+
diff --git a/mcs/class/corlib/System.Security.Cryptography/SHA384.cs b/mcs/class/corlib/System.Security.Cryptography/SHA384.cs
new file mode 100644
index 00000000000..d240775f720
--- /dev/null
+++ b/mcs/class/corlib/System.Security.Cryptography/SHA384.cs
@@ -0,0 +1,44 @@
+//
+// System.Security.Cryptography SHA384 Class implementation
+//
+// Authors:
+// Matthew S. Ford (Matthew.S.Ford@Rose-Hulman.Edu)
+//
+// Copyright 2001 by Matthew S. Ford.
+//
+
+
+using System.Security.Cryptography;
+
+namespace System.Security.Cryptography {
+
+ /// <summary>
+ /// Common base class for all derived SHA384 iplementations.
+ /// </summary>
+ public abstract class SHA384 : HashAlgorithm {
+
+ /// <summary>
+ /// Called from constructor of derived class.
+ /// </summary>
+ protected SHA384 () {
+
+ }
+
+
+ /// <summary>
+ /// Creates the default derived class.
+ /// </summary>
+ public static new SHA384 Create () {
+ return new SHA384Managed();
+ }
+
+ /// <summary>
+ /// Creates a new derived class.
+ /// </summary>
+ /// <param name="st">FIXME: No clue. Specifies which derived class to create?</param>
+ public static new SHA384 Create (string st) {
+ return Create();
+ }
+ }
+}
+
diff --git a/mcs/class/corlib/System.Security.Cryptography/SHA512.cs b/mcs/class/corlib/System.Security.Cryptography/SHA512.cs
new file mode 100644
index 00000000000..f4ac4919873
--- /dev/null
+++ b/mcs/class/corlib/System.Security.Cryptography/SHA512.cs
@@ -0,0 +1,44 @@
+//
+// System.Security.Cryptography SHA512 Class implementation
+//
+// Authors:
+// Matthew S. Ford (Matthew.S.Ford@Rose-Hulman.Edu)
+//
+// Copyright 2001 by Matthew S. Ford.
+//
+
+
+using System.Security.Cryptography;
+
+namespace System.Security.Cryptography {
+
+ /// <summary>
+ /// Common base class for all derived SHA512 iplementations.
+ /// </summary>
+ public abstract class SHA512 : HashAlgorithm {
+
+ /// <summary>
+ /// Called from constructor of derived class.
+ /// </summary>
+ protected SHA512 () {
+
+ }
+
+
+ /// <summary>
+ /// Creates the default derived class.
+ /// </summary>
+ public static new SHA512 Create () {
+ return new SHA512Managed();
+ }
+
+ /// <summary>
+ /// Creates a new derived class.
+ /// </summary>
+ /// <param name="st">FIXME: No clue. Specifies which derived class to create?</param>
+ public static new SHA512 Create (string st) {
+ return Create();
+ }
+ }
+}
+
diff --git a/mcs/class/corlib/System.Security.Cryptography/ToBase64Transform.cs b/mcs/class/corlib/System.Security.Cryptography/ToBase64Transform.cs
new file mode 100644
index 00000000000..c87233682a4
--- /dev/null
+++ b/mcs/class/corlib/System.Security.Cryptography/ToBase64Transform.cs
@@ -0,0 +1,233 @@
+//
+// System.Security.Cryptography.ToBase64Transform
+//
+// Author:
+// Sergey Chaban (serge@wildwestsoftware.com)
+//
+
+using System;
+using System.Security.Cryptography;
+
+
+namespace System.Security.Cryptography {
+
+ public class ToBase64Transform : ICryptoTransform {
+
+
+ /// <summary>
+ /// Default constructor.
+ /// </summary>
+ public ToBase64Transform ()
+ {
+ }
+
+
+ /// <summary>
+ /// </summary>
+ public virtual bool CanTransformMultipleBlocks {
+ get {
+ return false;
+ }
+ }
+
+
+ /// <summary>
+ /// Returns the input block size for the Base64 encoder.
+ /// </summary>
+ /// <remarks>
+ /// The returned value is always 3.
+ /// </remarks>
+ public virtual int InputBlockSize {
+ get {
+ return 3;
+ }
+ }
+
+
+ /// <summary>
+ /// Returns the output block size for the Base64 encoder.
+ /// </summary>
+ /// <remarks>
+ /// The value returned by this property is always 4.
+ /// </remarks>
+ public virtual int OutputBlockSize {
+ get {
+ return 4;
+ }
+ }
+
+
+ /// <summary>
+ /// </summary>
+ public virtual int TransformBlock (byte [] inputBuffer,
+ int inputOffset,
+ int inputCount,
+ byte [] outputBuffer,
+ int outputOffset)
+ {
+ if (inputCount != this.InputBlockSize)
+ throw new CryptographicException();
+
+ byte [] lookup = Base64Table.EncodeTable;
+
+ int b1 = inputBuffer [inputOffset];
+ int b2 = inputBuffer [inputOffset + 1];
+ int b3 = inputBuffer [inputOffset + 2];
+
+ outputBuffer [outputOffset] = lookup [b1 >> 2];
+ outputBuffer [outputOffset+1] = lookup [((b1 << 4) & 0x30) | (b2 >> 4)];
+ outputBuffer [outputOffset+2] = lookup [((b2 << 2) & 0x3c) | (b3 >> 6)];
+ outputBuffer [outputOffset+3] = lookup [b3 & 0x3f];
+
+ return this.OutputBlockSize;
+ }
+
+
+
+
+ // LAMESPEC: It's not clear from Beta2 docs what should be
+ // happening here if inputCount > InputBlockSize.
+ // It just "Converts the specified region of the specified
+ // byte array" and that's all.
+ // Beta2 implementation throws some strange (and undocumented)
+ // exception in such case. The exception is thrown by
+ // System.Convert and not the method itself.
+ // Anyhow, this implementation just encodes blocks of any size,
+ // like any usual Base64 encoder.
+
+ /// <summary>
+ /// </summary>
+ public virtual byte [] TransformFinalBlock (byte [] inputBuffer,
+ int inputOffset,
+ int inputCount)
+ {
+ int blockLen = this.InputBlockSize;
+ int outLen = this.OutputBlockSize;
+ int fullBlocks = inputCount / blockLen;
+ int tail = inputCount % blockLen;
+
+ byte [] res = new byte [(inputCount != 0)
+ ? ((inputCount + 2) / blockLen) * outLen
+ : 0];
+
+ int outputOffset = 0;
+
+ for (int i = 0; i < fullBlocks; i++) {
+
+ TransformBlock (inputBuffer, inputOffset,
+ blockLen, res, outputOffset);
+
+ inputOffset += blockLen;
+ outputOffset += outLen;
+ }
+
+
+ byte [] lookup = Base64Table.EncodeTable;
+ int b1,b2;
+
+
+ // When fewer than 24 input bits are available
+ // in an input group, zero bits are added
+ // (on the right) to form an integral number of
+ // 6-bit groups.
+ switch (tail) {
+ case 0:
+ break;
+ case 1:
+ b1 = inputBuffer [inputOffset];
+ res [outputOffset] = lookup [b1 >> 2];
+ res [outputOffset+1] = lookup [(b1 << 4) & 0x30];
+
+ // padding
+ res [outputOffset+2] = (byte)'=';
+ res [outputOffset+3] = (byte)'=';
+ break;
+
+ case 2:
+ b1 = inputBuffer [inputOffset];
+ b2 = inputBuffer [inputOffset + 1];
+ res [outputOffset] = lookup [b1 >> 2];
+ res [outputOffset+1] = lookup [((b1 << 4) & 0x30) | (b2 >> 4)];
+ res [outputOffset+2] = lookup [(b2 << 2) & 0x3c];
+
+ // one-byte padding
+ res [outputOffset+3] = (byte)'=';
+ break;
+
+ default:
+ break;
+ }
+
+ return res;
+ }
+
+
+
+ /// <summary>
+ /// </summary>
+ public override string ToString ()
+ {
+ return "mono::System.Security.Cryptography.ToBase64Transform";
+ }
+
+ } // ToBase64Transform
+
+
+
+ // FIXME: Ought to be in a standalone file.
+ internal sealed class Base64Table {
+
+ // This is the Base64 alphabet as described in RFC 2045
+ // (Table 1, page 25).
+ private static string ALPHABET =
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+
+ private static byte[] encodeTable;
+ private static byte[] decodeTable;
+
+
+ static Base64Table ()
+ {
+ int len = ALPHABET.Length;
+
+ encodeTable = new byte [len];
+
+ for (int i=0; i < len; i++) {
+ encodeTable [i] = (byte) ALPHABET [i];
+ }
+
+
+ decodeTable = new byte [1 + (int)'z'];
+
+ for (int i=0; i < decodeTable.Length; i++) {
+ decodeTable [i] = Byte.MaxValue;
+ }
+
+ for (int i=0; i < len; i++) {
+ char ch = ALPHABET [i];
+ decodeTable [(int)ch] = (byte) i;
+ }
+ }
+
+
+ private Base64Table ()
+ {
+ // Never instantiated.
+ }
+
+
+ internal static byte [] EncodeTable {
+ get {
+ return encodeTable;
+ }
+ }
+
+ internal static byte [] DecodeTable {
+ get {
+ return decodeTable;
+ }
+ }
+
+ } // Base64Table
+
+} // System.Security.Cryptography
diff --git a/mcs/class/corlib/System.Security.Cryptography/common.src b/mcs/class/corlib/System.Security.Cryptography/common.src
new file mode 100644
index 00000000000..498589ae6d9
--- /dev/null
+++ b/mcs/class/corlib/System.Security.Cryptography/common.src
@@ -0,0 +1,15 @@
+CipherMode.cs
+CryptoStreamMode.cs
+HashAlgorithm.cs
+ICryptoTransform.cs
+KeySizes.cs
+MD5.cs
+MD5CryptoServiceProvider.cs
+PaddingMode.cs
+SHA1.cs
+SHA1CryptoServiceProvider.cs
+SHA256.cs
+SHA256Managed.cs
+SHA384.cs
+SHA512.cs
+ToBase64Transform.cs
diff --git a/mcs/class/corlib/System.Security.Cryptography/unix.src b/mcs/class/corlib/System.Security.Cryptography/unix.src
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/mcs/class/corlib/System.Security.Cryptography/unix.src
diff --git a/mcs/class/corlib/System.Security.Cryptography/windows.src b/mcs/class/corlib/System.Security.Cryptography/windows.src
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/mcs/class/corlib/System.Security.Cryptography/windows.src
diff --git a/mcs/class/corlib/System.Security.Permissions/ChangeLog b/mcs/class/corlib/System.Security.Permissions/ChangeLog
new file mode 100644
index 00000000000..23c6e4d57c5
--- /dev/null
+++ b/mcs/class/corlib/System.Security.Permissions/ChangeLog
@@ -0,0 +1,3 @@
+2001-07-18 Michael Lambert <michaellambert@email.com>
+
+ * EnvironmentPermissionAccess.cs, FileIOPermissionAccess.cs, ReflectionPermissionFlag.cs: Add.
diff --git a/mcs/class/corlib/System.Security.Permissions/EnvironmentPermissionAccess.cs b/mcs/class/corlib/System.Security.Permissions/EnvironmentPermissionAccess.cs
new file mode 100644
index 00000000000..19594ceb570
--- /dev/null
+++ b/mcs/class/corlib/System.Security.Permissions/EnvironmentPermissionAccess.cs
@@ -0,0 +1,23 @@
+//------------------------------------------------------------------------------
+//
+// System.Security.Permissions.EnvironmentPermissionAccess.cs
+//
+// Copyright (C) 2001 Michael Lambert, All Rights Reserved
+//
+// Author: Michael Lambert, michaellambert@email.com
+// Created: Thu 07/18/2001
+//
+//------------------------------------------------------------------------------
+
+namespace System.Security.Permissions
+{
+
+public enum EnvironmentPermissionAccess
+{
+ AllAccess,
+ NoAccess,
+ Read,
+ Write,
+}
+
+} // Namespace
diff --git a/mcs/class/corlib/System.Security.Permissions/FileIOPermissionAccess.cs b/mcs/class/corlib/System.Security.Permissions/FileIOPermissionAccess.cs
new file mode 100644
index 00000000000..2fdce58cee9
--- /dev/null
+++ b/mcs/class/corlib/System.Security.Permissions/FileIOPermissionAccess.cs
@@ -0,0 +1,25 @@
+//------------------------------------------------------------------------------
+//
+// System.Security.Permissions.FileIOPermissionAccess.cs
+//
+// Copyright (C) 2001 Michael Lambert, All Rights Reserved
+//
+// Author: Michael Lambert, michaellambert@email.com
+// Created: Thu 07/18/2001
+//
+//------------------------------------------------------------------------------
+
+namespace System.Security.Permissions
+{
+
+public enum FileIOPermissionAccess
+{
+ AllAccess,
+ Append,
+ NoAccess,
+ PathDiscovery,
+ Read,
+ Write,
+}
+
+} // Namespace
diff --git a/mcs/class/corlib/System.Security.Permissions/ReflectionPermissionFlag.cs b/mcs/class/corlib/System.Security.Permissions/ReflectionPermissionFlag.cs
new file mode 100644
index 00000000000..f3e9e921ec1
--- /dev/null
+++ b/mcs/class/corlib/System.Security.Permissions/ReflectionPermissionFlag.cs
@@ -0,0 +1,24 @@
+//------------------------------------------------------------------------------
+//
+// System.Security.Permissions.ReflectionPermissionFlag.cs
+//
+// Copyright (C) 2001 Michael Lambert, All Rights Reserved
+//
+// Author: Michael Lambert, michaellambert@email.com
+// Created: Thu 07/18/2001
+//
+//------------------------------------------------------------------------------
+
+namespace System.Security.Permissions
+{
+
+ public enum ReflectionPermissionFlag
+ {
+ AllFlags,
+ MemberAccess,
+ NoFlags,
+ ReflectionEmit,
+ TypeInformation,
+ }
+
+} // Namespace
diff --git a/mcs/class/corlib/System.Security.Permissions/common.src b/mcs/class/corlib/System.Security.Permissions/common.src
new file mode 100644
index 00000000000..20d984f12d4
--- /dev/null
+++ b/mcs/class/corlib/System.Security.Permissions/common.src
@@ -0,0 +1,3 @@
+ReflectionPermissionFlag.cs
+FileIOPermissionAccess.cs
+EnvironmentPermissionAccess.cs
diff --git a/mcs/class/corlib/System.Security.Permissions/unix.src b/mcs/class/corlib/System.Security.Permissions/unix.src
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/mcs/class/corlib/System.Security.Permissions/unix.src
diff --git a/mcs/class/corlib/System.Security.Permissions/windows.src b/mcs/class/corlib/System.Security.Permissions/windows.src
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/mcs/class/corlib/System.Security.Permissions/windows.src
diff --git a/mcs/class/corlib/System.Text/ASCIIEncoding.cs b/mcs/class/corlib/System.Text/ASCIIEncoding.cs
new file mode 100755
index 00000000000..2bfe091a40c
--- /dev/null
+++ b/mcs/class/corlib/System.Text/ASCIIEncoding.cs
@@ -0,0 +1,40 @@
+//
+// System.Text.ASCIIEncoding.cs
+//
+// Author:
+// Sean MacIsaac (macisaac@ximian.com)
+//
+// (C) Ximian, Inc. http://www.ximian.com
+//
+
+
+namespace System.Text {
+
+ public class ASCIIEncoding : Encoding {
+ public override int GetByteCount(char[] chars, int index, int count) {
+ // FIXME
+ return 0;
+ }
+
+ public override int GetBytes(char[] chars, int charIndex, int charCount, byte[] bytes, int byteIndex) {
+ // FIXME
+ return 0;
+ }
+
+ public override char[] GetChars(byte[] bytes, int byteIndex, int byteCount, char[] chars, int charIndex) {
+ // FIXME
+ return null;
+ }
+
+ public override int GetMaxByteCount(int charCount) {
+ // FIXME
+ return 0;
+ }
+
+ public override int GetMaxCharCount(int byteCount) {
+ // FIXME
+ return 0;
+ }
+ }
+}
+
diff --git a/mcs/class/corlib/System.Text/ChangeLog b/mcs/class/corlib/System.Text/ChangeLog
new file mode 100755
index 00000000000..8c69037315f
--- /dev/null
+++ b/mcs/class/corlib/System.Text/ChangeLog
@@ -0,0 +1,31 @@
+2001-07-16 Marcin Szczepanski <marcins@zipworld.com.au>
+
+ * StringBuilder.cs (Text): Fixed.
+
+ * StringBuilderTest.cs: Implement Test suite.
+
+2001-07-12 Marcin Szczepanski <marcins@zipworld.com.au>
+
+ * StringBuilder.cs: Implemented.
+
+ The only methods left unimplemented are the AppendFormat( ... )
+ ones just because it's probably better to wait until some of the
+ Format related classes are implemented. I've put that as a TODO
+ comment at the top and created the methods with a "nop" body.
+
+2001-06-26 Sean MacIsaac <macisaac@ximian.com>
+
+ * UnicodeEncoding.cs: Members added so that a clean compile is
+ possible.
+
+ * ASCIIEncoding.cs: Members added so that a clean compile is
+ possible.
+
+ * UTF7Encoding.cs: Members added so that a clean compile is
+ possible.
+
+ * UTF8Encoding.cs: Members added so that a clean compile is
+ possible.
+
+ * Encoding.cs: All public members included. Most members
+ unimplemented.
diff --git a/mcs/class/corlib/System.Text/Encoding.cs b/mcs/class/corlib/System.Text/Encoding.cs
new file mode 100755
index 00000000000..178975441f3
--- /dev/null
+++ b/mcs/class/corlib/System.Text/Encoding.cs
@@ -0,0 +1,263 @@
+// -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+//
+// System.Text.Encoding.cs
+//
+// Author:
+// Sean MacIsaac (macisaac@ximian.com)
+//
+// (C) Ximian, Inc. http://www.ximian.com
+//
+
+
+namespace System.Text {
+
+ public abstract class Encoding {
+
+ private static ASCIIEncoding asciiEncoding;
+ private static UnicodeEncoding bigEndianUnicode;
+ private static UnicodeEncoding unicodeEncoding;
+ private static UTF7Encoding utf7Encoding;
+ private static UTF8Encoding utf8Encoding;
+
+ private int codepage;
+ protected string bodyName;
+ protected string encodingName;
+ protected string headerName;
+
+ protected Encoding() {
+ }
+
+ protected Encoding(int codepage) {
+ this.codepage = codepage;
+ }
+
+ public static Encoding ASCII {
+ get {
+ if (asciiEncoding == null)
+ asciiEncoding = new ASCIIEncoding ();
+ return asciiEncoding;
+ }
+ }
+
+ public static Encoding BigEndianUnicode {
+ get {
+ if (bigEndianUnicode == null)
+ bigEndianUnicode = new UnicodeEncoding (true, true);
+ return bigEndianUnicode;
+ }
+ }
+
+ public virtual string BodyName {
+ get {
+ return bodyName;
+ }
+ }
+
+ public virtual int CodePage {
+ get {
+ return codepage;
+ }
+ }
+
+ public static Encoding Default {
+ get {
+ return ASCII;
+ }
+ }
+
+ public virtual string EncodingName {
+ get {
+ return encodingName;
+ }
+ }
+
+ public virtual string HeaderName {
+ get {
+ return headerName;
+ }
+ }
+
+ public virtual bool IsBrowserDisplay {
+ get {
+ // FIXME
+ return false;
+ }
+ }
+
+ public virtual bool IsBrowserSave {
+ get {
+ // FIXME
+ return false;
+ }
+ }
+
+ public virtual bool IsMailNewsDisplay {
+ get {
+ // FIXME
+ return false;
+ }
+ }
+
+ public virtual bool IsMailNewsSave {
+ get {
+ // FIXME
+ return false;
+ }
+ }
+
+ public static Encoding Unicode {
+ get {
+ if (unicodeEncoding == null) {
+ unicodeEncoding = new UnicodeEncoding();
+ }
+ return unicodeEncoding;
+ }
+ }
+
+ public static Encoding UTF7 {
+ get {
+ if (utf7Encoding == null) {
+ utf7Encoding = new UTF7Encoding();
+ }
+ return utf7Encoding;
+ }
+ }
+
+ public static Encoding UTF8 {
+ get {
+ if (utf8Encoding == null) {
+ utf8Encoding = new UTF8Encoding();
+ }
+ return utf8Encoding;
+ }
+ }
+
+ public virtual string WebName {
+ get {
+ // FIXME
+ return "";
+ }
+ }
+
+ public virtual int WindowsCodePage {
+ get {
+ // FIXME
+ return 0;
+ }
+ }
+
+ public static byte[] Convert(Encoding srcEncoding, Encoding dstEncoding, byte[] bytes) {
+ // FIXME
+ return null;
+ }
+
+ public static byte[] Convert(Encoding srcEncoding, Encoding dstEncoding, byte[] bytes, int index, int count) {
+ // FIXME
+ return null;
+ }
+
+ public override bool Equals(object value) {
+ // FIXME
+ return false;
+ }
+
+ public virtual int GetByteCount(char[] chars) {
+ // FIXME
+ return 0;
+ }
+
+ public virtual int GetByteCount(string s) {
+ // FIXME
+ return 0;
+ }
+
+ public abstract int GetByteCount(char[] chars, int index, int count);
+
+ public virtual byte[] GetBytes(char[] chars) {
+ // FIXME
+ return null;
+ }
+
+ public virtual byte[] GetBytes(string s) {
+ // FIXME
+ return null;
+ }
+
+ public virtual byte[] GetBytes(char[] chars, int index, int count) {
+ // FIXME
+ return null;
+ }
+
+ public abstract int GetBytes(char[] chars, int charIndex, int charCount, byte[] bytes, int byteIndex);
+
+ public virtual byte[] GetBytes(string s, int charIndex, int charCount, byte[] bytes, int byteIndex) {
+ // FIXME
+ return null;
+ }
+
+ public virtual int GetCharCount(byte[] bytes) {
+ // FIXME
+ return 0;
+ }
+
+ public virtual int GetCharCount(byte[] bytes, int index, int count) {
+ // FIXME
+ return 0;
+ }
+
+ public virtual char[] GetChars(byte[] bytes) {
+ // FIXME
+ return null;
+ }
+
+ public virtual char[] GetChars(byte[] bytes, int index, int count) {
+ // FIXME
+ return null;
+ }
+
+ public abstract char[] GetChars(byte[] bytes, int byteIndex, int byteCount, char[] chars, int charIndex);
+
+ public virtual Decoder GetDecoder() {
+ // FIXME
+ return null;
+ }
+
+ public virtual Encoder GetEncoder() {
+ // FIXME
+ return null;
+ }
+
+ public virtual Encoding GetEncoding(int codepage) {
+ // FIXME
+ return null;
+ }
+
+ public virtual Encoding GetEncoding(string name) {
+ return null;
+ }
+
+ public override int GetHashCode() {
+ // FIXME
+ return 0;
+ }
+
+ public abstract int GetMaxByteCount(int charCount);
+
+ public abstract int GetMaxCharCount(int byteCount);
+
+ public virtual byte[] GetPreamble() {
+ // FIXME
+ return null;
+ }
+
+ public virtual string GetString(byte[] bytes) {
+ // FIXME
+ return null;
+ }
+
+ public virtual string GetString(byte[] bytes, int index, int count) {
+ // FIXME
+ return null;
+ }
+ }
+}
diff --git a/mcs/class/corlib/System.Text/StringBuilder.cs b/mcs/class/corlib/System.Text/StringBuilder.cs
new file mode 100644
index 00000000000..acf7a245f02
--- /dev/null
+++ b/mcs/class/corlib/System.Text/StringBuilder.cs
@@ -0,0 +1,564 @@
+// -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+//
+// System.Text.StringBuilder
+//
+// Author: Marcin Szczepanski (marcins@zipworld.com.au)
+//
+// TODO: Implement the AppendFormat methods. Wasn't sure how
+// best to do this at this early stage, might want to see
+// how the String class and the IFormatProvide / IFormattable interfaces
+// pan out first.
+//
+// TODO: Make sure the coding complies to the ECMA draft, there's some
+// variable names that probably don't (like sString)
+//
+
+namespace System.Text {
+ public sealed class StringBuilder {
+
+ const int defaultCapacity = 16;
+
+ private int sCapacity;
+ private int sLength;
+ private char[] sString;
+
+ public StringBuilder() {
+
+ // The MS Implementation uses the default
+ // capacity for a StringBuilder. The spec
+ // says it's up to the implementer, but
+ // we'll do it the MS way just in case.
+
+ sString = new char[ defaultCapacity ];
+ sCapacity = defaultCapacity;
+ sLength = 0;
+ }
+
+ public StringBuilder( int capacity ) {
+ if( capacity < defaultCapacity ) {
+ // The spec says that the capacity
+ // has to be at least the default capacity
+ capacity = defaultCapacity;
+ }
+
+ sString = new char[capacity];
+ sCapacity = capacity;
+ sLength = 0;
+ }
+
+ public StringBuilder( string str ) {
+
+ if( str.Length < defaultCapacity ) {
+ char[] tString = str.ToCharArray();
+ sString = new char[ defaultCapacity ];
+ Array.Copy( tString, sString, str.Length );
+ sLength = str.Length;
+ sCapacity = defaultCapacity;
+ } else {
+ sString = str.ToCharArray();
+ sCapacity = sString.Length;
+ sLength = sString.Length;
+ }
+ }
+
+ public int Capacity {
+ get {
+ return sCapacity;
+ }
+
+ set {
+ if( value < sLength ) {
+ throw new ArgumentException( "Capacity must be > length" );
+ } else {
+ char[] tString = new char[value];
+ Array.Copy( sString, tString, sLength );
+ sString = tString;
+ sCapacity = sString.Length;
+ }
+ }
+ }
+
+
+ public int Length {
+ get {
+ return sLength;
+ }
+
+ set {
+ if( value < 0 || value > Int32.MaxValue) {
+ throw new ArgumentOutOfRangeException();
+ } else {
+ if( value < sLength ) {
+ // Truncate current string at value
+
+ // LAMESPEC: The spec is unclear as to what to do
+ // with the capacity when truncating the string.
+ //
+ // Don't change the capacity, as this is what
+ // the MS implementation does.
+
+ sLength = value;
+ } else {
+ // Expand the capacity to the new length and
+ // pad the string with spaces.
+
+ // LAMESPEC: The spec says to put the spaces on the
+ // left of the string however the MS implementation
+ // puts them on the right. We'll do that for
+ // compatibility (!)
+
+ char[] tString = new char[ value ];
+ int padLength = value - sLength;
+
+ string padding = new String( ' ', padLength );
+ Array.Copy( sString, tString, sLength );
+ Array.Copy( padding.ToCharArray(), 0, tString, sLength, padLength );
+ sString = tString;
+ sLength = sString.Length;
+ sCapacity = value;
+ }
+ }
+ }
+ }
+
+ public char this[ int index ] {
+ get {
+
+ if( index >= sLength || index < 0 ) {
+ throw new IndexOutOfRangeException();
+ }
+ return sString[ index ];
+ }
+
+ set {
+ if( index >= sLength || index < 0 ) {
+ throw new IndexOutOfRangeException();
+ }
+ sString[ index ] = value;
+ }
+ }
+
+ public override string ToString() {
+ return ToString(0, sLength);
+ }
+
+ public string ToString( int startIndex, int length ) {
+ if( startIndex < 0 || length < 0 || startIndex + length > sLength ) {
+ throw new ArgumentOutOfRangeException();
+ }
+
+ return new String( sString, startIndex, length );
+ }
+
+ public int EnsureCapacity( int capacity ) {
+ if( capacity < 0 ) {
+ throw new ArgumentOutOfRangeException(
+ "Capacity must be greater than 0." );
+ }
+
+ if( capacity <= sCapacity ) {
+ return sCapacity;
+ } else {
+ Capacity = capacity;
+ return sCapacity;
+ }
+ }
+
+ public bool Equals( StringBuilder sb ) {
+ if( this.ToString() == sb.ToString() ) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ public StringBuilder Remove( int startIndex, int length ) {
+ if( startIndex < 0 || length < 0 || startIndex + length > sLength ) {
+ throw new ArgumentOutOfRangeException();
+ }
+
+ // Copy everything after the 'removed' part to the start
+ // of the removed part and truncate the sLength
+
+ Array.Copy( sString, startIndex + length, sString,
+ startIndex, length );
+
+ sLength -= length;
+ return this;
+ }
+
+ public StringBuilder Replace( char oldChar, char newChar ) {
+
+ return Replace( oldChar, newChar, 0, sLength);
+ }
+
+ public StringBuilder Replace( char oldChar, char newChar, int startIndex, int count ) {
+ if( startIndex + count > sLength || startIndex < 0 || count < 0 ) {
+ throw new ArgumentOutOfRangeException();
+ }
+
+ for( int replaceIterate = startIndex; replaceIterate < startIndex + count; replaceIterate++ ) {
+ if( this[replaceIterate] == oldChar ) {
+ this[replaceIterate] = newChar;
+ }
+ }
+
+ return this;
+ }
+
+ public StringBuilder Replace( string oldValue, string newValue ) {
+ return Replace( oldValue, newValue, 0, sLength );
+ }
+
+ public StringBuilder Replace( string oldValue, string newValue, int startIndex, int count ) {
+ string startString = this.ToString();
+ StringBuilder newStringB = new StringBuilder();
+ string newString;
+
+ if( oldValue == null ) {
+ throw new ArgumentNullException(
+ "The old value cannot be null.");
+ }
+
+ if( startIndex < 0 || count < 0 || startIndex + count > sLength ) {
+ throw new ArgumentOutOfRangeException();
+ }
+
+ if( oldValue.Length == 0 ) {
+ throw new ArgumentException(
+ "The old value cannot be zero length.");
+ }
+
+ int nextIndex = startIndex; // Where to start the next search
+ int lastIndex = nextIndex; // Where the last search finished
+
+ while( nextIndex != -1 ) {
+ nextIndex = startString.IndexOf( oldValue, lastIndex);
+ if( nextIndex != -1 ) {
+ // The MS implementation won't replace a substring
+ // if that substring goes over the "count"
+ // boundary, so we'll make sure the behaviour
+ // here is the same.
+
+ if( nextIndex + oldValue.Length <= startIndex + count ) {
+
+ // Add everything to the left of the old
+ // string
+ newStringB.Append( startString.Substring( lastIndex, nextIndex - lastIndex ) );
+
+ // Add the replacement string
+ newStringB.Append( newValue );
+
+ // Set the next start point to the
+ // end of the last match
+ lastIndex = nextIndex + oldValue.Length;
+ } else {
+ // We're past the "count" we're supposed to replace within
+ nextIndex = -1;
+ newStringB.Append(
+ startString.Substring( lastIndex ) );
+ }
+
+ } else {
+ // Append everything left over
+ newStringB.Append( startString.Substring( lastIndex ) );
+ }
+ }
+
+ newString = newStringB.ToString();
+
+ EnsureCapacity( newString.Length );
+ sString = newString.ToCharArray();
+ sLength = newString.Length;
+ return this;
+ }
+
+
+ /* The Append Methods */
+
+ // TODO: Currently most of these methods convert the
+ // parameter to a CharArray (via a String) and then pass
+ // it to Append( char[] ). There might be a faster way
+ // of doing this, but it's probably adequate and anything else
+ // would make it too messy.
+ //
+ // As an example, a sample test run of appending a 100 character
+ // string to the StringBuilder, and loooping this 50,000 times
+ // results in an elapsed time of 2.4s using the MS StringBuilder
+ // and 2.7s using this StringBuilder. Note that this results
+ // in a 5 million character string. I believe MS uses a lot
+ // of "native" DLLs for the "meat" of the base classes.
+
+
+ public StringBuilder Append( char[] value ) {
+ if( sLength + value.Length > sCapacity ) {
+ // Need more capacity, double the capacity StringBuilder
+ // and make sure we have at least enough for the value
+ // if that's going to go over double.
+
+ Capacity = value.Length + ( sCapacity + sCapacity);
+ }
+
+ Array.Copy( value, 0, sString, sLength, value.Length );
+ sLength += value.Length;
+
+ return this;
+ }
+
+ public StringBuilder Append( string value ) {
+ if( value != null ) {
+ return Append( value.ToCharArray() );
+ } else {
+ return null;
+ }
+ }
+
+ public StringBuilder Append( bool value ) {
+ return Append( value.ToString().ToCharArray() );
+ }
+
+ public StringBuilder Append( byte value ) {
+ return Append( value.ToString().ToCharArray() );
+ }
+
+ public StringBuilder Append( int index, char value) {
+ char[] appendChar = new char[1];
+
+ appendChar[0] = value;
+ return Append( appendChar );
+ }
+
+
+ public StringBuilder Append( decimal value ) {
+ return Append( value.ToString().ToCharArray() );
+ }
+
+ public StringBuilder Append( double value ) {
+ return Append( value.ToString().ToCharArray() );
+ }
+
+ public StringBuilder Append( short value ) {
+ return Append( value.ToString().ToCharArray() );
+ }
+
+ public StringBuilder Append( int value ) {
+ return Append( value.ToString().ToCharArray() );
+ }
+
+ public StringBuilder Append( long value ) {
+ return Append( value.ToString().ToCharArray() );
+ }
+
+ public StringBuilder Append( object value ) {
+ return Append( value.ToString().ToCharArray() );
+ }
+
+ public StringBuilder Append( sbyte value ) {
+ return Append( value.ToString().ToCharArray() );
+ }
+
+ public StringBuilder Append( float value ) {
+ return Append( value.ToString().ToCharArray() );
+ }
+
+ public StringBuilder Append( ushort value ) {
+ return Append( value.ToString().ToCharArray() );
+ }
+
+ public StringBuilder Append( uint value ) {
+ return Append( value.ToString().ToCharArray() );
+ }
+
+ public StringBuilder Append( ulong value ) {
+ return Append( value.ToString().ToCharArray() );
+ }
+
+ public StringBuilder Append( char value, int repeatCount ) {
+ if( repeatCount < 0 ) {
+ throw new ArgumentOutOfRangeException();
+ }
+
+ return Append( new String( value, repeatCount) );
+ }
+
+ public StringBuilder Append( char[] value, int startIndex, int charCount ) {
+
+ if( (charCount < 0 || startIndex < 0) ||
+ ( charCount + startIndex > value.Length ) ) {
+ throw new ArgumentOutOfRangeException();
+ }
+
+ if( value == null ) {
+ if( !(startIndex == 0 && charCount == 0) ) {
+ throw new ArgumentNullException();
+ } else {
+ return this;
+ }
+ } else {
+ char[] appendChars = new char[ charCount ];
+
+ Array.Copy( value, startIndex, appendChars, 0, charCount );
+ return Append( appendChars );
+ }
+ }
+
+ public StringBuilder Append( string value, int startIndex, int count ) {
+ if( (count < 0 || startIndex < 0) ||
+ ( startIndex + count > value.Length ) ) {
+ throw new ArgumentOutOfRangeException();
+ }
+
+ return Append( value.Substring( startIndex, count ).ToCharArray() );
+ }
+
+ public StringBuilder AppendFormat( string format, object arg0 ) {
+ // TODO: Implement
+ return this;
+ }
+
+ public StringBuilder AppendFormat( string format, params object[] args ) {
+ // TODO: Implement
+ return this;
+ }
+
+ public StringBuilder AppendFormat( IFormatProvider provider, string format,
+ params object[] args ) {
+ // TODO: Implement
+ return this;
+ }
+
+ public StringBuilder AppendFormat( string format, object arg0, object arg1 ) {
+ // TODO: Implement;
+ return this;
+ }
+
+ public StringBuilder AppendFormat( string format, object arg0, object arg1, object arg2 ) {
+ // TODO Implement
+ return this;
+ }
+
+ /* The Insert Functions */
+
+ // Similarly to the Append functions, get everything down to a CharArray
+ // and insert that.
+
+ public StringBuilder Insert( int index, char[] value ) {
+ if( index > sLength || index < 0) {
+ throw new ArgumentOutOfRangeException();
+ }
+
+ if( value == null || value.Length == 0 ) {
+ return this;
+ } else {
+ // Check we have the capacity to insert this array
+ if( sCapacity < sLength + value.Length ) {
+ Capacity = value.Length + ( sCapacity + sCapacity );
+ }
+
+ // Move everything to the right of the insert point across
+ Array.Copy( sString, index, sString, index + value.Length, sLength - index);
+
+ // Copy in stuff from the insert buffer
+ Array.Copy( value, 0, sString, index, value.Length );
+
+ sLength += value.Length;
+ return this;
+ }
+ }
+
+ public StringBuilder Insert( int index, string value ) {
+ return Insert( index, value.ToCharArray() );
+ }
+
+ public StringBuilder Insert( int index, bool value ) {
+ return Insert( index, value.ToString().ToCharArray() );
+ }
+
+ public StringBuilder Insert( int index, byte value ) {
+ return Insert( index, value.ToString().ToCharArray() );
+ }
+
+ public StringBuilder Insert( int index, char value) {
+ char[] insertChar = new char[1];
+
+ insertChar[0] = value;
+ return Insert( index, insertChar );
+ }
+
+ public StringBuilder Insert( int index, decimal value ) {
+ return Insert( index, value.ToString().ToCharArray() );
+ }
+
+ public StringBuilder Insert( int index, double value ) {
+ return Insert( index, value.ToString().ToCharArray() );
+ }
+
+ public StringBuilder Insert( int index, short value ) {
+ return Insert( index, value.ToString().ToCharArray() );
+ }
+
+ public StringBuilder Insert( int index, int value ) {
+ return Insert( index, value.ToString().ToCharArray() );
+ }
+
+ public StringBuilder Insert( int index, long value ) {
+ return Insert( index, value.ToString().ToCharArray() );
+ }
+
+ public StringBuilder Insert( int index, object value ) {
+ return Insert( index, value.ToString().ToCharArray() );
+ }
+
+ public StringBuilder Insert( int index, sbyte value ) {
+ return Insert( index, value.ToString().ToCharArray() );
+ }
+
+ public StringBuilder Insert( int index, float value ) {
+ return Insert( index, value.ToString().ToCharArray() );
+ }
+
+ public StringBuilder Insert( int index, ushort value ) {
+ return Insert( index, value.ToString().ToCharArray() );
+ }
+
+ public StringBuilder Insert( int index, uint value ) {
+ return Insert( index, value.ToString().ToCharArray() );
+ }
+
+ public StringBuilder Insert( int index, ulong value ) {
+ return Insert( index, value.ToString().ToCharArray() );
+ }
+
+ public StringBuilder Insert( int index, string value, int count ) {
+ if ( count < 0 ) {
+ throw new ArgumentOutOfRangeException();
+ }
+
+ if( value != null ) {
+ if( value != "" ) {
+ for( int insertCount = 0; insertCount < count;
+ insertCount++ ) {
+ Insert( index, value.ToCharArray() );
+ }
+ }
+ }
+ return this;
+ }
+
+ public StringBuilder Insert( int index, char[] value, int startIndex,
+ int charCount ) {
+
+ if( value != null ) {
+ if( charCount < 0 || startIndex < 0 || startIndex + charCount > value.Length ) {
+ throw new ArgumentOutOfRangeException();
+ }
+
+ char[] insertChars = new char[ charCount ];
+ Array.Copy( value, startIndex, insertChars, 0, charCount );
+ return Insert( index, insertChars );
+ } else {
+ return this;
+ }
+ }
+ }
+}
diff --git a/mcs/class/corlib/System.Text/UTF7Encoding.cs b/mcs/class/corlib/System.Text/UTF7Encoding.cs
new file mode 100755
index 00000000000..c21389b7e8a
--- /dev/null
+++ b/mcs/class/corlib/System.Text/UTF7Encoding.cs
@@ -0,0 +1,40 @@
+//
+// System.Text.UTF7Encoding.cs
+//
+// Author:
+// Sean MacIsaac (macisaac@ximian.com)
+//
+// (C) Ximian, Inc. http://www.ximian.com
+//
+
+
+namespace System.Text {
+
+ public class UTF7Encoding : Encoding {
+ public override int GetByteCount(char[] chars, int index, int count) {
+ // FIXME
+ return 0;
+ }
+
+ public override int GetBytes(char[] chars, int charIndex, int charCount, byte[] bytes, int byteIndex) {
+ // FIXME
+ return 0;
+ }
+
+ public override char[] GetChars(byte[] bytes, int byteIndex, int byteCount, char[] chars, int charIndex) {
+ // FIXME
+ return null;
+ }
+
+ public override int GetMaxByteCount(int charCount) {
+ // FIXME
+ return 0;
+ }
+
+ public override int GetMaxCharCount(int byteCount) {
+ // FIXME
+ return 0;
+ }
+ }
+}
+
diff --git a/mcs/class/corlib/System.Text/UTF8Encoding.cs b/mcs/class/corlib/System.Text/UTF8Encoding.cs
new file mode 100755
index 00000000000..eb7ddffaf7d
--- /dev/null
+++ b/mcs/class/corlib/System.Text/UTF8Encoding.cs
@@ -0,0 +1,40 @@
+//
+// System.Text.UTF8Encoding.cs
+//
+// Author:
+// Sean MacIsaac (macisaac@ximian.com)
+//
+// (C) Ximian, Inc. http://www.ximian.com
+//
+
+
+namespace System.Text {
+
+ public class UTF8Encoding : Encoding {
+ public override int GetByteCount(char[] chars, int index, int count) {
+ // FIXME
+ return 0;
+ }
+
+ public override int GetBytes(char[] chars, int charIndex, int charCount, byte[] bytes, int byteIndex) {
+ // FIXME
+ return 0;
+ }
+
+ public override char[] GetChars(byte[] bytes, int byteIndex, int byteCount, char[] chars, int charIndex) {
+ // FIXME
+ return null;
+ }
+
+ public override int GetMaxByteCount(int charCount) {
+ // FIXME
+ return 0;
+ }
+
+ public override int GetMaxCharCount(int byteCount) {
+ // FIXME
+ return 0;
+ }
+ }
+}
+
diff --git a/mcs/class/corlib/System.Text/UnicodeEncoding.cs b/mcs/class/corlib/System.Text/UnicodeEncoding.cs
new file mode 100755
index 00000000000..374c6e1963c
--- /dev/null
+++ b/mcs/class/corlib/System.Text/UnicodeEncoding.cs
@@ -0,0 +1,46 @@
+// -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+//
+// System.Text.UnicodeEncoding.cs
+//
+// Author:
+// Sean MacIsaac (macisaac@ximian.com)
+//
+// (C) Ximian, Inc. http://www.ximian.com
+//
+
+
+namespace System.Text {
+
+ public class UnicodeEncoding : Encoding {
+ public UnicodeEncoding() {
+ }
+
+ public UnicodeEncoding(bool bigEndian, bool byteOrderMark) {
+ }
+
+ public override int GetByteCount(char[] chars, int index, int count) {
+ // FIXME
+ return 0;
+ }
+
+ public override int GetBytes(char[] chars, int charIndex, int charCount, byte[] bytes, int byteIndex) {
+ // FIXME
+ return 0;
+ }
+
+ public override char[] GetChars(byte[] bytes, int byteIndex, int byteCount, char[] chars, int charIndex) {
+ // FIXME
+ return null;
+ }
+
+ public override int GetMaxByteCount(int charCount) {
+ // FIXME
+ return 0;
+ }
+
+ public override int GetMaxCharCount(int byteCount) {
+ // FIXME
+ return 0;
+ }
+ }
+}
diff --git a/mcs/class/corlib/System.Text/common.src b/mcs/class/corlib/System.Text/common.src
new file mode 100755
index 00000000000..774b5bc098c
--- /dev/null
+++ b/mcs/class/corlib/System.Text/common.src
@@ -0,0 +1,6 @@
+ASCIIEncoding.cs
+Encoding.cs
+StringBuilder.cs
+UTF7Encoding.cs
+UTF8Encoding.cs
+UnicodeEncoding.cs
diff --git a/mcs/class/corlib/System.Text/unix.src b/mcs/class/corlib/System.Text/unix.src
new file mode 100755
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/mcs/class/corlib/System.Text/unix.src
diff --git a/mcs/class/corlib/System.Text/windows.src b/mcs/class/corlib/System.Text/windows.src
new file mode 100755
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/mcs/class/corlib/System.Text/windows.src
diff --git a/mcs/class/corlib/System.Threading/ChangeLog b/mcs/class/corlib/System.Threading/ChangeLog
new file mode 100644
index 00000000000..a3ba2327f6a
--- /dev/null
+++ b/mcs/class/corlib/System.Threading/ChangeLog
@@ -0,0 +1,3 @@
+2001-07-18 Michael Lambert <michaellambert@email.com>
+
+ * ThreadPriority.cs, ThreadState.cs: Add.
diff --git a/mcs/class/corlib/System.Threading/ThreadPriority.cs b/mcs/class/corlib/System.Threading/ThreadPriority.cs
new file mode 100644
index 00000000000..5359c74455b
--- /dev/null
+++ b/mcs/class/corlib/System.Threading/ThreadPriority.cs
@@ -0,0 +1,24 @@
+//------------------------------------------------------------------------------
+//
+// System.Threading.ThreadPriority.cs
+//
+// Copyright (C) 2001 Michael Lambert, All Rights Reserved
+//
+// Author: Michael Lambert, michaellambert@email.com
+// Created: Thu 07/18/2001
+//
+//------------------------------------------------------------------------------
+
+namespace System.Threading
+{
+
+public enum ThreadPriority
+{
+ AboveNormal,
+ BelowNormal,
+ Highest,
+ Lowest,
+ Normal,
+}
+
+} // Namespace
diff --git a/mcs/class/corlib/System.Threading/ThreadState.cs b/mcs/class/corlib/System.Threading/ThreadState.cs
new file mode 100644
index 00000000000..c72ee97df93
--- /dev/null
+++ b/mcs/class/corlib/System.Threading/ThreadState.cs
@@ -0,0 +1,25 @@
+//------------------------------------------------------------------------------
+//
+// System.Threading.ThreadState.cs
+//
+// Copyright (C) 2001 Michael Lambert, All Rights Reserved
+//
+// Author: Michael Lambert, michaellambert@email.com
+// Created: Thu 07/18/2001
+//
+//------------------------------------------------------------------------------
+
+namespace System.Threading
+{
+
+public enum ThreadState
+{
+ Aborted,
+ AbortRequested,
+ Background,
+ Running,
+ Unstarted,
+ WaitSleepJoin,
+}
+
+} // Namespace
diff --git a/mcs/class/corlib/System.Threading/common.src b/mcs/class/corlib/System.Threading/common.src
new file mode 100644
index 00000000000..feba1d5271b
--- /dev/null
+++ b/mcs/class/corlib/System.Threading/common.src
@@ -0,0 +1,2 @@
+ThreadPriority.cs
+ThreadState.cs
diff --git a/mcs/class/corlib/System.Threading/unix.src b/mcs/class/corlib/System.Threading/unix.src
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/mcs/class/corlib/System.Threading/unix.src
diff --git a/mcs/class/corlib/System.Threading/windows.src b/mcs/class/corlib/System.Threading/windows.src
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/mcs/class/corlib/System.Threading/windows.src
diff --git a/mcs/class/corlib/System/ApplicationException.cs b/mcs/class/corlib/System/ApplicationException.cs
new file mode 100644
index 00000000000..9bb597644aa
--- /dev/null
+++ b/mcs/class/corlib/System/ApplicationException.cs
@@ -0,0 +1,29 @@
+//
+// System.ApplicationException.cs
+//
+// Author:
+// Joe Shaw (joe@ximian.com)
+//
+// (C) 2001 Ximian, Inc. http://www.ximian.com
+//
+
+namespace System {
+
+ public class ApplicationException : Exception {
+ // Constructors
+ public ApplicationException ()
+ : base ("An application exception has occurred.")
+ {
+ }
+
+ public ApplicationException (string message)
+ : base (message)
+ {
+ }
+
+ public ApplicationException (string message, Exception inner)
+ : base (message, inner)
+ {
+ }
+ }
+}
diff --git a/mcs/class/corlib/System/ArgumentException.cs b/mcs/class/corlib/System/ArgumentException.cs
new file mode 100644
index 00000000000..c97c57cac12
--- /dev/null
+++ b/mcs/class/corlib/System/ArgumentException.cs
@@ -0,0 +1,50 @@
+//
+// System.ArgumentException.cs
+//
+// Author:
+// Joe Shaw (joe@ximian.com)
+//
+// (C) 2001 Ximian, Inc. http://www.ximian.com
+//
+
+namespace System {
+
+ public class ArgumentException : SystemException {
+ private string param_name;
+
+ // Constructors
+ public ArgumentException ()
+ : base ("An invalid argument was specified.")
+ {
+ }
+
+ public ArgumentException (string message)
+ : base (message)
+ {
+ }
+
+ public ArgumentException (string message, Exception inner)
+ : base (message, inner)
+ {
+ }
+
+ public ArgumentException (string message, string param_name)
+ : base (message)
+ {
+ this.param_name = param_name;
+ }
+
+ public ArgumentException (string message, string param_name, Exception inner)
+ : base (message, inner)
+ {
+ this.param_name = param_name;
+ }
+
+ // Properties
+ public virtual string ParamName {
+ get {
+ return param_name;
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/mcs/class/corlib/System/ArgumentNullException.cs b/mcs/class/corlib/System/ArgumentNullException.cs
new file mode 100644
index 00000000000..d35a9648e63
--- /dev/null
+++ b/mcs/class/corlib/System/ArgumentNullException.cs
@@ -0,0 +1,29 @@
+//
+// System.ArgumentNullException.cs
+//
+// Author:
+// Joe Shaw (joe@ximian.com)
+//
+// (C) 2001 Ximian, Inc. http://www.ximian.com
+//
+
+namespace System {
+
+ public class ArgumentNullException : ArgumentException {
+ // Constructors
+ public ArgumentNullException ()
+ : base ("Argument cannot be null")
+ {
+ }
+
+ public ArgumentNullException (string param_name)
+ : base ("Argument cannot be null", param_name)
+ {
+ }
+
+ public ArgumentNullException (string param_name, string message)
+ : base (message, param_name)
+ {
+ }
+ }
+} \ No newline at end of file
diff --git a/mcs/class/corlib/System/ArgumentOutOfRangeException.cs b/mcs/class/corlib/System/ArgumentOutOfRangeException.cs
new file mode 100644
index 00000000000..26acf91cf46
--- /dev/null
+++ b/mcs/class/corlib/System/ArgumentOutOfRangeException.cs
@@ -0,0 +1,44 @@
+//
+// System.ArgumentOutOfRangeException.cs
+//
+// Author:
+// Joe Shaw (joe@ximian.com)
+//
+// (C) 2001 Ximian, Inc. http://www.ximian.com
+//
+
+namespace System {
+
+ public class ArgumentOutOfRangeException : ArgumentException {
+ private object actual_value;
+
+ // Constructors
+ public ArgumentOutOfRangeException ()
+ : base ("Argument is out of range")
+ {
+ }
+
+ public ArgumentOutOfRangeException (string param_name)
+ : base ("Argument is out of range", param_name)
+ {
+ }
+
+ public ArgumentOutOfRangeException (string param_name, string message)
+ : base (message, param_name)
+ {
+ }
+
+ public ArgumentOutOfRangeException (string param_name, object actual_value, string message)
+ : base (message, param_name)
+ {
+ this.actual_value = actual_value;
+ }
+
+ // Properties
+ public virtual object ActualValue {
+ get {
+ return actual_value;
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/mcs/class/corlib/System/ArithmeticException.cs b/mcs/class/corlib/System/ArithmeticException.cs
new file mode 100644
index 00000000000..cc5bfa92477
--- /dev/null
+++ b/mcs/class/corlib/System/ArithmeticException.cs
@@ -0,0 +1,29 @@
+//
+// System.ArithmeticException.cs
+//
+// Author:
+// Joe Shaw (joe@ximian.com)
+//
+// (C) 2001 Ximian, Inc. http://www.ximian.com
+//
+
+namespace System {
+
+ public class ArithmeticException : SystemException {
+ // Constructors
+ public ArithmeticException ()
+ : base ("The arithmetic operation is not allowed")
+ {
+ }
+
+ public ArithmeticException (string message)
+ : base (message)
+ {
+ }
+
+ public ArithmeticException (string message, Exception inner)
+ : base (message, inner)
+ {
+ }
+ }
+} \ No newline at end of file
diff --git a/mcs/class/corlib/System/Array.cs b/mcs/class/corlib/System/Array.cs
new file mode 100644
index 00000000000..be7f5cf03da
--- /dev/null
+++ b/mcs/class/corlib/System/Array.cs
@@ -0,0 +1,510 @@
+//
+// System.Array.cs
+//
+// Author:
+// Joe Shaw (joe@ximian.com)
+//
+// (C) 2001 Ximian, Inc. http://www.ximian.com
+//
+
+using System.Collections;
+using System.Runtime.CompilerServices;
+
+namespace System
+{
+
+ public abstract class Array : ICloneable
+ {
+ // Constructor
+ protected Array ()
+ {
+ /* empty */
+ }
+
+ // Properties
+ public int Length
+ {
+ get
+ {
+ int length = this.GetLength (0);
+
+ for (int i = 1; i < this.Rank; i++) {
+ length *= this.GetLength (i);
+ }
+
+ return length;
+ }
+ }
+
+ public int Rank
+ {
+ get
+ {
+ return this.GetRank ();
+ }
+ }
+
+ // InternalCall Methods
+
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ public extern int GetRank ();
+
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ public extern int GetLength (int dimension);
+
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ public extern int GetLowerBound (int dimension);
+
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ public extern object GetValue (int[] idxs);
+
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ public extern void SetValue (object value, int[] idxs);
+
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ public extern static Array CreateInstance(Type elementType, int[] lengths, int [] bounds);
+
+ // Methods Implementations
+
+ public int GetUpperBound (int dimension)
+ {
+ return GetLowerBound (dimension) +
+ GetLength (dimension);
+ }
+
+ public object GetValue (int idx)
+ {
+ int[] ind = new int [1];
+
+ ind [0] = idx;
+
+ return GetValue (ind);
+ }
+
+ public object GetValue (int idx1, int idx2)
+ {
+ int[] ind = new int [2];
+
+ ind [0] = idx1;
+ ind [1] = idx2;
+
+ return GetValue (ind);
+ }
+
+ public object GetValue (int idx1, int idx2, int idx3)
+ {
+ int[] ind = new int [3];
+
+ ind [0] = idx1;
+ ind [1] = idx2;
+ ind [2] = idx3;
+
+ return GetValue (ind);
+ }
+
+ public void SetValue (object value, int idx)
+ {
+ int[] ind = new int [1];
+
+ ind [0] = idx;
+
+ SetValue (value, ind);
+ }
+
+ public void SetValue (object value, int idx1, int idx2)
+ {
+ int[] ind = new int [2];
+
+ ind [0] = idx1;
+ ind [1] = idx2;
+
+ SetValue (value, ind);
+ }
+
+ public void SetValue (object value, int idx1, int idx2, int idx3)
+ {
+ int[] ind = new int [3];
+
+ ind [0] = idx1;
+ ind [1] = idx2;
+ ind [2] = idx3;
+
+ SetValue (value, ind);
+ }
+
+ public static Array CreateInstance(Type elementType, int length)
+ {
+ int[] lengths = new int [1];
+ int[] bounds = null;
+
+ lengths [0] = length;
+
+ return CreateInstance (elementType, lengths, bounds);
+ }
+
+ public static Array CreateInstance(Type elementType, int l1, int l2)
+ {
+ int[] lengths = new int [2];
+ int[] bounds = null;
+
+ lengths [0] = l1;
+ lengths [1] = l2;
+
+ return CreateInstance (elementType, lengths, bounds);
+ }
+
+ public static Array CreateInstance(Type elementType, int l1, int l2, int l3)
+ {
+ int[] lengths = new int [3];
+ int[] bounds = null;
+
+ lengths [0] = l1;
+ lengths [1] = l2;
+ lengths [2] = l3;
+
+ return CreateInstance (elementType, lengths, bounds);
+ }
+
+ public static Array CreateInstance(Type elementType, int[] lengths)
+ {
+ int[] bounds = null;
+
+ return CreateInstance (elementType, lengths, bounds);
+ }
+
+
+ public static int BinarySearch (Array array, object value)
+ {
+ return BinarySearch (array, array.GetLowerBound (0), array.GetLength (0),
+ value, null);
+ }
+
+ public static int BinarySearch (Array array, object value, IComparer comparer)
+ {
+ return BinarySearch (array, array.GetLowerBound (0), array.GetLength (0),
+ value, comparer);
+ }
+
+ public static int BinarySearch (Array array, int index, int length, object value)
+ {
+ return BinarySearch (array, index, length, value, null);
+ }
+
+ public static int BinarySearch (Array array, int index,
+ int length, object value,
+ IComparer comparer)
+ {
+ if (array == null)
+ throw new ArgumentNullException ();
+
+ if (array.Rank > 1)
+ throw new RankException ();
+
+ if (index < array.GetLowerBound (0) || length < 0)
+ throw new ArgumentOutOfRangeException ();
+
+ if (index + length > array.GetUpperBound (0))
+ throw new ArgumentException ();
+
+ if (comparer == null && !(value is IComparable))
+ throw new ArgumentException ();
+
+ // FIXME: Throw an ArgumentException if comparer
+ // is null and value is not of the same type as the
+ // elements of array.
+
+ for (int i = 0; i < length; i++)
+ {
+ int result;
+
+ if (comparer == null && !(array.GetValue(index + i) is IComparable))
+ throw new ArgumentException ();
+
+ if (comparer == null)
+ result = (value as IComparable).CompareTo(array.GetValue(index + i));
+ else
+ result = comparer.Compare(value, array.GetValue(index + i));
+
+ if (result == 0)
+ return index + i;
+ else if (result < 0)
+ return ~(index + i);
+ }
+
+ return ~(index + length);
+ }
+
+ public static void Clear (Array array, int index, int length)
+ {
+ if (array == null)
+ throw new ArgumentNullException ();
+
+ if (array.Rank > 1)
+ throw new RankException ();
+
+ if (index < array.GetLowerBound (0) || length < 0 ||
+ index + length > array.GetUpperBound (0))
+ throw new ArgumentOutOfRangeException ();
+
+ for (int i = 0; i < length; i++)
+ {
+ if (array.GetValue(index + i) is bool)
+ array.SetValue(false, index + i);
+ else if (array.GetValue(index + i) is ValueType)
+ array.SetValue(0, index + i);
+ else
+ array.SetValue(null, index + i);
+ }
+ }
+
+ public virtual object Clone ()
+ {
+ // Array is abstract -- Array a = new Array();
+ Array a = (Array)this.Clone();
+
+ // I don't know how to handle this ?
+ if (this.Rank > 1)
+ throw new RankException ();
+
+ for (int i = 0; i < this.GetLength (0); i++)
+ {
+ int index = this.GetLowerBound (0) + i;
+
+ a.SetValue(this.GetValue(index), index);
+ }
+
+ return a;
+ }
+
+ public static void Copy (Array source, Array dest, int length)
+ {
+ // I don't know how to handle this ?
+ if (source.Rank > 1 || dest.Rank > 1)
+ throw new RankException ();
+
+ Copy (source, source.GetLowerBound (0), dest, dest.GetLowerBound (0), length);
+ }
+
+ public static void Copy (Array source, int source_idx, Array dest, int dest_idx, int length)
+ {
+ // I don't know how to handle this ?
+ if (source.Rank > 1 || dest.Rank > 1)
+ throw new RankException ();
+
+ if (length < 0)
+ throw new ArgumentOutOfRangeException ();
+
+ if (source == null || dest == null)
+ throw new ArgumentNullException ();
+
+ if (source_idx < source.GetLowerBound (0) ||
+ source_idx + length > source.GetUpperBound (0) ||
+ dest_idx < dest.GetLowerBound (0) || dest_idx + length > dest.GetUpperBound (0))
+ throw new ArgumentException ();
+
+ if (source.Rank != dest.Rank)
+ throw new RankException ();
+
+ for (int i = 0; i < length; i++)
+ {
+ int index = source.GetLowerBound (0) + i;
+
+ dest.SetValue(source.GetValue(index), index);
+ }
+
+ }
+
+ public static int IndexOf (Array array, object value)
+ {
+ return IndexOf (array, value, 0, array.Length);
+ }
+
+ public static int IndexOf (Array array, object value, int index)
+ {
+ return IndexOf (array, value, index, array.Length - index);
+ }
+
+ public static int IndexOf (Array array, object value, int index, int length)
+ {
+ if (array == null)
+ throw new ArgumentNullException ();
+
+ if (length < 0 || index < array.GetLowerBound (0) ||
+ index > array.GetUpperBound (0))
+ throw new ArgumentOutOfRangeException ();
+
+ for (int i = 0; i < length; i++)
+ {
+ if (array.GetValue(index + i) == value)
+ return index + i;
+ }
+
+ return array.GetLowerBound (0) - 1;
+ }
+
+ public static int LastIndexOf (Array array, object value)
+ {
+ return LastIndexOf (array, value, 0, array.Length);
+ }
+
+ public static int LastIndexOf (Array array, object value, int index)
+ {
+ return LastIndexOf (array, value, index, array.Length - index);
+ }
+
+ public static int LastIndexOf (Array array, object value, int index, int length)
+ {
+ if (array == null)
+ throw new ArgumentNullException ();
+
+ if (length < 0 || index < array.GetLowerBound (0) ||
+ index > array.GetUpperBound (0))
+ throw new ArgumentOutOfRangeException ();
+
+ for (int i = length - 1; i >= 0; i--)
+ {
+ if (array.GetValue(index + i) == value)
+ return index + i;
+ }
+
+ return array.GetLowerBound (0) - 1;
+ }
+
+ public static void Reverse (Array array)
+ {
+ Reverse (array, array.GetLowerBound (0), array.GetLength (0));
+ }
+
+ public static void Reverse (Array array, int index, int length)
+ {
+ if (array == null)
+ throw new ArgumentNullException ();
+
+ if (array.Rank > 1)
+ throw new RankException ();
+
+ if (index < array.GetLowerBound (0) || length < 0)
+ throw new ArgumentOutOfRangeException ();
+
+ if (index + length > array.GetUpperBound (0))
+ throw new ArgumentException ();
+
+ for (int i = 0; i < length/2; i++)
+ {
+ object tmp;
+
+ tmp = array.GetValue (index + i);
+ array.SetValue(array.GetValue (index + length - i - 1), index + i);
+ array.SetValue(tmp, index + length - i - 1);
+ }
+ }
+
+ public static void Sort (Array array)
+ {
+ Sort (array, null, array.GetLowerBound (0), array.GetLength (0), null);
+ }
+
+ public static void Sort (Array keys, Array items)
+ {
+ Sort (keys, items, keys.GetLowerBound (0), keys.GetLength (0), null);
+ }
+
+ public static void Sort (Array array, IComparer comparer)
+ {
+ Sort (array, null, array.GetLowerBound (0), array.GetLength (0), comparer);
+ }
+
+ public static void Sort (Array array, int index, int length)
+ {
+ Sort (array, null, index, length, null);
+ }
+
+ public static void Sort (Array keys, Array items, IComparer comparer)
+ {
+ Sort (keys, items, keys.GetLowerBound (0), keys.GetLength (0), comparer);
+ }
+
+ public static void Sort (Array keys, Array items, int index, int length)
+ {
+ Sort (keys, items, index, length, null);
+ }
+
+ public static void Sort (Array array, int index, int length, IComparer comparer)
+ {
+ Sort (array, null, index, length, comparer);
+ }
+
+ public static void Sort (Array keys, Array items, int index, int length, IComparer comparer)
+ {
+ int low0 = index;
+ int high0 = index + length - 1;
+
+ qsort (keys, items, index, index + length - 1, comparer);
+ }
+
+ private static void qsort (Array keys, Array items, int low0, int high0, IComparer comparer)
+ {
+ int pivot;
+ int low = low0;
+ int high = high0;
+
+ if (keys.Rank > 1 || items.Rank > 1)
+ throw new RankException ();
+
+ if (low >= high)
+ return;
+
+ pivot = (low + high) / 2;
+
+ if (compare (keys.GetValue (low), keys.GetValue (pivot), comparer) > 0)
+ swap (keys, items, low, pivot);
+
+ if (compare (keys.GetValue (pivot), keys.GetValue (high), comparer) > 0)
+ swap (keys, items, pivot, high);
+
+ while (low < high)
+ {
+ // Move the walls in
+ while (low < high && compare (keys.GetValue (low), keys.GetValue (pivot), comparer) < 0)
+ low++;
+ while (low < high && compare (keys.GetValue (pivot), keys.GetValue (high), comparer) < 0)
+ high--;
+
+ if (low < high)
+ {
+ swap (keys, items, low, high);
+ low++;
+ high--;
+ }
+ }
+
+ qsort (keys, items, low0, low - 1, comparer);
+ qsort (keys, items, high + 1, high0, comparer);
+ }
+
+ private static void swap (Array keys, Array items, int i, int j)
+ {
+ object tmp;
+
+ tmp = keys.GetValue (i);
+ keys.SetValue (keys.GetValue (j), i);
+ keys.SetValue (tmp, j);
+
+ if (items != null)
+ {
+ tmp = items.GetValue (i);
+ items.SetValue (items.GetValue (j), i);
+ items.SetValue (tmp, j);
+ }
+ }
+
+ private static int compare (object value1, object value2, IComparer comparer)
+ {
+ if (comparer == null)
+ return ((IComparable) value1).CompareTo(value2);
+ else
+ return comparer.Compare(value1, value2);
+ }
+
+ }
+}
diff --git a/mcs/class/corlib/System/ArrayTypeMismatchException.cs b/mcs/class/corlib/System/ArrayTypeMismatchException.cs
new file mode 100644
index 00000000000..ecfc88a4cc8
--- /dev/null
+++ b/mcs/class/corlib/System/ArrayTypeMismatchException.cs
@@ -0,0 +1,29 @@
+//
+// System.ArrayTypeMismatchException.cs
+//
+// Author:
+// Joe Shaw (joe@ximian.com)
+//
+// (C) 2001 Ximian, Inc. http://www.ximian.com
+//
+
+namespace System {
+
+ public class ArrayTypeMismatchException : SystemException {
+ // Constructors
+ public ArrayTypeMismatchException ()
+ : base ("Source array type cannot be assigned to destination array type")
+ {
+ }
+
+ public ArrayTypeMismatchException (string message)
+ : base (message)
+ {
+ }
+
+ public ArrayTypeMismatchException (string message, Exception inner)
+ : base (message, inner)
+ {
+ }
+ }
+} \ No newline at end of file
diff --git a/mcs/class/corlib/System/Attribute.cs b/mcs/class/corlib/System/Attribute.cs
new file mode 100644
index 00000000000..9db339aa399
--- /dev/null
+++ b/mcs/class/corlib/System/Attribute.cs
@@ -0,0 +1,284 @@
+//
+// System.Attribute.cs
+//
+// Authors:
+// Miguel de Icaza (miguel@ximian.com) - Original
+// Nick D. Drochak II (ndrochak@gol.com) - Implemented most of the guts
+//
+// (C) Ximian, Inc. http://www.ximian.com
+//
+
+using System;
+namespace System {
+
+ public abstract class Attribute {
+
+ protected Attribute ()
+ {
+ }
+
+ public virtual object TypeId {
+ get {
+ // Derived classes should override this default behaviour as appropriate
+ return this.GetType();
+ }
+ }
+
+ private static void CheckParameters(object element, Type attributeType)
+ {
+ // neither parameter is allowed to be null
+ if (null == element)
+ {
+ throw new ArgumentNullException("element");
+ }
+
+ if (null == attributeType)
+ {
+ throw new ArgumentNullException("attributeType");
+ }
+
+ }
+
+ private static System.Attribute FindAttribute(object[] attributes)
+ {
+ // if there exists more than one attribute of the given type, throw an exception
+ if (attributes.Length > 1)
+ {
+ throw new System.Reflection.AmbiguousMatchException("<element> has more than one attribute of type <attributeType>");
+ }
+
+ if (attributes.Length < 1)
+ {
+ return (System.Attribute) null;
+ }
+
+ // tested above for '> 1' and and '< 1', so only '== 1' is left, i.e. we found the attribute
+ return (System.Attribute) attributes[0];
+ }
+
+ private static void CheckAncestry(Type attributeType)
+ {
+ // attributeType must be derived from type System.Attribute
+ Type t = typeof(System.Attribute);
+
+ /* fixme: thgi does not work for target monolib2
+ if (!attributeType.IsSubclassOf(t))
+ {
+ throw new ArgumentException("Parameter is not a type derived from System.Attribute", "attributeType");
+ }
+ */
+ }
+
+ public static Attribute GetCustomAttribute(System.Reflection.ParameterInfo element, Type attributeType){
+ return GetCustomAttribute(element, attributeType, true);
+ }
+
+ public static Attribute GetCustomAttribute(System.Reflection.MemberInfo element, Type attributeType){
+ return GetCustomAttribute(element, attributeType, true);
+ }
+
+ public static Attribute GetCustomAttribute(System.Reflection.Assembly element, Type attributeType){ return GetCustomAttribute(element, attributeType, true);
+ }
+
+ public static Attribute GetCustomAttribute(System.Reflection.Module element, Type attributeType){
+ return GetCustomAttribute(element, attributeType, true);
+ }
+
+ public static Attribute GetCustomAttribute(System.Reflection.Module element, Type attributeType, bool inherit){
+ // neither parameter is allowed to be null
+ CheckParameters(element, attributeType);
+
+ // attributeType must be derived from type System.Attribute
+ CheckAncestry(attributeType);
+
+ // Module inheritance hierarchies CAN NOT be searched for attributes, so the second
+ // parameter of GetCustomAttributes() is INGNORED.
+ object[] attributes = element.GetCustomAttributes(attributeType, inherit);
+
+ return FindAttribute(attributes);
+ }
+
+ public static Attribute GetCustomAttribute(System.Reflection.Assembly element, Type attributeType, bool inherit){
+ // neither parameter is allowed to be null
+ CheckParameters(element, attributeType);
+
+ // attributeType must be derived from type System.Attribute
+ CheckAncestry(attributeType);
+
+ // Assembly inheritance hierarchies CAN NOT be searched for attributes, so the second
+ // parameter of GetCustomAttributes() is INGNORED.
+ object[] attributes = element.GetCustomAttributes(attributeType, inherit);
+
+ return FindAttribute(attributes);
+ }
+ public static Attribute GetCustomAttribute(System.Reflection.ParameterInfo element, Type attributeType, bool inherit){
+ // neither parameter is allowed to be null
+ CheckParameters(element, attributeType);
+
+ // attributeType must be derived from type System.Attribute
+ CheckAncestry(attributeType);
+
+ // ParameterInfo inheritance hierarchies CAN NOT be searched for attributes, so the second
+ // parameter of GetCustomAttributes() is INGNORED.
+ object[] attributes = element.GetCustomAttributes(attributeType, inherit);
+
+ return FindAttribute(attributes);
+ }
+ public static Attribute GetCustomAttribute(System.Reflection.MemberInfo element, Type attributeType, bool inherit){
+ // neither parameter is allowed to be null
+ CheckParameters(element, attributeType);
+
+ // attributeType must be derived from type System.Attribute
+ CheckAncestry(attributeType);
+
+ // MemberInfo inheritance hierarchies can be searched for attributes, so the second
+ // parameter of GetCustomAttributes() is respected.
+ object[] attributes = element.GetCustomAttributes(attributeType, inherit);
+
+ return FindAttribute(attributes);
+ }
+
+ public static Attribute[] GetCustomAttributes(System.Reflection.Assembly element){
+ return System.Attribute.GetCustomAttributes(element, true);
+ }
+ public static Attribute[] GetCustomAttributes(System.Reflection.ParameterInfo element){
+ return System.Attribute.GetCustomAttributes(element, true);
+ }
+ public static Attribute[] GetCustomAttributes(System.Reflection.MemberInfo element){
+ return System.Attribute.GetCustomAttributes(element, true);
+ }
+ public static Attribute[] GetCustomAttributes(System.Reflection.Module element){
+ return System.Attribute.GetCustomAttributes(element, true);
+ }
+ public static Attribute[] GetCustomAttributes(System.Reflection.Assembly element, Type attributeType){
+ return System.Attribute.GetCustomAttributes(element, attributeType, true);
+ }
+ public static Attribute[] GetCustomAttributes(System.Reflection.Module element, Type attributeType){
+ return System.Attribute.GetCustomAttributes(element, attributeType, true);
+ }
+ public static Attribute[] GetCustomAttributes(System.Reflection.ParameterInfo element, Type attributeType){
+ return System.Attribute.GetCustomAttributes(element, attributeType, true);
+ }
+ public static Attribute[] GetCustomAttributes(System.Reflection.MemberInfo element, Type attributeType)
+ {
+ return System.Attribute.GetCustomAttributes(element, attributeType, true);
+ }
+ public static Attribute[] GetCustomAttributes(System.Reflection.Assembly element, Type attributeType, bool inherit)
+ {
+ // element parameter is not allowed to be null
+ CheckParameters(element, attributeType);
+
+ // make a properly typed array to return containing the custom attributes
+ System.Attribute[] attributes = (System.Attribute[]) element.GetCustomAttributes(attributeType, inherit);
+
+ return attributes;
+ }
+ public static Attribute[] GetCustomAttributes(System.Reflection.ParameterInfo element, Type attributeType, bool inherit){
+ // element parameter is not allowed to be null
+ CheckParameters(element, attributeType);
+
+ // make a properly typed array to return containing the custom attributes
+ System.Attribute[] attributes = (System.Attribute[]) element.GetCustomAttributes(attributeType, inherit);
+
+ return attributes;
+ }
+ public static Attribute[] GetCustomAttributes(System.Reflection.Module element, Type attributeType, bool inherit){
+ // element parameter is not allowed to be null
+ CheckParameters(element, attributeType);
+
+ // make a properly typed array to return containing the custom attributes
+ System.Attribute[] attributes = (System.Attribute[]) element.GetCustomAttributes(attributeType, inherit);
+
+ return attributes;
+ }
+ public static Attribute[] GetCustomAttributes(System.Reflection.MemberInfo element, Type attributeType, bool inherit)
+ {
+ // element parameter is not allowed to be null
+ CheckParameters(element, attributeType);
+
+ // make a properly typed array to return containing the custom attributes
+ System.Attribute[] attributes = (System.Attribute[]) element.GetCustomAttributes(attributeType, inherit);
+
+ return attributes;
+ }
+ public static Attribute[] GetCustomAttributes(System.Reflection.Module element, bool inherit)
+ {
+ // element parameter is not allowed to be null
+ CheckParameters(element, typeof(System.Attribute));
+
+ // make a properly typed array to return containing the custom attributes
+ System.Attribute[] attributes = (System.Attribute[]) element.GetCustomAttributes(inherit);
+
+ return attributes;
+ }
+ public static Attribute[] GetCustomAttributes(System.Reflection.Assembly element, bool inherit){
+ // element parameter is not allowed to be null
+ CheckParameters(element, typeof(System.Attribute));
+
+ // make a properly typed array to return containing the custom attributes
+ System.Attribute[] attributes = (System.Attribute[]) element.GetCustomAttributes(inherit);
+
+ return attributes;
+ }
+ public static Attribute[] GetCustomAttributes(System.Reflection.MemberInfo element, bool inherit){
+ // element parameter is not allowed to be null
+ CheckParameters(element, typeof(System.Attribute));
+
+ // make a properly typed array to return containing the custom attributes
+ System.Attribute[] attributes = (System.Attribute[]) element.GetCustomAttributes(inherit);
+
+ return attributes;
+ }
+ public static Attribute[] GetCustomAttributes(System.Reflection.ParameterInfo element, bool inherit){
+ // element parameter is not allowed to be null
+ CheckParameters(element, typeof(System.Attribute));
+
+ // make a properly typed array to return containing the custom attributes
+ System.Attribute[] attributes = (System.Attribute[]) element.GetCustomAttributes(inherit);
+
+ return attributes;
+ }
+
+ public override int GetHashCode(){
+ // TODO: Implement me
+ return 0;
+ }
+
+ public virtual bool IsDefaultAttribute(){
+ // Derived classes should override this default behaviour as appropriate
+ return false;
+ }
+
+ public static bool IsDefined(System.Reflection.Module element, Type attributeType){
+ return (System.Attribute.GetCustomAttributes(element, attributeType).Length > 0);
+ }
+ public static bool IsDefined(System.Reflection.ParameterInfo element, Type attributeType){
+ return (System.Attribute.GetCustomAttributes(element, attributeType).Length > 0);
+ }
+ public static bool IsDefined(System.Reflection.MemberInfo element, Type attributeType){
+ return (System.Attribute.GetCustomAttributes(element, attributeType).Length > 0);
+ }
+ public static bool IsDefined(System.Reflection.Assembly element, Type attributeType){
+ return (System.Attribute.GetCustomAttributes(element, attributeType).Length > 0);
+ }
+ public static bool IsDefined(System.Reflection.MemberInfo element, Type attributeType, bool inherit){
+ return (System.Attribute.GetCustomAttributes(element, attributeType, inherit).Length > 0);
+ }
+ public static bool IsDefined(System.Reflection.Assembly element, Type attributeType, bool inherit){
+ return (System.Attribute.GetCustomAttributes(element, attributeType, inherit).Length > 0);
+ }
+ public static bool IsDefined(System.Reflection.Module element, Type attributeType, bool inherit){
+ return (System.Attribute.GetCustomAttributes(element, attributeType, inherit).Length > 0);
+ }
+ public static bool IsDefined(System.Reflection.ParameterInfo element, Type attributeType, bool inherit){
+ return (System.Attribute.GetCustomAttributes(element, attributeType, inherit).Length > 0);
+ }
+
+ public virtual bool Match(object obj){
+ // default action is the same as Equals. Derived classes should override as appropriate
+ return this.Equals(obj);
+ }
+
+ }
+
+}
diff --git a/mcs/class/corlib/System/AttributeTargets.cs b/mcs/class/corlib/System/AttributeTargets.cs
new file mode 100644
index 00000000000..14ab48af65b
--- /dev/null
+++ b/mcs/class/corlib/System/AttributeTargets.cs
@@ -0,0 +1,33 @@
+//------------------------------------------------------------------------------
+//
+// System.AttributeTargets.cs
+//
+// Copyright (C) 2001 Michael Lambert, All Rights Reserved
+//
+// Author: Michael Lambert, michaellambert@email.com
+// Created: Thu 07/18/2001
+//
+//------------------------------------------------------------------------------
+
+namespace System
+{
+
+public enum AttributeTargets
+{
+ All,
+ Assembly,
+ Class,
+ Constructor,
+ Delegate,
+ Enum,
+ Event,
+ Field,
+ Interface,
+ Method,
+ Parameter,
+ Property,
+ ReturnValue,
+ Struct,
+}
+
+} // Namespace
diff --git a/mcs/class/corlib/System/Boolean.cs b/mcs/class/corlib/System/Boolean.cs
new file mode 100644
index 00000000000..c863f647288
--- /dev/null
+++ b/mcs/class/corlib/System/Boolean.cs
@@ -0,0 +1,177 @@
+//
+// System.Boolean.cs
+//
+// Author:
+// Derek Holden (dholden@draper.com)
+//
+// (C) Ximian, Inc. http://www.ximian.com
+//
+
+//
+// I guess this is the Boolean class. This was written word for word
+// off the Library specification for System.Boolean in the ECMA
+// TC39 TG2 and TG3 working documents.
+//
+// The XML style documentation isn't that elegant, but it seems to
+// be the standard way according to the poorly documented C#
+// Programmer's Reference section on XML Documentation.
+//
+// This header and the one above it can be formatted however, just trying
+// to keep it consistent w/ the existing mcs headers.
+//
+// Even though it's not in the ECMA docs, the .NET Framework Class Library
+// says this implements IConvertible, but if it does it has some other
+// member functions to implement.
+//
+
+namespace System {
+
+ /// <summary>
+ /// Represents the boolean values of logical true and false.
+ /// </summary>
+ // The .NET Framework SDK lists this as implementing IConvertible,
+ // though it's not done in the ECMA spec.
+ public struct Boolean : IComparable { //, IConvertible {
+
+ /// <value>
+ /// The String representation of Boolean False
+ /// </value>
+ public static readonly string FalseString;
+
+ /// <value>
+ /// The String representation of Boolean True
+ /// </value>
+ public static readonly string TrueString;
+
+ /// <value>
+ /// Internal bool value for for this instance
+ /// </value>
+ //
+ // HACK: we tag it as public, so the source will compile.
+ public bool value;
+
+ static Boolean ()
+ {
+ FalseString = "False";
+ TrueString = "True";
+ }
+
+ /// <summary>
+ /// Compares the current Boolean instance against another object.
+ /// </summary>
+ /// <remarks>
+ /// Throws an ArgumentException if <c>obj</c> isn't null or
+ /// a Boolean.
+ /// </remarks>
+ /// <param name="obj">
+ /// The object to compare against
+ /// </param>
+ /// <returns>
+ /// An int reflecting the sort order of this instance as
+ /// compared to <c>obj</c>
+ /// -1 if this instance is false and <c>obj</c> is true
+ /// 0 if this instance is equal to <c>obj</c>
+ /// 1 if this instance is true and <c>obj</c> is false,
+ /// or <c>obj</c> is null
+ /// </returns>
+ public int CompareTo (object obj)
+ {
+ if(obj != null && !(obj is System.Boolean))
+ throw new ArgumentException
+ ("Object is not a Boolean and is not a null reference");
+
+ // for case #3
+ if (obj == null || (value == true && (bool)obj == false))
+ return 1;
+
+ // for case #2, else it's #1
+ return (value == (bool)obj) ? 0 : -1;
+ }
+
+ /// <summary>
+ /// Determines whether this instance and another object represent the
+ /// same type and value.
+ /// </summary>
+ /// <param name="obj">
+ /// The object to check against
+ /// </param>
+ /// <returns>
+ /// true if this instnace and <c>obj</c> are same value,
+ /// otherwise false if it is not or null
+ /// </returns>
+ public override bool Equals (Object obj)
+ {
+ if (obj == null || !(obj is System.Boolean))
+ return false;
+
+ return ((bool)obj) == value;
+ }
+
+ /// <summary>
+ /// Generates a hashcode for this object.
+ /// </summary>
+ /// <returns>
+ /// An Int32 value holding the hash code
+ /// </returns>
+ public override int GetHashCode ()
+ {
+ // Guess there's not too many ways to hash a Boolean
+ return value ? 1 : 0;
+ }
+
+ /// <summary>
+ /// Returns a given string as a boolean value. The string must be
+ /// equivalent to either TrueString or FalseString, with leading and/or
+ /// trailing spaces, and is parsed case-insensitively.
+ /// </summary>
+ /// <remarks>
+ /// Throws an ArgumentNullException if <c>val</c> is null, or a
+ /// FormatException if <c>val</c> doesn't match <c>TrueString</c>
+ /// or <c>FalseString</c>
+ /// </remarks>
+ /// <param name="val">
+ /// The string value to parse
+ /// </param>
+ /// <returns>
+ /// true if <c>val</c> is equivalent to TrueString,
+ /// otherwise false
+ /// </returns>
+ public static bool Parse (string val)
+ {
+ if (val == null)
+ throw new ArgumentNullException ("Value is a null reference");
+
+ val = val.Trim ();
+
+ if (String.Compare (val, TrueString, true) == 0)
+ return true;
+
+ if (String.Compare (val, FalseString, true) == 0)
+ return false;
+
+ throw new FormatException
+ ("Value is not equivalent to either TrueString or FalseString");
+ }
+
+ /// <summary>
+ /// Returns a string representation of this Boolean object.
+ /// </summary>
+ /// <returns>
+ /// <c>FalseString</c> if the instance value is false, otherwise
+ /// <c>TrueString</c>
+ /// </returns>
+ public override string ToString ()
+ {
+ return value ? TrueString : FalseString;
+ }
+
+ // =========== IConvertible Methods =========== //
+
+ public TypeCode GetTypeCode ()
+ {
+ return TypeCode.Boolean;
+ }
+
+ } // System.Boolean
+
+} // Namespace System
diff --git a/mcs/class/corlib/System/Byte.cs b/mcs/class/corlib/System/Byte.cs
new file mode 100644
index 00000000000..8eb351c55ca
--- /dev/null
+++ b/mcs/class/corlib/System/Byte.cs
@@ -0,0 +1,92 @@
+//
+// System.Byte.cs
+//
+// Author:
+// Miguel de Icaza (miguel@ximian.com)
+//
+// (C) Ximian, Inc. http://www.ximian.com
+//
+
+using System.Globalization;
+
+namespace System {
+
+ public struct Byte : IComparable, IFormattable { //, IConvertible {
+ public const byte MinValue = 0;
+ public const byte MaxValue = 255;
+
+ // VES needs to know about value. public is workaround
+ // so source will compile
+ public byte value;
+
+ public int CompareTo (object v)
+ {
+ if (!(v is System.Byte))
+ throw new ArgumentException ("Value is not a System.Byte");
+
+ return value - ((byte) v);
+ }
+
+ public override bool Equals (object o)
+ {
+ if (!(o is System.Byte))
+ return false;
+
+ return ((byte) o) == value;
+ }
+
+ public override int GetHashCode ()
+ {
+ return value;
+ }
+
+ public static byte Parse (string s)
+ {
+ return Parse (s, NumberStyles.Integer, null);
+ }
+
+ public static byte Parse (string s, IFormatProvider fp)
+ {
+ return Parse (s, NumberStyles.Integer, fp);
+ }
+
+ public static byte Parse (string s, NumberStyles style)
+ {
+ return Parse (s, style, null);
+ }
+
+ public static byte Parse (string s, NumberStyles style, IFormatProvider fp)
+ {
+ // TODO: Implement me
+ return 0;
+ }
+
+ public override string ToString ()
+ {
+ return ToString ("G", null);
+ }
+
+ public string ToString (IFormatProvider fp)
+ {
+ return ToString ("G", fp);
+ }
+
+ public string ToString (string format)
+ {
+ return ToString (format, null);
+ }
+
+ public string ToString (string format, IFormatProvider fp)
+ {
+ // TODO: Implement me.
+ return "";
+ }
+
+ // =========== IConvertible Methods =========== //
+
+ public TypeCode GetTypeCode ()
+ {
+ return TypeCode.Byte;
+ }
+ }
+}
diff --git a/mcs/class/corlib/System/CLSCompliantAttribute.cs b/mcs/class/corlib/System/CLSCompliantAttribute.cs
new file mode 100755
index 00000000000..937ab2ac5e8
--- /dev/null
+++ b/mcs/class/corlib/System/CLSCompliantAttribute.cs
@@ -0,0 +1,33 @@
+//
+// System.CLSCompliantAttribute.cs
+//
+// Author:
+// Miguel de Icaza (miguel@ximian.com)
+//
+// (C) Ximian, Inc. http://www.ximian.com
+//
+
+namespace System {
+
+ /// <summary>
+ /// Used to indicate if an element of a program is CLS compliant.
+ /// </summary>
+ ///
+ /// <remarks>
+ /// </remarks>
+ public class CLSCompliant : Attribute {
+
+ bool is_compliant;
+
+ public CLSCompliant (bool is_compliant)
+ {
+ this.is_compliant = is_compliant;
+ }
+
+ public bool IsCompliant {
+ get {
+ return is_compliant;
+ }
+ }
+ }
+}
diff --git a/mcs/class/corlib/System/ChangeLog b/mcs/class/corlib/System/ChangeLog
new file mode 100644
index 00000000000..5af59efc01d
--- /dev/null
+++ b/mcs/class/corlib/System/ChangeLog
@@ -0,0 +1,350 @@
+2001-08-20 Dietmar Maurer <dietmar@ximian.com>
+
+ * Attribute.cs: uncomment some code to make it compile again
+
+ * mono.src: removed duplicated Attribute.cs
+
+2001-08-16 Nick Drochak <ndrochak@gol.com>
+
+ * Attribute.cs: implemented all methods except GetHashCode()
+
+ * common.src: added Attribute.cs so it would compile in
+
+2001-08-10 Dietmar Maurer <dietmar@ximian.com>
+
+ * Object.cs: changed MemberWiseClone to MemberwiseClone, and
+ marked it as InternalCall
+
+
+ * common.src: removed UriFormatException.cs because the file is
+ not there.
+
+ * RuntimeTypeHandle.cs: replaced IntrPtr with IntPtr
+ * Char.cs: replaced byte with char
+
+ * Array.cs: make it work with the mono interpreter
+
+2001-08-06 Miguel de Icaza <miguel@ximian.com>
+
+ * Version.cs: Make the class sealed
+
+2001-08-08 Bob Smith <bob@thestuff.net>
+
+ * Random.cs: Many compile fixes.
+ * Random.cs: I read a bad spec. Class updated to match real spec.
+
+2001-08-06 Miguel de Icaza <miguel@ximian.com>
+
+ * IntPtr.cs: Added and Completed implementation.
+
+ * Uri.cs: Add a note.
+
+2001-08-06 Bob Smith <bob@thestuff.net>
+
+ * Random.cs: Compile fix. Needs more testing.
+
+2001-08-06 Garrett Rooney <rooneg@electricjellyfish.net>
+
+ * Uri.cs: Initial Implementation. Parsing needs to be fixed to take
+ into account IPv6 addresses, url encoding needs to be implemented, and
+ various minor methods need to be written, but this is a decent start.
+
+2001-08-06 Dietmar Maurer <dietmar@ximian.com>
+
+ * common.src: added Object.cs
+
+ * mono.src: added ValueType.cs
+
+2001-08-02 Dietmar Maurer <dietmar@ximian.com>
+
+ * Math.cs: replaced libc with libm
+
+2001-08-02 Bob Smith <bob@thestuff.net>
+
+ * Random.cs: Implemented. Needs testing.
+
+2001-08-02 Miguel de Icaza <miguel@ximian.com>
+
+ * IServiceProvider.cs, EventHandler.cs: New files.
+
+2001-08-02 Marcel Narings <marcel@narings.nl>
+
+ * DateTime.cs: Cleaned up a bit. Added the Add* family members.
+ Added exceptions. Added IConvertible. Still needs some platform
+ dependend stuff, the Parse and ToString members
+
+2001-08-01 Dietmar Maurer <dietmar@ximian.com>
+
+ * Type.cs (GetTypeFromHandle): added placeholder
+
+2001-07-24 Derek Holden <dholden@draper.com>
+
+ * Boolean.cs: Formatted to code style standard. Added GetTypeCode
+ which is really an IConvertible defined method.
+
+ * Byte.cs: Added a missing Parse method. Put in Parse and ToString
+ behavior, still need to do the main Parse and ToString.
+
+ * Char.cs: Added a bunch of missing ECMA methods. Commented a
+ specification discrepency. Still didn't any unicode stuff, though
+ every IsFoo(char c) method has an IsFoo(string, index)
+ counterpart, added wrappers for those.
+
+ * Convert.cs: Fixed NaN/Inf checking and double/float
+ rounding. Added ToType for IConvertible classes
+
+ * Double.cs: Fixed ECMA min and max values. Added IsInfinity /
+ IsNaN methods. Changed Inf/NaN internals.
+
+ * IConvertible.cs: Added comments for using
+ Convert.ToType. Changed return values to draft base values.
+
+ * Int16.cs: Added a missing Parse statement. Put in behavior for
+ overloaded ToString and Parse methods.
+
+ * Int32.cs: Added a missing Parse statement. Put in behavior for
+ overloaded ToString and Parse methods.
+
+ * Int64.cs: Added a missing Parse statement. Put in behavior for
+ overloaded ToString and Parse methods.
+
+ * Single.cs: Put in ECMA epsilon value. Added IsInfinity / IsNaN
+ methods. Changed Inf/NaN internals.
+
+ * SByte.cs: Added a missing Parse method. Put in Parse and
+ ToString behavior, still need to do the main Parse and ToString.
+
+ * UInt16.cs: Added a missing Parse statement. Put in behavior for
+ overloaded ToString and Parse methods.
+
+ * UInt32.cs: Added a missing Parse statement. Put in behavior for
+ overloaded ToString and Parse methods.
+
+ * UInt64.cs: Added a missing Parse statement. Put in behavior for
+ overloaded ToString and Parse methods.
+
+2001-07-20 Miguel de Icaza <miguel@ximian.com>
+
+ * MulticastDelegate.cs: New File.
+
+ * Delegate.cs: New file.
+
+ * Enum.cs: New file.
+
+ * Attribute.cs: New file.
+
+ * Type.cs: New file.
+
+ * ParamArrayAttribute.cs: New file.
+
+ * RuntimeTypeHandle.cs: New file.
+
+ * MulticastDelegate.cs: Added.
+
+ * DateTime.cs: Added
+
+ * Delegate.cs: Added
+
+2001-07-18 Michael Lambert <michaellambert@email.com>
+
+ * AttributeTargets.cs: Add.
+
+2001-07-19 Jeffrey Stedfast <fejj@ximian.com>
+
+ * Char.cs: Made ToUpper and ToLower public methods.
+
+ * String.cs: Lots and lots of compile fixes - just need to write
+ DateTime.cs and this should build completely now.
+
+2001-07-19 Bob Smith (bob@thestuff.net)
+
+ * Math.cs: Implemented.
+
+2001-07-19 Miguel de Icaza <miguel@ximian.com>
+
+ * String.cs: Removed tolower and toupper.
+
+ * Char.cs: Moved ToLower and ToUpper from string to here.
+
+ * Convert.cs ToByte (float value), ToByte (double value) Use IsNan
+ instead of comparing the value to Nan.
+
+2001-07-19 Duco Fijma (duco@lorentz.xs4all.nl)
+
+ * TimeSpan.cs: New implementation.
+
+2001-07-18 Scott Sanders <scott@stonecobra.com>
+
+ * UriFormatExcpetion.cs: Add - 85% complete
+
+2001-07-17 Jeffrey Stedfast <fejj@ximian.com>
+
+ * String.cs (IndexOf): Slight optimization that allows skipping
+ over a few chars here and there. This isn't as good as using my
+ Boyer-Moore implementation, however, Boyer-Moore is only really
+ good for long strings (I plan on making the code decide which
+ string search algorithm it should use on-the-fly at some point).
+ (LastIndexOf): Fix to work correctly.
+ (BoyerMoore): Took out some unneeded code and fixed an edge-case.
+
+2001-07-16 Michael Lambert <michaellambert@email.com>
+
+ * EventArgs.cs: Add.
+
+2001-07-16 Miguel de Icaza <miguel@ximian.com>
+
+ * Version.cs: Remove my buggy comment.
+
+2001-07-15 Sean MacIsaac <macisaac@ximian.com>
+
+ * String.cs: Spelling error of IComparable, object's
+ MemberwiseClone cannot be overridden. Made indexer valid for now,
+ but not sure what to do about this in the long run. Seems to be a
+ couple bugs in csc.exe having to do with multiple pointer defs in
+ the same statement, and returning subclasses of a class in the
+ return type of an interface function implementation. Also moved
+ operators inside of class definition.
+
+2001-07-14 Jeffrey Stedfast <fejj@ximian.com>
+
+ * String.cs: A tom of compile fixes, although we still don't compile.
+
+ * IConvertible.cs: The To*Int64() methods return *Int64's, not
+ *Int32's. Also, it's ToDateTime() not ToDateType().
+
+2001-07-14 Jeffrey Stedfast <fejj@ximian.com>
+
+ * String.cs: Apparently I needed to at least write stubs for the
+ IConvertible interfaces. *sigh*
+
+2001-07-14 Jeffrey Stedfast <fejj@ximian.com>
+
+ * String.cs: Many logic/other fixes and better usage of the
+ features of c#
+ (tolower): New convenience method to help condense code.
+ (toupper): Another new helper method.
+ (Compare): Use the new helper methods.
+ (ToLower): use tolower().
+ (ToUpper): use toupper().
+ (LastIndexOfAny): Implemented.
+ (BoyerMoore): New private helper method that implements a modified
+ version of the Boyer-Moore search algorithm. Noothing uses it yet
+ as I'm not 100% sure it even works properly with unicode strings
+ not to mention it uses a huge lookup-table :-)
+ (Split): Implemented.
+
+2001-07-13 Jeffrey Stedfast <fejj@ximian.com>
+
+ * TODO: Added things that need to be finished in System.String
+
+ * String.cs: New source file implementing the System.String class
+
+2001-07-12 Sean MacIsaac <macisaac@ximian.com>
+
+ * TypeCode.cs: UInt64 was UInt63.
+
+ * Object.cs: Fixed a numer of compiler errors.
+
+ * Array.cs: Fixed some compiler errors.
+
+ * IComparable.cs: Fixed some compiler errors.
+
+ * ICloneable.cs: Fixed some compiler errors.
+
+ * IConvertible.cs: Fixed some compiler errors.
+
+ * IFormattable.cs: Fixed a compiler error.
+
+ * IFormatProvider.cs: Fixed a compiler error.
+
+ * IDisposable.cs: Fixed a compiler error.
+
+ * IFormatProvider.cs: Added public accesability type to
+ IFormatProvider.
+
+ * Exception.cs: Added a using statement to remove compile time
+ error.
+
+ * ApplicationException.cs: Removed a ; that was causing a compiler
+ error.
+
+ * Int16.cs: Fixed some compiler errors.
+
+ * Int32.cs: Fixed some compiler errors.
+
+ * Int64.cs: Fixed some compiler errors.
+
+ * SystemException.cs: Fixed a compiler error.
+
+ * UInt16.cs: Fixed some compiler errors.
+
+ * UInt32.cs: Fixed some compiler errors.
+
+ * UInt64.cs: Fixed some compiler errors.
+
+ * Void.cs: Fixed a compiler error.
+
+2001-07-12 Joe Shaw <joe@ximian.com>
+
+ * Array.cs: Fix backwards parameters to Array.SetValue()
+ throughout.
+ (BinarySearch): Fix backward logic surrounding whether to call
+ value.CompareTo or comparer.Compare.
+ (LastIndexOf): Stop being stupid. I am so not used to strongly
+ bounded arrays...
+ (Sort): Implement a quicksort.
+
+2001-07-11 Joe Shaw <joe@ximian.com>
+
+ * Array.cs: Change all instances of trying to access an array with
+ the index operator to calls to GetValue and SetValue, and add
+ InternalGetValue and InternalSetValue which are internal calls
+ into the runtime. Ew.
+
+2001-07-10 Joe Shaw <joe@ximian.com>
+
+ * Array.cs: Implemented everything but Sort().
+
+2001-07-09 Jeffrey Stedfast <fejj@ximian.com>
+
+ * Object.cs (Object::Equals): Object variable name is `o'.
+
+2001-07-06 Joe Shaw <joe@ximian.com>
+
+ * Int16.cs, Int32.cs, Int64.cs, UInt16.cs, UInt32.cs, UInt64.cs:
+ Implement the IComparable and IFormattable interfaces. Fix a typo
+ (publig -> public)
+
+ * ApplicationException.cs, ArgumentException.cs,
+ ArgumentNullException.cs, ArgumentOutOfRangeException.cs,
+ ArtithmeticException.cs, ArrayTypeMismatchException.cs,
+ DivideByZeroException.cs, DuplicateWaitObjectException.cs,
+ ExecutionEngineException.cs, FormatException.cs,
+ IndexOutOfRangeException.cs, InvalidCastException.cs,
+ InvalidOperationException.cs, InvalidProgramException.cs,
+ MulticateNotSupportedException.cs, NotFiniteNumberException.cs,
+ NotSupportedException.cs, NullReferenceException.cs,
+ OutOfMemoryException.cs, OverflowException.cs, RankException.cs,
+ StackOverflowException.cs, SystemException.cs,
+ TypeInitializationException.cs: Added all of the exceptions
+ specified by the language spec. Mmmm... bloat.
+
+2001-07-06 Miguel de Icaza <miguel@ximian.com>
+
+ * Int64.cs, Int32.cs: Put. Parsing and ToString missing. Should
+ do a generic routine all of these guys use.
+
+ * Int16.cs: identified missing methods.
+
+ * UInt16.cs, UInt32.cs, UInt64.cs: Add.
+
+2001-06-26 Miguel de Icaza <miguel@ximian.com>
+
+ * TypeCode.cs: Implement
+
+ * Void.cs: Implement.
+
+ * TODO: Add file to keep track of pending tasks.
+
+ * Object.cs, ValueType.cs: Implement.
+
diff --git a/mcs/class/corlib/System/Char.cs b/mcs/class/corlib/System/Char.cs
new file mode 100644
index 00000000000..ee259dae13d
--- /dev/null
+++ b/mcs/class/corlib/System/Char.cs
@@ -0,0 +1,339 @@
+//
+// System.Char.cs
+//
+// Author:
+// Miguel de Icaza (miguel@ximian.com)
+//
+// (C) Ximian, Inc. http://www.ximian.com
+//
+
+// Note about the ToString()'s. ECMA says there's only a ToString() method,
+// BUT it is just a wrapper for ToString(null). However there is no other ToString
+// in the docs. Turning to the NET framework sdk reveals that there is a
+// ToString(formatprovider) method, as well as a 'static ToString (char c)' method,
+// which appears to just be a Convert.ToString(char c) type method. ECMA also
+// doesn't list this class as implementing IFormattable.
+
+using System.Globalization;
+
+namespace System {
+
+ public struct Char : IComparable { //, IFormattable, IConvertible {
+ public const char MaxValue = (char) 0xffff;
+ public const char MinValue = (char) 0;
+
+ // VES needs to know about value. public is workaround
+ // so source will compile
+ public char value;
+
+ public int CompareTo (object v)
+ {
+ if (!(v is System.Char))
+ throw new ArgumentException ("Value is not a System.Char");
+
+ return value - ((char) v);
+ }
+
+ public override bool Equals (object o)
+ {
+ if (!(o is System.Char))
+ return false;
+
+ return ((Char) o) == value;
+ }
+
+ public override int GetHashCode ()
+ {
+ return value;
+ }
+
+ public static double GetNumericValue (char c)
+ {
+ if ((c >= 48) && (c <= 57))
+ return (double) (c - '0');
+ return -1;
+ }
+
+ public static double GetNumericValue (string str, int index)
+ {
+ if (str == null)
+ throw new ArgumentNullException ("Str is a null reference");
+
+ if (index < 0 || index >= str.Length)
+ throw new ArgumentOutOfRangeException
+ ("The value of index is less than zero, or greater than or equal to the length of str");
+
+ return GetNumericValue (str[index]);
+ }
+
+ public static UnicodeCategory GetUnicodeCategory (char c)
+ {
+ // TODO: Implement me
+ return UnicodeCategory.OtherSymbol;
+ }
+
+ public static UnicodeCategory GetUnicodeCategory (string str, int index) {
+ if (str == null)
+ throw new ArgumentNullException ("Str is a null reference");
+
+ if (index < 0 || index >= str.Length)
+ throw new ArgumentOutOfRangeException
+ ("The value of index is less than zero, or greater than or equal to the length of str");
+
+ return GetUnicodeCategory (str[index]);
+ }
+
+ public static bool IsControl (char c)
+ {
+ // TODO: Make me Unicode aware
+ return ((c > 1) && (c < 32));
+ }
+
+ public static bool IsControl (string str, int index)
+ {
+ if (str == null)
+ throw new ArgumentNullException ("Str is a null reference");
+
+ if (index < 0 || index >= str.Length)
+ throw new ArgumentOutOfRangeException
+ ("The value of index is less than zero, or greater than or equal to the length of str");
+
+ return IsControl (str[index]);
+ }
+
+ public static bool IsDigit (char c)
+ {
+ return ((c >= '0') && (c <= '9'));
+ }
+
+ public static bool IsDigit (string str, int index)
+ {
+ if (str == null)
+ throw new ArgumentNullException ("Str is a null reference");
+
+ if (index < 0 || index >= str.Length)
+ throw new ArgumentOutOfRangeException
+ ("The value of index is less than zero, or greater than or equal to the length of str");
+
+ return IsDigit (str[index]);
+ }
+
+ public static bool IsLetter (char c)
+ {
+ // TODO: Make me Unicode aware
+ return ((c >= 65) && (c <= 126));
+ }
+
+ public static bool IsLetter (string str, int index)
+ {
+ if (str == null)
+ throw new ArgumentNullException ("Str is a null reference");
+
+ if (index < 0 || index >= str.Length)
+ throw new ArgumentOutOfRangeException
+ ("The value of index is less than zero, or greater than or equal to the length of str");
+
+ return IsLetter (str[index]);
+ }
+
+ public static bool IsLetterOrDigit (char c)
+ {
+ // TODO: Implement me
+ return false;
+ }
+
+ public static bool IsLetterOrDigit (string str, int index)
+ {
+ if (str == null)
+ throw new ArgumentNullException ("Str is a null reference");
+
+ if (index < 0 || index >= str.Length)
+ throw new ArgumentOutOfRangeException
+ ("The value of index is less than zero, or greater than or equal to the length of str");
+
+ return IsLetterOrDigit (str[index]);
+ }
+
+ public static bool IsLower (char c)
+ {
+ // TODO: Implement me
+ return false;
+ }
+
+ public static bool IsLower (string str, int index)
+ {
+ if (str == null)
+ throw new ArgumentNullException ("Str is a null reference");
+
+ if (index < 0 || index >= str.Length)
+ throw new ArgumentOutOfRangeException
+ ("The value of index is less than zero, or greater than or equal to the length of str");
+
+ return IsLower (str[index]);
+ }
+
+ public static bool IsNumber (char c)
+ {
+ // TODO: Implement me
+ return false;
+ }
+
+ public static bool IsNumber (string str, int index)
+ {
+ if (str == null)
+ throw new ArgumentNullException ("Str is a null reference");
+
+ if (index < 0 || index >= str.Length)
+ throw new ArgumentOutOfRangeException
+ ("The value of index is less than zero, or greater than or equal to the length of str");
+
+ return IsNumber (str[index]);
+ }
+
+ public static bool IsPunctuation (char c)
+ {
+ // TODO: Implement me
+ return false;
+ }
+
+ public static bool IsPunctuation (string str, int index)
+ {
+ if (str == null)
+ throw new ArgumentNullException ("Str is a null reference");
+
+ if (index < 0 || index >= str.Length)
+ throw new ArgumentOutOfRangeException
+ ("The value of index is less than zero, or greater than or equal to the length of str");
+
+ return IsPunctuation (str[index]);
+ }
+
+ public static bool IsSeparator (char c)
+ {
+ // TODO: Implement me
+ return false;
+ }
+
+ public static bool IsSeparator (string str, int index)
+ {
+ if (str == null)
+ throw new ArgumentNullException ("Str is a null reference");
+
+ if (index < 0 || index >= str.Length)
+ throw new ArgumentOutOfRangeException
+ ("The value of index is less than zero, or greater than or equal to the length of str");
+
+ return IsSeparator (str[index]);
+ }
+
+ public static bool IsSurrogate (char c)
+ {
+ // TODO: Implement me
+ return false;
+ }
+
+ public static bool IsSurrogate (string str, int index)
+ {
+ if (str == null)
+ throw new ArgumentNullException ("Str is a null reference");
+
+ if (index < 0 || index >= str.Length)
+ throw new ArgumentOutOfRangeException
+ ("The value of index is less than zero, or greater than or equal to the length of str");
+
+ return IsSurrogate (str[index]);
+ }
+
+ public static bool IsSymbol (char c)
+ {
+ // TODO: Implement me
+ return false;
+ }
+
+ public static bool IsSymbol (string str, int index)
+ {
+ if (str == null)
+ throw new ArgumentNullException ("Str is a null reference");
+
+ if (index < 0 || index >= str.Length)
+ throw new ArgumentOutOfRangeException
+ ("The value of index is less than zero, or greater than or equal to the length of str");
+
+ return IsSymbol (str[index]);
+ }
+
+ public static bool IsUpper (char c)
+ {
+ // TODO: Implement me
+ return false;
+ }
+
+ public static bool IsUpper (string str, int index)
+ {
+ if (str == null)
+ throw new ArgumentNullException ("Str is a null reference");
+
+ if (index < 0 || index >= str.Length)
+ throw new ArgumentOutOfRangeException
+ ("The value of index is less than zero, or greater than or equal to the length of str");
+
+ return IsUpper (str[index]);
+ }
+
+ public static bool IsWhiteSpace (char c)
+ {
+ // TODO: Implement me
+ return false;
+ }
+
+ public static bool IsWhiteSpace (string str, int index)
+ {
+ if (str == null)
+ throw new ArgumentNullException ("Str is a null reference");
+
+ if (index < 0 || index >= str.Length)
+ throw new ArgumentOutOfRangeException
+ ("The value of index is less than zero, or greater than or equal to the length of str");
+
+ return IsWhiteSpace (str[index]);
+ }
+
+ public static char Parse (string str)
+ {
+ // TODO: Implement me
+ return (char) 0;
+ }
+
+ public static char ToLower (char c)
+ {
+ // TODO: make me unicode aware
+ return (c >= 'A' && c <= 'Z') ? (char) (c + 33) : c;
+ }
+
+ public static char ToUpper (char c)
+ {
+ // TODO: make me unicode aware
+ return (char) ((c >= 'a' && c <= 'z') ? c - 33 : c);
+ }
+
+ public override string ToString ()
+ {
+ // LAMESPEC: ECMA draft lists this as returning ToString (null),
+ // However it doesn't list another ToString() method.
+ return ToString (null);
+ }
+
+ public string ToString (IFormatProvider fp)
+ {
+ // LAMESPEC: ECMA draft doesn't say Char implements IFormattable
+ return "";
+ }
+
+ // =========== IConvertible Methods =========== //
+
+ public TypeCode GetTypeCode ()
+ {
+ return TypeCode.Char;
+ }
+ }
+}
diff --git a/mcs/class/corlib/System/ContextStaticAttribute.cs b/mcs/class/corlib/System/ContextStaticAttribute.cs
new file mode 100755
index 00000000000..5cde02b2bef
--- /dev/null
+++ b/mcs/class/corlib/System/ContextStaticAttribute.cs
@@ -0,0 +1,24 @@
+//
+// System.ContextStatic.cs
+//
+// Author:
+// Miguel de Icaza (miguel@ximian.com)
+//
+// (C) Ximian, Inc. http://www.ximian.com
+//
+
+namespace System {
+
+ /// <summary>
+ /// The ContextStatic attribute is used to flag fields as being unique
+ /// </summary>
+ ///
+ /// <remarks>
+ ///
+ /// </remarks>
+ public class ContextStatic : Attribute {
+
+ // No methods.
+
+ }
+}
diff --git a/mcs/class/corlib/System/Convert.cs b/mcs/class/corlib/System/Convert.cs
new file mode 100644
index 00000000000..ddf1831c5bd
--- /dev/null
+++ b/mcs/class/corlib/System/Convert.cs
@@ -0,0 +1,1630 @@
+//
+// System.Convert.cs
+//
+// Author:
+// Derek Holden (dholden@draper.com)
+//
+// (C) Ximian, Inc. http://www.ximian.com
+//
+
+//
+// System.Convert class. This was written word for word off the
+// Library specification for System.Convert in the ECMA TC39 TG2
+// and TG3 working documents. The first page of which has a table
+// for all legal conversion scenerios.
+//
+// This header and the one above it can be formatted however, just trying
+// to keep it consistent w/ the existing mcs headers.
+//
+// This Convert class could be written another way, with each type
+// implementing IConvertible and defining their own conversion functions,
+// and this class just calling the type's implementation. Or, they can
+// be defined here and the implementing type can use these functions when
+// defining their IConvertible interface. Byte's ToBoolean() calls
+// Convert.ToBoolean(byte), or Convert.ToBoolean(byte) calls
+// byte.ToBoolean(). The first case is what is done here.
+//
+// See http://lists.ximian.com/archives/public/mono-list/2001-July/000525.html
+//
+// There are also conversion functions that are not defined in
+// the ECMA draft, such as there is no bool ToBoolean(DateTime value),
+// and placing that somewhere won't compile w/ this Convert since the
+// function doesn't exist. However calling that when using Microsoft's
+// System.Convert doesn't produce any compiler errors, it just throws
+// an InvalidCastException at runtime.
+//
+// Whenever a decimal, double, or single is converted to an integer
+// based type, it is even rounded. This uses Math.Round which only
+// has Round(decimal) and Round(double), so in the Convert from
+// single cases the value is passed to Math as a double. This
+// may not be completely necessary.
+//
+// The .NET Framework SDK lists DBNull as a member of this class
+// as 'public static readonly object DBNull;'.
+//
+// It should also be decided if all the cast return values should be
+// returned as unchecked or not.
+//
+// All the XML function comments were auto generated which is why they
+// sound someone redundant.
+//
+// TYPE | BOOL BYTE CHAR DT DEC DBL I16 I32 I64 SBYT SNGL STR UI16 UI32 UI64
+// -----+--------------------------------------------------------------------
+// BOOL | X X X X X X X X X X X X X
+// BYTE | X X X X X X X X X X X X X X
+// CHAR | X X X X X X X X X X
+// DT | X X
+// DEC | X X X X X X X X X X X X X
+// DBL | X X X X X X X X X X X X X
+// I16 | X X X X X X X X X X X X X X
+// I32 | X X X X X X X X X X X X X X
+// I64 | X X X X X X X X X X X X X X
+// SBYT | X X X X X X X X X X X X X X
+// SNGL | X X X X X X X X X X X X X
+// STR | X X X X X X X X X X X X X X X
+// UI16 | X X X X X X X X X X X X X X
+// UI32 | X X X X X X X X X X X X X X
+// UI64 | X X X X X X X X X X X X X X
+//
+
+namespace System {
+
+ public sealed class Convert {
+
+ // ========== Boolean Conversions ========== //
+
+ public static bool ToBoolean (bool value)
+ {
+ return value;
+ }
+
+ public static bool ToBoolean (byte value)
+ {
+ return (value != 0);
+ }
+
+ public static bool ToBoolean (decimal value)
+ {
+ return (value != 0M);
+ }
+
+ public static bool ToBoolean (double value)
+ {
+ return (value != 0);
+ }
+
+ public static bool ToBoolean (float value)
+ {
+ return (value != 0f);
+ }
+
+ public static bool ToBoolean (int value)
+ {
+ return (value != 0);
+ }
+
+ public static bool ToBoolean (long value)
+ {
+ return (value != 0);
+ }
+
+ public static bool ToBoolean (sbyte value)
+ {
+ return (value != 0);
+ }
+
+ public static bool ToBoolean (short value)
+ {
+ return (value != 0);
+ }
+
+ public static bool ToBoolean (string value)
+ {
+ return Boolean.Parse (value);
+ }
+
+ public static bool ToBoolean (uint value)
+ {
+ return (value != 0);
+ }
+
+ public static bool ToBoolean (ulong value)
+ {
+ return (value != 0);
+ }
+
+ public static bool ToBoolean (ushort value)
+ {
+ return (value != 0);
+ }
+
+ // ========== Byte Conversions ========== //
+
+ public static byte ToByte (bool value)
+ {
+ return (byte)(value ? 1 : 0);
+ }
+
+ public static byte ToByte (byte value)
+ {
+ return value;
+ }
+
+ public static byte ToByte (char value)
+ {
+ if (value > Byte.MaxValue)
+ throw new OverflowException
+ ("Value is greater than Byte.MaxValue");
+
+ return (byte)value;
+ }
+
+ public static byte ToByte (decimal value)
+ {
+ if (value > Byte.MaxValue || value < Byte.MinValue)
+ throw new OverflowException
+ ("Value is greater than Byte.MaxValue or less than Byte.MinValue");
+
+ // Returned Even-Rounded
+ return (byte)(Math.Round (value));
+ }
+
+ public static byte ToByte (double value)
+ {
+ if (value > Byte.MaxValue || value < Byte.MinValue)
+ throw new OverflowException
+ ("Value is greater than Byte.MaxValue or less than Byte.MinValue");
+
+ // This and the float version of ToByte are the only ones
+ // the spec listed as checking for .NaN and Infinity overflow
+ if (Double.IsNaN(value) || Double.IsInfinity(value))
+ throw new OverflowException
+ ("Value is equal to Double.NaN, Double.PositiveInfinity, or Double.NegativeInfinity");
+
+ // Returned Even-Rounded
+ return (byte)(Math.Round (value));
+ }
+
+ public static byte ToByte (float value)
+ {
+ if (value > Byte.MaxValue || value < Byte.MinValue)
+ throw new OverflowException
+ ("Value is greater than Byte.MaxValue or less than Byte.Minalue");
+
+ // This and the double version of ToByte are the only ones
+ // the spec listed as checking for .NaN and Infinity overflow
+ if (Single.IsNaN(value) || Single.IsInfinity(value))
+ throw new OverflowException
+ ("Value is equal to Single.NaN, Single.PositiveInfinity, or Single.NegativeInfinity");
+
+ // Returned Even-Rounded, pass it as a double, could have this
+ // method just call Convert.ToByte ( (double)value)
+ return (byte)(Math.Round ( (double)value));
+ }
+
+ public static byte ToByte (int value)
+ {
+ if (value > Byte.MaxValue || value < Byte.MinValue)
+ throw new OverflowException
+ ("Value is greater than Byte.MaxValue or less than Byte.MinValue");
+
+ return (byte)value;
+ }
+
+ public static byte ToByte (long value)
+ {
+ if (value > Byte.MaxValue || value < Byte.MinValue)
+ throw new OverflowException
+ ("Value is greater than Byte.MaxValue or less than Byte.MinValue");
+
+ return (byte)value;
+ }
+
+ public static byte ToByte (sbyte value)
+ {
+ if (value < Byte.MinValue)
+ throw new OverflowException
+ ("Value is less than Byte.MinValue");
+
+ return (byte)value;
+ }
+
+ public static byte ToByte (short value)
+ {
+ if (value > Byte.MaxValue || value < Byte.MinValue)
+ throw new OverflowException
+ ("Value is greater than Byte.MaxValue or less than Byte.MinValue");
+
+ return (byte)value;
+ }
+
+ public static byte ToByte (string value)
+ {
+ return Byte.Parse (value);
+ }
+
+ public static byte ToByte (string value, IFormatProvider provider)
+ {
+ return Byte.Parse (value, provider);
+ }
+
+ public static byte ToByte (uint value)
+ {
+ if (value > Byte.MaxValue)
+ throw new OverflowException
+ ("Value is greater than Byte.MaxValue");
+
+ return (byte)value;
+ }
+
+ public static byte ToByte (ulong value)
+ {
+ if (value > Byte.MaxValue)
+ throw new OverflowException
+ ("Value is greater than Byte.MaxValue");
+
+ return (byte)value;
+ }
+
+ public static byte ToByte (ushort value)
+ {
+ if (value > Byte.MaxValue)
+ throw new OverflowException
+ ("Value is greater than Byte.MaxValue");
+
+ return (byte)value;
+ }
+
+ // ========== Char Conversions ========== //
+
+ public static char ToChar (byte value)
+ {
+ return (char)value;
+ }
+
+ public static char ToChar (char value)
+ {
+ return value;
+ }
+
+ public static char ToChar (int value)
+ {
+ if (value > Char.MaxValue || value < Char.MinValue)
+ throw new OverflowException
+ ("Value is greater than Char.MaxValue or less than Char.MinValue");
+
+ return (char)value;
+ }
+
+ public static char ToChar (long value)
+ {
+ if (value > Char.MaxValue || value < Char.MinValue)
+ throw new OverflowException
+ ("Value is greater than Char.MaxValue or less than Char.MinValue");
+
+ return (char)value;
+ }
+
+ public static char ToChar (sbyte value)
+ {
+ if (value < Char.MinValue)
+ throw new OverflowException
+ ("Value is less than Char.MinValue");
+
+ return (char)value;
+ }
+
+ public static char ToChar (short value)
+ {
+ if (value < Char.MinValue)
+ throw new OverflowException
+ ("Value is less than Char.MinValue");
+
+ return (char)value;
+ }
+
+ public static char ToChar (string value)
+ {
+ return Char.Parse (value);
+ }
+
+ public static char ToChar (uint value)
+ {
+ if (value > Char.MaxValue)
+ throw new OverflowException
+ ("Value is greater than Char.MaxValue");
+
+ return (char)value;
+ }
+
+ public static char ToChar (ulong value)
+ {
+ if (value > Char.MaxValue)
+ throw new OverflowException
+ ("Value is greater than Char.MaxValue");
+
+ return (char)value;
+ }
+
+ public static char ToChar (ushort value)
+ {
+ if (value > Char.MaxValue)
+ throw new OverflowException
+ ("Value is greater than Char.MaxValue");
+
+ return (char)value;
+ }
+
+ // ========== DateTime Conversions ========== //
+
+ public static DateTime ToDateTime (string value)
+ {
+ return DateTime.Parse (value);
+ }
+
+ public static DateTime ToDateTime (string value, IFormatProvider provider)
+ {
+ return DateTime.Parse (value, provider);
+ }
+
+ // ========== Decimal Conversions ========== //
+
+ public static decimal ToDecimal (bool value)
+ {
+ return value ? 1 : 0;
+ }
+
+ public static decimal ToDecimal (byte value)
+ {
+ return (decimal)value;
+ }
+
+ public static decimal ToDecimal (decimal value)
+ {
+ return value;
+ }
+
+ public static decimal ToDecimal (double value)
+ {
+ if (value > (double)Decimal.MaxValue || value < (double)Decimal.MinValue)
+ throw new OverflowException
+ ("Value is greater than Decimal.MaxValue or less than Decimal.MinValue");
+
+ return (decimal)value;
+ }
+
+ public static decimal ToDecimal (float value)
+ {
+ if (value > (double)Decimal.MaxValue || value < (double)Decimal.MinValue)
+ throw new OverflowException
+ ("Value is greater than Decimal.MaxValue or less than Decimal.MinValue");
+
+ return (decimal)value;
+ }
+
+ public static decimal ToDecimal (int value)
+ {
+ return (decimal)value;
+ }
+
+ public static decimal ToDecimal (long value)
+ {
+ return (decimal)value;
+ }
+
+ public static decimal ToDecimal (sbyte value)
+ {
+ return (decimal)value;
+ }
+
+ public static decimal ToDecimal (short value)
+ {
+ return (decimal)value;
+ }
+
+ public static decimal ToDecimal (string value)
+ {
+ return Decimal.Parse (value);
+ }
+
+ public static decimal ToDecimal (string value, IFormatProvider provider)
+ {
+ return Decimal.Parse (value, provider);
+ }
+
+ public static decimal ToDecimal (uint value)
+ {
+ return (decimal)value;
+ }
+
+ public static decimal ToDecimal (ulong value)
+ {
+ return (decimal)value;
+ }
+
+ public static decimal ToDecimal (ushort value)
+ {
+ return (decimal)value;
+ }
+
+ // ========== Double Conversions ========== //
+
+ public static double ToDouble (bool value)
+ {
+ return value ? 1 : 0;
+ }
+
+ public static double ToDouble (byte value)
+ {
+ return (double)value;
+ }
+
+ public static double ToDouble (decimal value)
+ {
+ return (double)value;
+ }
+
+ public static double ToDouble (double value)
+ {
+ return value;
+ }
+
+ public static double ToDouble (float value)
+ {
+ return (double)value;
+ }
+
+ public static double ToDouble (int value)
+ {
+ return (double)value;
+ }
+
+ public static double ToDouble (long value)
+ {
+ return (double)value;
+ }
+
+ public static double ToDouble (sbyte value)
+ {
+ return (double)value;
+ }
+
+ public static double ToDouble (short value)
+ {
+ return (double)value;
+ }
+
+ public static double ToDouble (string value)
+ {
+ return Double.Parse (value);
+ }
+
+ public static double ToDouble (string value, IFormatProvider provider)
+ {
+ return Double.Parse (value, provider);
+ }
+
+ public static double ToDouble (uint value)
+ {
+ return (double)value;
+ }
+
+ public static double ToDouble (ulong value)
+ {
+ return (double)value;
+ }
+
+ public static double ToDouble (ushort value)
+ {
+ return (double)value;
+ }
+
+ // ========== Int16 Conversions ========== //
+
+ public static short ToInt16 (bool value)
+ {
+ return (short)(value ? 1 : 0);
+ }
+
+ public static short ToInt16 (byte value)
+ {
+ return (short)value;
+ }
+
+ public static short ToInt16 (char value)
+ {
+ if (value > Int16.MaxValue)
+ throw new OverflowException
+ ("Value is greater than Int16.MaxValue");
+
+ return (short)value;
+ }
+
+ public static short ToInt16 (decimal value)
+ {
+ if (value > Int16.MaxValue || value < Int16.MinValue)
+ throw new OverflowException
+ ("Value is greater than Int16.MaxValue or less than Int16.MinValue");
+
+ // Returned Even-Rounded
+ return (short)(Math.Round (value));
+ }
+
+ public static short ToInt16 (double value)
+ {
+ if (value > Int16.MaxValue || value < Int16.MinValue)
+ throw new OverflowException
+ ("Value is greater than Int16.MaxValue or less than Int16.MinValue");
+
+ // Returned Even-Rounded
+ return (short)(Math.Round (value));
+ }
+
+ public static short ToInt16 (float value)
+ {
+ if (value > Int16.MaxValue || value < Int16.MinValue)
+ throw new OverflowException
+ ("Value is greater than Int16.MaxValue or less than Int16.MinValue");
+
+ // Returned Even-Rounded, use Math.Round pass as a double.
+ return (short)Math.Round ( (double)value);
+ }
+
+ public static short ToInt16 (int value)
+ {
+ if (value > Int16.MaxValue || value < Int16.MinValue)
+ throw new OverflowException
+ ("Value is greater than Int16.MaxValue or less than Int16.MinValue");
+
+ return (short)value;
+ }
+
+ public static short ToInt16 (long value)
+ {
+ if (value > Int16.MaxValue || value < Int16.MinValue)
+ throw new OverflowException
+ ("Value is greater than Int16.MaxValue or less than Int16.MinValue");
+
+ return (short)value;
+ }
+
+ public static short ToInt16 (sbyte value)
+ {
+ return (short)value;
+ }
+
+ public static short ToInt16 (short value)
+ {
+ return value;
+ }
+
+ public static short ToInt16 (string value)
+ {
+ return Int16.Parse (value);
+ }
+
+ public static short ToInt16 (string value, IFormatProvider provider)
+ {
+ return Int16.Parse (value, provider);
+ }
+
+ public static short ToInt16 (uint value)
+ {
+ if (value > Int16.MaxValue)
+ throw new OverflowException
+ ("Value is greater than Int16.MaxValue");
+
+ return (short)value;
+ }
+
+ public static short ToInt16 (ulong value)
+ {
+ if (value > (ulong)Int16.MaxValue)
+ throw new OverflowException
+ ("Value is greater than Int16.MaxValue");
+
+ return (short)value;
+ }
+
+ public static short ToInt16 (ushort value)
+ {
+ if (value > Int16.MaxValue)
+ throw new OverflowException
+ ("Value is greater than Int16.MaxValue");
+
+ return (short)value;
+ }
+
+ // ========== Int32 Conversions ========== //
+
+ public static int ToInt32 (bool value)
+ {
+ return value ? 1 : 0;
+ }
+
+ public static int ToInt32 (byte value)
+ {
+ return (int)value;
+ }
+
+ public static int ToInt32 (char value)
+ {
+ return (int)value;
+ }
+
+ public static int ToInt32 (decimal value)
+ {
+ if (value > Int32.MaxValue || value < Int32.MinValue)
+ throw new OverflowException
+ ("Value is greater than Int32.MaxValue or less than Int32.MinValue");
+
+ // Returned Even-Rounded
+ return (int)(Math.Round (value));
+ }
+
+ public static int ToInt32 (double value)
+ {
+ if (value > Int32.MaxValue || value < Int32.MinValue)
+ throw new OverflowException
+ ("Value is greater than Int32.MaxValue or less than Int32.MinValue");
+
+ // Returned Even-Rounded
+ return (int)(Math.Round (value));
+ }
+
+ public static int ToInt32 (float value)
+ {
+ if (value > Int32.MaxValue || value < Int32.MinValue)
+ throw new OverflowException
+ ("Value is greater than Int32.MaxValue or less than Int32.MinValue");
+
+ // Returned Even-Rounded, pass as a double, could just call
+ // Convert.ToInt32 ( (double)value);
+ return (int)(Math.Round ( (double)value));
+ }
+
+ public static int ToInt32 (int value)
+ {
+ return value;
+ }
+
+ public static int ToInt32 (long value)
+ {
+ if (value > Int32.MaxValue || value < Int32.MinValue)
+ throw new OverflowException
+ ("Value is greater than Int32.MaxValue or less than Int32.MinValue");
+
+ return (int)value;
+ }
+
+ public static int ToInt32 (sbyte value)
+ {
+ return (int)value;
+ }
+
+ public static int ToInt32 (short value)
+ {
+ return (int)value;
+ }
+
+ public static int ToInt32 (string value)
+ {
+ return Int32.Parse (value);
+ }
+
+ public static int ToInt32 (string value, IFormatProvider provider)
+ {
+ return Int32.Parse (value, provider);
+ }
+
+ public static int ToInt32 (uint value)
+ {
+ if (value > Int32.MaxValue)
+ throw new OverflowException
+ ("Value is greater than Int32.MaxValue");
+
+ return (int)value;
+ }
+
+ public static int ToInt32 (ulong value)
+ {
+ if (value > Int32.MaxValue)
+ throw new OverflowException
+ ("Value is greater than Int32.MaxValue");
+
+ return (int)value;
+ }
+
+ public static int ToInt32 (ushort value)
+ {
+ return (int)value;
+ }
+
+ // ========== Int64 Conversions ========== //
+
+ public static long ToInt64 (bool value)
+ {
+ return value ? 1 : 0;
+ }
+
+ public static long ToInt64 (byte value)
+ {
+ return (long)value;
+ }
+
+ public static long ToInt64 (char value)
+ {
+ return (long)value;
+ }
+
+ public static long ToInt64 (decimal value)
+ {
+ if (value > Int64.MaxValue || value < Int64.MinValue)
+ throw new OverflowException
+ ("Value is greater than Int64.MaxValue or less than Int64.MinValue");
+
+ // Returned Even-Rounded
+ return (long)(Math.Round (value));
+ }
+
+ public static long ToInt64 (double value)
+ {
+ if (value > Int64.MaxValue || value < Int64.MinValue)
+ throw new OverflowException
+ ("Value is greater than Int64.MaxValue or less than Int64.MinValue");
+
+ // Returned Even-Rounded
+ return (long)(Math.Round (value));
+ }
+
+ public static long ToInt64 (float value)
+ {
+ if (value > Int64.MaxValue || value < Int64.MinValue)
+ throw new OverflowException
+ ("Value is greater than Int64.MaxValue or less than Int64.MinValue");
+
+ // Returned Even-Rounded, pass to Math as a double, could
+ // just call Convert.ToInt64 ( (double)value);
+ return (long)(Math.Round ( (double)value));
+ }
+
+ public static long ToInt64 (int value)
+ {
+ return (long)value;
+ }
+
+ public static long ToInt64 (long value)
+ {
+ return value;
+ }
+
+ public static long ToInt64 (sbyte value)
+ {
+ return (long)value;
+ }
+
+ public static long ToInt64 (short value)
+ {
+ return (long)value;
+ }
+
+ public static long ToInt64 (string value)
+ {
+ return Int64.Parse (value);
+ }
+
+ public static long ToInt64 (string value, IFormatProvider provider)
+ {
+ return Int64.Parse (value, provider);
+ }
+
+ public static long ToInt64 (uint value)
+ {
+ return (long)value;
+ }
+
+ public static long ToInt64 (ulong value)
+ {
+ if (value > Int64.MaxValue)
+ throw new OverflowException
+ ("Value is greater than Int64.MaxValue");
+
+ return (long)value;
+ }
+
+ public static long ToInt64 (ushort value)
+ {
+ return (long)value;
+ }
+
+ // ========== SByte Conversions ========== //
+
+ public static sbyte ToSByte (bool value)
+ {
+ return (sbyte)(value ? 1 : 0);
+ }
+
+ public static sbyte ToSByte (byte value)
+ {
+ if (value > SByte.MaxValue)
+ throw new OverflowException
+ ("Value is greater than SByte.MaxValue");
+
+ return (sbyte)value;
+ }
+
+ public static sbyte ToSByte (char value)
+ {
+ if (value > SByte.MaxValue)
+ throw new OverflowException
+ ("Value is greater than SByte.MaxValue");
+
+ return (sbyte)value;
+ }
+
+ public static sbyte ToSByte (decimal value)
+ {
+ if (value > SByte.MaxValue || value < SByte.MinValue)
+ throw new OverflowException
+ ("Value is greater than SByte.MaxValue or less than SByte.MinValue");
+
+ // Returned Even-Rounded
+ return (sbyte)(Math.Round (value));
+ }
+
+ public static sbyte ToSByte (double value)
+ {
+ if (value > SByte.MaxValue || value < SByte.MinValue)
+ throw new OverflowException
+ ("Value is greater than SByte.MaxValue or less than SByte.MinValue");
+
+ // Returned Even-Rounded
+ return (sbyte)(Math.Round (value));
+ }
+
+ public static sbyte ToSByte (float value)
+ {
+ if (value > SByte.MaxValue || value < SByte.MinValue)
+ throw new OverflowException
+ ("Value is greater than SByte.MaxValue or less than SByte.Minalue");
+
+ // Returned Even-Rounded, pass as double to Math
+ return (sbyte)(Math.Round ( (double)value));
+ }
+
+ public static sbyte ToSByte (int value)
+ {
+ if (value > SByte.MaxValue || value < SByte.MinValue)
+ throw new OverflowException
+ ("Value is greater than SByte.MaxValue or less than SByte.MinValue");
+
+ return (sbyte)value;
+ }
+
+ public static sbyte ToSByte (long value)
+ {
+ if (value > SByte.MaxValue || value < SByte.MinValue)
+ throw new OverflowException
+ ("Value is greater than SByte.MaxValue or less than SByte.MinValue");
+
+ return (sbyte)value;
+ }
+
+ public static sbyte ToSByte (sbyte value)
+ {
+ return value;
+ }
+
+ public static sbyte ToSByte (short value)
+ {
+ if (value > SByte.MaxValue || value < SByte.MinValue)
+ throw new OverflowException
+ ("Value is greater than SByte.MaxValue or less than SByte.MinValue");
+
+ return (sbyte)value;
+ }
+
+ public static sbyte ToSByte (string value)
+ {
+ return SByte.Parse (value);
+ }
+
+ public static sbyte ToSByte (string value, IFormatProvider provider)
+ {
+ return SByte.Parse (value, provider);
+ }
+
+ public static sbyte ToSByte (uint value)
+ {
+ if (value > SByte.MaxValue)
+ throw new OverflowException
+ ("Value is greater than SByte.MaxValue");
+
+ return (sbyte)value;
+ }
+
+ public static sbyte ToSByte (ulong value)
+ {
+ if (value > (ulong)SByte.MaxValue)
+ throw new OverflowException
+ ("Value is greater than SByte.MaxValue");
+
+ return (sbyte)value;
+ }
+
+ public static sbyte ToSByte (ushort value)
+ {
+ if (value > SByte.MaxValue)
+ throw new OverflowException
+ ("Value is greater than SByte.MaxValue");
+
+ return (sbyte)value;
+ }
+
+ // ========== Single Conversions ========== //
+
+ public static float ToSingle (bool value)
+ {
+ return value ? 1 : 0;
+ }
+
+ public static float ToSingle (byte value)
+ {
+ return (float)value;
+ }
+
+ public static float ToSingle (decimal value)
+ {
+ return (float)value;
+ }
+
+ public static float ToSingle (double value)
+ {
+ if (value > Single.MaxValue || value < Single.MinValue)
+ throw new OverflowException
+ ("Value is greater than Single.MaxValue or less than Single.MinValue");
+
+ return (float)value;
+ }
+
+ public static float ToSingle (float value)
+ {
+ return value;
+ }
+
+ public static float ToSingle (int value)
+ {
+ return (float)value;
+ }
+
+ public static float ToSingle (long value)
+ {
+ return (float)value;
+ }
+
+ public static float ToSingle (sbyte value)
+ {
+ return (float)value;
+ }
+
+ public static float ToSingle (short value)
+ {
+ return (float)value;
+ }
+
+ public static float ToSingle (string value)
+ {
+ return Single.Parse (value);
+ }
+
+ public static float ToSingle (string value, IFormatProvider provider)
+ {
+ return Single.Parse (value, provider);
+ }
+
+ public static float ToSingle (uint value)
+ {
+ return (float)value;
+ }
+
+ public static float ToSingle (ulong value)
+ {
+ return (float)value;
+ }
+
+ public static float ToSingle (ushort value)
+ {
+ return (float)value;
+ }
+
+ // ========== String Conversions ========== //
+
+ public static string ToString (bool value)
+ {
+ return value.ToString ();
+ }
+
+ public static string ToString (byte value)
+ {
+ return value.ToString ();
+ }
+
+ public static string ToString (byte value, IFormatProvider provider)
+ {
+ return value.ToString (provider);
+ }
+
+ public static string ToString (char value)
+ {
+ return value.ToString ();
+ }
+
+ public static string ToString (DateTime value)
+ {
+ return value.ToString ();
+ }
+
+ public static string ToString (DateTime value, IFormatProvider provider)
+ {
+ return value.ToString (provider);
+ }
+
+ public static string ToString (decimal value)
+ {
+ return value.ToString ();
+ }
+
+ public static string ToString (decimal value, IFormatProvider provider)
+ {
+ return value.ToString (provider);
+ }
+
+ public static string ToString (double value)
+ {
+ return value.ToString ();
+ }
+
+ public static string ToString (double value, IFormatProvider provider)
+ {
+ return value.ToString (provider);
+ }
+
+ public static string ToString (float value)
+ {
+ return value.ToString ();
+ }
+
+ public static string ToString (float value, IFormatProvider provider)
+ {
+ return value.ToString (provider);
+ }
+
+ public static string ToString (int value)
+ {
+ return value.ToString ();
+ }
+
+ public static string ToString (int value, IFormatProvider provider)
+ {
+ return value.ToString (provider);
+ }
+
+ public static string ToString (long value)
+ {
+ return value.ToString ();
+ }
+
+ public static string ToString (long value, IFormatProvider provider)
+ {
+ return value.ToString (provider);
+ }
+
+ public static string ToString (sbyte value)
+ {
+ return value.ToString ();
+ }
+
+ public static string ToString (sbyte value, IFormatProvider provider)
+ {
+ return value.ToString (provider);
+ }
+
+ public static string ToString (short value)
+ {
+ return value.ToString ();
+ }
+
+ public static string ToString (short value, IFormatProvider provider)
+ {
+ return value.ToString (provider);
+ }
+
+ public static string ToString (string value)
+ {
+ return value;
+ }
+
+ public static string ToString (uint value)
+ {
+ return value.ToString ();
+ }
+
+ public static string ToString (uint value, IFormatProvider provider)
+ {
+ return value.ToString (provider);
+ }
+
+ public static string ToString (ulong value)
+ {
+ return value.ToString ();
+ }
+
+ public static string ToString (ulong value, IFormatProvider provider)
+ {
+ return value.ToString (provider);
+ }
+
+ public static string ToString (ushort value)
+ {
+ return value.ToString ();
+ }
+
+ public static string ToString (ushort value, IFormatProvider provider)
+ {
+ return value.ToString (provider);
+ }
+
+ // ========== UInt16 Conversions ========== //
+
+ public static ushort ToUInt16 (bool value)
+ {
+ return (ushort)(value ? 1 : 0);
+ }
+
+ public static ushort ToUInt16 (byte value)
+ {
+ return (ushort)value;
+ }
+
+ public static ushort ToUInt16 (char value)
+ {
+ return (ushort)value;
+ }
+
+ public static ushort ToUInt16 (decimal value)
+ {
+ if (value > UInt16.MaxValue || value < UInt16.MinValue)
+ throw new OverflowException
+ ("Value is greater than UInt16.MaxValue or less than UInt16.MinValue");
+
+ // Returned Even-Rounded
+ return (ushort)(Math.Round (value));
+ }
+
+ public static ushort ToUInt16 (double value)
+ {
+ if (value > UInt16.MaxValue || value < UInt16.MinValue)
+ throw new OverflowException
+ ("Value is greater than UInt16.MaxValue or less than UInt16.MinValue");
+
+ // Returned Even-Rounded
+ return (ushort)(Math.Round (value));
+ }
+
+ public static ushort ToUInt16 (float value)
+ {
+ if (value > UInt16.MaxValue || value < UInt16.MinValue)
+ throw new OverflowException
+ ("Value is greater than UInt16.MaxValue or less than UInt16.MinValue");
+
+ // Returned Even-Rounded, pass as double to Math
+ return (ushort)(Math.Round ( (double)value));
+ }
+
+ public static ushort ToUInt16 (int value)
+ {
+ if (value > UInt16.MaxValue || value < UInt16.MinValue)
+ throw new OverflowException
+ ("Value is greater than UInt16.MaxValue or less than UInt16.MinValue");
+
+ return (ushort)value;
+ }
+
+ public static ushort ToUInt16 (long value)
+ {
+ if (value > UInt16.MaxValue || value < UInt16.MinValue)
+ throw new OverflowException
+ ("Value is greater than UInt16.MaxValue or less than UInt16.MinValue");
+
+ return (ushort)value;
+ }
+
+ public static ushort ToUInt16 (sbyte value)
+ {
+ if (value < UInt16.MinValue)
+ throw new OverflowException
+ ("Value is less than UInt16.MinValue");
+
+ return (ushort)value;
+ }
+
+ public static ushort ToUInt16 (short value)
+ {
+ if (value < UInt16.MinValue)
+ throw new OverflowException
+ ("Value is less than UInt16.MinValue");
+
+ return (ushort)value;
+ }
+
+ public static ushort ToUInt16 (string value)
+ {
+ return UInt16.Parse (value);
+ }
+
+ public static ushort ToUInt16 (string value, IFormatProvider provider)
+ {
+ return UInt16.Parse (value, provider);
+ }
+
+ public static ushort ToUInt16 (uint value)
+ {
+ if (value > UInt16.MaxValue)
+ throw new OverflowException
+ ("Value is greater than UInt16.MaxValue");
+
+ return (ushort)value;
+ }
+
+ public static ushort ToUInt16 (ulong value)
+ {
+ if (value > (ulong)UInt16.MaxValue)
+ throw new OverflowException
+ ("Value is greater than UInt16.MaxValue");
+
+ return (ushort)value;
+ }
+
+ public static ushort ToUInt16 (ushort value)
+ {
+ return value;
+ }
+
+ // ========== UInt32 Conversions ========== //
+
+ public static uint ToUInt32 (bool value)
+ {
+ return (uint)(value ? 1 : 0);
+ }
+
+ public static uint ToUInt32 (byte value)
+ {
+ return (uint)value;
+ }
+
+ public static uint ToUInt32 (char value)
+ {
+ return (uint)value;
+ }
+
+ public static uint ToUInt32 (decimal value)
+ {
+ if (value > UInt32.MaxValue || value < UInt32.MinValue)
+ throw new OverflowException
+ ("Value is greater than UInt32.MaxValue or less than UInt32.MinValue");
+
+ // Returned Even-Rounded
+ return (uint)(Math.Round (value));
+ }
+
+ public static uint ToUInt32 (double value)
+ {
+ if (value > UInt32.MaxValue || value < UInt32.MinValue)
+ throw new OverflowException
+ ("Value is greater than UInt32.MaxValue or less than UInt32.MinValue");
+
+ // Returned Even-Rounded
+ return (uint)(Math.Round (value));
+ }
+
+ public static uint ToUInt32 (float value)
+ {
+ if (value > UInt32.MaxValue || value < UInt32.MinValue)
+ throw new OverflowException
+ ("Value is greater than UInt32.MaxValue or less than UInt32.MinValue");
+
+ // Returned Even-Rounded, pass as double to Math
+ return (uint)(Math.Round ( (double)value));
+ }
+
+ public static uint ToUInt32 (int value)
+ {
+ if (value < UInt32.MinValue)
+ throw new OverflowException
+ ("Value is less than UInt32.MinValue");
+
+ return (uint)value;
+ }
+
+ public static uint ToUInt32 (long value)
+ {
+ if (value > UInt32.MaxValue || value < UInt32.MinValue)
+ throw new OverflowException
+ ("Value is greater than UInt32.MaxValue or less than UInt32.MinValue");
+
+ return (uint)value;
+ }
+
+ public static uint ToUInt32 (sbyte value)
+ {
+ if (value < UInt32.MinValue)
+ throw new OverflowException
+ ("Value is less than UInt32.MinValue");
+
+ return (uint)value;
+ }
+
+ public static uint ToUInt32 (short value)
+ {
+ if (value < UInt32.MinValue)
+ throw new OverflowException
+ ("Value is less than UInt32.MinValue");
+
+ return (uint)value;
+ }
+
+ public static uint ToUInt32 (string value)
+ {
+ return UInt32.Parse (value);
+ }
+
+ public static uint ToUInt32 (string value, IFormatProvider provider)
+ {
+ return UInt32.Parse (value, provider);
+ }
+
+ public static uint ToUInt32 (uint value)
+ {
+ return value;
+ }
+
+ public static uint ToUInt32 (ulong value)
+ {
+ if (value > UInt32.MaxValue)
+ throw new OverflowException
+ ("Value is greater than UInt32.MaxValue");
+
+ return (uint)value;
+ }
+
+ public static uint ToUInt32 (ushort value)
+ {
+ return (uint)value;
+ }
+
+ // ========== UInt64 Conversions ========== //
+
+ public static ulong ToUInt64 (bool value)
+ {
+ return (ulong)(value ? 1 : 0);
+ }
+
+ public static ulong ToUInt64 (byte value)
+ {
+ return (ulong)value;
+ }
+
+ public static ulong ToUInt64 (char value)
+ {
+ return (ulong)value;
+ }
+
+ public static ulong ToUInt64 (decimal value)
+ {
+ if (value > UInt64.MaxValue || value < UInt64.MinValue)
+ throw new OverflowException
+ ("Value is greater than UInt64.MaxValue or less than UInt64.MinValue");
+
+ // Returned Even-Rounded
+ return (ulong)(Math.Round (value));
+ }
+
+ public static ulong ToUInt64 (double value)
+ {
+ if (value > UInt64.MaxValue || value < UInt64.MinValue)
+ throw new OverflowException
+ ("Value is greater than UInt64.MaxValue or less than UInt64.MinValue");
+
+ // Returned Even-Rounded
+ return (ulong)(Math.Round (value));
+ }
+
+ public static ulong ToUInt64 (float value)
+ {
+ if (value > UInt64.MaxValue || value < UInt64.MinValue)
+ throw new OverflowException
+ ("Value is greater than UInt64.MaxValue or less than UInt64.MinValue");
+
+ // Returned Even-Rounded, pass as a double to Math
+ return (ulong)(Math.Round ( (double)value));
+ }
+
+ public static ulong ToUInt64 (int value)
+ {
+ if (value < (int)UInt64.MinValue)
+ throw new OverflowException
+ ("Value is less than UInt64.MinValue");
+
+ return (ulong)value;
+ }
+
+ public static ulong ToUInt64 (long value)
+ {
+ if (value < (long)UInt64.MinValue)
+ throw new OverflowException
+ ("Value is less than UInt64.MinValue");
+
+ return (ulong)value;
+ }
+
+ public static ulong ToUInt64 (sbyte value)
+ {
+ if (value < (sbyte)UInt64.MinValue)
+ throw new OverflowException
+ ("Value is less than UInt64.MinValue");
+
+ return (ulong)value;
+ }
+
+ public static ulong ToUInt64 (short value)
+ {
+ if (value < (short)UInt64.MinValue)
+ throw new OverflowException
+ ("Value is less than UInt64.MinValue");
+
+ return (ulong)value;
+ }
+
+ public static ulong ToUInt64 (string value)
+ {
+ return UInt64.Parse (value);
+ }
+
+ public static ulong ToUInt64 (string value, IFormatProvider provider)
+ {
+ return UInt64.Parse (value, provider);
+ }
+
+ public static ulong ToUInt64 (uint value)
+ {
+ return (ulong)value;
+ }
+
+ public static ulong ToUInt64 (ulong value)
+ {
+ return value;
+ }
+
+ public static ulong ToUInt64 (ushort value)
+ {
+ return (ulong)value;
+ }
+
+ // ========== Conversion / Helper Fucntions ========== //
+
+ // Lookup table for the conversion ToType method. Order
+ // is important! Used by ToType for comparing the target
+ // type, and uses hardcoded array indexes.
+ private static Type[] conversionTable = {
+ // Valid ICovnertible Types
+ typeof (Boolean), // 0 TypeCode.Boolean
+ typeof (Byte), // 1 TypeCode.Byte
+ typeof (Char), // 2 TypeCode.Char
+ typeof (DateTime), // 3 TypeCode.DateTime
+ typeof (Decimal), // 4 TypeCode.Decimal
+ typeof (Double), // 5 TypeCode.Double
+ typeof (Int16), // 6 TypeCode.Int16
+ typeof (Int32), // 7 TypeCode.Int32
+ typeof (Int64), // 8 TypeCode.Int64
+ typeof (SByte), // 9 TypeCode.Sbyte
+ typeof (Single), // 10 TypeCode.Single
+ typeof (String), // 11 TypeCode.String
+ typeof (UInt16), // 12 TypeCode.UInt16
+ typeof (UInt32), // 13 TypeCode.UInt32
+ typeof (UInt64), // 14 TypeCode.UInt64
+
+ // Invalid IConvertible Interface Types
+ typeof (Object) // 15 TypeCode.Object
+ };
+
+ // Function to convert an object to another type and return
+ // it as an object. In place for the core data types to use
+ // when implementing IConvertible. Uses hardcoded indexes in
+ // the conversionTypes array, so if modify carefully.
+ internal static object ToType (object value, Type conversionType,
+ IFormatProvider provider)
+ {
+ if (value == null)
+ throw new ArgumentException
+ ("Invalid conversion from null value");
+
+ if (value is IConvertible) {
+ IConvertible convertValue = (IConvertible)value;
+
+ if (conversionType == conversionTable[0]) {
+ // 0 TypeCode.Boolean
+ return (object)(convertValue.ToBoolean (provider));
+
+ } else if (conversionType == conversionTable[1]) {
+ // 1 TypeCode.Byte
+ return (object)(convertValue.ToByte (provider));
+
+ } else if (conversionType == conversionTable[2]) {
+ // 2 TypeCode.Char
+ return (object)(convertValue.ToChar (provider));
+
+ } else if (conversionType == conversionTable[3]) {
+ // 3 TypeCode.DateTime
+ return (object)(convertValue.ToDateTime (provider));
+
+ } else if (conversionType == conversionTable[4]) {
+ // 4 TypeCode.Decimal
+ return (object)(convertValue.ToDecimal (provider));
+
+ } else if (conversionType == conversionTable[5]) {
+ // 5 TypeCode.Double
+ return (object)(convertValue.ToDouble (provider));
+
+ } else if (conversionType == conversionTable[6]) {
+ // 6 TypeCode.Int16
+ return (object)(convertValue.ToInt16 (provider));
+
+ } else if (conversionType == conversionTable[7]) {
+ // 7 TypeCode.Int32
+ return (object)(convertValue.ToInt32 (provider));
+
+ } else if (conversionType == conversionTable[8]) {
+ // 8 TypeCode.Int64
+ return (object)(convertValue.ToInt64 (provider));
+
+ } else if (conversionType == conversionTable[9]) {
+ // 9 TypeCode.Sbyte
+ return (object)(convertValue.ToSByte (provider));
+
+ } else if (conversionType == conversionTable[10]) {
+ // 10 TypeCode.Single
+ return (object)(convertValue.ToSingle (provider));
+
+ } else if (conversionType == conversionTable[11]) {
+ // 11 TypeCode.String
+ return (object)(convertValue.ToString (provider));
+
+ } else if (conversionType == conversionTable[12]) {
+ // 12 TypeCode.UInt16
+ return (object)(convertValue.ToUInt16 (provider));
+
+ } else if (conversionType == conversionTable[13]) {
+ // 13 TypeCode.UInt32
+ return (object)(convertValue.ToUInt32 (provider));
+
+ } else if (conversionType == conversionTable[14]) {
+ // 14 TypeCode.UInt64
+ return (object)(convertValue.ToUInt64 (provider));
+
+ } else if (conversionType == conversionTable[15]) {
+ // 15 TypeCode.Object
+ return (object)(value);
+
+ } else {
+ // Not in the conversion table
+ throw new InvalidCastException
+ ("Unknown target conversion type");
+ }
+ } else {
+ // Value is not IConvertible
+ throw new ArgumentException
+ ("Value is not a convertible object");
+ }
+ }
+ }
+}
diff --git a/mcs/class/corlib/System/DateTime.cs b/mcs/class/corlib/System/DateTime.cs
new file mode 100644
index 00000000000..4ea56a3ac00
--- /dev/null
+++ b/mcs/class/corlib/System/DateTime.cs
@@ -0,0 +1,726 @@
+//
+// System.DateTime.cs
+//
+// author:
+// Marcel Narings (marcel@narings.nl)
+//
+// (C) 2001 Marcel Narings
+
+using System;
+using System.Globalization ;
+
+
+namespace System
+{
+ /// <summary>
+ /// The DateTime structure represents dates and time ranging from 1-1-0001 12:00:00 AM to 31-12-9999 23:59:00 Common Era.
+ /// </summary>
+ ///
+ public struct DateTime : IComparable , IFormattable , IConvertible
+ {
+ long ticks;
+
+ private const long MaxTicks = 3155378975999999999L;
+ private const long MinTicks = 0L;
+ private const int dp400 = 146097;
+ private const int dp100 = 36524;
+ private const int dp4 = 1461;
+
+ public static readonly DateTime MaxValue = new DateTime (MaxTicks);
+ public static readonly DateTime MinValue = new DateTime (MinTicks);
+
+ private enum Which
+ {
+ Day,
+ DayYear,
+ Month,
+ Year
+ };
+
+ private static int[] daysmonth = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
+ private static int[] daysmonthleap = { 0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
+
+ private static long AbsoluteDays (int year, int month, int day)
+ {
+ int[] days;
+ int temp = 0, m=1 ;
+
+ days = (IsLeapYear(year) ? daysmonthleap : daysmonth);
+
+ while (m < month)
+ temp += days[m++];
+ return ((day-1) + temp + (365* (year-1)) + ((year-1)/4) - ((year-1)/100) + ((year-1)/400));
+ }
+
+ private int FromTicks(Which what)
+ {
+ int num400, num100, num4, numyears;
+ int M =1;
+
+ int[] days = daysmonth;
+ int totaldays = (int) (ticks / TimeSpan.TicksPerDay);
+
+ num400 = (totaldays / dp400);
+ totaldays -= num400 * dp400;
+
+ num100 = (totaldays / dp100);
+ if (num100 == 4) // leap
+ num100 = 3;
+ totaldays -= (num100 * dp100);
+
+ num4 = totaldays / dp4;
+ totaldays -= (num4 * dp4);
+
+ numyears = totaldays / 365 ;
+
+ if (numyears == 4) //leap
+ numyears =3 ;
+ if (what == Which.Year )
+ return num400*400 + num100*100 + num4*4 + numyears + 1;
+
+ totaldays -= (numyears * 365) ;
+ if (what == Which.DayYear )
+ return totaldays + 1;
+
+ if ((numyears==3) && ((num100 == 3) || !(num4 == 24)) ) //31 dec leapyear
+ days = daysmonthleap;
+
+ while (totaldays >= days[M])
+ totaldays -= days[M++];
+
+ if (what == Which.Month )
+ return M;
+
+ return totaldays +1;
+
+
+ }
+
+
+ // Constructors
+
+ /// <summary>
+ /// Constructs a DateTime for specified ticks
+ /// </summary>
+ ///
+ public DateTime (long newticks)
+ {
+ ticks = newticks;
+
+ if ( newticks < MinValue.ticks || newticks > MaxValue.ticks)
+ throw new ArgumentOutOfRangeException ();
+ }
+
+ public DateTime (int year, int month, int day)
+ : this (year, month, day,0,0,0,0) {}
+
+ public DateTime (int year, int month, int day, int hour, int minute, int second)
+ : this (year, month, day, hour, minute, second, 0) {}
+
+ public DateTime (int year, int month, int day, int hour, int minute, int second, int millisecond)
+ {
+ if ( year < 1 || year > 9999 ||
+ month < 1 || month >12 ||
+ day < 1 || day > DaysInMonth(year, month) ||
+ hour < 0 || hour > 23 ||
+ minute < 0 || minute > 59 ||
+ second < 0 || second > 59 )
+ throw new ArgumentOutOfRangeException() ;
+
+ ticks = AbsoluteDays(year,month,day) * TimeSpan.TicksPerDay +
+ hour * TimeSpan.TicksPerHour +
+ minute * TimeSpan.TicksPerMinute +
+ second * TimeSpan.TicksPerSecond +
+ millisecond * TimeSpan.TicksPerMillisecond ;
+
+ if (ticks < MinValue.ticks || ticks > MaxValue.ticks )
+ throw new ArgumentException() ;
+ }
+
+ public DateTime (int year, int month, int day, Calendar calendar)
+ : this (year, month, day, 0, 0, 0, 0, calendar) {}
+
+
+ public DateTime (int year, int month, int day, int hour, int minute, int second, Calendar calendar)
+ : this (year, month, day, hour, minute, second, 0, calendar) {}
+
+
+ public DateTime (int year, int month, int day, int hour, int minute, int second, int millisecond, Calendar calendar)
+ : this(year, month, day, hour, minute, second, millisecond)
+ {
+ if ( calendar == null)
+ throw new ArgumentNullException();
+ }
+
+
+ /* Properties */
+
+ public DateTime Date
+ {
+ get
+ {
+ return new DateTime(ticks - (ticks % TimeSpan.TicksPerDay )) ;
+ }
+ }
+
+ public int Day
+ {
+ get
+ {
+ return FromTicks(Which.Day);
+ }
+ }
+
+ public DayOfWeek DayOfWeek
+ {
+ get
+ {
+ return ( (DayOfWeek) (((ticks / TimeSpan.TicksPerDay)+1) % 7) );
+ }
+ }
+
+ public int DayOfYear
+ {
+ get
+ {
+ return FromTicks(Which.DayYear);
+ }
+ }
+
+ public int Hour
+ {
+ get
+ {
+ return ( (int) ((ticks % TimeSpan.TicksPerDay) / TimeSpan.TicksPerHour) );
+ }
+ }
+
+ public int Millisecond
+ {
+ get
+ {
+ return ( (int) (ticks % TimeSpan.TicksPerSecond / TimeSpan.TicksPerMillisecond) );
+ }
+ }
+
+ public int Minute
+ {
+ get
+ {
+ return ( (int) (ticks % TimeSpan.TicksPerHour / TimeSpan.TicksPerMinute) );
+ }
+ }
+
+ public int Month
+ {
+ get
+ {
+ return FromTicks(Which.Month);
+ }
+ }
+
+ // TODO implement me
+ public static DateTime Now
+ {
+ get
+ {
+ return new DateTime (0);
+ }
+ }
+
+ public int Second
+ {
+ get
+ {
+ return (int) (ticks % TimeSpan.TicksPerMinute / TimeSpan.TicksPerSecond);
+ }
+ }
+
+ public long Ticks
+ {
+ get
+ {
+ return ticks ;
+ }
+ }
+
+ public TimeSpan TimeOfDay
+ {
+ get
+ {
+ return new TimeSpan(ticks % TimeSpan.TicksPerDay );
+ }
+
+ }
+
+ //TODO implement
+ public static DateTime Today
+ {
+ get
+ {
+ return new DateTime (0);
+ }
+ }
+
+ //TODO implement
+ public static DateTime UtcNow
+ {
+ get {
+ return new DateTime (0);
+ }
+ }
+
+ public int Year
+ {
+ get
+ {
+ return FromTicks(Which.Year);
+ }
+ }
+
+ /* methods */
+
+ public DateTime Add (TimeSpan ts)
+ {
+ long newticks ;
+
+ newticks = ticks + ts.Ticks ;
+
+ if (ts.Ticks < MinTicks || ts.Ticks > MaxTicks ||
+ newticks < MinTicks || newticks > MaxTicks)
+ throw new ArgumentException ();
+
+ return new DateTime (newticks);
+ }
+
+ public DateTime AddDays (double days)
+ {
+ return AddMilliseconds (days * 86400000);
+ }
+
+ public DateTime AddTicks (long t)
+ {
+ long newticks = ticks + t;
+
+ if (t<MinTicks || t>MaxTicks || newticks<MinTicks || newticks>MaxTicks)
+ throw new ArgumentException ();
+
+ return new DateTime(newticks);
+ }
+
+ public DateTime AddHours (double hours)
+ {
+ return AddMilliseconds (hours * 3600000);
+ }
+
+ public DateTime AddMilliseconds (double ms)
+ {
+ long msticks, newticks;
+
+ msticks = (long) (ms += ms > 0 ? 0.5 : -0.5) * TimeSpan.TicksPerMillisecond ;
+ newticks = ticks + msticks ;
+
+ if (msticks < MinTicks || msticks > MaxTicks ||
+ newticks < MinTicks || newticks > MaxTicks)
+ throw new ArgumentException ();
+
+ return new DateTime (newticks);
+ }
+
+ public DateTime AddMinutes (double minutes)
+ {
+ return AddMilliseconds (minutes * 60000);
+ }
+
+ public DateTime AddMonths (int months)
+ {
+ int day, month, year, maxday ;
+ DateTime temp ;
+
+ day = this.Day;
+ month = this.Month + (months % 12);
+ year = this.Year + months/12 ;
+
+ if (month < 1)
+ {
+ month = 12 + month ;
+ year -- ;
+ }
+ else if (month>12)
+ {
+ month = month -12;
+ year ++;
+ }
+ maxday = DaysInMonth(year, month);
+ if (day > maxday)
+ day = maxday;
+
+ temp = new DateTime (year, month, day);
+ return temp.Add (this.TimeOfDay);
+ }
+
+ public DateTime AddSeconds (double seconds)
+ {
+ return AddMilliseconds (seconds*1000);
+ }
+
+ public DateTime AddYears (int years )
+ {
+ return AddMonths(years * 12);
+ }
+
+ public static int Compare (DateTime t1, DateTime t2)
+ {
+ if (t1.ticks < t2.ticks)
+ return -1;
+ else if (t1.ticks > t2.ticks)
+ return 1;
+ else
+ return 0;
+ }
+
+ public int CompareTo (object v)
+ {
+ if ( v == null)
+ return 1 ;
+
+ if (!(v is System.DateTime))
+ throw new ArgumentException ("Value is not a System.DateTime");
+
+ return Compare (this , (DateTime) v);
+ }
+
+ public static int DaysInMonth (int year, int month)
+ {
+ int[] days ;
+
+ if (month < 1 || month >12)
+ throw new ArgumentOutOfRangeException ();
+
+ days = (IsLeapYear(year) ? daysmonthleap : daysmonth);
+ return days[month];
+ }
+
+ public override bool Equals (object o)
+ {
+ if (!(o is System.DateTime))
+ return false;
+
+ return ((DateTime) o).ticks == ticks;
+ }
+
+ public static bool Equals (DateTime t1, DateTime t2 )
+ {
+ return (t1.ticks == t2.ticks );
+ }
+
+ // TODO: Implement me.
+ public static DateTime FromFileTime (long fileTime)
+ {
+ return new DateTime (0);
+ }
+
+ // TODO: Implement me.
+ public static DateTime FromOADate (double d)
+ {
+ return new DateTime(0);
+ }
+
+ // TODO: Implement me.
+ public string[] GetDateTimeFormats()
+ {
+ return null;
+ }
+
+ //TODO: implement me
+ public string[] GetDateTimeFormats( char format )
+ {
+ return null;
+ }
+
+ // TODO: implement me
+ public string[] GetDateTimeFormats( IFormatProvider provider)
+ {
+ return null;
+ }
+
+ //TODO: implement me
+ public string[] GetDateTimeFormats(char format,IFormatProvider provider )
+ {
+ return null;
+ }
+
+ public override int GetHashCode ()
+ {
+ return (int) ticks;
+ }
+
+ public TypeCode GetTypeCode ()
+ {
+ return TypeCode.DateTime;
+ }
+
+ public static bool IsLeapYear (int year)
+ {
+ return ( (year % 4 == 0 && year % 100 != 0) || year % 400 == 0) ;
+ }
+
+ public static DateTime Parse (string s)
+ {
+ // TODO: Implement me
+ return new DateTime (0);
+ }
+
+ public static DateTime Parse (string s, IFormatProvider fp)
+ {
+ // TODO: Implement me
+ return new DateTime (0);
+ }
+
+ public static DateTime Parse (string s, NumberStyles style, IFormatProvider fp)
+ {
+ // TODO: Implement me
+ return new DateTime (0);
+ }
+
+ public static DateTime ParseExact(string s, string format, IFormatProvider provider )
+ {
+ // TODO: Implement me
+ return new DateTime (0);
+ }
+
+ public static DateTime ParseExact(string s, string format, IFormatProvider provider, DateTimeStyles style )
+ {
+ // TODO: Implement me
+ return new DateTime (0);
+
+ }
+
+ public static DateTime ParseExact( string s, string[] formats, IFormatProvider provider, DateTimeStyles style )
+ {
+ // TODO: Implement me
+ return new DateTime (0);
+
+ }
+
+ public TimeSpan Subtract(DateTime dt )
+ {
+ return new TimeSpan(ticks - dt.ticks );
+ }
+
+ public DateTime Subtract(TimeSpan ts)
+ {
+ return new DateTime(ticks - ts.Ticks );
+ }
+
+ public long ToFileTime()
+ {
+ // TODO: Implement me
+ return 0 ;
+ }
+
+ public DateTime ToLocalTime()
+ {
+ // TODO Implement me
+ return new DateTime (0);
+ }
+
+ public string ToLongDateString()
+ {
+ // TODO implement me
+ return "ToLongDateString";
+ }
+
+ public string ToLongTimeString()
+ {
+ // TODO implement me
+ return "ToLongTimeString";
+ }
+
+ public double ToOADate()
+ {
+ // TODO implement me
+ return 0;
+ }
+
+ public string ToShortDateString()
+ {
+ // TODO implement me
+ return "ToShortDateString";
+ }
+
+ public string ToShortTimeString()
+ {
+ // TODO implement me
+ return "ToShortTimeString";
+ }
+
+ public override string ToString ()
+ {
+ // TODO: Implement me
+ return "" ;
+ }
+
+ public string ToString (IFormatProvider fp)
+ {
+ // TODO: Implement me.
+ return "ToString1";
+ }
+
+ public string ToString (string format)
+ {
+ // TODO: Implement me.
+ return "ToString2";
+ }
+
+ public string ToString (string format, IFormatProvider fp)
+ {
+ // TODO: Implement me.
+ return "" ;
+ }
+
+ public DateTime ToUniversalTime()
+ {
+ // TODO: implement me
+ return new DateTime(0);
+ }
+
+ /* OPERATORS */
+
+ public static DateTime operator +(DateTime d, TimeSpan t)
+ {
+ return new DateTime (d.ticks + t.Ticks);
+ }
+
+ public static bool operator ==(DateTime d1, DateTime d2)
+ {
+ return (d1.ticks == d2.ticks);
+ }
+
+ public static bool operator >(DateTime t1,DateTime t2)
+ {
+ return (t1.ticks > t2.ticks);
+ }
+
+ public static bool operator >=(DateTime t1,DateTime t2)
+ {
+ return (t1.ticks >= t2.ticks);
+ }
+
+ public static bool operator !=(DateTime d1, DateTime d2)
+ {
+ return (d1.ticks != d2.ticks);
+ }
+
+ public static bool operator <(DateTime t1, DateTime t2)
+ {
+ return (t1.ticks < t2.ticks );
+ }
+
+ public static bool operator <=(DateTime t1,DateTime t2)
+ {
+ return (t1.ticks <= t2.ticks);
+ }
+
+ public static TimeSpan operator -(DateTime d1,DateTime d2)
+ {
+ return new TimeSpan(d1.ticks - d2.ticks);
+ }
+
+ public static DateTime operator -(DateTime d,TimeSpan t )
+ {
+ return new DateTime (d.ticks - t.Ticks);
+ }
+
+ public bool ToBoolean(IFormatProvider provider)
+ {
+ throw new InvalidCastException();
+ }
+
+ public byte ToByte(IFormatProvider provider)
+ {
+ throw new InvalidCastException();
+ }
+
+ public char ToChar(IFormatProvider provider)
+ {
+ throw new InvalidCastException();
+ }
+
+ // TODO Implement me
+ public System.DateTime ToDateTime(IFormatProvider provider)
+ {
+ return new System.DateTime(this.ticks);
+ }
+
+ public decimal ToDecimal(IFormatProvider provider)
+ {
+ throw new InvalidCastException();
+ }
+
+ public double ToDouble(IFormatProvider provider)
+ {
+ throw new InvalidCastException();
+ }
+
+ public Int16 ToInt16(IFormatProvider provider)
+ {
+ throw new InvalidCastException();
+ }
+
+ public Int32 ToInt32(IFormatProvider provider)
+ {
+ throw new InvalidCastException();
+ }
+
+ public Int64 ToInt64(IFormatProvider provider)
+ {
+ throw new InvalidCastException();
+ }
+
+ public SByte ToSByte(IFormatProvider provider)
+ {
+ throw new InvalidCastException();
+ }
+
+ public Single ToSingle(IFormatProvider provider)
+ {
+ throw new InvalidCastException();
+ }
+
+ public object ToType(Type conversionType,IFormatProvider provider)
+ {
+ throw new InvalidCastException();
+ }
+
+ UInt16 System.IConvertible.ToUInt16(IFormatProvider provider)
+ {
+ throw new InvalidCastException();
+ }
+
+ public UInt32 ToUInt32(IFormatProvider provider)
+ {
+ throw new InvalidCastException();
+ }
+
+ public UInt64 ToUInt64(IFormatProvider provider)
+ {
+ throw new InvalidCastException();
+ }
+ }
+}
+
+namespace System
+{
+ public enum DayOfWeek
+ {
+ Sunday,
+ Monday,
+ Tuesday,
+ Wednesday,
+ Thursday,
+ Friday,
+ Saturday
+ }
+}
+
diff --git a/mcs/class/corlib/System/Delegate.cs b/mcs/class/corlib/System/Delegate.cs
new file mode 100644
index 00000000000..9ae80635285
--- /dev/null
+++ b/mcs/class/corlib/System/Delegate.cs
@@ -0,0 +1,96 @@
+//
+// System.Delegate.cs
+//
+// Author:
+// Miguel de Icaza (miguel@ximian.com)
+//
+// (C) Ximian, Inc. http://www.ximian.com
+//
+// TODO: Mucho left to implement
+//
+
+using System;
+using System.Runtime.Serialization;
+
+namespace System {
+
+ public abstract class Delegate : ICloneable, ISerializable {
+ protected Type target_type;
+ protected object target;
+ protected string method;
+
+ protected Delegate (object target, string method)
+ {
+ if (target == null)
+ throw new ArgumentNullException ("Target object is null");
+
+ if (method == null)
+ throw new ArgumentNullException ("method name is null");
+
+ this.target_type = null;
+ this.target = target;
+ this.method = method;
+ }
+
+ protected Delegate (Type target_type, string method)
+ {
+ if (target == null)
+ throw new ArgumentNullException ("Target type is null");
+
+ if (method == null)
+ throw new ArgumentNullException ("method string is null");
+
+ this.target_type = target_type;
+ this.target = null;
+ this.method = method;
+ }
+
+#if NOTYET
+ public MethodInfo Method {
+ get {
+ return null;
+ }
+ }
+#endif
+
+ public object Target {
+ get {
+ return target;
+ }
+ }
+
+
+ //
+ // Methods
+ //
+
+ public abstract object Clone ();
+
+ public override bool Equals (object o)
+ {
+ if (!(o is System.Delegate))
+ return false;
+
+ Delegate d = (Delegate) o;
+
+ if ((d.target_type == target_type) &&
+ (d.target == target) &&
+ (d.method == method))
+ return true;
+
+ return false;
+ }
+
+ public override int GetHashCode ()
+ {
+ return method.GetHashCode ();
+ }
+
+ // This is from ISerializable
+ public void GetObjectData (SerializationInfo info, StreamingContext context)
+ {
+ // TODO: IMPLEMENT ME
+ }
+
+ }
+}
diff --git a/mcs/class/corlib/System/DivideByZeroException.cs b/mcs/class/corlib/System/DivideByZeroException.cs
new file mode 100644
index 00000000000..5b94f587222
--- /dev/null
+++ b/mcs/class/corlib/System/DivideByZeroException.cs
@@ -0,0 +1,29 @@
+//
+// System.DivideByZeroException.cs
+//
+// Author:
+// Joe Shaw (joe@ximian.com)
+//
+// (C) 2001 Ximian, Inc. http://www.ximian.com
+//
+
+namespace System {
+
+ public class DivideByZeroException : ArithmeticException {
+ // Constructors
+ public DivideByZeroException ()
+ : base ("Division by zero")
+ {
+ }
+
+ public DivideByZeroException (string message)
+ : base (message)
+ {
+ }
+
+ public DivideByZeroException (string message, Exception inner)
+ : base (message, inner)
+ {
+ }
+ }
+} \ No newline at end of file
diff --git a/mcs/class/corlib/System/Double.cs b/mcs/class/corlib/System/Double.cs
new file mode 100644
index 00000000000..af193760b4b
--- /dev/null
+++ b/mcs/class/corlib/System/Double.cs
@@ -0,0 +1,116 @@
+//
+// System.Double.cs
+//
+// Author:
+// Miguel de Icaza (miguel@ximian.com)
+//
+// (C) Ximian, Inc. http://www.ximian.com
+//
+
+using System.Globalization;
+
+namespace System {
+
+ public struct Double : IComparable, IFormattable { //, IConvertible {
+ public const double Epsilon = 4.9406564584124650e-324;
+ public const double MaxValue = 1.7976931348623157e308;
+ public const double MinValue = -1.7976931348623157e308;
+ public const double NaN = 0.0d / 0.0d;
+ public const double NegativeInfinity = -1.0d / 0.0d;
+ public const double PositiveInfinity = 1.0d / 0.0d;
+
+ // VES needs to know about value. public is workaround
+ // so source will compile
+ public double value;
+
+ public int CompareTo (object v)
+ {
+ if (!(v is System.Double))
+ throw new ArgumentException ("Value is not a System.Double");
+
+ return (int) (value - ((double) v));
+ }
+
+ public override bool Equals (object o)
+ {
+ if (!(o is System.Double))
+ return false;
+
+ return ((double) o) == value;
+ }
+
+ public override int GetHashCode ()
+ {
+ return (int) value;
+ }
+
+ public static bool IsInfinity (double d)
+ {
+ return (d == PositiveInfinity || d == NegativeInfinity);
+ }
+
+ public static bool IsNaN (double d)
+ {
+ return (d != d);
+ }
+
+ public static bool IsNegativeInfinity (double d)
+ {
+ return (d < 0.0d && (d == NegativeInfinity || d == PositiveInfinity));
+ }
+
+ public static bool IsPositiveInfinity (double d)
+ {
+ return (d > 0.0d && (d == NegativeInfinity || d == PositiveInfinity));
+ }
+
+ public static double Parse (string s)
+ {
+ return Parse (s, (NumberStyles.Float | NumberStyles.AllowThousands), null);
+ }
+
+ public static double Parse (string s, IFormatProvider fp)
+ {
+ return Parse (s, (NumberStyles.Float | NumberStyles.AllowThousands), fp);
+ }
+
+ public static double Parse (string s, NumberStyles style)
+ {
+ return Parse (s, style, null);
+ }
+
+ public static double Parse (string s, NumberStyles style, IFormatProvider fp)
+ {
+ // TODO: Implement me
+ return 0;
+ }
+
+ public override string ToString ()
+ {
+ return ToString (null, null);
+ }
+
+ public string ToString (IFormatProvider fp)
+ {
+ return ToString (null, fp);
+ }
+
+ public string ToString (string format)
+ {
+ return ToString (format, null);
+ }
+
+ public string ToString (string format, IFormatProvider fp)
+ {
+ // TODO: Implement me.
+ return "";
+ }
+
+ // =========== IConvertible Methods =========== //
+
+ public TypeCode GetTypeCode ()
+ {
+ return TypeCode.Double;
+ }
+ }
+}
diff --git a/mcs/class/corlib/System/DuplicateWaitObjectException.cs b/mcs/class/corlib/System/DuplicateWaitObjectException.cs
new file mode 100644
index 00000000000..72ccc25483d
--- /dev/null
+++ b/mcs/class/corlib/System/DuplicateWaitObjectException.cs
@@ -0,0 +1,29 @@
+//
+// System.DuplicateWaitObjectException.cs
+//
+// Author:
+// Joe Shaw (joe@ximian.com)
+//
+// (C) 2001 Ximian, Inc. http://www.ximian.com
+//
+
+namespace System {
+
+ public class DuplicateWaitObjectException : ArgumentException {
+ // Constructors
+ public DuplicateWaitObjectException ()
+ : base ("Duplicate objects in argument")
+ {
+ }
+
+ public DuplicateWaitObjectException (string param_name)
+ : base ("Duplicate objects in argument", param_name)
+ {
+ }
+
+ public DuplicateWaitObjectException (string param_name, string message)
+ : base (message, param_name)
+ {
+ }
+ }
+} \ No newline at end of file
diff --git a/mcs/class/corlib/System/Enum.cs b/mcs/class/corlib/System/Enum.cs
new file mode 100644
index 00000000000..fe1452cba7b
--- /dev/null
+++ b/mcs/class/corlib/System/Enum.cs
@@ -0,0 +1,16 @@
+//
+// System.Enum.cs
+//
+// Author:
+// Miguel de Icaza (miguel@ximian.com)
+//
+// (C) Ximian, Inc. http://www.ximian.com
+//
+// TODO: Mucho left to implement.
+//
+
+namespace System {
+
+ public abstract class Enum {
+ }
+}
diff --git a/mcs/class/corlib/System/Environment.cs b/mcs/class/corlib/System/Environment.cs
new file mode 100644
index 00000000000..0c7f35f36a0
--- /dev/null
+++ b/mcs/class/corlib/System/Environment.cs
@@ -0,0 +1,291 @@
+//------------------------------------------------------------------------------
+//
+// System.Environment.cs
+//
+// Copyright (C) 2001 Moonlight Enterprises, All Rights Reserved
+//
+// Author: Jim Richardson, develop@wtfo-guru.com
+// Created: Saturday, August 11, 2001
+//
+//------------------------------------------------------------------------------
+
+using System;
+using System.Diagnostics;
+using System.Collections;
+
+namespace System
+{
+ public sealed class Environment
+ {
+ public enum SpecialFolder
+ { // TODO: Determin if these windoze style folder identifiers
+ // linux counterparts
+ ApplicationData,
+ CommonApplicationData,
+ CommonProgramFiles,
+ Cookies,
+ DesktopDirectory,
+ Favorites,
+ History,
+ InternetCache,
+ LocalApplicationData,
+ Personal,
+ ProgramFiles,
+ Programs,
+ Recent,
+ SendTo,
+ StartMenu,
+ Startup,
+ System,
+ Templates
+ }
+
+ /// <summary>
+ /// Gets the command line for this process
+ /// </summary>
+ public static string CommandLine
+ {
+ get
+ {
+ return null;
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the current directory
+ /// </summary>
+ public static string CurrentDirectory
+ {
+ get
+ {
+ // TODO: needs more research/work/thought
+ return GetEnvironmentVariable("PWD");
+ }
+ set
+ {
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the exit code of this process
+ /// </summary>
+ public static int ExitCode
+ {
+ get
+ {
+ return 0;
+ }
+ set
+ {
+ }
+ }
+
+ /// <summary>
+ /// Gets the name of the local computer
+ /// </summary>
+ public static string MachineName
+ {
+ get
+ { // TODO: needs more research/work/thought
+ return GetEnvironmentVariable("HOSTNAME");
+ }
+ }
+
+ /// <summary>
+ /// Gets the standard new line value
+ /// </summary>
+ public static string NewLine
+ {
+ get
+ {
+ return PlatformSpecific.NewLine;
+ }
+ }
+
+ /// <summary>
+ /// Gets the current OS version information
+ /// </summary>
+ public static OperatingSystem OSVersion
+ {
+ get
+ {
+ return null;
+ }
+ }
+
+ /// <summary>
+ /// Get StackTrace
+ /// </summary>
+ public static string StackTrace
+ {
+ get
+ {
+ return null;
+ }
+ }
+
+ /// <summary>
+ /// Get a fully qualified path to the system directory
+ /// </summary>
+ public static string SystemDirectory
+ {
+ get
+ {
+ return GetFolderPath(SpecialFolder.System);
+ }
+ }
+
+ /// <summary>
+ /// Get the number of milliseconds that have elapsed since the system was booted
+ /// </summary>
+ public static int TickCount
+ {
+ get
+ {
+ return 0;
+ //return getTickCount();
+ }
+ }
+
+ /// <summary>
+ /// Get UserDomainName
+ /// </summary>
+ public static string UserDomainName
+ {
+ get
+ {
+ return null;
+ }
+ }
+
+ /// <summary>
+ /// Gets a flag indicating whether the process is in interactive mode
+ /// </summary>
+ public static bool UserInteractive
+ {
+ get
+ {
+ return false;
+ }
+ }
+
+ /// <summary>
+ /// Get the user name of current process is running under
+ /// </summary>
+ public static string UserName
+ {
+ get
+ {
+ // TODO: needs more research/work/thought
+ string result = GetEnvironmentVariable("USERNAME");
+ if(result == null || result.Equals(string.Empty))
+ {
+ result = GetEnvironmentVariable("USER");
+ }
+ return result;
+ }
+ }
+
+ /// <summary>
+ /// Get the version of an assembly
+ /// </summary>
+ public static Version Version
+ {
+ get
+ {
+ return null;
+ }
+ }
+
+ /// <summary>
+ /// Get the amount of physical memory mapped to process
+ /// </summary>
+ public static long WorkingSet
+ {
+ get
+ {
+ return 0;
+ }
+ }
+
+ public static void Exit(int exitCode)
+ {
+ }
+
+ /// <summary>
+ /// Substitute environment variables in the argument "name"
+ /// </summary>
+ public static string ExpandEnvironmentVariables(string name)
+ {
+ return name;
+ }
+
+ /// <summary>
+ /// Return an array of the command line arguments of the current process
+ /// </summary>
+ public static string[] GetCommandLineArgs()
+ {
+ return null;
+ }
+
+ /// <summary>
+ /// Return a string containing the value of the environment variable identifed by parameter "variable"
+ /// </summary>
+ public static string GetEnvironmentVariable(string variable)
+ {
+ return (string)(getEnvironmentStrings()[variable]);
+ }
+
+ /// <summary>
+ /// Return a set of all environment variables and their values
+ /// </summary>
+
+ public static IDictionary getEnvironmentStrings()
+ {
+ // could cache these in a member variable, but that
+ // wouldn't be very safe because the environment is
+ // dyanamic ya know
+ string strEnv = PlatformSpecific.getEnvironment();
+ char[] delimiter = new char[1];
+ delimiter[0] = '\t';
+ string[] arEnv = strEnv.Split(delimiter);
+ string[] arStr;
+ Hashtable ht = new Hashtable();
+ foreach(string str in arEnv)
+ {
+ delimiter[0] = '=';
+ arStr = str.Split(delimiter, 2);
+ switch(arStr.Length)
+ {
+ case 1:
+ ht.Add(arStr[0], "");
+ break;
+ case 2:
+ ht.Add(arStr[0], arStr[1]);
+ break;
+ default:
+ Debug.Assert(false); // this shouldn't happen
+ break;
+ }
+ }
+ return ht;
+ }
+
+ /// <summary>
+ /// Returns the fully qualified path of the folder specified by the "folder" parameter
+ /// </summary>
+ public static string GetFolderPath(SpecialFolder folder)
+ {
+ return null;
+ }
+
+ /// <summary>
+ /// Returns an array of the logical drives
+ /// </summary>
+ public static string[] GetLogicalDrives()
+ {
+ return null;
+ }
+
+ }
+}
diff --git a/mcs/class/corlib/System/EventArgs.cs b/mcs/class/corlib/System/EventArgs.cs
new file mode 100644
index 00000000000..be0d2be54e9
--- /dev/null
+++ b/mcs/class/corlib/System/EventArgs.cs
@@ -0,0 +1,25 @@
+//------------------------------------------------------------------------------
+//
+// System.EventArgs.cs
+//
+// Copyright (C) 2001 Michael Lambert, All Rights Reserved
+//
+// Author: Michael Lambert, michaellambert@email.com
+// Created: Mon 07/16/2001
+//
+//------------------------------------------------------------------------------
+
+using System;
+
+namespace System {
+
+ public class EventArgs
+ {
+ public static readonly EventArgs Empty = new EventArgs();
+
+ public EventArgs() { }
+ }
+
+} // System
+
+
diff --git a/mcs/class/corlib/System/EventHandler.cs b/mcs/class/corlib/System/EventHandler.cs
new file mode 100644
index 00000000000..407255b604e
--- /dev/null
+++ b/mcs/class/corlib/System/EventHandler.cs
@@ -0,0 +1,16 @@
+//
+// System.EventHandler.cs
+//
+// Author:
+// Miguel de Icaza (miguel@ximian.com)
+//
+// (C) Ximian, Inc. http://www.ximian.com
+//
+
+namespace System {
+
+ public delegate void EventHandler (object sender, EventArgs e);
+
+}
+
+
diff --git a/mcs/class/corlib/System/Exception.cs b/mcs/class/corlib/System/Exception.cs
new file mode 100644
index 00000000000..00994103c41
--- /dev/null
+++ b/mcs/class/corlib/System/Exception.cs
@@ -0,0 +1,137 @@
+//
+// System.Exception.cs
+//
+// Author:
+// Miguel de Icaza (miguel@ximian.com)
+//
+// (C) Ximian, Inc. http://www.ximian.com
+//
+
+using System.Runtime.Serialization;
+using System.Reflection;
+
+namespace System {
+
+ public class Exception : ISerializable {
+ Exception inner_exception;
+ string message;
+ string help_link;
+ string stack_trace = "TODO: implement stack traces";
+ int hresult;
+ private string source;
+
+ public Exception ()
+ {
+ inner_exception = null;
+ message = "";
+ }
+
+ public Exception (string msg)
+ {
+ inner_exception = null;
+ message = msg;
+ }
+
+ protected Exception (SerializationInfo info, StreamingContext sc)
+ {
+ if (info == null){
+ throw new ArgumentNullException ("info");
+ }
+
+ // TODO: Implement the restoration of an Exception
+ // from a stream.
+ }
+
+ public Exception (string msg, Exception e)
+ {
+ inner_exception = e;
+ message = msg;
+ }
+
+ public Exception InnerException {
+ get {
+ return inner_exception;
+ }
+ }
+
+ public string HelpLink {
+ get {
+ return help_link;
+ }
+
+ set {
+ help_link = value;
+ }
+ }
+
+ protected int HResult {
+ get {
+ return hresult;
+ }
+
+ set {
+ hresult = value;
+ }
+ }
+
+ public string Message {
+ get {
+ return message;
+ }
+ }
+
+ public string Source {
+ get {
+ // TODO: if source is null, we must return
+ // the name of the assembly where the error
+ // originated.
+ return source;
+ }
+
+ set {
+ source = value;
+ }
+ }
+
+ public string StackTrace {
+ get {
+ return stack_trace;
+ }
+ }
+
+ public MethodBase TargetSite {
+ get {
+ // TODO: Implement this.
+ return null;
+ }
+ }
+
+ public virtual Exception GetBaseException ()
+ {
+ Exception inner = inner_exception;
+
+ while (inner != null){
+ if (inner.InnerException != null)
+ inner = inner.InnerException;
+ else
+ return inner;
+ }
+
+ return null;
+ }
+
+ public virtual void GetObjectData (SerializationInfo info, StreamingContext context)
+ {
+ // TODO: implement me.
+ }
+
+ public override string ToString ()
+ {
+ return this.GetType ().FullName + "\n" +
+ message +
+ GetBaseException ().GetType ().FullName +
+ stack_trace;
+ }
+ }
+}
+
diff --git a/mcs/class/corlib/System/ExecutionEngineException.cs b/mcs/class/corlib/System/ExecutionEngineException.cs
new file mode 100644
index 00000000000..db1e2b555c7
--- /dev/null
+++ b/mcs/class/corlib/System/ExecutionEngineException.cs
@@ -0,0 +1,29 @@
+//
+// System.ExecutionEngineException.cs
+//
+// Author:
+// Joe Shaw (joe@ximian.com)
+//
+// (C) 2001 Ximian, Inc. http://www.ximian.com
+//
+
+namespace System {
+
+ public sealed class ExecutionEngineException : SystemException {
+ // Constructors
+ public ExecutionEngineException ()
+ : base ("Internal error occurred") // Haha. Nice.
+ {
+ }
+
+ public ExecutionEngineException (string message)
+ : base (message)
+ {
+ }
+
+ public ExecutionEngineException (string message, Exception inner)
+ : base (message, inner)
+ {
+ }
+ }
+} \ No newline at end of file
diff --git a/mcs/class/corlib/System/FlagsAttribute.cs b/mcs/class/corlib/System/FlagsAttribute.cs
new file mode 100755
index 00000000000..26e3525f1d4
--- /dev/null
+++ b/mcs/class/corlib/System/FlagsAttribute.cs
@@ -0,0 +1,26 @@
+//
+// System.FlagsAttribute.cs
+//
+// Author:
+// Miguel de Icaza (miguel@ximian.com)
+//
+// (C) Ximian, Inc. http://www.ximian.com
+//
+
+namespace System {
+
+ /// <summary>
+ /// The FlagsAttribute tags enumerations as bitfields.
+ /// </summary>
+ ///
+ /// <remarks>
+ /// The FlagsAttribute can be used to tag an enumeration to be
+ /// a bit field. This will allow the compiler and visual tools
+ /// to treat the bits in an enumeration as a set of flags.
+ /// </remarks>
+ public class FlagsAttribute : Attribute {
+
+ // No methods.
+
+ }
+}
diff --git a/mcs/class/corlib/System/FormatException.cs b/mcs/class/corlib/System/FormatException.cs
new file mode 100644
index 00000000000..332d50e1b52
--- /dev/null
+++ b/mcs/class/corlib/System/FormatException.cs
@@ -0,0 +1,29 @@
+//
+// System.FormatException.cs
+//
+// Author:
+// Joe Shaw (joe@ximian.com)
+//
+// (C) 2001 Ximian, Inc. http://www.ximian.com
+//
+
+namespace System {
+
+ public class FormatException : SystemException {
+ // Constructors
+ public FormatException ()
+ : base ("Invalid format")
+ {
+ }
+
+ public FormatException (string message)
+ : base (message)
+ {
+ }
+
+ public FormatException (string message, Exception inner)
+ : base (message, inner)
+ {
+ }
+ }
+} \ No newline at end of file
diff --git a/mcs/class/corlib/System/ICloneable.cs b/mcs/class/corlib/System/ICloneable.cs
new file mode 100644
index 00000000000..792550db1f5
--- /dev/null
+++ b/mcs/class/corlib/System/ICloneable.cs
@@ -0,0 +1,15 @@
+//
+// System.ICloneable.cs
+//
+// Author:
+// Miguel de Icaza (miguel@ximian.com)
+//
+// (C) Ximian, Inc. http://www.ximian.com
+//
+
+namespace System {
+
+ public interface ICloneable {
+ object Clone ();
+ }
+}
diff --git a/mcs/class/corlib/System/IComparable.cs b/mcs/class/corlib/System/IComparable.cs
new file mode 100644
index 00000000000..50af10d15e2
--- /dev/null
+++ b/mcs/class/corlib/System/IComparable.cs
@@ -0,0 +1,15 @@
+//
+// System.IComparable.cs
+//
+// Author:
+// Miguel de Icaza (miguel@ximian.com)
+//
+// (C) Ximian, Inc. http://www.ximian.com
+//
+
+namespace System {
+
+ public interface IComparable {
+ int CompareTo (object obj);
+ }
+}
diff --git a/mcs/class/corlib/System/IConvertible.cs b/mcs/class/corlib/System/IConvertible.cs
new file mode 100644
index 00000000000..62fd3d5b942
--- /dev/null
+++ b/mcs/class/corlib/System/IConvertible.cs
@@ -0,0 +1,54 @@
+//
+// System.IConvertible.cs
+//
+// Author:
+// Miguel de Icaza (miguel@ximian.com)
+//
+// (C) Ximian, Inc. http://www.ximian.com
+//
+
+//
+// Functions Implementing this interface should check out
+// System.Convert. Most of these methods are implemented
+// there for all these data types.
+//
+// System.Convert has ToType helper method for the object
+// ToType (Type conversionType, IFormatProvider provider)
+// method. In most cases you can specify your ToType function
+// as calling
+//
+// public Type value; // value of this data type
+// public object ToType(Type conversionType, IFormatProvider provider) {
+// Convert.ToType (value, conversionType, provider);
+// }
+//
+// Which is just a wrapper for your ToType methods.
+//
+// See http://lists.ximian.com/archives/public/mono-list/2001-July/000525.html
+// for more discussion on the topic
+//
+
+namespace System {
+
+ public interface IConvertible {
+
+ TypeCode GetTypeCode ();
+
+ bool ToBoolean (IFormatProvider provider);
+ byte ToByte (IFormatProvider provider);
+ char ToChar (IFormatProvider provider);
+ DateTime ToDateTime (IFormatProvider provider);
+ decimal ToDecimal (IFormatProvider provider);
+ double ToDouble (IFormatProvider provider);
+ short ToInt16 (IFormatProvider provider);
+ int ToInt32 (IFormatProvider provider);
+ long ToInt64 (IFormatProvider provider);
+ sbyte ToSByte (IFormatProvider provider);
+ float ToSingle (IFormatProvider provider);
+ string ToString (IFormatProvider provider);
+ object ToType (Type conversionType, IFormatProvider provider);
+ ushort ToUInt16 (IFormatProvider provider);
+ uint ToUInt32 (IFormatProvider provider);
+ ulong ToUInt64 (IFormatProvider provider);
+ }
+}
diff --git a/mcs/class/corlib/System/ICustomFormatter.cs b/mcs/class/corlib/System/ICustomFormatter.cs
new file mode 100644
index 00000000000..a370647f37f
--- /dev/null
+++ b/mcs/class/corlib/System/ICustomFormatter.cs
@@ -0,0 +1,15 @@
+//
+// System.ICustomFormatter.cs
+//
+// Author:
+// Miguel de Icaza (miguel@ximian.com)
+//
+// (C) Ximian, Inc. http://www.ximian.com
+//
+
+namespace System {
+
+ interface ICustomFormatter {
+ string Format (string format, object arg, IFormatProvider formatProvider);
+ }
+}
diff --git a/mcs/class/corlib/System/IDisposable.cs b/mcs/class/corlib/System/IDisposable.cs
new file mode 100644
index 00000000000..6c3ca1b6367
--- /dev/null
+++ b/mcs/class/corlib/System/IDisposable.cs
@@ -0,0 +1,17 @@
+//
+// System.IDisposable.cs
+//
+// Author:
+// Miguel de Icaza (miguel@ximian.com)
+//
+// (C) Ximian, Inc. http://www.ximian.com
+//
+
+namespace System {
+
+ public interface IDisposable {
+
+ void Dispose ();
+
+ }
+}
diff --git a/mcs/class/corlib/System/IFormatProvider.cs b/mcs/class/corlib/System/IFormatProvider.cs
new file mode 100644
index 00000000000..266c62d1295
--- /dev/null
+++ b/mcs/class/corlib/System/IFormatProvider.cs
@@ -0,0 +1,15 @@
+//
+// System.IFormatProvider.cs
+//
+// Author:
+// Miguel de Icaza (miguel@ximian.com)
+//
+// (C) Ximian, Inc. http://www.ximian.com
+//
+
+namespace System {
+
+ public interface IFormatProvider {
+ object GetFormat (Type format_type);
+ }
+}
diff --git a/mcs/class/corlib/System/IFormattable.cs b/mcs/class/corlib/System/IFormattable.cs
new file mode 100644
index 00000000000..1769f4034c0
--- /dev/null
+++ b/mcs/class/corlib/System/IFormattable.cs
@@ -0,0 +1,15 @@
+//
+// System.IFormattable.cs
+//
+// Author:
+// Miguel de Icaza (miguel@ximian.com)
+//
+// (C) Ximian, Inc. http://www.ximian.com
+//
+
+namespace System {
+
+ public interface IFormattable {
+ string ToString (string format, IFormatProvider format_provider);
+ }
+}
diff --git a/mcs/class/corlib/System/IServiceProvider.cs b/mcs/class/corlib/System/IServiceProvider.cs
new file mode 100644
index 00000000000..c10c880cee2
--- /dev/null
+++ b/mcs/class/corlib/System/IServiceProvider.cs
@@ -0,0 +1,17 @@
+//
+// System.IServiceProvider.cs
+//
+// Author:
+// Miguel de Icaza (miguel@ximian.com)
+//
+// (C) Ximian, Inc. http://www.ximian.com
+//
+
+namespace System {
+
+ public interface IServiceProvider {
+
+ object GetService (Type serviceType);
+
+ }
+}
diff --git a/mcs/class/corlib/System/IndexOutOfRangeException.cs b/mcs/class/corlib/System/IndexOutOfRangeException.cs
new file mode 100644
index 00000000000..62a690bd6ac
--- /dev/null
+++ b/mcs/class/corlib/System/IndexOutOfRangeException.cs
@@ -0,0 +1,29 @@
+//
+// System.IndexOutOfRangeException.cs
+//
+// Author:
+// Joe Shaw (joe@ximian.com)
+//
+// (C) 2001 Ximian, Inc. http://www.ximian.com
+//
+
+namespace System {
+
+ public sealed class IndexOutOfRangeException : SystemException {
+ // Constructors
+ public IndexOutOfRangeException ()
+ : base ("Array index is out of range")
+ {
+ }
+
+ public IndexOutOfRangeException (string message)
+ : base (message)
+ {
+ }
+
+ public IndexOutOfRangeException (string message, Exception inner)
+ : base (message, inner)
+ {
+ }
+ }
+} \ No newline at end of file
diff --git a/mcs/class/corlib/System/Int16.cs b/mcs/class/corlib/System/Int16.cs
new file mode 100644
index 00000000000..c647fa40660
--- /dev/null
+++ b/mcs/class/corlib/System/Int16.cs
@@ -0,0 +1,92 @@
+//
+// System.Int16.cs
+//
+// Author:
+// Miguel de Icaza (miguel@ximian.com)
+//
+// (C) Ximian, Inc. http://www.ximian.com
+//
+
+using System.Globalization;
+
+namespace System {
+
+ public struct Int16 : IComparable, IFormattable { //, IConvertible {
+ public const short MaxValue = 32767;
+ public const short MinValue = -32768;
+
+ // VES needs to know about value. public is workaround
+ // so source will compile
+ public short value;
+
+ public int CompareTo (object v)
+ {
+ if (!(v is System.Int16))
+ throw new ArgumentException ("Value is not a System.Int16");
+
+ return value - ((short) v);
+ }
+
+ public override bool Equals (object o)
+ {
+ if (!(o is System.Int16))
+ return false;
+
+ return ((short) o) == value;
+ }
+
+ public override int GetHashCode ()
+ {
+ return value;
+ }
+
+ public static short Parse (string s)
+ {
+ return Parse (s, NumberStyles.Integer, null);
+ }
+
+ public static short Parse (string s, IFormatProvider fp)
+ {
+ return Parse (s, NumberStyles.Integer, fp);
+ }
+
+ public static short Parse (string s, NumberStyles style)
+ {
+ return Parse (s, style, null);
+ }
+
+ public static short Parse (string s, NumberStyles style, IFormatProvider fp)
+ {
+ // TODO: Implement me
+ return 0;
+ }
+
+ public override string ToString ()
+ {
+ return ToString ("G", null);
+ }
+
+ public string ToString (IFormatProvider fp)
+ {
+ return ToString ("G", fp);
+ }
+
+ public string ToString (string format)
+ {
+ return ToString (format, null);
+ }
+
+ public string ToString (string format, IFormatProvider fp)
+ {
+ // TODO: Implement me.
+ return "";
+ }
+
+ // =========== IConvertible Methods =========== //
+
+ public TypeCode GetTypeCode ()
+ {
+ return TypeCode.Int16;
+ }
+ }
+}
diff --git a/mcs/class/corlib/System/Int32.cs b/mcs/class/corlib/System/Int32.cs
new file mode 100644
index 00000000000..87c714db0aa
--- /dev/null
+++ b/mcs/class/corlib/System/Int32.cs
@@ -0,0 +1,90 @@
+//
+// System.Int32.cs
+//
+// Author:
+// Miguel de Icaza (miguel@ximian.com)
+//
+// (C) Ximian, Inc. http://www.ximian.com
+//
+
+using System.Globalization;
+
+namespace System {
+
+ public struct Int32 : IComparable, IFormattable { //, IConvertible {
+ public const int MaxValue = 0x7fffffff;
+ public const int MinValue = -2147483648;
+
+ public int value;
+
+ public int CompareTo (object v)
+ {
+ if (!(v is System.Int32))
+ throw new ArgumentException ("Value is not a System.Int32");
+
+ return value - (int) v;
+ }
+
+ public override bool Equals (object o)
+ {
+ if (!(o is System.Int32))
+ return false;
+
+ return ((int) o) == value;
+ }
+
+ public override int GetHashCode ()
+ {
+ return value;
+ }
+
+ public static int Parse (string s)
+ {
+ return Parse (s, NumberStyles.Integer, null);
+ }
+
+ public static int Parse (string s, IFormatProvider fp)
+ {
+ return Parse (s, NumberStyles.Integer, fp);
+ }
+
+ public static int Parse (string s, NumberStyles style)
+ {
+ return Parse (s, style, null);
+ }
+
+ public static int Parse (string s, NumberStyles style, IFormatProvider fp)
+ {
+ // TODO: Implement me
+ return 0;
+ }
+
+ public override string ToString ()
+ {
+ return ToString ("G", null);
+ }
+
+ public string ToString (IFormatProvider fp)
+ {
+ return ToString ("G", fp);
+ }
+
+ public string ToString (string format)
+ {
+ return ToString (format, null);
+ }
+
+ public string ToString (string format, IFormatProvider fp)
+ {
+ // TODO: Implement me.
+ return "";
+ }
+
+ // =========== IConvertible Methods =========== //
+
+ public TypeCode GetTypeCode ()
+ {
+ return TypeCode.Int32;
+ }
+ }
+}
diff --git a/mcs/class/corlib/System/Int64.cs b/mcs/class/corlib/System/Int64.cs
new file mode 100644
index 00000000000..3af2fe6cdd8
--- /dev/null
+++ b/mcs/class/corlib/System/Int64.cs
@@ -0,0 +1,96 @@
+//
+// System.Int64.cs
+//
+// Author:
+// Miguel de Icaza (miguel@ximian.com)
+//
+// (C) Ximian, Inc. http://www.ximian.com
+//
+
+using System.Globalization;
+
+namespace System {
+
+ public struct Int64 : IComparable, IFormattable { //, IConvertible {
+ public const long MaxValue = 0x7fffffffffffffff;
+ public const long MinValue = -9223372036854775808;
+
+ public long value;
+
+ public int CompareTo (object v)
+ {
+ if (!(v is System.Int64))
+ throw new ArgumentException ("Value is not a System.Int64");
+
+ if (value == (long) v)
+ return 0;
+
+ if (value < (long) v)
+ return -1;
+
+ return 1;
+ }
+
+ public override bool Equals (object o)
+ {
+ if (!(o is System.Int64))
+ return false;
+
+ return ((long) o) == value;
+ }
+
+ public override int GetHashCode ()
+ {
+ return (int)(value & 0xffffffff) ^ (int)(value >> 32);
+ }
+
+ public static long Parse (string s)
+ {
+ return Parse (s, NumberStyles.Integer, null);
+ }
+
+ public static long Parse (string s, IFormatProvider fp)
+ {
+ return Parse (s, NumberStyles.Integer, fp);
+ }
+
+ public static long Parse (string s, NumberStyles style)
+ {
+ return Parse (s, style, null);
+ }
+
+ public static long Parse (string s, NumberStyles style, IFormatProvider fp)
+ {
+ // TODO: Implement me
+ return 0;
+ }
+
+ public override string ToString ()
+ {
+ return ToString ("G", null);
+ }
+
+ public string ToString (IFormatProvider fp)
+ {
+ return ToString ("G", fp);
+ }
+
+ public string ToString (string format)
+ {
+ return ToString (format, null);
+ }
+
+ public string ToString (string format, IFormatProvider fp)
+ {
+ // TODO: Implement me.
+ return "";
+ }
+
+ // =========== IConvertible Methods =========== //
+
+ public TypeCode GetTypeCode ()
+ {
+ return TypeCode.Int64;
+ }
+ }
+}
diff --git a/mcs/class/corlib/System/IntPtr.cs b/mcs/class/corlib/System/IntPtr.cs
new file mode 100644
index 00000000000..47c6e245351
--- /dev/null
+++ b/mcs/class/corlib/System/IntPtr.cs
@@ -0,0 +1,129 @@
+//
+// System.IntPtr.cs
+//
+// Author:
+// Miguel de Icaza (miguel@ximian.com)
+//
+// (C) Ximian, Inc. http://www.ximian.com
+//
+// FIXME: How do you specify a native int in C#? I am going to have to do some figuring out
+//
+using System;
+using System.Runtime.Serialization;
+
+namespace System {
+
+ public struct IntPtr : ISerializable {
+
+ unsafe public void *value;
+
+ public static IntPtr Zero;
+
+ unsafe static IntPtr ()
+ {
+ Zero.value = (void *) 0;
+ }
+
+ unsafe public IntPtr (int i32)
+ {
+ value = (void *) i32;
+ }
+
+ unsafe public IntPtr (long i64)
+ {
+ value = (void *) i64;
+ }
+
+ unsafe public IntPtr (void *ptr)
+ {
+ value = ptr;
+ }
+
+ unsafe public static int Size {
+ get {
+ return sizeof (void *);
+ }
+ }
+
+ public void GetObjectData (SerializationInfo si, StreamingContext sc)
+ {
+ // FIXME: Implement me.
+ }
+
+ unsafe public override bool Equals (object o)
+ {
+ if (!(o is System.IntPtr))
+ return false;
+
+ return ((IntPtr) o).value == value;
+ }
+
+ unsafe public override int GetHashCode ()
+ {
+ return (int) value;
+ }
+
+ unsafe public int ToInt32 ()
+ {
+ return (int) value;
+ }
+
+ unsafe public long ToInt64 ()
+ {
+ return (long) value;
+ }
+
+ unsafe public void *ToPointer ()
+ {
+ return value;
+ }
+
+ unsafe override public string ToString ()
+ {
+ if (Size == 4)
+ return ((int) value).ToString ();
+ else
+ return ((long) value).ToString ();
+ }
+
+ unsafe public static bool operator == (IntPtr a, IntPtr b)
+ {
+ return (a.value == b.value);
+ }
+
+ unsafe public static bool operator != (IntPtr a, IntPtr b)
+ {
+ return (a.value != b.value);
+ }
+
+ unsafe public static explicit operator IntPtr (int value)
+ {
+ return new IntPtr (value);
+ }
+
+ unsafe public static explicit operator IntPtr (long value)
+ {
+ return new IntPtr (value);
+ }
+
+ unsafe public static explicit operator IntPtr (void *value)
+ {
+ return new IntPtr (value);
+ }
+
+ unsafe public static explicit operator int (IntPtr value)
+ {
+ return (int) value.value;
+ }
+
+ unsafe public static explicit operator long (IntPtr value)
+ {
+ return (long) value.value;
+ }
+
+ unsafe public static explicit operator void * (IntPtr value)
+ {
+ return value.value;
+ }
+ }
+}
diff --git a/mcs/class/corlib/System/InvalidCastException.cs b/mcs/class/corlib/System/InvalidCastException.cs
new file mode 100644
index 00000000000..23989794e71
--- /dev/null
+++ b/mcs/class/corlib/System/InvalidCastException.cs
@@ -0,0 +1,29 @@
+//
+// System.InvalidCastException.cs
+//
+// Author:
+// Joe Shaw (joe@ximian.com)
+//
+// (C) 2001 Ximian, Inc. http://www.ximian.com
+//
+
+namespace System {
+
+ public class InvalidCastException : SystemException {
+ // Constructors
+ public InvalidCastException ()
+ : base ("Cannot cast from source type to destination type")
+ {
+ }
+
+ public InvalidCastException (string message)
+ : base (message)
+ {
+ }
+
+ public InvalidCastException (string message, Exception inner)
+ : base (message, inner)
+ {
+ }
+ }
+} \ No newline at end of file
diff --git a/mcs/class/corlib/System/InvalidOperationException.cs b/mcs/class/corlib/System/InvalidOperationException.cs
new file mode 100644
index 00000000000..c57029a110b
--- /dev/null
+++ b/mcs/class/corlib/System/InvalidOperationException.cs
@@ -0,0 +1,29 @@
+//
+// System.InvalidOperationException.cs
+//
+// Author:
+// Joe Shaw (joe@ximian.com)
+//
+// (C) 2001 Ximian, Inc. http://www.ximian.com
+//
+
+namespace System {
+
+ public class InvalidOperationException : SystemException {
+ // Constructors
+ public InvalidOperationException ()
+ : base ("The requested operation cannot be performed")
+ {
+ }
+
+ public InvalidOperationException (string message)
+ : base (message)
+ {
+ }
+
+ public InvalidOperationException (string message, Exception inner)
+ : base (message, inner)
+ {
+ }
+ }
+} \ No newline at end of file
diff --git a/mcs/class/corlib/System/InvalidProgramException.cs b/mcs/class/corlib/System/InvalidProgramException.cs
new file mode 100644
index 00000000000..88150558cc5
--- /dev/null
+++ b/mcs/class/corlib/System/InvalidProgramException.cs
@@ -0,0 +1,29 @@
+//
+// System.InvalidProgramException.cs
+//
+// Author:
+// Joe Shaw (joe@ximian.com)
+//
+// (C) 2001 Ximian, Inc. http://www.ximian.com
+//
+
+namespace System {
+
+ public sealed class InvalidProgramException : SystemException {
+ // Constructors
+ public InvalidProgramException ()
+ : base ("Metadata is incorrect")
+ {
+ }
+
+ public InvalidProgramException (string message)
+ : base (message)
+ {
+ }
+
+ public InvalidProgramException (string message, Exception inner)
+ : base (message, inner)
+ {
+ }
+ }
+} \ No newline at end of file
diff --git a/mcs/class/corlib/System/MarshalByRefObject.cs b/mcs/class/corlib/System/MarshalByRefObject.cs
new file mode 100644
index 00000000000..57b916194ba
--- /dev/null
+++ b/mcs/class/corlib/System/MarshalByRefObject.cs
@@ -0,0 +1,31 @@
+//
+// System.MarshalByRefObject.cs
+//
+// Author:
+// Miguel de Icaza (miguel@ximian.com)
+//
+// (C) Ximian, Inc. http://www.ximian.com
+//
+
+using System.Runtime.Remoting;
+
+namespace System {
+
+ public abstract class MarshalByRefObject {
+
+ public virtual ObjRef CreateObjRef (Type type)
+ {
+ return null;
+ }
+
+ public object GetLifeTimeService ()
+ {
+ return null;
+ }
+
+ public virtual object InitializeLifeTimeService ()
+ {
+ return null;
+ }
+ }
+}
diff --git a/mcs/class/corlib/System/Math.cs b/mcs/class/corlib/System/Math.cs
new file mode 100644
index 00000000000..08e86e2ba19
--- /dev/null
+++ b/mcs/class/corlib/System/Math.cs
@@ -0,0 +1,311 @@
+//
+// System.Math.cs
+//
+// Author:
+// Bob Smith (bob@thestuff.net)
+//
+// (C) 2001 Bob Smith. http://www.thestuff.net
+//
+
+using System;
+using System.Runtime.InteropServices;
+
+namespace System
+{
+ public sealed class Math
+ {
+ public const double E = 2.7182818284590452354;
+ public const double PI = 3.14159265358979323846;
+ public static decimal Abs(decimal value)
+ {
+ return (value < 0)? -value: value;
+ }
+ public static double Abs(double value)
+ {
+ return (value < 0)? -value: value;
+ }
+ public static float Abs(float value)
+ {
+ return (value < 0)? -value: value;
+ }
+ public static int Abs(int value)
+ {
+ if (value == Int32.MinValue)
+ throw new OverflowException("Value is too small.");
+ return (value < 0)? -value: value;
+ }
+ public static long Abs(long value)
+ {
+ if (value == Int64.MinValue)
+ throw new OverflowException("Value is too small.");
+ return (value < 0)? -value: value;
+ }
+ public static sbyte Abs(sbyte value)
+ {
+ if (value == SByte.MinValue)
+ throw new OverflowException("Value is too small.");
+ return (sbyte)((value < 0)? -value: value);
+ }
+ public static short Abs(short value)
+ {
+ if (value == Int16.MinValue)
+ throw new OverflowException("Value is too small.");
+ return (short)((value < 0)? -value: value);
+ }
+ [ DllImport("libm", EntryPoint="acos") ]
+ private extern static double _Acos(double d);
+ public static double Acos(double d)
+ {
+ if (d < -1 || d > 1) return Double.NaN;
+ return Math._Acos(d);
+ }
+ [ DllImport("libm", EntryPoint="asin") ]
+ private extern static double _Asin(double d);
+ public static double Asin(double d)
+ {
+ if (d < -1 || d > 1) return Double.NaN;
+ return Math._Asin(d);
+ }
+ [ DllImport("libm", EntryPoint="atan") ]
+ public extern static double Atan(double d);
+ [ DllImport("libm", EntryPoint="atan2") ]
+ public extern static double Atan2(double y, double x);
+ public static double Ceiling(double a)
+ {
+ double b = (double)((long)a);
+ return (b < a)? b+1: b;
+ }
+ [ DllImport("libm", EntryPoint="cos") ]
+ public extern static double Cos(double d);
+ [ DllImport("libm", EntryPoint="cosh") ]
+ public extern static double Cosh(double value);
+ [ DllImport("libm", EntryPoint="exp") ]
+ public extern static double Exp(double d);
+ public static double Floor(double d) {
+ return (double)((long)d) ;
+ }
+ public static double IEEERemainder(double x, double y)
+ {
+ double r;
+ if (y == 0) return Double.NaN;
+ r = x - (y * Math.Round(x/y));
+ if (r != 0) return r;
+ return (x > 0)? 0: -0;
+ }
+ [ DllImport("libm", EntryPoint="log") ]
+ private extern static double _Log(double d);
+ public static double Log(double d)
+ {
+ if (d == 0) return Double.NegativeInfinity;
+ else if (d < 0) return Double.NaN;
+ return Math._Log(d);
+ }
+ public static double Log(double a, double newBase)
+ {
+ if (a == 0) return Double.NegativeInfinity;
+ else if (a < 0) return Double.NaN;
+ return Math._Log(a)/Math._Log(newBase);
+ }
+ [ DllImport("libm", EntryPoint="log10") ]
+ private extern static double _Log10(double d);
+ public static double Log10(double d)
+ {
+ if (d == 0) return Double.NegativeInfinity;
+ else if (d < 0) return Double.NaN;
+ return Math._Log10(d);
+ }
+ public static byte Max(byte val1, byte val2)
+ {
+ return (val1 > val2)? val1: val2;
+ }
+ public static decimal Max(decimal val1, decimal val2)
+ {
+ return (val1 > val2)? val1: val2;
+ }
+ public static double Max(double val1, double val2)
+ {
+ return (val1 > val2)? val1: val2;
+ }
+ public static float Max(float val1, float val2)
+ {
+ return (val1 > val2)? val1: val2;
+ }
+ public static int Max(int val1, int val2)
+ {
+ return (val1 > val2)? val1: val2;
+ }
+ public static long Max(long val1, long val2)
+ {
+ return (val1 > val2)? val1: val2;
+ }
+ public static sbyte Max(sbyte val1, sbyte val2)
+ {
+ return (val1 > val2)? val1: val2;
+ }
+ public static short Max(short val1, short val2)
+ {
+ return (val1 > val2)? val1: val2;
+ }
+ public static uint Max(uint val1, uint val2)
+ {
+ return (val1 > val2)? val1: val2;
+ }
+ public static ulong Max(ulong val1, ulong val2)
+ {
+ return (val1 > val2)? val1: val2;
+ }
+ public static ushort Max(ushort val1, ushort val2)
+ {
+ return (val1 > val2)? val1: val2;
+ }
+ public static byte Min(byte val1, byte val2)
+ {
+ return (val1 < val2)? val1: val2;
+ }
+ public static decimal Min(decimal val1, decimal val2)
+ {
+ return (val1 < val2)? val1: val2;
+ }
+ public static double Min(double val1, double val2)
+ {
+ return (val1 < val2)? val1: val2;
+ }
+ public static float Min(float val1, float val2)
+ {
+ return (val1 < val2)? val1: val2;
+ }
+ public static int Min(int val1, int val2)
+ {
+ return (val1 < val2)? val1: val2;
+ }
+ public static long Min(long val1, long val2)
+ {
+ return (val1 < val2)? val1: val2;
+ }
+ public static sbyte Min(sbyte val1, sbyte val2)
+ {
+ return (val1 < val2)? val1: val2;
+ }
+ public static short Min(short val1, short val2)
+ {
+ return (val1 < val2)? val1: val2;
+ }
+ public static uint Min(uint val1, uint val2)
+ {
+ return (val1 < val2)? val1: val2;
+ }
+ public static ulong Min(ulong val1, ulong val2)
+ {
+ return (val1 < val2)? val1: val2;
+ }
+ public static ushort Min(ushort val1, ushort val2)
+ {
+ return (val1 < val2)? val1: val2;
+ }
+ [ DllImport("libm", EntryPoint="pow") ]
+ public extern static double Pow(double x, double y);
+ public static decimal Round(decimal d)
+ {
+ decimal r = (decimal)((long)d);
+ decimal a = d-r;
+ if (a > .5M) return ++r;
+ else if (a <.5M) return r;
+ else
+ {
+ if (r%2 == 0) return r;
+ else return ++r;
+ }
+ }
+ public static decimal Round(decimal d, int decimals)
+ {
+ long p = 10;
+ int c;
+ decimal retval = d;
+ if (decimals < 0 || decimals > 15)
+ throw new ArgumentOutOfRangeException("Value is too small or too big.");
+ else if (decimals == 0)
+ return Math.Round(d);
+ for (c=0; c<decimals; c++) p*=10;
+ retval*=p;
+ retval=Math.Round(retval);
+ retval/=p;
+ return retval;
+ }
+ public static double Round(double d)
+ {
+ double r = (double)((long)d);
+ double a = d-r;
+ if (a > .5) return ++r;
+ else if (a <.5) return r;
+ else
+ {
+ if (r%2 == 0) return r;
+ else return ++r;
+ }
+ }
+ public static double Round(double value, int digits) {
+ long p = 10;
+ int c;
+ double retval = value;
+ if (digits < 0 || digits > 15)
+ throw new ArgumentOutOfRangeException("Value is too small or too big.");
+ else if (digits == 0)
+ return Math.Round(value);
+ for (c=0; c<digits; c++) p*=10;
+ retval*=p;
+ retval=Math.Round(retval);
+ retval/=p;
+ return retval;
+ }
+ public static int Sign(decimal value)
+ {
+ if (value > 0) return 1;
+ return (value == 0)? 0: -1;
+ }
+ public static int Sign(double value)
+ {
+ if (value > 0) return 1;
+ return (value == 0)? 0: -1;
+ }
+ public static int Sign(float value)
+ {
+ if (value > 0) return 1;
+ return (value == 0)? 0: -1;
+ }
+ public static int Sign(int value)
+ {
+ if (value > 0) return 1;
+ return (value == 0)? 0: -1;
+ }
+ public static int Sign(long value)
+ {
+ if (value > 0) return 1;
+ return (value == 0)? 0: -1;
+ }
+ public static int Sign(sbyte value)
+ {
+ if (value > 0) return 1;
+ return (value == 0)? 0: -1;
+ }
+ public static int Sign(short value)
+ {
+ if (value > 0) return 1;
+ return (value == 0)? 0: -1;
+ }
+ [ DllImport("libm", EntryPoint="sin") ]
+ public extern static double Sin(double a);
+ [ DllImport("libm", EntryPoint="sinh") ]
+ public extern static double Sinh(double value);
+ [ DllImport("libm", EntryPoint="sqrt") ]
+ private extern static double _Sqrt(double d);
+ public static double Sqrt(double d)
+ {
+ if (d < 0) return Double.NaN;
+ return Math._Sqrt(d);
+ }
+ [ DllImport("libm", EntryPoint="tan") ]
+ public extern static double Tan(double a);
+ [ DllImport("libm", EntryPoint="tanh") ]
+ public extern static double Tanh(double value);
+ }
+}
diff --git a/mcs/class/corlib/System/MulticastDelegate.cs b/mcs/class/corlib/System/MulticastDelegate.cs
new file mode 100644
index 00000000000..41a2dec7087
--- /dev/null
+++ b/mcs/class/corlib/System/MulticastDelegate.cs
@@ -0,0 +1,52 @@
+//
+// System.MultiCastDelegate.cs
+//
+// Author:
+// Miguel de Icaza (miguel@ximian.com)
+//
+// (C) Ximian, Inc. http://www.ximian.com
+//
+// TODO: Mucho left to implement.
+//
+
+namespace System {
+
+ public abstract class MulticastDelegate : Delegate {
+
+ protected MulticastDelegate (object target, string method)
+ : base (target, method)
+ {
+ }
+
+ protected MulticastDelegate (Type target_type, string method)
+ : base (target_type, method)
+ {
+ }
+
+#if NOTYET
+ public MethodInfo Method {
+ get {
+ return null;
+ }
+ }
+#endif
+
+ //
+ // Methods
+ //
+ public override bool Equals (object o)
+ {
+ if (!(o is System.MulticastDelegate))
+ return false;
+
+ return base.Equals (o);
+ }
+
+ public override int GetHashCode ()
+ {
+ return base.GetHashCode ();
+ }
+
+
+ }
+}
diff --git a/mcs/class/corlib/System/MulticastNotSupportedException.cs b/mcs/class/corlib/System/MulticastNotSupportedException.cs
new file mode 100644
index 00000000000..02d2a7900c6
--- /dev/null
+++ b/mcs/class/corlib/System/MulticastNotSupportedException.cs
@@ -0,0 +1,29 @@
+//
+// System.MulticastNotSupportedException.cs
+//
+// Author:
+// Joe Shaw (joe@ximian.com)
+//
+// (C) 2001 Ximian, Inc. http://www.ximian.com
+//
+
+namespace System {
+
+ public sealed class MulticastNotSupportedException : SystemException {
+ // Constructors
+ public MulticastNotSupportedException ()
+ : base ("This operation cannot be performed with the specified delagates")
+ {
+ }
+
+ public MulticastNotSupportedException (string message)
+ : base (message)
+ {
+ }
+
+ public MulticastNotSupportedException (string message, Exception inner)
+ : base (message, inner)
+ {
+ }
+ }
+} \ No newline at end of file
diff --git a/mcs/class/corlib/System/NotFiniteNumberException.cs b/mcs/class/corlib/System/NotFiniteNumberException.cs
new file mode 100644
index 00000000000..f460a356033
--- /dev/null
+++ b/mcs/class/corlib/System/NotFiniteNumberException.cs
@@ -0,0 +1,49 @@
+//
+// System.NotFiniteNumberException.cs
+//
+// Author:
+// Joe Shaw (joe@ximian.com)
+//
+// (C) 2001 Ximian, Inc. http://www.ximian.com
+//
+
+namespace System {
+
+ public class NotFiniteNumberException : ArithmeticException {
+ double offending_number;
+
+ // Constructors
+ public NotFiniteNumberException ()
+ : base ("The number encountered was not a finite quantity")
+ {
+ }
+
+ public NotFiniteNumberException (double offending_number)
+ {
+ this.offending_number = offending_number;
+ }
+
+ public NotFiniteNumberException (string message)
+ : base (message)
+ {
+ }
+
+ public NotFiniteNumberException (string message, double offending_number)
+ {
+ this.offending_number = offending_number;
+ }
+
+ public NotFiniteNumberException (string message, double offending_number, Exception inner)
+ : base (message, inner)
+ {
+ this.offending_number = offending_number;
+ }
+
+ // Properties
+ public virtual double OffendingNumber {
+ get {
+ return offending_number;
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/mcs/class/corlib/System/NotSupportedException.cs b/mcs/class/corlib/System/NotSupportedException.cs
new file mode 100644
index 00000000000..8a6078a9396
--- /dev/null
+++ b/mcs/class/corlib/System/NotSupportedException.cs
@@ -0,0 +1,29 @@
+//
+// System.NotSupportedException.cs
+//
+// Author:
+// Joe Shaw (joe@ximian.com)
+//
+// (C) 2001 Ximian, Inc. http://www.ximian.com
+//
+
+namespace System {
+
+ public class NotSupportedException : SystemException {
+ // Constructors
+ public NotSupportedException ()
+ : base ("Operation is not supported")
+ {
+ }
+
+ public NotSupportedException (string message)
+ : base (message)
+ {
+ }
+
+ public NotSupportedException (string message, Exception inner)
+ : base (message, inner)
+ {
+ }
+ }
+} \ No newline at end of file
diff --git a/mcs/class/corlib/System/NullReferenceException.cs b/mcs/class/corlib/System/NullReferenceException.cs
new file mode 100644
index 00000000000..5f712bbb09d
--- /dev/null
+++ b/mcs/class/corlib/System/NullReferenceException.cs
@@ -0,0 +1,29 @@
+//
+// System.NullReferenceException.cs
+//
+// Author:
+// Joe Shaw (joe@ximian.com)
+//
+// (C) 2001 Ximian, Inc. http://www.ximian.com
+//
+
+namespace System {
+
+ public class NullReferenceException : SystemException {
+ // Constructors
+ public NullReferenceException ()
+ : base ("A null value was found where an object instance was required")
+ {
+ }
+
+ public NullReferenceException (string message)
+ : base (message)
+ {
+ }
+
+ public NullReferenceException (string message, Exception inner)
+ : base (message, inner)
+ {
+ }
+ }
+} \ No newline at end of file
diff --git a/mcs/class/corlib/System/Object.cs b/mcs/class/corlib/System/Object.cs
new file mode 100644
index 00000000000..4b01425433d
--- /dev/null
+++ b/mcs/class/corlib/System/Object.cs
@@ -0,0 +1,111 @@
+//
+// System.Object.cs
+//
+// Author:
+// Miguel de Icaza (miguel@ximian.com)
+//
+// (C) Ximian, Inc. http://www.ximian.com
+//
+// This should probably be implemented in IL instead of C#, to
+// use internalcalls to get its hands on the underlying Type
+// of an object.
+//
+
+using System.Runtime.CompilerServices;
+
+namespace System {
+
+ public class Object {
+
+ // <summary>
+ // Compares this object to the specified object.
+ // Returns true if they are equal, false otherwise.
+ // </summary>
+ public virtual bool Equals (object o)
+ {
+ return this == o;
+ }
+
+ // <summary>
+ // Compares two objects for equality
+ // </summary>
+ public static bool Equals (object a, object b)
+ {
+ if (a == null) {
+ if (b == null)
+ return true;
+ return false;
+ } else {
+ if (b == null)
+ return false;
+ return a.Equals (b);
+ }
+ }
+
+ // <summary>
+ // Initializes a new instance of the object class.
+ // </summary>
+ public Object ()
+ {
+ }
+
+ // <summary>
+ // Object destructor.
+ // </summary>
+ ~Object ()
+ {
+ }
+
+ // <summary>
+ // Returns a hashcode for this object. Each derived
+ // class should return a hash code that makes sense
+ // for that particular implementation of the object.
+ // </summary>
+ public virtual int GetHashCode ()
+ {
+ return 0;
+ }
+
+ // <summary>
+ // Returns the Type associated with the object.
+ // </summary>
+ public Type GetType ()
+ {
+ // TODO: This probably needs to be tied up
+ // with the Type system. Private communications
+ // channel?
+ // Type is abstract, so the following line won't cut it.
+ //return new Type ();
+ return null;
+ }
+
+ // <summary>
+ // Shallow copy of the object.
+ // </summary>
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ protected extern object MemberwiseClone ();
+
+ // <summary>
+ // Returns a stringified representation of the object.
+ // This is not supposed to be used for user presentation,
+ // use Format() for that and IFormattable.
+ //
+ // ToString is mostly used for debugging purposes.
+ // </summary>
+ public virtual string ToString ()
+ {
+ return GetType().FullName;
+ }
+
+ // <summary>
+ // Tests whether a is equal to b.
+ // Can not figure out why this even exists
+ // </summary>
+ public static bool ReferenceEquals (object a, object b)
+ {
+ return (a == b);
+ }
+
+
+ }
+}
diff --git a/mcs/class/corlib/System/OperatingSystem.cs b/mcs/class/corlib/System/OperatingSystem.cs
new file mode 100644
index 00000000000..bc5b0c4ccca
--- /dev/null
+++ b/mcs/class/corlib/System/OperatingSystem.cs
@@ -0,0 +1,104 @@
+//------------------------------------------------------------------------------
+//
+// System.OperatingSystem.cs
+//
+// Copyright (C) 2001 Moonlight Enterprises, All Rights Reserved
+//
+// Author: Jim Richardson, develop@wtfo-guru.com
+// Created: Saturday, August 11, 2001
+//
+//------------------------------------------------------------------------------
+
+using System;
+
+namespace System
+{
+ /// <summary>
+ /// Class representing a specific operating system version for a specific platform
+ /// </summary>
+ public sealed class OperatingSystem : ICloneable
+ {
+ private System.PlatformID itsPlatform;
+ private Version itsVersion;
+
+ public OperatingSystem(PlatformID platform, Version version)
+ {
+ if(version == null)
+ {
+ throw new ArgumentNullException();
+ }
+
+ itsPlatform = platform;
+ itsVersion = version;
+ }
+
+ /// <summary>
+ /// Get the PlatformID
+ /// </summary>
+ public PlatformID Platform
+ {
+ get
+ {
+ return itsPlatform;
+ }
+ }
+
+ /// <summary>
+ /// Gets the version object
+ /// </summary>
+ public Version Version
+ {
+ get
+ {
+ return itsVersion;
+ }
+ }
+
+ /// <summary>
+ /// Return a clone of this object
+ /// </summary>
+ public object Clone()
+ {
+ return new OperatingSystem(itsPlatform, itsVersion);
+ }
+
+ /// <summary>
+ /// Return true if obj equals this object
+ /// </summary>
+ public override bool Equals(object obj)
+ {
+ //Check for null and compare run-time types.
+ if (obj == null || GetType() != obj.GetType()) return false;
+ OperatingSystem os = (OperatingSystem)obj;
+ return (itsPlatform == os.itsPlatform) &&
+ (os.itsVersion.Equals(itsVersion));
+ }
+
+ /// <summary>
+ /// Return hash code
+ /// </summary>
+ public override int GetHashCode()
+ { // this leave us enuf for 256 unique platforms which should suffice for a good while
+ return ((int)itsPlatform << 24) | itsVersion.GetHashCode() >> 8;
+ }
+
+ /// <summary>
+ /// Return a string reprentation of this instance
+ /// </summary>
+ public override string ToString()
+ {
+ string str;
+
+ switch(itsPlatform)
+ {
+ case System.PlatformID.Win32NT: str = "Microsoft Windows NT"; break;
+ case System.PlatformID.Win32S: str = "Microsoft Win32S"; break;
+ case System.PlatformID.Win32Windows: str = "Microsoft Windows 98"; break;
+ case System.PlatformID.Linux86Redhat: str = "Redhat Linux"; break;
+ default: str = "<unknown>"; break;
+ }
+
+ return str + " " + itsVersion.ToString();
+ }
+ }
+}
diff --git a/mcs/class/corlib/System/OutOfMemoryException.cs b/mcs/class/corlib/System/OutOfMemoryException.cs
new file mode 100644
index 00000000000..0889cf0b114
--- /dev/null
+++ b/mcs/class/corlib/System/OutOfMemoryException.cs
@@ -0,0 +1,29 @@
+//
+// System.OutOfMemoryException.cs
+//
+// Author:
+// Joe Shaw (joe@ximian.com)
+//
+// (C) 2001 Ximian, Inc. http://www.ximian.com
+//
+
+namespace System {
+
+ public class OutOfMemoryException : SystemException {
+ // Constructors
+ public OutOfMemoryException ()
+ : base ("There is insufficient memory to continue execution")
+ {
+ }
+
+ public OutOfMemoryException (string message)
+ : base (message)
+ {
+ }
+
+ public OutOfMemoryException (string message, Exception inner)
+ : base (message, inner)
+ {
+ }
+ }
+}
diff --git a/mcs/class/corlib/System/OverflowException.cs b/mcs/class/corlib/System/OverflowException.cs
new file mode 100644
index 00000000000..5bee3b461a5
--- /dev/null
+++ b/mcs/class/corlib/System/OverflowException.cs
@@ -0,0 +1,29 @@
+//
+// System.OverflowExceptionException.cs
+//
+// Author:
+// Joe Shaw (joe@ximian.com)
+//
+// (C) 2001 Ximian, Inc. http://www.ximian.com
+//
+
+namespace System {
+
+ public class OverflowExceptionException : ArithmeticException {
+ // Constructors
+ public OverflowExceptionException ()
+ : base ("Number overflow")
+ {
+ }
+
+ public OverflowExceptionException (string message)
+ : base (message)
+ {
+ }
+
+ public OverflowExceptionException (string message, Exception inner)
+ : base (message, inner)
+ {
+ }
+ }
+} \ No newline at end of file
diff --git a/mcs/class/corlib/System/ParamArrayAttribute.cs b/mcs/class/corlib/System/ParamArrayAttribute.cs
new file mode 100644
index 00000000000..9b56a5daa59
--- /dev/null
+++ b/mcs/class/corlib/System/ParamArrayAttribute.cs
@@ -0,0 +1,18 @@
+//
+// System.ParamArrayAttribute.cs
+//
+// Author:
+// Miguel de Icaza (miguel@ximian.com)
+//
+// (C) Ximian, Inc. http://www.ximian.com
+//
+
+namespace System {
+
+ public abstract class ParamArrayAttribute {
+
+ public ParamArrayAttribute ()
+ {
+ }
+ }
+}
diff --git a/mcs/class/corlib/System/PlatformID.cs b/mcs/class/corlib/System/PlatformID.cs
new file mode 100644
index 00000000000..8a8a6f0b52d
--- /dev/null
+++ b/mcs/class/corlib/System/PlatformID.cs
@@ -0,0 +1,26 @@
+//------------------------------------------------------------------------------
+//
+// System.PlatformID.cs
+//
+// Copyright (C) 2001 Moonlight Enterprises, All Rights Reserved
+//
+// Author: Jim Richardson, develop@wtfo-guru.com
+// Created: Saturday, August 13, 2001
+//
+//------------------------------------------------------------------------------
+
+
+namespace System
+{
+ public enum PlatformID
+ { // TODO: determine what definitions to incorporate
+ // possibilities are quite varied
+ // my redhat example is just an idea that
+ // can / will be determined at a later date
+ // I chose Redhat as an ex since that is the distro I am familiar with
+ Win32NT,
+ Win32S,
+ Win32Windows,
+ Linux86Redhat
+ }
+} \ No newline at end of file
diff --git a/mcs/class/corlib/System/Random.cs b/mcs/class/corlib/System/Random.cs
new file mode 100644
index 00000000000..aae46c34f81
--- /dev/null
+++ b/mcs/class/corlib/System/Random.cs
@@ -0,0 +1,70 @@
+//
+// System.Random.cs
+//
+// Author:
+// Bob Smith (bob@thestuff.net)
+//
+// (C) 2001 Bob Smith. http://www.thestuff.net
+//
+
+using System;
+
+namespace System
+{
+ public class Random
+ {
+ private int S = 1;
+ private const int A = 16807;
+ private const int M = 2147483647;
+ private const int Q = 127773;
+ private const int R = 2836;
+ public Random()
+ {
+ S = (int)(DateTime.Now.Ticks);
+ }
+ public Random(int Seed)
+ {
+ S = Seed;
+ }
+ public virtual int Next()
+ {
+ return (int)(this.Sample()*Int32.MaxValue);
+ }
+ public virtual int Next(int maxValue)
+ {
+ if (maxValue < 0)
+ throw new ArgumentOutOfRangeException("Max value is less then min value.");
+ else if (maxValue == 0)
+ return 0;
+ return (int)(this.Sample()*maxValue);
+ }
+ public virtual int Next(int minValue, int maxValue)
+ {
+ if (minValue > maxValue)
+ throw new ArgumentOutOfRangeException("Min value is greater then max value.");
+ else if (minValue == maxValue)
+ return minValue;
+ return (int)(this.Sample()*maxValue)+minValue;
+ }
+ public virtual void NextBytes(byte[] buffer)
+ {
+ int i, l;
+ if (buffer == null)
+ throw new ArgumentNullException();
+ l = buffer.GetUpperBound(0);
+ for (i = buffer.GetLowerBound(0); i < l; i++)
+ {
+ buffer[i] = (byte)(this.Sample()*Byte.MaxValue);
+ }
+ }
+ public virtual double NextDouble()
+ {
+ return this.Sample();
+ }
+ protected virtual double Sample(){
+ S=A*(S%Q)-R*(S/Q);
+ if(S<0) S+=M;
+ return S/(double)Int32.MaxValue;
+ }
+ }
+}
diff --git a/mcs/class/corlib/System/RankException.cs b/mcs/class/corlib/System/RankException.cs
new file mode 100644
index 00000000000..5eb3709d4ac
--- /dev/null
+++ b/mcs/class/corlib/System/RankException.cs
@@ -0,0 +1,29 @@
+//
+// System.RankException.cs
+//
+// Author:
+// Joe Shaw (joe@ximian.com)
+//
+// (C) 2001 Ximian, Inc. http://www.ximian.com
+//
+
+namespace System {
+
+ public class RankException : SystemException {
+ // Constructors
+ public RankException ()
+ : base ("Two arrays must have the same number of dimensions")
+ {
+ }
+
+ public RankException (string message)
+ : base (message)
+ {
+ }
+
+ public RankException (string message, Exception inner)
+ : base (message, inner)
+ {
+ }
+ }
+} \ No newline at end of file
diff --git a/mcs/class/corlib/System/RuntimeTypeHandle.cs b/mcs/class/corlib/System/RuntimeTypeHandle.cs
new file mode 100644
index 00000000000..6ce46a99e26
--- /dev/null
+++ b/mcs/class/corlib/System/RuntimeTypeHandle.cs
@@ -0,0 +1,31 @@
+//
+// System.RuntimeTypeHandle.cs
+//
+// Author:
+// Miguel de Icaza (miguel@ximian.com)
+//
+// (C) Ximian, Inc. http://www.ximian.com
+//
+
+using System.Runtime.Serialization;
+
+namespace System {
+
+ // FIXME: Implement me!
+ public struct RuntimeTypeHandle : ISerializable {
+ IntPtr value;
+
+ public IntPtr Value {
+ get {
+ return (IntPtr) value;
+ }
+ }
+
+ // This is from ISerializable
+ public void GetObjectData (SerializationInfo info, StreamingContext context)
+ {
+ // TODO: IMPLEMENT ME.
+ }
+
+ }
+}
diff --git a/mcs/class/corlib/System/SByte.cs b/mcs/class/corlib/System/SByte.cs
new file mode 100644
index 00000000000..258dff58012
--- /dev/null
+++ b/mcs/class/corlib/System/SByte.cs
@@ -0,0 +1,92 @@
+//
+// System.SByte.cs
+//
+// Author:
+// Miguel de Icaza (miguel@ximian.com)
+//
+// (C) Ximian, Inc. http://www.ximian.com
+//
+
+using System.Globalization;
+
+namespace System {
+
+ public struct SByte : IComparable, IFormattable { //, IConvertible {
+ public const sbyte MinValue = -128;
+ public const sbyte MaxValue = 127;
+
+ // VES needs to know about value. public is workaround
+ // so source will compile
+ public sbyte value;
+
+ public int CompareTo (object v)
+ {
+ if (!(v is System.SByte))
+ throw new ArgumentException ("Value is not a System.SByte");
+
+ return value - ((sbyte) v);
+ }
+
+ public override bool Equals (object o)
+ {
+ if (!(o is System.SByte))
+ return false;
+
+ return ((sbyte) o) == value;
+ }
+
+ public override int GetHashCode ()
+ {
+ return value;
+ }
+
+ public static sbyte Parse (string s)
+ {
+ return Parse (s, NumberStyles.Integer, null);
+ }
+
+ public static sbyte Parse (string s, IFormatProvider fp)
+ {
+ return Parse (s, NumberStyles.Integer, fp);
+ }
+
+ public static sbyte Parse (string s, NumberStyles style)
+ {
+ return Parse (s, style, null);
+ }
+
+ public static sbyte Parse (string s, NumberStyles style, IFormatProvider fp)
+ {
+ // TODO: Implement me
+ return 0;
+ }
+
+ public override string ToString ()
+ {
+ return ToString ("G", null);
+ }
+
+ public string ToString (IFormatProvider fp)
+ {
+ return ToString ("G", fp);
+ }
+
+ public string ToString (string format)
+ {
+ return ToString (format, null);
+ }
+
+ public string ToString (string format, IFormatProvider fp)
+ {
+ // TODO: Implement me.
+ return "";
+ }
+
+ // =========== ICovnertible Methods =========== //
+
+ public TypeCode GetTypeCode ()
+ {
+ return TypeCode.Byte;
+ }
+ }
+}
diff --git a/mcs/class/corlib/System/Single.cs b/mcs/class/corlib/System/Single.cs
new file mode 100644
index 00000000000..cb898bdeb98
--- /dev/null
+++ b/mcs/class/corlib/System/Single.cs
@@ -0,0 +1,116 @@
+//
+// System.Single.cs
+//
+// Author:
+// Miguel de Icaza (miguel@ximian.com)
+//
+// (C) Ximian, Inc. http://www.ximian.com
+//
+
+using System.Globalization;
+
+namespace System {
+
+ public struct Single : IComparable, IFormattable { //, IConvertible {
+ public const float Epsilon = 1.4e-45f;
+ public const float MaxValue = 3.40282346638528859e38f;
+ public const float MinValue = -3.40282346638528859e38f;
+ public const float NaN = 0.0f / 0.0f;
+ public const float PositiveInfinity = 1.0f / 0.0f;
+ public const float NegativeInfinity = -1.0f / 0.0f;
+
+ // VES needs to know about value. public is workaround
+ // so source will compile
+ public float value;
+
+ public int CompareTo (object v)
+ {
+ if (!(v is System.Single))
+ throw new ArgumentException ("Value is not a System.Single");
+
+ return (int) (value - ((float) v));
+ }
+
+ public override bool Equals (object o)
+ {
+ if (!(o is System.Single))
+ return false;
+
+ return ((float) o) == value;
+ }
+
+ public override int GetHashCode ()
+ {
+ return (int) value;
+ }
+
+ public static bool IsInfinity (float f)
+ {
+ return (f == PositiveInfinity || f == NegativeInfinity);
+ }
+
+ public static bool IsNaN (float f)
+ {
+ return (f != f);
+ }
+
+ public static bool IsNegativeInfinity (float f)
+ {
+ return (f < 0.0f && (f == NegativeInfinity || f == PositiveInfinity));
+ }
+
+ public static bool IsPositiveInfinity (float f)
+ {
+ return (f > 0.0f && (f == NegativeInfinity || f == PositiveInfinity));
+ }
+
+ public static float Parse (string s)
+ {
+ return Parse (s, (NumberStyles.Float | NumberStyles.AllowThousands), null);
+ }
+
+ public static float Parse (string s, IFormatProvider fp)
+ {
+ return Parse (s, (NumberStyles.Float | NumberStyles.AllowThousands), fp);
+ }
+
+ public static float Parse (string s, NumberStyles style)
+ {
+ return Parse (s, style, null);
+ }
+
+ public static float Parse (string s, NumberStyles style, IFormatProvider fp)
+ {
+ // TODO: Implement me
+ return 0;
+ }
+
+ public override string ToString ()
+ {
+ return ToString(null, null);
+ }
+
+ public string ToString (IFormatProvider fp)
+ {
+ return ToString(null, fp);
+ }
+
+ public string ToString (string format)
+ {
+ return ToString(format, null);
+ }
+
+ public string ToString (string format, IFormatProvider fp)
+ {
+ // TODO: Implement me.
+ return "";
+ }
+
+ // ============= IConvertible Methods ============ //
+
+ public TypeCode GetTypeCode ()
+ {
+ return TypeCode.Single;
+ }
+ }
+}
diff --git a/mcs/class/corlib/System/StackOverflowException.cs b/mcs/class/corlib/System/StackOverflowException.cs
new file mode 100644
index 00000000000..f389346d6f8
--- /dev/null
+++ b/mcs/class/corlib/System/StackOverflowException.cs
@@ -0,0 +1,29 @@
+//
+// System.StackOverflowException.cs
+//
+// Author:
+// Joe Shaw (joe@ximian.com)
+//
+// (C) 2001 Ximian, Inc. http://www.ximian.com
+//
+
+namespace System {
+
+ public class StackOverflowException : SystemException {
+ // Constructors
+ public StackOverflowException ()
+ : base ("The requested operation caused a stack overflow")
+ {
+ }
+
+ public StackOverflowException (string message)
+ : base (message)
+ {
+ }
+
+ public StackOverflowException (string message, Exception inner)
+ : base (message, inner)
+ {
+ }
+ }
+} \ No newline at end of file
diff --git a/mcs/class/corlib/System/String.cs b/mcs/class/corlib/System/String.cs
new file mode 100644
index 00000000000..a42fc811ee8
--- /dev/null
+++ b/mcs/class/corlib/System/String.cs
@@ -0,0 +1,1622 @@
+// -*- Mode: C++; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+//
+// System.String.cs
+//
+// Author:
+// Jeffrey Stedfast (fejj@ximian.com)
+//
+// (C) 2001 Ximian, Inc. http://www.ximian.com
+//
+
+// FIXME: from what I gather from msdn, when a function is to return an empty string
+// we should be returning this.Empty - some methods do this and others don't.
+
+// FIXME: I didn't realise until later that `string' has a .Length method and so
+// I am missing some proper bounds-checking in some methods. Find these
+// instances and throw the ArgumentOutOfBoundsException at the programmer.
+// I like pelting programmers with ArgumentOutOfBoundsException's :-)
+
+// FIXME: The ToLower(), ToUpper(), and Compare(..., bool ignoreCase) methods
+// need to be made unicode aware.
+
+// FIXME: when you have a char carr[], does carr.Length include the terminating null char?
+
+using System;
+using System.Text;
+using System.Collections;
+using System.Globalization;
+
+namespace System {
+
+ public sealed class String : IComparable, ICloneable, IConvertible, IEnumerable {
+ public static readonly string Empty = "";
+ private char[] c_str;
+ private int length;
+
+ // Constructors
+ unsafe public String (char *value)
+ {
+ int i;
+
+ // FIXME: can I do value.Length here?
+ if (value == null) {
+ this.length = 0;
+ } else {
+ for (i = 0; *(value + i) != '\0'; i++);
+ this.length = i;
+ }
+
+ this.c_str = new char [this.length + 1];
+ for (i = 0; i < this.length; i++)
+ this.c_str[i] = *(value + i);
+ this.c_str[i] = '\0';
+ }
+
+ public String (char[] value)
+ {
+ int i;
+
+ // FIXME: value.Length includes the terminating null char?
+ this.length = value != null ? strlen (value): 0;
+ this.c_str = new char [this.length + 1];
+ for (i = 0; i < this.length; i++)
+ this.c_str[i] = value[i];
+ this.c_str[i] = '\0';
+ }
+
+ unsafe public String (sbyte *value)
+ {
+ // FIXME: consider unicode?
+ int i;
+
+ // FIXME: can I do value.Length here? */
+ if (value == null) {
+ this.length = 0;
+ } else {
+ for (i = 0; *(value + i) != '\0'; i++);
+ this.length = i;
+ }
+
+ this.c_str = new char [this.length + 1];
+ for (i = 0; i < this.length; i++)
+ this.c_str[i] = (char) *(value + i);
+ this.c_str[i] = '\0';
+ }
+
+ public String (char c, int count)
+ {
+ int i;
+
+ this.length = count;
+ this.c_str = new char [count + 1];
+ for (i = 0; i < count; i++)
+ this.c_str[i] = c;
+ this.c_str[i] = '\0';
+ }
+
+ unsafe public String (char *value, int startIndex, int length)
+ {
+ int i;
+
+ if (value == null && startIndex != 0 && length != 0)
+ throw new ArgumentNullException ();
+
+ if (startIndex < 0 || length < 0)
+ throw new ArgumentOutOfRangeException ();
+
+ this.length = length;
+ this.c_str = new char [length + 1];
+ for (i = 0; i < length; i++)
+ this.c_str[i] = *(value + startIndex + i);
+ this.c_str[i] = '\0';
+ }
+
+ public String (char[] value, int startIndex, int length)
+ {
+ int i;
+
+ if (value == null && startIndex != 0 && length != 0)
+ throw new ArgumentNullException ();
+
+ if (startIndex < 0 || length < 0)
+ throw new ArgumentOutOfRangeException ();
+
+ this.length = length;
+ this.c_str = new char [length + 1];
+ for (i = 0; i < length; i++)
+ this.c_str[i] = value[startIndex + i];
+ this.c_str[i] = '\0';
+ }
+
+ unsafe public String (sbyte *value, int startIndex, int length)
+ {
+ // FIXME: consider unicode?
+ int i;
+
+ if (value == null && startIndex != 0 && length != 0)
+ throw new ArgumentNullException ();
+
+ if (startIndex < 0 || length < 0)
+ throw new ArgumentOutOfRangeException ();
+
+ this.length = length;
+ this.c_str = new char [length + 1];
+ for (i = 0; i < length; i++)
+ this.c_str[i] = (char) *(value + startIndex + i);
+ this.c_str[i] = '\0';
+ }
+
+ unsafe public String (sbyte *value, int startIndex, int length, Encoding enc)
+ {
+ // FIXME: implement me
+ }
+
+ ~String ()
+ {
+ // FIXME: is there anything we need to do here?
+ /*base.Finalize ();*/
+ }
+
+ // Properties
+ public int Length {
+ get {
+ return this.length;
+ }
+ }
+
+ // FIXME: is this correct syntax??
+ public char this [int index] {
+ get {
+ if (index > this.length)
+ throw new ArgumentOutOfRangeException ();
+
+ return this.c_str[index];
+ }
+ }
+
+ // Private helper methods
+ private static int strlen (char[] str)
+ {
+ // FIXME: if str.Length includes terminating null char, then return (str.Length - 1)
+ return str.Length;
+ }
+
+ private static char tolowerordinal (char c)
+ {
+ // FIXME: implement me
+ return c;
+ }
+
+ private static bool is_lwsp (char c)
+ {
+ /* this comes from the msdn docs for String.Trim() */
+ if ((c >= '\x9' && c <= '\xD') || c == '\x20' || c == '\xA0' ||
+ (c >= '\x2000' && c <= '\x200B') || c == '\x3000' || c == '\xFEFF')
+ return true;
+ else
+ return false;
+ }
+#if XXX
+ unsafe private static int BoyerMoore (char[] haystack, char[] needle, int startIndex, int count)
+ {
+ /* (hopefully) Unicode-safe Boyer-Moore implementation */
+ uint[] skiptable = new uint[65536]; /* our unicode-safe skip-table */
+ char *he_ptr;
+ char *ne_ptr; /* end-of-string pointers */
+ char *hc_ptr;
+ char *nc_ptr; /* compare pointers */
+ char *h_ptr;
+ char *the_ptr; /* haystack pointers */
+ int h_len, n_len, n, i;
+
+ if (haystack == null || needle == null)
+ throw new ArgumentNullException ();
+
+ h_len = count;
+ n_len = strlen (needle);
+
+ /* if the search buffer is shorter than the pattern buffer, we can't match */
+ if (h_len < n_len)
+ return -1;
+
+ /* return an instant match if the pattern is 0-length */
+ if (n_len == 0)
+ return startIndex;
+
+ /* set a pointer at the end of each string */
+ ne_ptr = needle + n_len - 1; /* point to char before '\0' */
+ he_ptr = haystack + startIndex + count; /* point to last valid char */
+
+ /* init the skip table with the pattern length */
+ for (i = 0; i < 65536; i++)
+ skiptable[i] = n_len;
+
+ /* set the skip value for the chars that *do* appear in the
+ * pattern buffer (needle) to the distance from the index to
+ * the end of the pattern buffer. */
+ for (nc_ptr = needle; nc_ptr < ne_ptr; nc_ptr++)
+ skiptable[(uint) *nc_ptr] = ne_ptr - nc_ptr;
+
+ h_ptr = haystack + startIndex;
+ while (h_len >= n_len) {
+ the_ptr = h_ptr + n_len - 1; /* set the temp haystack end pointer */
+ hc_ptr = h_ptr + n_len - 1; /* set the haystack compare pointer */
+ nc_ptr = ne_ptr; /* set the needle compare pointer */
+
+ /* work our way backwards until they don't match */
+ for (i = 0; nc_ptr > needle; nc_ptr--, hc_ptr--, i++)
+ if (*nc_ptr != *hc_ptr)
+ break;
+
+ if (*nc_ptr != *hc_ptr) {
+ n = skiptable[(uint) *hc_ptr] - i;
+ h_ptr += n;
+ h_len -= n;
+ } else
+ return h_ptr - haystack;
+ }
+
+ return -1;
+ }
+#endif
+ // Methods
+ public object Clone ()
+ {
+ // FIXME: implement me
+ return null;
+ }
+
+ public static int Compare (string strA, string strB)
+ {
+ int i;
+
+ /* Does this remind anyone of the nautilus string.h wrappers? ;-) */
+ if (strA == null) {
+ if (strB == null)
+ return 0;
+ else
+ return -1;
+ } else if (strB == null)
+ return 1;
+
+ for (i = 0; strA[i] == strB[i] && strA[i] != '\0'; i++);
+
+ return ((int) (strA[i] - strB[i]));
+ }
+
+ public static int Compare (string strA, string strB, bool ignoreCase)
+ {
+ int i;
+
+ if (!ignoreCase)
+ return Compare (strA, strB);
+
+ /*
+ * And here I thought Eazel developers were on crack...
+ * if a string is null it should pelt the programmer with
+ * ArgumentNullExceptions, damnit!
+ */
+ if (strA == null) {
+ if (strB == null)
+ return 0;
+ else
+ return -1;
+ } else if (strB == null)
+ return 1;
+
+ for (i = 0; strA[i] != '\0' && strB[i] != '\0'; i++) {
+ if (Char.ToLower (strA[i]) != Char.ToLower (strB[i]))
+ break;
+ }
+
+ return ((int) (strA[i] - strB[i]));
+ }
+
+ public static int Compare (string strA, string strB, bool ignoreCase, CultureInfo culture)
+ {
+ // FIXME: implement me
+ return 0;
+ }
+
+ public static int Compare (string strA, int indexA, string strB, int indexB, int length)
+ {
+ int i;
+
+ if (length < 0 || indexA < 0 || indexB < 0)
+ throw new ArgumentOutOfRangeException ();
+
+ if (indexA > strA.Length || indexB > strB.Length)
+ throw new ArgumentOutOfRangeException ();
+
+ /* And again with the ("" > null) logic... lord have mercy! */
+ if (strA == null) {
+ if (strB == null)
+ return 0;
+ else
+ return -1;
+ } else if (strB == null)
+ return 1;
+
+ for (i = 0; i < length - 1; i++) {
+ if (strA[indexA + i] != strB[indexB + i])
+ break;
+ }
+
+ return ((int) (strA[indexA + i] - strB[indexB + i]));
+ }
+
+ public static int Compare (string strA, int indexA, string strB, int indexB,
+ int length, bool ignoreCase)
+ {
+ int i;
+
+ if (!ignoreCase)
+ return Compare (strA, indexA, strB, indexB, length);
+
+ if (length < 0 || indexA < 0 || indexB < 0)
+ throw new ArgumentOutOfRangeException ();
+
+ if (indexA > strA.Length || indexB > strB.Length)
+ throw new ArgumentOutOfRangeException ();
+
+ /* When will the hurting stop!?!? */
+ if (strA == null) {
+ if (strB == null)
+ return 0;
+ else
+ return -1;
+ } else if (strB == null)
+ return 1;
+
+ for (i = 0; i < length - 1; i++) {
+ if (Char.ToLower (strA[indexA + i]) != Char.ToLower (strB[indexB + i]))
+ break;
+ }
+
+ return ((int) (strA[indexA + i] - strB[indexB + i]));
+ }
+
+ public static int Compare (string strA, int indexA, string strB, int indexB,
+ int length, bool ignoreCase, CultureInfo culture)
+ {
+ if (culture == null)
+ throw new ArgumentNullException ();
+
+ if (length < 0 || indexA < 0 || indexB < 0)
+ throw new ArgumentOutOfRangeException ();
+
+ if (indexA > strA.Length || indexB > strB.Length)
+ throw new ArgumentOutOfRangeException ();
+
+ /* I can't take it anymore! */
+ if (strA == null) {
+ if (strB == null)
+ return 0;
+ else
+ return -1;
+ } else if (strB == null)
+ return 1;
+ // FIXME: implement me
+ return 0;
+ }
+
+ public static int CompareOrdinal (string strA, string strB)
+ {
+ int i;
+
+ /* Please God, make it stop! */
+ if (strA == null) {
+ if (strB == null)
+ return 0;
+ else
+ return -1;
+ } else if (strB == null)
+ return 1;
+
+ for (i = 0; strA[i] != '\0'; i++) {
+ char cA, cB;
+
+ cA = tolowerordinal (strA[i]);
+ cB = tolowerordinal (strB[i]);
+
+ if (cA != cB)
+ break;
+ }
+
+ return ((int) (strA[i] - strB[i]));
+ }
+
+ public static int CompareOrdinal (string strA, int indexA, string strB, int indexB,
+ int length)
+ {
+ int i;
+
+ if (length < 0 || indexA < 0 || indexB < 0)
+ throw new ArgumentOutOfRangeException ();
+
+ /* Nooooooooo!! */
+ if (strA == null) {
+ if (strB == null)
+ return 0;
+ else
+ return -1;
+ } else if (strB == null)
+ return 1;
+
+ for (i = 0; i < length; i++) {
+ char cA, cB;
+
+ cA = tolowerordinal (strA[indexA + i]);
+ cB = tolowerordinal (strB[indexB + i]);
+
+ if (cA != cB)
+ break;
+ }
+
+ return ((int) (strA[indexA + i] - strB[indexB + i]));
+ }
+
+ public int CompareTo (object obj)
+ {
+ return Compare (this, obj == null ? null : obj.ToString ());
+ }
+
+ public int CompareTo (string str)
+ {
+ return Compare (this, str);
+ }
+
+ public static string Concat (object arg)
+ {
+ return arg != null ? arg.ToString () : String.Empty;
+ }
+
+ public static string Concat (params object[] args)
+ {
+ string[] strings;
+ char[] str;
+ int len, i;
+
+ if (args == null)
+ throw new ArgumentNullException ();
+
+ strings = new string [args.Length];
+ len = 0;
+ i = 0;
+ foreach (object arg in args) {
+ /* use Empty for each null argument */
+ if (arg == null)
+ strings[i] = String.Empty;
+ else
+ strings[i] = arg.ToString ();
+ len += strings[i].Length;
+ i++;
+ }
+
+ if (len == 0)
+ return String.Empty;
+
+ str = new char [len + 1];
+ i = 0;
+ for (int j = 0; j < strings.Length; j++)
+ for (int k = 0; k < strings[j].Length; k++)
+ str[i++] = strings[j][k];
+ str[i] = '\0';
+
+ return new String (str);
+ }
+
+ public static string Concat (params string[] values)
+ {
+ int len, i;
+ char[] str;
+
+ if (values == null)
+ throw new ArgumentNullException ();
+
+ len = 0;
+ foreach (string value in values)
+ len += value != null ? value.Length : 0;
+
+ if (len == 0)
+ return String.Empty;
+
+ str = new char [len + 1];
+ i = 0;
+ foreach (string value in values) {
+ if (value == null)
+ continue;
+
+ for (int j = 0; j < value.Length; j++)
+ str[i++] = value[j];
+ }
+ str[i] = '\0';
+
+ return new String (str);
+ }
+
+ public static string Concat (object arg0, object arg1)
+ {
+ string str0 = arg0 != null ? arg0.ToString () : String.Empty;
+ string str1 = arg1 != null ? arg1.ToString () : String.Empty;
+
+ return Concat (str0, str1);
+ }
+
+ public static string Concat (string str0, string str1)
+ {
+ char[] concat;
+ int i, j, len;
+
+ if (str0 == null)
+ str0 = String.Empty;
+ if (str1 == null)
+ str1 = String.Empty;
+
+ len = str0.Length + str1.Length;
+ if (len == 0)
+ return String.Empty;
+
+ concat = new char [len + 1];
+ for (i = 0; i < str0.Length; i++)
+ concat[i] = str0[i];
+ for (j = 0 ; j < str1.Length; j++)
+ concat[i + j] = str1[j];
+ concat[len] = '\0';
+
+ return new String (concat);
+ }
+
+ public static string Concat (object arg0, object arg1, object arg2)
+ {
+ string str0 = arg0 != null ? arg0.ToString () : String.Empty;
+ string str1 = arg1 != null ? arg1.ToString () : String.Empty;
+ string str2 = arg2 != null ? arg2.ToString () : String.Empty;
+
+ return Concat (str0, str1, str2);
+ }
+
+ public static string Concat (string str0, string str1, string str2)
+ {
+ char[] concat;
+ int i, j, k, len;
+
+ if (str0 == null)
+ str0 = String.Empty;
+ if (str1 == null)
+ str1 = String.Empty;
+ if (str2 == null)
+ str2 = String.Empty;
+
+ len = str0.Length + str1.Length + str2.Length;
+ if (len == 0)
+ return String.Empty;
+
+ concat = new char [len + 1];
+ for (i = 0; i < str0.Length; i++)
+ concat[i] = str0[i];
+ for (j = 0; j < str1.Length; j++)
+ concat[i + j] = str1[j];
+ for (k = 0; k < str2.Length; k++)
+ concat[i + j + k] = str2[k];
+ concat[len] = '\0';
+
+ return new String (concat);
+ }
+
+ public static string Concat (string str0, string str1, string str2, string str3)
+ {
+ char[] concat;
+ int i, j, k, l, len;
+
+ if (str0 == null)
+ str0 = String.Empty;
+ if (str1 == null)
+ str1 = String.Empty;
+ if (str2 == null)
+ str2 = String.Empty;
+ if (str3 == null)
+ str3 = String.Empty;
+
+ len = str0.Length + str1.Length + str2.Length + str3.Length;
+ if (len == 0)
+ return String.Empty;
+
+ concat = new char [len + 1];
+ for (i = 0; i < str0.Length; i++)
+ concat[i] = str0[i];
+ for (j = 0; j < str1.Length; j++)
+ concat[i + j] = str1[j];
+ for (k = 0; k < str2.Length; k++)
+ concat[i + j + k] = str2[k];
+ for (l = 0; l < str3.Length; l++)
+ concat[i + j + k + l] = str3[l];
+ concat[len] = '\0';
+
+ return new String (concat);
+ }
+
+ public static string Copy (string str)
+ {
+ // FIXME: how do I *copy* a string if I can only have 1 of each?
+ if (str == null)
+ throw new ArgumentNullException ();
+
+ return str;
+ }
+
+ public void CopyTo (int sourceIndex, char[] destination, int destinationIndex, int count)
+ {
+ // LAMESPEC: should I null-terminate?
+ int i;
+
+ if (destination == null)
+ throw new ArgumentNullException ();
+
+ if (sourceIndex < 0 || destinationIndex < 0 || count < 0)
+ throw new ArgumentOutOfRangeException ();
+
+ if (sourceIndex + count > this.length)
+ throw new ArgumentOutOfRangeException ();
+
+ if (destinationIndex + count > destination.Length)
+ throw new ArgumentOutOfRangeException ();
+
+ for (i = 0; i < count; i++)
+ destination[destinationIndex + i] = this.c_str[sourceIndex + i];
+ }
+
+ public bool EndsWith (string value)
+ {
+ bool endswith = true;
+ int start, i;
+
+ if (value == null)
+ throw new ArgumentNullException ();
+
+ start = this.length - value.Length;
+ if (start < 0)
+ return false;
+
+ for (i = start; i < this.length && endswith; i++)
+ endswith = this.c_str[i] == value[i - start];
+
+ return endswith;
+ }
+
+ public override bool Equals (object obj)
+ {
+ if (!(obj is String))
+ return false;
+
+ return this == (String) obj;
+ }
+
+ public bool Equals (string value)
+ {
+ return this == value;
+ }
+
+ public static bool Equals (string a, string b)
+ {
+ return a == b;
+ }
+
+ public static string Format (string format, object arg0)
+ {
+ // FIXME: implement me
+ return null;
+ }
+
+ public static string Format (string format, params object[] args)
+ {
+ // FIXME: implement me
+ return null;
+ }
+
+ public static string Format (IFormatProvider provider, string format, params object[] args)
+ {
+ // FIXME: implement me
+ return null;
+ }
+
+ public static string Format (string format, object arg0, object arg1)
+ {
+ // FIXME: implement me
+ return null;
+ }
+
+ public static string Format (string format, object arg0, object arg1, object arg2)
+ {
+ // FIXME: implement me
+ return null;
+ }
+
+ //public CharEnumerator GetEnumerator ()
+ public IEnumerator GetEnumerator ()
+ {
+ // FIXME: implement me
+ return null;
+ }
+
+ public override int GetHashCode ()
+ {
+ // FIXME: implement me
+ return 0;
+ }
+
+ public new Type GetType ()
+ {
+ // FIXME: implement me
+ return null;
+ }
+
+ public TypeCode GetTypeCode ()
+ {
+ // FIXME: implement me
+ return 0;
+ }
+
+ public int IndexOf (char value)
+ {
+ return IndexOf (value, 0, this.length);
+ }
+
+ public int IndexOf (string value)
+ {
+ return IndexOf (value, 0, this.length);
+ }
+
+ public int IndexOf (char value, int startIndex)
+ {
+ return IndexOf (value, startIndex, this.length - startIndex);
+ }
+
+ public int IndexOf (string value, int startIndex)
+ {
+ return IndexOf (value, startIndex, this.length - startIndex);
+ }
+
+ public int IndexOf (char value, int startIndex, int count)
+ {
+ int i;
+
+ if (startIndex < 0 || count < 0 || startIndex + count > this.length)
+ throw new ArgumentOutOfRangeException ();
+
+ for (i = startIndex; i - startIndex < count; i++)
+ if (this.c_str[i] == value)
+ return i;
+
+ return -1;
+ }
+
+ public int IndexOf (string value, int startIndex, int count)
+ {
+ // FIXME: Use a modified Boyer-Moore algorithm to work with unicode?
+ int i;
+
+ if (value == null)
+ throw new ArgumentNullException ();
+
+ if (startIndex < 0 || count < 0 || startIndex + count > this.length)
+ throw new ArgumentOutOfRangeException ();
+
+ for (i = startIndex; i - startIndex + value.Length <= count; ) {
+ if (this.c_str[i] == value[0]) {
+ bool equal = true;
+ int j, nexti = 0;
+
+ for (j = 1; equal && value[j] != '\0'; j++) {
+ equal = this.c_str[i + j] == value[j];
+ if (this.c_str[i + j] == value[0] && nexti == 0)
+ nexti = i + j;
+ }
+
+ if (equal)
+ return i;
+
+ if (nexti != 0)
+ i = nexti;
+ else
+ i += j;
+ } else
+ i++;
+ }
+
+ return -1;
+ }
+
+ public int IndexOfAny (char[] values)
+ {
+ return IndexOfAny (values, 0, this.length);
+ }
+
+ public int IndexOfAny (char[] values, int startIndex)
+ {
+ return IndexOfAny (values, startIndex, this.length - startIndex);
+ }
+
+ public int IndexOfAny (char[] values, int startIndex, int count)
+ {
+ if (values == null)
+ throw new ArgumentNullException ();
+
+ if (startIndex < 0 || count < 0 || startIndex + count > this.length)
+ throw new ArgumentOutOfRangeException ();
+
+ for (int i = startIndex; i < startIndex + count; i++) {
+ for (int j = 0; j < strlen (values); j++) {
+ if (this.c_str[i] == values[j])
+ return i;
+ }
+ }
+
+ return -1;
+ }
+
+ public string Insert (int startIndex, string value)
+ {
+ char[] str;
+ int i, j;
+
+ if (value == null)
+ throw new ArgumentNullException ();
+
+ if (startIndex < 0 || startIndex > this.length)
+ throw new ArgumentOutOfRangeException ();
+
+ str = new char [value.Length + this.length + 1];
+ for (i = 0; i < startIndex; i++)
+ str[i] = this.c_str[i];
+ for (j = 0; j < value.Length; j++)
+ str[i + j] = value[j];
+ for ( ; i < this.length; i++)
+ str[i + j] = this.c_str[i];
+ str[i + j] = '\0';
+
+ return new String (str);
+ }
+
+ public static string Intern (string str)
+ {
+ if (str == null)
+ throw new ArgumentNullException ();
+ // FIXME: implement me
+ return null;
+ }
+
+ public static string IsInterned (string str)
+ {
+ if (str == null)
+ throw new ArgumentNullException ();
+ // FIXME: implement me
+ return null;
+ }
+
+ public static string Join (string separator, string[] value)
+ {
+ return Join (separator, value, 0, value.Length);
+ }
+
+ public static string Join (string separator, string[] value, int startIndex, int count)
+ {
+ // LAMESPEC: msdn doesn't specify what happens when separator is null
+ int len, i, j, used;
+ char[] str;
+
+ if (separator == null || value == null)
+ throw new ArgumentNullException ();
+
+ if (startIndex + count > value.Length)
+ throw new ArgumentOutOfRangeException ();
+
+ len = 0;
+ for (i = startIndex, used = 0; used < count; i++, used++) {
+ if (i != startIndex)
+ len += separator.Length;
+
+ len += value[i].Length;
+ }
+
+ // We have no elements to join?
+ if (i == startIndex)
+ return String.Empty;
+
+ str = new char [len + 1];
+ for (i = 0; i < value[startIndex].Length; i++)
+ str[i] = value[startIndex][i];
+
+ used = 1;
+ for (j = startIndex + 1; used < count; j++, used++) {
+ int k;
+
+ for (k = 0; k < separator.Length; k++)
+ str[i++] = separator[k];
+ for (k = 0; k < value[j].Length; k++)
+ str[i++] = value[j][k];
+ }
+ str[i] = '\0';
+
+ return new String (str);
+ }
+
+ public int LastIndexOf (char value)
+ {
+ for (int i = this.length; i >= 0; i--) {
+ if (this.c_str[i] == value)
+ return i;
+ }
+
+ return -1;
+ }
+
+ public int LastIndexOf (string value)
+ {
+ return LastIndexOf (value, this.length, this.length);
+ }
+
+ public int LastIndexOf (char value, int startIndex)
+ {
+ if (startIndex < 0 || startIndex > this.length)
+ throw new ArgumentOutOfRangeException ();
+
+ for (int i = startIndex; i >= 0; i--) {
+ if (this.c_str[i] == value)
+ return i;
+ }
+
+ return -1;
+ }
+
+ public int LastIndexOf (string value, int startIndex)
+ {
+ return LastIndexOf (value, startIndex, this.length);
+ }
+
+ public int LastIndexOf (char value, int startIndex, int count)
+ {
+ if (startIndex < 0 || count < 0)
+ throw new ArgumentOutOfRangeException ();
+
+ if (startIndex > this.length || startIndex - count < 0)
+ throw new ArgumentOutOfRangeException ();
+
+ for (int i = startIndex; i >= startIndex - count; i--) {
+ if (this.c_str[i] == value)
+ return i;
+ }
+
+ return -1;
+ }
+
+ public int LastIndexOf (string value, int startIndex, int count)
+ {
+ // LAMESPEC: currently I'm using startIndex as the 0-position in the comparison,
+ // but maybe it's the end-position in MS's implementation?
+ // msdn is unclear on this point. I think this is correct though.
+ int i, len;
+
+ if (value == null)
+ throw new ArgumentNullException ();
+
+ if (startIndex < 0 || startIndex > this.length)
+ throw new ArgumentOutOfRangeException ();
+
+ if (count < 0 || startIndex - count < 0)
+ throw new ArgumentOutOfRangeException ();
+
+ if (value == String.Empty)
+ return startIndex;
+
+ if (startIndex + value.Length > this.length) {
+ /* just a little optimization */
+ int start;
+
+ start = this.length - value.Length;
+ count -= startIndex - start;
+ startIndex = start;
+ }
+
+ // FIXME: use a reversed-unicode-safe-Boyer-Moore?
+ len = value.Length - 1;
+ for (i = startIndex; i >= startIndex - count; i--) {
+ if (this.c_str[i + len] == value[len]) {
+ bool equal = true;
+ int j;
+
+ for (j = len - 1; equal && j >= 0; j--)
+ equal = this.c_str[i + j] == value[j];
+
+ if (equal)
+ return i;
+ }
+ }
+
+ return -1;
+ }
+
+ public int LastIndexOfAny (char[] values)
+ {
+ return LastIndexOfAny (values, this.length, this.length);
+ }
+
+ public int LastIndexOfAny (char[] values, int startIndex)
+ {
+ return LastIndexOfAny (values, startIndex, startIndex);
+ }
+
+ public int LastIndexOfAny (char[] values, int startIndex, int count)
+ {
+ int i;
+
+ if (values == null)
+ throw new ArgumentNullException ();
+
+ if (startIndex < 0 || count < 0 || startIndex - count < 0)
+ throw new ArgumentOutOfRangeException ();
+
+ for (i = startIndex; i >= startIndex - count; i--) {
+ for (int j = 0; j < strlen (values); j++) {
+ if (this.c_str[i] == values[j])
+ return i;
+ }
+ }
+
+ return -1;
+ }
+
+ public string PadLeft (int totalWidth)
+ {
+ return PadLeft (totalWidth, ' ');
+ }
+
+ public string PadLeft (int totalWidth, char padChar)
+ {
+ char[] str;
+ int i, j;
+
+ if (totalWidth < 0)
+ throw new ArgumentException ();
+
+ str = new char [totalWidth > this.length ? totalWidth : this.length + 1];
+ for (i = 0; i < totalWidth - this.length; i++)
+ str[i] = padChar;
+
+ for (j = 0; j < this.length; i++, j++)
+ str[i] = this.c_str[j];
+
+ str[i] = '\0';
+
+ return new String (str);
+ }
+
+ public string PadRight (int totalWidth)
+ {
+ return PadRight (totalWidth, ' ');
+ }
+
+ public string PadRight (int totalWidth, char padChar)
+ {
+ char[] str;
+ int i;
+
+ if (totalWidth < 0)
+ throw new ArgumentException ();
+
+ str = new char [totalWidth > this.length ? totalWidth : this.length + 1];
+ for (i = 0; i < this.length; i++)
+ str[i] = this.c_str[i];
+
+ for ( ; i < str.Length; i++)
+ str[i] = padChar;
+
+ str[i] = '\0';
+
+ return new String (str);
+ }
+
+ public string Remove (int startIndex, int count)
+ {
+ char[] str;
+ int i, j, len;
+
+ if (startIndex < 0 || count < 0 || startIndex + count > this.length)
+ throw new ArgumentOutOfRangeException ();
+
+ len = this.length - count;
+ if (len == 0)
+ return String.Empty;
+
+ str = new char [len + 1];
+ for (i = 0; i < startIndex; i++)
+ str[i] = this.c_str[i];
+ for (j = i + count; j < this.length; j++)
+ str[i++] = this.c_str[j];
+ str[i] = '\0';
+
+ return new String (str);
+ }
+
+ public string Replace (char oldChar, char newChar)
+ {
+ char[] str;
+ int i;
+
+ str = new char [this.length + 1];
+ for (i = 0; i < this.length; i++) {
+ if (this.c_str[i] == oldChar)
+ str[i] = newChar;
+ else
+ str[i] = this.c_str[i];
+ }
+ str[i] = '\0';
+
+ return new String (str);
+ }
+
+ public string Replace (string oldValue, string newValue)
+ {
+ // LAMESPEC: msdn doesn't specify what to do if either args is null
+ int index, len, i, j;
+ char[] str;
+
+ if (oldValue == null || newValue == null)
+ throw new ArgumentNullException ();
+
+ // Use IndexOf in case I later rewrite it to use Boyer-Moore
+ index = IndexOf (oldValue, 0);
+ if (index == -1) {
+ // This is the easy one ;-)
+ return Substring (0, this.length);
+ }
+
+ len = this.length - oldValue.Length + newValue.Length;
+ if (len == 0)
+ return String.Empty;
+
+ str = new char [len + 1];
+ for (i = 0; i < index; i++)
+ str[i] = this.c_str[i];
+ for (j = 0; j < newValue.Length; j++)
+ str[i++] = newValue[j];
+ for (j = index + oldValue.Length; j < this.length; j++)
+ str[i++] = this.c_str[j];
+ str[i] = '\0';
+
+ return new String (str);
+ }
+
+ private int splitme (char[] separators, int startIndex)
+ {
+ /* this is basically a customized IndexOfAny() for the Split() methods */
+ for (int i = startIndex; i < this.length; i++) {
+ if (separators != null) {
+ foreach (char sep in separators) {
+ if (this.c_str[i] == sep)
+ return i - startIndex;
+ }
+ } else if (is_lwsp (this.c_str[i])) {
+ return i - startIndex;
+ }
+ }
+
+ return -1;
+ }
+
+ public string[] Split (params char[] separator)
+ {
+ /**
+ * split:
+ * @separator: delimiting chars or null to split on whtspc
+ *
+ * Returns: 1. An array consisting of a single
+ * element (@this) if none of the delimiting
+ * chars appear in @this. 2. An array of
+ * substrings which are delimited by one of
+ * the separator chars. 3. An array of
+ * substrings separated by whitespace if
+ * @separator is null. The Empty string should
+ * be returned wherever 2 delimiting chars are
+ * adjacent.
+ **/
+ // FIXME: would using a Queue be better?
+ string[] strings;
+ ArrayList list;
+ int index, len;
+
+ list = new ArrayList ();
+ for (index = 0, len = 0; index < this.length; index += len + 1) {
+ len = splitme (separator, index);
+ len = len > -1 ? len : this.length - index;
+ if (len == 0) {
+ list.Add (String.Empty);
+ } else {
+ char[] str;
+ int i;
+
+ str = new char [len + 1];
+ for (i = 0; i < len; i++)
+ str[i] = this.c_str[index + i];
+ str[i] = '\0';
+
+ list.Add (new String (str));
+ }
+ }
+
+ strings = new string [list.Count];
+ if (list.Count == 1) {
+ /* special case for an array holding @this */
+ strings[0] = this;
+ } else {
+ for (index = 0; index < list.Count; index++)
+ strings[index] = (string) list[index];
+ }
+
+ return strings;
+ }
+
+ public string[] Split (char[] separator, int maxCount)
+ {
+ // FIXME: what to do if maxCount <= 0?
+ // FIXME: would using Queue be better than ArrayList?
+ string[] strings;
+ ArrayList list;
+ int index, len, used;
+
+ used = 0;
+ list = new ArrayList ();
+ for (index = 0, len = 0; index < this.length && used < maxCount; index += len + 1) {
+ len = splitme (separator, index);
+ len = len > -1 ? len : this.length - index;
+ if (len == 0) {
+ list.Add (String.Empty);
+ } else {
+ char[] str;
+ int i;
+
+ str = new char [len + 1];
+ for (i = 0; i < len; i++)
+ str[i] = this.c_str[index + i];
+ str[i] = '\0';
+
+ list.Add (new String (str));
+ }
+ used++;
+ }
+
+ /* fit the remaining chunk of the @this into it's own element */
+ if (index != this.length) {
+ char[] str;
+ int i;
+
+ str = new char [this.length - index + 1];
+ for (i = index; i < this.length; i++)
+ str[i - index] = this.c_str[i];
+ str[i - index] = '\0';
+
+ list.Add (new String (str));
+ }
+
+ strings = new string [list.Count];
+ if (list.Count == 1) {
+ /* special case for an array holding @this */
+ strings[0] = this;
+ } else {
+ for (index = 0; index < list.Count; index++)
+ strings[index] = (string) list[index];
+ }
+
+ return strings;
+ }
+
+ public bool StartsWith (string value)
+ {
+ bool startswith = true;
+ int i;
+
+ if (value == null)
+ throw new ArgumentNullException ();
+
+ if (value.Length > this.length)
+ return false;
+
+ for (i = 0; i < value.Length && startswith; i++)
+ startswith = startswith && value[i] == this.c_str[i];
+
+ return startswith;
+ }
+
+ public string Substring (int startIndex)
+ {
+ char[] str;
+ int i, len;
+
+ if (startIndex < 0 || startIndex > this.length)
+ throw new ArgumentOutOfRangeException ();
+
+ len = this.length - startIndex;
+ if (len == 0)
+ return String.Empty;
+
+ str = new char [len + 1];
+ for (i = startIndex; i < this.length; i++)
+ str[i - startIndex] = this.c_str[i];
+ str[i] = '\0';
+
+ return new String (str);
+ }
+
+ public string Substring (int startIndex, int length)
+ {
+ char[] str;
+ int i;
+
+ if (startIndex < 0 || length < 0 || startIndex + length > this.length)
+ throw new ArgumentOutOfRangeException ();
+
+ if (length == 0)
+ return String.Empty;
+
+ str = new char [length + 1];
+ for (i = startIndex; i < startIndex + length; i++)
+ str[i - startIndex] = this.c_str[i];
+ str[i] = '\0';
+
+ return new String (str);
+ }
+
+ public bool ToBoolean (IFormatProvider provider)
+ {
+ // FIXME: implement me
+ return false;
+ }
+
+ public byte ToByte (IFormatProvider provider)
+ {
+ // FIXME: implement me
+ return (byte) '\0';
+ }
+
+ public char ToChar (IFormatProvider provider)
+ {
+ // FIXME: implement me
+ return '\0';
+ }
+
+ public char[] ToCharArray ()
+ {
+ return ToCharArray (0, this.length);
+ }
+
+ public char[] ToCharArray (int startIndex, int length)
+ {
+ char[] chars;
+ int i;
+
+ if (startIndex < 0 || length < 0 || startIndex + length > this.length)
+ throw new ArgumentOutOfRangeException ();
+
+ chars = new char [length + 1];
+ for (i = startIndex; i < length; i++)
+ chars[i - startIndex] = this.c_str[i];
+
+ chars[length] = '\0';
+
+ return chars;
+ }
+
+ public DateTime ToDateTime (IFormatProvider provider)
+ {
+ // FIXME: implement me
+
+ return new DateTime (0);
+ }
+
+ public decimal ToDecimal (IFormatProvider provider)
+ {
+ // FIXME: implement me
+ return 0.0M;
+ }
+
+ public double ToDouble (IFormatProvider provider)
+ {
+ // FIXME: implement me
+ return 0.0;
+ }
+
+ public short ToInt16 (IFormatProvider provider)
+ {
+ // FIXME: implement me
+ return 0;
+ }
+
+ public int ToInt32 (IFormatProvider provider)
+ {
+ // FIXME: implement me
+ return 0;
+ }
+
+ public long ToInt64 (IFormatProvider provider)
+ {
+ // FIXME: implement me
+ return 0;
+ }
+
+ public string ToLower ()
+ {
+ char[] str;
+ int i;
+
+ str = new char [this.length + 1];
+ for (i = 0; i < this.length; i++)
+ str[i] = Char.ToLower (this.c_str[i]);
+ str[i] = '\0';
+
+ return new String (str);
+ }
+
+ public string ToLower (CultureInfo culture)
+ {
+ // FIXME: implement me
+ return null;
+ }
+
+ public sbyte ToSByte (IFormatProvider provider)
+ {
+ // FIXME: implement me
+ return 0;
+ }
+
+ public float ToSingle (IFormatProvider provider)
+ {
+ // FIXME: implement me
+ return 0.0F;
+ }
+
+ public override string ToString ()
+ {
+ return Substring (0, this.length);
+ }
+
+ public string ToString (IFormatProvider format)
+ {
+ // FIXME: implement me
+ return null;
+ }
+
+ public object ToType (Type conversionType, IFormatProvider provider)
+ {
+ // FIXME: implement me
+ return null;
+ }
+
+ public ushort ToUInt16 (IFormatProvider provider)
+ {
+ // FIXME: implement me
+ return 0;
+ }
+
+ public uint ToUInt32 (IFormatProvider provider)
+ {
+ // FIXME: implement me
+ return 0;
+ }
+
+ public ulong ToUInt64 (IFormatProvider provider)
+ {
+ // FIXME: implement me
+ return 0;
+ }
+
+ public string ToUpper ()
+ {
+ char[] str;
+ int i;
+
+ str = new char [this.length + 1];
+ for (i = 0; i < this.length; i++)
+ str[i] = Char.ToUpper (this.c_str[i]);
+ str[i] = '\0';
+
+ return new String (str);
+ }
+
+ public string ToUpper (CultureInfo culture)
+ {
+ // FIXME: implement me
+ return null;
+ }
+
+ public string Trim ()
+ {
+ return Trim (null);
+ }
+
+ public string Trim (params char[] trimChars)
+ {
+ int begin, end;
+ bool matches;
+
+ matches = true;
+ for (begin = 0; matches && begin < this.length; begin++) {
+ if (trimChars != null) {
+ matches = false;
+ foreach (char c in trimChars)
+ matches = this.c_str[begin] == c;
+ } else {
+ matches = is_lwsp (this.c_str[begin]);
+ }
+ }
+
+ matches = true;
+ for (end = this.length; end > begin; end--) {
+ if (trimChars != null) {
+ matches = false;
+ foreach (char c in trimChars)
+ matches = this.c_str[end] == c;
+ } else {
+ matches = is_lwsp (this.c_str[end]);
+ }
+ }
+
+ if (begin == end)
+ return String.Empty;
+
+ return Substring (begin, end - begin);
+ }
+
+ public string TrimEnd (params char[] trimChars)
+ {
+ bool matches = true;
+ int end;
+
+ for (end = this.length; end > 0; end--) {
+ if (trimChars != null) {
+ matches = false;
+ foreach (char c in trimChars)
+ matches = this.c_str[end] == c;
+ } else {
+ matches = is_lwsp (this.c_str[end]);
+ }
+ }
+
+ if (end == 0)
+ return String.Empty;
+
+ return Substring (0, end);
+ }
+
+ public string TrimStart (params char[] trimChars)
+ {
+ bool matches = true;
+ int begin;
+
+ for (begin = 0; matches && begin < this.length; begin++) {
+ if (trimChars != null) {
+ matches = false;
+ foreach (char c in trimChars)
+ matches = this.c_str[begin] == c;
+ } else {
+ matches = is_lwsp (this.c_str[begin]);
+ }
+ }
+
+ if (begin == this.length)
+ return String.Empty;
+
+ return Substring (begin, this.length - begin);
+ }
+
+ // Operators
+ public static bool operator ==(string a, string b)
+ {
+ return a == b;
+ }
+
+ public static bool operator !=(string a, string b)
+ {
+ return a != b;
+ }
+ }
+}
diff --git a/mcs/class/corlib/System/SystemException.cs b/mcs/class/corlib/System/SystemException.cs
new file mode 100644
index 00000000000..79fa92ca2ec
--- /dev/null
+++ b/mcs/class/corlib/System/SystemException.cs
@@ -0,0 +1,29 @@
+//
+// System.SystemException.cs
+//
+// Author:
+// Joe Shaw (joe@ximian.com)
+//
+// (C) 2001 Ximian, Inc. http://www.ximian.com
+//
+
+namespace System {
+
+ public class SystemException : Exception {
+ // Constructors
+ public SystemException ()
+ : base ("A system exception has occurred.")
+ {
+ }
+
+ public SystemException (string message)
+ : base (message)
+ {
+ }
+
+ public SystemException (string message, Exception inner)
+ : base (message, inner)
+ {
+ }
+ }
+}
diff --git a/mcs/class/corlib/System/TODO b/mcs/class/corlib/System/TODO
new file mode 100644
index 00000000000..065809deedb
--- /dev/null
+++ b/mcs/class/corlib/System/TODO
@@ -0,0 +1,22 @@
+System.Object:
+ Need a mechanism for getting an object underlying type.
+
+System.ValueType:
+ Need to lock memory and "scan" the actual contents to compute
+ hash code and do comparissions. Should be simple to do with
+ C#, the problem is figuring out the size of the object.
+
+System.String:
+ Need to implement the Format() and CompareOrdinal() methods
+ as we all implement all of the methods that take into account
+ CultureInfo or Encoding stuff.
+
+System.Array:
+ It's not possible to test to see if the whole thing works, as
+ GetValue() and SetValue() make calls into the runtime. However,
+ I've tried my implementations of things like BinarySearch() and
+ Sort() on the MS-provided System.Array and they seem to work fine.
+ According to the spec, System.Array implements the IList interface.
+ The spec doesn't have the methods for those interfaces, however,
+ the class doesn't (yet) implement that interface and those methods
+ are not (yet) written.
diff --git a/mcs/class/corlib/System/TimeSpan.cs b/mcs/class/corlib/System/TimeSpan.cs
new file mode 100644
index 00000000000..bd92c95dc07
--- /dev/null
+++ b/mcs/class/corlib/System/TimeSpan.cs
@@ -0,0 +1,540 @@
+//
+// System.TimeSpan.cs
+//
+// author:
+// Duco Fijma (duco@lorentz.xs4all.nl)
+//
+// (C) 2001 Duco Fijma
+//
+// version: 07312001
+
+namespace System {
+
+ public struct TimeSpan : IComparable {
+ private long _ticks;
+
+ // Ctors
+
+ public TimeSpan (long value) { _ticks = value; }
+ public TimeSpan (int hours, int minutes, int seconds)
+ : this(false, 0, hours, minutes, seconds, 0, 0) {}
+ public TimeSpan (int days, int hours, int minutes, int seconds)
+ : this(false, days, hours, minutes, seconds, 0, 0) {}
+ public TimeSpan (int days, int hours, int minutes, int seconds, int milliseconds)
+ : this(false, days, hours, minutes, seconds, milliseconds, 0) {}
+
+ internal TimeSpan (bool sign, int days, int hours, int minutes, int seconds, int milliseconds, long ticks)
+ {
+ checked {
+ _ticks = TicksPerDay * days +
+ TicksPerHour * hours +
+ TicksPerMinute * minutes +
+ TicksPerSecond * seconds +
+ TicksPerMillisecond * milliseconds +
+ ticks;
+ if ( sign ) {
+ _ticks = -_ticks;
+ }
+ }
+ }
+
+ // Fields
+
+ public static readonly TimeSpan MaxValue = new TimeSpan (long.MaxValue);
+ public static readonly TimeSpan MinValue = new TimeSpan (long.MinValue);
+ public const long TicksPerDay = 864000000000L;
+ public const long TicksPerHour = 36000000000L;
+ public const long TicksPerMillisecond = 10000L;
+ public const long TicksPerMinute = 600000000L;
+ public const long TicksPerSecond = 10000000L;
+ public static readonly TimeSpan Zero = new TimeSpan (0L);
+
+ // Properties
+
+ public int Days
+ {
+ get {
+ return (int) TotalDays;
+ }
+ }
+
+ public int Hours
+ {
+ get {
+ return (int) (_ticks % TicksPerDay / TicksPerHour);
+ }
+ }
+
+ public int Milliseconds
+ {
+ get
+ {
+ return (int) (_ticks % TicksPerSecond / TicksPerMillisecond);
+ }
+ }
+
+ public int Minutes
+ {
+ get
+ {
+ return (int) (_ticks % TicksPerHour / TicksPerMinute);
+ }
+ }
+
+ public int Seconds
+ {
+ get
+ {
+ return (int) (_ticks % TicksPerMinute / TicksPerSecond);
+ }
+ }
+
+ public long Ticks
+ {
+ get
+ {
+ return _ticks;
+ }
+ }
+
+ public double TotalDays
+ {
+ get
+ {
+ return (double) _ticks / TicksPerDay;
+ }
+ }
+
+ public double TotalHours
+ {
+ get
+ {
+ return (double) _ticks / TicksPerHour;
+ }
+ }
+
+ public double TotalMilliseconds
+ {
+ get
+ {
+ return (double) _ticks / TicksPerMillisecond;
+ }
+ }
+
+ public double TotalMinutes
+ {
+ get {
+ return (double) _ticks / TicksPerMinute;
+ }
+ }
+
+ public double TotalSeconds
+ {
+ get {
+ return (double) _ticks / TicksPerSecond;
+ }
+ }
+
+ // Methods
+
+ public TimeSpan Add (TimeSpan ts)
+ {
+ checked {
+ return new TimeSpan (_ticks + ts.Ticks);
+ }
+ }
+
+ public static int Compare (TimeSpan t1, TimeSpan t2)
+ {
+ if (t1._ticks < t2._ticks) {
+ return -1;
+ }
+ else if (t1._ticks > t2._ticks) {
+ return 1;
+ }
+ else {
+ return 0;
+ }
+ }
+
+ public int CompareTo (object value)
+ {
+
+ if (value == null ) {
+ return 1;
+ }
+
+ if (!(value is TimeSpan)) {
+ throw new ArgumentException ("Argument of System.TimeSpan.CompareTo should be a TimeSpan");
+ }
+
+ return Compare(this, (TimeSpan) value);
+ }
+
+ public TimeSpan Duration ()
+ {
+ checked {
+ return new TimeSpan (Math.Abs (_ticks));
+ }
+ }
+
+ public override bool Equals (object value)
+ {
+ if (!(value is TimeSpan)) {
+ return false;
+ }
+ return Equals (this, (TimeSpan) value);
+ }
+
+ public static bool Equals (TimeSpan t1, TimeSpan t2)
+ {
+ return t1._ticks == t2._ticks;
+ }
+
+ // Implementing FromDays -> FromHours -> FromMinutes -> FromSeconds ->
+ // FromMilliseconds as done here is probably not the most efficient
+ // way.
+ public static TimeSpan FromDays (double value)
+ {
+ if (Double.IsNaN (value) || Double.IsNegativeInfinity (value)) {
+ return MinValue;
+ }
+
+ if (Double.IsPositiveInfinity (value)) {
+ return MaxValue;
+ }
+
+ return new TimeSpan ((int) value,0,0,0,0) + FromHours ((value - ((int) value)) * 24);
+ }
+
+ public static TimeSpan FromHours (double value)
+ {
+ if (Double.IsNaN (value) || Double.IsNegativeInfinity (value)) {
+ return MinValue;
+ }
+
+ if (Double.IsPositiveInfinity (value)) {
+ return MaxValue;
+ }
+
+ return new TimeSpan ((int) value,0,0) + FromMinutes ((value - ((int) value)) * 60);
+ }
+
+ public static TimeSpan FromMinutes (double value)
+ {
+ if (Double.IsNaN (value) || Double.IsNegativeInfinity (value)) {
+ return MinValue;
+ }
+
+ if (Double.IsPositiveInfinity (value)) {
+ return MaxValue;
+ }
+
+ return new TimeSpan (0, (int) value, 0) + FromSeconds((value - ((int) value)) * 60);
+ }
+
+ public static TimeSpan FromSeconds (double value)
+ {
+ if (Double.IsNaN (value) || Double.IsNegativeInfinity (value)) {
+ return MinValue;
+ }
+
+ if (Double.IsPositiveInfinity (value)) {
+ return MaxValue;
+ }
+
+ return new TimeSpan (0, 0, 0, (int) value, ((int) ((value - ((int) value)) * 1000)));
+
+ }
+
+ public static TimeSpan FromTicks (long value)
+ {
+ return new TimeSpan (value);
+ }
+
+ public override int GetHashCode ()
+ {
+ return _ticks.GetHashCode ();
+ }
+
+ public TimeSpan Negate ()
+ {
+ checked {
+ return new TimeSpan (-_ticks);
+ }
+ }
+
+ public static TimeSpan Parse (string s)
+ {
+ if (s == null) {
+ throw new ArgumentNullException ("null reference passed to TimeSpan.Parse");
+ }
+
+ Parser p = new Parser (s);
+ return p.Execute ();
+ }
+
+ public TimeSpan Subtract (TimeSpan ts)
+ {
+ checked {
+ return new TimeSpan (_ticks - ts.Ticks);
+ }
+ }
+
+ public override string ToString ()
+ {
+ string res = "";
+
+ if (_ticks < 0) {
+ res += "-";
+ }
+
+ // We need to take absolute values of all components.
+ // Can't handle negative timespans by negating the TimeSpan
+ // as a whole. This would lead to an overflow for the
+ // degenerate case "TimeSpan.MinValue.ToString()".
+ if (Days != 0) {
+ res += Math.Abs (Days) + "." ;
+ }
+
+ res += string.Format ("{0:00}:{1:00}:{2:00}", Math.Abs(Hours), Math.Abs(Minutes), Math.Abs(Seconds));
+
+ int fractional = (int) Math.Abs (_ticks % TicksPerSecond);
+ if (fractional != 0) {
+ res += string.Format (".{0:0000000}", fractional);
+ }
+
+ return res;
+ }
+
+ public static TimeSpan operator + (TimeSpan t1, TimeSpan t2)
+ {
+ return t1.Add (t2);
+ }
+
+ public static bool operator == (TimeSpan t1, TimeSpan t2)
+ {
+ return Compare (t1, t2) == 0;
+ }
+
+ public static bool operator > (TimeSpan t1, TimeSpan t2)
+ {
+ return Compare (t1, t2) == 1;
+ }
+
+ public static bool operator >= (TimeSpan t1, TimeSpan t2)
+ {
+ return Compare (t1, t2) != -1;
+ }
+
+ public static bool operator != (TimeSpan t1, TimeSpan t2)
+ {
+ return Compare (t1, t2) != 0;
+ }
+
+ public static bool operator < (TimeSpan t1, TimeSpan t2)
+ {
+ return Compare (t1, t2) == -1;
+ }
+
+ public static bool operator <= (TimeSpan t1, TimeSpan t2)
+ {
+ return Compare (t1, t2) != 1;
+ }
+
+ public static TimeSpan operator - (TimeSpan t1, TimeSpan t2)
+ {
+ return t1.Subtract (t2);
+ }
+
+ public static TimeSpan operator - (TimeSpan t)
+ {
+ return t.Negate ();
+ }
+
+ public static TimeSpan operator + (TimeSpan t)
+ {
+ return t;
+ }
+ }
+
+ // Class Parser implements simple parser for TimeSpan::Parse
+ internal class Parser {
+
+ private string _src;
+ private int _cur;
+ private int _length;
+
+ public Parser (string src)
+ {
+ _src = src;
+ Reset ();
+ }
+
+ public void Reset ()
+ {
+ _cur = 0;
+ _length = _src.Length;
+ }
+
+ public bool AtEnd
+ {
+ get {
+ return _cur >= _length;
+ }
+ }
+
+ private void ThrowFormatException()
+ {
+ throw new FormatException ("Invalid format for TimeSpan.Parse");
+ }
+
+ // All "Parse" functions throw a FormatException on syntax error.
+ // Their return value is semantic value of the item parsed.
+
+ // Range checking is spread over three different places:
+ // 1) When parsing "int" values, an exception is thrown immediately
+ // when the value parsed exceeds the maximum value for an int.
+ // 2) An explicit check is built in that checks for hours > 23 and
+ // for minutes and seconds > 59.
+ // 3) Throwing an exceptions for a final TimeSpan value > MaxValue
+ // or < MinValue is left to the TimeSpan constructor called.
+
+ // Parse zero or more whitespace chars.
+ private void ParseWhiteSpace ()
+ {
+ while (!AtEnd && Char.IsWhiteSpace (_src, _cur)) {
+ _cur++;
+ }
+ }
+
+ // Parse optional sign character.
+ private bool ParseSign ()
+ {
+ bool res = false;
+
+ if (!AtEnd && _src[_cur] == '-') {
+ res = true;
+ _cur++;
+ }
+
+ return res;
+ }
+
+ // Parse simple int value
+ private int ParseInt ()
+ {
+ int res = 0;
+ int count = 0;
+
+ while (!AtEnd && Char.IsDigit (_src, _cur)) {
+ checked {
+ res = res*10 + _src[_cur] - '0';
+ }
+ _cur++;
+ count++;
+ }
+
+ if (count == 0) {
+ ThrowFormatException ();
+ }
+
+ return res;
+ }
+
+ // Parse optional dot
+ private bool ParseOptDot ()
+ {
+ if (AtEnd) {
+ return false;
+ }
+
+ if (_src[_cur] == '.') {
+ _cur++;
+ return true;
+ }
+ else {
+ return false;
+ }
+ }
+
+ // Parse NON-optional colon
+ private void ParseColon ()
+ {
+ if (!AtEnd && _src[_cur] == ':') {
+ _cur++;
+ }
+ else {
+ ThrowFormatException ();
+ }
+ }
+
+ // Parse [1..7] digits, representing fractional seconds (ticks)
+ private long ParseTicks ()
+ {
+ long mag = 1000000;
+ long res = 0;
+ bool digitseen = false;
+
+ while ( mag > 0 && !AtEnd && Char.IsDigit (_src, _cur) ) {
+ res = res + (_src[_cur] - '0') * mag;
+ _cur++;
+ mag = mag / 10;
+ digitseen = true;
+ }
+
+ if (!digitseen) {
+ ThrowFormatException ();
+ }
+
+ return res;
+ }
+
+ public TimeSpan Execute ()
+ {
+ bool sign;
+ int days;
+ int hours;
+ int minutes;
+ int seconds;
+ long ticks;
+
+ // Parse [ws][dd.]hh:mm:ss[.ff][ws]
+ ParseWhiteSpace ();
+ sign = ParseSign ();
+ days = ParseInt ();
+ if (ParseOptDot ()) {
+ hours = ParseInt ();
+ }
+ else {
+ hours = days;
+ days = 0;
+ }
+ ParseColon();
+ minutes = ParseInt ();
+ ParseColon();
+ seconds = ParseInt ();
+ if ( ParseOptDot () ) {
+ ticks = ParseTicks ();
+ }
+ else {
+ ticks = 0;
+ }
+ ParseWhiteSpace ();
+
+ if ( !AtEnd ) {
+ ThrowFormatException ();
+ }
+
+ if ( hours > 23 || minutes > 59 || seconds > 59 ) {
+ throw new OverflowException ( "Value outside range in TimeSpan.Parse" );
+ }
+
+ TimeSpan ts = new TimeSpan (sign, days, hours, minutes, seconds, 0, ticks);
+
+ return ts;
+ }
+ }
+}
+
+
diff --git a/mcs/class/corlib/System/Type.cs b/mcs/class/corlib/System/Type.cs
new file mode 100644
index 00000000000..fec6a5b48a3
--- /dev/null
+++ b/mcs/class/corlib/System/Type.cs
@@ -0,0 +1,27 @@
+//
+// System.Type.cs
+//
+// Author:
+// Miguel de Icaza (miguel@ximian.com)
+//
+// (C) Ximian, Inc. http://www.ximian.com
+//
+// TODO: Mucho left to implement.
+//
+
+namespace System {
+
+ public abstract class Type {
+
+ public abstract string FullName {
+ get;
+ }
+
+ public Type GetTypeFromHandle (RuntimeTypeHandle handle) {
+
+ // FIXME: implement me
+
+ return null;
+ }
+ }
+}
diff --git a/mcs/class/corlib/System/TypeCode.cs b/mcs/class/corlib/System/TypeCode.cs
new file mode 100644
index 00000000000..a11a1054022
--- /dev/null
+++ b/mcs/class/corlib/System/TypeCode.cs
@@ -0,0 +1,32 @@
+//
+// System.TypeCode.cs
+//
+// Author:
+// Miguel de Icaza (miguel@ximian.com)
+//
+// (C) Ximian, Inc. http://www.ximian.com
+//
+
+namespace System {
+
+ public enum TypeCode {
+ Empty = 0,
+ Object = 1,
+ DBNull = 2,
+ Boolean = 3,
+ Char = 4,
+ SByte = 5,
+ Byte = 6,
+ Int16 = 7,
+ UInt16 = 8,
+ Int32 = 9,
+ UInt32 = 10,
+ Int64 = 11,
+ UInt64 = 12,
+ Single = 13,
+ Double = 14,
+ Decimal = 15,
+ DateTime = 16,
+ String = 18,
+ }
+}
diff --git a/mcs/class/corlib/System/TypeInitializationException.cs b/mcs/class/corlib/System/TypeInitializationException.cs
new file mode 100644
index 00000000000..2adbb2f89e6
--- /dev/null
+++ b/mcs/class/corlib/System/TypeInitializationException.cs
@@ -0,0 +1,30 @@
+//
+// System.TypeInitializationException.cs
+//
+// Author:
+// Joe Shaw (joe@ximian.com)
+//
+// (C) 2001 Ximian, Inc. http://www.ximian.com
+//
+
+namespace System {
+
+ public class TypeInitializationException : SystemException {
+ string type_name;
+
+ // Constructors
+ public TypeInitializationException (string type_name, Exception inner)
+ : base ("An exception was thrown by the type initializer for " + type_name, inner)
+ {
+ this.type_name = type_name;
+ }
+
+ // Properties
+ public string TypeName {
+ get {
+ return type_name;
+ }
+ }
+ }
+
+} \ No newline at end of file
diff --git a/mcs/class/corlib/System/UInt16.cs b/mcs/class/corlib/System/UInt16.cs
new file mode 100644
index 00000000000..9c164709df9
--- /dev/null
+++ b/mcs/class/corlib/System/UInt16.cs
@@ -0,0 +1,89 @@
+//
+// System.UInt16.cs
+//
+// Author:
+// Miguel de Icaza (miguel@ximian.com)
+//
+// (C) Ximian, Inc. http://www.ximian.com
+//
+
+using System.Globalization;
+
+namespace System {
+
+ public struct UInt16 : IComparable, IFormattable { //, IConvertible {
+ public const ushort MaxValue = 0xffff;
+ public const ushort MinValue = 0;
+
+ public ushort value;
+
+ public int CompareTo (object v)
+ {
+ if (!(v is System.UInt16))
+ throw new ArgumentException ("Value is not a System.UInt16");
+
+ return value - ((ushort) v);
+ }
+
+ public override bool Equals (object o)
+ {
+ if (!(o is System.UInt16))
+ return false;
+
+ return ((ushort) o) == value;
+ }
+
+ public override int GetHashCode ()
+ {
+ return value;
+ }
+
+ public static ushort Parse (string s)
+ {
+ return Parse (s, NumberStyles.Integer, null);
+ }
+
+ public static ushort Parse (string s, IFormatProvider fp)
+ {
+ return Parse (s, NumberStyles.Integer, fp);
+ }
+
+ public static ushort Parse (string s, NumberStyles style)
+ {
+ return Parse (s, style, null);
+ }
+
+ public static ushort Parse (string s, NumberStyles style, IFormatProvider fp)
+ {
+ // TODO: Implement me
+ return 0;
+ }
+
+ public override string ToString ()
+ {
+ return ToString ("G", null);
+ }
+
+ public string ToString (IFormatProvider fp)
+ {
+ return ToString ("G", fp);
+ }
+
+ public string ToString (string format)
+ {
+ return ToString (format, null);
+ }
+
+ public string ToString (string format, IFormatProvider fp)
+ {
+ // TODO: Implement me.
+ return "";
+ }
+
+ // =========== IConvertible Methods =========== //
+ public TypeCode GetTypeCode ()
+ {
+ return TypeCode.UInt16;
+ }
+ }
+}
diff --git a/mcs/class/corlib/System/UInt32.cs b/mcs/class/corlib/System/UInt32.cs
new file mode 100644
index 00000000000..053d81e4eaf
--- /dev/null
+++ b/mcs/class/corlib/System/UInt32.cs
@@ -0,0 +1,96 @@
+//
+// System.UInt32.cs
+//
+// Author:
+// Miguel de Icaza (miguel@ximian.com)
+//
+// (C) Ximian, Inc. http://www.ximian.com
+//
+
+using System.Globalization;
+
+namespace System {
+
+ public struct UInt32 : IComparable, IFormattable { //, IConvertible {
+ public const uint MaxValue = 0xffffffff;
+ public const uint MinValue = 0;
+
+ public uint value;
+
+ public int CompareTo (object v)
+ {
+ if (!(v is System.UInt32))
+ throw new ArgumentException ("Value is not a System.UInt32");
+
+ if (value == (uint) v)
+ return 0;
+
+ if (value < (uint) v)
+ return -1;
+
+ return 1;
+ }
+
+ public override bool Equals (object o)
+ {
+ if (!(o is System.UInt32))
+ return false;
+
+ return ((uint) o) == value;
+ }
+
+ public override int GetHashCode ()
+ {
+ return (int) value;
+ }
+
+ public static uint Parse (string s)
+ {
+ return Parse (s, NumberStyles.Integer, null);
+ }
+
+ public static uint Parse (string s, IFormatProvider fp)
+ {
+ return Parse (s, NumberStyles.Integer, fp);
+ }
+
+ public static uint Parse (string s, NumberStyles style)
+ {
+ return Parse (s, style, null);
+ }
+
+ public static uint Parse (string s, NumberStyles style, IFormatProvider fp)
+ {
+ // TODO: Implement me
+ return 0;
+ }
+
+ public override string ToString ()
+ {
+ return ToString ("G", null);
+ }
+
+ public string ToString (IFormatProvider fp)
+ {
+ return ToString ("G", fp);
+ }
+
+ public string ToString (string format)
+ {
+ return ToString (format, null);
+ }
+
+ public string ToString (string format, IFormatProvider fp)
+ {
+ // TODO: Implement me.
+ return "";
+ }
+
+ // =========== IConvertible Methods =========== //
+
+ public TypeCode GetTypeCode ()
+ {
+ return TypeCode.UInt32;
+ }
+ }
+}
diff --git a/mcs/class/corlib/System/UInt64.cs b/mcs/class/corlib/System/UInt64.cs
new file mode 100644
index 00000000000..14960c14857
--- /dev/null
+++ b/mcs/class/corlib/System/UInt64.cs
@@ -0,0 +1,96 @@
+//
+// System.UInt64.cs
+//
+// Author:
+// Miguel de Icaza (miguel@ximian.com)
+//
+// (C) Ximian, Inc. http://www.ximian.com
+//
+
+using System.Globalization;
+
+namespace System {
+
+ public struct UInt64 : IComparable, IFormattable { //, IConvertible {
+ public const ulong MaxValue = 0xffffffffffffffff;
+ public const ulong MinValue = 0;
+
+ public ulong value;
+
+ public int CompareTo (object v)
+ {
+ if (!(v is System.UInt64))
+ throw new ArgumentException ("Value is not a System.UInt64");
+
+ if (value == (ulong) v)
+ return 0;
+
+ if (value < (ulong) v)
+ return -1;
+
+ return 1;
+ }
+
+ public override bool Equals (object o)
+ {
+ if (!(o is System.UInt64))
+ return false;
+
+ return ((ulong) o) == value;
+ }
+
+ public override int GetHashCode ()
+ {
+ return (int)(value & 0xffffffff) ^ (int)(value >> 32);
+ }
+
+ public static ulong Parse (string s)
+ {
+ return Parse (s, NumberStyles.Integer, null);
+ }
+
+ public static ulong Parse (string s, IFormatProvider fp)
+ {
+ return Parse (s, NumberStyles.Integer, fp);
+ }
+
+ public static ulong Parse (string s, NumberStyles style)
+ {
+ return Parse (s, style, null);
+ }
+
+ public static ulong Parse (string s, NumberStyles style, IFormatProvider fp)
+ {
+ // TODO: Implement me
+ return 0;
+ }
+
+ public override string ToString ()
+ {
+ return ToString ("G", null);
+ }
+
+ public string ToString (IFormatProvider fp)
+ {
+ return ToString ("G", fp);
+ }
+
+ public string ToString (string format)
+ {
+ return ToString (format, null);
+ }
+
+ public string ToString (string format, IFormatProvider fp)
+ {
+ // TODO: Implement me.
+ return "";
+ }
+
+ // =========== IConvertible Methods =========== //
+
+ public TypeCode GetTypeCode ()
+ {
+ return TypeCode.UInt64;
+ }
+ }
+}
diff --git a/mcs/class/corlib/System/Unix.cs b/mcs/class/corlib/System/Unix.cs
new file mode 100644
index 00000000000..6000648c194
--- /dev/null
+++ b/mcs/class/corlib/System/Unix.cs
@@ -0,0 +1,80 @@
+//------------------------------------------------------------------------------
+//
+// System.Private.Unix.cs
+//
+// Copyright (C) 2001 Moonlight Enterprises, All Rights Reserved
+//
+// Author: Jim Richardson, develop@wtfo-guru.com
+// Created: Tuesday, August 21, 2001
+//
+//------------------------------------------------------------------------------
+using System;
+using System.IO;
+using System.Diagnostics;
+using System.Runtime.InteropServices;
+
+namespace System
+{
+ public sealed class PlatformSpecific
+ {
+ /// <summary>
+ /// Gets the standard new line value
+ /// </summary>
+ public static string NewLine
+ {
+ get
+ {
+ return "\n";
+ }
+ }
+
+ [ DllImport("libc", EntryPoint="getpid") ]
+ private extern static int getPid();
+
+ private static char[] getPidFileContents(string fileName, ref int length)
+ {
+ Int32 pid = getPid();
+ // TODO: Use a special folder define probably for the proc folder
+ string path = Path.Combine("/proc", pid.ToString());
+ path = Path.Combine(path, fileName);
+ StreamReader stream = File.OpenText(path);
+ FileInfo finfo = new FileInfo(path);
+ length = (int)finfo.Length;
+ char[] buffer = new char[length];
+ stream.Read(buffer, 0, length);
+ return buffer;
+ }
+
+ public static string getEnvironment()
+ {
+ // couldn't DllImport environ from libc because it was a
+ // global variable not a method couldn't find another
+ // way to access unsafe globals
+ // definitely a candidate for "libmono"
+
+ string strEnv = null;
+
+ try
+ {
+ int length = 0;
+ char[] arEnv = getPidFileContents("environ", ref length);
+
+ for(int i = 0; i < length - 1; i++)
+ {
+ if(arEnv[i] == '\0')
+ {
+ arEnv[i] = '\t'; // safer delimeter
+ }
+ }
+ strEnv = new string(arEnv);
+ //Console.WriteLine(str);
+ }
+ catch(Exception e)
+ {
+ Debug.WriteLine(e.ToString());
+ strEnv = null;
+ }
+ return strEnv;
+ }
+ }
+} \ No newline at end of file
diff --git a/mcs/class/corlib/System/ValueType.cs b/mcs/class/corlib/System/ValueType.cs
new file mode 100644
index 00000000000..1781418e2d5
--- /dev/null
+++ b/mcs/class/corlib/System/ValueType.cs
@@ -0,0 +1,66 @@
+//
+// System.ValueType.cs
+//
+// Author:
+// Miguel de Icaza (miguel@ximian.com)
+//
+// (C) Ximian, Inc. http://www.ximian.com
+//
+
+namespace System {
+
+ public abstract class ValueType {
+
+ // <summary>
+ // ValueType constructor
+ // </summary>
+ protected ValueType ()
+ {
+ }
+
+ // <summary>
+ // True if this instance and o represent the same type
+ // and have the same value.
+ // </summary>
+ public override bool Equals (object o)
+ {
+ if (o == null){
+ throw new ArgumentNullException ("Null argument to Equals");
+ }
+
+ if (o.GetType() != this.GetType())
+ return false;
+
+ // TODO:
+ // Now implement bit compare here.
+
+ // TODO: Implement me!
+ return false;
+ }
+
+ // <summary>
+ // Gets a hashcode for this value type using the
+ // bits in the structure
+ // </summary>
+ public override int GetHashCode ()
+ {
+ if (this == null)
+ return 0;
+
+ // TODO: compute a hashcode based on the actual
+ // contents.
+
+ return 0;
+ }
+
+ // <summary>
+ // Stringified representation of this ValueType.
+ // Must be overriden for better results, by default
+ // it just returns the Type name.
+ // </summary>
+ public override string ToString ()
+ {
+ return GetType().FullName;
+ }
+ }
+}
diff --git a/mcs/class/corlib/System/Version.cs b/mcs/class/corlib/System/Version.cs
new file mode 100644
index 00000000000..72dda550fba
--- /dev/null
+++ b/mcs/class/corlib/System/Version.cs
@@ -0,0 +1,195 @@
+//
+// System.Version.cs
+//
+// Author:
+// Miguel de Icaza (miguel@ximian.com)
+//
+// (C) Ximian, Inc. http://www.ximian.com
+//
+
+namespace System {
+
+ public sealed class Version : ICloneable, IComparable {
+ int major, minor, build, revision;
+
+ const int MAXINT = int.MaxValue;
+
+ public Version (string version)
+ {
+ int n;
+ string [] vals = version.Split (new Char [] {'.'});
+
+ n = vals.Length;
+ if (n > 0)
+ major = int.Parse (vals [0]);
+ if (n > 1)
+ minor = int.Parse (vals [1]);
+ if (n > 2)
+ build = int.Parse (vals [2]);
+ if (n > 3)
+ revision = int.Parse (vals [3]);
+ }
+
+ public Version (int major, int minor)
+ {
+ this.major = major;
+ this.minor = minor;
+ this.build = MAXINT;
+ this.revision = MAXINT;
+ }
+
+ public Version (int major, int minor, int build)
+ {
+ this.major = major;
+ this.minor = minor;
+ this.build = build;
+ this.revision = MAXINT;
+ }
+
+ public Version (int major, int minor, int build, int revision)
+ {
+ this.major = major;
+ this.minor = minor;
+ this.build = build;
+ this.revision = revision;
+ }
+
+ public int Build {
+ get {
+ return build;
+ }
+ }
+
+ public int Major {
+ get {
+ return major;
+ }
+ }
+
+ public int Minor {
+ get {
+ return minor;
+ }
+ }
+
+ public int Revision {
+ get {
+ return revision;
+ }
+ }
+
+ public object Clone ()
+ {
+ return new Version (major, minor, build, revision);
+ }
+
+ public int CompareTo (object version)
+ {
+ Version v;
+
+ if (version == null)
+ throw new ArgumentNullException ("version");
+ if (! (version is Version))
+ throw new ArgumentException ("version");
+
+ v = version as Version;
+
+ if (this.major > v.major)
+ return 1;
+ else if (this.major < v.major)
+ return -1;
+
+ if (this.minor > v.minor)
+ return 1;
+ else if (this.minor < this.minor)
+ return -1;
+
+ if (this.build > v.build)
+ return 1;
+ else if (this.build < this.build)
+ return -1;
+
+ // FIXME: Compare revision or build first?
+ if (this.revision > v.revision)
+ return 1;
+ else if (this.revision < v.revision)
+ return -1;
+
+ return 0;
+ }
+
+ public override bool Equals (object obj)
+ {
+ Version x;
+
+ if (obj == null)
+ throw new ArgumentNullException ("obj");
+ if (!(obj is Version))
+ return false;
+
+ x = (Version) obj;
+
+ if ((x.major == major) &&
+ (x.minor == minor) &&
+ (x.build == build) &&
+ (x.revision == revision))
+ return true;
+ return false;
+ }
+
+ public override int GetHashCode ()
+ {
+ return (revision << 24) | (build << 16) | (minor << 8) | major;
+ }
+
+ // <summary>
+ // Returns a stringified representation of the version, format:
+ // major.minor[.build[.revision]]
+ // </summary>
+ public override string ToString ()
+ {
+ string mm = major.ToString () + "." + minor.ToString ();
+
+ if (build != MAXINT)
+ mm = mm + "." + build.ToString ();
+ if (revision != MAXINT)
+ mm = mm + "." + revision.ToString ();
+
+ return mm;
+ }
+
+ // <summary>
+ // LAME: This API is lame, since there is no way of knowing
+ // how many fields a Version object has, it is unfair to throw
+ // an ArgumentException, but this is what the spec claims.
+ //
+ // ie, Version a = new Version (1, 2); a.ToString (3) should
+ // throw the expcetion.
+ // </summary>
+ public string ToString (int fields)
+ {
+ if (fields == 0)
+ return "";
+ if (fields == 1)
+ return major.ToString ();
+ if (fields == 2)
+ return major.ToString () + "." + minor.ToString ();
+ if (fields == 3){
+ if (build == MAXINT)
+ throw new ArgumentException ("fields is larger than the number of components defined in this instance");
+ return major.ToString () + "." + minor.ToString () + "." +
+ build.ToString ();
+ }
+ if (fields == 4){
+ if (build == MAXINT || revision == MAXINT)
+ throw new ArgumentException ("fields is larger than the number of components defined in this instance");
+ return major.ToString () + "." + minor.ToString () + "." +
+ build.ToString () + "." + revision.ToString ();
+ }
+ throw new ArgumentException ("Invalid fields parameter: " + fields.ToString());
+ }
+ }
+}
+
+
+
diff --git a/mcs/class/corlib/System/Void.cs b/mcs/class/corlib/System/Void.cs
new file mode 100644
index 00000000000..1ad4e1c5b2c
--- /dev/null
+++ b/mcs/class/corlib/System/Void.cs
@@ -0,0 +1,14 @@
+//
+// System.Void.cs
+//
+// Author:
+// Miguel de Icaza (miguel@ximian.com)
+//
+// (C) Ximian, Inc. http://www.ximian.com
+//
+
+namespace System {
+
+ public struct Void {
+ }
+}
diff --git a/mcs/class/corlib/System/Windows.cs b/mcs/class/corlib/System/Windows.cs
new file mode 100644
index 00000000000..91a8f3b4f32
--- /dev/null
+++ b/mcs/class/corlib/System/Windows.cs
@@ -0,0 +1,101 @@
+//------------------------------------------------------------------------------
+//
+// System.Private.Windows.cs
+//
+// Copyright (C) 2001 Moonlight Enterprises, All Rights Reserved
+//
+// Author: Jim Richardson, develop@wtfo-guru.com
+// Created: Tuesday, August 21, 2001
+//
+//------------------------------------------------------------------------------
+
+using System;
+using System.Diagnostics;
+using System.Runtime.InteropServices;
+
+namespace System
+{
+ public sealed class PlatformSpecific
+ {
+ /// <summary>
+ /// Gets the standard new line value
+ /// </summary>
+ public static string NewLine
+ {
+ get
+ {
+ return "\r\n";
+ }
+ }
+
+ // TODO: verify the "W" versions are available on 95/98/ME
+ // or whatever other windoze platforms we'll target
+ [ DllImport("kernel32", EntryPoint="GetEnvironmentStringsW") ]
+ private extern static IntPtr getEnvironStrings();
+ [ DllImport("kernel32", EntryPoint="FreeEnvironmentStringsW") ]
+ private extern static int freeEnvironStrings(IntPtr p);
+
+ public static string getEnvironment()
+ {
+ IntPtr pEnv = getEnvironStrings();
+ int start = 0;
+ int offset = 0;
+ int length = 0;
+ int consecutive_nulls = 0;
+ int null_count = 0;
+ char ch;
+ string strEnv = null;
+
+ try
+ {
+ // the first string is just the process identifer, etc.
+ // the array of strings ends with double (perhaps) triple null
+ // if we read too far before we reach the end an exception will
+ // surely be thrown
+ while(length == 0)
+ {
+ ch = (char)System.Runtime.InteropServices.Marshal.ReadInt16(pEnv, offset);
+
+ offset += 2;
+
+ if(ch == '\0')
+ {
+ null_count++;
+ consecutive_nulls++;
+ if(start == 0 && null_count > 1)
+ { // we skip the first two windows strings
+ // because they aren't environment variables
+ start = offset;
+ }
+ if(consecutive_nulls > 1)
+ { // TODO: verify this length is exactly correct
+ // this was a quickie calculation that worked
+ length = offset - (consecutive_nulls + start);
+ }
+ }
+ else
+ {
+ consecutive_nulls = 0;
+ }
+ }
+
+ char[] arEnv = new char[length];
+ int index;
+ for(offset = start, index = 0; index < length; offset += 2, index++)
+ {
+ ch = (char)System.Runtime.InteropServices.Marshal.ReadInt16(pEnv, offset);
+ arEnv[index] = ch == '\0' ? '\n' : ch;
+ }
+ strEnv = new string(arEnv);
+ //Console.WriteLine(str);
+ }
+ catch(Exception ex)
+ {
+ Debug.WriteLine(ex.ToString());
+ strEnv = null;
+ }
+ freeEnvironStrings(pEnv);
+ return strEnv;
+ }
+ }
+} \ No newline at end of file
diff --git a/mcs/class/corlib/System/common.src b/mcs/class/corlib/System/common.src
new file mode 100755
index 00000000000..cf7f5173ae3
--- /dev/null
+++ b/mcs/class/corlib/System/common.src
@@ -0,0 +1,73 @@
+ApplicationException.cs
+ArgumentException.cs
+ArgumentNullException.cs
+ArgumentOutOfRangeException.cs
+ArithmeticException.cs
+Array.cs
+ArrayTypeMismatchException.cs
+Attribute.cs
+AttributeTargets.cs
+Boolean.cs
+Byte.cs
+Char.cs
+CLSCompliantAttribute.cs
+Convert.cs
+ContextStaticAttribute.cs
+DivideByZeroException.cs
+Double.cs
+DuplicateWaitObjectException.cs
+Environment.cs
+EventArgs.cs
+EventHandler.cs
+Exception.cs
+ExecutionEngineException.cs
+FlagsAttribute.cs
+FormatException.cs
+ICloneable.cs
+IComparable.cs
+IConvertible.cs
+ICustomFormatter.cs
+IDisposable.cs
+IFormatProvider.cs
+IFormattable.cs
+IndexOutOfRangeException.cs
+Int16.cs
+Int32.cs
+Int64.cs
+IntPtr.cs
+InvalidCastException.cs
+InvalidOperationException.cs
+InvalidProgramException.cs
+IServiceProvider.cs
+Math.cs
+MulticastNotSupportedException.cs
+NotFiniteNumberException.cs
+NotSupportedException.cs
+NullReferenceException.cs
+Object.cs
+OperatingSystem.cs
+OutOfMemoryException.cs
+OverflowException.cs
+PlatformID.cs
+RankException.cs
+SByte.cs
+Single.cs
+StackOverflowException.cs
+String.cs
+SystemException.cs
+TypeCode.cs
+UInt16.cs
+UInt32.cs
+UInt64.cs
+Version.cs
+Void.cs
+DateTime.cs
+Delegate.cs
+Enum.cs
+MulticastDelegate.cs
+ParamArrayAttribute.cs
+RuntimeTypeHandle.cs
+Type.cs
+TypeInitializationException.cs
+ValueType.cs
+MarshalByRefObject.cs
diff --git a/mcs/class/corlib/System/mono.src b/mcs/class/corlib/System/mono.src
new file mode 100644
index 00000000000..3af1fbc116e
--- /dev/null
+++ b/mcs/class/corlib/System/mono.src
@@ -0,0 +1,10 @@
+DateTime.cs
+Delegate.cs
+Enum.cs
+MulticastDelegate.cs
+ParamArrayAttribute.cs
+RuntimeTypeHandle.cs
+Type.cs
+TypeInitializationException.cs
+ValueType.cs
+MarshalByRefObject.cs
diff --git a/mcs/class/corlib/System/unix.src b/mcs/class/corlib/System/unix.src
new file mode 100755
index 00000000000..88f35a4d7a5
--- /dev/null
+++ b/mcs/class/corlib/System/unix.src
@@ -0,0 +1 @@
+Unix.cs
diff --git a/mcs/class/corlib/System/windows.src b/mcs/class/corlib/System/windows.src
new file mode 100755
index 00000000000..0d684bc2f87
--- /dev/null
+++ b/mcs/class/corlib/System/windows.src
@@ -0,0 +1 @@
+Windows.cs
diff --git a/mcs/class/corlib/Test/BitArrayTest.cs b/mcs/class/corlib/Test/BitArrayTest.cs
new file mode 100644
index 00000000000..a18bd8d12af
--- /dev/null
+++ b/mcs/class/corlib/Test/BitArrayTest.cs
@@ -0,0 +1,272 @@
+//
+// BitArrayTest.cs - NUnit Test Cases for the System.Collections.BitArray class
+//
+// Author: David Menestrina (dmenest@yahoo.com)
+//
+
+using NUnit.Framework;
+using System.Collections;
+using System;
+
+public class BitArrayTest : TestCase
+{
+ private BitArray testBa;
+ private bool [] testPattern;
+ private BitArray op1;
+ private BitArray op2;
+
+ private void verifyPattern(BitArray ba, bool[] pattern)
+ {
+ AssertEquals(ba.Length, pattern.Length);
+ for (int i = 0; i < pattern.Length; i++)
+ AssertEquals(ba[i], pattern[i]);
+ }
+
+ public BitArrayTest( string name ) : base(name) { }
+
+ protected override void SetUp()
+ {
+ testPattern = new bool[70];
+
+ int i;
+ for(i = 0; i < testPattern.Length/2; i++)
+ testPattern[i] = ((i % 2) == 0);
+ for(; i < testPattern.Length; i++)
+ testPattern[i] = ((i % 2) != 0);
+
+ testBa = new BitArray(70);
+ for(i = 0; i < testBa.Length/2; i++)
+ testBa[i] = ((i % 2) == 0);
+ for(; i < testBa.Length; i++)
+ testBa[i] = ((i % 2) != 0);
+
+ // for TestAnd, TestOr, TestNot, TestXor
+ op1 = new BitArray(new int[] { 0x33333333, 0x33333333 });
+ op2 = new BitArray(new int[] { 0x66666666, 0x66666666 });
+ }
+
+ public void TestBoolConstructor()
+ {
+ BitArray ba = new BitArray(testPattern);
+ verifyPattern(ba, testPattern);
+ }
+
+ public void TestCopyConstructor()
+ {
+ BitArray ba = new BitArray(testBa);
+
+ verifyPattern(ba, testPattern);
+ }
+
+ public void TestByteConstructor()
+ {
+ byte [] byteArr = new byte[] { 0xaa, 0x55, 0xaa, 0x55, 0x80 };
+ BitArray ba = new BitArray(byteArr);
+
+ AssertEquals(ba.Length, byteArr.Length * 8);
+
+ // spot check
+ Assert(ba[7]);
+ Assert(!ba[6]);
+ Assert(!ba[15]);
+ Assert(ba[14]);
+ Assert(ba[39]);
+ Assert(!ba[35]);
+
+ }
+
+ public void TestIntConstructor()
+ {
+ int [] intArr = new int[] { ~0x55555555, 0x55555551 };
+ BitArray ba = new BitArray(intArr);
+
+ AssertEquals(ba.Length, intArr.Length * 32);
+
+ // spot check
+
+ Assert(ba[31]);
+ Assert(!ba[30]);
+ Assert(!ba[63]);
+ Assert(ba[62]);
+ Assert(ba[32]);
+ Assert(!ba[35]);
+ }
+
+ public void TestValConstructor()
+ {
+ BitArray ba = new BitArray(64, false);
+
+ AssertEquals(ba.Length, 64);
+ foreach (bool b in ba)
+ Assert(!b);
+
+ ba = new BitArray(64, true);
+
+ AssertEquals(ba.Length, 64);
+ foreach (bool b in ba)
+ Assert(b);
+ }
+
+ public void TestClone()
+ {
+ BitArray ba = (BitArray)testBa.Clone();
+
+ verifyPattern(ba, testPattern);
+
+ // ensure that changes in ba don't get propagated to testBa
+ ba[0] = false;
+ ba[1] = false;
+ ba[2] = false;
+
+ verifyPattern(testBa, testPattern);
+ }
+
+ public void TestSetLength()
+ {
+ int origLen = testBa.Length;
+ testBa.Length += 33;
+
+ AssertEquals(origLen + 33, testBa.Length);
+ for (int i = origLen; i < testBa.Length; i++)
+ testBa[i] = true;
+
+ testBa.Length -= 33;
+ verifyPattern(testBa, testPattern);
+ }
+
+ public void TestAnd()
+ {
+ BitArray result = op1.And(op2);
+ AssertEquals(result.Length, op1.Length);
+ for (int i = 0; i < result.Length; )
+ {
+ Assert(!result[i++]);
+ Assert(result[i++]);
+ Assert(!result[i++]);
+ Assert(!result[i++]);
+ }
+ }
+
+ public void TestOr()
+ {
+ BitArray result = op1.Or(op2);
+ AssertEquals(result.Length, op1.Length);
+ for (int i = 0; i < result.Length; )
+ {
+ Assert(result[i++]);
+ Assert(result[i++]);
+ Assert(result[i++]);
+ Assert(!result[i++]);
+ }
+ }
+
+ public void TestNot()
+ {
+ BitArray result = op1.Not();
+ AssertEquals(result.Length, op1.Length);
+ for (int i = 0; i < result.Length; )
+ {
+ Assert(!result[i++]);
+ Assert(!result[i++]);
+ Assert(result[i++]);
+ Assert(result[i++]);
+ }
+ }
+
+ public void TestXor()
+ {
+ BitArray result = op1.Xor(op2);
+ AssertEquals(result.Length, op1.Length);
+ for (int i = 0; i < result.Length; )
+ {
+ Assert(result[i++]);
+ Assert(!result[i++]);
+ Assert(result[i++]);
+ Assert(!result[i++]);
+ }
+ }
+
+ public void TestSetAll()
+ {
+ testBa.SetAll(false);
+ foreach(bool b in testBa)
+ Assert(!b);
+ testBa.SetAll(true);
+ foreach(bool b in testBa)
+ Assert(b);
+ }
+
+ public void TestCopyToBool()
+ {
+ bool[] barray = new bool[testBa.Length + 10];
+
+ testBa.CopyTo(barray, 5);
+
+ for (int i = 0; i < testBa.Length; i++)
+ AssertEquals(testBa[i], barray[i+5]);
+ }
+
+ public void TestCopyToByte()
+ {
+ testBa.Length = 34;
+ byte[] barray = new byte[5 + 10];
+
+ testBa.CopyTo(barray, 5);
+
+ for (int i = 5; i < 9; i++)
+ AssertEquals(0x55, barray[i] & 0xff);
+
+ // FIXME: MS fails on the next line. This is because
+ // we truncated testBa.Length, and MS's internal array still
+ // has the old bits set. CopyTo() doesn't say specifically
+ // whether the "junk" bits (bits past Length, but within Length
+ // rounded up to 32) will be copied as 0, or if those bits are
+ // undefined.
+ //AssertEquals(0x01, barray[9] & 0xff);
+ }
+
+ public void TestCopyToInt()
+ {
+ testBa.Length = 34;
+ int[] iarray = new int[2 + 10];
+
+ testBa.CopyTo(iarray, 5);
+
+ AssertEquals(0x55555555, iarray[5]);
+ // FIXME: Same thing here as in TestCopyToByte
+ //AssertEquals(0x01, iarray[6]);
+ }
+
+ public void TestEnumerator()
+ {
+ IEnumerator e = testBa.GetEnumerator();
+
+ for (int i = 0; e.MoveNext(); i++)
+ AssertEquals(e.Current, testPattern[i]);
+
+ Assert(!e.MoveNext());
+ // read, to make sure reading isn't considered a write.
+ bool b = testBa[0];
+
+ e.Reset();
+ for (int i = 0; e.MoveNext(); i++)
+ AssertEquals(e.Current, testPattern[i]);
+
+ try
+ {
+ e.Reset();
+ testBa[0] = !testBa[0];
+ e.MoveNext();
+ Fail("IEnumerator.MoveNext() should throw when collection modified.");
+ }
+ catch (InvalidOperationException)
+ {
+ }
+ }
+}
+
+
+
+
+
+
diff --git a/mcs/class/corlib/Test/CaseInsensitiveComparerTest.cs b/mcs/class/corlib/Test/CaseInsensitiveComparerTest.cs
new file mode 100644
index 00000000000..5618cf58a2a
--- /dev/null
+++ b/mcs/class/corlib/Test/CaseInsensitiveComparerTest.cs
@@ -0,0 +1,62 @@
+// CaseInsensitiveComparerTest
+
+using System;
+using System.Collections;
+
+using NUnit.Framework;
+
+
+
+namespace Testsuite.System.Collections {
+
+
+ /// <summary>CaseInsensitiveComparer test suite.</summary>
+ public class CaseInsensitiveComparerTest {
+ public static ITest Suite {
+ get {
+ TestSuite suite = new TestSuite("CaseInsensitiveComparerTest tests");
+ suite.AddTest(CIComparerTestCase.Suite);
+ return suite;
+ }
+ }
+ }
+
+
+ public class CIComparerTestCase : TestCase {
+
+ public CIComparerTestCase (String name) : base(name)
+ {
+ }
+
+ protected override void SetUp ()
+ {
+ }
+
+ public static ITest Suite
+ {
+ get {
+ Console.WriteLine("Testing " + (new CaseInsensitiveComparer ()));
+ return new TestSuite(typeof(CIComparerTestCase));
+ }
+ }
+
+ public void TestDefaultInstance ()
+ {
+ // Make sure the instance returned by Default
+ // is really a CaseInsensitiveComparer.
+ Assert((CaseInsensitiveComparer.Default
+ as CaseInsensitiveComparer) != null);
+ }
+
+ public void TestCompare () {
+ CaseInsensitiveComparer cic = new CaseInsensitiveComparer ();
+
+ Assert(cic.Compare ("WILD WEST", "Wild West") == 0);
+ Assert(cic.Compare ("WILD WEST", "wild west") == 0);
+ Assert(cic.Compare ("Zeus", "Mars") > 0);
+ Assert(cic.Compare ("Earth", "Venus") < 0);
+ }
+
+ }
+
+}
diff --git a/mcs/class/corlib/Test/CaseInsensitiveHashCodeProviderTest.cs b/mcs/class/corlib/Test/CaseInsensitiveHashCodeProviderTest.cs
new file mode 100644
index 00000000000..3a506d17d9f
--- /dev/null
+++ b/mcs/class/corlib/Test/CaseInsensitiveHashCodeProviderTest.cs
@@ -0,0 +1,68 @@
+// CaseInsensitiveHashCodeProviderTest
+
+using System;
+using System.Collections;
+
+using NUnit.Framework;
+
+
+
+namespace Testsuite.System.Collections {
+
+
+ /// <summary>CaseInsensitiveHashCodeProvider test suite.</summary>
+ public class CaseInsensitiveHashCodeProviderTest {
+ public static ITest Suite {
+ get {
+ TestSuite suite = new TestSuite ("CaseInsensitiveHashCodeProviderTest tests");
+ suite.AddTest (CIHashCodeProviderTestCase.Suite);
+ return suite;
+ }
+ }
+ }
+
+
+ public class CIHashCodeProviderTestCase : TestCase {
+
+ public CIHashCodeProviderTestCase(String name) : base(name)
+ {
+ }
+
+ protected override void SetUp ()
+ {
+ }
+
+ public static ITest Suite
+ {
+ get {
+ Console.WriteLine("Testing " + (new CaseInsensitiveHashCodeProvider()));
+ return new TestSuite(typeof(CIHashCodeProviderTestCase));
+ }
+ }
+
+ public void TestDefaultInstance ()
+ {
+ // Make sure the instance returned by Default
+ // is really a CaseInsensitiveHashCodeProvider.
+ Assert((CaseInsensitiveHashCodeProvider.Default
+ as CaseInsensitiveHashCodeProvider) != null);
+ }
+
+ public void TestHashCode () {
+ CaseInsensitiveHashCodeProvider cih = new CaseInsensitiveHashCodeProvider ();
+ int h1 = cih.GetHashCode ("Test String");
+ int h2 = cih.GetHashCode ("test string");
+ int h3 = cih.GetHashCode ("TEST STRING");
+
+ Assert("Mixed Case != lower case", h1 == h2);
+ Assert("Mixed Case != UPPER CASE", h1 == h3);
+
+ h1 = cih.GetHashCode ("one");
+ h2 = cih.GetHashCode ("another");
+ // Actually this is quite possible.
+ Assert(h1 != h2);
+ }
+
+ }
+
+}
diff --git a/mcs/class/corlib/Test/CollectionBaseTest.cs b/mcs/class/corlib/Test/CollectionBaseTest.cs
new file mode 100644
index 00000000000..f627430b411
--- /dev/null
+++ b/mcs/class/corlib/Test/CollectionBaseTest.cs
@@ -0,0 +1,231 @@
+//
+// System.Collections.CollectionBase
+// Test suite for System.Collections.CollectionBase
+//
+// Author:
+// Nick D. Drochak II
+//
+// (C) 2001 Nick D. Drochak II
+//
+
+
+using System;
+using System.Collections;
+using NUnit.Framework;
+
+public class CollectionBaseTest : TestCase
+{
+ public CollectionBaseTest () : base ("System.Collection.CollectionBase testsuite") {}
+ public CollectionBaseTest (String name) : base (name) {}
+
+ // We need a concrete class to test the abstract base class
+ public class ConcreteCollection : CollectionBase
+ {
+ // These fields are used as markers to test the On* hooks.
+ public bool onClearFired;
+ public bool onClearCompleteFired;
+
+ public bool onInsertFired;
+ public int onInsertIndex;
+ public bool onInsertCompleteFired;
+ public int onInsertCompleteIndex;
+
+ public bool onRemoveFired;
+ public int onRemoveIndex;
+ public bool onRemoveCompleteFired;
+ public int onRemoveCompleteIndex;
+
+ public bool onSetFired;
+ public int onSetOldValue;
+ public int onSetNewValue;
+ public bool onSetCompleteFired;
+ public int onSetCompleteOldValue;
+ public int onSetCompleteNewValue;
+
+ // This constructor is used to test OnValid()
+ public ConcreteCollection()
+ {
+ IList listObj;
+ listObj = this;
+ listObj.Add(null);
+ }
+
+ // This constructor puts consecutive integers into the list
+ public ConcreteCollection(int i) {
+ IList listObj;
+ listObj = this;
+
+ int j;
+ for (j = 0; j< i; j++) {
+ listObj.Add(j);
+ }
+ }
+
+ // A helper method to look at a value in the list at a specific index
+ public int PeekAt(int index)
+ {
+ IList listObj;
+ listObj = this;
+ return (int) listObj[index];
+ }
+
+ // Mark the flag if this hook is fired
+ protected override void OnClear() {
+ this.onClearFired = true;
+ }
+
+ // Mark the flag if this hook is fired
+ protected override void OnClearComplete()
+ {
+ this.onClearCompleteFired = true;
+ }
+
+ // Mark the flag, and save the paramter if this hook is fired
+ protected override void OnInsert(int index, object value)
+ {
+ this.onInsertFired = true;
+ this.onInsertIndex = index;
+ }
+
+ // Mark the flag, and save the paramter if this hook is fired
+ protected override void OnInsertComplete(int index, object value)
+ {
+ this.onInsertCompleteFired = true;
+ this.onInsertCompleteIndex = index;
+ }
+
+ // Mark the flag, and save the paramter if this hook is fired
+ protected override void OnRemove(int index, object value)
+ {
+ this.onRemoveFired = true;
+ this.onRemoveIndex = index;
+ }
+
+ // Mark the flag, and save the paramter if this hook is fired
+ protected override void OnRemoveComplete(int index, object value)
+ {
+ this.onRemoveCompleteFired = true;
+ this.onRemoveCompleteIndex = index;
+ }
+
+ // Mark the flag, and save the paramters if this hook is fired
+ protected override void OnSet(int index, object oldValue, object newValue)
+ {
+ this.onSetFired = true;
+ this.onSetOldValue = (int) oldValue;
+ this.onSetNewValue = (int) newValue;
+ }
+
+ // Mark the flag, and save the paramters if this hook is fired
+ protected override void OnSetComplete(int index, object oldValue, object newValue)
+ {
+ this.onSetCompleteFired = true;
+ this.onSetCompleteOldValue = (int) oldValue;
+ this.onSetCompleteNewValue = (int) newValue;
+ }
+ } // public class ConcreteCollection
+
+ public static ITest Suite {
+ get {
+ return new TestSuite (typeof(CollectionBaseTest));
+ }
+ }
+
+ // Check the count property
+ public void TestCount() {
+ ConcreteCollection myCollection;
+ myCollection = new ConcreteCollection(4);
+ Assert(4 == myCollection.Count);
+ }
+
+ // Make sure GetEnumerator returns an object
+ public void TestGetEnumerator() {
+ ConcreteCollection myCollection;
+ myCollection = new ConcreteCollection(4);
+ Assert(null != myCollection.GetEnumerator());
+ }
+
+ // OnValid disallows nulls
+ public void TestOnValid() {
+ ConcreteCollection myCollection;
+ try {
+ myCollection = new ConcreteCollection();
+ }
+ catch (System.ArgumentNullException) {
+ }
+ }
+
+ // Test various Insert paths
+ public void TestInsert() {
+ ConcreteCollection myCollection;
+ int numberOfItems;
+ numberOfItems = 3;
+ // The constructor inserts
+ myCollection = new ConcreteCollection(numberOfItems);
+ Assert(myCollection.onInsertFired);
+ Assert(myCollection.onInsertCompleteFired);
+
+ // Using the IList interface, check inserts in the middle
+ IList listObj = myCollection;
+ listObj.Insert(1, 9);
+ Assert(myCollection.onInsertIndex == 1);
+ Assert(myCollection.onInsertCompleteIndex == 1);
+ Assert(myCollection.PeekAt(1) == 9);
+ }
+
+ // Test Clear and it's hooks
+ public void TestClear()
+ {
+ ConcreteCollection myCollection;
+ int numberOfItems;
+ numberOfItems = 1;
+ myCollection = new ConcreteCollection(numberOfItems);
+ myCollection.Clear();
+ Assert(myCollection.Count == 0);
+ Assert(myCollection.onClearFired);
+ Assert(myCollection.onClearCompleteFired);
+ }
+
+ // Test RemoveAt, other removes and the hooks
+ public void TestRemove()
+ {
+ ConcreteCollection myCollection;
+ int numberOfItems;
+ numberOfItems = 3;
+ // Set up a test collection
+ myCollection = new ConcreteCollection(numberOfItems);
+
+ // The list is 0-based. So if we remove the second one
+ myCollection.RemoveAt(1);
+
+ // We should see the original third one in it's place
+ Assert(myCollection.PeekAt(1) == 2);
+ Assert(myCollection.onRemoveFired);
+ Assert(myCollection.onRemoveIndex == 1);
+ Assert(myCollection.onRemoveCompleteFired);
+ Assert(myCollection.onRemoveCompleteIndex == 1);
+ IList listObj = myCollection;
+ listObj.Remove(0);
+ // Confirm parameters are being passed to the hooks
+ Assert(myCollection.onRemoveIndex == 0);
+ Assert(myCollection.onRemoveCompleteIndex == 0);
+ }
+
+ // Test the random access feature
+ public void TestSet()
+ {
+ ConcreteCollection myCollection;
+ int numberOfItems;
+ numberOfItems = 3;
+ myCollection = new ConcreteCollection(numberOfItems);
+ IList listObj = myCollection;
+ listObj[0] = 99;
+ Assert((int) listObj[0] == 99);
+ Assert(myCollection.onSetFired);
+ Assert(myCollection.onSetCompleteFired);
+ Assert(myCollection.onSetOldValue == 0);
+ Assert(myCollection.onSetCompleteOldValue == 0);
+ Assert(myCollection.onSetNewValue == 99);
+ Assert(myCollection.onSetCompleteNewValue == 99);
+ }
+}
diff --git a/mcs/class/corlib/Test/ComparerTest.cs b/mcs/class/corlib/Test/ComparerTest.cs
new file mode 100644
index 00000000000..3defdb4229a
--- /dev/null
+++ b/mcs/class/corlib/Test/ComparerTest.cs
@@ -0,0 +1,72 @@
+// ComparerTest
+
+using System;
+using System.Collections;
+
+using NUnit.Framework;
+
+
+
+namespace Testsuite.System.Collections {
+
+
+ /// <summary>Comparer test suite.</summary>
+ public class ComparerTest {
+ public static ITest Suite {
+ get {
+ TestSuite suite = new TestSuite ("Comparer tests");
+ suite.AddTest (ComparerTestCase.Suite);
+ return suite;
+ }
+ }
+ }
+
+
+ public class ComparerTestCase : TestCase {
+
+ public ComparerTestCase (String name) : base(name)
+ {
+ }
+
+ protected override void SetUp ()
+ {
+ }
+
+ public static ITest Suite
+ {
+ get {
+ Console.WriteLine("Testing " + Comparer.Default);
+ return new TestSuite(typeof(ComparerTestCase));
+ }
+ }
+
+ public void TestDefaultInstance ()
+ {
+ // Make sure the instance returned by Default
+ // is really a Comparer.
+ Assert((Comparer.Default as Comparer) != null);
+ }
+
+ public void TestCompare ()
+ {
+ Comparer c = Comparer.Default;
+
+ bool thrown = false;
+
+ try {
+ c.Compare (new Object (), new Object ());
+ } catch (ArgumentException) {
+ thrown = true;
+ }
+
+ Assert("ArgumentException expected", thrown);
+
+ Assert(c.Compare (1, 2) < 0);
+ Assert(c.Compare (2, 2) == 0);
+ Assert(c.Compare (3, 2) > 0);
+
+ }
+
+ }
+
+}
diff --git a/mcs/class/corlib/Test/HashtableTest.cs b/mcs/class/corlib/Test/HashtableTest.cs
new file mode 100644
index 00000000000..0ecd689b457
--- /dev/null
+++ b/mcs/class/corlib/Test/HashtableTest.cs
@@ -0,0 +1,202 @@
+// HashtableTest
+
+using System;
+using System.Collections;
+
+using NUnit.Framework;
+
+
+namespace Testsuite.System.Collections {
+
+
+ /// <summary>Hashtable test.</summary>
+ public class HashtableTest {
+ public static ITest Suite {
+ get {
+ TestSuite suite = new TestSuite("All Hashtable tests");
+ suite.AddTest(HTBasicOperationsTest.Suite);
+ return suite;
+ }
+ }
+ }
+
+
+
+
+ public class HTBasicOperationsTest : TestCase {
+
+ protected Hashtable ht;
+ private static Random rnd;
+
+ public HTBasicOperationsTest (String name) : base(name)
+ {
+ }
+
+ protected override void SetUp ()
+ {
+ ht=new Hashtable ();
+ rnd=new Random ();
+ }
+
+ public static ITest Suite
+ {
+ get {
+ return new TestSuite (typeof(HTBasicOperationsTest));
+ }
+ }
+
+
+
+ private void SetDefaultData ()
+ {
+ ht.Clear ();
+ ht.Add ("k1","another");
+ ht.Add ("k2","yet");
+ ht.Add ("k3","hashtable");
+ }
+
+
+ public void TestAddRemoveClear ()
+ {
+ ht.Clear ();
+ Assert (ht.Count == 0);
+
+ SetDefaultData ();
+ Assert (ht.Count == 3);
+
+ bool thrown=false;
+ try {
+ ht.Add ("k2","cool");
+ } catch (ArgumentException) {thrown=true;}
+ Assert("Must throw ArgumentException!",thrown);
+
+ ht["k2"]="cool";
+ Assert(ht.Count == 3);
+ Assert(ht["k2"].Equals("cool"));
+
+ }
+
+ public void TestCopyTo ()
+ {
+ SetDefaultData ();
+ Object[] entries=new Object[ht.Count];
+ ht.CopyTo (entries,0);
+ Assert("Not an entry.",entries[0] is DictionaryEntry);
+ }
+
+
+ public void TestUnderHeavyLoad ()
+ {
+ Console.WriteLine ("Testing "+ht);
+ ht.Clear ();
+
+ int max=100000;
+ String[] cache=new String[max*2];
+ int n=0;
+
+ for (int i=0;i<max;i++) {
+ int id=rnd.Next()&0xFFFF;
+ String key=""+id+"-key-"+id;
+ String val="value-"+id;
+ if (ht[key]==null) {
+ ht[key]=val;
+ cache[n]=key;
+ cache[n+max]=val;
+ n++;
+ }
+ }
+
+ Assert(ht.Count==n);
+
+ for (int i=0;i<n;i++) {
+ String key=cache[i];
+ String val=ht[key] as String;
+ String err="ht[\""+key+"\"]=\""+val+
+ "\", expected \""+cache[i+max]+"\"";
+ Assert(err,val!=null && val.Equals(cache[i+max]));
+ }
+
+ int r1=(n/3);
+ int r2=r1+(n/5);
+
+ for (int i=r1;i<r2;i++) {
+ ht.Remove(cache[i]);
+ }
+
+
+ for (int i=0;i<n;i++) {
+ if (i>=r1 && i<r2) {
+ Assert(ht[cache[i]]==null);
+ } else {
+ String key=cache[i];
+ String val=ht[key] as String;
+ String err="ht[\""+key+"\"]=\""+val+
+ "\", expected \""+cache[i+max]+"\"";
+ Assert(err,val!=null && val.Equals(cache[i+max]));
+ }
+ }
+
+ ICollection keys=ht.Keys;
+ int nKeys=0;
+ foreach (Object key in keys) {
+ Assert((key as String) != null);
+ nKeys++;
+ }
+ Assert(nKeys==ht.Count);
+
+
+ ICollection vals=ht.Values;
+ int nVals=0;
+ foreach (Object val in vals) {
+ Assert((val as String) != null);
+ nVals++;
+ }
+ Assert(nVals==ht.Count);
+
+ }
+
+ /// <summary>
+ /// Test hashtable with CaseInsensitiveHashCodeProvider
+ /// and CaseInsensitive comparer.
+ /// </summary>
+ public void TestCaseInsensitive ()
+ {
+ // Not very meaningfull test, just to make
+ // sure that hcp is set properly set.
+ Hashtable ciHashtable = new Hashtable(11,1.0f,CaseInsensitiveHashCodeProvider.Default,CaseInsensitiveComparer.Default);
+ ciHashtable ["key1"] = "value";
+ ciHashtable ["key2"] = "VALUE";
+ Assert(ciHashtable ["key1"].Equals ("value"));
+ Assert(ciHashtable ["key2"].Equals ("VALUE"));
+
+ ciHashtable ["KEY1"] = "new_value";
+ Assert(ciHashtable ["key1"].Equals ("new_value"));
+
+ }
+
+
+ public void TestCopyConstructor ()
+ {
+ SetDefaultData ();
+
+ Hashtable htCopy = new Hashtable (ht);
+
+ Assert(ht.Count == htCopy.Count);
+ }
+
+
+ public void TestEnumerator ()
+ {
+ SetDefaultData ();
+
+ IEnumerator e = ht.GetEnumerator ();
+
+ while (e.MoveNext ()) {}
+
+ Assert (!e.MoveNext ());
+
+ }
+
+
+ }
+}
diff --git a/mcs/class/corlib/Test/MemoryStreamTest.cs b/mcs/class/corlib/Test/MemoryStreamTest.cs
new file mode 100644
index 00000000000..0b91645dcf7
--- /dev/null
+++ b/mcs/class/corlib/Test/MemoryStreamTest.cs
@@ -0,0 +1,128 @@
+//
+// System.IO.StringWriter
+//
+// Author: Marcin Szczepanski (marcins@zipworld.com.au)
+//
+// TODO: Add some testing for exceptions
+//
+// TODO: Add some testing for the CanXXX properties, exceptions,
+// various different constructors.
+//
+
+using NUnit.Framework;
+using System.IO;
+using System;
+using System.Text;
+
+public class MemoryStreamTest : TestCase {
+
+ private MemoryStream testStream;
+ private byte[] testStreamData;
+
+ public MemoryStreamTest( string name ): base(name) { }
+
+ protected override void SetUp() {
+ testStreamData = new byte[100];
+
+ for( int i = 0; i < 100; i++ ) {
+ testStreamData[i] = (byte)(100 - i);
+ }
+
+ testStream = new MemoryStream( testStreamData );
+ }
+
+ public void TestConstructors() {
+ MemoryStream ms = new MemoryStream();
+
+ AssertEquals( 0, ms.Length );
+ AssertEquals( 0, ms.Capacity );
+ AssertEquals( true, ms.CanWrite );
+
+ ms = new MemoryStream( 10 );
+
+ // FIXME: Should ms.Length be 0 if there is no data?
+ // the spec is a little unclear. If this is changed then
+ // the code will probably need to change
+
+ AssertEquals( 10, ms.Length );
+ AssertEquals( 10, ms.Capacity );
+ }
+
+ //
+ // Verify that the first count bytes in testBytes are the same as
+ // the count bytes from index start in testStreamData
+ //
+ private void VerifyTestData( byte[] testBytes, int start, int count) {
+ if( testBytes == null ) {
+ throw new ArgumentNullException();
+ } else if( ( start < 0 || count < 0 ) || start + count > testStreamData.Length || start > testStreamData.Length ) {
+ throw new ArgumentOutOfRangeException();
+ }
+
+ for( int test = 0; test < count; test++ ) {
+ if( testBytes[ test ] != testStreamData[ start + test ] ) {
+ string failStr = String.Format( "testByte {0} (testStream {1}) was <{2}>, expecting <{3}>", test, start+test,
+ testBytes[ test ], testStreamData[ start+test] );
+ Fail( failStr );
+ }
+ }
+ }
+
+ public void TestRead() {
+ byte[] readBytes = new byte[20];
+
+ /* Test simple read */
+ testStream.Read( readBytes, 0, 10 );
+ VerifyTestData( readBytes, 0, 10 );
+
+ /* Seek back to beginning */
+
+ testStream.Seek( 0, SeekOrigin.Begin );
+
+ /* Read again, bit more this time */
+ testStream.Read( readBytes, 0, 20 );
+ VerifyTestData( readBytes, 0, 20 );
+
+ /* Seek to 20 bytes from End */
+ testStream.Seek( -20, SeekOrigin.End );
+ testStream.Read( readBytes, 0, 20);
+ VerifyTestData( readBytes, 80, 20);
+
+ int readByte = testStream.ReadByte();
+ AssertEquals( -1, readByte );
+
+ }
+
+ public void TestWriteBytes() {
+ byte[] readBytes = new byte[100];
+ MemoryStream ms = new MemoryStream( 100 );
+
+ for( int i = 0; i < 100; i++ ) {
+ ms.WriteByte( testStreamData[i] );
+ }
+
+ ms.Seek( 0, SeekOrigin.Begin);
+
+ testStream.Read( readBytes, 0, 100 );
+
+ VerifyTestData( readBytes, 0, 100 );
+ }
+
+ public void TestWriteBlock() {
+ byte[] readBytes = new byte[100];
+ MemoryStream ms = new MemoryStream( 100 );
+
+ ms.Write( testStreamData, 0, 100 );
+
+ ms.Seek( 0, SeekOrigin.Begin);
+
+ testStream.Read( readBytes, 0, 100 );
+
+ VerifyTestData( readBytes, 0, 100 );
+
+ byte[] arrayBytes = testStream.ToArray();
+
+ VerifyTestData( arrayBytes, 0, 100 );
+
+ }
+} \ No newline at end of file
diff --git a/mcs/class/corlib/Test/PathTest.cs b/mcs/class/corlib/Test/PathTest.cs
new file mode 100644
index 00000000000..52d9df06a1e
--- /dev/null
+++ b/mcs/class/corlib/Test/PathTest.cs
@@ -0,0 +1,138 @@
+//
+// System.IO.Path Test Cases
+//
+// Author: Marcin Szczepanski (marcins@zipworld.com.au)
+//
+// TODO: Add a more thorough workout for some
+// of the "trickier" functions.
+
+#define WINDOWS
+
+using NUnit.Framework;
+using System.IO;
+using System;
+using System.Text;
+
+public class PathTest : TestCase {
+
+ string path1;
+ string path2;
+ string path3;
+
+
+ public PathTest( string name ): base(name) { }
+
+ protected override void SetUp() {
+
+ #if WINDOWS
+
+ path1 = "c:\\foo\\test.txt";
+ path2 = "c:\\winnt";
+ path3 = "system32";
+
+ #elif UNIX
+
+ path1 = "/foo/test.txt";
+ path2 = "/etc";
+ path3 = "init.d"
+
+ #elif MAC
+
+ path1 = "foo:test.txt";
+ path2 = "foo";
+ path3 = "bar";
+
+ #endif
+
+ }
+
+
+ public void TestChangeExtension() {
+ string testPath = Path.ChangeExtension( path1, "doc" );
+
+ #if WINDOWS
+ AssertEquals( "c:\\foo\\test.doc", testPath );
+ #elif UNIX
+ AssertEquals( "/foo/test.doc", testPath );
+ #elif MAC
+ AssertEquals( "foo:test.doc", testPath );
+ #endif
+ }
+
+ public void TestCombine() {
+ string testPath = Path.Combine( path2, path3 );
+
+ #if WINDOWS
+ AssertEquals( "c:\\winnt\\system32", testPath );
+ #elif UNIX
+ AssertEquals( "/etc/init.d", testPath );
+ #elif MAC
+ AssertEquals( "foo:bar", testPath );
+ #endif
+ }
+
+ public void TestDirectoryName() {
+ string testDirName = Path.GetDirectoryName( path1 );
+
+ #if WINDOWS
+ AssertEquals( "c:\\foo", testDirName );
+ #elif UNIX
+ AssertEquals( "/etc", testDirName );
+ #elif MAC
+ AssertEquals( "foo", testDirName );
+ #endif
+ }
+
+ public void TestGetExtension() {
+ string testExtn = Path.GetExtension( path1 );
+
+ AssertEquals( ".txt", testExtn );
+
+ testExtn = Path.GetExtension( path2 );
+
+ AssertEquals ( "", testExtn );
+ }
+
+ public void TestGetFileName() {
+ string testFileName = Path.GetFileName( path1 );
+
+ AssertEquals( "test.txt", testFileName );
+ }
+
+ public void TestGetFileNameWithoutExtension() {
+ string testFileName = Path.GetFileNameWithoutExtension( path1 );
+
+ AssertEquals( "test", testFileName );
+ }
+
+ public void TestGetFullPath() {
+ string testFullPath = Path.GetFullPath( "foo.txt" );
+ // AssertEquals( "foo.txt", testFullPath );
+ }
+
+ public void TestGetTempPath() {
+ string getTempPath = Path.GetTempPath();
+ AssertEquals( Environment.GetEnvironmentVariable( "TEMP" ) + '\\', getTempPath );
+ }
+
+ /*
+ // Not sure what's an appropriate test for this function? Maybe just
+ // check if the temp file exists as advertised
+ //
+ public void TestGetTempFileName() {
+ string getTempFileName = Path.GetTempFileName();
+ //Console.WriteLine( getTempFileName );
+ }*/
+
+ public void TestHasExtension() {
+ AssertEquals( true, Path.HasExtension( "foo.txt" ) );
+ AssertEquals( false, Path.HasExtension( "foo" ) );
+ AssertEquals( true, Path.HasExtension( path1 ) );
+ AssertEquals( false, Path.HasExtension( path2 ) );
+ }
+
+ public void TestRooted() {
+ AssertEquals( true, Path.IsPathRooted( "c:\\winnt\\" ) );
+ AssertEquals( false, Path.IsPathRooted( "system32\\drivers\\" ) );
+ }
+}
diff --git a/mcs/class/corlib/Test/QueueTest.cs b/mcs/class/corlib/Test/QueueTest.cs
new file mode 100644
index 00000000000..eb6a7ac6fb3
--- /dev/null
+++ b/mcs/class/corlib/Test/QueueTest.cs
@@ -0,0 +1,176 @@
+//
+// System.Collections.QueueTest
+// Test suite for System.Collections.Queue
+//
+// Author:
+// Ricardo Fernández Pascual
+//
+// (C) 2001 Ricardo Fernández Pascual
+//
+
+
+
+using System;
+using System.Collections;
+using NUnit.Framework;
+
+namespace Testsuite.System.Collections {
+
+ public class QueueTest : TestCase {
+
+ public QueueTest () : base ("System.Collection.Queue testsuite") {}
+ public QueueTest (String name) : base (name) {}
+
+ protected Queue q1;
+ protected Queue q2;
+ protected Queue emptyQueue;
+
+ protected override void SetUp () {
+ q1 = new Queue (10);
+ for (int i = 0; i < 100; i++)
+ q1.Enqueue (i);
+
+ q2 = new Queue (50, 1.5);
+ for (int i = 50; i < 100; i++)
+ q2.Enqueue (i);
+
+ emptyQueue = new Queue ();
+ }
+
+ public static ITest Suite {
+ get {
+ return new TestSuite (typeof (QueueTest));
+ }
+ }
+
+ public void TestConstructors () {
+ Assert (q1.Count == 100);
+ Assert (q2.Count == 50);
+ Assert (emptyQueue.Count = 0);
+ // TODO: Test Queue (ICollection)
+ }
+
+ // TODO: should test all methods from ICollection,
+ // but it should be done in ICollectionTest.cs... ??
+
+ public void TestCopyTo () {
+ int[] a1 = new int[100];
+ int[] a2 = new int[60];
+
+ q1.CopyTo (a1, 0);
+ for (int i = 0; i < 100; i++)
+ AssertEquals (i, a1[i]);
+
+ // Remove some items from q2 and add other
+ // items, to avoid having an "easy" just created
+ // Queue
+ for (int i = 50; i < 60; i++)
+ Assert (i == (int) q2.Dequeue ());
+ for (int i = 100; i < 110; i++)
+ q2.Enqueue (i);
+
+ q2.CopyTo (a2, 10);
+ for (int i = 60; i < 110; i++)
+ Assert (i == a2[i - 60 + 10]);
+
+ // Copying an empty Queue should not modify the array
+ emptyQueue.CopyTo (a2, 10);
+ for (int i = 60; i < 110; i++)
+ Assert (i == a2[i - 60 + 10]);
+ }
+
+ public void TestEnumerator () {
+ int i;
+ IEnumerable e;
+ e = q1.GetEnumerator ();
+ i = 0;
+ while (e.MoveNext ()) {
+ Assert (e.Current () == i);
+ i++;
+ }
+ e = q2.GetEnumerator ();
+ i = 50;
+ while (e.MoveNext ()) {
+ Assert (e.Current () == i++);
+ i++;
+ }
+ e = emptyQueue.GetEnumerator ();
+ while (e.MoveNext ()) {
+ Fail ("Empty Queue enumarator returning elements!");
+ }
+ e = q1.GetEnumerator ();
+ try {
+ e.MoveNext ();
+ q1.Enqueue (0);
+ e.MoveNext ();
+ Fail ("Should have thrown InvalidOperationException");
+ } catch (InvalidOperationException e) {}
+ e = q1.GetEnumerator ();
+ try {
+ e.MoveNext ();
+ q1.Enqueue (0);
+ object o = e.Current ();
+ Fail ("Should have thrown InvalidOperationException");
+ } catch (InvalidOperationException e) {}
+ }
+
+ public void TestClone () {
+ Queue q3 = (Queue) q2.Clone ();
+ Assert (q3.Count == q2.Count);
+ for (int i = 0; i < 50; i++)
+ Assert (q2.Dequeue ().Equals (q3.Dequeue ()));
+ Assert (q3.Count == 0);
+ Assert (q2.Count == 0);
+ }
+
+ public void ClearTest () {
+ q1.Clear ();
+ Assert (q1.Count == 0);
+ q2.Clear ();
+ Assert (q2.Count == 0);
+ emptyQueue.Clear ();
+ Assert (emptyQueue.Count == 0);
+ }
+
+ public void ContainsTest () {
+ for (int i = 0; i < 100; i++) {
+ Assert (q1.Contains (i));
+ Assert (!emptyQueue.Contains (i));
+ if (i < 50)
+ Assert (!q2.Contains (i));
+ else
+ Assert (q2.Contains (i));
+ }
+ }
+
+ public void EnqueueDequeuePeekTest () {
+ int q1size = q1.Count;
+ int q2size = q2.Count;
+ q2.Enqueue (null);
+ Assert (q2.Count = ++q2size);
+ for (int i = 0; i < 50; i++) {
+ int k = q1.Peek ();
+ Assert (q1.Count == q1size);
+ int j = q1.Dequeue ();
+ Assert (q1.Count == --q1size);
+ Assert (i == j);
+ Assert (j == k);
+ q2.Enqueue (j);
+ Assert (q2.Count == ++q2size);
+ }
+ for (int i = 50; i < 100; i++) {
+ Assert (((int) q2.Dequeue ()) == i);
+ Assert (q2.Count == --q2size);
+ }
+ Assert (q2.Peek () == null);
+ Assert (q2.Dequeue () == null);
+ Assert (q2.Count == --q2size);
+ for (int i = 0; i < 50; i++) {
+ Assert (((int) q2.Dequeue ()) == i);
+ Assert (q2.Count == --q2size);
+ }
+ }
+
+ // TODO: test Syncronized operation
+ }
+}
diff --git a/mcs/class/corlib/Test/RandomTest.cs b/mcs/class/corlib/Test/RandomTest.cs
new file mode 100644
index 00000000000..a767915512d
--- /dev/null
+++ b/mcs/class/corlib/Test/RandomTest.cs
@@ -0,0 +1,68 @@
+//
+// System.Random Test Cases
+//
+// Author: Bob Smith <bob@thestuff.net>
+//
+
+using NUnit.Framework;
+using System;
+
+public class RandomTest : TestCase
+{
+ public RandomTest(string name): base(name){}
+ public void TestDouble()
+ {
+ Random r = new Random();
+ int i;
+ double c=0;
+ for (i=0; i<20; i++) c+=r.NextDouble();
+ c/=i;
+ Assert (c < .7 && c > .3);
+ }
+ public void TestSeed()
+ {
+ Random r = new Random(42);
+ Random r2 = new Random(42);
+ int i;
+ double c=0, c2=0;
+ for (i=0; i<20; i++)
+ {
+ c += r.NextDouble();
+ c2 += r2.NextDouble();
+ }
+ AssertEquals(c, c2);
+ }
+ public void TestNext()
+ {
+ Random r = new Random();
+ int i;
+ long c;
+ for (i=0; i<20; i++)
+ {
+ c = r.Next();
+ Assert (c < Int32.MaxValue && c >= 0);
+ }
+ }
+ public void TestNextMax()
+ {
+ Random r = new Random();
+ int i;
+ long c;
+ for (i=0; i<20; i++)
+ {
+ c = r.Next(10);
+ Assert (c < 10 && c >= 0);
+ }
+ }
+ public void TestNextMinMax()
+ {
+ Random r = new Random();
+ int i;
+ long c;
+ for (i=0; i<20; i++)
+ {
+ c = r.Next(1, 10);
+ Assert (c < 10 && c >= 1);
+ }
+ }
+}
diff --git a/mcs/class/corlib/Test/ReadOnlyCollectionBaseTest.cs b/mcs/class/corlib/Test/ReadOnlyCollectionBaseTest.cs
new file mode 100644
index 00000000000..48d72b4555a
--- /dev/null
+++ b/mcs/class/corlib/Test/ReadOnlyCollectionBaseTest.cs
@@ -0,0 +1,47 @@
+//
+// System.Collections.ReadOnlyCollectionBase
+// Test suite for System.Collections.ReadOnlyCollectionBase
+//
+// Author:
+// Nick D. Drochak II
+//
+// (C) 2001 Nick D. Drochak II
+//
+
+
+using System;
+using System.Collections;
+using NUnit.Framework;
+
+ public class ReadOnlyCollectionBaseTest : TestCase {
+ public ReadOnlyCollectionBaseTest () : base ("System.Collection.ReadOnlyCollectionBase testsuite") {}
+ public ReadOnlyCollectionBaseTest (String name) : base (name) {}
+
+ // We need a concrete class to test the abstract base class
+ public class ConcreteReadOnlyCollection : ReadOnlyCollectionBase
+ {
+ }
+
+ public static ITest Suite
+ {
+ get {
+ return new TestSuite (typeof(ReadOnlyCollectionBaseTest));
+ }
+ }
+
+ // Make sure that the Count is 0 for a new object
+ public void TestZeroCountOnNew()
+ {
+ ConcreteReadOnlyCollection myCollection;
+ myCollection = new ConcreteReadOnlyCollection();
+ Assert(0 == myCollection.Count);
+ }
+
+ // Make sure we get an object from GetEnumerator()
+ public void TestGetEnumerator()
+ {
+ ConcreteReadOnlyCollection myCollection;
+ myCollection = new ConcreteReadOnlyCollection();
+ Assert(null != myCollection.GetEnumerator());
+ }
+ }
diff --git a/mcs/class/corlib/Test/StackTest.cs b/mcs/class/corlib/Test/StackTest.cs
new file mode 100644
index 00000000000..1e631b1305f
--- /dev/null
+++ b/mcs/class/corlib/Test/StackTest.cs
@@ -0,0 +1,275 @@
+//
+// StackTest.cs
+//
+// Author:
+// Chris Hynes <chrish@assistedsolutions.com>
+//
+// (C) 2001 Chris Hynes
+//
+
+using System;
+
+using System.Collections;
+
+using NUnit.Framework;
+
+namespace Ximian.Mono.Tests
+{
+ public class StackTest: TestCase
+ {
+ private Stack stack1;
+ private Stack stack2;
+ private Stack stackInt;
+
+ public void TestConstructor()
+ {
+ AssertEquals(false, stack1 == null);
+ }
+
+ public void TestICollectionConstructor()
+ {
+ Stack stackTest = new Stack(new int[] {0, 1, 2, 3, 4});
+
+ for (int i = 4; i >= 0; i--)
+ AssertEquals(i, stackTest.Pop());
+
+ AssertEquals(0, stackTest.Count);
+ }
+
+ public void TestIntConstructor()
+ {
+ Stack stackTest = new Stack(50);
+
+ AssertEquals(false, stackTest == null);
+ }
+
+ public void TestCount()
+ {
+ Stack stackTest = new Stack();
+
+ stackTest.Push(50);
+ stackTest.Push(5);
+ stackTest.Push(0);
+ stackTest.Push(50);
+
+ AssertEquals(4, stackTest.Count);
+ }
+
+ public void TestIsReadOnly()
+ {
+ AssertEquals(false, stack1.IsReadOnly);
+ }
+
+ public void TestIsSyncronized()
+ {
+ AssertEquals(false, stack1.IsSynchronized);
+ AssertEquals(true, Stack.Synchronized(stack1).IsSynchronized);
+ }
+
+ public void TestSyncRoot()
+ {
+ AssertEquals(false, stack1.SyncRoot == null);
+ }
+
+ public void TestGetEnumerator()
+ {
+ stackInt.Pop();
+
+ int j = 3;
+
+ foreach (int i in stackInt)
+ {
+ AssertEquals(j--, i);
+ }
+
+ stackInt.Clear();
+
+ IEnumerator e = stackInt.GetEnumerator();
+
+ AssertEquals(false, e.MoveNext());
+ }
+
+ public void TestClear()
+ {
+ stackInt.Clear();
+
+ AssertEquals(0, stackInt.Count);
+ }
+
+ public void TestClone()
+ {
+ Stack clone = (Stack)stackInt.Clone();
+
+ while (stackInt.Count > 0)
+ {
+ AssertEquals(stackInt.Pop(), clone.Pop());
+ }
+ }
+
+ public void TestContains()
+ {
+ string toLocate = "test";
+
+ stackInt.Push(toLocate);
+
+ stackInt.Push("chaff");
+
+ Assert(stackInt.Contains(toLocate));
+
+ stackInt.Pop();
+
+ Assert(stackInt.Contains(toLocate));
+
+ stackInt.Pop();
+
+ Assert(!stackInt.Contains(toLocate));
+ }
+
+ public void TestCopyTo()
+ {
+ int[] arr = new int[stackInt.Count - 1];
+ int[,] arrMulti;
+
+ try
+ {
+ stackInt.CopyTo(null, 0);
+ Fail("Should throw an ArgumentNullException");
+ }
+ catch (ArgumentNullException) {}
+
+ try
+ {
+ stackInt.CopyTo(arr, -1);
+ Fail("Should throw an ArgumentOutOfRangeException");
+ }
+ catch (ArgumentOutOfRangeException) {}
+
+ try
+ {
+ stackInt.CopyTo(arrMulti = new int[1, 1], 1);
+ Fail("Should throw an ArgumentException");
+ }
+ catch (ArgumentException) {}
+
+ try
+ {
+ stackInt.CopyTo(arr = new int[2], 3);
+ Fail("Should throw an ArgumentException");
+ }
+ catch (ArgumentException) {}
+
+ try
+ {
+ stackInt.CopyTo(arr = new int[3], 2);
+ Fail("Should throw an ArgumentException");
+ }
+ catch (ArgumentException) {}
+
+ try
+ {
+ stackInt.CopyTo(arr = new int[2], 3);
+ Fail("Should throw an ArgumentException");
+ }
+ catch (ArgumentException) {}
+
+ arr = new int[stackInt.Count];
+
+ stackInt.CopyTo(arr, 0);
+
+ int j = 4;
+
+ for (int i = 0; i < 4; i++)
+ {
+ AssertEquals(j--, arr[i]);
+ }
+ }
+
+ public void TestSyncronized()
+ {
+ Stack syncStack = Stack.Synchronized(stackInt);
+
+ syncStack.Push(5);
+
+ for (int i = 5; i >= 0; i--)
+ AssertEquals(i, syncStack.Pop());
+ }
+
+ public void TestPushPeekPop()
+ {
+ stackInt.Pop();
+
+ int topVal = (int)stackInt.Peek();
+
+ AssertEquals(3, topVal);
+
+ AssertEquals(4, stackInt.Count);
+
+ AssertEquals(topVal, stackInt.Pop());
+
+ AssertEquals(2, stackInt.Pop());
+
+ Stack test = new Stack();
+ test.Push(null);
+
+ AssertEquals(null, test.Pop());
+ }
+
+ public void TestToArray()
+ {
+ object[] arr = stackInt.ToArray();
+
+ AssertEquals(stackInt.Count, arr.Length);
+
+ for (int i = 0; i < 5; i++)
+ AssertEquals(arr[i], stackInt.Pop());
+ }
+
+ static void Main(string[] args)
+ {
+ //
+ // TODO: Add code to start application here
+ //
+ }
+
+ protected override void SetUp()
+ {
+ stack1 = new Stack();
+ stack2 = new Stack();
+
+ stackInt = new Stack();
+
+ for (int i = 0; i < 5; i++)
+ stackInt.Push(i);
+ }
+
+ public static ITest Suite
+ {
+ get
+ {
+ TestSuite stackSuite = new TestSuite();
+
+ stackSuite.AddTest(new StackTest("TestConstructor"));
+ stackSuite.AddTest(new StackTest("TestICollectionConstructor"));
+ stackSuite.AddTest(new StackTest("TestIntConstructor"));
+
+ stackSuite.AddTest(new StackTest("TestCount"));
+ stackSuite.AddTest(new StackTest("TestIsReadOnly"));
+ stackSuite.AddTest(new StackTest("TestIsSyncronized"));
+ stackSuite.AddTest(new StackTest("TestSyncRoot"));
+
+ stackSuite.AddTest(new StackTest("TestGetEnumerator"));
+ stackSuite.AddTest(new StackTest("TestClear"));
+ stackSuite.AddTest(new StackTest("TestClone"));
+ stackSuite.AddTest(new StackTest("TestContains"));
+ stackSuite.AddTest(new StackTest("TestPushPeekPop"));
+ stackSuite.AddTest(new StackTest("TestCopyTo"));
+ stackSuite.AddTest(new StackTest("TestSyncronized"));
+ stackSuite.AddTest(new StackTest("TestToArray"));
+
+ return stackSuite;
+ }
+ }
+
+ public StackTest(string name): base(name) {}
+ }
+}
diff --git a/mcs/class/corlib/Test/StringBuilderTest.cs b/mcs/class/corlib/Test/StringBuilderTest.cs
new file mode 100644
index 00000000000..e5e821ce86f
--- /dev/null
+++ b/mcs/class/corlib/Test/StringBuilderTest.cs
@@ -0,0 +1,107 @@
+//
+// StringBuilderTest.dll - NUnit Test Cases for the System.Text.StringBuilder class
+//
+// Author: Marcin Szczepanski (marcins@zipworld.com.au)
+//
+// NOTES: I've also run all these tests against the MS implementation of
+// System.Text.StringBuilder to confirm that they return the same results
+// and they do.
+//
+// TODO: Add tests for the AppendFormat methods once the AppendFormat methods
+// are implemented in the StringBuilder class itself
+//
+// TODO: Potentially add more variations on Insert / Append tests for all the
+// possible types. I don't really think that's necessary as they all
+// pretty much just do .ToString().ToCharArray() and then use the Append / Insert
+// CharArray function. The ToString() bit for each type should be in the unit
+// tests for those types, and the unit test for ToCharArray should be in the
+// string test type. If someone wants to add those tests here for completness
+// (and some double checking) then feel free :)
+//
+
+using NUnit.Framework;
+using System.Text;
+using System;
+
+public class StringBuilderTest : TestCase {
+
+ public StringBuilderTest( string name ) : base(name) { }
+
+ public void TestAppend() {
+ StringBuilder sb = new StringBuilder( "Foo" );
+ sb.Append( "Two" );
+ string expected = "FooTwo";
+ AssertEquals( expected, sb.ToString() );
+ }
+
+ public void TestInsert() {
+ StringBuilder sb = new StringBuilder();
+
+ AssertEquals( String.Empty, sb.ToString() );
+ /* Test empty StringBuilder conforms to spec */
+
+ sb.Insert( 0, "Foo" ); /* Test insert at start of empty string */
+
+ AssertEquals( "Foo", sb.ToString() );
+
+ sb.Insert( 1, "!!" ); /* Test insert not at start of string */
+
+ AssertEquals( "F!!oo", sb.ToString() );
+
+ sb.Insert( 5, ".." ); /* Test insert at end of string */
+
+ AssertEquals( "F!!oo..", sb.ToString() );
+
+ sb.Insert( 0, 1234 ); /* Test insert of a number (at start of string) */
+
+ AssertEquals( "1234F!!oo..", sb.ToString() );
+
+ sb.Insert( 5, 1.5 ); /* Test insert of a decimal (and end of string) */
+
+ AssertEquals( "1234F1.5!!oo..", sb.ToString() );
+
+ sb.Insert( 4, 'A' ); /* Test char insert in middle of string */
+
+ AssertEquals( "1234AF1.5!!oo..", sb.ToString() );
+
+ }
+
+ public void TestReplace() {
+ StringBuilder sb = new StringBuilder( "Foobarbaz" );
+
+ sb.Replace( "bar", "!!!" ); /* Test same length replace in middle of string */
+
+ AssertEquals( "Foo!!!baz", sb.ToString() );
+
+ sb.Replace( "Foo", "ABcD" ); /* Test longer replace at start of string */
+
+ AssertEquals( "ABcD!!!baz", sb.ToString() );
+
+ sb.Replace( "baz", "00" ); /* Test shorter replace at end of string */
+
+ AssertEquals( "ABcD!!!00", sb.ToString() );
+
+ sb.Replace( sb.ToString(), null ); /* Test string clear as in spec */
+
+ AssertEquals( String.Empty, sb.ToString() );
+
+ /* | 10 20 30
+ /* |0123456789012345678901234567890| */
+ sb.Append( "abc this is testing abc the abc abc partial replace abc" );
+
+ sb.Replace( "abc", "!!!", 0, 31 ); /* Partial replace at start of string */
+
+ AssertEquals( "!!! this is testing !!! the !!! abc partial replace abc", sb.ToString() );
+
+ sb.Replace( "testing", "", 0, 15 ); /* Test replace across boundary */
+
+ AssertEquals( "!!! this is testing !!! the !!! abc partial replace abc", sb.ToString() );
+
+ sb.Replace( "!!!", "" ); /* Test replace with empty string */
+
+ AssertEquals(" this is testing the abc partial replace abc", sb.ToString() );
+ }
+
+ public void TestAppendFormat() {
+ }
+} \ No newline at end of file
diff --git a/mcs/class/corlib/Test/StringReaderTest.cs b/mcs/class/corlib/Test/StringReaderTest.cs
new file mode 100644
index 00000000000..4e402869025
--- /dev/null
+++ b/mcs/class/corlib/Test/StringReaderTest.cs
@@ -0,0 +1,83 @@
+//
+// System.IO.StringWriter
+//
+// Author: Marcin Szczepanski (marcins@zipworld.com.au)
+//
+// TODO: Add some testing for exceptions
+//
+// TODO: Some of the tests could be a bit more thorough
+//
+
+using NUnit.Framework;
+using System.IO;
+using System;
+
+public class StringReaderTest : TestCase {
+
+ public StringReaderTest( string name ): base(name) { }
+
+ public void TestPeekRead() {
+ StringReader reader = new StringReader( "Test String" );
+
+ int c = reader.Peek();
+ AssertEquals( c, 'T' );
+
+ int read = reader.Read();
+
+ AssertEquals( read, 'T' );
+
+ c = reader.Peek();
+
+ AssertEquals( c, 'e' );
+ }
+
+ public void TestRead() {
+ StringReader reader = new StringReader( "Test String" );
+
+ /* Read from start of string */
+ char[] test = new char[5];
+
+ int charsRead = reader.Read( test, 0, 5 );
+
+ AssertEquals( 5, charsRead );
+ AssertEquals( "Test ", new String(test) );
+
+ /* Read to end of string */
+ //reader = new StringReader( "Test String" );
+
+ test = new char[6];
+ charsRead = reader.Read( test, 0, 6 );
+ AssertEquals( 6, charsRead);
+ AssertEquals( "String", new String( test ) );
+
+ /* Read past end of string */
+
+ test = new char[6];
+ reader = new StringReader( "Foo" );
+ charsRead = reader.Read( test, 0, 6 );
+ AssertEquals( 3, charsRead );
+ AssertEquals( "Foo\0\0\0", new String( test ) );
+
+ }
+
+ public void TestReadEOL() {
+ StringReader reader = new StringReader( "Line1\rLine2\r\nLine3\nLine4" );
+
+ string test = reader.ReadLine();
+
+ AssertEquals( "Line1", test );
+
+ test = reader.ReadLine();
+
+ AssertEquals( "Line2", test );
+
+ test = reader.ReadLine();
+
+ AssertEquals( "Line3", test );
+
+ test = reader.ReadLine();
+
+ AssertEquals( "Line4", test );
+ }
+}
+ \ No newline at end of file
diff --git a/mcs/class/corlib/Test/StringWriterTest.cs b/mcs/class/corlib/Test/StringWriterTest.cs
new file mode 100644
index 00000000000..79de82154ee
--- /dev/null
+++ b/mcs/class/corlib/Test/StringWriterTest.cs
@@ -0,0 +1,45 @@
+//
+// System.IO.StringWriter
+//
+// Author: Marcin Szczepanski (marcins@zipworld.com.au)
+//
+// TODO: Add some testing for exceptions
+//
+
+using NUnit.Framework;
+using System.IO;
+using System;
+using System.Text;
+
+public class StringWriterTest : TestCase {
+
+ public StringWriterTest( string name ): base(name) { }
+
+ public void TestConstructors() {
+ StringBuilder sb = new StringBuilder("Test String");
+
+ StringWriter writer = new StringWriter( sb );
+ AssertEquals( sb, writer.GetStringBuilder() );
+ }
+
+ public void TestWrite() {
+ StringWriter writer = new StringWriter();
+
+ AssertEquals( String.Empty, writer.ToString() );
+
+ writer.Write( 'A' );
+ AssertEquals( "A", writer.ToString() );
+
+ writer.Write( " foo" );
+ AssertEquals( "A foo", writer.ToString() );
+
+
+ char[] testBuffer = "Test String".ToCharArray();
+
+ writer.Write( testBuffer, 0, 4 );
+ AssertEquals( "A fooTest", writer.ToString() );
+
+ writer.Write( testBuffer, 5, 6 );
+ AssertEquals( "A fooTestString", writer.ToString() );
+ }
+}
diff --git a/mcs/class/corlib/Unix/Wrapper.cs b/mcs/class/corlib/Unix/Wrapper.cs
new file mode 100644
index 00000000000..dcef852de3b
--- /dev/null
+++ b/mcs/class/corlib/Unix/Wrapper.cs
@@ -0,0 +1,209 @@
+/*
+ * Generated automatically: do not edit this file.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+namespace Unix {
+
+public struct stat {
+ public uint st_dev;
+ public uint st_mode;
+ public uint st_nlink;
+ public uint st_uid;
+ public uint st_gid;
+ public long st_size;
+ public uint st_atime;
+ public uint st_mtime;
+ public uint st_ctime;
+};
+
+public class Wrapper {
+
+ public const int SEEK_SET = 0;
+ public const int SEEK_CUR = 1;
+ public const int SEEK_END = 2;
+ public const int O_RDONLY = 0x00000000;
+ public const int O_WRONLY = 0x00000001;
+ public const int O_RDWR = 0x00000002;
+ public const int O_CREAT = 0x00000040;
+ public const int O_EXCL = 0x00000080;
+ public const int O_NOCTTY = 0x00000100;
+ public const int O_TRUNC = 0x00000200;
+ public const int O_SYNC = 0x00001000;
+ public const int O_APPEND = 0x00000400;
+ public const int STDIN_FILENO = 0x00000000;
+ public const int STDOUT_FILENO = 0x00000001;
+ public const int STDERR_FILENO = 0x00000002;
+ public const int S_IFMT = 0x0000f000;
+ public const int S_IFSOCK = 0x0000c000;
+ public const int S_IFLNK = 0x0000a000;
+ public const int S_IFREG = 0x00008000;
+ public const int S_IFBLK = 0x00006000;
+ public const int S_IFDIR = 0x00004000;
+ public const int S_IFCHR = 0x00002000;
+ public const int S_IFIFO = 0x00001000;
+ public const int S_ISUID = 0x00000800;
+ public const int S_ISGID = 0x00000400;
+ public const int S_ISVTX = 0x00000200;
+ public const int S_IRWXU = 0x000001c0;
+ public const int S_IRUSR = 0x00000100;
+ public const int S_IWUSR = 0x00000080;
+ public const int S_IXUSR = 0x00000040;
+ public const int S_IRWXG = 0x00000038;
+ public const int S_IRGRP = 0x00000020;
+ public const int S_IWGRP = 0x00000010;
+ public const int S_IXGRP = 0x00000008;
+ public const int S_IRWXO = 0x00000007;
+ public const int S_IROTH = 0x00000004;
+ public const int S_IWOTH = 0x00000002;
+ public const int S_IXOTH = 0x00000001;
+ public const int EPERM = 1;
+ public const int ENOENT = 2;
+ public const int ESRCH = 3;
+ public const int EINTR = 4;
+ public const int EIO = 5;
+ public const int ENXIO = 6;
+ public const int E2BIG = 7;
+ public const int ENOEXEC = 8;
+ public const int EBADF = 9;
+ public const int ECHILD = 10;
+ public const int EAGAIN = 11;
+ public const int ENOMEM = 12;
+ public const int EACCES = 13;
+ public const int EFAULT = 14;
+ public const int ENOTBLK = 15;
+ public const int EBUSY = 16;
+ public const int EEXIST = 17;
+ public const int EXDEV = 18;
+ public const int ENODEV = 19;
+ public const int EISDIR = 21;
+ public const int EINVAL = 22;
+ public const int ENFILE = 23;
+ public const int EMFILE = 24;
+ public const int ENOTTY = 25;
+ public const int ETXTBSY = 26;
+ public const int EFBIG = 27;
+ public const int ENOSPC = 28;
+ public const int ESPIPE = 29;
+ public const int EROFS = 30;
+ public const int EMLINK = 31;
+ public const int EPIPE = 32;
+ public const int EDOM = 33;
+ public const int ERANGE = 34;
+ public const int EDEADLK = 35;
+ public const int ENAMETOOLONG = 36;
+ public const int ENOLCK = 37;
+ public const int ENOSYS = 38;
+ public const int ENOTEMPTY = 39;
+ public const int ELOOP = 40;
+ public const int EWOULDBLOCK = 11;
+ public const int ENOMSG = 42;
+ public const int EIDRM = 43;
+ public const int ECHRNG = 44;
+ public const int EL2NSYNC = 45;
+ public const int EL3HLT = 46;
+ public const int EL3RST = 47;
+ public const int ELNRNG = 48;
+ public const int EUNATCH = 49;
+ public const int ENOCSI = 50;
+ public const int EL2HLT = 51;
+ public const int EBADE = 52;
+ public const int EBADR = 53;
+ public const int EXFULL = 54;
+ public const int ENOANO = 55;
+ public const int EBADRQC = 56;
+ public const int EBADSLT = 57;
+ public const int EDEADLOCK = 35;
+ public const int EBFONT = 59;
+ public const int ENOSTR = 60;
+ public const int ENODATA = 61;
+ public const int ETIME = 62;
+ public const int ENOSR = 63;
+ public const int ENONET = 64;
+ public const int ENOPKG = 65;
+ public const int EREMOTE = 66;
+ public const int ENOLINK = 67;
+ public const int EADV = 68;
+ public const int ESRMNT = 69;
+ public const int ECOMM = 70;
+ public const int EPROTO = 71;
+ public const int EMULTIHOP = 72;
+ public const int EDOTDOT = 73;
+ public const int EBADMSG = 74;
+ public const int EOVERFLOW = 75;
+ public const int ENOTUNIQ = 76;
+ public const int EBADFD = 77;
+ public const int EREMCHG = 78;
+ public const int ELIBACC = 79;
+ public const int ELIBBAD = 80;
+ public const int ELIBSCN = 81;
+ public const int ELIBMAX = 82;
+ public const int ELIBEXEC = 83;
+ public const int EILSEQ = 84;
+ public const int ERESTART = 85;
+ public const int ESTRPIPE = 86;
+ public const int EUSERS = 87;
+ public const int ENOTSOCK = 88;
+ public const int EDESTADDRREQ = 89;
+ public const int EMSGSIZE = 90;
+ public const int EPROTOTYPE = 91;
+ public const int ENOPROTOOPT = 92;
+ public const int EPROTONOSUPPORT = 93;
+ public const int ESOCKTNOSUPPORT = 94;
+ public const int EOPNOTSUPP = 95;
+ public const int EPFNOSUPPORT = 96;
+ public const int EAFNOSUPPORT = 97;
+ public const int EADDRINUSE = 98;
+ public const int EADDRNOTAVAIL = 99;
+ public const int ENETDOWN = 100;
+ public const int ENETUNREACH = 101;
+ public const int ENETRESET = 102;
+ public const int ECONNABORTED = 103;
+ public const int ECONNRESET = 104;
+ public const int ENOBUFS = 105;
+ public const int EISCONN = 106;
+ public const int ENOTCONN = 107;
+ public const int ESHUTDOWN = 108;
+ public const int ETOOMANYREFS = 109;
+ public const int ETIMEDOUT = 110;
+ public const int ECONNREFUSED = 111;
+ public const int EHOSTDOWN = 112;
+ public const int EHOSTUNREACH = 113;
+ public const int EALREADY = 114;
+ public const int EINPROGRESS = 115;
+ public const int ESTALE = 116;
+ public const int EUCLEAN = 117;
+ public const int ENOTNAM = 118;
+ public const int ENAVAIL = 119;
+ public const int EISNAM = 120;
+ public const int EREMOTEIO = 121;
+ public const int EDQUOT = 122;
+ public const int ENOMEDIUM = 123;
+ public const int EMEDIUMTYPE = 124;
+
+
+ [DllImport("monowrapper", EntryPoint="mono_wrapper_seek", CharSet=CharSet.Ansi)]
+ public unsafe static extern long seek (IntPtr fd, long offset, int whence);
+
+ [DllImport("monowrapper", EntryPoint="mono_wrapper_read", CharSet=CharSet.Ansi)]
+ public unsafe static extern int read (IntPtr fd, void * buf, int count);
+
+ [DllImport("monowrapper", EntryPoint="mono_wrapper_write", CharSet=CharSet.Ansi)]
+ public unsafe static extern int write (IntPtr fd, void * buf, int count);
+
+ [DllImport("monowrapper", EntryPoint="mono_wrapper_fstat", CharSet=CharSet.Ansi)]
+ public unsafe static extern int fstat (IntPtr fd, stat * buf);
+
+ [DllImport("monowrapper", EntryPoint="mono_wrapper_ftruncate", CharSet=CharSet.Ansi)]
+ public unsafe static extern int ftruncate (IntPtr fd, long length);
+
+ [DllImport("monowrapper", EntryPoint="mono_wrapper_open", CharSet=CharSet.Ansi)]
+ public unsafe static extern IntPtr open (string path, int flags, int mode);
+
+ [DllImport("monowrapper", EntryPoint="mono_wrapper_close", CharSet=CharSet.Ansi)]
+ public unsafe static extern int close (IntPtr fd);
+
+}
+}
diff --git a/mcs/class/corlib/Unix/common.src b/mcs/class/corlib/Unix/common.src
new file mode 100644
index 00000000000..14f9533ef75
--- /dev/null
+++ b/mcs/class/corlib/Unix/common.src
@@ -0,0 +1 @@
+Wrapper.cs \ No newline at end of file
diff --git a/mcs/class/corlib/Unix/mono.src b/mcs/class/corlib/Unix/mono.src
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/mcs/class/corlib/Unix/mono.src
diff --git a/mcs/class/corlib/Unix/windows.src b/mcs/class/corlib/Unix/windows.src
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/mcs/class/corlib/Unix/windows.src
diff --git a/mcs/class/corlib/makefile b/mcs/class/corlib/makefile
new file mode 100644
index 00000000000..7dc0dd3ba27
--- /dev/null
+++ b/mcs/class/corlib/makefile
@@ -0,0 +1,38 @@
+DIRS= \
+ System \
+ System.Collections \
+ System.Configuration.Assemblies \
+ System.Diagnostics \
+ System.Globalization \
+ System.IO \
+ System.Reflection \
+ System.Runtime.CompilerServices \
+ System.Runtime.InteropServices \
+ System.Runtime.Serialization \
+ System.Security.Cryptography \
+ System.Security.Permissions \
+ System.Text \
+ System.Threading \
+ Unix
+
+all:
+ @echo "You must use 'make windows' or 'make unix'."
+ @echo "'make unix' is broken for now."
+
+windows: make-list
+ $(CSC) /unsafe /target:library /out:corlib.dll /nowarn:1595 @list
+
+monolib: make-list
+ $(CSC) /unsafe /nostdlib /target:library /out:corlib.dll /nowarn:1595 @listmono
+
+monolib2: make-list
+ $(CSC) /unsafe /target:library /out:corlib.dll /nowarn:1595 @list
+
+unix:
+ @echo "'make unix' is broken for now."
+
+make-list:
+ for i in $(DIRS); do \
+ cat $$i/common.src $$i/windows.src | sed "s/^/$$i\\\\/"; \
+ done > list
+
diff --git a/mcs/class/makefile b/mcs/class/makefile
new file mode 100644
index 00000000000..041a26ab21e
--- /dev/null
+++ b/mcs/class/makefile
@@ -0,0 +1,15 @@
+DIRS=corlib System System.Drawing System.Web System.XML
+ROOT=//$(subst \,/,$(subst :\,/,$(SYSTEMROOT)))
+CSC=$(ROOT)/microsoft.net/framework/v1.0.2914/csc.exe
+
+all:
+ @echo "You must use 'make windows' or 'make unix'."
+ @echo "'make unix' is broken for now."
+
+windows:
+ for i in $(DIRS); do \
+ (cd $$i; CSC=$(CSC) NUNIT_CONSOLE=NUnitConsole.exe PLATFORM=window make windows) || exit 1;\
+ done;
+
+unix:
+ @echo "'make unix' is broken for now."
diff --git a/mcs/class/notes/BitVecto32.txt b/mcs/class/notes/BitVecto32.txt
new file mode 100644
index 00000000000..fad747dfe76
--- /dev/null
+++ b/mcs/class/notes/BitVecto32.txt
@@ -0,0 +1,6 @@
+* Why does CreateSection take a short for the range number?
+
+ It would seem like it should be possible to have numbers between 0
+ and UInt32.MaxValue in there. Why is the API limiting things to 16
+ bits?
+
diff --git a/mcs/docs/order.txt b/mcs/docs/order.txt
index 40ce6970d81..fb23b66c014 100755
--- a/mcs/docs/order.txt
+++ b/mcs/docs/order.txt
@@ -1,2 +1,3 @@
-Order:
- Not all code paths return a value \ No newline at end of file
+The plans:
+
+ Currently types and base classes are being registered. \ No newline at end of file
diff --git a/mcs/errors/cs0146.cs b/mcs/errors/cs0146.cs
new file mode 100644
index 00000000000..8b81c046864
--- /dev/null
+++ b/mcs/errors/cs0146.cs
@@ -0,0 +1,7 @@
+// cs0146.cs: circular class definition
+// Line: 6
+class A : B {
+}
+
+class B : A {
+}
diff --git a/mcs/errors/cs0246.cs b/mcs/errors/cs0246.cs
new file mode 100644
index 00000000000..8cf6b9a081d
--- /dev/null
+++ b/mcs/errors/cs0246.cs
@@ -0,0 +1,4 @@
+// cs0246.cs: can not find type `B'
+// Line: 4
+interface A : B {
+}
diff --git a/mcs/errors/cs0509.cs b/mcs/errors/cs0509.cs
new file mode 100644
index 00000000000..f89988f2cb3
--- /dev/null
+++ b/mcs/errors/cs0509.cs
@@ -0,0 +1,8 @@
+// cs0509.cs: base class is sealed
+// Line: 7
+struct V {
+ int v;
+}
+
+class X : V {
+}
diff --git a/mcs/errors/cs0527-2.cs b/mcs/errors/cs0527-2.cs
new file mode 100644
index 00000000000..e312377061b
--- /dev/null
+++ b/mcs/errors/cs0527-2.cs
@@ -0,0 +1,8 @@
+class A1 {
+}
+
+class A2 {
+}
+
+class B : A1, A2 {
+}
diff --git a/mcs/errors/cs0527.cs b/mcs/errors/cs0527.cs
new file mode 100644
index 00000000000..994add02c67
--- /dev/null
+++ b/mcs/errors/cs0527.cs
@@ -0,0 +1,7 @@
+// cs0527: type in interface list is not an interface
+// Line: 6
+class X {
+}
+
+interface A : X {
+}
diff --git a/mcs/errors/cs0529.cs b/mcs/errors/cs0529.cs
new file mode 100644
index 00000000000..52e725162d0
--- /dev/null
+++ b/mcs/errors/cs0529.cs
@@ -0,0 +1,7 @@
+// cs0529: Recursive interface definition
+// Line: 3
+interface A : B {
+}
+
+interface B : A {
+}
diff --git a/mcs/errors/errors.txt b/mcs/errors/errors.txt
index d769c5c1bd2..ea7cd6eba1d 100755
--- a/mcs/errors/errors.txt
+++ b/mcs/errors/errors.txt
@@ -8,4 +8,8 @@ numbers to match the Microsoft numbers:
of handling it.
-2 Internal error, an interface is being defined inside an
- interface (This should never happen). \ No newline at end of file
+ interface (This should never happen).
+
+-3 Constant type is not one of sbyte, byte, short, ushort, int,
+ uint, long, ulong, char, float, double, decimal, bool, string, enum
+ or null type. \ No newline at end of file
diff --git a/mcs/jay/.cvsignore b/mcs/jay/.cvsignore
new file mode 100755
index 00000000000..75b36e0911d
--- /dev/null
+++ b/mcs/jay/.cvsignore
@@ -0,0 +1,2 @@
+jay
+jay.exe
diff --git a/mcs/jay/ACKNOWLEDGEMENTS b/mcs/jay/ACKNOWLEDGEMENTS
new file mode 100644
index 00000000000..b66bb250645
--- /dev/null
+++ b/mcs/jay/ACKNOWLEDGEMENTS
@@ -0,0 +1,25 @@
+ Berkeley Yacc owes much to the unflagging efforts of Keith Bostic.
+His badgering kept me working on it long after I was ready to quit.
+
+ Berkeley Yacc is based on the excellent algorithm for computing LALR(1)
+lookaheads developed by Tom Pennello and Frank DeRemer. The algorithm is
+described in their almost impenetrable article in TOPLAS 4,4.
+
+ Finally, much of the credit for the latest version must go to those
+who pointed out deficiencies of my earlier releases. Among the most
+prolific contributors were
+
+ Benson I. Margulies
+ Dave Gentzel
+ Antoine Verheijen
+ Peter S. Housel
+ Dale Smith
+ Ozan Yigit
+ John Campbell
+ Bill Sommerfeld
+ Paul Hilfinger
+ Gary Bridgewater
+ Dave Bakken
+ Dan Lanciani
+ Richard Sargent
+ Parag Patel
diff --git a/mcs/jay/ChangeLog b/mcs/jay/ChangeLog
new file mode 100755
index 00000000000..20b2931583a
--- /dev/null
+++ b/mcs/jay/ChangeLog
@@ -0,0 +1,9 @@
+2001-07-15 Sean MacIsaac <macisaac@ximian.com>
+
+ * makefile: added windows and unix targets.
+
+2001-07-14 Sean MacIsaac <macisaac@ximian.com>
+
+ * main.c: fixed error in command line flag -c if it was not first
+ option.
+
diff --git a/mcs/jay/NEW_FEATURES b/mcs/jay/NEW_FEATURES
new file mode 100644
index 00000000000..b030c625b00
--- /dev/null
+++ b/mcs/jay/NEW_FEATURES
@@ -0,0 +1,46 @@
+ The -r option has been implemented. The -r option tells Yacc to
+put the read-only tables in y.tab.c and the code and variables in
+y.code.c. Keith Bostic asked for this option so that :yyfix could be
+eliminated.
+
+ The -l and -t options have been implemented. The -l option tells
+Yacc not to include #line directives in the code it produces. The -t
+option causes debugging code to be included in the compiled parser.
+
+ The code for error recovery has been changed to implement the same
+algorithm as AT&T Yacc. There will still be differences in the way
+error recovery works because AT&T Yacc uses more default reductions
+than Berkeley Yacc.
+
+ The environment variable TMPDIR determines the directory where
+temporary files will be created. If TMPDIR is defined, temporary files
+will be created in the directory whose pathname is the value of TMPDIR.
+By default, temporary files are created in /tmp.
+
+ The keywords are now case-insensitive. For example, %nonassoc,
+%NONASSOC, %NonAssoc, and %nOnAsSoC are all equivalent.
+
+ Commas and semicolons that are not part of C code are treated as
+commentary.
+
+ Line-end comments, as in BCPL, are permitted. Line-end comments
+begin with // and end at the next end-of-line. Line-end comments are
+permitted in C code; they are converted to C comments on output.
+
+ The form of y.output files has been changed to look more like
+those produced by AT&T Yacc.
+
+ A new kind of declaration has been added. The form of the declaration
+is
+
+ %ident string
+
+where string is a sequence of characters begining with a double quote
+and ending with either a double quote or the next end-of-line, whichever
+comes first. The declaration will cause a #ident directive to be written
+near the start of the output file.
+
+ If a parser has been compiled with debugging code, that code can be
+enabled by setting an environment variable. If the environment variable
+YYDEBUG is set to 0, debugging output is suppressed. If it is set to 1,
+debugging output is written to standard output.
diff --git a/mcs/jay/NOTES b/mcs/jay/NOTES
new file mode 100644
index 00000000000..9db3c96ce1b
--- /dev/null
+++ b/mcs/jay/NOTES
@@ -0,0 +1,9 @@
+Berkeley Yacc reflects its origins. The reason so many routines
+use exactly six register variables is that Berkeley Yacc was
+developed on a VAX using PCC. PCC placed at most six variables
+in registers. I went to considerable effort to find which six
+variables most belonged in registers. Changes in machines and
+compilers make that effort worthless, perhaps even harmful.
+
+The code contains many instances where address calculations are
+performed in particular ways to optimize the code for the VAX.
diff --git a/mcs/jay/README b/mcs/jay/README
new file mode 100644
index 00000000000..b261173398e
--- /dev/null
+++ b/mcs/jay/README
@@ -0,0 +1,10 @@
+This is a port of Jay to C#, the original Jay can be found here:
+ http://www.informatik.uni-osnabrueck.de/bernd/jay/
+
+This is a temporary solution as we move to a Bison-generated parser
+as it would provide better error recovery (and error productions
+are broken in my port of Jay).
+
+The original README from Jay is in `README.jay'
+
+Miguel
diff --git a/mcs/jay/README.jay b/mcs/jay/README.jay
new file mode 100644
index 00000000000..94b7b72e6e4
--- /dev/null
+++ b/mcs/jay/README.jay
@@ -0,0 +1,55 @@
+ This version of Berkeley Yacc was taken from the BSD-Lite CD and targeted
+to Java by
+
+ axel.schreiner@informatik.uni-osnabrueck.de
+
+Makefile -> makefile removed Berkeleyisms, call it jay
+defs.h eliminate -dlpr options, %union, output_file, #ident
+ eliminate sekeleton.c references
+error.c eliminate %union
+main.c eliminate -dlpr options, %union, output_file
+output.c eliminate -dlpr options, %union, output_file
+ fix #define, short, -t/yyDebug
+ respell YYERRCODE, YYTABLESIZE, YYFINAL, YYMAXTOKEN
+ output trailer last
+ switch to filter behaviour
+reader.c eliminate output_file, #ident
+ #line -> // line, pass //
+ yyvsp[] -> yyVals[yyTop], yyval -> yyVal
+skeleton.c -> skeleton Java skeleton
+test removed
+yacc.1 -> jay.1 adapted
+yyfix.* removed
+
+Types: there is a significant difference. yacc uses %union to cast the value
+stack and <tag> to select alternatives. This works for l- and r-values alike.
+jay uses Object as the value stack and <tag> to set a class. l-values must not
+be cast. $n should not be assigned to, but $$ usually is. $n is referenced,
+but $$ usually is not. Consequently jay casts $n and $<tag>$ but not $<>n
+and $$. This makes assignment to $n references to $$ kludgily possible.
+As another kludge, to prevent 'untyped' messages and to avoid unnecessary
+casts, casts to "Object" are not emitted.
+-------------------------------------------------------------------------------
+ Berkeley Yacc is an LALR(1) parser generator. Berkeley Yacc has been made
+as compatible as possible with AT&T Yacc. Berkeley Yacc can accept any input
+specification that conforms to the AT&T Yacc documentation. Specifications
+that take advantage of undocumented features of AT&T Yacc will probably be
+rejected.
+
+ Berkeley Yacc is distributed with no warranty whatever. The code is certain
+to contain errors. Neither the author nor any contributor takes responsibility
+for any consequences of its use.
+
+ Berkeley Yacc is in the public domain. The data structures and algorithms
+used in Berkeley Yacc are all either taken from documents available to the
+general public or are inventions of the author. Anyone may freely distribute
+source or binary forms of Berkeley Yacc whether unchanged or modified.
+Distributers may charge whatever fees they can obtain for Berkeley Yacc.
+Programs generated by Berkeley Yacc may be distributed freely.
+
+ Please report bugs to
+
+ robert.corbett@eng.Sun.COM
+
+Include a small example if possible. Please include the banner string from
+skeleton.c with the bug report. Do not expect rapid responses.
diff --git a/mcs/jay/closure.c b/mcs/jay/closure.c
new file mode 100644
index 00000000000..5f63c5f32cd
--- /dev/null
+++ b/mcs/jay/closure.c
@@ -0,0 +1,295 @@
+/*
+ * Copyright (c) 1989 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Robert Paul Corbett.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * 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 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)closure.c 5.3 (Berkeley) 5/24/93";
+#endif /* not lint */
+
+#include "defs.h"
+
+short *itemset;
+short *itemsetend;
+unsigned *ruleset;
+
+static unsigned *first_derives;
+static unsigned *EFF;
+
+
+set_EFF()
+{
+ register unsigned *row;
+ register int symbol;
+ register short *sp;
+ register int rowsize;
+ register int i;
+ register int rule;
+
+ rowsize = WORDSIZE(nvars);
+ EFF = NEW2(nvars * rowsize, unsigned);
+
+ row = EFF;
+ for (i = start_symbol; i < nsyms; i++)
+ {
+ sp = derives[i];
+ for (rule = *sp; rule > 0; rule = *++sp)
+ {
+ symbol = ritem[rrhs[rule]];
+ if (ISVAR(symbol))
+ {
+ symbol -= start_symbol;
+ SETBIT(row, symbol);
+ }
+ }
+ row += rowsize;
+ }
+
+ reflexive_transitive_closure(EFF, nvars);
+
+#ifdef DEBUG
+ print_EFF();
+#endif
+}
+
+
+set_first_derives()
+{
+ register unsigned *rrow;
+ register unsigned *vrow;
+ register int j;
+ register unsigned k;
+ register unsigned cword;
+ register short *rp;
+
+ int rule;
+ int i;
+ int rulesetsize;
+ int varsetsize;
+
+ rulesetsize = WORDSIZE(nrules);
+ varsetsize = WORDSIZE(nvars);
+ first_derives = NEW2(nvars * rulesetsize, unsigned) - ntokens * rulesetsize;
+
+ set_EFF();
+
+ rrow = first_derives + ntokens * rulesetsize;
+ for (i = start_symbol; i < nsyms; i++)
+ {
+ vrow = EFF + ((i - ntokens) * varsetsize);
+ k = BITS_PER_WORD;
+ for (j = start_symbol; j < nsyms; k++, j++)
+ {
+ if (k >= BITS_PER_WORD)
+ {
+ cword = *vrow++;
+ k = 0;
+ }
+
+ if (cword & (1 << k))
+ {
+ rp = derives[j];
+ while ((rule = *rp++) >= 0)
+ {
+ SETBIT(rrow, rule);
+ }
+ }
+ }
+
+ vrow += varsetsize;
+ rrow += rulesetsize;
+ }
+
+#ifdef DEBUG
+ print_first_derives();
+#endif
+
+ FREE(EFF);
+}
+
+
+closure(nucleus, n)
+short *nucleus;
+int n;
+{
+ register int ruleno;
+ register unsigned word;
+ register unsigned i;
+ register short *csp;
+ register unsigned *dsp;
+ register unsigned *rsp;
+ register int rulesetsize;
+
+ short *csend;
+ unsigned *rsend;
+ int symbol;
+ int itemno;
+
+ rulesetsize = WORDSIZE(nrules);
+ rsp = ruleset;
+ rsend = ruleset + rulesetsize;
+ for (rsp = ruleset; rsp < rsend; rsp++)
+ *rsp = 0;
+
+ csend = nucleus + n;
+ for (csp = nucleus; csp < csend; ++csp)
+ {
+ symbol = ritem[*csp];
+ if (ISVAR(symbol))
+ {
+ dsp = first_derives + symbol * rulesetsize;
+ rsp = ruleset;
+ while (rsp < rsend)
+ *rsp++ |= *dsp++;
+ }
+ }
+
+ ruleno = 0;
+ itemsetend = itemset;
+ csp = nucleus;
+ for (rsp = ruleset; rsp < rsend; ++rsp)
+ {
+ word = *rsp;
+ if (word)
+ {
+ for (i = 0; i < BITS_PER_WORD; ++i)
+ {
+ if (word & (1 << i))
+ {
+ itemno = rrhs[ruleno+i];
+ while (csp < csend && *csp < itemno)
+ *itemsetend++ = *csp++;
+ *itemsetend++ = itemno;
+ while (csp < csend && *csp == itemno)
+ ++csp;
+ }
+ }
+ }
+ ruleno += BITS_PER_WORD;
+ }
+
+ while (csp < csend)
+ *itemsetend++ = *csp++;
+
+#ifdef DEBUG
+ print_closure(n);
+#endif
+}
+
+
+
+finalize_closure()
+{
+ FREE(itemset);
+ FREE(ruleset);
+ FREE(first_derives + ntokens * WORDSIZE(nrules));
+}
+
+
+#ifdef DEBUG
+
+print_closure(n)
+int n;
+{
+ register short *isp;
+
+ printf("\n\nn = %d\n\n", n);
+ for (isp = itemset; isp < itemsetend; isp++)
+ printf(" %d\n", *isp);
+}
+
+
+print_EFF()
+{
+ register int i, j;
+ register unsigned *rowp;
+ register unsigned word;
+ register unsigned k;
+
+ printf("\n\nEpsilon Free Firsts\n");
+
+ for (i = start_symbol; i < nsyms; i++)
+ {
+ printf("\n%s", symbol_name[i]);
+ rowp = EFF + ((i - start_symbol) * WORDSIZE(nvars));
+ word = *rowp++;
+
+ k = BITS_PER_WORD;
+ for (j = 0; j < nvars; k++, j++)
+ {
+ if (k >= BITS_PER_WORD)
+ {
+ word = *rowp++;
+ k = 0;
+ }
+
+ if (word & (1 << k))
+ printf(" %s", symbol_name[start_symbol + j]);
+ }
+ }
+}
+
+
+print_first_derives()
+{
+ register int i;
+ register int j;
+ register unsigned *rp;
+ register unsigned cword;
+ register unsigned k;
+
+ printf("\n\n\nFirst Derives\n");
+
+ for (i = start_symbol; i < nsyms; i++)
+ {
+ printf("\n%s derives\n", symbol_name[i]);
+ rp = first_derives + i * WORDSIZE(nrules);
+ k = BITS_PER_WORD;
+ for (j = 0; j <= nrules; k++, j++)
+ {
+ if (k >= BITS_PER_WORD)
+ {
+ cword = *rp++;
+ k = 0;
+ }
+
+ if (cword & (1 << k))
+ printf(" %d\n", j);
+ }
+ }
+
+ fflush(stdout);
+}
+
+#endif
diff --git a/mcs/jay/defs.h b/mcs/jay/defs.h
new file mode 100644
index 00000000000..ac1d63f53a3
--- /dev/null
+++ b/mcs/jay/defs.h
@@ -0,0 +1,308 @@
+/*
+ * Copyright (c) 1989 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Robert Paul Corbett.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * 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 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)defs.h 5.6 (Berkeley) 5/24/93
+ */
+
+#include <assert.h>
+#include <ctype.h>
+#include <stdio.h>
+
+
+/* machine-dependent definitions */
+/* the following definitions are for the Tahoe */
+/* they might have to be changed for other machines */
+
+/* MAXCHAR is the largest unsigned character value */
+/* MAXSHORT is the largest value of a C short */
+/* MINSHORT is the most negative value of a C short */
+/* MAXTABLE is the maximum table size */
+/* BITS_PER_WORD is the number of bits in a C unsigned */
+/* WORDSIZE computes the number of words needed to */
+/* store n bits */
+/* BIT returns the value of the n-th bit starting */
+/* from r (0-indexed) */
+/* SETBIT sets the n-th bit starting from r */
+
+#define MAXCHAR 255
+#define MAXSHORT 32767
+#define MINSHORT -32768
+#define MAXTABLE 32500
+#define BITS_PER_WORD 32
+#define WORDSIZE(n) (((n)+(BITS_PER_WORD-1))/BITS_PER_WORD)
+#define BIT(r, n) ((((r)[(n)>>5])>>((n)&31))&1)
+#define SETBIT(r, n) ((r)[(n)>>5]|=((unsigned)1<<((n)&31)))
+
+
+/* character names */
+
+#define NUL '\0' /* the null character */
+#define NEWLINE '\n' /* line feed */
+#define SP ' ' /* space */
+#define BS '\b' /* backspace */
+#define HT '\t' /* horizontal tab */
+#define VT '\013' /* vertical tab */
+#define CR '\r' /* carriage return */
+#define FF '\f' /* form feed */
+#define QUOTE '\'' /* single quote */
+#define DOUBLE_QUOTE '\"' /* double quote */
+#define BACKSLASH '\\' /* backslash */
+
+
+/* defines for constructing filenames */
+
+#define CODE_SUFFIX ".code.c"
+#define DEFINES_SUFFIX ".tab.h"
+#define OUTPUT_SUFFIX ".tab.c"
+#define VERBOSE_SUFFIX ".output"
+
+
+/* keyword codes */
+
+#define TOKEN 0
+#define LEFT 1
+#define RIGHT 2
+#define NONASSOC 3
+#define MARK 4
+#define TEXT 5
+#define TYPE 6
+#define START 7
+
+
+/* symbol classes */
+
+#define UNKNOWN 0
+#define TERM 1
+#define NONTERM 2
+
+
+/* the undefined value */
+
+#define UNDEFINED (-1)
+
+
+/* action codes */
+
+#define SHIFT 1
+#define REDUCE 2
+
+
+/* character macros */
+
+#define IS_IDENT(c) (isalnum(c) || (c) == '_' || (c) == '.' || (c) == '$')
+#define IS_OCTAL(c) ((c) >= '0' && (c) <= '7')
+#define NUMERIC_VALUE(c) ((c) - '0')
+
+
+/* symbol macros */
+
+#define ISTOKEN(s) ((s) < start_symbol)
+#define ISVAR(s) ((s) >= start_symbol)
+
+
+/* storage allocation macros */
+
+#define CALLOC(k,n) (calloc((unsigned)(k),(unsigned)(n)))
+#define FREE(x) (free((char*)(x)))
+#define MALLOC(n) (malloc((unsigned)(n)))
+#define NEW(t) ((t*)allocate(sizeof(t)))
+#define NEW2(n,t) ((t*)allocate((unsigned)((n)*sizeof(t))))
+#define REALLOC(p,n) (realloc((char*)(p),(unsigned)(n)))
+
+
+/* the structure of a symbol table entry */
+
+typedef struct bucket bucket;
+struct bucket
+{
+ struct bucket *link;
+ struct bucket *next;
+ char *name;
+ char *tag;
+ short value;
+ short index;
+ short prec;
+ char class;
+ char assoc;
+};
+
+
+/* the structure of the LR(0) state machine */
+
+typedef struct core core;
+struct core
+{
+ struct core *next;
+ struct core *link;
+ short number;
+ short accessing_symbol;
+ short nitems;
+ short items[1];
+};
+
+
+/* the structure used to record shifts */
+
+typedef struct shifts shifts;
+struct shifts
+{
+ struct shifts *next;
+ short number;
+ short nshifts;
+ short shift[1];
+};
+
+
+/* the structure used to store reductions */
+
+typedef struct reductions reductions;
+struct reductions
+{
+ struct reductions *next;
+ short number;
+ short nreds;
+ short rules[1];
+};
+
+
+/* the structure used to represent parser actions */
+
+typedef struct action action;
+struct action
+{
+ struct action *next;
+ short symbol;
+ short number;
+ short prec;
+ char action_code;
+ char assoc;
+ char suppressed;
+};
+
+
+/* global variables */
+
+extern char tflag;
+extern char vflag;
+
+extern char *myname;
+extern char *cptr;
+extern char *line;
+extern int lineno;
+extern int outline;
+
+extern char *action_file_name;
+extern char *input_file_name;
+extern char *prolog_file_name;
+extern char *local_file_name;
+extern char *verbose_file_name;
+
+extern FILE *action_file;
+extern FILE *input_file;
+extern FILE *prolog_file;
+extern FILE *local_file;
+extern FILE *verbose_file;
+
+extern int nitems;
+extern int nrules;
+extern int nsyms;
+extern int ntokens;
+extern int nvars;
+extern int ntags;
+
+extern char *line_format;
+
+extern int start_symbol;
+extern char **symbol_name;
+extern short *symbol_value;
+extern short *symbol_prec;
+extern char *symbol_assoc;
+
+extern short *ritem;
+extern short *rlhs;
+extern short *rrhs;
+extern short *rprec;
+extern char *rassoc;
+
+extern short **derives;
+extern char *nullable;
+
+extern bucket *first_symbol;
+extern bucket *last_symbol;
+
+extern int nstates;
+extern core *first_state;
+extern shifts *first_shift;
+extern reductions *first_reduction;
+extern short *accessing_symbol;
+extern core **state_table;
+extern shifts **shift_table;
+extern reductions **reduction_table;
+extern unsigned *LA;
+extern short *LAruleno;
+extern short *lookaheads;
+extern short *goto_map;
+extern short *from_state;
+extern short *to_state;
+
+extern action **parser;
+extern int SRtotal;
+extern int RRtotal;
+extern short *SRconflicts;
+extern short *RRconflicts;
+extern short *defred;
+extern short *rules_used;
+extern short nunused;
+extern short final_state;
+
+/* global functions */
+
+extern char *allocate();
+extern bucket *lookup();
+extern bucket *make_bucket();
+
+
+/* system variables */
+
+extern int errno;
+
+
+/* system functions */
+
+extern void free();
+extern char *calloc();
+extern char *malloc();
+extern char *realloc();
+extern char *strcpy();
diff --git a/mcs/jay/depend b/mcs/jay/depend
new file mode 100644
index 00000000000..134445ffddd
--- /dev/null
+++ b/mcs/jay/depend
@@ -0,0 +1,11 @@
+closure.o: closure.c defs.h
+error.o: error.c defs.h
+lalr.o: lalr.c defs.h
+lr0.o: lr0.c defs.h
+main.o: main.c defs.h
+mkpar.o: mkpar.c defs.h
+output.o: output.c defs.h
+reader.o: reader.c defs.h
+symtab.o: symtab.c defs.h
+verbose.o: verbose.c defs.h
+warshall.o: warshall.c defs.h
diff --git a/mcs/jay/error.c b/mcs/jay/error.c
new file mode 100644
index 00000000000..dd8bf291c20
--- /dev/null
+++ b/mcs/jay/error.c
@@ -0,0 +1,335 @@
+/*
+ * Copyright (c) 1989 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Robert Paul Corbett.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * 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 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)error.c 5.3 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+/* routines for printing error messages */
+
+#include "defs.h"
+
+
+fatal(msg)
+char *msg;
+{
+ fprintf(stderr, "%s: f - %s\n", myname, msg);
+ done(2);
+}
+
+
+no_space()
+{
+ fprintf(stderr, "%s: f - out of space\n", myname);
+ done(2);
+}
+
+
+open_error(filename)
+char *filename;
+{
+ fprintf(stderr, "%s: f - cannot open \"%s\"\n", myname, filename);
+ done(2);
+}
+
+
+unexpected_EOF()
+{
+ fprintf(stderr, "%s: e - line %d of \"%s\", unexpected end-of-file\n",
+ myname, lineno, input_file_name);
+ done(1);
+}
+
+
+print_pos(st_line, st_cptr)
+char *st_line;
+char *st_cptr;
+{
+ register char *s;
+
+ if (st_line == 0) return;
+ for (s = st_line; *s != '\n'; ++s)
+ {
+ if (isprint(*s) || *s == '\t')
+ putc(*s, stderr);
+ else
+ putc('?', stderr);
+ }
+ putc('\n', stderr);
+ for (s = st_line; s < st_cptr; ++s)
+ {
+ if (*s == '\t')
+ putc('\t', stderr);
+ else
+ putc(' ', stderr);
+ }
+ putc('^', stderr);
+ putc('\n', stderr);
+}
+
+
+syntax_error(st_lineno, st_line, st_cptr)
+int st_lineno;
+char *st_line;
+char *st_cptr;
+{
+ fprintf(stderr, "%s: e - line %d of \"%s\", syntax error\n",
+ myname, st_lineno, input_file_name);
+ print_pos(st_line, st_cptr);
+ done(1);
+}
+
+
+unterminated_comment(c_lineno, c_line, c_cptr)
+int c_lineno;
+char *c_line;
+char *c_cptr;
+{
+ fprintf(stderr, "%s: e - line %d of \"%s\", unmatched /*\n",
+ myname, c_lineno, input_file_name);
+ print_pos(c_line, c_cptr);
+ done(1);
+}
+
+
+unterminated_string(s_lineno, s_line, s_cptr)
+int s_lineno;
+char *s_line;
+char *s_cptr;
+{
+ fprintf(stderr, "%s: e - line %d of \"%s\", unterminated string\n",
+ myname, s_lineno, input_file_name);
+ print_pos(s_line, s_cptr);
+ done(1);
+}
+
+
+unterminated_text(t_lineno, t_line, t_cptr)
+int t_lineno;
+char *t_line;
+char *t_cptr;
+{
+ fprintf(stderr, "%s: e - line %d of \"%s\", unmatched %%{\n",
+ myname, t_lineno, input_file_name);
+ print_pos(t_line, t_cptr);
+ done(1);
+}
+
+
+illegal_tag(t_lineno, t_line, t_cptr)
+int t_lineno;
+char *t_line;
+char *t_cptr;
+{
+ fprintf(stderr, "%s: e - line %d of \"%s\", illegal tag\n",
+ myname, t_lineno, input_file_name);
+ print_pos(t_line, t_cptr);
+ done(1);
+}
+
+
+illegal_character(c_cptr)
+char *c_cptr;
+{
+ fprintf(stderr, "%s: e - line %d of \"%s\", illegal character\n",
+ myname, lineno, input_file_name);
+ print_pos(line, c_cptr);
+ done(1);
+}
+
+
+used_reserved(s)
+char *s;
+{
+ fprintf(stderr, "%s: e - line %d of \"%s\", illegal use of reserved symbol \
+%s\n", myname, lineno, input_file_name, s);
+ done(1);
+}
+
+
+tokenized_start(s)
+char *s;
+{
+ fprintf(stderr, "%s: e - line %d of \"%s\", the start symbol %s cannot be \
+declared to be a token\n", myname, lineno, input_file_name, s);
+ done(1);
+}
+
+
+retyped_warning(s)
+char *s;
+{
+ fprintf(stderr, "%s: w - line %d of \"%s\", the type of %s has been \
+redeclared\n", myname, lineno, input_file_name, s);
+}
+
+
+reprec_warning(s)
+char *s;
+{
+ fprintf(stderr, "%s: w - line %d of \"%s\", the precedence of %s has been \
+redeclared\n", myname, lineno, input_file_name, s);
+}
+
+
+revalued_warning(s)
+char *s;
+{
+ fprintf(stderr, "%s: w - line %d of \"%s\", the value of %s has been \
+redeclared\n", myname, lineno, input_file_name, s);
+}
+
+
+terminal_start(s)
+char *s;
+{
+ fprintf(stderr, "%s: e - line %d of \"%s\", the start symbol %s is a \
+token\n", myname, lineno, input_file_name, s);
+ done(1);
+}
+
+
+restarted_warning()
+{
+ fprintf(stderr, "%s: w - line %d of \"%s\", the start symbol has been \
+redeclared\n", myname, lineno, input_file_name);
+}
+
+
+no_grammar()
+{
+ fprintf(stderr, "%s: e - line %d of \"%s\", no grammar has been \
+specified\n", myname, lineno, input_file_name);
+ done(1);
+}
+
+
+terminal_lhs(s_lineno)
+int s_lineno;
+{
+ fprintf(stderr, "%s: e - line %d of \"%s\", a token appears on the lhs \
+of a production\n", myname, s_lineno, input_file_name);
+ done(1);
+}
+
+
+prec_redeclared()
+{
+ fprintf(stderr, "%s: w - line %d of \"%s\", conflicting %%prec \
+specifiers\n", myname, lineno, input_file_name);
+}
+
+
+unterminated_action(a_lineno, a_line, a_cptr)
+int a_lineno;
+char *a_line;
+char *a_cptr;
+{
+ fprintf(stderr, "%s: e - line %d of \"%s\", unterminated action\n",
+ myname, a_lineno, input_file_name);
+ print_pos(a_line, a_cptr);
+ done(1);
+}
+
+
+dollar_warning(a_lineno, i)
+int a_lineno;
+int i;
+{
+ fprintf(stderr, "%s: w - line %d of \"%s\", $%d references beyond the \
+end of the current rule\n", myname, a_lineno, input_file_name, i);
+}
+
+
+dollar_error(a_lineno, a_line, a_cptr)
+int a_lineno;
+char *a_line;
+char *a_cptr;
+{
+ fprintf(stderr, "%s: e - line %d of \"%s\", illegal $-name\n",
+ myname, a_lineno, input_file_name);
+ print_pos(a_line, a_cptr);
+ done(1);
+}
+
+
+untyped_lhs()
+{
+ fprintf(stderr, "%s: w - line %d of \"%s\", $$ is untyped\n",
+ myname, lineno, input_file_name);
+ /** done(1); */
+}
+
+
+untyped_rhs(i, s)
+int i;
+char *s;
+{
+ fprintf(stderr, "%s: w - line %d of \"%s\", $%d (%s) is untyped\n",
+ myname, lineno, input_file_name, i, s);
+ /** done(1); */
+}
+
+
+unknown_rhs(i)
+int i;
+{
+ fprintf(stderr, "%s: e - line %d of \"%s\", $%d is untyped\n",
+ myname, lineno, input_file_name, i);
+ done(1);
+}
+
+
+default_action_warning()
+{
+ fprintf(stderr, "%s: w - line %d of \"%s\", the default action assigns an \
+undefined value to $$\n", myname, lineno, input_file_name);
+}
+
+
+undefined_goal(s)
+char *s;
+{
+ fprintf(stderr, "%s: e - the start symbol %s is undefined\n", myname, s);
+ done(1);
+}
+
+
+undefined_symbol_warning(s)
+char *s;
+{
+ fprintf(stderr, "%s: w - the symbol %s is undefined\n", myname, s);
+}
diff --git a/mcs/jay/jay.1 b/mcs/jay/jay.1
new file mode 100644
index 00000000000..85040fd5694
--- /dev/null
+++ b/mcs/jay/jay.1
@@ -0,0 +1,120 @@
+.\" Copyright (c) 1989, 1990 The Regents of the University of California.
+.\" All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" Robert Paul Corbett.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" 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 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)yacc.1 5.8 (Berkeley) 5/24/93
+.\"
+.TH JAY 1 "May 24, 1993 / July 8, 1998"
+.UC 6
+.SH NAME
+jay \- an LALR(1) parser generator for Java and C#
+.SH SYNOPSIS
+.B jay [ -tv ] [ -c ] [ -b
+.I file_prefix
+.B ] [ -V
+.I yyValue
+.B ]
+.I filename
+.B <
+.I skeleton
+.SH DESCRIPTION
+.I Jay
+reads the grammar specification in the file
+.I filename
+and generates an LR(1) parser for it.
+The parsers consist of a set of LALR(1) parsing tables and a driver routine
+from the file
+.I skeleton
+written in the Java programming language.
+.I Jay
+writes the parse tables and the driver routine to standard output.
+.PP
+The following options are available:
+.RS
+.TP
+\fB-b \fIfile_prefix\fR
+The
+.B -b
+option changes the prefix prepended to the output file names to
+the string denoted by
+.IR file_prefix.
+The default prefix is the character
+.IR y.
+.TP
+.B -c
+The
+.B -c
+option makes jay generate C# code instead of the default Java.
+.TP
+.B -t
+The
+.B -t
+option arranges for
+debugging information to be incorporated in the compiled code.
+.TP
+.B -v
+The
+.B -v
+option causes a human-readable description of the generated parser to
+be written to the file
+.IR y.output.
+.RE
+.PP
+If the environment variable TMPDIR is set, the string denoted by
+TMPDIR will be used as the name of the directory where the temporary
+files are created.
+.SH FILES
+.IR skeleton
+.br
+.IR y.output
+.br
+.IR /tmp/yacc.aXXXXXX
+.br
+.IR /tmp/yacc.tXXXXXX
+.br
+.IR /tmp/yacc.uXXXXXX
+.SH DIAGNOSTICS
+If there are rules that are never reduced, the number of such rules is
+reported on standard error.
+If there are any LALR(1) conflicts, the number of conflicts is reported
+on standard error.
+.SH HISTORY
+.I Jay
+is derived from Berkeley
+.I yacc .
+Input conventions closely follow those of
+.I yacc ;
+for details,
+consult the parser
+.I skeleton
+file and the commented example included with the sources.
diff --git a/mcs/jay/lalr.c b/mcs/jay/lalr.c
new file mode 100644
index 00000000000..bf9aec846b7
--- /dev/null
+++ b/mcs/jay/lalr.c
@@ -0,0 +1,678 @@
+/*
+ * Copyright (c) 1989 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Robert Paul Corbett.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * 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 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)lalr.c 5.3 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+#include "defs.h"
+
+typedef
+ struct shorts
+ {
+ struct shorts *next;
+ short value;
+ }
+ shorts;
+
+int tokensetsize;
+short *lookaheads;
+short *LAruleno;
+unsigned *LA;
+short *accessing_symbol;
+core **state_table;
+shifts **shift_table;
+reductions **reduction_table;
+short *goto_map;
+short *from_state;
+short *to_state;
+
+short **transpose();
+
+static int infinity;
+static int maxrhs;
+static int ngotos;
+static unsigned *F;
+static short **includes;
+static shorts **lookback;
+static short **R;
+static short *INDEX;
+static short *VERTICES;
+static int top;
+
+
+lalr()
+{
+ tokensetsize = WORDSIZE(ntokens);
+
+ set_state_table();
+ set_accessing_symbol();
+ set_shift_table();
+ set_reduction_table();
+ set_maxrhs();
+ initialize_LA();
+ set_goto_map();
+ initialize_F();
+ build_relations();
+ compute_FOLLOWS();
+ compute_lookaheads();
+}
+
+
+
+set_state_table()
+{
+ register core *sp;
+
+ state_table = NEW2(nstates, core *);
+ for (sp = first_state; sp; sp = sp->next)
+ state_table[sp->number] = sp;
+}
+
+
+
+set_accessing_symbol()
+{
+ register core *sp;
+
+ accessing_symbol = NEW2(nstates, short);
+ for (sp = first_state; sp; sp = sp->next)
+ accessing_symbol[sp->number] = sp->accessing_symbol;
+}
+
+
+
+set_shift_table()
+{
+ register shifts *sp;
+
+ shift_table = NEW2(nstates, shifts *);
+ for (sp = first_shift; sp; sp = sp->next)
+ shift_table[sp->number] = sp;
+}
+
+
+
+set_reduction_table()
+{
+ register reductions *rp;
+
+ reduction_table = NEW2(nstates, reductions *);
+ for (rp = first_reduction; rp; rp = rp->next)
+ reduction_table[rp->number] = rp;
+}
+
+
+
+set_maxrhs()
+{
+ register short *itemp;
+ register short *item_end;
+ register int length;
+ register int max;
+
+ length = 0;
+ max = 0;
+ item_end = ritem + nitems;
+ for (itemp = ritem; itemp < item_end; itemp++)
+ {
+ if (*itemp >= 0)
+ {
+ length++;
+ }
+ else
+ {
+ if (length > max) max = length;
+ length = 0;
+ }
+ }
+
+ maxrhs = max;
+}
+
+
+
+initialize_LA()
+{
+ register int i, j, k;
+ register reductions *rp;
+
+ lookaheads = NEW2(nstates + 1, short);
+
+ k = 0;
+ for (i = 0; i < nstates; i++)
+ {
+ lookaheads[i] = k;
+ rp = reduction_table[i];
+ if (rp)
+ k += rp->nreds;
+ }
+ lookaheads[nstates] = k;
+
+ LA = NEW2(k * tokensetsize, unsigned);
+ LAruleno = NEW2(k, short);
+ lookback = NEW2(k, shorts *);
+
+ k = 0;
+ for (i = 0; i < nstates; i++)
+ {
+ rp = reduction_table[i];
+ if (rp)
+ {
+ for (j = 0; j < rp->nreds; j++)
+ {
+ LAruleno[k] = rp->rules[j];
+ k++;
+ }
+ }
+ }
+}
+
+
+set_goto_map()
+{
+ register shifts *sp;
+ register int i;
+ register int symbol;
+ register int k;
+ register short *temp_map;
+ register int state2;
+ register int state1;
+
+ goto_map = NEW2(nvars + 1, short) - ntokens;
+ temp_map = NEW2(nvars + 1, short) - ntokens;
+
+ ngotos = 0;
+ for (sp = first_shift; sp; sp = sp->next)
+ {
+ for (i = sp->nshifts - 1; i >= 0; i--)
+ {
+ symbol = accessing_symbol[sp->shift[i]];
+
+ if (ISTOKEN(symbol)) break;
+
+ if (ngotos == MAXSHORT)
+ fatal("too many gotos");
+
+ ngotos++;
+ goto_map[symbol]++;
+ }
+ }
+
+ k = 0;
+ for (i = ntokens; i < nsyms; i++)
+ {
+ temp_map[i] = k;
+ k += goto_map[i];
+ }
+
+ for (i = ntokens; i < nsyms; i++)
+ goto_map[i] = temp_map[i];
+
+ goto_map[nsyms] = ngotos;
+ temp_map[nsyms] = ngotos;
+
+ from_state = NEW2(ngotos, short);
+ to_state = NEW2(ngotos, short);
+
+ for (sp = first_shift; sp; sp = sp->next)
+ {
+ state1 = sp->number;
+ for (i = sp->nshifts - 1; i >= 0; i--)
+ {
+ state2 = sp->shift[i];
+ symbol = accessing_symbol[state2];
+
+ if (ISTOKEN(symbol)) break;
+
+ k = temp_map[symbol]++;
+ from_state[k] = state1;
+ to_state[k] = state2;
+ }
+ }
+
+ FREE(temp_map + ntokens);
+}
+
+
+
+/* Map_goto maps a state/symbol pair into its numeric representation. */
+
+int
+map_goto(state, symbol)
+int state;
+int symbol;
+{
+ register int high;
+ register int low;
+ register int middle;
+ register int s;
+
+ low = goto_map[symbol];
+ high = goto_map[symbol + 1];
+
+ for (;;)
+ {
+ assert(low <= high);
+ middle = (low + high) >> 1;
+ s = from_state[middle];
+ if (s == state)
+ return (middle);
+ else if (s < state)
+ low = middle + 1;
+ else
+ high = middle - 1;
+ }
+}
+
+
+
+initialize_F()
+{
+ register int i;
+ register int j;
+ register int k;
+ register shifts *sp;
+ register short *edge;
+ register unsigned *rowp;
+ register short *rp;
+ register short **reads;
+ register int nedges;
+ register int stateno;
+ register int symbol;
+ register int nwords;
+
+ nwords = ngotos * tokensetsize;
+ F = NEW2(nwords, unsigned);
+
+ reads = NEW2(ngotos, short *);
+ edge = NEW2(ngotos + 1, short);
+ nedges = 0;
+
+ rowp = F;
+ for (i = 0; i < ngotos; i++)
+ {
+ stateno = to_state[i];
+ sp = shift_table[stateno];
+
+ if (sp)
+ {
+ k = sp->nshifts;
+
+ for (j = 0; j < k; j++)
+ {
+ symbol = accessing_symbol[sp->shift[j]];
+ if (ISVAR(symbol))
+ break;
+ SETBIT(rowp, symbol);
+ }
+
+ for (; j < k; j++)
+ {
+ symbol = accessing_symbol[sp->shift[j]];
+ if (nullable[symbol])
+ edge[nedges++] = map_goto(stateno, symbol);
+ }
+
+ if (nedges)
+ {
+ reads[i] = rp = NEW2(nedges + 1, short);
+
+ for (j = 0; j < nedges; j++)
+ rp[j] = edge[j];
+
+ rp[nedges] = -1;
+ nedges = 0;
+ }
+ }
+
+ rowp += tokensetsize;
+ }
+
+ SETBIT(F, 0);
+ digraph(reads);
+
+ for (i = 0; i < ngotos; i++)
+ {
+ if (reads[i])
+ FREE(reads[i]);
+ }
+
+ FREE(reads);
+ FREE(edge);
+}
+
+
+
+build_relations()
+{
+ register int i;
+ register int j;
+ register int k;
+ register short *rulep;
+ register short *rp;
+ register shifts *sp;
+ register int length;
+ register int nedges;
+ register int done;
+ register int state1;
+ register int stateno;
+ register int symbol1;
+ register int symbol2;
+ register short *shortp;
+ register short *edge;
+ register short *states;
+ register short **new_includes;
+
+ includes = NEW2(ngotos, short *);
+ edge = NEW2(ngotos + 1, short);
+ states = NEW2(maxrhs + 1, short);
+
+ for (i = 0; i < ngotos; i++)
+ {
+ nedges = 0;
+ state1 = from_state[i];
+ symbol1 = accessing_symbol[to_state[i]];
+
+ for (rulep = derives[symbol1]; *rulep >= 0; rulep++)
+ {
+ length = 1;
+ states[0] = state1;
+ stateno = state1;
+
+ for (rp = ritem + rrhs[*rulep]; *rp >= 0; rp++)
+ {
+ symbol2 = *rp;
+ sp = shift_table[stateno];
+ k = sp->nshifts;
+
+ for (j = 0; j < k; j++)
+ {
+ stateno = sp->shift[j];
+ if (accessing_symbol[stateno] == symbol2) break;
+ }
+
+ states[length++] = stateno;
+ }
+
+ add_lookback_edge(stateno, *rulep, i);
+
+ length--;
+ done = 0;
+ while (!done)
+ {
+ done = 1;
+ rp--;
+ if (ISVAR(*rp))
+ {
+ stateno = states[--length];
+ edge[nedges++] = map_goto(stateno, *rp);
+ if (nullable[*rp] && length > 0) done = 0;
+ }
+ }
+ }
+
+ if (nedges)
+ {
+ includes[i] = shortp = NEW2(nedges + 1, short);
+ for (j = 0; j < nedges; j++)
+ shortp[j] = edge[j];
+ shortp[nedges] = -1;
+ }
+ }
+
+ new_includes = transpose(includes, ngotos);
+
+ for (i = 0; i < ngotos; i++)
+ if (includes[i])
+ FREE(includes[i]);
+
+ FREE(includes);
+
+ includes = new_includes;
+
+ FREE(edge);
+ FREE(states);
+}
+
+
+add_lookback_edge(stateno, ruleno, gotono)
+int stateno, ruleno, gotono;
+{
+ register int i, k;
+ register int found;
+ register shorts *sp;
+
+ i = lookaheads[stateno];
+ k = lookaheads[stateno + 1];
+ found = 0;
+ while (!found && i < k)
+ {
+ if (LAruleno[i] == ruleno)
+ found = 1;
+ else
+ ++i;
+ }
+ assert(found);
+
+ sp = NEW(shorts);
+ sp->next = lookback[i];
+ sp->value = gotono;
+ lookback[i] = sp;
+}
+
+
+
+short **
+transpose(R, n)
+short **R;
+int n;
+{
+ register short **new_R;
+ register short **temp_R;
+ register short *nedges;
+ register short *sp;
+ register int i;
+ register int k;
+
+ nedges = NEW2(n, short);
+
+ for (i = 0; i < n; i++)
+ {
+ sp = R[i];
+ if (sp)
+ {
+ while (*sp >= 0)
+ nedges[*sp++]++;
+ }
+ }
+
+ new_R = NEW2(n, short *);
+ temp_R = NEW2(n, short *);
+
+ for (i = 0; i < n; i++)
+ {
+ k = nedges[i];
+ if (k > 0)
+ {
+ sp = NEW2(k + 1, short);
+ new_R[i] = sp;
+ temp_R[i] = sp;
+ sp[k] = -1;
+ }
+ }
+
+ FREE(nedges);
+
+ for (i = 0; i < n; i++)
+ {
+ sp = R[i];
+ if (sp)
+ {
+ while (*sp >= 0)
+ *temp_R[*sp++]++ = i;
+ }
+ }
+
+ FREE(temp_R);
+
+ return (new_R);
+}
+
+
+
+compute_FOLLOWS()
+{
+ digraph(includes);
+}
+
+
+compute_lookaheads()
+{
+ register int i, n;
+ register unsigned *fp1, *fp2, *fp3;
+ register shorts *sp, *next;
+ register unsigned *rowp;
+
+ rowp = LA;
+ n = lookaheads[nstates];
+ for (i = 0; i < n; i++)
+ {
+ fp3 = rowp + tokensetsize;
+ for (sp = lookback[i]; sp; sp = sp->next)
+ {
+ fp1 = rowp;
+ fp2 = F + tokensetsize * sp->value;
+ while (fp1 < fp3)
+ *fp1++ |= *fp2++;
+ }
+ rowp = fp3;
+ }
+
+ for (i = 0; i < n; i++)
+ for (sp = lookback[i]; sp; sp = next)
+ {
+ next = sp->next;
+ FREE(sp);
+ }
+
+ FREE(lookback);
+ FREE(F);
+}
+
+
+digraph(relation)
+short **relation;
+{
+ register int i;
+
+ infinity = ngotos + 2;
+ INDEX = NEW2(ngotos + 1, short);
+ VERTICES = NEW2(ngotos + 1, short);
+ top = 0;
+
+ R = relation;
+
+ for (i = 0; i < ngotos; i++)
+ INDEX[i] = 0;
+
+ for (i = 0; i < ngotos; i++)
+ {
+ if (INDEX[i] == 0 && R[i])
+ traverse(i);
+ }
+
+ FREE(INDEX);
+ FREE(VERTICES);
+}
+
+
+
+traverse(i)
+register int i;
+{
+ register unsigned *fp1;
+ register unsigned *fp2;
+ register unsigned *fp3;
+ register int j;
+ register short *rp;
+
+ int height;
+ unsigned *base;
+
+ VERTICES[++top] = i;
+ INDEX[i] = height = top;
+
+ base = F + i * tokensetsize;
+ fp3 = base + tokensetsize;
+
+ rp = R[i];
+ if (rp)
+ {
+ while ((j = *rp++) >= 0)
+ {
+ if (INDEX[j] == 0)
+ traverse(j);
+
+ if (INDEX[i] > INDEX[j])
+ INDEX[i] = INDEX[j];
+
+ fp1 = base;
+ fp2 = F + j * tokensetsize;
+
+ while (fp1 < fp3)
+ *fp1++ |= *fp2++;
+ }
+ }
+
+ if (INDEX[i] == height)
+ {
+ for (;;)
+ {
+ j = VERTICES[top--];
+ INDEX[j] = infinity;
+
+ if (i == j)
+ break;
+
+ fp1 = base;
+ fp2 = F + j * tokensetsize;
+
+ while (fp1 < fp3)
+ *fp2++ = *fp1++;
+ }
+ }
+}
diff --git a/mcs/jay/lr0.c b/mcs/jay/lr0.c
new file mode 100644
index 00000000000..43106ea6cf3
--- /dev/null
+++ b/mcs/jay/lr0.c
@@ -0,0 +1,637 @@
+/*
+ * Copyright (c) 1989 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Robert Paul Corbett.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * 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 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)lr0.c 5.3 (Berkeley) 1/20/91";
+#endif /* not lint */
+
+#include "defs.h"
+
+extern short *itemset;
+extern short *itemsetend;
+extern unsigned *ruleset;
+
+int nstates;
+core *first_state;
+shifts *first_shift;
+reductions *first_reduction;
+
+int get_state();
+core *new_state();
+
+static core **state_set;
+static core *this_state;
+static core *last_state;
+static shifts *last_shift;
+static reductions *last_reduction;
+
+static int nshifts;
+static short *shift_symbol;
+
+static short *redset;
+static short *shiftset;
+
+static short **kernel_base;
+static short **kernel_end;
+static short *kernel_items;
+
+
+allocate_itemsets()
+{
+ register short *itemp;
+ register short *item_end;
+ register int symbol;
+ register int i;
+ register int count;
+ register int max;
+ register short *symbol_count;
+
+ count = 0;
+ symbol_count = NEW2(nsyms, short);
+
+ item_end = ritem + nitems;
+ for (itemp = ritem; itemp < item_end; itemp++)
+ {
+ symbol = *itemp;
+ if (symbol >= 0)
+ {
+ count++;
+ symbol_count[symbol]++;
+ }
+ }
+
+ kernel_base = NEW2(nsyms, short *);
+ kernel_items = NEW2(count, short);
+
+ count = 0;
+ max = 0;
+ for (i = 0; i < nsyms; i++)
+ {
+ kernel_base[i] = kernel_items + count;
+ count += symbol_count[i];
+ if (max < symbol_count[i])
+ max = symbol_count[i];
+ }
+
+ shift_symbol = symbol_count;
+ kernel_end = NEW2(nsyms, short *);
+}
+
+
+allocate_storage()
+{
+ allocate_itemsets();
+ shiftset = NEW2(nsyms, short);
+ redset = NEW2(nrules + 1, short);
+ state_set = NEW2(nitems, core *);
+}
+
+
+append_states()
+{
+ register int i;
+ register int j;
+ register int symbol;
+
+#ifdef TRACE
+ fprintf(stderr, "Entering append_states()\n");
+#endif
+ for (i = 1; i < nshifts; i++)
+ {
+ symbol = shift_symbol[i];
+ j = i;
+ while (j > 0 && shift_symbol[j - 1] > symbol)
+ {
+ shift_symbol[j] = shift_symbol[j - 1];
+ j--;
+ }
+ shift_symbol[j] = symbol;
+ }
+
+ for (i = 0; i < nshifts; i++)
+ {
+ symbol = shift_symbol[i];
+ shiftset[i] = get_state(symbol);
+ }
+}
+
+
+free_storage()
+{
+ FREE(shift_symbol);
+ FREE(redset);
+ FREE(shiftset);
+ FREE(kernel_base);
+ FREE(kernel_end);
+ FREE(kernel_items);
+ FREE(state_set);
+}
+
+
+
+generate_states()
+{
+ allocate_storage();
+ itemset = NEW2(nitems, short);
+ ruleset = NEW2(WORDSIZE(nrules), unsigned);
+ set_first_derives();
+ initialize_states();
+
+ while (this_state)
+ {
+ closure(this_state->items, this_state->nitems);
+ save_reductions();
+ new_itemsets();
+ append_states();
+
+ if (nshifts > 0)
+ save_shifts();
+
+ this_state = this_state->next;
+ }
+
+ finalize_closure();
+ free_storage();
+}
+
+
+
+int
+get_state(symbol)
+int symbol;
+{
+ register int key;
+ register short *isp1;
+ register short *isp2;
+ register short *iend;
+ register core *sp;
+ register int found;
+ register int n;
+
+#ifdef TRACE
+ fprintf(stderr, "Entering get_state(%d)\n", symbol);
+#endif
+
+ isp1 = kernel_base[symbol];
+ iend = kernel_end[symbol];
+ n = iend - isp1;
+
+ key = *isp1;
+ assert(0 <= key && key < nitems);
+ sp = state_set[key];
+ if (sp)
+ {
+ found = 0;
+ while (!found)
+ {
+ if (sp->nitems == n)
+ {
+ found = 1;
+ isp1 = kernel_base[symbol];
+ isp2 = sp->items;
+
+ while (found && isp1 < iend)
+ {
+ if (*isp1++ != *isp2++)
+ found = 0;
+ }
+ }
+
+ if (!found)
+ {
+ if (sp->link)
+ {
+ sp = sp->link;
+ }
+ else
+ {
+ sp = sp->link = new_state(symbol);
+ found = 1;
+ }
+ }
+ }
+ }
+ else
+ {
+ state_set[key] = sp = new_state(symbol);
+ }
+
+ return (sp->number);
+}
+
+
+
+initialize_states()
+{
+ register int i;
+ register short *start_derives;
+ register core *p;
+
+ start_derives = derives[start_symbol];
+ for (i = 0; start_derives[i] >= 0; ++i)
+ continue;
+
+ p = (core *) MALLOC(sizeof(core) + i*sizeof(short));
+ if (p == 0) no_space();
+
+ p->next = 0;
+ p->link = 0;
+ p->number = 0;
+ p->accessing_symbol = 0;
+ p->nitems = i;
+
+ for (i = 0; start_derives[i] >= 0; ++i)
+ p->items[i] = rrhs[start_derives[i]];
+
+ first_state = last_state = this_state = p;
+ nstates = 1;
+}
+
+
+new_itemsets()
+{
+ register int i;
+ register int shiftcount;
+ register short *isp;
+ register short *ksp;
+ register int symbol;
+
+ for (i = 0; i < nsyms; i++)
+ kernel_end[i] = 0;
+
+ shiftcount = 0;
+ isp = itemset;
+ while (isp < itemsetend)
+ {
+ i = *isp++;
+ symbol = ritem[i];
+ if (symbol > 0)
+ {
+ ksp = kernel_end[symbol];
+ if (!ksp)
+ {
+ shift_symbol[shiftcount++] = symbol;
+ ksp = kernel_base[symbol];
+ }
+
+ *ksp++ = i + 1;
+ kernel_end[symbol] = ksp;
+ }
+ }
+
+ nshifts = shiftcount;
+}
+
+
+
+core *
+new_state(symbol)
+int symbol;
+{
+ register int n;
+ register core *p;
+ register short *isp1;
+ register short *isp2;
+ register short *iend;
+
+#ifdef TRACE
+ fprintf(stderr, "Entering new_state(%d)\n", symbol);
+#endif
+
+ if (nstates >= MAXSHORT)
+ fatal("too many states");
+
+ isp1 = kernel_base[symbol];
+ iend = kernel_end[symbol];
+ n = iend - isp1;
+
+ p = (core *) allocate((unsigned) (sizeof(core) + (n - 1) * sizeof(short)));
+ p->accessing_symbol = symbol;
+ p->number = nstates;
+ p->nitems = n;
+
+ isp2 = p->items;
+ while (isp1 < iend)
+ *isp2++ = *isp1++;
+
+ last_state->next = p;
+ last_state = p;
+
+ nstates++;
+
+ return (p);
+}
+
+
+/* show_cores is used for debugging */
+
+show_cores()
+{
+ core *p;
+ int i, j, k, n;
+ int itemno;
+
+ k = 0;
+ for (p = first_state; p; ++k, p = p->next)
+ {
+ if (k) printf("\n");
+ printf("state %d, number = %d, accessing symbol = %s\n",
+ k, p->number, symbol_name[p->accessing_symbol]);
+ n = p->nitems;
+ for (i = 0; i < n; ++i)
+ {
+ itemno = p->items[i];
+ printf("%4d ", itemno);
+ j = itemno;
+ while (ritem[j] >= 0) ++j;
+ printf("%s :", symbol_name[rlhs[-ritem[j]]]);
+ j = rrhs[-ritem[j]];
+ while (j < itemno)
+ printf(" %s", symbol_name[ritem[j++]]);
+ printf(" .");
+ while (ritem[j] >= 0)
+ printf(" %s", symbol_name[ritem[j++]]);
+ printf("\n");
+ fflush(stdout);
+ }
+ }
+}
+
+
+/* show_ritems is used for debugging */
+
+show_ritems()
+{
+ int i;
+
+ for (i = 0; i < nitems; ++i)
+ printf("ritem[%d] = %d\n", i, ritem[i]);
+}
+
+
+/* show_rrhs is used for debugging */
+show_rrhs()
+{
+ int i;
+
+ for (i = 0; i < nrules; ++i)
+ printf("rrhs[%d] = %d\n", i, rrhs[i]);
+}
+
+
+/* show_shifts is used for debugging */
+
+show_shifts()
+{
+ shifts *p;
+ int i, j, k;
+
+ k = 0;
+ for (p = first_shift; p; ++k, p = p->next)
+ {
+ if (k) printf("\n");
+ printf("shift %d, number = %d, nshifts = %d\n", k, p->number,
+ p->nshifts);
+ j = p->nshifts;
+ for (i = 0; i < j; ++i)
+ printf("\t%d\n", p->shift[i]);
+ }
+}
+
+
+save_shifts()
+{
+ register shifts *p;
+ register short *sp1;
+ register short *sp2;
+ register short *send;
+
+ p = (shifts *) allocate((unsigned) (sizeof(shifts) +
+ (nshifts - 1) * sizeof(short)));
+
+ p->number = this_state->number;
+ p->nshifts = nshifts;
+
+ sp1 = shiftset;
+ sp2 = p->shift;
+ send = shiftset + nshifts;
+
+ while (sp1 < send)
+ *sp2++ = *sp1++;
+
+ if (last_shift)
+ {
+ last_shift->next = p;
+ last_shift = p;
+ }
+ else
+ {
+ first_shift = p;
+ last_shift = p;
+ }
+}
+
+
+
+save_reductions()
+{
+ register short *isp;
+ register short *rp1;
+ register short *rp2;
+ register int item;
+ register int count;
+ register reductions *p;
+ register short *rend;
+
+ count = 0;
+ for (isp = itemset; isp < itemsetend; isp++)
+ {
+ item = ritem[*isp];
+ if (item < 0)
+ {
+ redset[count++] = -item;
+ }
+ }
+
+ if (count)
+ {
+ p = (reductions *) allocate((unsigned) (sizeof(reductions) +
+ (count - 1) * sizeof(short)));
+
+ p->number = this_state->number;
+ p->nreds = count;
+
+ rp1 = redset;
+ rp2 = p->rules;
+ rend = rp1 + count;
+
+ while (rp1 < rend)
+ *rp2++ = *rp1++;
+
+ if (last_reduction)
+ {
+ last_reduction->next = p;
+ last_reduction = p;
+ }
+ else
+ {
+ first_reduction = p;
+ last_reduction = p;
+ }
+ }
+}
+
+
+set_derives()
+{
+ register int i, k;
+ register int lhs;
+ register short *rules;
+
+ derives = NEW2(nsyms, short *);
+ rules = NEW2(nvars + nrules, short);
+
+ k = 0;
+ for (lhs = start_symbol; lhs < nsyms; lhs++)
+ {
+ derives[lhs] = rules + k;
+ for (i = 0; i < nrules; i++)
+ {
+ if (rlhs[i] == lhs)
+ {
+ rules[k] = i;
+ k++;
+ }
+ }
+ rules[k] = -1;
+ k++;
+ }
+
+#ifdef DEBUG
+ print_derives();
+#endif
+}
+
+free_derives()
+{
+ FREE(derives[start_symbol]);
+ FREE(derives);
+}
+
+#ifdef DEBUG
+print_derives()
+{
+ register int i;
+ register short *sp;
+
+ printf("\nDERIVES\n\n");
+
+ for (i = start_symbol; i < nsyms; i++)
+ {
+ printf("%s derives ", symbol_name[i]);
+ for (sp = derives[i]; *sp >= 0; sp++)
+ {
+ printf(" %d", *sp);
+ }
+ putchar('\n');
+ }
+
+ putchar('\n');
+}
+#endif
+
+
+set_nullable()
+{
+ register int i, j;
+ register int empty;
+ int done;
+
+ nullable = MALLOC(nsyms);
+ if (nullable == 0) no_space();
+
+ for (i = 0; i < nsyms; ++i)
+ nullable[i] = 0;
+
+ done = 0;
+ while (!done)
+ {
+ done = 1;
+ for (i = 1; i < nitems; i++)
+ {
+ empty = 1;
+ while ((j = ritem[i]) >= 0)
+ {
+ if (!nullable[j])
+ empty = 0;
+ ++i;
+ }
+ if (empty)
+ {
+ j = rlhs[-j];
+ if (!nullable[j])
+ {
+ nullable[j] = 1;
+ done = 0;
+ }
+ }
+ }
+ }
+
+#ifdef DEBUG
+ for (i = 0; i < nsyms; i++)
+ {
+ if (nullable[i])
+ printf("%s is nullable\n", symbol_name[i]);
+ else
+ printf("%s is not nullable\n", symbol_name[i]);
+ }
+#endif
+}
+
+
+free_nullable()
+{
+ FREE(nullable);
+}
+
+
+lr0()
+{
+ set_derives();
+ set_nullable();
+ generate_states();
+}
diff --git a/mcs/jay/main.c b/mcs/jay/main.c
new file mode 100644
index 00000000000..c6954eb9285
--- /dev/null
+++ b/mcs/jay/main.c
@@ -0,0 +1,341 @@
+/*
+ * Copyright (c) 1989 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Robert Paul Corbett.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * 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 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+char copyright[] =
+"@(#) Copyright (c) 1989 The Regents of the University of California.\n\
+ All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static char sccsid[] = "@(#)main.c 5.5 (Berkeley) 5/24/93";
+#endif /* not lint */
+
+#include <signal.h>
+#include "defs.h"
+
+char tflag;
+char vflag;
+char csharp = 0;
+
+char *file_prefix = "y";
+char *myname = "yacc";
+char *temp_form = "yacc.XXXXXXX";
+
+int lineno;
+int outline;
+
+char *action_file_name;
+char *input_file_name = "";
+char *prolog_file_name;
+char *local_file_name;
+char *verbose_file_name;
+
+FILE *action_file; /* a temp file, used to save actions associated */
+ /* with rules until the parser is written */
+FILE *input_file; /* the input file */
+FILE *prolog_file; /* temp files, used to save text until all */
+FILE *local_file; /* symbols have been defined */
+FILE *verbose_file; /* y.output */
+
+int nitems;
+int nrules;
+int nsyms;
+int ntokens;
+int nvars;
+
+int start_symbol;
+char **symbol_name;
+short *symbol_value;
+short *symbol_prec;
+char *symbol_assoc;
+
+short *ritem;
+short *rlhs;
+short *rrhs;
+short *rprec;
+char *rassoc;
+short **derives;
+char *nullable;
+
+extern char *mktemp();
+extern char *getenv();
+
+done(k)
+int k;
+{
+ if (action_file) { fclose(action_file); unlink(action_file_name); }
+ if (prolog_file) { fclose(prolog_file); unlink(prolog_file_name); }
+ if (local_file) { fclose(local_file); unlink(local_file_name); }
+ exit(k);
+}
+
+
+void
+onintr(signo)
+ int signo;
+{
+ done(1);
+}
+
+
+set_signals()
+{
+#ifdef SIGINT
+ if (signal(SIGINT, SIG_IGN) != SIG_IGN)
+ signal(SIGINT, onintr);
+#endif
+#ifdef SIGTERM
+ if (signal(SIGTERM, SIG_IGN) != SIG_IGN)
+ signal(SIGTERM, onintr);
+#endif
+#ifdef SIGHUP
+ if (signal(SIGHUP, SIG_IGN) != SIG_IGN)
+ signal(SIGHUP, onintr);
+#endif
+}
+
+
+usage()
+{
+ fprintf(stderr, "usage: %s [-tvc] [-b file_prefix] filename\n", myname);
+ exit(1);
+}
+
+
+getargs(argc, argv)
+int argc;
+char *argv[];
+{
+ register int i;
+ register char *s;
+
+ if (argc > 0) myname = argv[0];
+ for (i = 1; i < argc; ++i)
+ {
+ s = argv[i];
+ if (*s != '-') break;
+ switch (*++s)
+ {
+ case '\0':
+ input_file = stdin;
+ if (i + 1 < argc) usage();
+ return;
+
+ case '-':
+ ++i;
+ goto no_more_options;
+
+ case 'b':
+ if (*++s)
+ file_prefix = s;
+ else if (++i < argc)
+ file_prefix = argv[i];
+ else
+ usage();
+ continue;
+
+ case 't':
+ tflag = 1;
+ break;
+
+ case 'c':
+ csharp = 1;
+ line_format = "#line %d \"%s\"\n";
+ break;
+
+ case 'v':
+ vflag = 1;
+ break;
+
+ default:
+ usage();
+ }
+
+ for (;;)
+ {
+ switch (*++s)
+ {
+ case '\0':
+ goto end_of_option;
+
+ case 't':
+ tflag = 1;
+ break;
+
+ case 'v':
+ vflag = 1;
+ break;
+
+ case 'c':
+ csharp = 1;
+ break;
+
+ default:
+ usage();
+ }
+ }
+end_of_option:;
+ }
+
+no_more_options:;
+ if (i + 1 != argc) usage();
+ input_file_name = argv[i];
+}
+
+
+char *
+allocate(n)
+unsigned n;
+{
+ register char *p;
+
+ p = NULL;
+ if (n)
+ {
+ p = CALLOC(1, n);
+ if (!p) no_space();
+ }
+ return (p);
+}
+
+
+create_file_names()
+{
+ int i, len;
+ char *tmpdir;
+
+ tmpdir = getenv("TMPDIR");
+ if (tmpdir == 0) tmpdir = "/tmp";
+
+ len = strlen(tmpdir);
+ i = len + 13;
+ if (len && tmpdir[len-1] != '/')
+ ++i;
+
+ action_file_name = MALLOC(i);
+ if (action_file_name == 0) no_space();
+ prolog_file_name = MALLOC(i);
+ if (prolog_file_name == 0) no_space();
+ local_file_name = MALLOC(i);
+ if (local_file_name == 0) no_space();
+
+ strcpy(action_file_name, tmpdir);
+ strcpy(prolog_file_name, tmpdir);
+ strcpy(local_file_name, tmpdir);
+
+ if (len && tmpdir[len - 1] != '/')
+ {
+ action_file_name[len] = '/';
+ prolog_file_name[len] = '/';
+ local_file_name[len] = '/';
+ ++len;
+ }
+
+ strcpy(action_file_name + len, temp_form);
+ strcpy(prolog_file_name + len, temp_form);
+ strcpy(local_file_name + len, temp_form);
+
+ action_file_name[len + 5] = 'a';
+ prolog_file_name[len + 5] = 'p';
+ local_file_name[len + 5] = 'l';
+
+ mktemp(action_file_name);
+ mktemp(prolog_file_name);
+ mktemp(local_file_name);
+
+ len = strlen(file_prefix);
+
+ if (vflag)
+ {
+ verbose_file_name = MALLOC(len + 8);
+ if (verbose_file_name == 0)
+ no_space();
+ strcpy(verbose_file_name, file_prefix);
+ strcpy(verbose_file_name + len, VERBOSE_SUFFIX);
+ }
+}
+
+
+open_files()
+{
+ create_file_names();
+
+ if (input_file == 0)
+ {
+ input_file = fopen(input_file_name, "r");
+ if (input_file == 0)
+ open_error(input_file_name);
+ }
+
+ action_file = fopen(action_file_name, "w");
+ if (action_file == 0)
+ open_error(action_file_name);
+
+ prolog_file = fopen(prolog_file_name, "w");
+ if (prolog_file == 0)
+ open_error(prolog_file_name);
+
+ local_file = fopen(local_file_name, "w");
+ if (local_file == 0)
+ open_error(local_file_name);
+
+ if (vflag)
+ {
+ verbose_file = fopen(verbose_file_name, "w");
+ if (verbose_file == 0)
+ open_error(verbose_file_name);
+ }
+}
+
+
+int
+main(argc, argv)
+int argc;
+char *argv[];
+{
+ set_signals();
+ getargs(argc, argv);
+ open_files();
+ reader();
+ lr0();
+ lalr();
+ make_parser();
+ verbose();
+ output();
+ done(0);
+ /*NOTREACHED*/
+}
diff --git a/mcs/jay/makefile b/mcs/jay/makefile
new file mode 100644
index 00000000000..82cce87c559
--- /dev/null
+++ b/mcs/jay/makefile
@@ -0,0 +1,14 @@
+all = jay
+c = closure.c error.c lalr.c lr0.c main.c mkpar.c output.c reader.c \
+ symtab.c verbose.c warshall.c
+
+CFLAGS=#-g
+
+jay: $(c:.c=.o) ; $(CC) -o $@ $(CFLAGS) $(c:.c=.o)
+
+clean:
+ rm -f jay *.o
+
+windows: jay
+
+unix: jay
diff --git a/mcs/jay/mkpar.c b/mcs/jay/mkpar.c
new file mode 100644
index 00000000000..42ead14514d
--- /dev/null
+++ b/mcs/jay/mkpar.c
@@ -0,0 +1,395 @@
+/*
+ * Copyright (c) 1989 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Robert Paul Corbett.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * 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 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)mkpar.c 5.3 (Berkeley) 1/20/91";
+#endif /* not lint */
+
+#include "defs.h"
+
+action **parser;
+int SRtotal;
+int RRtotal;
+short *SRconflicts;
+short *RRconflicts;
+short *defred;
+short *rules_used;
+short nunused;
+short final_state;
+
+static int SRcount;
+static int RRcount;
+
+extern action *parse_actions();
+extern action *get_shifts();
+extern action *add_reductions();
+extern action *add_reduce();
+
+
+make_parser()
+{
+ register int i;
+
+ parser = NEW2(nstates, action *);
+ for (i = 0; i < nstates; i++)
+ parser[i] = parse_actions(i);
+
+ find_final_state();
+ remove_conflicts();
+ unused_rules();
+ if (SRtotal + RRtotal > 0) total_conflicts();
+ defreds();
+}
+
+
+action *
+parse_actions(stateno)
+register int stateno;
+{
+ register action *actions;
+
+ actions = get_shifts(stateno);
+ actions = add_reductions(stateno, actions);
+ return (actions);
+}
+
+
+action *
+get_shifts(stateno)
+int stateno;
+{
+ register action *actions, *temp;
+ register shifts *sp;
+ register short *to_state;
+ register int i, k;
+ register int symbol;
+
+ actions = 0;
+ sp = shift_table[stateno];
+ if (sp)
+ {
+ to_state = sp->shift;
+ for (i = sp->nshifts - 1; i >= 0; i--)
+ {
+ k = to_state[i];
+ symbol = accessing_symbol[k];
+ if (ISTOKEN(symbol))
+ {
+ temp = NEW(action);
+ temp->next = actions;
+ temp->symbol = symbol;
+ temp->number = k;
+ temp->prec = symbol_prec[symbol];
+ temp->action_code = SHIFT;
+ temp->assoc = symbol_assoc[symbol];
+ actions = temp;
+ }
+ }
+ }
+ return (actions);
+}
+
+action *
+add_reductions(stateno, actions)
+int stateno;
+register action *actions;
+{
+ register int i, j, m, n;
+ register int ruleno, tokensetsize;
+ register unsigned *rowp;
+
+ tokensetsize = WORDSIZE(ntokens);
+ m = lookaheads[stateno];
+ n = lookaheads[stateno + 1];
+ for (i = m; i < n; i++)
+ {
+ ruleno = LAruleno[i];
+ rowp = LA + i * tokensetsize;
+ for (j = ntokens - 1; j >= 0; j--)
+ {
+ if (BIT(rowp, j))
+ actions = add_reduce(actions, ruleno, j);
+ }
+ }
+ return (actions);
+}
+
+
+action *
+add_reduce(actions, ruleno, symbol)
+register action *actions;
+register int ruleno, symbol;
+{
+ register action *temp, *prev, *next;
+
+ prev = 0;
+ for (next = actions; next && next->symbol < symbol; next = next->next)
+ prev = next;
+
+ while (next && next->symbol == symbol && next->action_code == SHIFT)
+ {
+ prev = next;
+ next = next->next;
+ }
+
+ while (next && next->symbol == symbol &&
+ next->action_code == REDUCE && next->number < ruleno)
+ {
+ prev = next;
+ next = next->next;
+ }
+
+ temp = NEW(action);
+ temp->next = next;
+ temp->symbol = symbol;
+ temp->number = ruleno;
+ temp->prec = rprec[ruleno];
+ temp->action_code = REDUCE;
+ temp->assoc = rassoc[ruleno];
+
+ if (prev)
+ prev->next = temp;
+ else
+ actions = temp;
+
+ return (actions);
+}
+
+
+find_final_state()
+{
+ register int goal, i;
+ register short *to_state;
+ register shifts *p;
+
+ p = shift_table[0];
+ to_state = p->shift;
+ goal = ritem[1];
+ for (i = p->nshifts - 1; i >= 0; --i)
+ {
+ final_state = to_state[i];
+ if (accessing_symbol[final_state] == goal) break;
+ }
+}
+
+
+unused_rules()
+{
+ register int i;
+ register action *p;
+
+ rules_used = (short *) MALLOC(nrules*sizeof(short));
+ if (rules_used == 0) no_space();
+
+ for (i = 0; i < nrules; ++i)
+ rules_used[i] = 0;
+
+ for (i = 0; i < nstates; ++i)
+ {
+ for (p = parser[i]; p; p = p->next)
+ {
+ if (p->action_code == REDUCE && p->suppressed == 0)
+ rules_used[p->number] = 1;
+ }
+ }
+
+ nunused = 0;
+ for (i = 3; i < nrules; ++i)
+ if (!rules_used[i]) ++nunused;
+
+ if (nunused)
+ if (nunused == 1)
+ fprintf(stderr, "%s: 1 rule never reduced\n", myname);
+ else
+ fprintf(stderr, "%s: %d rules never reduced\n", myname, nunused);
+}
+
+
+remove_conflicts()
+{
+ register int i;
+ register int symbol;
+ register action *p, *pref;
+
+ SRtotal = 0;
+ RRtotal = 0;
+ SRconflicts = NEW2(nstates, short);
+ RRconflicts = NEW2(nstates, short);
+ for (i = 0; i < nstates; i++)
+ {
+ SRcount = 0;
+ RRcount = 0;
+ symbol = -1;
+ for (p = parser[i]; p; p = p->next)
+ {
+ if (p->symbol != symbol)
+ {
+ pref = p;
+ symbol = p->symbol;
+ }
+ else if (i == final_state && symbol == 0)
+ {
+ SRcount++;
+ p->suppressed = 1;
+ }
+ else if (pref->action_code == SHIFT)
+ {
+ if (pref->prec > 0 && p->prec > 0)
+ {
+ if (pref->prec < p->prec)
+ {
+ pref->suppressed = 2;
+ pref = p;
+ }
+ else if (pref->prec > p->prec)
+ {
+ p->suppressed = 2;
+ }
+ else if (pref->assoc == LEFT)
+ {
+ pref->suppressed = 2;
+ pref = p;
+ }
+ else if (pref->assoc == RIGHT)
+ {
+ p->suppressed = 2;
+ }
+ else
+ {
+ pref->suppressed = 2;
+ p->suppressed = 2;
+ }
+ }
+ else
+ {
+ SRcount++;
+ p->suppressed = 1;
+ }
+ }
+ else
+ {
+ RRcount++;
+ p->suppressed = 1;
+ }
+ }
+ SRtotal += SRcount;
+ RRtotal += RRcount;
+ SRconflicts[i] = SRcount;
+ RRconflicts[i] = RRcount;
+ }
+}
+
+
+total_conflicts()
+{
+ fprintf(stderr, "%s: ", myname);
+ if (SRtotal == 1)
+ fprintf(stderr, "1 shift/reduce conflict");
+ else if (SRtotal > 1)
+ fprintf(stderr, "%d shift/reduce conflicts", SRtotal);
+
+ if (SRtotal && RRtotal)
+ fprintf(stderr, ", ");
+
+ if (RRtotal == 1)
+ fprintf(stderr, "1 reduce/reduce conflict");
+ else if (RRtotal > 1)
+ fprintf(stderr, "%d reduce/reduce conflicts", RRtotal);
+
+ fprintf(stderr, ".\n");
+}
+
+
+int
+sole_reduction(stateno)
+int stateno;
+{
+ register int count, ruleno;
+ register action *p;
+
+ count = 0;
+ ruleno = 0;
+ for (p = parser[stateno]; p; p = p->next)
+ {
+ if (p->action_code == SHIFT && p->suppressed == 0)
+ return (0);
+ else if (p->action_code == REDUCE && p->suppressed == 0)
+ {
+ if (ruleno > 0 && p->number != ruleno)
+ return (0);
+ if (p->symbol != 1)
+ ++count;
+ ruleno = p->number;
+ }
+ }
+
+ if (count == 0)
+ return (0);
+ return (ruleno);
+}
+
+
+defreds()
+{
+ register int i;
+
+ defred = NEW2(nstates, short);
+ for (i = 0; i < nstates; i++)
+ defred[i] = sole_reduction(i);
+}
+
+free_action_row(p)
+register action *p;
+{
+ register action *q;
+
+ while (p)
+ {
+ q = p->next;
+ FREE(p);
+ p = q;
+ }
+}
+
+free_parser()
+{
+ register int i;
+
+ for (i = 0; i < nstates; i++)
+ free_action_row(parser[i]);
+
+ FREE(parser);
+}
diff --git a/mcs/jay/output.c b/mcs/jay/output.c
new file mode 100644
index 00000000000..81e4755c9cd
--- /dev/null
+++ b/mcs/jay/output.c
@@ -0,0 +1,1173 @@
+/*
+ * Copyright (c) 1989 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Robert Paul Corbett.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * 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 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)output.c 5.7 (Berkeley) 5/24/93";
+#endif /* not lint */
+
+#include "defs.h"
+#include <string.h>
+
+static int nvectors;
+static int nentries;
+static short **froms;
+static short **tos;
+static short *tally;
+static short *width;
+static short *state_count;
+static short *order;
+static short *base;
+static short *pos;
+static int maxtable;
+static short *table;
+static short *check;
+static int lowzero;
+static int high;
+extern int csharp;
+
+output () {
+ int lno = 0;
+ char buf [128];
+
+ free_itemsets();
+ free_shifts();
+ free_reductions();
+
+ while (fgets(buf, sizeof buf, stdin) != NULL) {
+ char * cp;
+ ++ lno;
+ if (buf[strlen(buf)-1] != '\n')
+ fprintf(stderr, "jay: line %d is too long\n", lno), done(1);
+ switch (buf[0]) {
+ case '#': continue;
+ case 't': if (!tflag) fputs("//t", stdout);
+ case '.': break;
+ default:
+ cp = strtok(buf, " \t\r\n");
+ if (cp)
+ if (strcmp(cp, "actions") == 0) output_semantic_actions();
+ else if (strcmp(cp, "debug") == 0) output_debug();
+ else if (strcmp(cp, "epilog") == 0) output_trailing_text();
+ else if (strcmp(cp, "prolog") == 0)
+ output_stored_text(prolog_file, prolog_file_name);
+ else if (strcmp(cp, "local") == 0)
+ output_stored_text(local_file, local_file_name);
+ else if (strcmp(cp, "tables") == 0)
+ output_rule_data(), output_yydefred(), output_actions();
+ else if (strcmp(cp, "tokens") == 0)
+ output_defines(strtok(NULL, "\r\n"));
+ else
+ fprintf(stderr, "jay: unknown call (%s) in line %d\n", cp, lno);
+ continue;
+ }
+ fputs(buf+1, stdout), ++ outline;
+ }
+ free_parser();
+}
+
+output_rule_data()
+{
+ register int i;
+ register int j;
+
+
+ printf(" %s static %s short [] yyLhs = {%16d,",
+ csharp ? "" : " protected",
+ csharp ? "" : " final",
+ symbol_value[start_symbol]);
+
+ j = 10;
+ for (i = 3; i < nrules; i++)
+ {
+ if (j >= 10)
+ {
+ ++outline;
+ putchar('\n');
+ j = 1;
+ }
+ else
+ ++j;
+
+ printf("%5d,", symbol_value[rlhs[i]]);
+ }
+ outline += 2;
+ printf("\n };\n");
+
+ printf(" %s static %s short [] yyLen = {%12d,",
+ csharp ? "" : "protected",
+ csharp ? "" : "final",
+ 2);
+
+ j = 10;
+ for (i = 3; i < nrules; i++)
+ {
+ if (j >= 10)
+ {
+ ++outline;
+ putchar('\n');
+ j = 1;
+ }
+ else
+ j++;
+
+ printf("%5d,", rrhs[i + 1] - rrhs[i] - 1);
+ }
+ outline += 2;
+ printf("\n };\n");
+}
+
+
+output_yydefred()
+{
+ register int i, j;
+
+ printf(" %s static %s short [] yyDefRed = {%13d,",
+ csharp ? "" : "protected",
+ csharp ? "" : "final",
+ (defred[0] ? defred[0] - 2 : 0));
+
+ j = 10;
+ for (i = 1; i < nstates; i++)
+ {
+ if (j < 10)
+ ++j;
+ else
+ {
+ ++outline;
+ putchar('\n');
+ j = 1;
+ }
+
+ printf("%5d,", (defred[i] ? defred[i] - 2 : 0));
+ }
+
+ outline += 2;
+ printf("\n };\n");
+}
+
+
+output_actions()
+{
+ nvectors = 2*nstates + nvars;
+
+ froms = NEW2(nvectors, short *);
+ tos = NEW2(nvectors, short *);
+ tally = NEW2(nvectors, short);
+ width = NEW2(nvectors, short);
+
+ token_actions();
+ FREE(lookaheads);
+ FREE(LA);
+ FREE(LAruleno);
+ FREE(accessing_symbol);
+
+ goto_actions();
+ FREE(goto_map + ntokens);
+ FREE(from_state);
+ FREE(to_state);
+
+ sort_actions();
+ pack_table();
+ output_base();
+ output_table();
+ output_check();
+}
+
+
+token_actions()
+{
+ register int i, j;
+ register int shiftcount, reducecount;
+ register int max, min;
+ register short *actionrow, *r, *s;
+ register action *p;
+
+ actionrow = NEW2(2*ntokens, short);
+ for (i = 0; i < nstates; ++i)
+ {
+ if (parser[i])
+ {
+ for (j = 0; j < 2*ntokens; ++j)
+ actionrow[j] = 0;
+
+ shiftcount = 0;
+ reducecount = 0;
+ for (p = parser[i]; p; p = p->next)
+ {
+ if (p->suppressed == 0)
+ {
+ if (p->action_code == SHIFT)
+ {
+ ++shiftcount;
+ actionrow[p->symbol] = p->number;
+ }
+ else if (p->action_code == REDUCE && p->number != defred[i])
+ {
+ ++reducecount;
+ actionrow[p->symbol + ntokens] = p->number;
+ }
+ }
+ }
+
+ tally[i] = shiftcount;
+ tally[nstates+i] = reducecount;
+ width[i] = 0;
+ width[nstates+i] = 0;
+ if (shiftcount > 0)
+ {
+ froms[i] = r = NEW2(shiftcount, short);
+ tos[i] = s = NEW2(shiftcount, short);
+ min = MAXSHORT;
+ max = 0;
+ for (j = 0; j < ntokens; ++j)
+ {
+ if (actionrow[j])
+ {
+ if (min > symbol_value[j])
+ min = symbol_value[j];
+ if (max < symbol_value[j])
+ max = symbol_value[j];
+ *r++ = symbol_value[j];
+ *s++ = actionrow[j];
+ }
+ }
+ width[i] = max - min + 1;
+ }
+ if (reducecount > 0)
+ {
+ froms[nstates+i] = r = NEW2(reducecount, short);
+ tos[nstates+i] = s = NEW2(reducecount, short);
+ min = MAXSHORT;
+ max = 0;
+ for (j = 0; j < ntokens; ++j)
+ {
+ if (actionrow[ntokens+j])
+ {
+ if (min > symbol_value[j])
+ min = symbol_value[j];
+ if (max < symbol_value[j])
+ max = symbol_value[j];
+ *r++ = symbol_value[j];
+ *s++ = actionrow[ntokens+j] - 2;
+ }
+ }
+ width[nstates+i] = max - min + 1;
+ }
+ }
+ }
+ FREE(actionrow);
+}
+
+goto_actions()
+{
+ register int i, j, k;
+
+ state_count = NEW2(nstates, short);
+
+ k = default_goto(start_symbol + 1);
+ printf(" protected static %s short [] yyDgoto = {%14d,", csharp ? "" : "final", k);
+ save_column(start_symbol + 1, k);
+
+ j = 10;
+ for (i = start_symbol + 2; i < nsyms; i++)
+ {
+ if (j >= 10)
+ {
+ ++outline;
+ putchar('\n');
+ j = 1;
+ }
+ else
+ ++j;
+
+ k = default_goto(i);
+ printf("%5d,", k);
+ save_column(i, k);
+ }
+
+ outline += 2;
+ printf("\n };\n");
+ FREE(state_count);
+}
+
+int
+default_goto(symbol)
+int symbol;
+{
+ register int i;
+ register int m;
+ register int n;
+ register int default_state;
+ register int max;
+
+ m = goto_map[symbol];
+ n = goto_map[symbol + 1];
+
+ if (m == n) return (0);
+
+ for (i = 0; i < nstates; i++)
+ state_count[i] = 0;
+
+ for (i = m; i < n; i++)
+ state_count[to_state[i]]++;
+
+ max = 0;
+ default_state = 0;
+ for (i = 0; i < nstates; i++)
+ {
+ if (state_count[i] > max)
+ {
+ max = state_count[i];
+ default_state = i;
+ }
+ }
+
+ return (default_state);
+}
+
+
+
+save_column(symbol, default_state)
+int symbol;
+int default_state;
+{
+ register int i;
+ register int m;
+ register int n;
+ register short *sp;
+ register short *sp1;
+ register short *sp2;
+ register int count;
+ register int symno;
+
+ m = goto_map[symbol];
+ n = goto_map[symbol + 1];
+
+ count = 0;
+ for (i = m; i < n; i++)
+ {
+ if (to_state[i] != default_state)
+ ++count;
+ }
+ if (count == 0) return;
+
+ symno = symbol_value[symbol] + 2*nstates;
+
+ froms[symno] = sp1 = sp = NEW2(count, short);
+ tos[symno] = sp2 = NEW2(count, short);
+
+ for (i = m; i < n; i++)
+ {
+ if (to_state[i] != default_state)
+ {
+ *sp1++ = from_state[i];
+ *sp2++ = to_state[i];
+ }
+ }
+
+ tally[symno] = count;
+ width[symno] = sp1[-1] - sp[0] + 1;
+}
+
+sort_actions()
+{
+ register int i;
+ register int j;
+ register int k;
+ register int t;
+ register int w;
+
+ order = NEW2(nvectors, short);
+ nentries = 0;
+
+ for (i = 0; i < nvectors; i++)
+ {
+ if (tally[i] > 0)
+ {
+ t = tally[i];
+ w = width[i];
+ j = nentries - 1;
+
+ while (j >= 0 && (width[order[j]] < w))
+ j--;
+
+ while (j >= 0 && (width[order[j]] == w) && (tally[order[j]] < t))
+ j--;
+
+ for (k = nentries - 1; k > j; k--)
+ order[k + 1] = order[k];
+
+ order[j + 1] = i;
+ nentries++;
+ }
+ }
+}
+
+
+pack_table()
+{
+ register int i;
+ register int place;
+ register int state;
+
+ base = NEW2(nvectors, short);
+ pos = NEW2(nentries, short);
+
+ maxtable = 1000;
+ table = NEW2(maxtable, short);
+ check = NEW2(maxtable, short);
+
+ lowzero = 0;
+ high = 0;
+
+ for (i = 0; i < maxtable; i++)
+ check[i] = -1;
+
+ for (i = 0; i < nentries; i++)
+ {
+ state = matching_vector(i);
+
+ if (state < 0)
+ place = pack_vector(i);
+ else
+ place = base[state];
+
+ pos[i] = place;
+ base[order[i]] = place;
+ }
+
+ for (i = 0; i < nvectors; i++)
+ {
+ if (froms[i])
+ FREE(froms[i]);
+ if (tos[i])
+ FREE(tos[i]);
+ }
+
+ FREE(froms);
+ FREE(tos);
+ FREE(pos);
+}
+
+
+/* The function matching_vector determines if the vector specified by */
+/* the input parameter matches a previously considered vector. The */
+/* test at the start of the function checks if the vector represents */
+/* a row of shifts over terminal symbols or a row of reductions, or a */
+/* column of shifts over a nonterminal symbol. Berkeley Yacc does not */
+/* check if a column of shifts over a nonterminal symbols matches a */
+/* previously considered vector. Because of the nature of LR parsing */
+/* tables, no two columns can match. Therefore, the only possible */
+/* match would be between a row and a column. Such matches are */
+/* unlikely. Therefore, to save time, no attempt is made to see if a */
+/* column matches a previously considered vector. */
+/* */
+/* Matching_vector is poorly designed. The test could easily be made */
+/* faster. Also, it depends on the vectors being in a specific */
+/* order. */
+
+int
+matching_vector(vector)
+int vector;
+{
+ register int i;
+ register int j;
+ register int k;
+ register int t;
+ register int w;
+ register int match;
+ register int prev;
+
+ i = order[vector];
+ if (i >= 2*nstates)
+ return (-1);
+
+ t = tally[i];
+ w = width[i];
+
+ for (prev = vector - 1; prev >= 0; prev--)
+ {
+ j = order[prev];
+ if (width[j] != w || tally[j] != t)
+ return (-1);
+
+ match = 1;
+ for (k = 0; match && k < t; k++)
+ {
+ if (tos[j][k] != tos[i][k] || froms[j][k] != froms[i][k])
+ match = 0;
+ }
+
+ if (match)
+ return (j);
+ }
+
+ return (-1);
+}
+
+
+
+int
+pack_vector(vector)
+int vector;
+{
+ register int i, j, k, l;
+ register int t;
+ register int loc;
+ register int ok;
+ register short *from;
+ register short *to;
+ int newmax;
+
+ i = order[vector];
+ t = tally[i];
+ assert(t);
+
+ from = froms[i];
+ to = tos[i];
+
+ j = lowzero - from[0];
+ for (k = 1; k < t; ++k)
+ if (lowzero - from[k] > j)
+ j = lowzero - from[k];
+ for (;; ++j)
+ {
+ if (j == 0)
+ continue;
+ ok = 1;
+ for (k = 0; ok && k < t; k++)
+ {
+ loc = j + from[k];
+ if (loc >= maxtable)
+ {
+ if (loc >= MAXTABLE)
+ fatal("maximum table size exceeded");
+
+ newmax = maxtable;
+ do { newmax += 200; } while (newmax <= loc);
+ table = (short *) REALLOC(table, newmax*sizeof(short));
+ if (table == 0) no_space();
+ check = (short *) REALLOC(check, newmax*sizeof(short));
+ if (check == 0) no_space();
+ for (l = maxtable; l < newmax; ++l)
+ {
+ table[l] = 0;
+ check[l] = -1;
+ }
+ maxtable = newmax;
+ }
+
+ if (check[loc] != -1)
+ ok = 0;
+ }
+ for (k = 0; ok && k < vector; k++)
+ {
+ if (pos[k] == j)
+ ok = 0;
+ }
+ if (ok)
+ {
+ for (k = 0; k < t; k++)
+ {
+ loc = j + from[k];
+ table[loc] = to[k];
+ check[loc] = from[k];
+ if (loc > high) high = loc;
+ }
+
+ while (check[lowzero] != -1)
+ ++lowzero;
+
+ return (j);
+ }
+ }
+}
+
+
+
+output_base()
+{
+ register int i, j;
+
+ printf(" protected static %s short [] yySindex = {%13d,", csharp?"":"final", base[0]);
+
+ j = 10;
+ for (i = 1; i < nstates; i++)
+ {
+ if (j >= 10)
+ {
+ ++outline;
+ putchar('\n');
+ j = 1;
+ }
+ else
+ ++j;
+
+ printf("%5d,", base[i]);
+ }
+
+ outline += 2;
+ printf("\n };\n protected static %s short [] yyRindex = {%13d,",
+ csharp ? "" : "final",
+ base[nstates]);
+
+ j = 10;
+ for (i = nstates + 1; i < 2*nstates; i++)
+ {
+ if (j >= 10)
+ {
+ ++outline;
+ putchar('\n');
+ j = 1;
+ }
+ else
+ ++j;
+
+ printf("%5d,", base[i]);
+ }
+
+ outline += 2;
+ printf("\n };\n protected static %s short [] yyGindex = {%13d,",
+ csharp ? "" : "final",
+ base[2*nstates]);
+
+ j = 10;
+ for (i = 2*nstates + 1; i < nvectors - 1; i++)
+ {
+ if (j >= 10)
+ {
+ ++outline;
+ putchar('\n');
+ j = 1;
+ }
+ else
+ ++j;
+
+ printf("%5d,", base[i]);
+ }
+
+ outline += 2;
+ printf("\n };\n");
+ FREE(base);
+}
+
+
+
+output_table()
+{
+ register int i;
+ register int j;
+
+ printf(" protected static %s short [] yyTable = {%14d,", csharp ? "" : "final", table[0]);
+
+ j = 10;
+ for (i = 1; i <= high; i++)
+ {
+ if (j >= 10)
+ {
+ ++outline;
+ putchar('\n');
+ j = 1;
+ }
+ else
+ ++j;
+
+ printf("%5d,", table[i]);
+ }
+
+ outline += 2;
+ printf("\n };\n");
+ FREE(table);
+}
+
+
+
+output_check()
+{
+ register int i;
+ register int j;
+
+ printf(" protected static %s short [] yyCheck = {%14d,",
+ csharp ? "" : "final",
+ check[0]);
+
+ j = 10;
+ for (i = 1; i <= high; i++)
+ {
+ if (j >= 10)
+ {
+ ++outline;
+ putchar('\n');
+ j = 1;
+ }
+ else
+ ++j;
+
+ printf("%5d,", check[i]);
+ }
+
+ outline += 2;
+ printf("\n };\n");
+ FREE(check);
+}
+
+
+int
+is_C_identifier(name)
+char *name;
+{
+ register char *s;
+ register int c;
+
+ s = name;
+ c = *s;
+ if (c == '"')
+ {
+ c = *++s;
+ if (!isalpha(c) && c != '_' && c != '$')
+ return (0);
+ while ((c = *++s) != '"')
+ {
+ if (!isalnum(c) && c != '_' && c != '$')
+ return (0);
+ }
+ return (1);
+ }
+
+ if (!isalpha(c) && c != '_' && c != '$')
+ return (0);
+ while (c = *++s)
+ {
+ if (!isalnum(c) && c != '_' && c != '$')
+ return (0);
+ }
+ return (1);
+}
+
+
+output_defines(prefix)
+char *prefix;
+{
+ register int c, i;
+ register char *s;
+
+ for (i = 2; i < ntokens; ++i)
+ {
+ s = symbol_name[i];
+ if (is_C_identifier(s))
+ {
+ if (prefix)
+ printf(" %s ", prefix);
+ c = *s;
+ if (c == '"')
+ {
+ while ((c = *++s) != '"')
+ {
+ putchar(c);
+ }
+ }
+ else
+ {
+ do
+ {
+ putchar(c);
+ }
+ while (c = *++s);
+ }
+ ++outline;
+ printf(" = %d%s\n", symbol_value[i], csharp ? ";" : ";");
+ }
+ }
+
+ ++outline;
+ printf(" %s yyErrorCode = %d%s\n", prefix ? prefix : "", symbol_value[1], csharp ? ";" : ";");
+}
+
+
+output_stored_text(file, name)
+FILE *file;
+char *name;
+{
+ register int c;
+ register FILE *in;
+
+ fflush(file);
+ in = fopen(name, "r");
+ if (in == NULL)
+ open_error(name);
+ if ((c = getc(in)) != EOF) {
+ if (c == '\n')
+ ++outline;
+ putchar(c);
+ while ((c = getc(in)) != EOF)
+ {
+ if (c == '\n')
+ ++outline;
+ putchar(c);
+ }
+ printf(line_format, ++outline + 1, "-");
+ }
+ fclose(in);
+}
+
+
+output_debug()
+{
+ register int i, j, k, max;
+ char **symnam, *s;
+ char * prefix = tflag ? "" : "//t";
+
+ ++outline;
+ printf(" protected static %s int yyFinal = %d;\n", csharp ? "" : "final", final_state);
+
+ ++outline;
+ printf("%s public static %s string [] yyRule = {\n", prefix, csharp ? "" : "final");
+ for (i = 2; i < nrules; ++i)
+ {
+ printf("%s \"%s :", prefix, symbol_name[rlhs[i]]);
+ for (j = rrhs[i]; ritem[j] > 0; ++j)
+ {
+ s = symbol_name[ritem[j]];
+ if (s[0] == '"')
+ {
+ printf(" \\\"");
+ while (*++s != '"')
+ {
+ if (*s == '\\')
+ {
+ if (s[1] == '\\')
+ printf("\\\\\\\\");
+ else
+ printf("\\\\%c", s[1]);
+ ++s;
+ }
+ else
+ putchar(*s);
+ }
+ printf("\\\"");
+ }
+ else if (s[0] == '\'')
+ {
+ if (s[1] == '"')
+ printf(" '\\\"'");
+ else if (s[1] == '\\')
+ {
+ if (s[2] == '\\')
+ printf(" '\\\\\\\\");
+ else
+ printf(" '\\\\%c", s[2]);
+ s += 2;
+ while (*++s != '\'')
+ putchar(*s);
+ putchar('\'');
+ }
+ else
+ printf(" '%c'", s[1]);
+ }
+ else
+ printf(" %s", s);
+ }
+ ++outline;
+ printf("\",\n");
+ }
+ ++ outline;
+ printf("%s };\n", prefix);
+
+ max = 0;
+ for (i = 2; i < ntokens; ++i)
+ if (symbol_value[i] > max)
+ max = symbol_value[i];
+
+ /* need yyName for yyExpecting() */
+
+ printf(" protected static %s string [] yyName = {", csharp ? "" : "final");
+ symnam = (char **) MALLOC((max+1)*sizeof(char *));
+ if (symnam == 0) no_space();
+
+ /* Note that it is not necessary to initialize the element */
+ /* symnam[max]. */
+ for (i = 0; i < max; ++i)
+ symnam[i] = 0;
+ for (i = ntokens - 1; i >= 2; --i)
+ symnam[symbol_value[i]] = symbol_name[i];
+ symnam[0] = "end-of-file";
+
+ j = 70; fputs(" ", stdout);
+ for (i = 0; i <= max; ++i)
+ {
+ if (s = symnam[i])
+ {
+ if (s[0] == '"')
+ {
+ k = 7;
+ while (*++s != '"')
+ {
+ ++k;
+ if (*s == '\\')
+ {
+ k += 2;
+ if (*++s == '\\')
+ ++k;
+ }
+ }
+ j += k;
+ if (j > 70)
+ {
+ ++outline;
+ printf("\n ");
+ j = k;
+ }
+ printf("\"\\\"");
+ s = symnam[i];
+ while (*++s != '"')
+ {
+ if (*s == '\\')
+ {
+ printf("\\\\");
+ if (*++s == '\\')
+ printf("\\\\");
+ else
+ putchar(*s);
+ }
+ else
+ putchar(*s);
+ }
+ printf("\\\"\",");
+ }
+ else if (s[0] == '\'')
+ {
+ if (s[1] == '"')
+ {
+ j += 7;
+ if (j > 70)
+ {
+ ++outline;
+ printf("\n ");
+ j = 7;
+ }
+ printf("\"'\\\"'\",");
+ }
+ else
+ {
+ k = 5;
+ while (*++s != '\'')
+ {
+ ++k;
+ if (*s == '\\')
+ {
+ k += 2;
+ if (*++s == '\\')
+ ++k;
+ }
+ }
+ j += k;
+ if (j > 70)
+ {
+ ++outline;
+ printf("\n ");
+ j = k;
+ }
+ printf("\"'");
+ s = symnam[i];
+ while (*++s != '\'')
+ {
+ if (*s == '\\')
+ {
+ printf("\\\\");
+ if (*++s == '\\')
+ printf("\\\\");
+ else
+ putchar(*s);
+ }
+ else
+ putchar(*s);
+ }
+ printf("'\",");
+ }
+ }
+ else
+ {
+ k = strlen(s) + 3;
+ j += k;
+ if (j > 70)
+ {
+ ++outline;
+ printf("\n ");
+ j = k;
+ }
+ putchar('"');
+ do { putchar(*s); } while (*++s);
+ printf("\",");
+ }
+ }
+ else
+ {
+ j += 5;
+ if (j > 70)
+ {
+ ++outline;
+ printf("\n ");
+ j = 5;
+ }
+ printf("null,");
+ }
+ }
+ outline += 2;
+ printf("\n };\n");
+ FREE(symnam);
+}
+
+output_trailing_text()
+{
+ register int c, last;
+ register FILE *in;
+
+ if (line == 0)
+ return;
+
+ in = input_file;
+ c = *cptr;
+ if (c == '\n')
+ {
+ ++lineno;
+ if ((c = getc(in)) == EOF)
+ return;
+ ++outline;
+ printf(line_format, lineno, input_file_name);
+ if (c == '\n')
+ ++outline;
+ putchar(c);
+ last = c;
+ }
+ else
+ {
+ ++outline;
+ printf(line_format, lineno, input_file_name);
+ do { putchar(c); } while ((c = *++cptr) != '\n');
+ ++outline;
+ putchar('\n');
+ last = '\n';
+ }
+
+ while ((c = getc(in)) != EOF)
+ {
+ if (c == '\n')
+ ++outline;
+ putchar(c);
+ last = c;
+ }
+
+ if (last != '\n')
+ {
+ ++outline;
+ putchar('\n');
+ }
+ printf(line_format, ++outline + 1, "-");
+}
+
+
+output_semantic_actions()
+{
+ register int c, last;
+
+ fclose(action_file);
+ action_file = fopen(action_file_name, "r");
+ if (action_file == NULL)
+ open_error(action_file_name);
+
+ if ((c = getc(action_file)) == EOF)
+ return;
+
+ last = c;
+ if (c == '\n')
+ ++outline;
+ putchar(c);
+ while ((c = getc(action_file)) != EOF)
+ {
+ if (c == '\n')
+ ++outline;
+ putchar(c);
+ last = c;
+ }
+
+ if (last != '\n')
+ {
+ ++outline;
+ putchar('\n');
+ }
+
+ printf(line_format, ++outline + 1, "-");
+}
+
+
+free_itemsets()
+{
+ register core *cp, *next;
+
+ FREE(state_table);
+ for (cp = first_state; cp; cp = next)
+ {
+ next = cp->next;
+ FREE(cp);
+ }
+}
+
+
+free_shifts()
+{
+ register shifts *sp, *next;
+
+ FREE(shift_table);
+ for (sp = first_shift; sp; sp = next)
+ {
+ next = sp->next;
+ FREE(sp);
+ }
+}
+
+
+
+free_reductions()
+{
+ register reductions *rp, *next;
+
+ FREE(reduction_table);
+ for (rp = first_reduction; rp; rp = next)
+ {
+ next = rp->next;
+ FREE(rp);
+ }
+}
diff --git a/mcs/jay/reader.c b/mcs/jay/reader.c
new file mode 100644
index 00000000000..f2cdd5af834
--- /dev/null
+++ b/mcs/jay/reader.c
@@ -0,0 +1,1627 @@
+/*
+ * Copyright (c) 1989 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Robert Paul Corbett.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * 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 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)reader.c 5.7 (Berkeley) 1/20/91";
+#endif /* not lint */
+
+#include "defs.h"
+
+/* The line size must be a positive integer. One hundred was chosen */
+/* because few lines in Yacc input grammars exceed 100 characters. */
+/* Note that if a line exceeds LINESIZE characters, the line buffer */
+/* will be expanded to accomodate it. */
+
+#define LINESIZE 100
+
+char *cache;
+int cinc, cache_size;
+
+int ntags, tagmax;
+char **tag_table;
+
+char saw_eof;
+char *cptr, *line;
+int linesize;
+
+bucket *goal;
+int prec;
+int gensym;
+char last_was_action;
+
+int maxitems;
+bucket **pitem;
+
+int maxrules;
+bucket **plhs;
+
+int name_pool_size;
+char *name_pool;
+
+char *line_format = "\t\t\t\t\t// line %d \"%s\"\n";
+
+
+cachec(c)
+int c;
+{
+ assert(cinc >= 0);
+ if (cinc >= cache_size)
+ {
+ cache_size += 256;
+ cache = REALLOC(cache, cache_size);
+ if (cache == 0) no_space();
+ }
+ cache[cinc] = c;
+ ++cinc;
+}
+
+
+get_line()
+{
+ register FILE *f = input_file;
+ register int c;
+ register int i;
+
+ if (saw_eof || (c = getc(f)) == EOF)
+ {
+ if (line) { FREE(line); line = 0; }
+ cptr = 0;
+ saw_eof = 1;
+ return;
+ }
+
+ if (line == 0 || linesize != (LINESIZE + 1))
+ {
+ if (line) FREE(line);
+ linesize = LINESIZE + 1;
+ line = MALLOC(linesize);
+ if (line == 0) no_space();
+ }
+
+ i = 0;
+ ++lineno;
+ for (;;)
+ {
+ line[i] = c;
+ if (c == '\n') { cptr = line; return; }
+ if (++i >= linesize)
+ {
+ linesize += LINESIZE;
+ line = REALLOC(line, linesize);
+ if (line == 0) no_space();
+ }
+ c = getc(f);
+ if (c == EOF)
+ {
+ line[i] = '\n';
+ saw_eof = 1;
+ cptr = line;
+ return;
+ }
+ }
+}
+
+
+char *
+dup_line()
+{
+ register char *p, *s, *t;
+
+ if (line == 0) return (0);
+ s = line;
+ while (*s != '\n') ++s;
+ p = MALLOC(s - line + 1);
+ if (p == 0) no_space();
+
+ s = line;
+ t = p;
+ while ((*t++ = *s++) != '\n') continue;
+ return (p);
+}
+
+
+skip_comment()
+{
+ register char *s;
+
+ int st_lineno = lineno;
+ char *st_line = dup_line();
+ char *st_cptr = st_line + (cptr - line);
+
+ s = cptr + 2;
+ for (;;)
+ {
+ if (*s == '*' && s[1] == '/')
+ {
+ cptr = s + 2;
+ FREE(st_line);
+ return;
+ }
+ if (*s == '\n')
+ {
+ get_line();
+ if (line == 0)
+ unterminated_comment(st_lineno, st_line, st_cptr);
+ s = cptr;
+ }
+ else
+ ++s;
+ }
+}
+
+
+int
+nextc()
+{
+ register char *s;
+
+ if (line == 0)
+ {
+ get_line();
+ if (line == 0)
+ return (EOF);
+ }
+
+ s = cptr;
+ for (;;)
+ {
+ switch (*s)
+ {
+ case '\n':
+ get_line();
+ if (line == 0) return (EOF);
+ s = cptr;
+ break;
+
+ case ' ':
+ case '\t':
+ case '\f':
+ case '\r':
+ case '\v':
+ case ',':
+ case ';':
+ ++s;
+ break;
+
+ case '\\':
+ cptr = s;
+ return ('%');
+
+ case '/':
+ if (s[1] == '*')
+ {
+ cptr = s;
+ skip_comment();
+ s = cptr;
+ break;
+ }
+ else if (s[1] == '/')
+ {
+ get_line();
+ if (line == 0) return (EOF);
+ s = cptr;
+ break;
+ }
+ /* fall through */
+
+ default:
+ cptr = s;
+ return (*s);
+ }
+ }
+}
+
+
+int
+keyword()
+{
+ register int c;
+ char *t_cptr = cptr;
+
+ c = *++cptr;
+ if (isalpha(c))
+ {
+ cinc = 0;
+ for (;;)
+ {
+ if (isalpha(c))
+ {
+ if (isupper(c)) c = tolower(c);
+ cachec(c);
+ }
+ else if (isdigit(c) || c == '_' || c == '.' || c == '$')
+ cachec(c);
+ else
+ break;
+ c = *++cptr;
+ }
+ cachec(NUL);
+
+ if (strcmp(cache, "token") == 0 || strcmp(cache, "term") == 0)
+ return (TOKEN);
+ if (strcmp(cache, "type") == 0)
+ return (TYPE);
+ if (strcmp(cache, "left") == 0)
+ return (LEFT);
+ if (strcmp(cache, "right") == 0)
+ return (RIGHT);
+ if (strcmp(cache, "nonassoc") == 0 || strcmp(cache, "binary") == 0)
+ return (NONASSOC);
+ if (strcmp(cache, "start") == 0)
+ return (START);
+ }
+ else
+ {
+ ++cptr;
+ if (c == '{')
+ return (TEXT);
+ if (c == '%' || c == '\\')
+ return (MARK);
+ if (c == '<')
+ return (LEFT);
+ if (c == '>')
+ return (RIGHT);
+ if (c == '0')
+ return (TOKEN);
+ if (c == '2')
+ return (NONASSOC);
+ }
+ syntax_error(lineno, line, t_cptr);
+ /*NOTREACHED*/
+}
+
+
+copy_text(f)
+FILE *f;
+{
+ register int c;
+ int quote;
+ int need_newline = 0;
+ int t_lineno = lineno;
+ char *t_line = dup_line();
+ char *t_cptr = t_line + (cptr - line - 2);
+
+ if (*cptr == '\n')
+ {
+ get_line();
+ if (line == 0)
+ unterminated_text(t_lineno, t_line, t_cptr);
+ }
+ fprintf(f, line_format, lineno, input_file_name);
+
+loop:
+ c = *cptr++;
+ switch (c)
+ {
+ case '\n':
+ next_line:
+ putc('\n', f);
+ need_newline = 0;
+ get_line();
+ if (line) goto loop;
+ unterminated_text(t_lineno, t_line, t_cptr);
+
+ case '\'':
+ case '"':
+ {
+ int s_lineno = lineno;
+ char *s_line = dup_line();
+ char *s_cptr = s_line + (cptr - line - 1);
+
+ quote = c;
+ putc(c, f);
+ for (;;)
+ {
+ c = *cptr++;
+ putc(c, f);
+ if (c == quote)
+ {
+ need_newline = 1;
+ FREE(s_line);
+ goto loop;
+ }
+ if (c == '\n')
+ unterminated_string(s_lineno, s_line, s_cptr);
+ if (c == '\\')
+ {
+ c = *cptr++;
+ putc(c, f);
+ if (c == '\n')
+ {
+ get_line();
+ if (line == 0)
+ unterminated_string(s_lineno, s_line, s_cptr);
+ }
+ }
+ }
+ }
+
+ case '/':
+ putc(c, f);
+ need_newline = 1;
+ c = *cptr;
+ if (c == '/')
+ {
+ do putc(c, f); while ((c = *++cptr) != '\n');
+ goto next_line;
+ }
+ if (c == '*')
+ {
+ int c_lineno = lineno;
+ char *c_line = dup_line();
+ char *c_cptr = c_line + (cptr - line - 1);
+
+ putc('*', f);
+ ++cptr;
+ for (;;)
+ {
+ c = *cptr++;
+ putc(c, f);
+ if (c == '*' && *cptr == '/')
+ {
+ putc('/', f);
+ ++cptr;
+ FREE(c_line);
+ goto loop;
+ }
+ if (c == '\n')
+ {
+ get_line();
+ if (line == 0)
+ unterminated_comment(c_lineno, c_line, c_cptr);
+ }
+ }
+ }
+ need_newline = 1;
+ goto loop;
+
+ case '%':
+ case '\\':
+ if (*cptr == '}')
+ {
+ if (need_newline) putc('\n', f);
+ ++cptr;
+ FREE(t_line);
+ return;
+ }
+ /* fall through */
+
+ default:
+ putc(c, f);
+ need_newline = 1;
+ goto loop;
+ }
+}
+
+int
+hexval(c)
+int c;
+{
+ if (c >= '0' && c <= '9')
+ return (c - '0');
+ if (c >= 'A' && c <= 'F')
+ return (c - 'A' + 10);
+ if (c >= 'a' && c <= 'f')
+ return (c - 'a' + 10);
+ return (-1);
+}
+
+
+bucket *
+get_literal()
+{
+ register int c, quote;
+ register int i;
+ register int n;
+ register char *s;
+ register bucket *bp;
+ int s_lineno = lineno;
+ char *s_line = dup_line();
+ char *s_cptr = s_line + (cptr - line);
+
+ quote = *cptr++;
+ cinc = 0;
+ for (;;)
+ {
+ c = *cptr++;
+ if (c == quote) break;
+ if (c == '\n') unterminated_string(s_lineno, s_line, s_cptr);
+ if (c == '\\')
+ {
+ char *c_cptr = cptr - 1;
+
+ c = *cptr++;
+ switch (c)
+ {
+ case '\n':
+ get_line();
+ if (line == 0) unterminated_string(s_lineno, s_line, s_cptr);
+ continue;
+
+ case '0': case '1': case '2': case '3':
+ case '4': case '5': case '6': case '7':
+ n = c - '0';
+ c = *cptr;
+ if (IS_OCTAL(c))
+ {
+ n = (n << 3) + (c - '0');
+ c = *++cptr;
+ if (IS_OCTAL(c))
+ {
+ n = (n << 3) + (c - '0');
+ ++cptr;
+ }
+ }
+ if (n > MAXCHAR) illegal_character(c_cptr);
+ c = n;
+ break;
+
+ case 'x':
+ c = *cptr++;
+ n = hexval(c);
+ if (n < 0 || n >= 16)
+ illegal_character(c_cptr);
+ for (;;)
+ {
+ c = *cptr;
+ i = hexval(c);
+ if (i < 0 || i >= 16) break;
+ ++cptr;
+ n = (n << 4) + i;
+ if (n > MAXCHAR) illegal_character(c_cptr);
+ }
+ c = n;
+ break;
+
+ case 'a': c = 7; break;
+ case 'b': c = '\b'; break;
+ case 'f': c = '\f'; break;
+ case 'n': c = '\n'; break;
+ case 'r': c = '\r'; break;
+ case 't': c = '\t'; break;
+ case 'v': c = '\v'; break;
+ }
+ }
+ cachec(c);
+ }
+ FREE(s_line);
+
+ n = cinc;
+ s = MALLOC(n);
+ if (s == 0) no_space();
+
+ for (i = 0; i < n; ++i)
+ s[i] = cache[i];
+
+ cinc = 0;
+ if (n == 1)
+ cachec('\'');
+ else
+ cachec('"');
+
+ for (i = 0; i < n; ++i)
+ {
+ c = ((unsigned char *)s)[i];
+ if (c == '\\' || c == cache[0])
+ {
+ cachec('\\');
+ cachec(c);
+ }
+ else if (isprint(c))
+ cachec(c);
+ else
+ {
+ cachec('\\');
+ switch (c)
+ {
+ case 7: cachec('a'); break;
+ case '\b': cachec('b'); break;
+ case '\f': cachec('f'); break;
+ case '\n': cachec('n'); break;
+ case '\r': cachec('r'); break;
+ case '\t': cachec('t'); break;
+ case '\v': cachec('v'); break;
+ default:
+ cachec(((c >> 6) & 7) + '0');
+ cachec(((c >> 3) & 7) + '0');
+ cachec((c & 7) + '0');
+ break;
+ }
+ }
+ }
+
+ if (n == 1)
+ cachec('\'');
+ else
+ cachec('"');
+
+ cachec(NUL);
+ bp = lookup(cache);
+ bp->class = TERM;
+ if (n == 1 && bp->value == UNDEFINED)
+ bp->value = *(unsigned char *)s;
+ FREE(s);
+
+ return (bp);
+}
+
+
+int
+is_reserved(name)
+char *name;
+{
+ char *s;
+
+ if (strcmp(name, ".") == 0 ||
+ strcmp(name, "$accept") == 0 ||
+ strcmp(name, "$end") == 0)
+ return (1);
+
+ if (name[0] == '$' && name[1] == '$' && isdigit(name[2]))
+ {
+ s = name + 3;
+ while (isdigit(*s)) ++s;
+ if (*s == NUL) return (1);
+ }
+
+ return (0);
+}
+
+
+bucket *
+get_name()
+{
+ register int c;
+
+ cinc = 0;
+ for (c = *cptr; IS_IDENT(c); c = *++cptr)
+ cachec(c);
+ cachec(NUL);
+
+ if (is_reserved(cache)) used_reserved(cache);
+
+ return (lookup(cache));
+}
+
+
+int
+get_number()
+{
+ register int c;
+ register int n;
+
+ n = 0;
+ for (c = *cptr; isdigit(c); c = *++cptr)
+ n = 10*n + (c - '0');
+
+ return (n);
+}
+
+
+char *
+get_tag(int emptyOk)
+{
+ register int c;
+ register int i;
+ register char *s;
+ int t_lineno = lineno;
+ char *t_line = dup_line();
+ char *t_cptr = t_line + (cptr - line);
+
+ ++cptr;
+ c = nextc();
+ if (c == EOF) unexpected_EOF();
+ if (emptyOk && c == '>') {
+ ++cptr; return 0; // 0 indicates empty tag if emptyOk
+ }
+ if (!isalpha(c) && c != '_' && c != '$')
+ illegal_tag(t_lineno, t_line, t_cptr);
+
+ cinc = 0;
+ do { cachec(c); c = *++cptr; } while (IS_IDENT(c));
+ cachec(NUL);
+
+ c = nextc();
+ if (c == EOF) unexpected_EOF();
+ if (c != '>')
+ illegal_tag(t_lineno, t_line, t_cptr);
+ ++cptr;
+
+ for (i = 0; i < ntags; ++i)
+ {
+ if (strcmp(cache, tag_table[i]) == 0)
+ return (tag_table[i]);
+ }
+
+ if (ntags >= tagmax)
+ {
+ tagmax += 16;
+ tag_table = (char **)
+ (tag_table ? REALLOC(tag_table, tagmax*sizeof(char *))
+ : MALLOC(tagmax*sizeof(char *)));
+ if (tag_table == 0) no_space();
+ }
+
+ s = MALLOC(cinc);
+ if (s == 0) no_space();
+ strcpy(s, cache);
+ tag_table[ntags] = s;
+ ++ntags;
+ FREE(t_line);
+ return (s);
+}
+
+
+declare_tokens(assoc)
+int assoc;
+{
+ register int c;
+ register bucket *bp;
+ int value;
+ char *tag = 0;
+
+ if (assoc != TOKEN) ++prec;
+
+ c = nextc();
+ if (c == EOF) unexpected_EOF();
+ if (c == '<')
+ {
+ tag = get_tag(0);
+ c = nextc();
+ if (c == EOF) unexpected_EOF();
+ }
+
+ for (;;)
+ {
+ if (isalpha(c) || c == '_' || c == '.' || c == '$')
+ bp = get_name();
+ else if (c == '\'' || c == '"')
+ bp = get_literal();
+ else
+ return;
+
+ if (bp == goal) tokenized_start(bp->name);
+ bp->class = TERM;
+
+ if (tag)
+ {
+ if (bp->tag && tag != bp->tag)
+ retyped_warning(bp->name);
+ bp->tag = tag;
+ }
+
+ if (assoc != TOKEN)
+ {
+ if (bp->prec && prec != bp->prec)
+ reprec_warning(bp->name);
+ bp->assoc = assoc;
+ bp->prec = prec;
+ }
+
+ c = nextc();
+ if (c == EOF) unexpected_EOF();
+ value = UNDEFINED;
+ if (isdigit(c))
+ {
+ value = get_number();
+ if (bp->value != UNDEFINED && value != bp->value)
+ revalued_warning(bp->name);
+ bp->value = value;
+ c = nextc();
+ if (c == EOF) unexpected_EOF();
+ }
+ }
+}
+
+
+declare_types()
+{
+ register int c;
+ register bucket *bp;
+ char *tag;
+
+ c = nextc();
+ if (c == EOF) unexpected_EOF();
+ if (c != '<') syntax_error(lineno, line, cptr);
+ tag = get_tag(0);
+
+ for (;;)
+ {
+ c = nextc();
+ if (isalpha(c) || c == '_' || c == '.' || c == '$')
+ bp = get_name();
+ else if (c == '\'' || c == '"')
+ bp = get_literal();
+ else
+ return;
+
+ if (bp->tag && tag != bp->tag)
+ retyped_warning(bp->name);
+ bp->tag = tag;
+ }
+}
+
+
+declare_start()
+{
+ register int c;
+ register bucket *bp;
+
+ c = nextc();
+ if (c == EOF) unexpected_EOF();
+ if (!isalpha(c) && c != '_' && c != '.' && c != '$')
+ syntax_error(lineno, line, cptr);
+ bp = get_name();
+ if (bp->class == TERM)
+ terminal_start(bp->name);
+ if (goal && goal != bp)
+ restarted_warning();
+ goal = bp;
+}
+
+
+read_declarations()
+{
+ register int c, k;
+
+ cache_size = 256;
+ cache = MALLOC(cache_size);
+ if (cache == 0) no_space();
+
+ for (;;)
+ {
+ c = nextc();
+ if (c == EOF) unexpected_EOF();
+ if (c != '%') syntax_error(lineno, line, cptr);
+ switch (k = keyword())
+ {
+ case MARK:
+ return;
+
+ case TEXT:
+ copy_text(prolog_file);
+ break;
+
+ case TOKEN:
+ case LEFT:
+ case RIGHT:
+ case NONASSOC:
+ declare_tokens(k);
+ break;
+
+ case TYPE:
+ declare_types();
+ break;
+
+ case START:
+ declare_start();
+ break;
+ }
+ }
+}
+
+
+initialize_grammar()
+{
+ nitems = 4;
+ maxitems = 300;
+ pitem = (bucket **) MALLOC(maxitems*sizeof(bucket *));
+ if (pitem == 0) no_space();
+ pitem[0] = 0;
+ pitem[1] = 0;
+ pitem[2] = 0;
+ pitem[3] = 0;
+
+ nrules = 3;
+ maxrules = 100;
+ plhs = (bucket **) MALLOC(maxrules*sizeof(bucket *));
+ if (plhs == 0) no_space();
+ plhs[0] = 0;
+ plhs[1] = 0;
+ plhs[2] = 0;
+ rprec = (short *) MALLOC(maxrules*sizeof(short));
+ if (rprec == 0) no_space();
+ rprec[0] = 0;
+ rprec[1] = 0;
+ rprec[2] = 0;
+ rassoc = (char *) MALLOC(maxrules*sizeof(char));
+ if (rassoc == 0) no_space();
+ rassoc[0] = TOKEN;
+ rassoc[1] = TOKEN;
+ rassoc[2] = TOKEN;
+}
+
+
+expand_items()
+{
+ maxitems += 300;
+ pitem = (bucket **) REALLOC(pitem, maxitems*sizeof(bucket *));
+ if (pitem == 0) no_space();
+}
+
+
+expand_rules()
+{
+ maxrules += 100;
+ plhs = (bucket **) REALLOC(plhs, maxrules*sizeof(bucket *));
+ if (plhs == 0) no_space();
+ rprec = (short *) REALLOC(rprec, maxrules*sizeof(short));
+ if (rprec == 0) no_space();
+ rassoc = (char *) REALLOC(rassoc, maxrules*sizeof(char));
+ if (rassoc == 0) no_space();
+}
+
+
+advance_to_start()
+{
+ register int c;
+ register bucket *bp;
+ char *s_cptr;
+ int s_lineno;
+
+ for (;;)
+ {
+ c = nextc();
+ if (c != '%') break;
+ s_cptr = cptr;
+ switch (keyword())
+ {
+ case MARK:
+ no_grammar();
+
+ case TEXT:
+ copy_text(local_file);
+ break;
+
+ case START:
+ declare_start();
+ break;
+
+ default:
+ syntax_error(lineno, line, s_cptr);
+ }
+ }
+
+ c = nextc();
+ if (!isalpha(c) && c != '_' && c != '.' && c != '_')
+ syntax_error(lineno, line, cptr);
+ bp = get_name();
+ if (goal == 0)
+ {
+ if (bp->class == TERM)
+ terminal_start(bp->name);
+ goal = bp;
+ }
+
+ s_lineno = lineno;
+ c = nextc();
+ if (c == EOF) unexpected_EOF();
+ if (c != ':') syntax_error(lineno, line, cptr);
+ start_rule(bp, s_lineno);
+ ++cptr;
+}
+
+
+start_rule(bp, s_lineno)
+register bucket *bp;
+int s_lineno;
+{
+ if (bp->class == TERM)
+ terminal_lhs(s_lineno);
+ bp->class = NONTERM;
+ if (nrules >= maxrules)
+ expand_rules();
+ plhs[nrules] = bp;
+ rprec[nrules] = UNDEFINED;
+ rassoc[nrules] = TOKEN;
+}
+
+
+end_rule()
+{
+ register int i;
+
+ if (!last_was_action && plhs[nrules]->tag)
+ {
+ for (i = nitems - 1; pitem[i]; --i) continue;
+ if (pitem[i+1] == 0 || pitem[i+1]->tag != plhs[nrules]->tag)
+ default_action_warning(); /** if classes don't match exactly **/
+ } /** bug: could be superclass... **/
+
+ last_was_action = 0;
+ if (nitems >= maxitems) expand_items();
+ pitem[nitems] = 0;
+ ++nitems;
+ ++nrules;
+}
+
+
+insert_empty_rule()
+{
+ register bucket *bp, **bpp;
+
+ assert(cache);
+ sprintf(cache, "$$%d", ++gensym);
+ bp = make_bucket(cache);
+ last_symbol->next = bp;
+ last_symbol = bp;
+ bp->tag = plhs[nrules]->tag;
+ bp->class = NONTERM;
+
+ if ((nitems += 2) > maxitems)
+ expand_items();
+ bpp = pitem + nitems - 1;
+ *bpp-- = bp;
+ while (bpp[0] = bpp[-1]) --bpp;
+
+ if (++nrules >= maxrules)
+ expand_rules();
+ plhs[nrules] = plhs[nrules-1];
+ plhs[nrules-1] = bp;
+ rprec[nrules] = rprec[nrules-1];
+ rprec[nrules-1] = 0;
+ rassoc[nrules] = rassoc[nrules-1];
+ rassoc[nrules-1] = TOKEN;
+}
+
+
+add_symbol()
+{
+ register int c;
+ register bucket *bp;
+ int s_lineno = lineno;
+
+ c = *cptr;
+ if (c == '\'' || c == '"')
+ bp = get_literal();
+ else
+ bp = get_name();
+
+ c = nextc();
+ if (c == ':')
+ {
+ end_rule();
+ start_rule(bp, s_lineno);
+ ++cptr;
+ return;
+ }
+
+ if (last_was_action)
+ insert_empty_rule();
+ last_was_action = 0;
+
+ if (++nitems > maxitems)
+ expand_items();
+ pitem[nitems-1] = bp;
+}
+
+
+copy_action()
+{
+ register int c;
+ register int i, n;
+ int depth;
+ int quote;
+ char *tag;
+ register FILE *f = action_file;
+ int a_lineno = lineno;
+ char *a_line = dup_line();
+ char *a_cptr = a_line + (cptr - line);
+
+ if (last_was_action)
+ insert_empty_rule();
+ last_was_action = 1;
+
+ fprintf(f, "case %d:\n", nrules - 2);
+ fprintf(f, line_format, lineno, input_file_name);
+ putc(' ', f); putc(' ', f);
+ if (*cptr == '=') ++cptr;
+
+ n = 0;
+ for (i = nitems - 1; pitem[i]; --i) ++n;
+
+ depth = 0;
+loop:
+ c = *cptr;
+ if (c == '$')
+ {
+ if (cptr[1] == '<')
+ {
+ int d_lineno = lineno;
+ char *d_line = dup_line();
+ char *d_cptr = d_line + (cptr - line);
+
+ ++cptr;
+ tag = get_tag(1);
+ c = *cptr;
+ if (c == '$')
+ { if (tag && strcmp(tag, "Object"))
+ fprintf(f, "((%s)yyVal)", tag);
+ else fprintf(f, "yyVal");
+ ++cptr;
+ FREE(d_line);
+ goto loop;
+ }
+ else if (isdigit(c))
+ {
+ i = get_number();
+ if (i > n) dollar_warning(d_lineno, i);
+ if (tag && strcmp(tag, "Object"))
+ fprintf(f, "((%s)yyVals[%d+yyTop])", tag, i - n);
+ else fprintf(f, "yyVals[%d+yyTop]", i - n);
+ FREE(d_line);
+ goto loop;
+ }
+ else if (c == '-' && isdigit(cptr[1]))
+ {
+ ++cptr;
+ i = -get_number() - n;
+ if (tag && strcmp(tag, "Object"))
+ fprintf(f, "((%s)yyVals[%d+yyTop])", tag, i);
+ else fprintf(f, "yyVals[%d+yyTop]", tag, i);
+ FREE(d_line);
+ goto loop;
+ }
+ else
+ dollar_error(d_lineno, d_line, d_cptr);
+ }
+ else if (cptr[1] == '$')
+ {
+ if (ntags && plhs[nrules]->tag == 0)
+ untyped_lhs();
+ fprintf(f, "yyVal");
+ cptr += 2;
+ goto loop;
+ }
+ else if (isdigit(cptr[1]))
+ {
+ ++cptr;
+ i = get_number();
+ if (ntags)
+ {
+ if (i <= 0 || i > n)
+ unknown_rhs(i);
+ tag = pitem[nitems + i - n - 1]->tag;
+ if (tag == 0)
+ untyped_rhs(i, pitem[nitems + i - n - 1]->name),
+ fprintf(f, "yyVals[%d+yyTop]", i - n);
+ else if (strcmp(tag, "Object"))
+ fprintf(f, "((%s)yyVals[%d+yyTop])", tag, i - n);
+ else
+ fprintf(f, "yyVals[%d+yyTop]", i - n);
+ }
+ else
+ {
+ if (i > n)
+ dollar_warning(lineno, i);
+ fprintf(f, "yyVals[%d+yyTop]", i - n);
+ }
+ goto loop;
+ }
+ else if (cptr[1] == '-')
+ {
+ cptr += 2;
+ i = get_number();
+ if (ntags)
+ unknown_rhs(-i);
+ fprintf(f, "yyVals[%d+yyTop]", -i - n);
+ goto loop;
+ }
+ }
+ if (isalpha(c) || c == '_' || c == '$')
+ {
+ do
+ {
+ putc(c, f);
+ c = *++cptr;
+ } while (isalnum(c) || c == '_' || c == '$');
+ goto loop;
+ }
+ putc(c, f);
+ ++cptr;
+ switch (c)
+ {
+ case '\n':
+ next_line:
+ get_line();
+ if (line) goto loop;
+ unterminated_action(a_lineno, a_line, a_cptr);
+
+ case ';':
+ if (depth > 0) goto loop;
+ fprintf(f, "\nbreak;\n");
+ return;
+
+ case '{':
+ ++depth;
+ goto loop;
+
+ case '}':
+ if (--depth > 0) goto loop;
+ fprintf(f, "\n break;\n");
+ return;
+
+ case '\'':
+ case '"':
+ {
+ int s_lineno = lineno;
+ char *s_line = dup_line();
+ char *s_cptr = s_line + (cptr - line - 1);
+
+ quote = c;
+ for (;;)
+ {
+ c = *cptr++;
+ putc(c, f);
+ if (c == quote)
+ {
+ FREE(s_line);
+ goto loop;
+ }
+ if (c == '\n')
+ unterminated_string(s_lineno, s_line, s_cptr);
+ if (c == '\\')
+ {
+ c = *cptr++;
+ putc(c, f);
+ if (c == '\n')
+ {
+ get_line();
+ if (line == 0)
+ unterminated_string(s_lineno, s_line, s_cptr);
+ }
+ }
+ }
+ }
+
+ case '/':
+ c = *cptr;
+ if (c == '/')
+ {
+ putc('*', f);
+ while ((c = *++cptr) != '\n')
+ {
+ if (c == '*' && cptr[1] == '/')
+ fprintf(f, "* ");
+ else
+ putc(c, f);
+ }
+ fprintf(f, "*/\n");
+ goto next_line;
+ }
+ if (c == '*')
+ {
+ int c_lineno = lineno;
+ char *c_line = dup_line();
+ char *c_cptr = c_line + (cptr - line - 1);
+
+ putc('*', f);
+ ++cptr;
+ for (;;)
+ {
+ c = *cptr++;
+ putc(c, f);
+ if (c == '*' && *cptr == '/')
+ {
+ putc('/', f);
+ ++cptr;
+ FREE(c_line);
+ goto loop;
+ }
+ if (c == '\n')
+ {
+ get_line();
+ if (line == 0)
+ unterminated_comment(c_lineno, c_line, c_cptr);
+ }
+ }
+ }
+ goto loop;
+
+ default:
+ goto loop;
+ }
+}
+
+
+int
+mark_symbol()
+{
+ register int c;
+ register bucket *bp;
+
+ c = cptr[1];
+ if (c == '%' || c == '\\')
+ {
+ cptr += 2;
+ return (1);
+ }
+
+ if (c == '=')
+ cptr += 2;
+ else if ((c == 'p' || c == 'P') &&
+ ((c = cptr[2]) == 'r' || c == 'R') &&
+ ((c = cptr[3]) == 'e' || c == 'E') &&
+ ((c = cptr[4]) == 'c' || c == 'C') &&
+ ((c = cptr[5], !IS_IDENT(c))))
+ cptr += 5;
+ else
+ syntax_error(lineno, line, cptr);
+
+ c = nextc();
+ if (isalpha(c) || c == '_' || c == '.' || c == '$')
+ bp = get_name();
+ else if (c == '\'' || c == '"')
+ bp = get_literal();
+ else
+ {
+ syntax_error(lineno, line, cptr);
+ /*NOTREACHED*/
+ }
+
+ if (rprec[nrules] != UNDEFINED && bp->prec != rprec[nrules])
+ prec_redeclared();
+
+ rprec[nrules] = bp->prec;
+ rassoc[nrules] = bp->assoc;
+ return (0);
+}
+
+
+read_grammar()
+{
+ register int c;
+
+ initialize_grammar();
+ advance_to_start();
+
+ for (;;)
+ {
+ c = nextc();
+ if (c == EOF) break;
+ if (isalpha(c) || c == '_' || c == '.' || c == '$' || c == '\'' ||
+ c == '"')
+ add_symbol();
+ else if (c == '{' || c == '=')
+ copy_action();
+ else if (c == '|')
+ {
+ end_rule();
+ start_rule(plhs[nrules-1], 0);
+ ++cptr;
+ }
+ else if (c == '%')
+ {
+ if (mark_symbol()) break;
+ }
+ else
+ syntax_error(lineno, line, cptr);
+ }
+ end_rule();
+}
+
+
+free_tags()
+{
+ register int i;
+
+ if (tag_table == 0) return;
+
+ for (i = 0; i < ntags; ++i)
+ {
+ assert(tag_table[i]);
+ FREE(tag_table[i]);
+ }
+ FREE(tag_table);
+}
+
+
+pack_names()
+{
+ register bucket *bp;
+ register char *p, *s, *t;
+
+ name_pool_size = 13; /* 13 == sizeof("$end") + sizeof("$accept") */
+ for (bp = first_symbol; bp; bp = bp->next)
+ name_pool_size += strlen(bp->name) + 1;
+ name_pool = MALLOC(name_pool_size);
+ if (name_pool == 0) no_space();
+
+ strcpy(name_pool, "$accept");
+ strcpy(name_pool+8, "$end");
+ t = name_pool + 13;
+ for (bp = first_symbol; bp; bp = bp->next)
+ {
+ p = t;
+ s = bp->name;
+ while (*t++ = *s++) continue;
+ FREE(bp->name);
+ bp->name = p;
+ }
+}
+
+
+check_symbols()
+{
+ register bucket *bp;
+
+ if (goal->class == UNKNOWN)
+ undefined_goal(goal->name);
+
+ for (bp = first_symbol; bp; bp = bp->next)
+ {
+ if (bp->class == UNKNOWN)
+ {
+ undefined_symbol_warning(bp->name);
+ bp->class = TERM;
+ }
+ }
+}
+
+
+pack_symbols()
+{
+ register bucket *bp;
+ register bucket **v;
+ register int i, j, k, n;
+
+ nsyms = 2;
+ ntokens = 1;
+ for (bp = first_symbol; bp; bp = bp->next)
+ {
+ ++nsyms;
+ if (bp->class == TERM) ++ntokens;
+ }
+ start_symbol = ntokens;
+ nvars = nsyms - ntokens;
+
+ symbol_name = (char **) MALLOC(nsyms*sizeof(char *));
+ if (symbol_name == 0) no_space();
+ symbol_value = (short *) MALLOC(nsyms*sizeof(short));
+ if (symbol_value == 0) no_space();
+ symbol_prec = (short *) MALLOC(nsyms*sizeof(short));
+ if (symbol_prec == 0) no_space();
+ symbol_assoc = MALLOC(nsyms);
+ if (symbol_assoc == 0) no_space();
+
+ v = (bucket **) MALLOC(nsyms*sizeof(bucket *));
+ if (v == 0) no_space();
+
+ v[0] = 0;
+ v[start_symbol] = 0;
+
+ i = 1;
+ j = start_symbol + 1;
+ for (bp = first_symbol; bp; bp = bp->next)
+ {
+ if (bp->class == TERM)
+ v[i++] = bp;
+ else
+ v[j++] = bp;
+ }
+ assert(i == ntokens && j == nsyms);
+
+ for (i = 1; i < ntokens; ++i)
+ v[i]->index = i;
+
+ goal->index = start_symbol + 1;
+ k = start_symbol + 2;
+ while (++i < nsyms)
+ if (v[i] != goal)
+ {
+ v[i]->index = k;
+ ++k;
+ }
+
+ goal->value = 0;
+ k = 1;
+ for (i = start_symbol + 1; i < nsyms; ++i)
+ {
+ if (v[i] != goal)
+ {
+ v[i]->value = k;
+ ++k;
+ }
+ }
+
+ k = 0;
+ for (i = 1; i < ntokens; ++i)
+ {
+ n = v[i]->value;
+ if (n > 256)
+ {
+ for (j = k++; j > 0 && symbol_value[j-1] > n; --j)
+ symbol_value[j] = symbol_value[j-1];
+ symbol_value[j] = n;
+ }
+ }
+
+ if (v[1]->value == UNDEFINED)
+ v[1]->value = 256;
+
+ j = 0;
+ n = 257;
+ for (i = 2; i < ntokens; ++i)
+ {
+ if (v[i]->value == UNDEFINED)
+ {
+ while (j < k && n == symbol_value[j])
+ {
+ while (++j < k && n == symbol_value[j]) continue;
+ ++n;
+ }
+ v[i]->value = n;
+ ++n;
+ }
+ }
+
+ symbol_name[0] = name_pool + 8;
+ symbol_value[0] = 0;
+ symbol_prec[0] = 0;
+ symbol_assoc[0] = TOKEN;
+ for (i = 1; i < ntokens; ++i)
+ {
+ symbol_name[i] = v[i]->name;
+ symbol_value[i] = v[i]->value;
+ symbol_prec[i] = v[i]->prec;
+ symbol_assoc[i] = v[i]->assoc;
+ }
+ symbol_name[start_symbol] = name_pool;
+ symbol_value[start_symbol] = -1;
+ symbol_prec[start_symbol] = 0;
+ symbol_assoc[start_symbol] = TOKEN;
+ for (++i; i < nsyms; ++i)
+ {
+ k = v[i]->index;
+ symbol_name[k] = v[i]->name;
+ symbol_value[k] = v[i]->value;
+ symbol_prec[k] = v[i]->prec;
+ symbol_assoc[k] = v[i]->assoc;
+ }
+
+ FREE(v);
+}
+
+
+pack_grammar()
+{
+ register int i, j;
+ int assoc, prec;
+
+ ritem = (short *) MALLOC(nitems*sizeof(short));
+ if (ritem == 0) no_space();
+ rlhs = (short *) MALLOC(nrules*sizeof(short));
+ if (rlhs == 0) no_space();
+ rrhs = (short *) MALLOC((nrules+1)*sizeof(short));
+ if (rrhs == 0) no_space();
+ rprec = (short *) REALLOC(rprec, nrules*sizeof(short));
+ if (rprec == 0) no_space();
+ rassoc = REALLOC(rassoc, nrules);
+ if (rassoc == 0) no_space();
+
+ ritem[0] = -1;
+ ritem[1] = goal->index;
+ ritem[2] = 0;
+ ritem[3] = -2;
+ rlhs[0] = 0;
+ rlhs[1] = 0;
+ rlhs[2] = start_symbol;
+ rrhs[0] = 0;
+ rrhs[1] = 0;
+ rrhs[2] = 1;
+
+ j = 4;
+ for (i = 3; i < nrules; ++i)
+ {
+ rlhs[i] = plhs[i]->index;
+ rrhs[i] = j;
+ assoc = TOKEN;
+ prec = 0;
+ while (pitem[j])
+ {
+ ritem[j] = pitem[j]->index;
+ if (pitem[j]->class == TERM)
+ {
+ prec = pitem[j]->prec;
+ assoc = pitem[j]->assoc;
+ }
+ ++j;
+ }
+ ritem[j] = -i;
+ ++j;
+ if (rprec[i] == UNDEFINED)
+ {
+ rprec[i] = prec;
+ rassoc[i] = assoc;
+ }
+ }
+ rrhs[i] = j;
+
+ FREE(plhs);
+ FREE(pitem);
+}
+
+
+print_grammar()
+{
+ register int i, j, k;
+ int spacing;
+ register FILE *f = verbose_file;
+
+ if (!vflag) return;
+
+ k = 1;
+ for (i = 2; i < nrules; ++i)
+ {
+ if (rlhs[i] != rlhs[i-1])
+ {
+ if (i != 2) fprintf(f, "\n");
+ fprintf(f, "%4d %s :", i - 2, symbol_name[rlhs[i]]);
+ spacing = strlen(symbol_name[rlhs[i]]) + 1;
+ }
+ else
+ {
+ fprintf(f, "%4d ", i - 2);
+ j = spacing;
+ while (--j >= 0) putc(' ', f);
+ putc('|', f);
+ }
+
+ while (ritem[k] >= 0)
+ {
+ fprintf(f, " %s", symbol_name[ritem[k]]);
+ ++k;
+ }
+ ++k;
+ putc('\n', f);
+ }
+}
+
+
+reader()
+{
+ create_symbol_table();
+ read_declarations();
+ read_grammar();
+ free_symbol_table();
+ free_tags();
+ pack_names();
+ check_symbols();
+ pack_symbols();
+ pack_grammar();
+ free_symbols();
+ print_grammar();
+}
diff --git a/mcs/jay/skeleton b/mcs/jay/skeleton
new file mode 100644
index 00000000000..07135c082f2
--- /dev/null
+++ b/mcs/jay/skeleton
@@ -0,0 +1,268 @@
+# jay skeleton
+
+# character in column 1 determines outcome...
+# # is a comment
+# . is copied
+# t is copied as //t if -t is set
+# other lines are interpreted to call jay procedures
+
+.// created by jay 0.7 (c) 1998 Axel.Schreiner@informatik.uni-osnabrueck.de
+.
+ prolog ## %{ ... %} prior to the first %%
+
+.// %token constants
+.
+ tokens public static final int
+.
+. /** thrown for irrecoverable syntax errors and stack overflow.
+. */
+. public static class yyException extends java.lang.Exception {
+. public yyException (String message) {
+. super(message);
+. }
+. }
+.
+. /** must be implemented by a scanner object to supply input to the parser.
+. */
+. public interface yyInput {
+. /** move on to next token.
+. @return false if positioned beyond tokens.
+. @throws IOException on input error.
+. */
+. boolean advance () throws java.io.IOException;
+. /** classifies current token.
+. Should not be called if advance() returned false.
+. @return current %token or single character.
+. */
+. int token ();
+. /** associated with current token.
+. Should not be called if advance() returned false.
+. @return value for token().
+. */
+. Object value ();
+. }
+.
+. /** simplified error message.
+. @see <a href="#yyerror(java.lang.String, java.lang.String[])">yyerror</a>
+. */
+. public void yyerror (String message) {
+. yyerror(message, null);
+. }
+.
+. /** (syntax) error message.
+. Can be overwritten to control message format.
+. @param message text to be displayed.
+. @param expected vector of acceptable tokens, if available.
+. */
+. public void yyerror (String message, String[] expected) {
+. if (expected != null && expected.length > 0) {
+. System.err.print(message+", expecting");
+. for (int n = 0; n < expected.length; ++ n)
+. System.err.print(" "+expected[n]);
+. System.err.println();
+. } else
+. System.err.println(message);
+. }
+.
+. /** debugging support, requires the package jay.yydebug.
+. Set to null to suppress debugging messages.
+. */
+t protected jay.yydebug.yyDebug yydebug;
+.
+ debug ## tables for debugging support
+.
+. /** index-checked interface to yyName[].
+. @param token single character or %token value.
+. @return token name or [illegal] or [unknown].
+. */
+t public static final String yyname (int token) {
+t if (token < 0 || token > yyName.length) return "[illegal]";
+t String name;
+t if ((name = yyName[token]) != null) return name;
+t return "[unknown]";
+t }
+.
+. /** computes list of expected tokens on error by tracing the tables.
+. @param state for which to compute the list.
+. @return list of token names.
+. */
+. protected String[] yyExpecting (int state) {
+. int token, n, len = 0;
+. boolean[] ok = new boolean[yyName.length];
+.
+. if ((n = yySindex[state]) != 0)
+. for (token = n < 0 ? -n : 0;
+. token < yyName.length && n+token < yyTable.length; ++ token)
+. if (yyCheck[n+token] == token && !ok[token] && yyName[token] != null) {
+. ++ len;
+. ok[token] = true;
+. }
+. if ((n = yyRindex[state]) != 0)
+. for (token = n < 0 ? -n : 0;
+. token < yyName.length && n+token < yyTable.length; ++ token)
+. if (yyCheck[n+token] == token && !ok[token] && yyName[token] != null) {
+. ++ len;
+. ok[token] = true;
+. }
+.
+. String result[] = new String[len];
+. for (n = token = 0; n < len; ++ token)
+. if (ok[token]) result[n++] = yyName[token];
+. return result;
+. }
+.
+. /** the generated parser, with debugging messages.
+. Maintains a state and a value stack, currently with fixed maximum size.
+. @param yyLex scanner.
+. @param yydebug debug message writer implementing yyDebug, or null.
+. @return result of the last reduction, if any.
+. @throws yyException on irrecoverable parse error.
+. */
+. public Object yyparse (yyInput yyLex, Object yydebug)
+. throws java.io.IOException, yyException {
+t this.yydebug = (jay.yydebug.yyDebug)yydebug;
+. return yyparse(yyLex);
+. }
+.
+. /** initial size and increment of the state/value stack [default 256].
+. This is not final so that it can be overwritten outside of invocations
+. of yyparse().
+. */
+. protected int yyMax;
+.
+. /** executed at the beginning of a reduce action.
+. Used as $$ = yyDefault($1), prior to the user-specified action, if any.
+. Can be overwritten to provide deep copy, etc.
+. @param first value for $1, or null.
+. @return first.
+. */
+. protected Object yyDefault (Object first) {
+. return first;
+. }
+.
+. /** the generated parser.
+. Maintains a state and a value stack, currently with fixed maximum size.
+. @param yyLex scanner.
+. @return result of the last reduction, if any.
+. @throws yyException on irrecoverable parse error.
+. */
+. public Object yyparse (yyInput yyLex)
+. throws java.io.IOException, yyException {
+. if (yyMax <= 0) yyMax = 256; // initial size
+. int yyState = 0, yyStates[] = new int[yyMax]; // state stack
+. Object yyVal = null, yyVals[] = new Object[yyMax]; // value stack
+. int yyToken = -1; // current input
+. int yyErrorFlag = 0; // #tks to shift
+.
+ local ## %{ ... %} after the first %%
+
+. yyLoop: for (int yyTop = 0;; ++ yyTop) {
+. if (yyTop >= yyStates.length) { // dynamically increase
+. int[] i = new int[yyStates.length+yyMax];
+. System.arraycopy(yyStates, 0, i, 0, yyStates.length);
+. yyStates = i;
+. Object[] o = new Object[yyVals.length+yyMax];
+. System.arraycopy(yyVals, 0, o, 0, yyVals.length);
+. yyVals = o;
+. }
+. yyStates[yyTop] = yyState;
+. yyVals[yyTop] = yyVal;
+t if (yydebug != null) yydebug.push(yyState, yyVal);
+.
+. yyDiscarded: for (;;) { // discarding a token does not change stack
+. int yyN;
+. if ((yyN = yyDefRed[yyState]) == 0) { // else [default] reduce (yyN)
+. if (yyToken < 0) {
+. yyToken = yyLex.advance() ? yyLex.token() : 0;
+t if (yydebug != null)
+t yydebug.lex(yyState, yyToken, yyname(yyToken), yyLex.value());
+. }
+. if ((yyN = yySindex[yyState]) != 0 && (yyN += yyToken) >= 0
+. && yyN < yyTable.length && yyCheck[yyN] == yyToken) {
+t if (yydebug != null)
+t yydebug.shift(yyState, yyTable[yyN], yyErrorFlag-1);
+. yyState = yyTable[yyN]; // shift to yyN
+. yyVal = yyLex.value();
+. yyToken = -1;
+. if (yyErrorFlag > 0) -- yyErrorFlag;
+. continue yyLoop;
+. }
+. if ((yyN = yyRindex[yyState]) != 0 && (yyN += yyToken) >= 0
+. && yyN < yyTable.length && yyCheck[yyN] == yyToken)
+. yyN = yyTable[yyN]; // reduce (yyN)
+. else
+. switch (yyErrorFlag) {
+.
+. case 0:
+. yyerror("syntax error", yyExpecting(yyState));
+t if (yydebug != null) yydebug.error("syntax error");
+.
+. case 1: case 2:
+. yyErrorFlag = 3;
+. do {
+. if ((yyN = yySindex[yyStates[yyTop]]) != 0
+. && (yyN += yyErrorCode) >= 0 && yyN < yyTable.length
+. && yyCheck[yyN] == yyErrorCode) {
+t if (yydebug != null)
+t yydebug.shift(yyStates[yyTop], yyTable[yyN], 3);
+. yyState = yyTable[yyN];
+. yyVal = yyLex.value();
+. continue yyLoop;
+. }
+t if (yydebug != null) yydebug.pop(yyStates[yyTop]);
+. } while (-- yyTop >= 0);
+t if (yydebug != null) yydebug.reject();
+. throw new yyException("irrecoverable syntax error");
+.
+. case 3:
+. if (yyToken == 0) {
+t if (yydebug != null) yydebug.reject();
+. throw new yyException("irrecoverable syntax error at end-of-file");
+. }
+t if (yydebug != null)
+t yydebug.discard(yyState, yyToken, yyname(yyToken),
+t yyLex.value());
+. yyToken = -1;
+. continue yyDiscarded; // leave stack alone
+. }
+. }
+. int yyV = yyTop + 1-yyLen[yyN];
+t if (yydebug != null)
+t yydebug.reduce(yyState, yyStates[yyV-1], yyN, yyRule[yyN], yyLen[yyN]);
+. yyVal = yyDefault(yyV > yyTop ? null : yyVals[yyV]);
+. switch (yyN) {
+
+ actions ## code from the actions within the grammar
+
+. }
+. yyTop -= yyLen[yyN];
+. yyState = yyStates[yyTop];
+. int yyM = yyLhs[yyN];
+. if (yyState == 0 && yyM == 0) {
+t if (yydebug != null) yydebug.shift(0, yyFinal);
+. yyState = yyFinal;
+. if (yyToken < 0) {
+. yyToken = yyLex.advance() ? yyLex.token() : 0;
+t if (yydebug != null)
+t yydebug.lex(yyState, yyToken,yyname(yyToken), yyLex.value());
+. }
+. if (yyToken == 0) {
+t if (yydebug != null) yydebug.accept(yyVal);
+. return yyVal;
+. }
+. continue yyLoop;
+. }
+. if ((yyN = yyGindex[yyM]) != 0 && (yyN += yyState) >= 0
+. && yyN < yyTable.length && yyCheck[yyN] == yyState)
+. yyState = yyTable[yyN];
+. else
+. yyState = yyDgoto[yyM];
+t if (yydebug != null) yydebug.shift(yyStates[yyTop], yyState);
+. continue yyLoop;
+. }
+. }
+. }
+.
+ tables ## tables for rules, default reduction, and action calls
+.
+ epilog ## text following second %%
diff --git a/mcs/jay/skeleton.cs b/mcs/jay/skeleton.cs
new file mode 100644
index 00000000000..9dd1186651f
--- /dev/null
+++ b/mcs/jay/skeleton.cs
@@ -0,0 +1,351 @@
+# jay skeleton
+
+# character in column 1 determines outcome...
+# # is a comment
+# . is copied
+# t is copied as //t if -t is set
+# other lines are interpreted to call jay procedures
+
+.// created by jay 0.7 (c) 1998 Axel.Schreiner@informatik.uni-osnabrueck.de
+.
+ prolog ## %{ ... %} prior to the first %%
+
+.
+. /** simplified error message.
+. @see <a href="#yyerror(java.lang.String, java.lang.String[])">yyerror</a>
+. */
+. public void yyerror (string message) {
+. yyerror(message, null);
+. }
+.
+. /** (syntax) error message.
+. Can be overwritten to control message format.
+. @param message text to be displayed.
+. @param expected vector of acceptable tokens, if available.
+. */
+. public void yyerror (string message, string[] expected) {
+. if ((expected != null) && (expected.Length > 0)) {
+. System.Console.Write (message+", expecting");
+. for (int n = 0; n < expected.Length; ++ n)
+. System.Console.Write (" "+expected[n]);
+. System.Console.WriteLine ();
+. } else
+. System.Console.WriteLine (message);
+. }
+.
+. /** debugging support, requires the package jay.yydebug.
+. Set to null to suppress debugging messages.
+. */
+t protected yydebug.yyDebug yydebug;
+.
+ debug ## tables for debugging support
+.
+. /** index-checked interface to yyName[].
+. @param token single character or %token value.
+. @return token name or [illegal] or [unknown].
+. */
+t public static string yyname (int token) {
+t if ((token < 0) || (token > yyName.Length)) return "[illegal]";
+t string name;
+t if ((name = yyName[token]) != null) return name;
+t return "[unknown]";
+t }
+.
+. /** computes list of expected tokens on error by tracing the tables.
+. @param state for which to compute the list.
+. @return list of token names.
+. */
+. protected string[] yyExpecting (int state) {
+. int token, n, len = 0;
+. bool[] ok = new bool[yyName.Length];
+.
+. if ((n = yySindex[state]) != 0)
+. for (token = n < 0 ? -n : 0;
+. (token < yyName.Length) && (n+token < yyTable.Length); ++ token)
+. if (yyCheck[n+token] == token && !ok[token] && yyName[token] != null) {
+. ++ len;
+. ok[token] = true;
+. }
+. if ((n = yyRindex[state]) != 0)
+. for (token = n < 0 ? -n : 0;
+. (token < yyName.Length) && (n+token < yyTable.Length); ++ token)
+. if (yyCheck[n+token] == token && !ok[token] && yyName[token] != null) {
+. ++ len;
+. ok[token] = true;
+. }
+.
+. string [] result = new string[len];
+. for (n = token = 0; n < len; ++ token)
+. if (ok[token]) result[n++] = yyName[token];
+. return result;
+. }
+.
+. /** the generated parser, with debugging messages.
+. Maintains a state and a value stack, currently with fixed maximum size.
+. @param yyLex scanner.
+. @param yydebug debug message writer implementing yyDebug, or null.
+. @return result of the last reduction, if any.
+. @throws yyException on irrecoverable parse error.
+. */
+. public Object yyparse (yyParser.yyInput yyLex, Object yydebug)
+. {
+t this.yydebug = (yydebug.yyDebug)yydebug;
+. return yyparse(yyLex);
+. }
+.
+. /** initial size and increment of the state/value stack [default 256].
+. This is not final so that it can be overwritten outside of invocations
+. of yyparse().
+. */
+. protected int yyMax;
+.
+. /** executed at the beginning of a reduce action.
+. Used as $$ = yyDefault($1), prior to the user-specified action, if any.
+. Can be overwritten to provide deep copy, etc.
+. @param first value for $1, or null.
+. @return first.
+. */
+. protected Object yyDefault (Object first) {
+. return first;
+. }
+.
+. /** the generated parser.
+. Maintains a state and a value stack, currently with fixed maximum size.
+. @param yyLex scanner.
+. @return result of the last reduction, if any.
+. @throws yyException on irrecoverable parse error.
+. */
+. public Object yyparse (yyParser.yyInput yyLex)
+. {
+. if (yyMax <= 0) yyMax = 256; // initial size
+. int yyState = 0; // state stack ptr
+. int [] yyStates = new int[yyMax]; // state stack
+. Object yyVal = null; // value stack ptr
+. Object [] yyVals = new Object[yyMax]; // value stack
+. int yyToken = -1; // current input
+. int yyErrorFlag = 0; // #tks to shift
+.
+ local ## %{ ... %} after the first %%
+
+. int yyTop = 0;
+. goto skip;
+. yyLoop:
+. yyTop++;
+. skip:
+. for (;; ++ yyTop) {
+. if (yyTop >= yyStates.Length) { // dynamically increase
+. int[] i = new int[yyStates.Length+yyMax];
+. System.Array.Copy(yyStates, i, 0);
+. yyStates = i;
+. Object[] o = new Object[yyVals.Length+yyMax];
+. System.Array.Copy(yyVals, o, 0);
+. yyVals = o;
+. }
+. yyStates[yyTop] = yyState;
+. yyVals[yyTop] = yyVal;
+t if (yydebug != null) yydebug.push(yyState, yyVal);
+.
+. yyDiscarded: for (;;) { // discarding a token does not change stack
+. int yyN;
+. if ((yyN = yyDefRed[yyState]) == 0) { // else [default] reduce (yyN)
+. if (yyToken < 0) {
+. yyToken = yyLex.advance() ? yyLex.token() : 0;
+t if (yydebug != null)
+t yydebug.lex(yyState, yyToken, yyname(yyToken), yyLex.value());
+. }
+. if ((yyN = yySindex[yyState]) != 0 && ((yyN += yyToken) >= 0)
+. && (yyN < yyTable.Length) && (yyCheck[yyN] == yyToken)) {
+t if (yydebug != null)
+t yydebug.shift(yyState, yyTable[yyN], yyErrorFlag-1);
+. yyState = yyTable[yyN]; // shift to yyN
+. yyVal = yyLex.value();
+. yyToken = -1;
+. if (yyErrorFlag > 0) -- yyErrorFlag;
+. goto yyLoop;
+. }
+. if ((yyN = yyRindex[yyState]) != 0 && (yyN += yyToken) >= 0
+. && yyN < yyTable.Length && yyCheck[yyN] == yyToken)
+. yyN = yyTable[yyN]; // reduce (yyN)
+. else
+. switch (yyErrorFlag) {
+.
+. case 0:
+. yyerror("syntax error", yyExpecting(yyState));
+t if (yydebug != null) yydebug.error("syntax error");
+. goto case 1;
+. case 1: case 2:
+. yyErrorFlag = 3;
+. do {
+. if ((yyN = yySindex[yyStates[yyTop]]) != 0
+. && (yyN += Token.yyErrorCode) >= 0 && yyN < yyTable.Length
+. && yyCheck[yyN] == Token.yyErrorCode) {
+t if (yydebug != null)
+t yydebug.shift(yyStates[yyTop], yyTable[yyN], 3);
+. yyState = yyTable[yyN];
+. yyVal = yyLex.value();
+. goto yyLoop;
+. }
+t if (yydebug != null) yydebug.pop(yyStates[yyTop]);
+. } while (-- yyTop >= 0);
+t if (yydebug != null) yydebug.reject();
+. throw new yyParser.yyException("irrecoverable syntax error");
+.
+. case 3:
+. if (yyToken == 0) {
+t if (yydebug != null) yydebug.reject();
+. throw new yyParser.yyException("irrecoverable syntax error at end-of-file");
+. }
+t if (yydebug != null)
+t yydebug.discard(yyState, yyToken, yyname(yyToken),
+t yyLex.value());
+. yyToken = -1;
+. goto yyDiscarded; // leave stack alone
+. }
+. }
+. int yyV = yyTop + 1-yyLen[yyN];
+t if (yydebug != null)
+t yydebug.reduce(yyState, yyStates[yyV-1], yyN, yyRule[yyN], yyLen[yyN]);
+. yyVal = yyDefault(yyV > yyTop ? null : yyVals[yyV]);
+. switch (yyN) {
+
+ actions ## code from the actions within the grammar
+
+. }
+. yyTop -= yyLen[yyN];
+. yyState = yyStates[yyTop];
+. int yyM = yyLhs[yyN];
+. if (yyState == 0 && yyM == 0) {
+t if (yydebug != null) yydebug.shift(0, yyFinal);
+. yyState = yyFinal;
+. if (yyToken < 0) {
+. yyToken = yyLex.advance() ? yyLex.token() : 0;
+t if (yydebug != null)
+t yydebug.lex(yyState, yyToken,yyname(yyToken), yyLex.value());
+. }
+. if (yyToken == 0) {
+t if (yydebug != null) yydebug.accept(yyVal);
+. return yyVal;
+. }
+. goto yyLoop;
+. }
+. if (((yyN = yyGindex[yyM]) != 0) && ((yyN += yyState) >= 0)
+. && (yyN < yyTable.Length) && (yyCheck[yyN] == yyState))
+. yyState = yyTable[yyN];
+. else
+. yyState = yyDgoto[yyM];
+t if (yydebug != null) yydebug.shift(yyStates[yyTop], yyState);
+. goto yyLoop;
+. }
+. }
+. }
+.
+ tables ## tables for rules, default reduction, and action calls
+.
+ epilog ## text following second %%
+.namespace yydebug {
+. using System;
+. public interface yyDebug {
+. void push (int state, Object value);
+. void lex (int state, int token, string name, Object value);
+. void shift (int from, int to, int errorFlag);
+. void pop (int state);
+. void discard (int state, int token, string name, Object value);
+. void reduce (int from, int to, int rule, string text, int len);
+. void shift (int from, int to);
+. void accept (Object value);
+. void error (string message);
+. void reject ();
+. }
+.
+. class yyDebugSimple : yyDebug {
+. void println (string s){
+. Console.WriteLine (s);
+. }
+.
+. public void push (int state, Object value) {
+. println ("push\tstate "+state+"\tvalue "+value);
+. }
+.
+. public void lex (int state, int token, string name, Object value) {
+. println("lex\tstate "+state+"\treading "+name+"\tvalue "+value);
+. }
+.
+. public void shift (int from, int to, int errorFlag) {
+. switch (errorFlag) {
+. default: // normally
+. println("shift\tfrom state "+from+" to "+to);
+. break;
+. case 0: case 1: case 2: // in error recovery
+. println("shift\tfrom state "+from+" to "+to
+. +"\t"+errorFlag+" left to recover");
+. break;
+. case 3: // normally
+. println("shift\tfrom state "+from+" to "+to+"\ton error");
+. break;
+. }
+. }
+.
+. public void pop (int state) {
+. println("pop\tstate "+state+"\ton error");
+. }
+.
+. public void discard (int state, int token, string name, Object value) {
+. println("discard\tstate "+state+"\ttoken "+name+"\tvalue "+value);
+. }
+.
+. public void reduce (int from, int to, int rule, string text, int len) {
+. println("reduce\tstate "+from+"\tuncover "+to
+. +"\trule ("+rule+") "+text);
+. }
+.
+. public void shift (int from, int to) {
+. println("goto\tfrom state "+from+" to "+to);
+. }
+.
+. public void accept (Object value) {
+. println("accept\tvalue "+value);
+. }
+.
+. public void error (string message) {
+. println("error\t"+message);
+. }
+.
+. public void reject () {
+. println("reject");
+. }
+.
+. }
+.}
+.// %token constants
+. class Token {
+ tokens public const int
+. }
+. namespace yyParser {
+. using System;
+. /** thrown for irrecoverable syntax errors and stack overflow.
+. */
+. public class yyException : System.Exception {
+. public yyException (string message) : base (message) {
+. }
+. }
+.
+. /** must be implemented by a scanner object to supply input to the parser.
+. */
+. public interface yyInput {
+. /** move on to next token.
+. @return false if positioned beyond tokens.
+. @throws IOException on input error.
+. */
+. bool advance (); // throws java.io.IOException;
+. /** classifies current token.
+. Should not be called if advance() returned false.
+. @return current %token or single character.
+. */
+. int token ();
+. /** associated with current token.
+. Should not be called if advance() returned false.
+. @return value for token().
+. */
+. Object value ();
+. }
+. }
diff --git a/mcs/jay/symtab.c b/mcs/jay/symtab.c
new file mode 100644
index 00000000000..0c5f55c535b
--- /dev/null
+++ b/mcs/jay/symtab.c
@@ -0,0 +1,158 @@
+/*
+ * Copyright (c) 1989 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Robert Paul Corbett.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * 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 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)symtab.c 5.3 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+#include "defs.h"
+
+/* TABLE_SIZE is the number of entries in the symbol table. */
+/* TABLE_SIZE must be a power of two. */
+
+#define TABLE_SIZE 1024
+
+
+bucket **symbol_table;
+bucket *first_symbol;
+bucket *last_symbol;
+
+
+int
+hash(name)
+char *name;
+{
+ register char *s;
+ register int c, k;
+
+ assert(name && *name);
+ s = name;
+ k = *s;
+ while (c = *++s)
+ k = (31*k + c) & (TABLE_SIZE - 1);
+
+ return (k);
+}
+
+
+bucket *
+make_bucket(name)
+char *name;
+{
+ register bucket *bp;
+
+ assert(name);
+ bp = (bucket *) MALLOC(sizeof(bucket));
+ if (bp == 0) no_space();
+ bp->link = 0;
+ bp->next = 0;
+ bp->name = MALLOC(strlen(name) + 1);
+ if (bp->name == 0) no_space();
+ bp->tag = 0;
+ bp->value = UNDEFINED;
+ bp->index = 0;
+ bp->prec = 0;
+ bp-> class = UNKNOWN;
+ bp->assoc = TOKEN;
+
+ if (bp->name == 0) no_space();
+ strcpy(bp->name, name);
+
+ return (bp);
+}
+
+
+bucket *
+lookup(name)
+char *name;
+{
+ register bucket *bp, **bpp;
+
+ bpp = symbol_table + hash(name);
+ bp = *bpp;
+
+ while (bp)
+ {
+ if (strcmp(name, bp->name) == 0) return (bp);
+ bpp = &bp->link;
+ bp = *bpp;
+ }
+
+ *bpp = bp = make_bucket(name);
+ last_symbol->next = bp;
+ last_symbol = bp;
+
+ return (bp);
+}
+
+
+create_symbol_table()
+{
+ register int i;
+ register bucket *bp;
+
+ symbol_table = (bucket **) MALLOC(TABLE_SIZE*sizeof(bucket *));
+ if (symbol_table == 0) no_space();
+ for (i = 0; i < TABLE_SIZE; i++)
+ symbol_table[i] = 0;
+
+ bp = make_bucket("error");
+ bp->index = 1;
+ bp->class = TERM;
+
+ first_symbol = bp;
+ last_symbol = bp;
+ symbol_table[hash("error")] = bp;
+}
+
+
+free_symbol_table()
+{
+ FREE(symbol_table);
+ symbol_table = 0;
+}
+
+
+free_symbols()
+{
+ register bucket *p, *q;
+
+ for (p = first_symbol; p; p = q)
+ {
+ q = p->next;
+ FREE(p);
+ }
+}
diff --git a/mcs/jay/verbose.c b/mcs/jay/verbose.c
new file mode 100644
index 00000000000..33ae265ee2e
--- /dev/null
+++ b/mcs/jay/verbose.c
@@ -0,0 +1,366 @@
+/*
+ * Copyright (c) 1989 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Robert Paul Corbett.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * 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 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)verbose.c 5.3 (Berkeley) 1/20/91";
+#endif /* not lint */
+
+#include "defs.h"
+
+static short *null_rules;
+
+verbose()
+{
+ register int i;
+
+ if (!vflag) return;
+
+ null_rules = (short *) MALLOC(nrules*sizeof(short));
+ if (null_rules == 0) no_space();
+ fprintf(verbose_file, "\f\n");
+ for (i = 0; i < nstates; i++)
+ print_state(i);
+ FREE(null_rules);
+
+ if (nunused)
+ log_unused();
+ if (SRtotal || RRtotal)
+ log_conflicts();
+
+ fprintf(verbose_file, "\n\n%d terminals, %d nonterminals\n", ntokens,
+ nvars);
+ fprintf(verbose_file, "%d grammar rules, %d states\n", nrules - 2, nstates);
+}
+
+
+log_unused()
+{
+ register int i;
+ register short *p;
+
+ fprintf(verbose_file, "\n\nRules never reduced:\n");
+ for (i = 3; i < nrules; ++i)
+ {
+ if (!rules_used[i])
+ {
+ fprintf(verbose_file, "\t%s :", symbol_name[rlhs[i]]);
+ for (p = ritem + rrhs[i]; *p >= 0; ++p)
+ fprintf(verbose_file, " %s", symbol_name[*p]);
+ fprintf(verbose_file, " (%d)\n", i - 2);
+ }
+ }
+}
+
+
+log_conflicts()
+{
+ register int i;
+
+ fprintf(verbose_file, "\n\n");
+ for (i = 0; i < nstates; i++)
+ {
+ if (SRconflicts[i] || RRconflicts[i])
+ {
+ fprintf(verbose_file, "State %d contains ", i);
+ if (SRconflicts[i] == 1)
+ fprintf(verbose_file, "1 shift/reduce conflict");
+ else if (SRconflicts[i] > 1)
+ fprintf(verbose_file, "%d shift/reduce conflicts",
+ SRconflicts[i]);
+ if (SRconflicts[i] && RRconflicts[i])
+ fprintf(verbose_file, ", ");
+ if (RRconflicts[i] == 1)
+ fprintf(verbose_file, "1 reduce/reduce conflict");
+ else if (RRconflicts[i] > 1)
+ fprintf(verbose_file, "%d reduce/reduce conflicts",
+ RRconflicts[i]);
+ fprintf(verbose_file, ".\n");
+ }
+ }
+}
+
+
+print_state(state)
+int state;
+{
+ if (state)
+ fprintf(verbose_file, "\n\n");
+ if (SRconflicts[state] || RRconflicts[state])
+ print_conflicts(state);
+ fprintf(verbose_file, "state %d\n", state);
+ print_core(state);
+ print_nulls(state);
+ print_actions(state);
+}
+
+
+print_conflicts(state)
+int state;
+{
+ register int symbol, act, number;
+ register action *p;
+
+ symbol = -1;
+ for (p = parser[state]; p; p = p->next)
+ {
+ if (p->suppressed == 2)
+ continue;
+
+ if (p->symbol != symbol)
+ {
+ symbol = p->symbol;
+ number = p->number;
+ if (p->action_code == SHIFT)
+ act = SHIFT;
+ else
+ act = REDUCE;
+ }
+ else if (p->suppressed == 1)
+ {
+ if (state == final_state && symbol == 0)
+ {
+ fprintf(verbose_file, "%d: shift/reduce conflict \
+(accept, reduce %d) on $end\n", state, p->number - 2);
+ }
+ else
+ {
+ if (act == SHIFT)
+ {
+ fprintf(verbose_file, "%d: shift/reduce conflict \
+(shift %d, reduce %d) on %s\n", state, number, p->number - 2,
+ symbol_name[symbol]);
+ }
+ else
+ {
+ fprintf(verbose_file, "%d: reduce/reduce conflict \
+(reduce %d, reduce %d) on %s\n", state, number - 2, p->number - 2,
+ symbol_name[symbol]);
+ }
+ }
+ }
+ }
+}
+
+
+print_core(state)
+int state;
+{
+ register int i;
+ register int k;
+ register int rule;
+ register core *statep;
+ register short *sp;
+ register short *sp1;
+
+ statep = state_table[state];
+ k = statep->nitems;
+
+ for (i = 0; i < k; i++)
+ {
+ sp1 = sp = ritem + statep->items[i];
+
+ while (*sp >= 0) ++sp;
+ rule = -(*sp);
+ fprintf(verbose_file, "\t%s : ", symbol_name[rlhs[rule]]);
+
+ for (sp = ritem + rrhs[rule]; sp < sp1; sp++)
+ fprintf(verbose_file, "%s ", symbol_name[*sp]);
+
+ putc('.', verbose_file);
+
+ while (*sp >= 0)
+ {
+ fprintf(verbose_file, " %s", symbol_name[*sp]);
+ sp++;
+ }
+ fprintf(verbose_file, " (%d)\n", -2 - *sp);
+ }
+}
+
+
+print_nulls(state)
+int state;
+{
+ register action *p;
+ register int i, j, k, nnulls;
+
+ nnulls = 0;
+ for (p = parser[state]; p; p = p->next)
+ {
+ if (p->action_code == REDUCE &&
+ (p->suppressed == 0 || p->suppressed == 1))
+ {
+ i = p->number;
+ if (rrhs[i] + 1 == rrhs[i+1])
+ {
+ for (j = 0; j < nnulls && i > null_rules[j]; ++j)
+ continue;
+
+ if (j == nnulls)
+ {
+ ++nnulls;
+ null_rules[j] = i;
+ }
+ else if (i != null_rules[j])
+ {
+ ++nnulls;
+ for (k = nnulls - 1; k > j; --k)
+ null_rules[k] = null_rules[k-1];
+ null_rules[j] = i;
+ }
+ }
+ }
+ }
+
+ for (i = 0; i < nnulls; ++i)
+ {
+ j = null_rules[i];
+ fprintf(verbose_file, "\t%s : . (%d)\n", symbol_name[rlhs[j]],
+ j - 2);
+ }
+ fprintf(verbose_file, "\n");
+}
+
+
+print_actions(stateno)
+int stateno;
+{
+ register action *p;
+ register shifts *sp;
+ register int as;
+
+ if (stateno == final_state)
+ fprintf(verbose_file, "\t$end accept\n");
+
+ p = parser[stateno];
+ if (p)
+ {
+ print_shifts(p);
+ print_reductions(p, defred[stateno]);
+ }
+
+ sp = shift_table[stateno];
+ if (sp && sp->nshifts > 0)
+ {
+ as = accessing_symbol[sp->shift[sp->nshifts - 1]];
+ if (ISVAR(as))
+ print_gotos(stateno);
+ }
+}
+
+
+print_shifts(p)
+register action *p;
+{
+ register int count;
+ register action *q;
+
+ count = 0;
+ for (q = p; q; q = q->next)
+ {
+ if (q->suppressed < 2 && q->action_code == SHIFT)
+ ++count;
+ }
+
+ if (count > 0)
+ {
+ for (; p; p = p->next)
+ {
+ if (p->action_code == SHIFT && p->suppressed == 0)
+ fprintf(verbose_file, "\t%s shift %d\n",
+ symbol_name[p->symbol], p->number);
+ }
+ }
+}
+
+
+print_reductions(p, defred)
+register action *p;
+register int defred;
+{
+ register int k, anyreds;
+ register action *q;
+
+ anyreds = 0;
+ for (q = p; q ; q = q->next)
+ {
+ if (q->action_code == REDUCE && q->suppressed < 2)
+ {
+ anyreds = 1;
+ break;
+ }
+ }
+
+ if (anyreds == 0)
+ fprintf(verbose_file, "\t. error\n");
+ else
+ {
+ for (; p; p = p->next)
+ {
+ if (p->action_code == REDUCE && p->number != defred)
+ {
+ k = p->number - 2;
+ if (p->suppressed == 0)
+ fprintf(verbose_file, "\t%s reduce %d\n",
+ symbol_name[p->symbol], k);
+ }
+ }
+
+ if (defred > 0)
+ fprintf(verbose_file, "\t. reduce %d\n", defred - 2);
+ }
+}
+
+
+print_gotos(stateno)
+int stateno;
+{
+ register int i, k;
+ register int as;
+ register short *to_state;
+ register shifts *sp;
+
+ putc('\n', verbose_file);
+ sp = shift_table[stateno];
+ to_state = sp->shift;
+ for (i = 0; i < sp->nshifts; ++i)
+ {
+ k = to_state[i];
+ as = accessing_symbol[k];
+ if (ISVAR(as))
+ fprintf(verbose_file, "\t%s goto %d\n", symbol_name[as], k);
+ }
+}
diff --git a/mcs/jay/warshall.c b/mcs/jay/warshall.c
new file mode 100644
index 00000000000..4672244e368
--- /dev/null
+++ b/mcs/jay/warshall.c
@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) 1989 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Robert Paul Corbett.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * 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 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)warshall.c 5.4 (Berkeley) 5/24/93";
+#endif /* not lint */
+
+#include "defs.h"
+
+transitive_closure(R, n)
+unsigned *R;
+int n;
+{
+ register int rowsize;
+ register unsigned i;
+ register unsigned *rowj;
+ register unsigned *rp;
+ register unsigned *rend;
+ register unsigned *ccol;
+ register unsigned *relend;
+ register unsigned *cword;
+ register unsigned *rowi;
+
+ rowsize = WORDSIZE(n);
+ relend = R + n*rowsize;
+
+ cword = R;
+ i = 0;
+ rowi = R;
+ while (rowi < relend)
+ {
+ ccol = cword;
+ rowj = R;
+
+ while (rowj < relend)
+ {
+ if (*ccol & (1 << i))
+ {
+ rp = rowi;
+ rend = rowj + rowsize;
+ while (rowj < rend)
+ *rowj++ |= *rp++;
+ }
+ else
+ {
+ rowj += rowsize;
+ }
+
+ ccol += rowsize;
+ }
+
+ if (++i >= BITS_PER_WORD)
+ {
+ i = 0;
+ cword++;
+ }
+
+ rowi += rowsize;
+ }
+}
+
+reflexive_transitive_closure(R, n)
+unsigned *R;
+int n;
+{
+ register int rowsize;
+ register unsigned i;
+ register unsigned *rp;
+ register unsigned *relend;
+
+ transitive_closure(R, n);
+
+ rowsize = WORDSIZE(n);
+ relend = R + n*rowsize;
+
+ i = 0;
+ rp = R;
+ while (rp < relend)
+ {
+ *rp |= (1 << i);
+ if (++i >= BITS_PER_WORD)
+ {
+ i = 0;
+ rp++;
+ }
+
+ rp += rowsize;
+ }
+}
diff --git a/mcs/makefile b/mcs/makefile
new file mode 100755
index 00000000000..04839e0050b
--- /dev/null
+++ b/mcs/makefile
@@ -0,0 +1,13 @@
+DIRS=jay mcs class tools
+
+all:
+ @echo "You must use 'make windows' or 'make unix'."
+ @echo "'make unix' is broken for now."
+
+windows:
+ for i in $(DIRS); do \
+ (cd $$i; make windows) \
+ done
+
+unix:
+ echo "'make unix' is broken for now."
diff --git a/mcs/mcs/.cvsignore b/mcs/mcs/.cvsignore
new file mode 100644
index 00000000000..2b426a690cb
--- /dev/null
+++ b/mcs/mcs/.cvsignore
@@ -0,0 +1,4 @@
+compiler.pdb
+compiler.exe
+cs-parser.cs
+y.output
diff --git a/mcs/mcs/ChangeLog b/mcs/mcs/ChangeLog
index 202a33903dc..c1d44645a25 100755
--- a/mcs/mcs/ChangeLog
+++ b/mcs/mcs/ChangeLog
@@ -1,3 +1,288 @@
+2001-08-22 Miguel de Icaza <miguel@ximian.com>
+
+ * codegen.cs (EmitCode): New function, will emit the code for a
+ Block of code given a TypeContainer and its ILGenerator.
+
+ * statement.cs (Block): Standard public readonly optimization.
+ (Block::Block constructors): Link children.
+ (Block::Child): Child Linker.
+ (Block::EmitVariables): Emits IL variable declarations.
+
+ * class.cs: Drop support for MethodGroups here, delay until
+ Semantic Analysis.
+ (Method::): Applied the same simplification that I did before, and
+ move from Properties to public readonly fields.
+ (Method::ParameterTypes): Returns the parameter types for the
+ function, and implements a cache that will be useful later when I
+ do error checking and the semantic analysis on the methods is
+ performed.
+ (Constructor::GetCallingConvention): Renamed from CallingConvetion
+ and made a method, optional argument tells whether this is a class
+ or a structure to apply the `has-this' bit.
+ (Method::GetCallingConvention): Implement, returns the calling
+ convention.
+ (Method::Define): Defines the type, a second pass is performed
+ later to populate the methods.
+
+ (Constructor::ParameterTypes): implement a cache similar to the
+ one on Method::ParameterTypes, useful later when we do semantic
+ analysis.
+
+ (TypeContainer::EmitMethod): New method. Emits methods.
+
+ * expression.cs: Removed MethodGroup class from here.
+
+ * parameter.cs (Parameters::GetCallingConvention): new method.
+
+2001-08-21 Miguel de Icaza <miguel@ximian.com>
+
+ * class.cs (TypeContainer::Populate): Drop RootContext from the
+ argument.
+
+ (Constructor::CallingConvention): Returns the calling convention.
+ (Constructor::ParameterTypes): Returns the constructor parameter
+ types.
+
+ (TypeContainer::AddConstructor): Keep track of default constructor
+ and the default static constructor.
+
+ (Constructor::) Another class that starts using `public readonly'
+ instead of properties.
+
+ (Constructor::IsDefault): Whether this is a default constructor.
+
+ (Field::) use readonly public fields instead of properties also.
+
+ (TypeContainer::TypeAttr, TypeContainer::AddConstructor): Keep
+ track of static constructors; If none is used, turn on
+ BeforeFieldInit in the TypeAttributes.
+
+ * cs-parser.jay (opt_argument_list): now the return can be null
+ for the cases where there are no arguments.
+
+ (constructor_declarator): If there is no implicit `base' or
+ `this', then invoke the default parent constructor.
+
+ * modifiers.cs (MethodAttr): New static function maps a set of
+ modifiers flags into a MethodAttributes enum
+ (FieldAttr): renamed from `Map'. So now we have FieldAttr,
+ MethodAttr, TypeAttr to represent the various mappings where the
+ modifiers are used.
+ (FieldAttr): Map also `readonly' to `FieldAttributes.InitOnly'
+
+2001-08-19 Miguel de Icaza <miguel@ximian.com>
+
+ * parameter.cs (GetParameterInfo): Fix bug where there would be no
+ method arguments.
+
+ * interface.cs (PopulateIndexer): Implemented the code generator
+ for interface indexers.
+
+2001-08-17 Miguel de Icaza <miguel@ximian.com>
+
+ * interface.cs (InterfaceMemberBase): Now we track the new status
+ here.
+
+ (PopulateProperty): Implement property population. Woohoo! Got
+ Methods and Properties going today.
+
+ Removed all the properties for interfaces, and replaced them with
+ `public readonly' fields.
+
+2001-08-16 Miguel de Icaza <miguel@ximian.com>
+
+ * interface.cs (AddEvent, AddMethod, AddIndexer, AddProperty):
+ initialize their hashtables/arraylists only when they are needed
+ instead of doing this always.
+
+ * parameter.cs: Handle refs and out parameters.
+
+ * cs-parser.jay: Use an ArrayList to construct the arguments
+ instead of the ParameterCollection, and then cast that to a
+ Parameter[] array.
+
+ * parameter.cs: Drop the use of ParameterCollection and use
+ instead arrays of Parameters.
+
+ (GetParameterInfo): Use the Type, not the Name when resolving
+ types.
+
+2001-08-13 Miguel de Icaza <miguel@ximian.com>
+
+ * parameter.cs: Eliminate the properties Name, Type and ModFlags,
+ and instead use public readonly fields.
+
+ * class.cs: Put back walking code for type containers.
+
+2001-08-11 Miguel de Icaza <miguel@ximian.com>
+
+ * class.cs (MakeConstant): Code to define constants.
+
+ * rootcontext.cs (LookupType): New function. Used to locate types
+
+
+2001-08-08 Miguel de Icaza <miguel@ximian.com>
+
+ * rootcontext.cs: OH MY! My trick works! It is amazing how nice
+ this System.Reflection code is. Kudos to Microsoft
+
+ * typemanager.cs: Implement a type cache and avoid loading all
+ types at boot time. Wrap in LookupType the internals. This made
+ the compiler so much faster. Wow. I rule!
+
+ * driver.cs: Make sure we always load mscorlib first (for
+ debugging purposes, nothing really important).
+
+ * Renamespaced things that were on `CSC' to `CIR'. Maybe I should
+ have moved to `CSC' rather than `CIR'. Oh man! The confussion!
+
+ * rootcontext.cs: Lookup types on their namespace; Lookup types
+ on namespaces that have been imported using the `using' keyword.
+
+ * class.cs (TypeContainer::TypeAttr): Virtualize.
+ (Class::TypeAttr): Return attributes suitable for this bad boy.
+ (Struct::TypeAttr): ditto.
+ Handle nested classes.
+ (TypeContainer::) Remove all the type visiting code, it is now
+ replaced with the rootcontext.cs code
+
+ * rootcontext.cs (GetClassBases): Added support for structs.
+
+2001-08-06 Miguel de Icaza <miguel@ximian.com>
+
+ * interface.cs, statement.cs, class.cs, parameter.cs,
+ rootcontext.cs, gen-treedump.cs, enum.cs, cs-parse.jay:
+ Drop use of TypeRefs, and use strings instead.
+
+2001-08-04 Miguel de Icaza <miguel@ximian.com>
+
+ * rootcontext.cs:
+
+ * class.cs (Struct::Struct): set the SEALED flags after
+ checking the modifiers.
+ (TypeContainer::TypeAttr): new property, returns the
+ TypeAttributes for a class.
+
+ * cs-parser.jay (type_list): Oops, list production was creating a
+ new list of base types.
+
+ * rootcontext.cs (StdLib): New property.
+ (GetInterfaceTypeByName): returns an interface by type name, and
+ encapsulates error handling here.
+ (GetInterfaces): simplified.
+ (ResolveTree): Encapsulated all the tree resolution here.
+ (CreateClass, GetClassBases, GetInterfaceOrClass): Create class
+ types.
+
+ * driver.cs: Add support for --nostdlib, to avoid loading the
+ default assemblies.
+ (Main): Do not put tree resolution here.
+
+ * rootcontext.cs: Beginning of the class resolution.
+
+2001-08-03 Miguel de Icaza <miguel@ximian.com>
+
+ * rootcontext.cs: Provide better error reporting.
+
+ * cs-parser.jay (interface_base): set our $$ to be interfaces.
+
+ * rootcontext.cs (CreateInterface): Handle the case where there
+ are no parent interfaces.
+
+ (CloseTypes): Routine to flush types at the end.
+ (CreateInterface): Track types.
+ (GetInterfaces): Returns an array of Types from the list of
+ defined interfaces.
+
+ * typemanager.c (AddUserType): Mechanism to track user types (puts
+ the type on the global type hash, and allows us to close it at the
+ end).
+
+2001-08-02 Miguel de Icaza <miguel@ximian.com>
+
+ * tree.cs: Removed RecordType, added RecordClass, RecordStruct and
+ RecordInterface instead.
+
+ * cs-parser.jay: Updated to reflect changes above.
+
+ * decl.cs (Definition): Keep track of the TypeBuilder type that
+ represents this type here. Not sure we will use it in the long
+ run, but wont hurt for now.
+
+ * driver.cs: Smaller changes to accomodate the new code.
+
+ Call ResolveInterfaceBases, Call ResolveClassBases, Save assembly
+ when done.
+
+ * rootcontext.cs (CreateInterface): New method, used to create
+ the System.TypeBuilder type for interfaces.
+ (ResolveInterfaces): new entry point to resolve the interface
+ hierarchy.
+ (CodeGen): Property, used to keep track of the code generator.
+
+2001-07-26 Miguel de Icaza <miguel@ximian.com>
+
+ * cs-parser.jay: Add a second production for delegate_declaration
+ with `VOID'.
+
+ (enum_body): Put an opt_comma here instead of putting it on
+ enum_body or enum_member_declarations so we can handle trailing
+ commas on enumeration members. Gets rid of a shift/reduce.
+
+ (type_list): Need a COMMA in the middle.
+
+ (indexer_declaration): Tell tokenizer to recognize get/set
+
+ * Remove old targets.
+
+ * Re-add the parser target.
+
+2001-07-13 Simon Cozens <simon@simon-cozens.org>
+
+ * cs-parser.jay: Add precendence rules for a number of operators
+ ot reduce the number of shift/reduce conflicts in the grammar.
+
+2001-07-17 Miguel de Icaza <miguel@ximian.com>
+
+ * tree.cs: moved IGenerator interface and renamed it to ITreeDump
+ and put it here.
+
+ Get rid of old crufty code.
+
+ * rootcontext.cs: Use this to keep track of the parsed
+ representation and the defined types available to the program.
+
+ * gen-treedump.cs: adjust for new convention.
+
+ * type.cs: Split out the type manager, and the assembly builder
+ from here.
+
+ * typemanager.cs: the type manager will live here now.
+
+ * cil-codegen.cs: And the code generator here.
+
+2001-07-14 Sean MacIsaac <macisaac@ximian.com>
+
+ * makefile: Fixed up for easy making.
+
+2001-07-13 Simon Cozens <simon@simon-cozens.org>
+
+ * cs-parser.jay (rank_specifier): Remove a conflict by reordering
+ the
+
+ (unary_expression): Expand pre_increment_expression and
+ post_decrement_expression to reduce a shift/reduce.
+
+2001-07-11 Simon Cozens
+
+ * cs-tokenizer.cs: Hex numbers should begin with a 0.
+
+ Improve allow_keyword_as_indent name.
+
+2001-06-19 Miguel de Icaza <miguel@ximian.com>
+
+ * Adjustments for Beta2.
+
2001-06-13 Miguel de Icaza <miguel@ximian.com>
* decl.cs: Added `Define' abstract method.
diff --git a/mcs/mcs/TODO b/mcs/mcs/TODO
new file mode 100644
index 00000000000..45f490b8023
--- /dev/null
+++ b/mcs/mcs/TODO
@@ -0,0 +1,75 @@
+* Handle duplicate methods and constructors in semantic analysis
+
+* Ordering
+
+ First define methods and operator overloads.
+
+ Do enumerations and constants.
+
+ Process function bodies
+
+ Can a constant_expression invoke overloaded operators?
+ Explicit user-defined conversions?
+
+* Visibility
+
+ I am not processing visibility yet.
+
+* Tokenizer
+
+ Propagate file/location to upper layers
+
+* Error handling
+
+ Normalize, and use Tokenizer location
+
+* Enumerations
+
+ Currently I am not resolving enumerations.
+
+ Either I track them with `RecordEnum' as I do with classes,
+ structs and interfaces or I rewrite the code to visit type
+ containers and `walk' the enums with this process.
+
+* Known problems:
+
+ Can not parse try {} catch {}
+
+ Have not figured out why.
+
+ Cast expressions
+
+ They should should use:
+
+ OPEN_PARENS type CLOSE_PARENS
+
+ instead of the current production which is wrong, because it
+ only handles a few cases.
+
+ Complex casts like:
+
+ Array r = (string []) object
+
+ Wont be parsed.
+
+
+* Interfaces
+
+ For indexers, the output of ix2.cs is different from our
+ compiler and theirs. They use a DefaultMemberAttribute, which
+ I have yet to figure out:
+
+ .class interface private abstract auto ansi INTERFACE
+ {
+ .custom instance void [mscorlib]System.Reflection.DefaultMemberAttribute::.ctor(string)
+ = ( 01 00 04 49 74 65 6D 00 00 ) // ...Item..
+ ...
+ }
+
+* Interface indexers
+
+ I have not figured out why the Microsoft version puts an
+ `instance' attribute, and I am not generating this `instance' attribute.
+
+
+
diff --git a/mcs/mcs/class.cs b/mcs/mcs/class.cs
index 131f29a43b7..05724bc5146 100755
--- a/mcs/mcs/class.cs
+++ b/mcs/mcs/class.cs
@@ -7,30 +7,64 @@
//
// (C) 2001 Ximian, Inc (http://www.ximian.com)
//
-// TODO:
-//
-// a. Maybe keep a list of defined names in the order they
-// appeared, so we can walk things in this way to present
-// the users with errors in that order?
//
using System.Collections;
+using System.Reflection;
+using System.Reflection.Emit;
using System;
namespace CIR {
public class TypeContainer : DeclSpace {
protected int mod_flags;
- Hashtable types, fields, properties;
- Hashtable enums, constants, interfaces, method_groups;
- ArrayList constructor_list;
+ // Holds a list of classes and structures
+ ArrayList types;
+
+ // Holds the list of properties
+ ArrayList properties;
+
+ // Holds the list of enumerations
+ ArrayList enums;
+
+ // Holds the list of constructors
+ ArrayList constructors;
+
+ // Holds the list of fields
+ ArrayList fields;
+
+ // Holds a list of fields that have initializers
+ ArrayList initialized_fields;
+
+ // Holds a list of static fields that have initializers
+ ArrayList initialized_static_fields;
+
+ // Holds the list of constants
+ ArrayList constants;
+ // Holds the list of
+ ArrayList interfaces;
+
+ // Holds the methods.
+ ArrayList methods;
+
+ //
+ // Pointers to the default constructor and the default static constructor
+ //
+ Constructor default_constructor;
+ Constructor default_static_constructor;
+
+ //
+ // Whether we have seen a static constructor for this class or not
+ //
+ bool have_static_constructor = false;
+
//
// This is the namespace in which this typecontainer
// was declared. We use this to resolve names.
//
- CSC.Namespace my_namespace;
+ Namespace my_namespace;
//
// This one is computed after we can distinguish interfaces
@@ -41,12 +75,20 @@ namespace CIR {
TypeContainer parent;
ArrayList type_bases;
- public TypeContainer (TypeContainer parent, string name) : base (name)
+ //
+ // This behaves like a property ;-)
+ //
+ readonly public RootContext RootContext;
+
+ public TypeContainer (RootContext rc, TypeContainer parent, string name) : base (name)
{
- types = new Hashtable ();
+ string n;
+ types = new ArrayList ();
this.parent = parent;
+ RootContext = rc;
- string n;
+ object a = rc.Report;
+
if (parent == null)
n = "";
else
@@ -66,9 +108,9 @@ namespace CIR {
return res;
if (constants == null)
- constants = new Hashtable ();
+ constants = new ArrayList ();
- constants.Add (name, constant);
+ constants.Add (constant);
DefineName (name, constant);
return AdditionResult.Success;
@@ -83,9 +125,9 @@ namespace CIR {
return res;
if (enums == null)
- enums = new Hashtable ();
+ enums = new ArrayList ();
- enums.Add (name, e);
+ enums.Add (e);
DefineName (name, e);
return AdditionResult.Success;
@@ -101,7 +143,7 @@ namespace CIR {
return res;
DefineName (name, c);
- types.Add (name, c);
+ types.Add (c);
return AdditionResult.Success;
}
@@ -115,7 +157,7 @@ namespace CIR {
return res;
DefineName (name, s);
- types.Add (name, s);
+ types.Add (s);
return AdditionResult.Success;
}
@@ -125,26 +167,15 @@ namespace CIR {
string name = method.Name;
Object value = defined_names [name];
- if (value != null && (!(value is MethodGroup)))
+ if (value != null && (!(value is Method)))
return AdditionResult.NameExists;
- if (method_groups == null)
- method_groups = new Hashtable ();
-
- MethodGroup mg = (MethodGroup) method_groups [name];
- if (mg == null){
- mg = new MethodGroup (name);
+ if (methods == null)
+ methods = new ArrayList ();
- mg.Add (method);
- method_groups.Add (name, mg);
+ methods.Add (method);
+ DefineName (name, method);
- return AdditionResult.Success;
- }
- mg.Add (method);
-
- if (value == null)
- DefineName (name, mg);
-
return AdditionResult.Success;
}
@@ -153,10 +184,22 @@ namespace CIR {
if (c.Name != Basename)
return AdditionResult.NotAConstructor;
- if (constructor_list == null)
- constructor_list = new ArrayList ();
+ if (constructors == null)
+ constructors = new ArrayList ();
+
+ constructors.Add (c);
- constructor_list.Add (c);
+ bool is_static = (c.ModFlags & Modifiers.STATIC) != 0;
+
+ if (is_static)
+ have_static_constructor = true;
+
+ if (c.IsDefault ()){
+ if (is_static)
+ default_static_constructor = c;
+ else
+ default_constructor = c;
+ }
return AdditionResult.Success;
}
@@ -170,8 +213,8 @@ namespace CIR {
return res;
if (interfaces == null)
- interfaces = new Hashtable ();
- interfaces.Add (name, iface);
+ interfaces = new ArrayList ();
+ interfaces.Add (iface);
DefineName (name, iface);
return AdditionResult.Success;
@@ -186,9 +229,29 @@ namespace CIR {
return res;
if (fields == null)
- fields = new Hashtable ();
-
- fields.Add (name, field);
+ fields = new ArrayList ();
+
+ fields.Add (field);
+ if (field.Initializer != null){
+ if ((field.ModFlags & Modifiers.STATIC) != 0){
+ if (initialized_static_fields == null)
+ initialized_static_fields = new ArrayList ();
+
+ initialized_static_fields.Add (field);
+
+ //
+ // We have not seen a static constructor,
+ // but we will provide static initialization of fields
+ //
+ have_static_constructor = true;
+ } else {
+ if (initialized_fields == null)
+ initialized_fields = new ArrayList ();
+
+ initialized_fields.Add (field);
+ }
+ }
+
DefineName (name, field);
return AdditionResult.Success;
}
@@ -202,43 +265,39 @@ namespace CIR {
return res;
if (properties == null)
- properties = new Hashtable ();
+ properties = new ArrayList ();
- properties.Add (name, prop);
+ properties.Add (prop);
DefineName (name, prop);
return AdditionResult.Success;
}
- public Constant GetConstant (string name) {
- return (Constant) constants [name];
- }
-
public TypeContainer Parent {
get {
return parent;
}
}
- public Hashtable Types {
+ public ArrayList Types {
get {
return types;
}
}
- public Hashtable MethodGroups {
+ public ArrayList Methods {
get {
- return method_groups;
+ return methods;
}
}
- public Hashtable Constants {
+ public ArrayList Constants {
get {
return constants;
}
}
- public Hashtable Interfaces {
+ public ArrayList Interfaces {
get {
return interfaces;
}
@@ -266,31 +325,31 @@ namespace CIR {
}
}
- public Hashtable Fields {
+ public ArrayList Fields {
get {
return fields;
}
}
- public Hashtable Constructors {
+ public ArrayList Constructors {
get {
return null; // constructors;
}
}
- public Hashtable Properties {
+ public ArrayList Properties {
get {
return properties;
}
}
- public Hashtable Enums {
+ public ArrayList Enums {
get {
return enums;
}
}
- public CSC.Namespace Namespace {
+ public Namespace Namespace {
get {
return my_namespace;
}
@@ -299,147 +358,208 @@ namespace CIR {
my_namespace = value;
}
}
-
- public int ResolveParents (Tree root)
- {
- if (Bases == null){
- base_class_name = "System.Object";
- return 0;
- }
-
- if (type_bases.Count == 0){
- base_class_name = "System.Object";
- return 0;
+
+ //
+ // The Toplevel is `root_types' which is a containerfor all
+ // types defined, hence the non-obviios parent.parent.
+ //
+ // If we were not tracking Namespaces we could remove this.
+ //
+ bool IsTopLevel {
+ get {
+ if (parent != null){
+ if (parent.parent == null)
+ return true;
+ }
+
+ return false;
}
-
- return 0;
}
- override public Type Define (Tree tree)
- {
- return null;
+ // <summary>
+ // Returns the TypeAttributes for this TypeContainer
+ // </summary>
+ public virtual TypeAttributes TypeAttr {
+ get {
+ TypeAttributes x = 0;
+
+ //
+ // FIXME: Figure out exactly how private, public and protected
+ // map to the TypeAttribute flags.
+ //
+ // FIXME: Figure out what `new' in the context of a class/struct means.
+ //
+ // FIXME: figure out what `internal' means in the context of class/structs
+ //
+ if ((mod_flags & Modifiers.PUBLIC) != 0)
+ x |= TypeAttributes.Public;
+
+ if ((mod_flags & Modifiers.PRIVATE) != 0)
+ x |= TypeAttributes.NotPublic;
+
+ if ((mod_flags & Modifiers.ABSTRACT) != 0)
+ x |= TypeAttributes.Abstract;
+
+ if ((mod_flags & Modifiers.SEALED) != 0)
+ x |= TypeAttributes.Sealed;
+
+ if (!IsTopLevel){
+ if ((mod_flags & Modifiers.PUBLIC) != 0)
+ x |= TypeAttributes.NestedPublic;
+ else
+ x |= TypeAttributes.NestedPrivate;
+ }
+
+ //
+ // If we have static constructors, the runtime needs to
+ // initialize the class, otherwise we can optimize
+ // the case.
+ //
+ if (!have_static_constructor)
+ x |= TypeAttributes.BeforeFieldInit;
+ return x;
+ }
}
-
- public delegate void VisitContainer (TypeContainer container, object cback_data);
- void VisitTypesAt (TypeContainer root, VisitContainer visit, object cback)
+ void EmitField (Field f)
{
- if (root == null)
+ Type t = LookupType (f.Type, false);
+
+ if (t == null)
return;
- foreach (DictionaryEntry de in root.Types){
- TypeContainer type = (TypeContainer) de.Value;
+ TypeBuilder.DefineField (f.Name, t, Modifiers.FieldAttr (f.ModFlags));
+ }
- visit (type, cback);
- VisitTypesAt (type, visit, cback);
- }
+ //
+ // Emits the class field initializers
+ //
+ void EmitStaticFieldInitializers (ConstructorBuilder cb)
+ {
+ // FIXME: Implement
}
- // <summary>
- // Use this method to visit all the types in a type container.
- // You can use cback to pass arbitrary data to your callback.
- // </summary>
- public void VisitTypes (VisitContainer visit, object cback)
+ //
+ // Emits the instance field initializers
+ //
+ void EmitFieldInitializers (ConstructorBuilder cb)
{
- foreach (DictionaryEntry de in types){
- TypeContainer type = (TypeContainer) de.Value;
+ // FIXME: Implement
+ }
- VisitTypesAt (type, visit, cback);
+ //
+ // Emits a constructor
+ //
+ void EmitConstructor (Constructor c)
+ {
+ if ((c.ModFlags & Modifiers.STATIC) != 0){
+ if (initialized_static_fields != null)
+ EmitStaticFieldInitializers (c.ConstructorBuilder);
+ } else {
+ if (initialized_fields != null)
+ EmitFieldInitializers (c.ConstructorBuilder);
}
-
+
}
- internal class VisitExpressions_Lambda {
- VisitExpressionRoot vb;
- object user_data;
+ //
+ // This function is used to emit instance and static constructors
+ // when the user did not provide one.
+ //
+ void EmitDefaultConstructor (bool is_static)
+ {
+ ConstructorBuilder cb;
+ MethodAttributes ca = (MethodAttributes.RTSpecialName |
+ MethodAttributes.SpecialName);
- void walk_arguments (ArrayList args)
- {
- if (args == null)
- return;
-
- int top = args.Count;
+ if (is_static)
+ ca |= MethodAttributes.Static;
+
+ //
+ // Default constructors provided by the compiler should be `protected'
+ // if the class is abstract, otherwise it is public
+ //
+ if ((mod_flags & Modifiers.ABSTRACT) != 0)
+ ca |= MethodAttributes.Family;
+ else
+ ca |= MethodAttributes.Public;
+
+ cb = TypeBuilder.DefineDefaultConstructor (ca);
- for (int i = 0; i < top; i++){
- Argument arg = (Argument) args [i];
+ if (is_static)
+ EmitStaticFieldInitializers (cb);
+ else
+ EmitFieldInitializers (cb);
+ }
- vb (arg.Expr, user_data);
- }
+ //
+ // Populates our TypeBuilder with fields and methods
+ //
+ public void Populate ()
+ {
+ if (Constants != null){
+ foreach (Constant c in Constants)
+ c.EmitConstant (RootContext, this);
}
- void walk_block (Block b)
- {
+ if (Fields != null){
+ foreach (Field f in Fields)
+ EmitField (f);
}
-
- void walk_constructor (Constructor c)
- {
- ConstructorInitializer init = c.Initializer;
-
- if (init != null && init.Arguments != null)
- walk_arguments (init.Arguments);
- walk_block (c.Block);
+ if (Constructors != null){
+ foreach (Constructor c in Constructors)
+ c.Define (this);
}
- void walk_properties (Property p)
- {
+ if (Methods != null){
+ foreach (Method m in Methods)
+ m.Define (this);
}
+ }
- void walk_method (Method m)
- {
- }
-
- void type_walker_1 (TypeContainer type, object cback)
- {
- if (type.Fields != null){
- foreach (DictionaryEntry de in type.Fields){
- Field f = (Field) de.Value;
-
- if (f.Initializer != null){
- if (f.Initializer is Expression)
- vb ((Expression) f.Initializer, user_data);
- }
- }
- }
-
- if (type.Constructors != null){
- foreach (DictionaryEntry de in type.Constructors)
- walk_constructor ((Constructor) de.Value);
- }
-
- if (type.Properties != null){
- foreach (DictionaryEntry de in type.Properties)
- walk_properties ((Property) de.Value);
- }
+ //
+ // Emits the code, this step is performed after all
+ // the types, enumerations, constructors
+ //
+ public void Emit ()
+ {
+ if (default_constructor == null)
+ EmitDefaultConstructor (false);
- if (type.MethodGroups != null){
- foreach (DictionaryEntry de in type.MethodGroups){
- Hashtable methods = ((MethodGroup) de.Value).Methods;
- foreach (Method m in methods)
- walk_method (m);
- }
- }
- }
+ if (initialized_static_fields != null && default_static_constructor == null)
+ EmitDefaultConstructor (true);
+ if (Constructors != null)
+ foreach (Constructor c in Constructors)
+ c.Emit ();
- internal VisitExpressions_Lambda (TypeContainer tc,
- VisitExpressionRoot vb,
- object user_data)
- {
- this.vb = vb;
- this.user_data = user_data;
+ if (Methods != null)
+ foreach (Method m in Methods)
+ m.Emit (this);
+ }
+
+ public delegate void ExamineType (TypeContainer container, object cback_data);
- tc.VisitTypes (new VisitContainer (type_walker_1), null);
+ void WalkTypesAt (TypeContainer root, ExamineType visit, object cback_data)
+ {
+ if (root == null)
+ return;
+
+ foreach (TypeContainer type in root.Types){
+ visit (type, cback_data);
+ WalkTypesAt (type, visit, cback_data);
}
}
-
- public delegate void VisitExpressionRoot (Expression e, object cback);
- // <summary>
- // Use this method to visit all the code blocks in a TypeContainer
- // </summary>
- public void VisitExpressionRoots (VisitExpressionRoot vb, object cback)
+
+ public void WalkTypes (ExamineType visit, object cback)
+ {
+ WalkTypesAt (this, visit, cback);
+ }
+
+ public Type LookupType (string name, bool silent)
{
- VisitExpressions_Lambda l = new VisitExpressions_Lambda (this, vb, cback);
+ return RootContext.LookupType (this, name, silent);
}
}
@@ -456,8 +576,8 @@ namespace CIR {
Modifiers.ABSTRACT |
Modifiers.SEALED;
- public Class (TypeContainer parent, string name, int mod)
- : base (parent, name)
+ public Class (RootContext rc, TypeContainer parent, string name, int mod)
+ : base (rc, parent, name)
{
int accmods;
@@ -468,6 +588,16 @@ namespace CIR {
this.mod_flags = Modifiers.Check (AllowedModifiers, mod, accmods);
}
+
+ //
+ // FIXME: How do we deal with the user specifying a different
+ // layout?
+ //
+ public override TypeAttributes TypeAttr {
+ get {
+ return base.TypeAttr | TypeAttributes.AutoLayout;
+ }
+ }
}
public class Struct : TypeContainer {
@@ -481,8 +611,8 @@ namespace CIR {
Modifiers.INTERNAL |
Modifiers.PRIVATE;
- public Struct (TypeContainer parent, string name, int mod)
- : base (parent, name)
+ public Struct (RootContext rc, TypeContainer parent, string name, int mod)
+ : base (rc, parent, name)
{
int accmods;
@@ -492,23 +622,41 @@ namespace CIR {
accmods = Modifiers.PRIVATE;
this.mod_flags = Modifiers.Check (AllowedModifiers, mod, accmods);
+
+ this.mod_flags |= Modifiers.SEALED;
+ }
+
+ //
+ // FIXME: Allow the user to specify a different set of attributes
+ // in some cases (Sealed for example is mandatory for a class,
+ // but what SequentialLayout can be changed
+ //
+ public override TypeAttributes TypeAttr {
+ get {
+ return base.TypeAttr |
+ TypeAttributes.SequentialLayout |
+ TypeAttributes.Sealed |
+ TypeAttributes.BeforeFieldInit;
+ }
}
}
public class Method {
- Parameters parameters;
- TypeRef return_typeref;
- string name;
- int modifiers;
- Block block;
-
+ public readonly Parameters Parameters;
+ public readonly string ReturnType;
+ public readonly string Name;
+ public readonly int ModFlags;
+ public MethodBuilder MethodBuilder;
+
+ Block block;
+
// return_type can be "null" for VOID values.
- public Method (TypeRef return_typeref, int mod, string name, Parameters parameters)
+ public Method (string return_type, int mod, string name, Parameters parameters)
{
- this.return_typeref = return_typeref;
- this.name = name;
- this.parameters = parameters;
- this.modifiers = Modifiers.Check (AllowedModifiers, mod, Modifiers.PRIVATE);
+ Name = name;
+ ReturnType = return_type;
+ Parameters = parameters;
+ ModFlags = Modifiers.Check (AllowedModifiers, mod, Modifiers.PRIVATE);
}
// <summary>
@@ -537,42 +685,97 @@ namespace CIR {
}
}
- public string Name {
- get {
- return name;
- }
+ //
+ // Returns the `System.Type' for the ReturnType of this
+ // function. Provides a nice cache. (used between semantic analysis
+ // and actual code generation
+ //
+ Type type_return_type;
+ public Type GetReturnType (TypeContainer parent)
+ {
+ if (type_return_type == null)
+ type_return_type = parent.LookupType (ReturnType, false);
+
+ return type_return_type;
}
- public int ModFlags {
- get {
- return modifiers;
- }
+ //
+ // Returns the System.Type array for the parameters of this method
+ //
+ Type [] parameter_types;
+ public Type [] ParameterTypes (TypeContainer parent)
+ {
+ if (Parameters == null)
+ return null;
+
+ if (parameter_types == null)
+ parameter_types = Parameters.GetParameterInfo (parent);
+
+ return parameter_types;
}
- public Parameters Parameters {
- get {
- return parameters;
- }
+ public CallingConventions GetCallingConvention (bool is_class)
+ {
+ CallingConventions cc = 0;
+
+ cc = Parameters.GetCallingConvention ();
+
+ if (is_class)
+ if ((ModFlags & Modifiers.STATIC) != 0)
+ cc |= CallingConventions.HasThis;
+
+ return cc;
}
- public Type ReturnType {
- get {
- return return_typeref.Type;
+ //
+ // Creates the type
+ //
+ public void Define (TypeContainer parent)
+ {
+ Type ret_type = GetReturnType (parent);
+ Type [] parameters = ParameterTypes (parent);
+
+ //
+ // Create the method
+ //
+ MethodBuilder = parent.TypeBuilder.DefineMethod (
+ Name, Modifiers.MethodAttr (ModFlags),
+ GetCallingConvention (parent is Class),
+ ret_type, parameters);
+
+ //
+ // Define each type attribute (in/out/ref) and
+ // the argument names.
+ //
+ Parameter [] p = Parameters.FixedParameters;
+ if (p != null){
+ int i;
+
+ for (i = 0; i < p.Length; i++)
+ MethodBuilder.DefineParameter (
+ i + 1, p [i].Attributes, p [i].Name);
+
+ if (i != parameters.Length)
+ Console.WriteLine ("Implement the type definition for params");
}
}
- public string ArgumentSignature {
- get {
- return ""; // TYPEFIX: Type.MakeParameterSignature (name, parameters);
- }
+ //
+ // Emits the code
+ //
+ public void Emit (TypeContainer parent)
+ {
+ ILGenerator ig = MethodBuilder.GetILGenerator ();
+
+ CodeGen.EmitCode (parent, ig, block);
}
}
public class Field {
- Type type;
- Object expr_or_array_init;
- string name;
- int modifiers;
+ public readonly string Type;
+ public readonly Object Initializer;
+ public readonly string Name;
+ public readonly int ModFlags;
// <summary>
// Modifiers allowed in a class declaration
@@ -586,36 +789,12 @@ namespace CIR {
Modifiers.STATIC |
Modifiers.READONLY;
- public Field (TypeRef typeref, int mod, string name, Object expr_or_array_init)
+ public Field (string type, int mod, string name, Object expr_or_array_init)
{
- this.type = type;
- this.modifiers = Modifiers.Check (AllowedModifiers, mod, Modifiers.PRIVATE);
- this.name = name;
- this.expr_or_array_init = expr_or_array_init;
- }
-
- public Type Type {
- get {
- return type;
- }
- }
-
- public object Initializer {
- get {
- return expr_or_array_init;
- }
- }
-
- public string Name {
- get {
- return name;
- }
- }
-
- public int ModFlags {
- get {
- return modifiers;
- }
+ Type = type;
+ ModFlags = Modifiers.Check (AllowedModifiers, mod, Modifiers.PRIVATE);
+ Name = name;
+ Initializer = expr_or_array_init;
}
}
@@ -647,9 +826,10 @@ namespace CIR {
}
public class Constructor {
- ConstructorInitializer init;
- string name;
- Parameters args;
+ public ConstructorBuilder ConstructorBuilder;
+ public readonly ConstructorInitializer Initializer;
+ public readonly Parameters Parameters;
+ public readonly string Name;
Block block;
int mod_flags;
@@ -667,32 +847,33 @@ namespace CIR {
// The spec claims that static is not permitted, but
// my very own code has static constructors.
//
-
public Constructor (string name, Parameters args, ConstructorInitializer init)
{
- this.name = name;
- this.args = args;
- this.init = init;
+ Name = name;
+ Parameters = args;
+ Initializer = init;
}
- public string Name {
- get {
- return name;
- }
+ //
+ // Returns true if this is a default constructor
+ //
+ public bool IsDefault ()
+ {
+ return (Parameters == null) &&
+ (Initializer is ConstructorBaseInitializer) &&
+ (Initializer.Arguments == null);
}
- public ConstructorInitializer Initializer {
+ public int ModFlags {
get {
- return init;
+ return mod_flags;
}
- }
- public Parameters Parameters {
- get {
- return args;
+ set {
+ mod_flags = value;
}
}
-
+
public Block Block {
get {
return block;
@@ -703,19 +884,65 @@ namespace CIR {
}
}
- public int ModFlags {
- get {
- return mod_flags;
- }
+ public CallingConventions GetCallingConvention (bool parent_is_class)
+ {
+ CallingConventions cc = 0;
+
+ if (Parameters.ArrayParameter != null)
+ cc |= CallingConventions.VarArgs;
+ else
+ cc |= CallingConventions.Standard;
- set {
- mod_flags = Modifiers.Check (AllowedModifiers, value, 0);
- }
+ if (parent_is_class)
+ if ((ModFlags & Modifiers.STATIC) != 0)
+ cc |= CallingConventions.HasThis;
+
+ // FIXME: How is `ExplicitThis' used in C#?
+
+ return cc;
+ }
+
+ //
+ // Cached representation
+ ///
+ Type [] parameter_types;
+ public Type [] ParameterTypes (TypeContainer tc)
+ {
+ if (Parameters == null)
+ return null;
+
+ if (parameter_types == null)
+ parameter_types = Parameters.GetParameterInfo (tc);
+
+ return parameter_types;
+ }
+
+ //
+ // Creates the ConstructorBuilder
+ //
+ public void Define (TypeContainer parent)
+ {
+ MethodAttributes ca = (MethodAttributes.RTSpecialName |
+ MethodAttributes.SpecialName);
+
+ if ((ModFlags & Modifiers.STATIC) != 0)
+ ca |= MethodAttributes.Static;
+
+ ConstructorBuilder = parent.TypeBuilder.DefineConstructor (
+ ca, GetCallingConvention (parent is Class),
+ ParameterTypes (parent));
+ }
+
+ //
+ // Emits the code
+ //
+ public void Emit ()
+ {
}
}
public class Property {
- TypeRef typeref;
+ string type;
string name;
int mod_flags;
Block get_block, set_block;
@@ -732,18 +959,18 @@ namespace CIR {
Modifiers.ABSTRACT |
Modifiers.VIRTUAL;
- public Property (TypeRef typeref, string name, int mod_flags, Block get_block, Block set_block)
+ public Property (string type, string name, int mod_flags, Block get_block, Block set_block)
{
- this.typeref = typeref;
+ this.type = type;
this.name = name;
this.mod_flags = Modifiers.Check (AllowedModifiers, mod_flags, Modifiers.PRIVATE);
this.get_block = get_block;
this.set_block = set_block;
}
- public Type Type {
+ public string Type {
get {
- return typeref.Type;
+ return type;
}
}
diff --git a/mcs/mcs/codegen.cs b/mcs/mcs/codegen.cs
new file mode 100755
index 00000000000..1f36bde8c6d
--- /dev/null
+++ b/mcs/mcs/codegen.cs
@@ -0,0 +1,58 @@
+//
+// codegen.cs: The code generator
+//
+// Author:
+// Miguel de Icaza (miguel@ximian.com)
+//
+// (C) 2001 Ximian, Inc.
+//
+
+using System;
+using System.Reflection;
+using System.Reflection.Emit;
+
+namespace CIR {
+
+ public class CodeGen {
+ AppDomain current_domain;
+ AssemblyBuilder assembly_builder;
+ ModuleBuilder module_builder;
+
+ public CodeGen (string name, string output)
+ {
+ AssemblyName an;
+
+ an = new AssemblyName ();
+ an.Name = "AssemblyName";
+ current_domain = AppDomain.CurrentDomain;
+ assembly_builder = current_domain.DefineDynamicAssembly (
+ an, AssemblyBuilderAccess.RunAndSave);
+
+ module_builder = assembly_builder.DefineDynamicModule (name, output);
+ }
+
+ public AssemblyBuilder AssemblyBuilder {
+ get {
+ return assembly_builder;
+ }
+ }
+
+ public ModuleBuilder ModuleBuilder {
+ get {
+ return module_builder;
+ }
+ }
+
+ public void Save (string name)
+ {
+ assembly_builder.Save (name);
+ }
+
+ public static void EmitCode (TypeContainer parent, ILGenerator ig, Block block)
+ {
+ block.EmitVariables (parent, ig);
+
+ ig.Emit (OpCodes.Ret);
+ }
+ }
+}
diff --git a/mcs/mcs/compiler.csproj b/mcs/mcs/compiler.csproj
new file mode 100755
index 00000000000..00ee7bc1d09
--- /dev/null
+++ b/mcs/mcs/compiler.csproj
@@ -0,0 +1,216 @@
+<VisualStudioProject>
+ <CSHARP
+ ProjectType = "Local"
+ ProductVersion = "7.0.9254"
+ SchemaVersion = "1.0"
+ ProjectGuid = "{896D1461-B76B-41C0-ABE6-ACA2BB4F7B5A}"
+ >
+ <Build>
+ <Settings
+ ApplicationIcon = ""
+ AssemblyKeyContainerName = ""
+ AssemblyName = "compiler"
+ AssemblyOriginatorKeyFile = ""
+ DefaultClientScript = "JScript"
+ DefaultHTMLPageLayout = "Grid"
+ DefaultTargetSchema = "IE50"
+ DelaySign = "false"
+ NoStandardLibraries = "false"
+ OutputType = "Exe"
+ RootNamespace = "CIR"
+ StartupObject = ""
+ >
+ <Config
+ Name = "Debug"
+ AllowUnsafeBlocks = "false"
+ BaseAddress = "285212672"
+ CheckForOverflowUnderflow = "false"
+ ConfigurationOverrideFile = ""
+ DefineConstants = "DEBUG;TRACE"
+ DocumentationFile = ""
+ DebugSymbols = "true"
+ FileAlignment = "4096"
+ IncrementalBuild = "true"
+ Optimize = "false"
+ OutputPath = "bin\Debug\"
+ RegisterForComInterop = "false"
+ RemoveIntegerChecks = "false"
+ TreatWarningsAsErrors = "false"
+ WarningLevel = "4"
+ />
+ <Config
+ Name = "Release"
+ AllowUnsafeBlocks = "false"
+ BaseAddress = "285212672"
+ CheckForOverflowUnderflow = "false"
+ ConfigurationOverrideFile = ""
+ DefineConstants = "TRACE"
+ DocumentationFile = ""
+ DebugSymbols = "false"
+ FileAlignment = "4096"
+ IncrementalBuild = "true"
+ Optimize = "true"
+ OutputPath = "bin\Release\"
+ RegisterForComInterop = "false"
+ RemoveIntegerChecks = "false"
+ TreatWarningsAsErrors = "false"
+ WarningLevel = "4"
+ />
+ </Settings>
+ <References>
+ <Reference
+ Name = "System"
+ AssemblyName = "System"
+ />
+ <Reference
+ Name = "System.Data"
+ AssemblyName = "System.Data"
+ />
+ <Reference
+ Name = "System.XML"
+ AssemblyName = "System.XML"
+ />
+ </References>
+ </Build>
+ <Files>
+ <Include>
+ <File
+ RelPath = "AssemblyInfo.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "assign.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "cil-codegen.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "class.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "constant.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "cs-parser.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "cs-tokenizer.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "decl.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "driver.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "enum.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "errors.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "expression.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "generator.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "gen-treedump.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "interface.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "literal.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "modifiers.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "namespace.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "parameter.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "parameterCollection.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "report.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "rootcontext.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "statement.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "statementCollection.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "tree.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "type.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ <File
+ RelPath = "typemanager.cs"
+ SubType = "Code"
+ BuildAction = "Compile"
+ />
+ </Include>
+ </Files>
+ </CSHARP>
+</VisualStudioProject>
+
diff --git a/mcs/mcs/compiler.csproj.user b/mcs/mcs/compiler.csproj.user
new file mode 100755
index 00000000000..0c76164add8
--- /dev/null
+++ b/mcs/mcs/compiler.csproj.user
@@ -0,0 +1,43 @@
+<VisualStudioProject>
+ <CSHARP>
+ <Build>
+ <Settings ReferencePath = "" >
+ <Config
+ Name = "Debug"
+ EnableASPDebugging = "false"
+ EnableASPXDebugging = "false"
+ EnableUnmanagedDebugging = "false"
+ EnableSQLServerDebugging = "false"
+ StartAction = "Project"
+ StartArguments = "i-undefined.cs"
+ StartPage = ""
+ StartProgram = ""
+ StartURL = ""
+ StartWorkingDirectory = "c:\mono\mcs\tests"
+ StartWithIE = "false"
+ />
+ <Config
+ Name = "Release"
+ EnableASPDebugging = "false"
+ EnableASPXDebugging = "false"
+ EnableUnmanagedDebugging = "false"
+ EnableSQLServerDebugging = "false"
+ StartAction = "Project"
+ StartArguments = ""
+ StartPage = ""
+ StartProgram = ""
+ StartURL = ""
+ StartWorkingDirectory = ""
+ StartWithIE = "false"
+ />
+ </Settings>
+ </Build>
+ <OtherProjectSettings
+ CopyProjectDestinationFolder = ""
+ CopyProjectUncPath = ""
+ CopyProjectOption = "0"
+ ProjectView = "ProjectFiles"
+ />
+ </CSHARP>
+</VisualStudioProject>
+
diff --git a/mcs/mcs/compiler.sln b/mcs/mcs/compiler.sln
new file mode 100755
index 00000000000..3b94d64a492
--- /dev/null
+++ b/mcs/mcs/compiler.sln
@@ -0,0 +1,21 @@
+Microsoft Visual Studio Solution File, Format Version 7.00
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "compiler", "compiler.csproj", "{896D1461-B76B-41C0-ABE6-ACA2BB4F7B5A}"
+EndProject
+Global
+ GlobalSection(SolutionConfiguration) = preSolution
+ ConfigName.0 = Debug
+ ConfigName.1 = Release
+ EndGlobalSection
+ GlobalSection(ProjectDependencies) = postSolution
+ EndGlobalSection
+ GlobalSection(ProjectConfiguration) = postSolution
+ {896D1461-B76B-41C0-ABE6-ACA2BB4F7B5A}.Debug.ActiveCfg = Debug|.NET
+ {896D1461-B76B-41C0-ABE6-ACA2BB4F7B5A}.Debug.Build.0 = Debug|.NET
+ {896D1461-B76B-41C0-ABE6-ACA2BB4F7B5A}.Release.ActiveCfg = Release|.NET
+ {896D1461-B76B-41C0-ABE6-ACA2BB4F7B5A}.Release.Build.0 = Release|.NET
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ EndGlobalSection
+ GlobalSection(ExtensibilityAddIns) = postSolution
+ EndGlobalSection
+EndGlobal
diff --git a/mcs/mcs/constant.cs b/mcs/mcs/constant.cs
index 8364173a241..40f4b72c098 100755
--- a/mcs/mcs/constant.cs
+++ b/mcs/mcs/constant.cs
@@ -1,11 +1,14 @@
namespace CIR {
using System;
+ using System.Reflection;
+ using System.Reflection.Emit;
public class Constant : Expression {
- public string name;
- public Expression expr;
- public TypeRef typeref;
+ string name;
+ Expression expr;
+ string type;
+ int mod_flags;
public const int AllowedModifiers =
Modifiers.NEW |
@@ -14,16 +17,12 @@ namespace CIR {
Modifiers.INTERNAL |
Modifiers.PRIVATE;
- public Constant (TypeRef typeref, string name, Expression expr)
+ public Constant (string type, string name, Expression expr, int mod_flags)
{
- this.typeref = typeref;
+ this.type = type;
this.name = name;
this.expr = expr;
- }
-
- public void Reduce ()
- {
-
+ this.mod_flags = Modifiers.Check (AllowedModifiers, mod_flags, Modifiers.PRIVATE);
}
public string Name {
@@ -32,9 +31,9 @@ namespace CIR {
}
}
- public Type ConstantType {
+ public string ConstantType {
get {
- return typeref.Type;
+ return type;
}
}
@@ -43,6 +42,51 @@ namespace CIR {
return expr;
}
}
+
+ public FieldAttributes FieldAttr {
+ get {
+ return FieldAttributes.Literal | Modifiers.FieldAttr (mod_flags) ;
+ }
+ }
+
+ // <summary>
+ // Defines the constant in the @parent
+ // </summary>
+ public void EmitConstant (RootContext rc, TypeContainer parent)
+ {
+ FieldBuilder fb;
+ TypeCode tc;
+ Type t;
+
+ t = rc.LookupType (parent, type);
+ if (t == null)
+ return;
+
+ tc = System.Type.GetTypeCode (t);
+
+ if ((tc == TypeCode.SByte) || (tc == TypeCode.Byte) ||
+ (tc == TypeCode.Int16) || (tc == TypeCode.UInt16) ||
+ (tc == TypeCode.Int32) || (tc == TypeCode.Int64) ||
+ (tc == TypeCode.UInt32) || (tc == TypeCode.UInt64)) {
+
+ } else if ((tc == TypeCode.Double) || (tc == TypeCode.Single)) {
+
+ } else if (tc == TypeCode.Char) {
+ } else if (tc == TypeCode.Decimal) {
+
+ } else if (t.IsSubclassOf (typeof (System.String))) {
+
+ } else if (t.IsSubclassOf (typeof (System.Enum))) {
+
+ } else {
+ rc.Report.Error (-3, "Constant type is not valid (only system types are allowed");
+ return;
+ }
+
+ fb = parent.TypeBuilder.DefineField (name, t, FieldAttr);
+
+ }
}
}
+
diff --git a/mcs/mcs/cs-parser.cs b/mcs/mcs/cs-parser.cs
deleted file mode 100755
index 90add9f4dd5..00000000000
--- a/mcs/mcs/cs-parser.cs
+++ /dev/null
@@ -1,5531 +0,0 @@
-// created by jay 0.7 (c) 1998 Axel.Schreiner@informatik.uni-osnabrueck.de
-
-#line 1 "cs-parser.jay"
-
-//
-// cs-parser.jay: The Parser for the C# compiler
-//
-// Author: Miguel de Icaza (miguel@gnu.org)
-//
-// Licensed under the terms of the GNU GPL
-//
-// (C) 2001 Ximian, Inc (http://www.ximian.com)
-//
-// TODO:
-// (1) Get rid of the *Collections.cs, that is an idea I took from System.CodeDOM
-// And come to think of it, it is not that great, it duplicates a lot of code
-// for something which is not really needed. We still have piles of typecasts
-// anwyays (due to the nature of the stack being a collection of Objects).
-//
-// (2) Figure out why error productions dont work. `type-declaration' is a
-// great spot to put an `error' because you can reproduce it with this input:
-// "public X { }"
-//
-// (3) Move Modifier checking from each object into the parser itself, that will
-// get rid of the global "error" symbol that we use now to report errors.
-// We still need to pass a pointer to the tree.ErrorHandler, but that is a
-// separate problem
-//
-using System.Text;
-using CSC;
-using System;
-
-namespace CSC
-{
- using System.Collections;
- using Compiler;
- using CSC;
- using CIR;
-
- /// <summary>
- /// The C# Parser
- /// </summary>
- public class CSharpParser : Parser {
- static int global_errors;
-
- Namespace current_namespace;
- TypeContainer current_container;
-
- // <summary>
- // Current block is used to add statements as we find
- // them.
- // </summary>
-
- Block current_block;
-
- // <summary>
- // Current interface is used by the various declaration
- // productions in the interface declaration to "add"
- // the interfaces as we find them.
- // </summary>
- Interface current_interface;
-
- // <summary>
- // This is used by the unary_expression code to resolve
- // a name against a parameter.
- // </summary>
- Parameters current_local_parameters;
-
- // <summary>
- // Using during property parsing to describe the implicit
- // value parameter that is passed to the "set" accesor
- // method
- // </summary>
- ParameterCollection implicit_value_parameters;
-
- // <summary>
- // Here we keep track of type references.
- // </summary>
- TypeRefManager type_references;
-#line 81 "-"
-
- /** simplified error message.
- @see <a href="#yyerror(java.lang.String, java.lang.String[])">yyerror</a>
- */
- public void yyerror (string message) {
- yyerror(message, null);
- }
-
- /** (syntax) error message.
- Can be overwritten to control message format.
- @param message text to be displayed.
- @param expected vector of acceptable tokens, if available.
- */
- public void yyerror (string message, string[] expected) {
- string res;
- if ((expected != null) && (expected.Length > 0)) {
- res = message+", expecting";
- for (int n = 0; n < expected.Length; ++ n)
- res += " "+expected[n];
- } else
- res = message;
- throw new Exception (res);
- }
-
- /** debugging support, requires the package jay.yydebug.
- Set to null to suppress debugging messages.
- */
- protected yydebug.yyDebug yydebug;
-
- protected static int yyFinal = 2;
- public static string [] yyRule = {
- "$accept : compilation_unit",
- "compilation_unit : opt_using_directives opt_attributes opt_namespace_member_declarations EOF",
- "using_directives : using_directive",
- "using_directives : using_directives using_directive",
- "using_directive : using_alias_directive",
- "using_directive : using_namespace_directive",
- "using_alias_directive : USING IDENTIFIER ASSIGN namespace_or_type_name SEMICOLON",
- "using_namespace_directive : USING namespace_name SEMICOLON",
- "namespace_declarations : namespace_declaration",
- "namespace_declarations : namespace_declarations namespace_declaration",
- "$$1 :",
- "namespace_declaration : NAMESPACE qualified_identifier $$1 namespace_body opt_semicolon",
- "opt_semicolon :",
- "opt_semicolon : SEMICOLON",
- "opt_comma :",
- "opt_comma : COMMA",
- "qualified_identifier : IDENTIFIER",
- "qualified_identifier : qualified_identifier DOT IDENTIFIER",
- "namespace_name : namespace_or_type_name",
- "namespace_body : OPEN_BRACE opt_using_directives opt_namespace_member_declarations CLOSE_BRACE",
- "opt_using_directives :",
- "opt_using_directives : using_directives",
- "opt_namespace_member_declarations :",
- "opt_namespace_member_declarations : namespace_member_declarations",
- "namespace_member_declarations : namespace_member_declaration",
- "namespace_member_declarations : namespace_member_declarations namespace_member_declaration",
- "namespace_member_declaration : type_declaration",
- "namespace_member_declaration : namespace_declaration",
- "type_declaration : class_declaration",
- "type_declaration : struct_declaration",
- "type_declaration : interface_declaration",
- "type_declaration : enum_declaration",
- "type_declaration : delegate_declaration",
- "opt_attributes :",
- "opt_attributes : attributes",
- "attributes : attribute_sections",
- "attribute_sections : attribute_section",
- "attribute_sections : attribute_sections attribute_section",
- "attribute_section : OPEN_BRACKET opt_attribute_target_specifier attribute_list CLOSE_BRACKET",
- "opt_attribute_target_specifier :",
- "opt_attribute_target_specifier : attribute_target_specifier",
- "attribute_target_specifier : attribute_target COLON",
- "attribute_target : IDENTIFIER",
- "attribute_target : EVENT",
- "attribute_target : RETURN",
- "attribute_list : attribute",
- "attribute_list : attribute_list COMMA attribute",
- "attribute : attribute_name",
- "attribute : opt_attribute_arguments",
- "attribute_name : type_name",
- "opt_attribute_arguments :",
- "opt_attribute_arguments : OPEN_PARENS attribute_arguments CLOSE_PARENS",
- "attribute_arguments : expression",
- "attribute_arguments : attribute_arguments COMMA expression",
- "opt_dimension_separators :",
- "opt_dimension_separators : dimension_separators",
- "dimension_separators : COMMA",
- "dimension_separators : dimension_separators COMMA",
- "class_body : OPEN_BRACE opt_class_member_declarations CLOSE_BRACE",
- "opt_class_member_declarations :",
- "opt_class_member_declarations : class_member_declarations",
- "class_member_declarations : class_member_declaration",
- "class_member_declarations : class_member_declarations class_member_declaration",
- "class_member_declaration : constant_declaration",
- "class_member_declaration : field_declaration",
- "class_member_declaration : method_declaration",
- "class_member_declaration : property_declaration",
- "class_member_declaration : event_declaration",
- "class_member_declaration : indexer_declaration",
- "class_member_declaration : operator_declaration",
- "class_member_declaration : constructor_declaration",
- "class_member_declaration : destructor_declaration",
- "class_member_declaration : type_declaration",
- "$$2 :",
- "struct_declaration : opt_attributes opt_modifiers STRUCT IDENTIFIER $$2 opt_struct_interfaces struct_body opt_semicolon",
- "opt_struct_interfaces :",
- "opt_struct_interfaces : struct_interfaces",
- "struct_interfaces : struct_interface",
- "struct_interfaces : struct_interfaces struct_interface",
- "struct_interface : COLON type_list",
- "struct_body : OPEN_BRACE opt_struct_member_declarations CLOSE_BRACE",
- "opt_struct_member_declarations :",
- "opt_struct_member_declarations : struct_member_declarations",
- "struct_member_declarations : struct_member_declaration",
- "struct_member_declarations : struct_member_declarations struct_member_declaration",
- "struct_member_declaration : constant_declaration",
- "struct_member_declaration : field_declaration",
- "struct_member_declaration : method_declaration",
- "struct_member_declaration : property_declaration",
- "struct_member_declaration : event_declaration",
- "struct_member_declaration : indexer_declaration",
- "struct_member_declaration : operator_declaration",
- "struct_member_declaration : constructor_declaration",
- "struct_member_declaration : type_declaration",
- "constant_declaration : opt_attributes opt_modifiers CONST type constant_declarators SEMICOLON",
- "constant_declarators : constant_declarator",
- "constant_declarators : constant_declarators COMMA constant_declarator",
- "constant_declarator : IDENTIFIER ASSIGN constant_expression",
- "field_declaration : opt_attributes opt_modifiers type variable_declarators SEMICOLON",
- "variable_declarators : variable_declarator",
- "variable_declarators : variable_declarators COMMA variable_declarator",
- "variable_declarator : IDENTIFIER ASSIGN variable_initializer",
- "variable_declarator : IDENTIFIER",
- "variable_initializer : expression",
- "variable_initializer : array_initializer",
- "method_declaration : method_header method_body",
- "method_header : opt_attributes opt_modifiers type member_name OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS",
- "method_header : opt_attributes opt_modifiers VOID member_name OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS",
- "method_body : block",
- "method_body : SEMICOLON",
- "opt_formal_parameter_list :",
- "opt_formal_parameter_list : formal_parameter_list",
- "formal_parameter_list : fixed_parameters",
- "formal_parameter_list : fixed_parameters COMMA parameter_array",
- "formal_parameter_list : parameter_array",
- "fixed_parameters : fixed_parameter",
- "fixed_parameters : fixed_parameters COMMA fixed_parameter",
- "fixed_parameter : opt_attributes opt_parameter_modifier type IDENTIFIER",
- "opt_parameter_modifier :",
- "opt_parameter_modifier : parameter_modifier",
- "parameter_modifier : REF",
- "parameter_modifier : OUT",
- "parameter_array : opt_attributes PARAMS type IDENTIFIER",
- "member_name : IDENTIFIER",
- "member_name : interface_type DOT IDENTIFIER",
- "$$3 :",
- "$$4 :",
- "property_declaration : opt_attributes opt_modifiers type member_name OPEN_BRACE $$3 accessor_declarations $$4 CLOSE_BRACE",
- "accessor_declarations : get_accessor_declaration opt_set_accessor_declaration",
- "accessor_declarations : set_accessor_declaration opt_get_accessor_declaration",
- "opt_get_accessor_declaration :",
- "opt_get_accessor_declaration : get_accessor_declaration",
- "opt_set_accessor_declaration :",
- "opt_set_accessor_declaration : set_accessor_declaration",
- "get_accessor_declaration : opt_attributes GET accessor_body",
- "$$5 :",
- "set_accessor_declaration : opt_attributes SET $$5 accessor_body",
- "accessor_body : block",
- "accessor_body : SEMICOLON",
- "$$6 :",
- "interface_declaration : opt_attributes opt_modifiers INTERFACE IDENTIFIER $$6 opt_interface_base interface_body",
- "opt_interface_base :",
- "opt_interface_base : interface_base",
- "interface_base : COLON interface_type_list",
- "interface_type_list : interface_type",
- "interface_type_list : interface_type_list COMMA interface_type",
- "interface_body : OPEN_BRACE opt_interface_member_declarations CLOSE_BRACE",
- "opt_interface_member_declarations :",
- "opt_interface_member_declarations : interface_member_declarations",
- "interface_member_declarations : interface_member_declaration",
- "interface_member_declarations : interface_member_declarations interface_member_declaration",
- "interface_member_declaration : interface_method_declaration",
- "interface_member_declaration : interface_property_declaration",
- "interface_member_declaration : interface_event_declaration",
- "interface_member_declaration : interface_indexer_declaration",
- "opt_new :",
- "opt_new : NEW",
- "interface_method_declaration : opt_attributes opt_new type IDENTIFIER OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS SEMICOLON",
- "interface_method_declaration : opt_attributes opt_new VOID IDENTIFIER OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS SEMICOLON",
- "$$7 :",
- "$$8 :",
- "interface_property_declaration : opt_attributes opt_new type IDENTIFIER OPEN_BRACE $$7 interface_accesors $$8 CLOSE_BRACE",
- "interface_accesors : opt_attributes GET SEMICOLON",
- "interface_accesors : opt_attributes SET SEMICOLON",
- "interface_accesors : opt_attributes GET SEMICOLON opt_attributes SET SEMICOLON",
- "interface_accesors : opt_attributes SET SEMICOLON opt_attributes GET SEMICOLON",
- "interface_event_declaration : opt_attributes opt_new EVENT type IDENTIFIER SEMICOLON",
- "$$9 :",
- "$$10 :",
- "interface_indexer_declaration : opt_attributes opt_new type THIS OPEN_BRACKET formal_parameter_list CLOSE_BRACKET OPEN_BRACE $$9 interface_accesors $$10 CLOSE_BRACE",
- "operator_declaration : opt_attributes opt_modifiers operator_declarator block",
- "operator_declarator : type OPERATOR overloadable_operator OPEN_PARENS type IDENTIFIER CLOSE_PARENS",
- "operator_declarator : type OPERATOR overloadable_operator OPEN_PARENS type IDENTIFIER COMMA type IDENTIFIER CLOSE_PARENS",
- "operator_declarator : conversion_operator_declarator",
- "overloadable_operator : BANG",
- "overloadable_operator : TILDE",
- "overloadable_operator : OP_INC",
- "overloadable_operator : OP_DEC",
- "overloadable_operator : TRUE",
- "overloadable_operator : FALSE",
- "overloadable_operator : PLUS",
- "overloadable_operator : MINUS",
- "overloadable_operator : STAR",
- "overloadable_operator : DIV",
- "overloadable_operator : PERCENT",
- "overloadable_operator : BITWISE_AND",
- "overloadable_operator : BITWISE_OR",
- "overloadable_operator : CARRET",
- "overloadable_operator : OP_SHIFT_LEFT",
- "overloadable_operator : OP_SHIFT_RIGHT",
- "overloadable_operator : OP_EQ",
- "overloadable_operator : OP_NE",
- "overloadable_operator : OP_GT",
- "overloadable_operator : OP_LT",
- "overloadable_operator : OP_GE",
- "overloadable_operator : OP_LE",
- "conversion_operator_declarator : IMPLICIT OPERATOR type OPEN_PARENS type IDENTIFIER CLOSE_PARENS",
- "conversion_operator_declarator : EXPLICIT OPERATOR type OPEN_PARENS type IDENTIFIER CLOSE_PARENS",
- "constructor_declaration : opt_attributes opt_modifiers constructor_declarator block",
- "constructor_declarator : IDENTIFIER OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS opt_constructor_initializer",
- "opt_constructor_initializer :",
- "opt_constructor_initializer : constructor_initializer",
- "constructor_initializer : COLON BASE OPEN_PARENS opt_argument_list CLOSE_PARENS",
- "constructor_initializer : COLON THIS OPEN_PARENS opt_argument_list CLOSE_PARENS",
- "destructor_declaration : opt_attributes TILDE IDENTIFIER OPEN_PARENS CLOSE_PARENS block",
- "event_declaration : opt_attributes opt_modifiers EVENT type variable_declarators SEMICOLON",
- "event_declaration : opt_attributes opt_modifiers EVENT type member_name OPEN_BRACE event_accesor_declarations CLOSE_BRACE SEMICOLON",
- "event_accesor_declarations : add_accessor_declaration remove_accessor_declaration",
- "event_accesor_declarations : remove_accessor_declaration add_accessor_declaration",
- "add_accessor_declaration : opt_attributes ADD block",
- "remove_accessor_declaration : opt_attributes REMOVE block",
- "indexer_declaration : opt_attributes opt_modifiers indexer_declarator OPEN_BRACE accessor_declarations CLOSE_BRACE",
- "indexer_declarator : type THIS OPEN_BRACKET formal_parameter_list CLOSE_BRACKET",
- "indexer_declarator : type interface_type DOT THIS OPEN_BRACKET formal_parameter_list CLOSE_BRACKET",
- "enum_declaration : opt_attributes opt_modifiers ENUM IDENTIFIER opt_enum_base enum_body opt_semicolon",
- "opt_enum_base :",
- "opt_enum_base : COLON integral_type",
- "enum_body : OPEN_BRACE opt_enum_member_declarations CLOSE_BRACE",
- "enum_body : OPEN_BRACE enum_member_declarations COMMA CLOSE_BRACE",
- "opt_enum_member_declarations :",
- "opt_enum_member_declarations : enum_member_declarations",
- "enum_member_declarations : enum_member_declaration",
- "enum_member_declarations : enum_member_declarations COMMA enum_member_declaration",
- "enum_member_declaration : opt_attributes IDENTIFIER",
- "enum_member_declaration : opt_attributes IDENTIFIER ASSIGN expression",
- "delegate_declaration : opt_attributes opt_modifiers DELEGATE type IDENTIFIER OPEN_PARENS formal_parameter_list CLOSE_PARENS SEMICOLON",
- "type_name : namespace_or_type_name",
- "namespace_or_type_name : qualified_identifier",
- "type : type_name",
- "type : builtin_types",
- "type : array_type",
- "type_list : type",
- "type_list : type_list type",
- "builtin_types : OBJECT",
- "builtin_types : STRING",
- "builtin_types : BOOL",
- "builtin_types : DECIMAL",
- "builtin_types : FLOAT",
- "builtin_types : DOUBLE",
- "builtin_types : integral_type",
- "integral_type : SBYTE",
- "integral_type : BYTE",
- "integral_type : SHORT",
- "integral_type : USHORT",
- "integral_type : INT",
- "integral_type : UINT",
- "integral_type : LONG",
- "integral_type : ULONG",
- "integral_type : CHAR",
- "interface_type : type_name",
- "array_type : type rank_specifiers",
- "primary_expression : literal",
- "primary_expression : qualified_identifier",
- "primary_expression : parenthesized_expression",
- "primary_expression : member_access",
- "primary_expression : invocation_expression",
- "primary_expression : element_access",
- "primary_expression : this_access",
- "primary_expression : base_access",
- "primary_expression : post_increment_expression",
- "primary_expression : post_decrement_expression",
- "primary_expression : new_expression",
- "primary_expression : typeof_expression",
- "primary_expression : sizeof_expression",
- "primary_expression : checked_expression",
- "primary_expression : unchecked_expression",
- "literal : boolean_literal",
- "literal : integer_literal",
- "literal : real_literal",
- "literal : LITERAL_CHARACTER",
- "literal : LITERAL_STRING",
- "literal : NULL",
- "real_literal : LITERAL_FLOAT",
- "real_literal : LITERAL_DOUBLE",
- "real_literal : LITERAL_DECIMAL",
- "integer_literal : LITERAL_INTEGER",
- "boolean_literal : TRUE",
- "boolean_literal : FALSE",
- "parenthesized_expression : OPEN_PARENS expression CLOSE_PARENS",
- "member_access : primary_expression DOT IDENTIFIER",
- "member_access : predefined_type DOT IDENTIFIER",
- "predefined_type : builtin_types",
- "invocation_expression : primary_expression OPEN_PARENS opt_argument_list CLOSE_PARENS",
- "opt_argument_list :",
- "opt_argument_list : argument_list",
- "argument_list : argument",
- "argument_list : argument_list COMMA argument",
- "argument : expression",
- "argument : REF variable_reference",
- "argument : OUT variable_reference",
- "variable_reference : expression",
- "element_access : primary_expression OPEN_BRACKET expression_list CLOSE_BRACKET",
- "expression_list : expression",
- "expression_list : expression_list COMMA expression",
- "this_access : THIS",
- "base_access : BASE DOT IDENTIFIER",
- "base_access : BASE OPEN_BRACKET expression_list CLOSE_BRACKET",
- "post_increment_expression : primary_expression OP_INC",
- "post_decrement_expression : primary_expression OP_DEC",
- "new_expression : object_or_delegate_creation_expression",
- "new_expression : array_creation_expression",
- "object_or_delegate_creation_expression : NEW type OPEN_PARENS opt_argument_list CLOSE_PARENS",
- "array_creation_expression : NEW type OPEN_BRACKET expression_list CLOSE_BRACKET opt_rank_specifier opt_array_initializer",
- "opt_rank_specifier :",
- "opt_rank_specifier : rank_specifiers",
- "rank_specifiers : rank_specifier",
- "rank_specifiers : rank_specifiers rank_specifier",
- "rank_specifier : OPEN_BRACKET opt_dim_separators CLOSE_BRACKET",
- "opt_dim_separators :",
- "opt_dim_separators : dim_separators",
- "dim_separators : COMMA",
- "dim_separators : dim_separators COMMA",
- "opt_array_initializer :",
- "opt_array_initializer : array_initializer",
- "array_initializer : OPEN_BRACE CLOSE_BRACE",
- "array_initializer : OPEN_BRACE variable_initializer_list CLOSE_BRACE",
- "array_initializer : OPEN_BRACE variable_initializer_list COMMA CLOSE_BRACE",
- "variable_initializer_list : variable_initializer",
- "variable_initializer_list : variable_initializer_list COMMA variable_initializer",
- "typeof_expression : TYPEOF OPEN_PARENS type CLOSE_PARENS",
- "sizeof_expression : SIZEOF OPEN_PARENS type CLOSE_PARENS",
- "checked_expression : CHECKED OPEN_PARENS expression CLOSE_PARENS",
- "unchecked_expression : UNCHECKED OPEN_PARENS expression CLOSE_PARENS",
- "unary_expression : primary_expression",
- "unary_expression : PLUS unary_expression",
- "unary_expression : MINUS unary_expression",
- "unary_expression : BANG unary_expression",
- "unary_expression : TILDE unary_expression",
- "unary_expression : STAR unary_expression",
- "unary_expression : BITWISE_AND unary_expression",
- "unary_expression : pre_increment_expression",
- "unary_expression : pre_decrement_expression",
- "unary_expression : cast_expression",
- "pre_increment_expression : OP_INC unary_expression",
- "pre_decrement_expression : OP_DEC unary_expression",
- "cast_expression : OPEN_PARENS qualified_identifier CLOSE_PARENS unary_expression",
- "cast_expression : OPEN_PARENS builtin_types CLOSE_PARENS unary_expression",
- "multiplicative_expression : unary_expression",
- "multiplicative_expression : multiplicative_expression STAR unary_expression",
- "multiplicative_expression : multiplicative_expression DIV unary_expression",
- "multiplicative_expression : multiplicative_expression PERCENT unary_expression",
- "additive_expression : multiplicative_expression",
- "additive_expression : additive_expression PLUS multiplicative_expression",
- "additive_expression : additive_expression MINUS multiplicative_expression",
- "shift_expression : additive_expression",
- "shift_expression : shift_expression OP_SHIFT_LEFT additive_expression",
- "shift_expression : shift_expression OP_SHIFT_RIGHT additive_expression",
- "relational_expression : shift_expression",
- "relational_expression : relational_expression OP_LT shift_expression",
- "relational_expression : relational_expression OP_GT shift_expression",
- "relational_expression : relational_expression OP_LE shift_expression",
- "relational_expression : relational_expression OP_GE shift_expression",
- "relational_expression : relational_expression IS type",
- "relational_expression : relational_expression AS type",
- "equality_expression : relational_expression",
- "equality_expression : equality_expression OP_EQ relational_expression",
- "equality_expression : equality_expression OP_NE relational_expression",
- "and_expression : equality_expression",
- "and_expression : and_expression BITWISE_AND equality_expression",
- "exclusive_or_expression : and_expression",
- "exclusive_or_expression : exclusive_or_expression CARRET and_expression",
- "inclusive_or_expression : exclusive_or_expression",
- "inclusive_or_expression : inclusive_or_expression BITWISE_OR exclusive_or_expression",
- "conditional_and_expression : inclusive_or_expression",
- "conditional_and_expression : conditional_and_expression OP_AND inclusive_or_expression",
- "conditional_or_expression : conditional_and_expression",
- "conditional_or_expression : conditional_or_expression OP_OR conditional_and_expression",
- "conditional_expression : conditional_or_expression",
- "conditional_expression : conditional_or_expression INTERR expression COLON expression",
- "assignment_expression : unary_expression ASSIGN expression",
- "assignment_expression : unary_expression OP_MULT_ASSIGN expression",
- "assignment_expression : unary_expression OP_DIV_ASSIGN expression",
- "assignment_expression : unary_expression OP_MOD_ASSIGN expression",
- "assignment_expression : unary_expression OP_ADD_ASSIGN expression",
- "assignment_expression : unary_expression OP_SUB_ASSIGN expression",
- "assignment_expression : unary_expression OP_SHIFT_LEFT_ASSIGN expression",
- "assignment_expression : unary_expression OP_SHIFT_RIGHT_ASSIGN expression",
- "assignment_expression : unary_expression OP_AND_ASSIGN expression",
- "assignment_expression : unary_expression OP_OR_ASSIGN expression",
- "assignment_expression : unary_expression OP_XOR_ASSIGN expression",
- "expression : conditional_expression",
- "expression : assignment_expression",
- "constant_expression : expression",
- "boolean_expression : expression",
- "$$11 :",
- "class_declaration : opt_attributes opt_modifiers CLASS IDENTIFIER $$11 opt_class_base class_body opt_semicolon",
- "opt_modifiers :",
- "opt_modifiers : modifiers",
- "modifiers : modifier",
- "modifiers : modifiers modifier",
- "modifier : NEW",
- "modifier : PUBLIC",
- "modifier : PROTECTED",
- "modifier : INTERNAL",
- "modifier : PRIVATE",
- "modifier : ABSTRACT",
- "modifier : SEALED",
- "modifier : STATIC",
- "modifier : READONLY",
- "modifier : VIRTUAL",
- "modifier : OVERRIDE",
- "modifier : EXTERN",
- "opt_class_base :",
- "opt_class_base : class_base",
- "class_base : COLON type_list",
- "$$12 :",
- "block : OPEN_BRACE $$12 opt_statement_list CLOSE_BRACE",
- "opt_statement_list :",
- "opt_statement_list : statement_list",
- "statement_list : statement",
- "statement_list : statement_list statement",
- "statement : declaration_statement",
- "statement : embedded_statement",
- "statement : labeled_statement",
- "embedded_statement : block",
- "embedded_statement : empty_statement",
- "embedded_statement : expression_statement",
- "embedded_statement : selection_statement",
- "embedded_statement : iteration_statement",
- "embedded_statement : jump_statement",
- "embedded_statement : try_statement",
- "embedded_statement : checked_statement",
- "embedded_statement : unchecked_statement",
- "embedded_statement : lock_statement",
- "embedded_statement : using_statement",
- "empty_statement : SEMICOLON",
- "labeled_statement : IDENTIFIER COLON statement",
- "declaration_statement : local_variable_declaration SEMICOLON",
- "declaration_statement : local_constant_declaration SEMICOLON",
- "local_variable_type : primary_expression type_suffixes",
- "local_variable_type : builtin_types type_suffixes",
- "local_variable_type : VOID type_suffixes",
- "type_suffixes :",
- "type_suffixes : type_suffix_list",
- "type_suffix_list : type_suffix",
- "type_suffix_list : type_suffix_list type_suffix",
- "type_suffix : OPEN_BRACKET opt_dim_separators CLOSE_BRACKET",
- "local_variable_declaration : local_variable_type variable_declarators",
- "local_constant_declaration : CONST type constant_declarator",
- "expression_statement : statement_expression SEMICOLON",
- "statement_expression : invocation_expression",
- "statement_expression : object_creation_expression",
- "statement_expression : assignment_expression",
- "statement_expression : post_increment_expression",
- "statement_expression : post_decrement_expression",
- "statement_expression : pre_increment_expression",
- "statement_expression : pre_decrement_expression",
- "object_creation_expression : object_or_delegate_creation_expression",
- "selection_statement : if_statement",
- "selection_statement : switch_statement",
- "if_statement : IF OPEN_PARENS boolean_expression CLOSE_PARENS embedded_statement",
- "if_statement : IF OPEN_PARENS boolean_expression CLOSE_PARENS embedded_statement ELSE embedded_statement",
- "switch_statement : SWITCH OPEN_PARENS expression CLOSE_PARENS switch_block",
- "switch_block : OPEN_BRACE opt_switch_sections CLOSE_BRACE",
- "opt_switch_sections :",
- "opt_switch_sections : switch_sections",
- "switch_sections : switch_section",
- "switch_sections : switch_sections switch_section",
- "$$13 :",
- "switch_section : switch_labels $$13 statement_list",
- "switch_labels : switch_label",
- "switch_labels : switch_labels switch_label",
- "switch_label : CASE constant_expression COLON",
- "switch_label : DEFAULT COLON",
- "iteration_statement : while_statement",
- "iteration_statement : do_statement",
- "iteration_statement : for_statement",
- "iteration_statement : foreach_statement",
- "while_statement : WHILE OPEN_PARENS boolean_expression CLOSE_PARENS embedded_statement",
- "do_statement : DO embedded_statement WHILE OPEN_PARENS boolean_expression CLOSE_PARENS SEMICOLON",
- "for_statement : FOR OPEN_PARENS opt_for_initializer SEMICOLON opt_for_condition SEMICOLON opt_for_iterator CLOSE_PARENS embedded_statement",
- "opt_for_initializer :",
- "opt_for_initializer : for_initializer",
- "for_initializer : local_variable_declaration",
- "for_initializer : statement_expression_list",
- "opt_for_condition :",
- "opt_for_condition : boolean_expression",
- "opt_for_iterator :",
- "opt_for_iterator : for_iterator",
- "for_iterator : statement_expression_list",
- "statement_expression_list : statement_expression",
- "statement_expression_list : statement_expression_list COMMA statement_expression",
- "foreach_statement : FOREACH OPEN_PARENS type IDENTIFIER IN expression CLOSE_PARENS embedded_statement",
- "jump_statement : break_statement",
- "jump_statement : continue_statement",
- "jump_statement : goto_statement",
- "jump_statement : return_statement",
- "jump_statement : throw_statement",
- "break_statement : BREAK SEMICOLON",
- "continue_statement : CONTINUE SEMICOLON",
- "goto_statement : GOTO IDENTIFIER SEMICOLON",
- "goto_statement : GOTO CASE constant_expression SEMICOLON",
- "goto_statement : GOTO DEFAULT SEMICOLON",
- "return_statement : RETURN opt_expression SEMICOLON",
- "throw_statement : THROW opt_expression SEMICOLON",
- "opt_expression :",
- "opt_expression : expression",
- "try_statement : TRY block catch_clauses",
- "try_statement : TRY block finalize_clause",
- "try_statement : TRY block catch_clauses finalize_clause",
- "catch_clauses : specific_catch_clauses opt_general_catch_clause",
- "catch_clauses : opt_specific_catch_clauses general_catch_clause",
- "opt_general_catch_clause :",
- "opt_general_catch_clause : general_catch_clause",
- "opt_specific_catch_clauses :",
- "opt_specific_catch_clauses : specific_catch_clauses",
- "specific_catch_clauses : specific_catch_clause",
- "specific_catch_clauses : specific_catch_clauses specific_catch_clause",
- "specific_catch_clause : CATCH OPEN_PARENS type opt_identifier CLOSE_PARENS block",
- "opt_identifier :",
- "opt_identifier : IDENTIFIER",
- "general_catch_clause : CATCH block",
- "finalize_clause : FINALLY block",
- "checked_statement : CHECKED block",
- "unchecked_statement : UNCHECKED block",
- "lock_statement : LOCK OPEN_PARENS expression CLOSE_PARENS embedded_statement",
- "using_statement : USING OPEN_PARENS resource_acquisition CLOSE_PARENS embedded_statement",
- "resource_acquisition : local_variable_declaration expression",
- };
- protected static string [] yyName = {
- "end-of-file",null,null,null,null,null,null,null,null,null,null,null,
- null,null,null,null,null,null,null,null,null,null,null,null,null,null,
- null,null,null,null,null,null,null,"'!'",null,null,null,"'%'","'&'",
- null,"'('","')'","'*'","'+'","','","'-'","'.'","'/'",null,null,null,
- null,null,null,null,null,null,null,"':'","';'","'<'","'='","'>'",
- "'?'",null,null,null,null,null,null,null,null,null,null,null,null,
- null,null,null,null,null,null,null,null,null,null,null,null,null,null,
- null,"'['",null,"']'","'^'",null,null,null,null,null,null,null,null,
- null,null,null,null,null,null,null,null,null,null,null,null,null,null,
- null,null,null,null,null,null,"'{'","'|'","'}'","'~'",null,null,null,
- null,null,null,null,null,null,null,null,null,null,null,null,null,null,
- null,null,null,null,null,null,null,null,null,null,null,null,null,null,
- null,null,null,null,null,null,null,null,null,null,null,null,null,null,
- null,null,null,null,null,null,null,null,null,null,null,null,null,null,
- null,null,null,null,null,null,null,null,null,null,null,null,null,null,
- null,null,null,null,null,null,null,null,null,null,null,null,null,null,
- null,null,null,null,null,null,null,null,null,null,null,null,null,null,
- null,null,null,null,null,null,null,null,null,null,null,null,null,null,
- null,null,null,null,null,null,null,null,null,null,null,null,null,null,
- null,"EOF","NONE","ERROR","ABSTRACT","AS","ADD","BASE","BOOL","BREAK",
- "BYTE","CASE","CATCH","CHAR","CHECKED","CLASS","CONST","CONTINUE",
- "DECIMAL","DEFAULT","DELEGATE","DO","DOUBLE","ELSE","ENUM","EVENT",
- "EXPLICIT","EXTERN","FALSE","FINALLY","FIXED","FLOAT","FOR","FOREACH",
- "GOTO","IF","IMPLICIT","IN","INT","INTERFACE","INTERNAL","IS","LOCK",
- "LONG","NAMESPACE","NEW","NULL","OBJECT","OPERATOR","OUT","OVERRIDE",
- "PARAMS","PRIVATE","PROTECTED","PUBLIC","READONLY","REF","RETURN",
- "REMOVE","SBYTE","SEALED","SHORT","SIZEOF","STATIC","STRING","STRUCT",
- "SWITCH","THIS","THROW","TRUE","TRY","TYPEOF","UINT","ULONG",
- "UNCHECKED","UNSAFE","USHORT","USING","VIRTUAL","VOID","WHILE","GET",
- "\"get\"","SET","\"set\"","OPEN_BRACE","CLOSE_BRACE","OPEN_BRACKET",
- "CLOSE_BRACKET","OPEN_PARENS","CLOSE_PARENS","DOT","COMMA","COLON",
- "SEMICOLON","TILDE","PLUS","MINUS","BANG","ASSIGN","OP_LT","OP_GT",
- "BITWISE_AND","BITWISE_OR","STAR","PERCENT","DIV","CARRET","INTERR",
- "OP_INC","\"++\"","OP_DEC","\"--\"","OP_SHIFT_LEFT","\"<<\"",
- "OP_SHIFT_RIGHT","\">>\"","OP_LE","\"<=\"","OP_GE","\">=\"","OP_EQ",
- "\"==\"","OP_NE","\"!=\"","OP_AND","\"&&\"","OP_OR","\"||\"",
- "OP_MULT_ASSIGN","\"*=\"","OP_DIV_ASSIGN","\"/=\"","OP_MOD_ASSIGN",
- "\"%=\"","OP_ADD_ASSIGN","\"+=\"","OP_SUB_ASSIGN","\"-=\"",
- "OP_SHIFT_LEFT_ASSIGN","\"<<=\"","OP_SHIFT_RIGHT_ASSIGN","\">>=\"",
- "OP_AND_ASSIGN","\"&=\"","OP_XOR_ASSIGN","\"^=\"","OP_OR_ASSIGN",
- "\"|=\"","OP_PTR","\"->\"","LITERAL_INTEGER","\"int literal\"",
- "LITERAL_FLOAT","\"float literal\"","LITERAL_DOUBLE",
- "\"double literal\"","LITERAL_DECIMAL","\"decimal literal\"",
- "LITERAL_CHARACTER","\"character literal\"","LITERAL_STRING",
- "\"string literal\"","IDENTIFIER",
- };
-
- /** index-checked interface to yyName[].
- @param token single character or %token value.
- @return token name or [illegal] or [unknown].
- */
- public static string yyname (int token) {
- if ((token < 0) || (token > yyName.Length)) return "[illegal]";
- string name;
- if ((name = yyName[token]) != null) return name;
- return "[unknown]";
- }
-
- /** computes list of expected tokens on error by tracing the tables.
- @param state for which to compute the list.
- @return list of token names.
- */
- protected string[] yyExpecting (int state) {
- int token, n, len = 0;
- bool[] ok = new bool[yyName.Length];
-
- if ((n = yySindex[state]) != 0)
- for (token = n < 0 ? -n : 0;
- (token < yyName.Length) && (n+token < yyTable.Length); ++ token)
- if (yyCheck[n+token] == token && !ok[token] && yyName[token] != null) {
- ++ len;
- ok[token] = true;
- }
- if ((n = yyRindex[state]) != 0)
- for (token = n < 0 ? -n : 0;
- (token < yyName.Length) && (n+token < yyTable.Length); ++ token)
- if (yyCheck[n+token] == token && !ok[token] && yyName[token] != null) {
- ++ len;
- ok[token] = true;
- }
-
- string [] result = new string[len];
- for (n = token = 0; n < len; ++ token)
- if (ok[token]) result[n++] = yyName[token];
- return result;
- }
-
- /** the generated parser, with debugging messages.
- Maintains a state and a value stack, currently with fixed maximum size.
- @param yyLex scanner.
- @param yydebug debug message writer implementing yyDebug, or null.
- @return result of the last reduction, if any.
- @throws yyException on irrecoverable parse error.
- */
- public Object yyparse (yyParser.yyInput yyLex, Object yydebug)
- {
- this.yydebug = (yydebug.yyDebug)yydebug;
- return yyparse(yyLex);
- }
-
- /** initial size and increment of the state/value stack [default 256].
- This is not final so that it can be overwritten outside of invocations
- of yyparse().
- */
- protected int yyMax;
-
- /** executed at the beginning of a reduce action.
- Used as $$ = yyDefault($1), prior to the user-specified action, if any.
- Can be overwritten to provide deep copy, etc.
- @param first value for $1, or null.
- @return first.
- */
- protected Object yyDefault (Object first) {
- return first;
- }
-
- /** the generated parser.
- Maintains a state and a value stack, currently with fixed maximum size.
- @param yyLex scanner.
- @return result of the last reduction, if any.
- @throws yyException on irrecoverable parse error.
- */
- public Object yyparse (yyParser.yyInput yyLex)
- {
- if (yyMax <= 0) yyMax = 256; // initial size
- int yyState = 0; // state stack ptr
- int [] yyStates = new int[yyMax]; // state stack
- Object yyVal = null; // value stack ptr
- Object [] yyVals = new Object[yyMax]; // value stack
- int yyToken = -1; // current input
- int yyErrorFlag = 0; // #tks to shift
-
- int yyTop = 0;
- goto skip;
- yyLoop:
- yyTop++;
- skip:
- for (;; ++ yyTop) {
- if (yyTop >= yyStates.Length) { // dynamically increase
- int[] i = new int[yyStates.Length+yyMax];
- System.Array.Copy(yyStates, i, 0);
- yyStates = i;
- Object[] o = new Object[yyVals.Length+yyMax];
- System.Array.Copy(yyVals, o, 0);
- yyVals = o;
- }
- yyStates[yyTop] = yyState;
- yyVals[yyTop] = yyVal;
- if (yydebug != null) yydebug.push(yyState, yyVal);
-
- yyDiscarded: for (;;) { // discarding a token does not change stack
- int yyN;
- if ((yyN = yyDefRed[yyState]) == 0) { // else [default] reduce (yyN)
- if (yyToken < 0) {
- yyToken = yyLex.advance() ? yyLex.token() : 0;
- if (yydebug != null)
- yydebug.lex(yyState, yyToken, yyname(yyToken), yyLex.value());
- }
- if ((yyN = yySindex[yyState]) != 0 && ((yyN += yyToken) >= 0)
- && (yyN < yyTable.Length) && (yyCheck[yyN] == yyToken)) {
- if (yydebug != null)
- yydebug.shift(yyState, yyTable[yyN], yyErrorFlag-1);
- yyState = yyTable[yyN]; // shift to yyN
- yyVal = yyLex.value();
- yyToken = -1;
- if (yyErrorFlag > 0) -- yyErrorFlag;
- goto yyLoop;
- }
- if ((yyN = yyRindex[yyState]) != 0 && (yyN += yyToken) >= 0
- && yyN < yyTable.Length && yyCheck[yyN] == yyToken)
- yyN = yyTable[yyN]; // reduce (yyN)
- else
- switch (yyErrorFlag) {
-
- case 0:
- yyerror("syntax error", yyExpecting(yyState));
- if (yydebug != null) yydebug.error("syntax error");
- goto case 1;
- case 1: case 2:
- yyErrorFlag = 3;
- do {
- if ((yyN = yySindex[yyStates[yyTop]]) != 0
- && (yyN += Token.yyErrorCode) >= 0 && yyN < yyTable.Length
- && yyCheck[yyN] == Token.yyErrorCode) {
- if (yydebug != null)
- yydebug.shift(yyStates[yyTop], yyTable[yyN], 3);
- yyState = yyTable[yyN];
- yyVal = yyLex.value();
- goto yyLoop;
- }
- if (yydebug != null) yydebug.pop(yyStates[yyTop]);
- } while (-- yyTop >= 0);
- if (yydebug != null) yydebug.reject();
- throw new yyParser.yyException("irrecoverable syntax error");
-
- case 3:
- if (yyToken == 0) {
- if (yydebug != null) yydebug.reject();
- throw new yyParser.yyException("irrecoverable syntax error at end-of-file");
- }
- if (yydebug != null)
- yydebug.discard(yyState, yyToken, yyname(yyToken),
- yyLex.value());
- yyToken = -1;
- goto yyDiscarded; // leave stack alone
- }
- }
- int yyV = yyTop + 1-yyLen[yyN];
- if (yydebug != null)
- yydebug.reduce(yyState, yyStates[yyV-1], yyN, yyRule[yyN], yyLen[yyN]);
- yyVal = yyDefault(yyV > yyTop ? null : yyVals[yyV]);
- switch (yyN) {
-case 1:
-#line 240 "cs-parser.jay"
- {
- /* At some point check that using only comes *before* any namespaces */
- }
- break;
-case 6:
-#line 257 "cs-parser.jay"
- {
- }
- break;
-case 7:
-#line 263 "cs-parser.jay"
- {
- current_namespace.Using ((string) yyVals[-1+yyTop]);
- }
- break;
-case 10:
-#line 274 "cs-parser.jay"
- {
- current_namespace = new Namespace (current_namespace, (string) yyVals[0+yyTop]);
- }
- break;
-case 11:
-#line 278 "cs-parser.jay"
- {
- current_namespace = current_namespace.Parent;
- }
- break;
-case 17:
-#line 295 "cs-parser.jay"
- {
- yyVal = ((yyVals[-2+yyTop]).ToString ()) + "." + (yyVals[0+yyTop].ToString ()); }
- break;
-case 19:
-#line 308 "cs-parser.jay"
- {
- }
- break;
-case 26:
-#line 329 "cs-parser.jay"
- {
- int mod_flags = 0;
- string name = "";
-
- if (yyVals[0+yyTop] is Class){
- Class c = (Class) yyVals[0+yyTop];
- mod_flags = c.ModFlags;
- name = c.Name;
- } else if (yyVals[0+yyTop] is Struct){
- Struct s = (Struct) yyVals[0+yyTop];
- mod_flags = s.ModFlags;
- name = s.Name;
- } else
- break;
-
- /* */
- /* We remove this error until we can */
- /*if ((mod_flags & (Modifiers.PRIVATE|Modifiers.PROTECTED)) != 0){ */
- /* error (1527, "Namespace elements cant be explicitly " + */
- /* "declared private or protected in `" + name + "'"); */
- /*} */
- }
- break;
-case 42:
-#line 396 "cs-parser.jay"
- {
- /* if (Collection.Contains ($$))... FIXME */
- note ("Allows: assembly, field, method, module, param, property, type");
- }
- break;
-case 49:
-#line 415 "cs-parser.jay"
- { /* reserved attribute name or identifier: 17.4 */ }
- break;
-case 73:
-#line 471 "cs-parser.jay"
- {
- Struct new_struct;
- string full_struct_name = MakeName ((string) yyVals[0+yyTop]);
-
- new_struct = new Struct (current_container, full_struct_name, (int) yyVals[-2+yyTop]);
- current_container = new_struct;
- current_container.Namespace = current_namespace;
- }
- break;
-case 74:
-#line 482 "cs-parser.jay"
- {
- Struct new_struct = (Struct) current_container;
-
- current_container = current_container.Parent;
- CheckDef (current_container.AddStruct (new_struct), new_struct.Name);
- yyVal = new_struct;
- }
- break;
-case 94:
-#line 538 "cs-parser.jay"
- {
- Modifiers.Check (Constant.AllowedModifiers, (int) yyVals[-4+yyTop], Modifiers.PRIVATE);
-
- foreach (DictionaryEntry constant in (ArrayList) yyVals[-1+yyTop]){
- Constant c = new Constant (
- (TypeRef) yyVals[-2+yyTop], (string) constant.Key,
- (Expression) constant.Value);
-
- CheckDef (current_container.AddConstant (c), c.Name);
- }
- }
- break;
-case 95:
-#line 553 "cs-parser.jay"
- {
- ArrayList constants = new ArrayList ();
- constants.Add (yyVals[0+yyTop]);
- yyVal = constants;
- }
- break;
-case 96:
-#line 559 "cs-parser.jay"
- {
- ArrayList constants = (ArrayList) yyVals[-2+yyTop];
-
- constants.Add (yyVals[0+yyTop]);
- }
- break;
-case 97:
-#line 567 "cs-parser.jay"
- {
- yyVal = new DictionaryEntry (yyVals[-2+yyTop], yyVals[0+yyTop]);
- }
- break;
-case 98:
-#line 578 "cs-parser.jay"
- {
- TypeRef typeref = (TypeRef) yyVals[-2+yyTop];
- int mod = (int) yyVals[-3+yyTop];
-
- foreach (VariableDeclaration var in (ArrayList) yyVals[-1+yyTop]){
- Field field = new Field (typeref, mod, var.identifier,
- var.expression_or_array_initializer);
-
- CheckDef (current_container.AddField (field), field.Name);
- }
- }
- break;
-case 99:
-#line 594 "cs-parser.jay"
- {
- ArrayList decl = new ArrayList ();
- yyVal = decl;
- decl.Add (yyVals[0+yyTop]);
- }
- break;
-case 100:
-#line 600 "cs-parser.jay"
- {
- ArrayList decls = (ArrayList) yyVals[-2+yyTop];
- decls.Add (yyVals[0+yyTop]);
- yyVal = yyVals[-2+yyTop];
- }
- break;
-case 101:
-#line 609 "cs-parser.jay"
- {
- yyVal = new VariableDeclaration ((string) yyVals[-2+yyTop], yyVals[0+yyTop]);
- }
- break;
-case 102:
-#line 613 "cs-parser.jay"
- {
- yyVal = new VariableDeclaration ((string) yyVals[0+yyTop], null);
- }
- break;
-case 105:
-#line 626 "cs-parser.jay"
- {
- Method method = (Method) yyVals[-1+yyTop];
-
- method.Block = (Block) yyVals[0+yyTop];
- CheckDef (current_container.AddMethod (method), method.Name);
-
- current_local_parameters = null;
- }
- break;
-case 106:
-#line 642 "cs-parser.jay"
- {
- Method method = new Method ((TypeRef) yyVals[-4+yyTop], (int) yyVals[-5+yyTop], (string) yyVals[-3+yyTop], (Parameters) yyVals[-1+yyTop]);
-
- current_local_parameters = (Parameters) yyVals[-1+yyTop];
-
- yyVal = method;
- }
- break;
-case 107:
-#line 654 "cs-parser.jay"
- {
- Method method = new Method (type ("void"), (int) yyVals[-5+yyTop], (string) yyVals[-3+yyTop], (Parameters) yyVals[-1+yyTop]);
-
- current_local_parameters = (Parameters) yyVals[-1+yyTop];
- yyVal = method;
- }
- break;
-case 109:
-#line 664 "cs-parser.jay"
- { yyVal = null; }
- break;
-case 110:
-#line 668 "cs-parser.jay"
- { yyVal = new Parameters (null, null); }
- break;
-case 112:
-#line 674 "cs-parser.jay"
- {
- yyVal = new Parameters ((ParameterCollection) yyVals[0+yyTop], null);
- }
- break;
-case 113:
-#line 678 "cs-parser.jay"
- {
- yyVal = new Parameters ((ParameterCollection) yyVals[-2+yyTop], (Parameter) yyVals[0+yyTop]);
- }
- break;
-case 114:
-#line 682 "cs-parser.jay"
- {
- yyVal = new Parameters (null, (Parameter) yyVals[0+yyTop]);
- }
- break;
-case 115:
-#line 689 "cs-parser.jay"
- {
- ParameterCollection pars = new ParameterCollection ();
- pars.Add ((Parameter) yyVals[0+yyTop]);
- yyVal = pars;
- }
- break;
-case 116:
-#line 695 "cs-parser.jay"
- {
- ParameterCollection pars = (ParameterCollection) yyVals[-2+yyTop];
- pars.Add ((Parameter) yyVals[0+yyTop]);
- yyVal = yyVals[-2+yyTop];
- }
- break;
-case 117:
-#line 707 "cs-parser.jay"
- {
- yyVal = new Parameter ((TypeRef) yyVals[-1+yyTop], (string) yyVals[0+yyTop], (Parameter.Modifier) yyVals[-2+yyTop]);
- }
- break;
-case 118:
-#line 713 "cs-parser.jay"
- { yyVal = Parameter.Modifier.NONE; }
- break;
-case 120:
-#line 718 "cs-parser.jay"
- { yyVal = Parameter.Modifier.REF; }
- break;
-case 121:
-#line 719 "cs-parser.jay"
- { yyVal = Parameter.Modifier.OUT; }
- break;
-case 122:
-#line 724 "cs-parser.jay"
- {
- yyVal = new Parameter ((TypeRef) yyVals[-1+yyTop], (string) yyVals[0+yyTop], Parameter.Modifier.PARAMS);
- note ("type must be a single-dimension array type");
- }
- break;
-case 123:
-#line 731 "cs-parser.jay"
- { yyVal = yyVals[0+yyTop].ToString (); }
- break;
-case 124:
-#line 732 "cs-parser.jay"
- { yyVal = yyVals[-2+yyTop].ToString () + "." + yyVals[0+yyTop].ToString (); }
- break;
-case 125:
-#line 740 "cs-parser.jay"
- {
- Parameter implicit_value_parameter;
- implicit_value_parameter = new Parameter ((TypeRef) yyVals[-2+yyTop], "value", Parameter.Modifier.NONE);
-
- lexer.properties = true;
-
- implicit_value_parameters = new ParameterCollection ();
- implicit_value_parameters.Add (implicit_value_parameter);
- }
- break;
-case 126:
-#line 750 "cs-parser.jay"
- {
- lexer.properties = false;
- }
- break;
-case 127:
-#line 754 "cs-parser.jay"
- {
- Property prop;
- DictionaryEntry pair = (DictionaryEntry) yyVals[-2+yyTop];
- Block get_block = null;
- Block set_block = null;
-
- if (pair.Key != null)
- get_block = (Block) pair.Key;
- if (pair.Value != null)
- set_block = (Block) pair.Value;
-
- prop = new Property ((TypeRef) yyVals[-6+yyTop], (string) yyVals[-5+yyTop], (int) yyVals[-7+yyTop], get_block, set_block);
-
- CheckDef (current_container.AddProperty (prop), prop.Name);
- implicit_value_parameters = null;
- }
- break;
-case 128:
-#line 774 "cs-parser.jay"
- {
- yyVal = new DictionaryEntry (yyVals[-1+yyTop], yyVals[0+yyTop]);
- }
- break;
-case 129:
-#line 778 "cs-parser.jay"
- {
- yyVal = new DictionaryEntry (yyVals[0+yyTop], yyVals[-1+yyTop]);
- }
- break;
-case 130:
-#line 784 "cs-parser.jay"
- { yyVal = null; }
- break;
-case 132:
-#line 789 "cs-parser.jay"
- { yyVal = null; }
- break;
-case 134:
-#line 795 "cs-parser.jay"
- {
- yyVal = yyVals[0+yyTop];
- }
- break;
-case 135:
-#line 802 "cs-parser.jay"
- {
- current_local_parameters = new Parameters (implicit_value_parameters, null);
- }
- break;
-case 136:
-#line 806 "cs-parser.jay"
- {
- yyVal = yyVals[0+yyTop];
- current_local_parameters = null;
- }
- break;
-case 138:
-#line 814 "cs-parser.jay"
- { yyVal = new Block (null); }
- break;
-case 139:
-#line 821 "cs-parser.jay"
- {
- Interface new_interface;
- string full_interface_name = MakeName ((string) yyVals[0+yyTop]);
-
- new_interface = new Interface (current_container, full_interface_name, (int) yyVals[-2+yyTop]);
- if (current_interface != null)
- error (-2, "Internal compiler error: interface inside interface");
- current_interface = new_interface;
- }
- break;
-case 140:
-#line 832 "cs-parser.jay"
- {
- Interface new_interface = (Interface) current_interface;
-
- if (yyVals[-1+yyTop] != null)
- new_interface.Bases = (ArrayList) yyVals[-1+yyTop];
-
- current_interface = null;
- CheckDef (current_container.AddInterface (new_interface), new_interface.Name);
- }
- break;
-case 141:
-#line 844 "cs-parser.jay"
- { yyVal = null; }
- break;
-case 143:
-#line 849 "cs-parser.jay"
- { yyVal = yyVals[0+yyTop]; }
- break;
-case 144:
-#line 854 "cs-parser.jay"
- {
- ArrayList interfaces = new ArrayList ();
-
- interfaces.Add (yyVals[0+yyTop]);
- }
- break;
-case 145:
-#line 860 "cs-parser.jay"
- {
- ArrayList interfaces = (ArrayList) yyVals[-2+yyTop];
- interfaces.Add (yyVals[0+yyTop]);
- yyVal = interfaces;
- }
- break;
-case 151:
-#line 885 "cs-parser.jay"
- {
- InterfaceMethod m = (InterfaceMethod) yyVals[0+yyTop];
-
- CheckDef (current_interface.AddMethod (m), m.Name);
- }
- break;
-case 152:
-#line 891 "cs-parser.jay"
- {
- InterfaceProperty p = (InterfaceProperty) yyVals[0+yyTop];
-
- CheckDef (current_interface.AddProperty (p), p.Name);
- }
- break;
-case 153:
-#line 897 "cs-parser.jay"
- {
- InterfaceEvent e = (InterfaceEvent) yyVals[0+yyTop];
-
- CheckDef (current_interface.AddEvent (e), e.Name);
- }
- break;
-case 154:
-#line 903 "cs-parser.jay"
- {
- InterfaceIndexer i = (InterfaceIndexer) yyVals[0+yyTop];
-
- CheckDef (current_interface.AddIndexer (i), "indexer");
- }
- break;
-case 155:
-#line 911 "cs-parser.jay"
- { yyVal = false; }
- break;
-case 156:
-#line 912 "cs-parser.jay"
- { yyVal = true; }
- break;
-case 157:
-#line 919 "cs-parser.jay"
- {
- yyVal = new InterfaceMethod ((TypeRef) yyVals[-5+yyTop], (string) yyVals[-4+yyTop], (bool) yyVals[-6+yyTop], (Parameters) yyVals[-2+yyTop]);
- }
- break;
-case 158:
-#line 925 "cs-parser.jay"
- {
- yyVal = new InterfaceMethod (type ("void"), (string) yyVals[-4+yyTop], (bool) yyVals[-6+yyTop], (Parameters) yyVals[-2+yyTop]);
- }
- break;
-case 159:
-#line 935 "cs-parser.jay"
- { lexer.properties = true; }
- break;
-case 160:
-#line 937 "cs-parser.jay"
- { lexer.properties = false; }
- break;
-case 161:
-#line 939 "cs-parser.jay"
- {
- int gs = (int) yyVals[-2+yyTop];
-
- yyVal = new InterfaceProperty ((TypeRef) yyVals[-6+yyTop], (string) yyVals[-5+yyTop], (bool) yyVals[-7+yyTop],
- (gs & 1) == 1, (gs & 2) == 2);
- }
- break;
-case 162:
-#line 948 "cs-parser.jay"
- { yyVal = 1; }
- break;
-case 163:
-#line 949 "cs-parser.jay"
- { yyVal = 2; }
- break;
-case 164:
-#line 951 "cs-parser.jay"
- { yyVal = 3; }
- break;
-case 165:
-#line 953 "cs-parser.jay"
- { yyVal = 3; }
- break;
-case 166:
-#line 958 "cs-parser.jay"
- {
- yyVal = new InterfaceEvent ((TypeRef) yyVals[-2+yyTop], (string) yyVals[-1+yyTop], (bool) yyVals[-4+yyTop]);
- }
- break;
-case 167:
-#line 967 "cs-parser.jay"
- { lexer.properties = true; }
- break;
-case 168:
-#line 969 "cs-parser.jay"
- { lexer.properties = false; }
- break;
-case 169:
-#line 971 "cs-parser.jay"
- {
- int a_flags = (int) yyVals[-2+yyTop];
-
- bool do_get = (a_flags & 1) == 1;
- bool do_set = (a_flags & 2) == 2;
-
- yyVal = new InterfaceIndexer ((TypeRef) yyVals[-9+yyTop], (Parameters) yyVals[-6+yyTop], do_get, do_set, (bool) yyVals[-10+yyTop]);
- }
- break;
-case 170:
-#line 983 "cs-parser.jay"
- {
- /* FIXME: validate that opt_modifiers is exactly: PUBLIC and STATIC */
- }
- break;
-case 171:
-#line 991 "cs-parser.jay"
- {
- /* FIXME: since reduce/reduce on this */
- /* rule, validate overloadable_operator is unary */
- }
- break;
-case 172:
-#line 1000 "cs-parser.jay"
- {
- /* FIXME: because of the reduce/reduce on PLUS and MINUS */
- /* validate overloadable_operator is binary */
- }
- break;
-case 198:
-#line 1045 "cs-parser.jay"
- {
- Constructor c = (Constructor) yyVals[-1+yyTop];
- c.Block = (Block) yyVals[0+yyTop];
- c.ModFlags = (int) yyVals[-2+yyTop];
-
- if ((c.ModFlags & Modifiers.STATIC) != 0){
- if ((c.ModFlags & Modifiers.Accessibility) != 0){
- error (515, "Access modifiers are not allowed on static constructors");
- }
- }
- CheckDef (current_container.AddConstructor (c), c.Name);
-
- current_local_parameters = null;
- }
- break;
-case 199:
-#line 1065 "cs-parser.jay"
- {
- ConstructorInitializer i = null;
-
- if (yyVals[0+yyTop] != null)
- i = (ConstructorInitializer) yyVals[0+yyTop];
-
- yyVal = new Constructor ((string) yyVals[-4+yyTop], (Parameters) yyVals[-2+yyTop], i);
-
- current_local_parameters = (Parameters) yyVals[-2+yyTop];
- }
- break;
-case 200:
-#line 1078 "cs-parser.jay"
- { yyVal = null; }
- break;
-case 202:
-#line 1084 "cs-parser.jay"
- {
- yyVal = new ConstructorBaseInitializer ((ArrayList) yyVals[-1+yyTop]);
- }
- break;
-case 203:
-#line 1088 "cs-parser.jay"
- {
- yyVal = new ConstructorThisInitializer ((ArrayList) yyVals[-1+yyTop]);
- }
- break;
-case 204:
-#line 1095 "cs-parser.jay"
- {
- Method d = new Method (type ("void"), 0, "Finalize", new Parameters (null, null));
-
- d.Block = (Block) yyVals[0+yyTop];
- CheckDef (current_container.AddMethod (d), d.Name);
- }
- break;
-case 205:
-#line 1107 "cs-parser.jay"
- { note ("validate that the flags only contain new public protected internal private static virtual sealed override abstract"); }
- break;
-case 206:
-#line 1112 "cs-parser.jay"
- { note ("validate that the flags only contain new public protected internal private static virtual sealed override abstract"); }
- break;
-case 211:
-#line 1131 "cs-parser.jay"
- {
- /* The signature is computed from the signature of the indexer. Look */
- /* at section 3.6 on the spec */
- note ("verify modifiers are NEW PUBLIC PROTECTED INTERNAL PRIVATE VIRTUAL SEALED OVERRIDE ABSTRACT");
- }
- break;
-case 214:
-#line 1150 "cs-parser.jay"
- {
- string name = (string) yyVals[-3+yyTop];
- Enum e = new Enum ((TypeRef) yyVals[-2+yyTop], (int) yyVals[-5+yyTop], name);
-
- foreach (VariableDeclaration ev in (ArrayList) yyVals[-1+yyTop]){
- CheckDef (
- e.AddEnum (
- ev.identifier,
- (Expression) ev.expression_or_array_initializer),
- ev.identifier);
- }
-
- CheckDef (current_container.AddEnum (e), name);
- }
- break;
-case 215:
-#line 1167 "cs-parser.jay"
- { yyVal = type ("System.Int32"); }
- break;
-case 216:
-#line 1168 "cs-parser.jay"
- { yyVal = yyVals[0+yyTop]; }
- break;
-case 217:
-#line 1173 "cs-parser.jay"
- {
- yyVal = yyVals[-1+yyTop];
- }
- break;
-case 218:
-#line 1177 "cs-parser.jay"
- {
- yyVal = yyVals[-2+yyTop];
- }
- break;
-case 219:
-#line 1183 "cs-parser.jay"
- { yyVal = new ArrayList (); }
- break;
-case 220:
-#line 1184 "cs-parser.jay"
- { yyVal = yyVals[0+yyTop]; }
- break;
-case 221:
-#line 1189 "cs-parser.jay"
- {
- ArrayList l = new ArrayList ();
-
- l.Add (yyVals[0+yyTop]);
- yyVal = l;
- }
- break;
-case 222:
-#line 1196 "cs-parser.jay"
- {
- ArrayList l = (ArrayList) yyVals[-2+yyTop];
-
- l.Add (yyVals[0+yyTop]);
-
- yyVal = l;
- }
- break;
-case 223:
-#line 1207 "cs-parser.jay"
- {
- yyVal = new VariableDeclaration ((string) yyVals[0+yyTop], null);
- }
- break;
-case 224:
-#line 1211 "cs-parser.jay"
- {
- yyVal = new VariableDeclaration ((string) yyVals[-2+yyTop], yyVals[0+yyTop]);
- }
- break;
-case 225:
-#line 1224 "cs-parser.jay"
- { note ("validate that modifiers only contains NEW PUBLIC PROTECTED INTERNAL PRIVATE"); }
- break;
-case 228:
-#line 1242 "cs-parser.jay"
- { /* class_type */
- /*
- This does interfaces, delegates, struct_types, class_types,
- parent classes, and more! 4.2
- */
- yyVal = type ((string) yyVals[0+yyTop]);
- }
- break;
-case 231:
-#line 1255 "cs-parser.jay"
- {
- ArrayList types = new ArrayList ();
-
- types.Add (yyVals[0+yyTop]);
- yyVal = types;
- }
- break;
-case 232:
-#line 1262 "cs-parser.jay"
- {
- ArrayList types = new ArrayList ();
- types.Add (yyVals[0+yyTop]);
- yyVal = types;
- }
- break;
-case 233:
-#line 1274 "cs-parser.jay"
- { yyVal = type ("System.Object"); }
- break;
-case 234:
-#line 1275 "cs-parser.jay"
- { yyVal = type ("System.String"); }
- break;
-case 235:
-#line 1276 "cs-parser.jay"
- { yyVal = type ("System.Boolean"); }
- break;
-case 236:
-#line 1277 "cs-parser.jay"
- { yyVal = type ("System.Decimal"); }
- break;
-case 237:
-#line 1278 "cs-parser.jay"
- { yyVal = type ("System.Single"); }
- break;
-case 238:
-#line 1279 "cs-parser.jay"
- { yyVal = type ("System.Double"); }
- break;
-case 240:
-#line 1284 "cs-parser.jay"
- { yyVal = type ("System.SByte"); }
- break;
-case 241:
-#line 1285 "cs-parser.jay"
- { yyVal = type ("System.Byte"); }
- break;
-case 242:
-#line 1286 "cs-parser.jay"
- { yyVal = type ("System.Int16"); }
- break;
-case 243:
-#line 1287 "cs-parser.jay"
- { yyVal = type ("System.UInt16"); }
- break;
-case 244:
-#line 1288 "cs-parser.jay"
- { yyVal = type ("System.Int32"); }
- break;
-case 245:
-#line 1289 "cs-parser.jay"
- { yyVal = type ("System.UInt32"); }
- break;
-case 246:
-#line 1290 "cs-parser.jay"
- { yyVal = type ("System.Int64"); }
- break;
-case 247:
-#line 1291 "cs-parser.jay"
- { yyVal = type ("System.UInt64"); }
- break;
-case 248:
-#line 1292 "cs-parser.jay"
- { yyVal = type ("System.Char"); }
- break;
-case 250:
-#line 1301 "cs-parser.jay"
- {
- yyVal = yyVals[-1+yyTop];
- /* FIXME: We need to create a type for the nested thing. */
- }
- break;
-case 251:
-#line 1312 "cs-parser.jay"
- {
- /* 7.5.1: Literals */
-
- }
- break;
-case 252:
-#line 1318 "cs-parser.jay"
- {
- string name = (string) yyVals[0+yyTop];
-
- yyVal = null;
- if (name.IndexOf ('.') == -1){
- /* */
- /* we need to check against current_block not being null */
- /* as `expression' is allowed in argument_lists, which */
- /* do not exist inside a block. */
- /* */
- if (current_block != null){
- if (current_block.IsVariableDefined (name))
- yyVal = new LocalVariableReference (current_block, name);
- }
- if ((yyVal == null) && (current_local_parameters != null)){
- Parameter par = current_local_parameters.GetParameterByName (name);
- if (par != null)
- yyVal = new ParameterReference (current_local_parameters, name);
- }
- }
- if (yyVal == null)
- yyVal = new SimpleName (name);
- }
- break;
-case 269:
-#line 1360 "cs-parser.jay"
- { yyVal = new CharLiteral ((char) lexer.Value); }
- break;
-case 270:
-#line 1361 "cs-parser.jay"
- { yyVal = new StringLiteral ((string) lexer.Value); }
- break;
-case 271:
-#line 1362 "cs-parser.jay"
- { yyVal = new NullLiteral (); }
- break;
-case 272:
-#line 1366 "cs-parser.jay"
- { yyVal = new FloatLiteral ((float) lexer.Value); }
- break;
-case 273:
-#line 1367 "cs-parser.jay"
- { yyVal = new DoubleLiteral ((double) lexer.Value); }
- break;
-case 274:
-#line 1368 "cs-parser.jay"
- { yyVal = new DecimalLiteral ((decimal) lexer.Value); }
- break;
-case 275:
-#line 1372 "cs-parser.jay"
- { yyVal = new IntLiteral ((Int32) lexer.Value); }
- break;
-case 276:
-#line 1376 "cs-parser.jay"
- { yyVal = new BoolLiteral (true); }
- break;
-case 277:
-#line 1377 "cs-parser.jay"
- { yyVal = new BoolLiteral (false); }
- break;
-case 278:
-#line 1382 "cs-parser.jay"
- { yyVal = yyVals[-1+yyTop]; }
- break;
-case 279:
-#line 1387 "cs-parser.jay"
- {
- yyVal = new MemberAccess ((Expression) yyVals[-2+yyTop], (string) yyVals[0+yyTop]);
- }
- break;
-case 280:
-#line 1391 "cs-parser.jay"
- {
- yyVal = new BuiltinTypeAccess ((TypeRef) yyVals[-2+yyTop], (string) yyVals[0+yyTop]);
- }
- break;
-case 282:
-#line 1402 "cs-parser.jay"
- {
- /* FIXME: */
- /* if $1 is MethodGroup */
- /* $$ = new Call ($1, $3); */
- /* else */
- /* $$ = new DelegateCall ($1, $3); */
- if (yyVals[-3+yyTop] == null)
- error (1, "THIS IS CRAZY");
-
- yyVal = new Invocation ((Expression) yyVals[-3+yyTop], (ArrayList) yyVals[-1+yyTop]);
- }
- break;
-case 283:
-#line 1416 "cs-parser.jay"
- { yyVal = new ArrayList (); }
- break;
-case 285:
-#line 1422 "cs-parser.jay"
- {
- ArrayList list = new ArrayList ();
- list.Add (yyVals[0+yyTop]);
- yyVal = list;
- }
- break;
-case 286:
-#line 1428 "cs-parser.jay"
- {
- ArrayList list = (ArrayList) yyVals[-2+yyTop];
- list.Add (yyVals[0+yyTop]);
- yyVal = list;
- }
- break;
-case 287:
-#line 1437 "cs-parser.jay"
- {
- yyVal = new Argument ((Expression) yyVals[0+yyTop], Argument.AType.Expression);
- }
- break;
-case 288:
-#line 1441 "cs-parser.jay"
- {
- yyVal = new Argument ((Expression) yyVals[0+yyTop], Argument.AType.Ref);
- }
- break;
-case 289:
-#line 1445 "cs-parser.jay"
- {
- yyVal = new Argument ((Expression) yyVals[0+yyTop], Argument.AType.Out);
- }
- break;
-case 290:
-#line 1451 "cs-parser.jay"
- { note ("section 5.4"); yyVal = yyVals[0+yyTop]; }
- break;
-case 294:
-#line 1466 "cs-parser.jay"
- {
- yyVal = new This ();
- }
- break;
-case 297:
-#line 1480 "cs-parser.jay"
- {
- yyVal = new Unary (Unary.Operator.PostIncrement, (Expression) yyVals[-1+yyTop]);
- }
- break;
-case 298:
-#line 1487 "cs-parser.jay"
- {
- yyVal = new Unary (Unary.Operator.PostDecrement, (Expression) yyVals[-1+yyTop]);
- }
- break;
-case 301:
-#line 1499 "cs-parser.jay"
- {
- yyVal = new New ((TypeRef) yyVals[-3+yyTop], (ArrayList) yyVals[-1+yyTop]);
- }
- break;
-case 319:
-#line 1559 "cs-parser.jay"
- {
- yyVal = new TypeOf ((TypeRef) yyVals[-1+yyTop]);
- }
- break;
-case 320:
-#line 1565 "cs-parser.jay"
- {
- yyVal = new SizeOf ((TypeRef) yyVals[-1+yyTop]);
-
- note ("Verify type is unmanaged");
- note ("if (5.8) builtin, yield constant expression");
- }
- break;
-case 324:
-#line 1583 "cs-parser.jay"
- {
- yyVal = new Unary (Unary.Operator.Plus, (Expression) yyVals[0+yyTop]);
- }
- break;
-case 325:
-#line 1587 "cs-parser.jay"
- {
- yyVal = new Unary (Unary.Operator.Minus, (Expression) yyVals[0+yyTop]);
- }
- break;
-case 326:
-#line 1591 "cs-parser.jay"
- {
- yyVal = new Unary (Unary.Operator.Negate, (Expression) yyVals[0+yyTop]);
- }
- break;
-case 327:
-#line 1595 "cs-parser.jay"
- {
- yyVal = new Unary (Unary.Operator.BitComplement, (Expression) yyVals[0+yyTop]);
- }
- break;
-case 328:
-#line 1599 "cs-parser.jay"
- {
- yyVal = new Unary (Unary.Operator.Indirection, (Expression) yyVals[0+yyTop]);
- }
- break;
-case 329:
-#line 1603 "cs-parser.jay"
- {
- yyVal = new Unary (Unary.Operator.AddressOf, (Expression) yyVals[0+yyTop]);
- }
- break;
-case 333:
-#line 1618 "cs-parser.jay"
- {
- yyVal = new Unary (Unary.Operator.PreIncrement, (Expression) yyVals[0+yyTop]);
- }
- break;
-case 334:
-#line 1625 "cs-parser.jay"
- {
- yyVal = new Unary (Unary.Operator.PreDecrement, (Expression) yyVals[0+yyTop]);
- }
- break;
-case 335:
-#line 1635 "cs-parser.jay"
- {
- yyVal = new Cast (type ((string) yyVals[-2+yyTop]), (Expression) yyVals[0+yyTop]);
- }
- break;
-case 336:
-#line 1639 "cs-parser.jay"
- {
- yyVal = new Cast ((TypeRef) yyVals[-2+yyTop], (Expression) yyVals[0+yyTop]);
- }
- break;
-case 338:
-#line 1647 "cs-parser.jay"
- {
- yyVal = new Binary (Binary.Operator.Multiply,
- (Expression) yyVals[-2+yyTop], (Expression) yyVals[0+yyTop]);
- }
- break;
-case 339:
-#line 1652 "cs-parser.jay"
- {
- yyVal = new Binary (Binary.Operator.Divide,
- (Expression) yyVals[-2+yyTop], (Expression) yyVals[0+yyTop]);
- }
- break;
-case 340:
-#line 1657 "cs-parser.jay"
- {
- yyVal = new Binary (Binary.Operator.Modulo,
- (Expression) yyVals[-2+yyTop], (Expression) yyVals[0+yyTop]);
- }
- break;
-case 342:
-#line 1666 "cs-parser.jay"
- {
- yyVal = new Binary (Binary.Operator.Add,
- (Expression) yyVals[-2+yyTop], (Expression) yyVals[0+yyTop]);
- }
- break;
-case 343:
-#line 1671 "cs-parser.jay"
- {
- yyVal = new Binary (Binary.Operator.Substract,
- (Expression) yyVals[-2+yyTop], (Expression) yyVals[0+yyTop]);
- }
- break;
-case 345:
-#line 1680 "cs-parser.jay"
- {
- yyVal = new Binary (Binary.Operator.ShiftLeft,
- (Expression) yyVals[-2+yyTop], (Expression) yyVals[0+yyTop]);
- }
- break;
-case 346:
-#line 1685 "cs-parser.jay"
- {
- yyVal = new Binary (Binary.Operator.ShiftRight,
- (Expression) yyVals[-2+yyTop], (Expression) yyVals[0+yyTop]);
- }
- break;
-case 348:
-#line 1694 "cs-parser.jay"
- {
- yyVal = new Binary (Binary.Operator.LessThan,
- (Expression) yyVals[-2+yyTop], (Expression) yyVals[0+yyTop]);
- }
- break;
-case 349:
-#line 1699 "cs-parser.jay"
- {
- yyVal = new Binary (Binary.Operator.GreatherThan,
- (Expression) yyVals[-2+yyTop], (Expression) yyVals[0+yyTop]);
- }
- break;
-case 350:
-#line 1704 "cs-parser.jay"
- {
- yyVal = new Binary (Binary.Operator.LessOrEqual,
- (Expression) yyVals[-2+yyTop], (Expression) yyVals[0+yyTop]);
- }
- break;
-case 351:
-#line 1709 "cs-parser.jay"
- {
- yyVal = new Binary (Binary.Operator.GreatherOrEqual,
- (Expression) yyVals[-2+yyTop], (Expression) yyVals[0+yyTop]);
- }
- break;
-case 352:
-#line 1714 "cs-parser.jay"
- {
- yyVal = new Probe (Probe.Operator.Is,
- (Expression) yyVals[-2+yyTop], (TypeRef) yyVals[0+yyTop]);
- }
- break;
-case 353:
-#line 1719 "cs-parser.jay"
- {
- yyVal = new Probe (Probe.Operator.As,
- (Expression) yyVals[-2+yyTop], (TypeRef) yyVals[0+yyTop]);
- }
- break;
-case 355:
-#line 1728 "cs-parser.jay"
- {
- yyVal = new Binary (Binary.Operator.Equal,
- (Expression) yyVals[-2+yyTop], (Expression) yyVals[0+yyTop]);
- }
- break;
-case 356:
-#line 1733 "cs-parser.jay"
- {
- yyVal = new Binary (Binary.Operator.NotEqual,
- (Expression) yyVals[-2+yyTop], (Expression) yyVals[0+yyTop]);
- }
- break;
-case 358:
-#line 1742 "cs-parser.jay"
- {
- yyVal = new Binary (Binary.Operator.BitwiseAnd,
- (Expression) yyVals[-2+yyTop], (Expression) yyVals[0+yyTop]);
- }
- break;
-case 360:
-#line 1751 "cs-parser.jay"
- {
- yyVal = new Binary (Binary.Operator.ExclusiveOr,
- (Expression) yyVals[-2+yyTop], (Expression) yyVals[0+yyTop]);
- }
- break;
-case 362:
-#line 1760 "cs-parser.jay"
- {
- yyVal = new Binary (Binary.Operator.BitwiseOr,
- (Expression) yyVals[-2+yyTop], (Expression) yyVals[0+yyTop]);
- }
- break;
-case 364:
-#line 1769 "cs-parser.jay"
- {
- yyVal = new Binary (Binary.Operator.LogicalAnd,
- (Expression) yyVals[-2+yyTop], (Expression) yyVals[0+yyTop]);
- }
- break;
-case 366:
-#line 1778 "cs-parser.jay"
- {
- yyVal = new Binary (Binary.Operator.LogicalOr,
- (Expression) yyVals[-2+yyTop], (Expression) yyVals[0+yyTop]);
- }
- break;
-case 368:
-#line 1787 "cs-parser.jay"
- {
- yyVal = new Conditional ((Expression) yyVals[-4+yyTop], (Expression) yyVals[-2+yyTop], (Expression) yyVals[0+yyTop]);
- }
- break;
-case 369:
-#line 1794 "cs-parser.jay"
- {
- yyVal = new Assign ((Expression) yyVals[-2+yyTop], (Expression) yyVals[0+yyTop]);
- }
- break;
-case 370:
-#line 1798 "cs-parser.jay"
- {
- yyVal = new Assign ((Expression) yyVals[-2+yyTop],
- new Binary (Binary.Operator.Multiply,
- (Expression) yyVals[-2+yyTop],
- (Expression) yyVals[0+yyTop]));
- }
- break;
-case 371:
-#line 1805 "cs-parser.jay"
- {
- yyVal = new Assign ((Expression) yyVals[-2+yyTop],
- new Binary (Binary.Operator.Divide,
- (Expression) yyVals[-2+yyTop],
- (Expression) yyVals[0+yyTop]));
- }
- break;
-case 372:
-#line 1812 "cs-parser.jay"
- {
- yyVal = new Assign ((Expression) yyVals[-2+yyTop],
- new Binary (Binary.Operator.Modulo,
- (Expression) yyVals[-2+yyTop],
- (Expression) yyVals[0+yyTop]));
- }
- break;
-case 373:
-#line 1819 "cs-parser.jay"
- {
- yyVal = new Assign ((Expression) yyVals[-2+yyTop],
- new Binary (Binary.Operator.Add,
- (Expression) yyVals[-2+yyTop],
- (Expression) yyVals[0+yyTop]));
- }
- break;
-case 374:
-#line 1826 "cs-parser.jay"
- {
- yyVal = new Assign ((Expression) yyVals[-2+yyTop],
- new Binary (Binary.Operator.Substract,
- (Expression) yyVals[-2+yyTop],
- (Expression) yyVals[0+yyTop]));
- }
- break;
-case 375:
-#line 1833 "cs-parser.jay"
- {
- yyVal = new Assign ((Expression) yyVals[-2+yyTop],
- new Binary (Binary.Operator.ShiftLeft,
- (Expression) yyVals[-2+yyTop],
- (Expression) yyVals[0+yyTop]));
- }
- break;
-case 376:
-#line 1840 "cs-parser.jay"
- {
- yyVal = new Assign ((Expression) yyVals[-2+yyTop],
- new Binary (Binary.Operator.ShiftRight,
- (Expression) yyVals[-2+yyTop],
- (Expression) yyVals[0+yyTop]));
- }
- break;
-case 377:
-#line 1847 "cs-parser.jay"
- {
- yyVal = new Assign ((Expression) yyVals[-2+yyTop],
- new Binary (Binary.Operator.BitwiseAnd,
- (Expression) yyVals[-2+yyTop],
- (Expression) yyVals[0+yyTop]));
- }
- break;
-case 378:
-#line 1854 "cs-parser.jay"
- {
- yyVal = new Assign ((Expression) yyVals[-2+yyTop],
- new Binary (Binary.Operator.BitwiseOr,
- (Expression) yyVals[-2+yyTop],
- (Expression) yyVals[0+yyTop]));
- }
- break;
-case 379:
-#line 1861 "cs-parser.jay"
- {
- yyVal = new Assign ((Expression) yyVals[-2+yyTop],
- new Binary (Binary.Operator.ExclusiveOr,
- (Expression) yyVals[-2+yyTop],
- (Expression) yyVals[0+yyTop]));
- }
- break;
-case 383:
-#line 1879 "cs-parser.jay"
- { CheckBoolean ((Expression) yyVals[0+yyTop]); yyVal = yyVals[0+yyTop]; }
- break;
-case 384:
-#line 1889 "cs-parser.jay"
- {
- Class new_class;
- string full_class_name = MakeName ((string) yyVals[0+yyTop]);
-
- new_class = new Class (current_container, full_class_name, (int) yyVals[-2+yyTop]);
- current_container = new_class;
- current_container.Namespace = current_namespace;
- }
- break;
-case 385:
-#line 1900 "cs-parser.jay"
- {
- Class new_class = (Class) current_container;
-
- if (yyVals[-2+yyTop] != null)
- new_class.Bases = (ArrayList) yyVals[-2+yyTop];
-
- current_container = current_container.Parent;
- CheckDef (current_container.AddClass (new_class), new_class.Name);
-
- yyVal = new_class;
- }
- break;
-case 386:
-#line 1914 "cs-parser.jay"
- { yyVal = (int) 0; }
- break;
-case 389:
-#line 1920 "cs-parser.jay"
- {
- int m1 = (int) yyVals[-1+yyTop];
- int m2 = (int) yyVals[0+yyTop];
-
- if ((m1 & m2) != 0)
- error (1002, "Duplicate modifier: `" + Modifiers.Name (m2) + "'");
-
- yyVal = (int) (m1 | m2);
- }
- break;
-case 390:
-#line 1932 "cs-parser.jay"
- { yyVal = Modifiers.NEW; }
- break;
-case 391:
-#line 1933 "cs-parser.jay"
- { yyVal = Modifiers.PUBLIC; }
- break;
-case 392:
-#line 1934 "cs-parser.jay"
- { yyVal = Modifiers.PROTECTED; }
- break;
-case 393:
-#line 1935 "cs-parser.jay"
- { yyVal = Modifiers.INTERNAL; }
- break;
-case 394:
-#line 1936 "cs-parser.jay"
- { yyVal = Modifiers.PRIVATE; }
- break;
-case 395:
-#line 1937 "cs-parser.jay"
- { yyVal = Modifiers.ABSTRACT; }
- break;
-case 396:
-#line 1938 "cs-parser.jay"
- { yyVal = Modifiers.SEALED; }
- break;
-case 397:
-#line 1939 "cs-parser.jay"
- { yyVal = Modifiers.STATIC; }
- break;
-case 398:
-#line 1940 "cs-parser.jay"
- { yyVal = Modifiers.READONLY; }
- break;
-case 399:
-#line 1941 "cs-parser.jay"
- { yyVal = Modifiers.VIRTUAL; }
- break;
-case 400:
-#line 1942 "cs-parser.jay"
- { yyVal = Modifiers.OVERRIDE; }
- break;
-case 401:
-#line 1943 "cs-parser.jay"
- { yyVal = Modifiers.EXTERN; }
- break;
-case 402:
-#line 1947 "cs-parser.jay"
- { yyVal = null; }
- break;
-case 403:
-#line 1948 "cs-parser.jay"
- { yyVal = yyVals[0+yyTop]; }
- break;
-case 404:
-#line 1952 "cs-parser.jay"
- { yyVal = yyVals[0+yyTop]; }
- break;
-case 405:
-#line 1970 "cs-parser.jay"
- {
- current_block = new Block (current_block);
- }
- break;
-case 406:
-#line 1974 "cs-parser.jay"
- {
- while (current_block.Implicit)
- current_block = current_block.Parent;
- yyVal = current_block;
- current_block = current_block.Parent;
- }
- break;
-case 411:
-#line 1994 "cs-parser.jay"
- {
- if ((Block) yyVals[0+yyTop] != current_block){
- current_block.AddStatement ((Statement) yyVals[0+yyTop]);
- current_block = (Block) yyVals[0+yyTop];
- }
- }
- break;
-case 412:
-#line 2001 "cs-parser.jay"
- {
- current_block.AddStatement ((Statement) yyVals[0+yyTop]);
- }
- break;
-case 413:
-#line 2005 "cs-parser.jay"
- {
- current_block.AddStatement ((Statement) yyVals[0+yyTop]);
- }
- break;
-case 425:
-#line 2026 "cs-parser.jay"
- {
- yyVal = new EmptyStatement ();
- }
- break;
-case 426:
-#line 2033 "cs-parser.jay"
- {
- string lab = (String) yyVals[-2+yyTop];
- Block block;
-
- block = new Block (current_block, lab);
- block.AddStatement ((Statement) yyVals[0+yyTop]);
- yyVal = block;
-
- if (!current_block.AddLabel (lab, block)){
- error (140, "The label '" + lab + "' is a duplicate");
- yyVal = yyVals[0+yyTop];
- }
- }
- break;
-case 429:
-#line 2061 "cs-parser.jay"
- {
- /* FIXME: Do something smart here regarding the composition of the type. */
- /* */
-
- /* Ok, the above "primary_expression" is there to get rid of */
- /* both reduce/reduce and shift/reduces in the grammar, it should */
- /* really just be "type_name". If you use type_name, a reduce/reduce */
- /* creeps up. If you use qualified_identifier (which is all we need */
- /* really) two shift/reduces appear. */
- /* */
- /* So, instead we do a super trick: we just allow ($1) to be a */
- /* SimpleName Expression. */
- /* */
- if (((Expression) yyVals[-1+yyTop]) is SimpleName)
- yyVal = type (((SimpleName) yyVals[-1+yyTop]).Name);
- else {
- error (-1, "Invalid Type definition");
- yyVal = type ("object");
- }
- }
- break;
-case 430:
-#line 2082 "cs-parser.jay"
- {
- /* FIXME: Do something smart with the type here. */
- yyVal = yyVals[-1+yyTop];
- }
- break;
-case 431:
-#line 2087 "cs-parser.jay"
- {
- yyVal = type ("VOID SOMETHING TYPE");
- }
- break;
-case 437:
-#line 2109 "cs-parser.jay"
- {
- yyVal = declare_local_variables ((TypeRef) yyVals[-1+yyTop], (ArrayList) yyVals[0+yyTop]);
- }
- break;
-case 439:
-#line 2121 "cs-parser.jay"
- {
- yyVal = yyVals[-1+yyTop];
- }
- break;
-case 440:
-#line 2131 "cs-parser.jay"
- { yyVal = new StatementExpression ((Expression) yyVals[0+yyTop]); }
- break;
-case 441:
-#line 2132 "cs-parser.jay"
- { yyVal = new StatementExpression ((Expression) yyVals[0+yyTop]); }
- break;
-case 442:
-#line 2133 "cs-parser.jay"
- { yyVal = new StatementExpression ((Expression) yyVals[0+yyTop]); }
- break;
-case 443:
-#line 2134 "cs-parser.jay"
- { yyVal = new StatementExpression ((Expression) yyVals[0+yyTop]); }
- break;
-case 444:
-#line 2135 "cs-parser.jay"
- { yyVal = new StatementExpression ((Expression) yyVals[0+yyTop]); }
- break;
-case 445:
-#line 2136 "cs-parser.jay"
- { yyVal = new StatementExpression ((Expression) yyVals[0+yyTop]); }
- break;
-case 446:
-#line 2137 "cs-parser.jay"
- { yyVal = new StatementExpression ((Expression) yyVals[0+yyTop]); }
- break;
-case 447:
-#line 2142 "cs-parser.jay"
- { note ("complain if this is a delegate maybe?"); }
- break;
-case 450:
-#line 2153 "cs-parser.jay"
- {
- yyVal = new If ((Expression) yyVals[-2+yyTop], (Statement) yyVals[0+yyTop]);
- }
- break;
-case 451:
-#line 2158 "cs-parser.jay"
- {
- yyVal = new If ((Expression) yyVals[-4+yyTop], (Statement) yyVals[-2+yyTop], (Statement) yyVals[0+yyTop]);
- }
- break;
-case 452:
-#line 2166 "cs-parser.jay"
- {
- yyVal = new Switch ((Expression) yyVals[-2+yyTop], (ArrayList) yyVals[0+yyTop]);
- }
- break;
-case 453:
-#line 2175 "cs-parser.jay"
- {
- yyVal = yyVals[-1+yyTop];
- }
- break;
-case 454:
-#line 2181 "cs-parser.jay"
- { yyVal = new ArrayList (); }
- break;
-case 456:
-#line 2187 "cs-parser.jay"
- {
- ArrayList sections = new ArrayList ();
-
- sections.Add (yyVals[0+yyTop]);
- yyVal = sections;
- }
- break;
-case 457:
-#line 2194 "cs-parser.jay"
- {
- ArrayList sections = (ArrayList) yyVals[-1+yyTop];
-
- sections.Add (yyVals[0+yyTop]);
- yyVal = sections;
- }
- break;
-case 458:
-#line 2204 "cs-parser.jay"
- {
- current_block = new Block (current_block);
- }
- break;
-case 459:
-#line 2208 "cs-parser.jay"
- {
- while (current_block.Implicit)
- current_block = current_block.Parent;
- yyVal = new SwitchSection ((ArrayList) yyVals[-2+yyTop], current_block);
- current_block = current_block.Parent;
- }
- break;
-case 460:
-#line 2218 "cs-parser.jay"
- {
- ArrayList labels = new ArrayList ();
-
- labels.Add (yyVals[0+yyTop]);
- yyVal = labels;
- }
- break;
-case 461:
-#line 2225 "cs-parser.jay"
- {
- ArrayList labels = (ArrayList) (yyVals[-1+yyTop]);
- labels.Add (yyVals[0+yyTop]);
-
- yyVal = labels;
- }
- break;
-case 462:
-#line 2234 "cs-parser.jay"
- { yyVal = new SwitchLabel ((Expression) yyVals[-1+yyTop]); }
- break;
-case 463:
-#line 2235 "cs-parser.jay"
- { yyVal = new SwitchLabel (null); }
- break;
-case 468:
-#line 2247 "cs-parser.jay"
- {
- yyVal = new While ((Expression) yyVals[-2+yyTop], (Statement) yyVals[0+yyTop]);
- }
- break;
-case 469:
-#line 2255 "cs-parser.jay"
- {
- yyVal = new Do ((Statement) yyVals[-5+yyTop], (Expression) yyVals[-2+yyTop]);
- }
- break;
-case 470:
-#line 2266 "cs-parser.jay"
- {
- yyVal = new For ((Statement) yyVals[-6+yyTop], (Expression) yyVals[-4+yyTop], (Statement) yyVals[-2+yyTop], (Statement) yyVals[0+yyTop]);
- }
- break;
-case 471:
-#line 2272 "cs-parser.jay"
- { yyVal = new EmptyStatement (); }
- break;
-case 475:
-#line 2282 "cs-parser.jay"
- { yyVal = new BoolLiteral (true); }
- break;
-case 477:
-#line 2287 "cs-parser.jay"
- { yyVal = new EmptyStatement (); }
- break;
-case 480:
-#line 2297 "cs-parser.jay"
- {
- Block b = new Block (null, true);
-
- b.AddStatement ((Statement) yyVals[0+yyTop]);
- yyVal = b;
- }
- break;
-case 481:
-#line 2304 "cs-parser.jay"
- {
- Block b = (Block) yyVals[-2+yyTop];
-
- b.AddStatement ((Statement) yyVals[0+yyTop]);
- yyVal = yyVals[-2+yyTop];
- }
- break;
-case 482:
-#line 2315 "cs-parser.jay"
- {
- string temp_id = current_block.MakeInternalID ();
- Expression assign_e, ma;
- Statement getcurrent;
- Block foreach_block, child_block;
-
- foreach_block = new Block (current_block, true);
-
- foreach_block.AddVariable (type ("IEnumerator"), temp_id);
- foreach_block.AddVariable ((TypeRef) yyVals[-5+yyTop], (string) yyVals[-4+yyTop]);
- assign_e = new Assign (new LocalVariableReference (foreach_block, temp_id),
- new Invocation (
- new MemberAccess ((Expression) yyVals[-2+yyTop], "GetEnumerator"), null));
- current_block.AddStatement (new StatementExpression (assign_e));
- ma = new MemberAccess (new LocalVariableReference (foreach_block, temp_id), "MoveNext");
- child_block = new Block (current_block);
-
- getcurrent = new StatementExpression (
- new Assign (
- new LocalVariableReference (foreach_block, (string) yyVals[-4+yyTop]),
- new Cast (
- (TypeRef) yyVals[-5+yyTop],
- new MemberAccess (
- new LocalVariableReference (foreach_block, temp_id), "Current"))));
-
- child_block.AddStatement (getcurrent);
- child_block.AddStatement ((Statement) yyVals[0+yyTop]);
- foreach_block.AddStatement (new While (ma, (Statement) child_block));
-
- yyVal = foreach_block;
- }
- break;
-case 488:
-#line 2358 "cs-parser.jay"
- {
- yyVal = new Break ();
- }
- break;
-case 489:
-#line 2365 "cs-parser.jay"
- {
- yyVal = new Continue ();
- }
- break;
-case 490:
-#line 2372 "cs-parser.jay"
- {
- yyVal = new Goto ((string) yyVals[-1+yyTop]);
- }
- break;
-case 493:
-#line 2381 "cs-parser.jay"
- {
- yyVal = new Return ((Expression) yyVals[-1+yyTop]);
- }
- break;
-case 494:
-#line 2388 "cs-parser.jay"
- {
- yyVal = new Throw ((Expression) yyVals[-1+yyTop]);
- }
- break;
-case 497:
-#line 2400 "cs-parser.jay"
- {
- DictionaryEntry cc = (DictionaryEntry) yyVals[0+yyTop];
- ArrayList s = null;
-
- if (cc.Key != null)
- s = (ArrayList) cc.Key;
-
- yyVal = new Try ((Block) yyVals[-1+yyTop], s, (Catch) cc.Value, null);
- }
- break;
-case 498:
-#line 2410 "cs-parser.jay"
- {
- yyVal = new Try ((Block) yyVals[-1+yyTop], null, null, (Block) yyVals[0+yyTop]);
- }
- break;
-case 499:
-#line 2414 "cs-parser.jay"
- {
- DictionaryEntry cc = (DictionaryEntry) yyVals[-1+yyTop];
- ArrayList s = null;
-
- if (cc.Key != null)
- s = (ArrayList) cc.Key;
-
- yyVal = new Try ((Block) yyVals[-2+yyTop], s, (Catch) cc.Value, (Block) yyVals[0+yyTop]);
- }
- break;
-case 500:
-#line 2427 "cs-parser.jay"
- {
- DictionaryEntry pair = new DictionaryEntry ();
-
- pair.Key = yyVals[-1+yyTop];
- pair.Value = yyVals[0+yyTop];
-
- yyVal = pair;
- }
- break;
-case 501:
-#line 2436 "cs-parser.jay"
- {
- DictionaryEntry pair = new DictionaryEntry ();
- pair.Key = yyVals[-1+yyTop];
- pair.Value = yyVals[-1+yyTop];
-
- yyVal = pair;
- }
- break;
-case 502:
-#line 2446 "cs-parser.jay"
- { yyVal = null; }
- break;
-case 504:
-#line 2451 "cs-parser.jay"
- { yyVal = null; }
- break;
-case 506:
-#line 2457 "cs-parser.jay"
- {
- ArrayList l = new ArrayList ();
-
- l.Add (yyVals[0+yyTop]);
- yyVal = l;
- }
- break;
-case 507:
-#line 2464 "cs-parser.jay"
- {
- ArrayList l = (ArrayList) yyVals[-1+yyTop];
-
- l.Add (yyVals[0+yyTop]);
- yyVal = l;
- }
- break;
-case 508:
-#line 2474 "cs-parser.jay"
- {
- string id = null;
-
- if (yyVals[-2+yyTop] != null)
- id = (string) yyVals[-2+yyTop];
-
- yyVal = new Catch ((TypeRef) yyVals[-3+yyTop], id, (Block) yyVals[0+yyTop]);
- }
- break;
-case 509:
-#line 2485 "cs-parser.jay"
- { yyVal = null; }
- break;
-case 511:
-#line 2491 "cs-parser.jay"
- {
- yyVal = new Catch (null, null, (Block) yyVals[0+yyTop]);
- }
- break;
-case 512:
-#line 2498 "cs-parser.jay"
- {
- yyVal = yyVals[0+yyTop];
- }
- break;
-case 513:
-#line 2505 "cs-parser.jay"
- {
- yyVal = new Checked ((Block) yyVals[0+yyTop]);
- }
- break;
-case 514:
-#line 2512 "cs-parser.jay"
- {
- yyVal = new Unchecked ((Block) yyVals[0+yyTop]);
- }
- break;
-case 515:
-#line 2519 "cs-parser.jay"
- {
- yyVal = new Lock ((Expression) yyVals[-2+yyTop], (Statement) yyVals[0+yyTop]);
- }
- break;
-#line 2673 "-"
- }
- yyTop -= yyLen[yyN];
- yyState = yyStates[yyTop];
- int yyM = yyLhs[yyN];
- if (yyState == 0 && yyM == 0) {
- if (yydebug != null) yydebug.shift(0, yyFinal);
- yyState = yyFinal;
- if (yyToken < 0) {
- yyToken = yyLex.advance() ? yyLex.token() : 0;
- if (yydebug != null)
- yydebug.lex(yyState, yyToken,yyname(yyToken), yyLex.value());
- }
- if (yyToken == 0) {
- if (yydebug != null) yydebug.accept(yyVal);
- return yyVal;
- }
- goto yyLoop;
- }
- if (((yyN = yyGindex[yyM]) != 0) && ((yyN += yyState) >= 0)
- && (yyN < yyTable.Length) && (yyCheck[yyN] == yyState))
- yyState = yyTable[yyN];
- else
- yyState = yyDgoto[yyM];
- if (yydebug != null) yydebug.shift(yyStates[yyTop], yyState);
- goto yyLoop;
- }
- }
- }
-
- static short [] yyLhs = { -1,
- 0, 4, 4, 5, 5, 6, 7, 10, 10, 14,
- 11, 15, 15, 16, 16, 12, 12, 9, 13, 1,
- 1, 3, 3, 17, 17, 18, 18, 19, 19, 19,
- 19, 19, 2, 2, 25, 26, 26, 27, 28, 28,
- 30, 31, 31, 31, 29, 29, 32, 32, 33, 34,
- 34, 36, 36, 38, 38, 39, 39, 40, 41, 41,
- 42, 42, 43, 43, 43, 43, 43, 43, 43, 43,
- 43, 43, 55, 21, 54, 54, 57, 57, 58, 56,
- 60, 60, 61, 61, 62, 62, 62, 62, 62, 62,
- 62, 62, 62, 44, 64, 64, 65, 45, 67, 67,
- 68, 68, 69, 69, 46, 71, 71, 72, 72, 74,
- 74, 76, 76, 76, 77, 77, 79, 80, 80, 81,
- 81, 78, 73, 73, 84, 85, 47, 83, 83, 89,
- 89, 87, 87, 86, 91, 88, 90, 90, 93, 22,
- 92, 92, 95, 96, 96, 94, 97, 97, 98, 98,
- 99, 99, 99, 99, 104, 104, 100, 100, 106, 107,
- 101, 105, 105, 105, 105, 102, 108, 109, 103, 50,
- 110, 110, 110, 111, 111, 111, 111, 111, 111, 111,
- 111, 111, 111, 111, 111, 111, 111, 111, 111, 111,
- 111, 111, 111, 111, 111, 112, 112, 51, 113, 114,
- 114, 115, 115, 52, 48, 48, 117, 117, 118, 119,
- 49, 120, 120, 23, 121, 121, 122, 122, 124, 124,
- 125, 125, 126, 126, 24, 35, 8, 63, 63, 63,
- 59, 59, 127, 127, 127, 127, 127, 127, 127, 123,
- 123, 123, 123, 123, 123, 123, 123, 123, 82, 128,
- 130, 130, 130, 130, 130, 130, 130, 130, 130, 130,
- 130, 130, 130, 130, 130, 131, 131, 131, 131, 131,
- 131, 147, 147, 147, 146, 145, 145, 132, 133, 133,
- 148, 134, 116, 116, 149, 149, 150, 150, 150, 151,
- 135, 152, 152, 136, 137, 137, 138, 139, 140, 140,
- 153, 154, 155, 155, 129, 129, 157, 158, 158, 159,
- 159, 156, 156, 70, 70, 70, 160, 160, 141, 142,
- 143, 144, 161, 161, 161, 161, 161, 161, 161, 161,
- 161, 161, 162, 163, 164, 164, 165, 165, 165, 165,
- 166, 166, 166, 167, 167, 167, 168, 168, 168, 168,
- 168, 168, 168, 169, 169, 169, 170, 170, 171, 171,
- 172, 172, 173, 173, 174, 174, 175, 175, 176, 176,
- 176, 176, 176, 176, 176, 176, 176, 176, 176, 37,
- 37, 66, 177, 179, 20, 53, 53, 180, 180, 181,
- 181, 181, 181, 181, 181, 181, 181, 181, 181, 181,
- 181, 178, 178, 182, 184, 75, 183, 183, 185, 185,
- 186, 186, 186, 188, 188, 188, 188, 188, 188, 188,
- 188, 188, 188, 188, 190, 189, 187, 187, 202, 202,
- 202, 203, 203, 204, 204, 205, 200, 201, 191, 206,
- 206, 206, 206, 206, 206, 206, 207, 192, 192, 208,
- 208, 209, 210, 211, 211, 212, 212, 215, 213, 214,
- 214, 216, 216, 193, 193, 193, 193, 217, 218, 219,
- 221, 221, 224, 224, 222, 222, 223, 223, 226, 225,
- 225, 220, 194, 194, 194, 194, 194, 227, 228, 229,
- 229, 229, 230, 231, 232, 232, 195, 195, 195, 233,
- 233, 236, 236, 237, 237, 235, 235, 239, 240, 240,
- 238, 234, 196, 197, 198, 199, 241,
- };
- static short [] yyLen = { 2,
- 4, 1, 2, 1, 1, 5, 3, 1, 2, 0,
- 5, 0, 1, 0, 1, 1, 3, 1, 4, 0,
- 1, 0, 1, 1, 2, 1, 1, 1, 1, 1,
- 1, 1, 0, 1, 1, 1, 2, 4, 0, 1,
- 2, 1, 1, 1, 1, 3, 1, 1, 1, 0,
- 3, 1, 3, 0, 1, 1, 2, 3, 0, 1,
- 1, 2, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 0, 8, 0, 1, 1, 2, 2, 3,
- 0, 1, 1, 2, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 6, 1, 3, 3, 5, 1, 3,
- 3, 1, 1, 1, 2, 7, 7, 1, 1, 0,
- 1, 1, 3, 1, 1, 3, 4, 0, 1, 1,
- 1, 4, 1, 3, 0, 0, 9, 2, 2, 0,
- 1, 0, 1, 3, 0, 4, 1, 1, 0, 7,
- 0, 1, 2, 1, 3, 3, 0, 1, 1, 2,
- 1, 1, 1, 1, 0, 1, 8, 8, 0, 0,
- 9, 3, 3, 6, 6, 6, 0, 0, 12, 4,
- 7, 10, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 7, 7, 4, 5, 0,
- 1, 5, 5, 6, 6, 9, 2, 2, 3, 3,
- 6, 5, 7, 7, 0, 2, 3, 4, 0, 1,
- 1, 3, 2, 4, 9, 1, 1, 1, 1, 1,
- 1, 2, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 2,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 3, 3, 3,
- 1, 4, 0, 1, 1, 3, 1, 2, 2, 1,
- 4, 1, 3, 1, 3, 4, 2, 2, 1, 1,
- 5, 7, 0, 1, 1, 2, 3, 0, 1, 1,
- 2, 0, 1, 2, 3, 4, 1, 3, 4, 4,
- 4, 4, 1, 2, 2, 2, 2, 2, 2, 1,
- 1, 1, 2, 2, 4, 4, 1, 3, 3, 3,
- 1, 3, 3, 1, 3, 3, 1, 3, 3, 3,
- 3, 3, 3, 1, 3, 3, 1, 3, 1, 3,
- 1, 3, 1, 3, 1, 3, 1, 5, 3, 3,
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 1,
- 1, 1, 1, 0, 8, 0, 1, 1, 2, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 0, 1, 2, 0, 4, 0, 1, 1, 2,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 3, 2, 2, 2, 2,
- 2, 0, 1, 1, 2, 3, 2, 3, 2, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 5,
- 7, 5, 3, 0, 1, 1, 2, 0, 3, 1,
- 2, 3, 2, 1, 1, 1, 1, 5, 7, 9,
- 0, 1, 1, 1, 0, 1, 0, 1, 1, 1,
- 3, 8, 1, 1, 1, 1, 1, 2, 2, 3,
- 4, 3, 3, 3, 0, 1, 3, 3, 4, 2,
- 2, 0, 1, 0, 1, 1, 2, 6, 0, 1,
- 2, 2, 2, 2, 5, 5, 2,
- };
- static short [] yyDefRed = { 0,
- 0, 0, 0, 0, 2, 4, 5, 0, 18, 0,
- 0, 0, 0, 34, 0, 36, 3, 0, 7, 0,
- 43, 44, 42, 0, 40, 0, 0, 0, 0, 27,
- 0, 24, 26, 28, 29, 30, 31, 32, 37, 16,
- 0, 17, 0, 226, 0, 45, 47, 48, 49, 41,
- 0, 395, 401, 393, 390, 400, 394, 392, 391, 398,
- 396, 397, 399, 0, 0, 388, 1, 25, 6, 0,
- 235, 241, 248, 0, 236, 238, 277, 237, 244, 246,
- 0, 271, 233, 240, 242, 0, 234, 294, 276, 0,
- 245, 247, 0, 243, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 275, 272, 273, 274, 269, 270, 0,
- 0, 52, 239, 281, 0, 251, 253, 254, 255, 256,
- 257, 258, 259, 260, 261, 262, 263, 264, 265, 266,
- 267, 268, 0, 299, 300, 0, 330, 331, 332, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 380,
- 381, 38, 0, 0, 0, 0, 0, 0, 0, 389,
- 0, 0, 0, 228, 0, 229, 230, 0, 0, 0,
- 0, 0, 0, 327, 324, 325, 326, 329, 328, 333,
- 334, 51, 0, 0, 0, 0, 297, 298, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 46, 0, 0, 384, 0, 0, 139, 73, 292,
- 0, 295, 0, 0, 0, 0, 305, 0, 0, 0,
- 0, 278, 0, 53, 0, 0, 0, 287, 0, 0,
- 285, 279, 280, 369, 370, 371, 372, 373, 374, 375,
- 376, 377, 379, 378, 338, 340, 339, 337, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 13, 11, 0,
- 0, 0, 0, 0, 0, 0, 296, 0, 321, 310,
- 0, 0, 0, 0, 306, 320, 319, 322, 335, 336,
- 291, 290, 289, 288, 282, 0, 0, 0, 0, 0,
- 403, 0, 216, 0, 0, 0, 0, 142, 0, 0,
- 0, 77, 293, 0, 307, 311, 301, 286, 368, 19,
- 0, 0, 0, 0, 0, 0, 0, 114, 115, 0,
- 0, 0, 221, 214, 249, 144, 0, 0, 140, 0,
- 0, 0, 78, 0, 0, 0, 0, 72, 0, 0,
- 61, 63, 64, 65, 66, 67, 68, 69, 70, 71,
- 0, 385, 121, 0, 120, 0, 119, 0, 0, 0,
- 217, 0, 0, 0, 0, 0, 149, 151, 152, 153,
- 154, 0, 93, 85, 86, 87, 88, 89, 90, 91,
- 92, 0, 0, 83, 74, 0, 313, 302, 0, 0,
- 58, 62, 405, 109, 105, 108, 0, 0, 225, 113,
- 116, 0, 218, 222, 145, 156, 0, 146, 150, 80,
- 84, 314, 103, 317, 104, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 173, 0, 0, 0, 122,
- 117, 224, 0, 0, 0, 315, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 99, 0, 0, 170, 198, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 425, 0, 414, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 442, 0, 0, 409,
- 411, 412, 413, 415, 416, 417, 418, 419, 420, 421,
- 422, 423, 424, 0, 0, 0, 0, 441, 448, 449,
- 464, 465, 466, 467, 483, 484, 485, 486, 487, 0,
- 0, 0, 0, 316, 318, 0, 0, 0, 95, 0,
- 0, 0, 0, 0, 0, 0, 111, 179, 178, 175,
- 180, 181, 174, 193, 192, 185, 186, 182, 184, 183,
- 187, 176, 177, 188, 189, 195, 194, 190, 191, 0,
- 0, 0, 0, 98, 125, 0, 0, 0, 0, 0,
- 0, 488, 513, 0, 489, 0, 0, 0, 0, 0,
- 0, 0, 0, 496, 0, 0, 0, 0, 514, 0,
- 0, 431, 0, 434, 0, 0, 430, 0, 429, 406,
- 410, 427, 428, 0, 0, 439, 0, 0, 0, 159,
- 0, 204, 0, 0, 94, 205, 0, 0, 0, 0,
- 124, 0, 0, 0, 101, 100, 0, 0, 0, 0,
- 135, 211, 0, 128, 133, 0, 131, 129, 438, 0,
- 473, 480, 0, 472, 0, 0, 382, 0, 492, 490,
- 383, 0, 0, 493, 0, 494, 0, 0, 0, 498,
- 0, 0, 506, 0, 0, 0, 0, 0, 435, 0,
- 426, 166, 0, 0, 0, 0, 97, 96, 0, 0,
- 0, 0, 0, 0, 107, 0, 199, 201, 0, 212,
- 126, 106, 0, 138, 137, 134, 0, 0, 0, 0,
- 0, 491, 0, 0, 0, 0, 512, 499, 0, 500,
- 503, 507, 0, 501, 517, 0, 436, 0, 0, 0,
- 0, 160, 0, 0, 0, 0, 0, 207, 0, 208,
- 0, 0, 0, 0, 0, 0, 0, 136, 0, 476,
- 0, 481, 0, 0, 515, 0, 452, 0, 511, 516,
- 468, 158, 167, 0, 0, 0, 157, 209, 210, 206,
- 197, 196, 0, 0, 171, 0, 127, 213, 0, 0,
- 0, 0, 0, 0, 0, 0, 456, 0, 460, 510,
- 0, 0, 0, 0, 161, 0, 0, 0, 469, 0,
- 0, 478, 0, 451, 0, 463, 453, 457, 0, 461,
- 0, 168, 0, 0, 202, 203, 0, 0, 482, 462,
- 0, 508, 0, 0, 0, 172, 470, 169, 164, 165,
- };
- protected static short [] yyDgoto = { 2,
- 3, 345, 29, 4, 5, 6, 7, 44, 10, 0,
- 30, 110, 224, 154, 289, 0, 31, 32, 33, 34,
- 35, 36, 37, 38, 14, 15, 16, 24, 45, 25,
- 26, 46, 47, 48, 164, 111, 248, 0, 0, 344,
- 369, 370, 371, 372, 373, 374, 375, 376, 377, 378,
- 379, 380, 420, 330, 296, 362, 331, 332, 341, 412,
- 413, 414, 342, 558, 559, 678, 480, 481, 444, 445,
- 381, 425, 474, 566, 507, 567, 347, 348, 349, 386,
- 387, 475, 599, 657, 766, 600, 664, 601, 668, 726,
- 727, 327, 295, 359, 328, 357, 395, 396, 397, 398,
- 399, 400, 401, 437, 752, 705, 786, 812, 843, 455,
- 590, 456, 457, 717, 718, 249, 710, 711, 712, 458,
- 294, 325, 113, 351, 352, 353, 114, 167, 236, 115,
- 116, 117, 118, 119, 120, 121, 122, 123, 124, 125,
- 126, 127, 128, 129, 130, 131, 132, 133, 250, 251,
- 313, 245, 134, 135, 365, 418, 237, 302, 303, 446,
- 136, 137, 138, 139, 140, 141, 142, 143, 144, 145,
- 146, 147, 148, 149, 150, 151, 682, 320, 290, 65,
- 66, 321, 518, 459, 519, 520, 521, 522, 523, 524,
- 525, 526, 527, 528, 529, 530, 531, 532, 533, 534,
- 535, 536, 629, 623, 624, 537, 538, 539, 540, 777,
- 805, 806, 807, 808, 829, 809, 541, 542, 543, 544,
- 673, 771, 820, 674, 675, 822, 545, 546, 547, 548,
- 549, 615, 689, 690, 691, 740, 692, 741, 693, 811,
- 697,
- };
- protected static short [] yySindex = { -312,
- -236, 0, -116, -312, 0, 0, 0, -97, 0, -56,
- -15, -273, -90, 0, -116, 0, 0, -49, 0, -44,
- 0, 0, 0, -328, 0, 69, -49, 4393, 166, 0,
- -90, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 63, 0, 8029, 0, -58, 0, 0, 0, 0, 0,
- -15, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 36, 4393, 0, 0, 0, 0, 19,
- 0, 0, 0, 86, 0, 0, 0, 0, 0, 0,
- 468, 0, 0, 0, 0, 90, 0, 0, 0, 95,
- 0, 0, 98, 0, 8029, 8029, 8029, 8029, 8029, 8029,
- 8029, 8029, 8029, 0, 0, 0, 0, 0, 0, -15,
- 88, 0, 0, 0, 74, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 111, 0, 0, 429, 0, 0, 0, -9,
- -51, 78, -155, 73, 112, 118, 126, 96, -295, 0,
- 0, 0, -328, 158, 83, 468, 87, 91, 100, 0,
- 8029, 101, 8029, 0, 116, 0, 0, 468, 468, 8029,
- -293, 168, 171, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 8029, 8029, 6957, 102, 0, 0, 103, 8029,
- 8029, 8029, 8029, 8029, 8029, 8029, 8029, 8029, 8029, 8029,
- 8029, 8029, 8029, 8029, 8029, 8029, 8029, 468, 468, 8029,
- 8029, 8029, 8029, 8029, 8029, 8029, 8029, 8029, 8029, 8029,
- 8029, 0, -312, 173, 0, -310, 175, 0, 0, 0,
- 33, 0, 179, 7493, 6957, 184, 0, -186, -87, 182,
- 8029, 0, 8029, 0, 34, 8029, 8029, 0, 183, 185,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, -9, -9,
- -51, -51, 184, 184, 78, 78, 78, 78, -155, -155,
- 73, 112, 118, 126, 193, 96, -90, 0, 0, 194,
- 186, 187, 31, 190, 196, 199, 0, 8029, 0, 0,
- 35, 200, 201, 204, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 6957, 8029, 210, 468, 213,
- 0, -116, 0, -116, 173, -49, 216, 0, 468, 217,
- 199, 0, 0, 184, 0, 0, 0, 0, 0, 0,
- 468, 184, -116, 173, 38, 215, 218, 0, 0, 149,
- 222, 221, 0, 0, 0, 0, 223, -116, 0, 468,
- -116, 173, 0, 184, 224, 184, 4236, 0, 230, -116,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- -299, 0, 0, 468, 0, 468, 0, 225, -116, 219,
- 0, -19, -49, 275, 235, -116, 0, 0, 0, 0,
- 0, 4393, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 236, -116, 0, 0, 7091, 0, 0, 162, 8233,
- 0, 0, 0, 0, 0, 0, -305, -287, 0, 0,
- 0, 8029, 0, 0, 0, 0, 8585, 0, 0, 0,
- 0, 0, 0, 0, 0, -60, 234, 468, 468, 276,
- 278, 164, 240, -208, 249, 0, 249, 251, 4633, 0,
- 0, 0, 468, 174, -265, 0, 7225, 250, -276, -266,
- 468, 468, 0, 254, 247, -116, 661, 252, 246, 119,
- 0, 43, 255, 0, 0, -116, 256, 54, 468, 258,
- 4947, 259, 266, -263, 267, 269, 8029, 272, 8029, 249,
- 64, 274, 279, 280, 0, 277, 0, 279, 79, 0,
- 0, 0, 0, 429, 0, 0, 0, 281, 4633, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 271, 282, 209, 285, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, -256,
- 284, 288, 70, 0, 0, 249, 283, 125, 0, 134,
- 286, 145, 146, -116, 227, 291, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 295,
- -116, 7627, 209, 0, 0, -116, -308, 155, 299, -116,
- -116, 0, 0, -276, 0, 311, 7761, 468, 8029, 300,
- 301, 8029, 8029, 0, 305, 8029, 308, -241, 0, 8163,
- 186, 0, 279, 0, 8029, 4633, 0, 7493, 0, 0,
- 0, 0, 0, 246, 312, 0, 309, -116, -116, 0,
- -116, 0, 8029, 243, 0, 0, -116, 468, 468, 317,
- 0, 315, 468, 321, 0, 0, -116, 322, 329, -36,
- 0, 0, 334, 0, 0, 339, 0, 0, 0, 336,
- 0, 0, 332, 0, 331, -239, 0, 333, 0, 0,
- 0, 338, 340, 0, 342, 0, 344, 249, 400, 0,
- 422, 423, 0, 8029, 79, 8029, 348, 351, 0, 350,
- 0, 0, 352, 353, -116, 359, 0, 0, -212, 364,
- -116, -116, -238, -233, 0, -240, 0, 0, -231, 0,
- 0, 0, -116, 0, 0, 0, -36, 8029, 8029, 8029,
- 414, 0, 4947, 4947, 369, 468, 0, 0, 75, 0,
- 0, 0, 249, 0, 0, 4947, 0, 4947, 361, 371,
- 156, 0, 363, 249, 249, 367, 405, 0, 452, 0,
- 377, 378, 380, 381, 152, 386, 385, 0, 384, 0,
- 383, 0, 8029, 456, 0, -61, 0, -226, 0, 0,
- 0, 0, 0, 388, 389, 394, 0, 0, 0, 0,
- 0, 0, 6957, 6957, 0, 468, 0, 0, 391, 8029,
- 397, 4947, 8029, 382, 403, -61, 0, -61, 0, 0,
- 406, -116, -116, -116, 0, 407, 410, -194, 0, 413,
- 331, 0, 4947, 0, 415, 0, 0, 0, 4633, 0,
- 249, 0, 427, 412, 0, 0, 424, 4947, 0, 0,
- 4633, 0, 430, 419, 426, 0, 0, 0, 0, 0,
- };
- protected static short [] yyRindex = { 8996,
- 0, 0, 9143, 8886, 0, 0, 0, -76, 0, 0,
- 2129, 28, 9198, 0, 813, 0, 0, 0, 0, 0,
- 0, 0, 0, 81, 0, 0, 0, 85, 0, 0,
- 9051, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 433, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 8315, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 1681,
- 0, 0, 0, 0, 1838, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 1995, 0, 0, 0, 2397,
- 2799, 2933, 5081, 5483, 5751, 5885, 6287, 6555, 6823, 0,
- 0, 0, 81, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 8741, 0, 432, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 434, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 9073, 8941, 0, 0, 440, 0, 0, 0,
- 0, 0, 0, 442, 434, 2263, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 443,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 2531, 2665,
- 3067, 3201, 3335, 3469, 3603, 3737, 3871, 4005, 5215, 5349,
- 5617, 6019, 6153, 6421, 0, 6689, 9126, 0, 0, 449,
- 442, 0, 0, 0, 450, 451, 0, 0, 0, 0,
- 0, 0, 454, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 8553, 0, -318, -235, 0, 0, 0, 0, 0,
- 453, 0, 0, 1210, 0, 0, 0, 0, 0, 0,
- 458, 8632, 889, -235, 8742, 0, 157, 0, 0, 0,
- 0, 459, 0, 0, 0, 0, 461, 8426, 0, -80,
- 1051, -235, 0, 1367, 1524, 8668, 8382, 0, 0, 970,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 8553, -29,
- 0, 374, 0, 8720, 0, 8478, 0, 0, 0, 0,
- 0, 8382, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 1130, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, -225, 0, 0, 0, 0, 0, 463, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 160, 0, 0, 8509, 0, 0, -12, 0,
- 0, 0, 0, 0, 0, 172, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 445, 0, 445, 0,
- 0, 0, 387, 0, 0, 9299, 0, -327, -108, 9155,
- 9178, 9237, 9248, 0, 584, 1195, 0, 0, 465, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 8509, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 8553, 0, 0, 0, 0, 8509, 0, 0, 0, 2,
- -150, 0, 0, 0, 0, 0, 462, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 442, 0, 402, 0, 0, 0, 0, 442, 0, 0,
- 0, 0, 0, 7359, 7895, 0, 0, 8509, 8553, 0,
- 8509, 0, 0, 0, 0, 0, -115, 0, 0, 0,
- 0, 467, 0, 0, 0, 0, 172, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 473, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 4319, 0,
- 4162, 0, 0, 0, 387, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 172, 0, 0, 0, 0, 0,
- 499, 563, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 8553, 0, 0, 0, 0, 0, 481, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 4476, 0, 491, 0, 489, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 434, 434, 0, 0, 0, 0, 0, 490,
- 0, 0, 0, 0, 0, 496, 0, 4790, 0, 0,
- 0, 172, 48, 5, 0, 0, 0, 0, 0, 0,
- 493, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- -123, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- };
- protected static short [] yyGindex = { 0,
- 618, -3, 555, 0, 839, 0, 0, 195, 0, 0,
- 0, 8, 0, 0, -45, 0, 0, 814, -158, 0,
- 0, 0, 0, 0, 0, 0, 834, 0, 0, 0,
- 0, 698, 0, 0, -22, 0, -25, 0, 0, 0,
- 0, 0, 482, -206, -161, -156, -153, -146, -135, -110,
- -107, 0, 825, 0, 0, 0, 0, 523, 528, 0,
- 0, 446, 229, 0, -454, -624, -415, 268, -453, 501,
- 0, 0, -272, -501, -192, -319, 0, 475, 478, 0,
- 0, -321, 212, 0, 0, 270, 0, 273, 0, 147,
- 0, 0, 0, 0, 0, 0, 0, 0, 476, 0,
- 0, 0, 0, 0, 68, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, -234, 0, 163, 165, 0,
- 0, 0, 586, 0, 0, 494, 67, 0, 549, -429,
- 0, 0, 0, -193, 0, 0, 0, 17, 114, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 572,
- 643, -10, 151, 0, 0, 0, -223, -306, 0, 0,
- 27, 161, 208, 0, 198, 248, 253, 298, 676, 681,
- 675, 682, 679, 0, 0, 263, -609, 0, 0, 0,
- 837, 0, 0, 0, 76, -513, 0, -484, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, -558,
- 0, 0, -134, 0, 287, -596, 0, 0, 0, 0,
- 0, 0, 97, 0, 0, 104, 0, 0, 0, 0,
- 0, 0, 0, 0, 106, 0, 0, 0, 0, 0,
- 0, 416, 0, 228, 0, 0, 0, 226, 220, 0,
- 0,
- };
- protected static short [] yyTable = { 13,
- 304, 49, 346, 609, 356, 631, 606, 21, 11, 28,
- 672, 610, 305, 555, 659, 700, 43, 112, 707, 281,
- 1, 12, 763, 219, 12, 11, 687, 28, 12, 509,
- 12, 11, 291, 12, 51, 12, 12, 291, 12, 22,
- 12, 423, 12, 688, 12, 12, 12, 12, 671, 754,
- 424, 12, 241, 20, 560, 291, 12, 552, 12, 12,
- 12, 696, 650, 12, 12, 12, 291, 12, 220, 172,
- 12, 435, 12, 12, 12, 12, 291, 291, 16, 12,
- 12, 12, 764, 12, 12, 12, 291, 221, 11, 509,
- 40, 432, 12, 12, 658, 477, 12, 16, 12, 12,
- 33, 755, 171, 291, 291, 208, 12, 12, 292, 291,
- 651, 291, 701, 460, 478, 12, 291, 16, 769, 770,
- 635, 16, 174, 175, 176, 177, 178, 179, 180, 181,
- 49, 461, 483, 772, 291, 230, 703, 233, 655, 706,
- 305, 209, 557, 459, 240, 23, 33, 166, 291, 669,
- 231, 459, 479, 553, 404, 611, 291, 244, 230, 306,
- 11, 173, 637, 11, 254, 255, 256, 257, 258, 259,
- 260, 261, 262, 263, 264, 11, 11, 509, 825, 731,
- 761, 482, 8, 12, 368, 762, 33, 765, 426, 708,
- 695, 130, 810, 16, 285, 9, 509, 561, 33, 405,
- 210, 211, 403, 672, 406, 803, 404, 407, 230, 27,
- 479, 368, 41, 804, 408, 11, 11, 212, 459, 213,
- 312, 312, 166, 301, 837, 409, 12, 265, 266, 267,
- 268, 268, 268, 268, 166, 166, 268, 268, 268, 268,
- 268, 268, 268, 268, 268, 268, 323, 268, 774, 775,
- 410, 405, 12, 411, 403, 291, 406, 18, 307, 407,
- 79, 780, 484, 781, 485, 510, 408, 309, 79, 310,
- 16, 654, 333, 16, 166, 166, 323, 409, 323, 354,
- 323, 466, 323, 28, 323, 152, 323, 467, 323, 153,
- 323, 339, 323, 19, 323, 603, 72, 510, 382, 73,
- 204, 205, 410, 355, 423, 411, 155, 618, 619, 165,
- 432, 156, 223, 724, 698, 157, 415, 824, 223, 704,
- 350, 698, 433, 12, 79, 510, 11, 631, 123, 80,
- 158, 20, 123, 11, 16, 102, 11, 102, 839, 367,
- 33, 33, 383, 132, 384, 84, 163, 85, 11, 385,
- 201, 202, 203, 847, 394, 386, 159, 402, 91, 92,
- 386, 161, 94, 642, 386, 162, 367, 11, 622, 40,
- 355, 39, 39, 627, 42, 39, 297, 311, 334, 386,
- 298, 298, 298, 595, 226, 166, 33, 596, 350, 162,
- 443, 11, 394, 11, 423, 166, 238, 239, 163, 509,
- 11, 269, 270, 767, 423, 386, 462, 166, 170, 402,
- 640, 509, 69, 510, 641, 423, 184, 50, 185, 736,
- 186, 628, 67, 185, 50, 186, 166, 11, 50, 355,
- 163, 355, 510, 182, 168, 183, 273, 274, 187, 169,
- 188, 443, 170, 187, 11, 188, 206, 355, 207, 214,
- 166, 215, 166, 271, 272, 11, 11, 189, 234, 11,
- 235, 11, 275, 276, 277, 278, 593, 725, 594, 216,
- 11, 614, 644, 614, 645, 511, 219, 11, 11, 11,
- 217, 593, 598, 646, 218, 514, 166, 291, 291, 648,
- 649, 660, 784, 661, 785, 737, 11, 795, 223, 796,
- 112, 225, 112, 166, 123, 227, 16, 511, 33, 228,
- 33, 279, 280, 242, 166, 166, 243, 514, 229, 232,
- 252, 253, 288, 293, 299, 508, 291, 308, 315, 166,
- 324, 322, 316, 300, 725, 511, 510, 166, 166, 510,
- 510, 317, 319, 335, 326, 514, 779, 329, 336, 337,
- 779, 340, 510, 343, 510, 166, 358, 361, 816, 817,
- 388, 788, 789, 391, 416, 389, 443, 390, 392, 366,
- 393, 421, 512, 432, 429, 436, 438, 440, 468, 471,
- 447, 472, 473, 677, 476, 508, 681, 683, 366, 423,
- 685, 486, 551, 565, 591, 556, 663, 666, 564, 681,
- 592, 597, 230, 607, 512, 602, 510, 605, 510, 513,
- 608, 612, 427, 613, 428, 11, 616, 677, 620, 515,
- 632, 621, 630, 511, 625, 626, 647, 634, 638, 510,
- 639, 633, 512, 514, 636, 510, 652, 643, 842, 653,
- 662, 513, 511, 709, 510, 651, 670, 510, 454, 679,
- 680, 515, 514, 598, 684, 11, 11, 686, 702, 593,
- 11, 557, 715, 716, 720, 465, 516, 722, 172, 513,
- 745, 723, 661, 508, 166, 660, 469, 470, 730, 515,
- 728, 729, 732, 733, 688, 734, 508, 735, 736, 739,
- 743, 550, 508, 746, 747, 748, 750, 749, 516, 562,
- 563, 751, 681, 681, 753, 756, 773, 757, 759, 776,
- 782, 783, 787, 754, 166, 166, 790, 604, 755, 166,
- 512, 517, 791, 792, 793, 794, 516, 797, 798, 799,
- 826, 71, 800, 72, 802, 815, 73, 813, 814, 512,
- 819, 75, 823, 11, 827, 76, 511, 801, 845, 511,
- 511, 831, 835, 517, 78, 836, 514, 513, 838, 514,
- 514, 79, 511, 840, 511, 844, 80, 515, 849, 846,
- 83, 848, 514, 10, 514, 850, 513, 677, 281, 283,
- 215, 517, 84, 190, 85, 308, 515, 87, 284, 402,
- 141, 75, 33, 76, 495, 91, 92, 309, 404, 94,
- 220, 143, 166, 11, 407, 432, 408, 200, 751, 833,
- 834, 471, 33, 191, 516, 192, 511, 193, 511, 194,
- 433, 195, 474, 196, 33, 197, 514, 198, 514, 199,
- 475, 200, 454, 516, 509, 477, 676, 455, 479, 511,
- 287, 318, 17, 512, 68, 511, 512, 512, 39, 514,
- 222, 422, 64, 363, 511, 514, 360, 511, 441, 512,
- 656, 512, 166, 430, 514, 417, 431, 514, 721, 517,
- 667, 439, 665, 768, 760, 758, 713, 714, 323, 832,
- 513, 719, 364, 513, 513, 434, 40, 338, 517, 314,
- 515, 281, 283, 515, 515, 508, 513, 282, 513, 286,
- 284, 160, 828, 0, 841, 821, 515, 508, 515, 699,
- 742, 830, 0, 512, 617, 512, 738, 744, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 445,
- 0, 445, 0, 445, 0, 0, 512, 516, 330, 0,
- 516, 516, 512, 0, 568, 0, 0, 0, 0, 0,
- 513, 512, 513, 516, 512, 516, 0, 0, 0, 0,
- 515, 0, 515, 0, 778, 0, 0, 0, 330, 0,
- 330, 0, 330, 513, 330, 0, 330, 0, 330, 513,
- 330, 0, 330, 515, 330, 569, 330, 0, 513, 515,
- 0, 513, 517, 0, 0, 517, 517, 0, 515, 0,
- 0, 515, 0, 0, 0, 0, 0, 516, 517, 516,
- 517, 570, 571, 572, 573, 0, 574, 575, 576, 577,
- 578, 579, 580, 581, 818, 582, 0, 583, 0, 584,
- 516, 585, 0, 586, 0, 587, 516, 588, 0, 589,
- 0, 0, 0, 0, 0, 516, 0, 0, 516, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 517, 0, 517, 0, 0, 0, 0, 35,
- 0, 0, 35, 0, 35, 0, 35, 0, 35, 0,
- 0, 35, 0, 35, 35, 517, 35, 0, 35, 0,
- 35, 517, 35, 35, 35, 35, 0, 0, 0, 35,
- 517, 0, 0, 517, 35, 0, 35, 35, 35, 0,
- 0, 35, 35, 35, 0, 35, 0, 35, 35, 35,
- 35, 35, 35, 35, 35, 0, 35, 35, 35, 35,
- 0, 35, 35, 35, 0, 0, 0, 0, 0, 0,
- 35, 35, 0, 0, 35, 0, 35, 35, 33, 35,
- 0, 35, 33, 0, 33, 0, 0, 33, 0, 33,
- 33, 0, 33, 35, 33, 0, 33, 0, 33, 33,
- 33, 33, 0, 0, 0, 33, 0, 0, 0, 0,
- 33, 0, 33, 33, 33, 0, 0, 33, 0, 33,
- 0, 33, 0, 0, 33, 0, 33, 33, 33, 33,
- 0, 0, 0, 33, 33, 33, 0, 33, 33, 33,
- 0, 0, 0, 0, 0, 0, 33, 33, 0, 0,
- 33, 0, 33, 33, 0, 0, 0, 0, 0, 33,
- 59, 35, 0, 33, 0, 33, 0, 0, 33, 33,
- 33, 33, 0, 33, 0, 33, 0, 33, 0, 33,
- 33, 33, 33, 0, 0, 0, 33, 0, 0, 0,
- 0, 33, 0, 33, 33, 33, 0, 0, 33, 0,
- 33, 0, 33, 0, 0, 33, 0, 33, 33, 33,
- 33, 0, 0, 0, 33, 33, 33, 0, 33, 33,
- 33, 0, 0, 0, 0, 0, 0, 33, 33, 0,
- 0, 33, 0, 33, 33, 0, 0, 33, 0, 0,
- 33, 60, 0, 0, 33, 0, 33, 0, 0, 33,
- 33, 33, 33, 0, 33, 0, 33, 0, 33, 0,
- 33, 33, 33, 33, 0, 0, 0, 33, 0, 0,
- 0, 0, 33, 0, 33, 33, 33, 0, 0, 33,
- 0, 33, 0, 33, 0, 0, 33, 0, 33, 33,
- 33, 33, 0, 0, 0, 33, 33, 33, 0, 33,
- 33, 33, 0, 0, 0, 0, 0, 0, 33, 33,
- 0, 0, 33, 0, 33, 33, 0, 0, 33, 33,
- 0, 0, 81, 33, 0, 33, 0, 0, 33, 0,
- 33, 33, 0, 33, 0, 33, 0, 33, 0, 33,
- 33, 33, 33, 0, 0, 0, 33, 0, 0, 0,
- 0, 33, 0, 33, 33, 33, 0, 0, 33, 0,
- 33, 0, 33, 0, 0, 33, 0, 33, 33, 33,
- 33, 0, 0, 0, 33, 33, 33, 0, 33, 33,
- 33, 0, 0, 0, 0, 0, 0, 33, 33, 0,
- 0, 33, 0, 33, 33, 0, 0, 0, 0, 33,
- 303, 82, 303, 303, 0, 303, 0, 0, 303, 303,
- 0, 0, 0, 303, 0, 0, 0, 303, 0, 0,
- 0, 0, 0, 303, 0, 0, 303, 0, 0, 0,
- 0, 0, 0, 303, 0, 0, 303, 0, 303, 0,
- 303, 303, 303, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 303, 0, 303, 303, 0, 303,
- 0, 0, 303, 0, 303, 0, 303, 303, 303, 303,
- 446, 303, 446, 0, 446, 0, 0, 0, 33, 331,
- 303, 303, 0, 303, 303, 303, 303, 303, 303, 303,
- 303, 303, 303, 303, 303, 303, 303, 303, 303, 303,
- 303, 303, 303, 303, 303, 0, 303, 0, 303, 331,
- 303, 331, 303, 331, 303, 331, 303, 331, 303, 331,
- 303, 331, 303, 331, 303, 331, 303, 331, 303, 0,
- 303, 0, 303, 0, 303, 0, 303, 0, 303, 0,
- 303, 0, 303, 0, 0, 0, 303, 0, 303, 0,
- 303, 0, 303, 0, 303, 0, 303, 304, 303, 304,
- 304, 0, 304, 0, 0, 304, 304, 0, 0, 0,
- 304, 0, 0, 0, 304, 0, 0, 0, 0, 0,
- 304, 0, 0, 304, 0, 0, 0, 0, 0, 0,
- 304, 0, 0, 304, 0, 304, 0, 304, 304, 304,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 304, 0, 304, 304, 0, 304, 0, 0, 304,
- 0, 304, 0, 304, 304, 304, 304, 0, 304, 0,
- 0, 0, 0, 0, 0, 0, 0, 304, 304, 0,
- 304, 304, 304, 304, 304, 304, 304, 304, 304, 304,
- 304, 304, 304, 304, 304, 304, 304, 304, 304, 304,
- 304, 304, 0, 304, 0, 304, 0, 304, 0, 304,
- 0, 304, 0, 304, 0, 304, 0, 304, 0, 304,
- 0, 304, 0, 304, 0, 304, 0, 304, 0, 304,
- 0, 304, 0, 304, 0, 304, 0, 304, 0, 304,
- 0, 0, 0, 304, 0, 304, 0, 304, 0, 304,
- 0, 304, 0, 304, 312, 304, 312, 312, 0, 312,
- 0, 0, 312, 312, 0, 0, 0, 312, 0, 0,
- 0, 312, 0, 0, 0, 0, 0, 312, 0, 0,
- 312, 0, 0, 0, 0, 0, 0, 312, 0, 0,
- 312, 0, 312, 0, 312, 312, 312, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 312, 0,
- 312, 312, 0, 312, 0, 0, 312, 0, 312, 0,
- 312, 312, 312, 312, 0, 312, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 312, 312, 312, 312, 312,
- 312, 312, 312, 312, 312, 312, 312, 312, 312, 312,
- 312, 312, 312, 312, 312, 312, 312, 312, 312, 0,
- 312, 0, 312, 0, 312, 0, 312, 0, 312, 0,
- 312, 0, 312, 0, 312, 0, 312, 0, 312, 0,
- 312, 0, 312, 0, 312, 0, 312, 0, 312, 0,
- 312, 0, 312, 0, 312, 0, 312, 0, 0, 0,
- 312, 0, 312, 0, 312, 0, 312, 0, 312, 0,
- 312, 252, 312, 252, 252, 0, 252, 0, 0, 252,
- 252, 0, 0, 0, 252, 0, 0, 0, 252, 0,
- 0, 0, 0, 0, 252, 0, 0, 252, 0, 0,
- 0, 0, 0, 0, 252, 0, 0, 252, 0, 252,
- 0, 252, 252, 252, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 252, 0, 252, 252, 0,
- 252, 0, 0, 252, 0, 252, 0, 252, 252, 252,
- 252, 0, 252, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 252, 252, 252, 252, 252, 0, 252, 252,
- 252, 252, 252, 252, 252, 252, 252, 252, 252, 252,
- 252, 252, 252, 252, 252, 252, 0, 252, 0, 252,
- 0, 252, 0, 252, 0, 252, 0, 252, 0, 252,
- 0, 252, 0, 252, 0, 252, 0, 252, 0, 252,
- 0, 252, 0, 252, 0, 252, 0, 252, 0, 252,
- 0, 252, 0, 252, 0, 0, 0, 252, 0, 252,
- 0, 252, 0, 252, 0, 252, 0, 252, 323, 252,
- 323, 323, 0, 323, 0, 0, 323, 323, 0, 0,
- 0, 323, 0, 0, 0, 323, 0, 0, 0, 0,
- 0, 323, 0, 0, 323, 0, 0, 0, 0, 0,
- 0, 323, 0, 0, 323, 0, 323, 0, 323, 323,
- 323, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 323, 0, 323, 323, 0, 323, 0, 0,
- 323, 0, 323, 0, 323, 323, 323, 323, 0, 323,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 323,
- 0, 323, 0, 323, 0, 323, 323, 323, 323, 323,
- 323, 323, 323, 323, 323, 323, 323, 323, 323, 323,
- 323, 323, 0, 0, 0, 0, 323, 0, 323, 0,
- 323, 0, 323, 0, 323, 0, 323, 0, 323, 0,
- 323, 0, 323, 0, 323, 0, 323, 0, 323, 0,
- 323, 0, 323, 0, 323, 0, 323, 0, 323, 0,
- 323, 0, 0, 0, 323, 0, 323, 0, 323, 0,
- 323, 0, 323, 0, 323, 337, 323, 337, 337, 0,
- 337, 0, 0, 337, 337, 0, 0, 0, 337, 0,
- 0, 0, 337, 0, 0, 0, 0, 0, 337, 0,
- 0, 337, 0, 0, 0, 0, 0, 0, 337, 0,
- 0, 337, 0, 337, 0, 337, 337, 337, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 337,
- 0, 337, 337, 0, 337, 0, 0, 337, 0, 337,
- 0, 337, 337, 337, 337, 0, 337, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 337, 0, 337, 337,
- 337, 0, 337, 337, 337, 337, 337, 337, 337, 0,
- 337, 337, 337, 337, 337, 337, 337, 337, 337, 337,
- 0, 337, 0, 337, 0, 337, 0, 337, 0, 337,
- 0, 337, 0, 337, 0, 337, 0, 337, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 227,
- 0, 227, 227, 0, 227, 0, 0, 227, 227, 0,
- 0, 337, 227, 337, 0, 337, 227, 337, 0, 337,
- 0, 337, 227, 337, 0, 227, 0, 0, 0, 0,
- 0, 0, 227, 0, 0, 227, 0, 227, 0, 227,
- 227, 227, 227, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 227, 0, 227, 227, 0, 227, 0,
- 0, 227, 0, 227, 0, 227, 227, 227, 227, 0,
- 227, 0, 0, 0, 0, 0, 0, 0, 0, 227,
- 227, 227, 227, 227, 227, 0, 227, 227, 227, 227,
- 227, 227, 227, 0, 227, 227, 227, 227, 227, 0,
- 0, 227, 227, 227, 0, 227, 0, 0, 0, 0,
- 0, 227, 0, 227, 0, 227, 0, 227, 0, 227,
- 0, 227, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 250, 0, 250, 250, 0, 250, 0,
- 0, 250, 250, 0, 0, 227, 250, 227, 0, 227,
- 250, 227, 0, 227, 0, 227, 250, 227, 0, 250,
- 0, 0, 0, 0, 0, 0, 250, 0, 0, 250,
- 0, 250, 0, 250, 250, 250, 250, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 250, 0, 250,
- 250, 0, 250, 0, 0, 250, 0, 250, 0, 250,
- 250, 250, 250, 0, 250, 0, 0, 0, 0, 0,
- 0, 0, 0, 250, 250, 0, 250, 250, 250, 0,
- 250, 250, 250, 250, 250, 250, 250, 0, 250, 250,
- 250, 250, 250, 0, 0, 250, 250, 250, 0, 250,
- 0, 0, 0, 0, 0, 250, 0, 250, 0, 250,
- 0, 250, 0, 250, 0, 250, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 341, 0, 341,
- 341, 0, 341, 0, 0, 341, 341, 0, 0, 250,
- 341, 250, 0, 250, 341, 250, 0, 250, 0, 250,
- 341, 250, 0, 341, 0, 0, 0, 0, 0, 0,
- 341, 0, 0, 341, 0, 341, 0, 341, 341, 341,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 341, 0, 341, 341, 0, 341, 0, 0, 341,
- 0, 341, 0, 341, 341, 341, 341, 0, 341, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 341, 0,
- 341, 341, 341, 0, 341, 341, 341, 341, 341, 341,
- 341, 0, 341, 341, 341, 341, 0, 0, 0, 341,
- 341, 341, 0, 341, 0, 341, 0, 341, 0, 341,
- 0, 341, 0, 341, 0, 341, 0, 341, 0, 341,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 342, 0, 342, 342, 0, 342, 0, 0, 342,
- 342, 0, 0, 341, 342, 341, 0, 341, 342, 341,
- 0, 341, 0, 341, 342, 341, 0, 342, 0, 0,
- 0, 0, 0, 0, 342, 0, 0, 342, 0, 342,
- 0, 342, 342, 342, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 342, 0, 342, 342, 0,
- 342, 0, 0, 342, 0, 342, 0, 342, 342, 342,
- 342, 0, 342, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 342, 0, 342, 342, 342, 0, 342, 342,
- 342, 342, 342, 342, 342, 0, 342, 342, 342, 342,
- 0, 0, 0, 342, 342, 342, 0, 342, 0, 342,
- 0, 342, 0, 342, 0, 342, 0, 342, 0, 342,
- 0, 342, 0, 342, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 343, 0, 343, 343, 0,
- 343, 0, 0, 343, 343, 0, 0, 342, 343, 342,
- 0, 342, 343, 342, 0, 342, 0, 342, 343, 342,
- 0, 343, 0, 0, 0, 0, 0, 0, 343, 0,
- 0, 343, 0, 343, 0, 343, 343, 343, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 343,
- 0, 343, 343, 0, 343, 0, 0, 343, 0, 343,
- 0, 343, 343, 343, 343, 0, 343, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 343, 0, 343, 343,
- 343, 0, 343, 343, 343, 343, 343, 343, 343, 0,
- 343, 343, 343, 343, 0, 0, 0, 343, 343, 343,
- 0, 343, 0, 343, 0, 343, 0, 343, 0, 343,
- 0, 343, 0, 343, 0, 343, 0, 343, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 344,
- 0, 344, 344, 0, 344, 0, 0, 344, 344, 0,
- 0, 343, 344, 343, 0, 343, 344, 343, 0, 343,
- 0, 343, 344, 343, 0, 344, 0, 0, 0, 0,
- 0, 0, 344, 0, 0, 344, 0, 344, 0, 344,
- 344, 344, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 344, 0, 344, 344, 0, 344, 0,
- 0, 344, 0, 344, 0, 344, 344, 344, 344, 0,
- 344, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 344, 0, 344, 344, 344, 0, 344, 344, 344, 344,
- 0, 0, 344, 0, 344, 344, 344, 344, 344, 0,
- 0, 344, 344, 344, 0, 344, 0, 344, 0, 344,
- 0, 344, 0, 344, 0, 344, 0, 344, 0, 344,
- 0, 344, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 347, 0, 347, 347, 0, 347, 0,
- 0, 347, 347, 0, 0, 344, 347, 344, 0, 344,
- 347, 344, 0, 344, 0, 344, 347, 344, 0, 347,
- 0, 0, 0, 0, 0, 0, 347, 0, 0, 347,
- 0, 347, 0, 347, 347, 347, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 347, 0, 347,
- 347, 0, 347, 0, 0, 347, 0, 347, 0, 347,
- 347, 347, 347, 0, 347, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 347, 0, 347, 347, 347, 0,
- 347, 347, 347, 347, 347, 347, 347, 0, 347, 347,
- 347, 347, 347, 0, 0, 347, 347, 347, 0, 347,
- 0, 0, 0, 0, 0, 347, 0, 347, 0, 347,
- 0, 347, 0, 347, 0, 347, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 345, 0, 345,
- 345, 0, 345, 0, 0, 345, 345, 0, 0, 347,
- 345, 347, 0, 347, 345, 347, 0, 347, 0, 347,
- 345, 347, 0, 345, 0, 0, 0, 0, 0, 0,
- 345, 0, 0, 345, 0, 345, 0, 345, 345, 345,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 345, 0, 345, 345, 0, 345, 0, 0, 345,
- 0, 345, 0, 345, 345, 345, 345, 0, 345, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 345, 0,
- 345, 345, 345, 0, 345, 345, 345, 345, 0, 0,
- 345, 0, 345, 345, 345, 345, 345, 0, 0, 345,
- 345, 345, 0, 345, 0, 345, 0, 345, 0, 345,
- 0, 345, 0, 345, 0, 345, 0, 345, 0, 345,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 346, 0, 346, 346, 0, 346, 0, 0, 346,
- 346, 0, 0, 345, 346, 345, 0, 345, 346, 345,
- 0, 345, 0, 345, 346, 345, 0, 346, 0, 0,
- 0, 0, 0, 0, 346, 0, 0, 346, 0, 346,
- 0, 346, 346, 346, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 346, 0, 346, 346, 0,
- 346, 0, 0, 346, 0, 346, 0, 346, 346, 346,
- 346, 0, 346, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 346, 0, 346, 346, 346, 0, 346, 346,
- 346, 346, 0, 0, 346, 0, 346, 346, 346, 346,
- 346, 0, 0, 346, 346, 346, 0, 346, 0, 346,
- 0, 346, 0, 346, 0, 346, 0, 346, 0, 346,
- 0, 346, 0, 346, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 353, 0, 353, 353, 0,
- 353, 0, 0, 353, 353, 0, 0, 346, 353, 346,
- 0, 346, 353, 346, 0, 346, 0, 346, 353, 346,
- 0, 353, 0, 0, 0, 0, 0, 0, 353, 0,
- 0, 353, 0, 353, 0, 353, 353, 353, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 353,
- 0, 353, 353, 0, 353, 0, 0, 353, 0, 353,
- 0, 353, 353, 353, 353, 0, 353, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 353, 0, 353, 353,
- 353, 0, 353, 353, 353, 353, 353, 353, 353, 0,
- 353, 353, 353, 353, 353, 0, 0, 353, 353, 353,
- 0, 353, 0, 0, 0, 0, 0, 353, 0, 353,
- 0, 353, 0, 353, 0, 353, 0, 353, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 352,
- 0, 352, 352, 0, 352, 0, 0, 352, 352, 0,
- 0, 353, 352, 353, 0, 353, 352, 353, 0, 353,
- 0, 353, 352, 353, 0, 352, 0, 0, 0, 0,
- 0, 0, 352, 0, 0, 352, 0, 352, 0, 352,
- 352, 352, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 352, 0, 352, 352, 0, 352, 0,
- 0, 352, 0, 352, 0, 352, 352, 352, 352, 0,
- 352, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 352, 0, 352, 352, 352, 0, 352, 352, 352, 352,
- 352, 352, 352, 0, 352, 352, 352, 352, 352, 0,
- 0, 352, 352, 352, 0, 352, 0, 0, 0, 0,
- 0, 352, 0, 352, 0, 352, 0, 352, 0, 352,
- 0, 352, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 348, 0, 348, 348, 0, 348, 0,
- 0, 348, 348, 0, 0, 352, 348, 352, 0, 352,
- 348, 352, 0, 352, 0, 352, 348, 352, 0, 348,
- 0, 0, 0, 0, 0, 0, 348, 0, 0, 348,
- 0, 348, 0, 348, 348, 348, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 348, 0, 348,
- 348, 0, 348, 0, 0, 348, 0, 348, 0, 348,
- 348, 348, 348, 0, 348, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 348, 0, 348, 348, 348, 0,
- 348, 348, 348, 348, 348, 348, 348, 0, 348, 348,
- 348, 348, 348, 0, 0, 348, 348, 348, 0, 348,
- 0, 0, 0, 0, 0, 348, 0, 348, 0, 348,
- 0, 348, 0, 348, 0, 348, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 349, 0, 349,
- 349, 0, 349, 0, 0, 349, 349, 0, 0, 348,
- 349, 348, 0, 348, 349, 348, 0, 348, 0, 348,
- 349, 348, 0, 349, 0, 0, 0, 0, 0, 0,
- 349, 0, 0, 349, 0, 349, 0, 349, 349, 349,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 349, 0, 349, 349, 0, 349, 0, 0, 349,
- 0, 349, 0, 349, 349, 349, 349, 0, 349, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 349, 0,
- 349, 349, 349, 0, 349, 349, 349, 349, 349, 349,
- 349, 0, 349, 349, 349, 349, 349, 0, 0, 349,
- 349, 349, 0, 349, 0, 0, 0, 0, 0, 349,
- 0, 349, 0, 349, 0, 349, 0, 349, 0, 349,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 350, 0, 350, 350, 0, 350, 0, 0, 350,
- 350, 0, 0, 349, 350, 349, 0, 349, 350, 349,
- 0, 349, 0, 349, 350, 349, 0, 350, 0, 0,
- 0, 0, 0, 0, 350, 0, 0, 350, 0, 350,
- 0, 350, 350, 350, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 350, 0, 350, 350, 0,
- 350, 0, 0, 350, 0, 350, 0, 350, 350, 350,
- 350, 0, 350, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 350, 0, 350, 350, 350, 0, 350, 350,
- 350, 350, 350, 350, 350, 0, 350, 350, 350, 350,
- 350, 0, 0, 350, 350, 350, 0, 350, 0, 0,
- 0, 0, 0, 350, 0, 350, 0, 350, 0, 350,
- 0, 350, 0, 350, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 351, 0, 351, 351, 0,
- 351, 0, 0, 351, 351, 0, 0, 350, 351, 350,
- 0, 350, 351, 350, 0, 350, 0, 350, 351, 350,
- 0, 351, 0, 0, 0, 0, 0, 0, 351, 0,
- 0, 351, 0, 351, 0, 351, 351, 351, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 351,
- 0, 351, 351, 0, 351, 0, 0, 351, 0, 351,
- 0, 351, 351, 351, 351, 0, 351, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 351, 0, 351, 351,
- 351, 0, 351, 351, 351, 351, 351, 351, 351, 0,
- 351, 351, 351, 351, 351, 0, 0, 351, 351, 351,
- 0, 351, 0, 0, 0, 0, 0, 351, 0, 351,
- 0, 351, 0, 351, 0, 351, 0, 351, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 351, 0, 351, 0, 351, 0, 351, 0, 351,
- 0, 351, 0, 351, 502, 502, 502, 502, 502, 0,
- 502, 502, 0, 502, 502, 502, 502, 0, 502, 502,
- 502, 0, 0, 0, 0, 502, 502, 0, 502, 502,
- 502, 502, 502, 0, 0, 502, 0, 0, 0, 502,
- 502, 0, 502, 502, 502, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 502, 0, 502, 0, 502, 502,
- 0, 502, 0, 502, 502, 502, 502, 502, 502, 502,
- 502, 502, 0, 502, 502, 52, 502, 502, 0, 0,
- 0, 0, 502, 502, 0, 0, 502, 0, 0, 0,
- 0, 502, 502, 502, 502, 502, 0, 0, 53, 502,
- 0, 502, 0, 0, 0, 0, 502, 0, 502, 0,
- 0, 54, 0, 0, 0, 0, 55, 0, 0, 0,
- 0, 56, 0, 57, 58, 59, 60, 0, 0, 0,
- 0, 61, 0, 0, 62, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 502, 63,
- 502, 0, 502, 0, 502, 0, 502, 0, 502, 0,
- 502, 497, 497, 497, 497, 497, 419, 497, 497, 0,
- 497, 497, 497, 497, 0, 497, 497, 497, 0, 0,
- 0, 0, 497, 0, 0, 497, 497, 497, 497, 497,
- 0, 0, 497, 0, 0, 0, 497, 497, 0, 497,
- 497, 497, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 497, 0, 497, 0, 497, 497, 0, 497, 0,
- 497, 497, 497, 497, 497, 497, 497, 497, 497, 0,
- 497, 497, 52, 497, 497, 0, 0, 0, 0, 497,
- 497, 0, 0, 497, 0, 0, 0, 0, 497, 497,
- 497, 497, 497, 0, 0, 53, 497, 0, 497, 0,
- 0, 0, 0, 497, 0, 497, 0, 0, 54, 0,
- 0, 0, 0, 55, 0, 0, 0, 0, 56, 0,
- 57, 58, 59, 60, 0, 0, 0, 0, 61, 0,
- 0, 62, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 497, 63, 497, 0, 497,
- 0, 497, 0, 497, 0, 497, 0, 497, 450, 450,
- 450, 450, 450, 0, 450, 450, 0, 450, 450, 450,
- 450, 0, 450, 450, 0, 0, 0, 0, 0, 450,
- 0, 0, 450, 450, 450, 450, 450, 0, 0, 450,
- 0, 0, 0, 450, 450, 0, 450, 450, 450, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 450, 0,
- 450, 0, 450, 450, 0, 450, 0, 450, 450, 450,
- 450, 450, 450, 450, 450, 450, 0, 450, 450, 0,
- 450, 450, 0, 0, 0, 0, 450, 450, 0, 0,
- 450, 0, 0, 0, 0, 450, 450, 450, 450, 450,
- 0, 0, 0, 450, 0, 450, 0, 0, 0, 0,
- 450, 0, 450, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 450, 0, 450, 0, 450, 0, 450, 0,
- 450, 0, 450, 0, 450, 70, 71, 487, 72, 0,
- 0, 73, 488, 0, 489, 490, 75, 0, 0, 491,
- 76, 0, 0, 0, 0, 0, 77, 0, 0, 78,
- 492, 493, 494, 495, 0, 0, 79, 0, 0, 0,
- 496, 80, 0, 81, 82, 83, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 497, 0, 84, 0, 85,
- 86, 0, 87, 0, 498, 88, 499, 89, 500, 90,
- 91, 92, 501, 0, 94, 502, 0, 503, 504, 0,
- 0, 0, 0, 423, 0, 0, 0, 95, 0, 0,
- 0, 0, 505, 96, 97, 98, 99, 0, 0, 0,
- 100, 0, 101, 0, 0, 0, 0, 102, 0, 103,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 104,
- 0, 105, 0, 106, 0, 107, 0, 108, 0, 109,
- 0, 506, 458, 458, 458, 458, 0, 0, 458, 458,
- 0, 458, 458, 458, 0, 0, 458, 458, 0, 0,
- 0, 0, 0, 458, 0, 0, 458, 458, 458, 458,
- 458, 0, 0, 458, 0, 0, 0, 458, 458, 0,
- 458, 458, 458, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 458, 0, 458, 0, 458, 458, 0, 458,
- 0, 458, 458, 458, 458, 458, 458, 458, 458, 458,
- 0, 458, 458, 0, 458, 458, 0, 0, 0, 0,
- 458, 0, 0, 0, 458, 0, 0, 0, 0, 458,
- 458, 458, 458, 458, 0, 0, 0, 458, 0, 458,
- 0, 0, 0, 0, 458, 0, 458, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 458, 0, 458, 0,
- 458, 0, 458, 0, 458, 0, 458, 0, 458, 70,
- 71, 487, 72, 0, 0, 73, 488, 0, 0, 490,
- 75, 0, 0, 491, 76, 0, 0, 0, 0, 0,
- 77, 0, 0, 78, 492, 493, 494, 495, 0, 0,
- 79, 0, 0, 0, 496, 80, 0, 81, 82, 83,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 497,
- 0, 84, 0, 85, 86, 0, 87, 0, 498, 88,
- 499, 89, 500, 90, 91, 92, 501, 0, 94, 502,
- 0, 0, 504, 0, 0, 0, 0, 423, 0, 0,
- 0, 95, 0, 0, 0, 0, 505, 96, 97, 98,
- 99, 0, 0, 0, 100, 0, 101, 0, 0, 0,
- 0, 102, 0, 103, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 354, 354, 0, 354, 0, 0, 354,
- 354, 0, 0, 104, 354, 105, 0, 106, 354, 107,
- 0, 108, 0, 109, 354, 40, 0, 354, 0, 0,
- 0, 0, 0, 0, 354, 0, 0, 0, 0, 354,
- 0, 354, 354, 354, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 354, 0, 354, 354, 0,
- 354, 0, 0, 354, 0, 354, 0, 354, 354, 354,
- 354, 0, 354, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 354, 0, 354, 354, 354, 0, 354, 354,
- 354, 354, 354, 354, 354, 0, 0, 0, 354, 354,
- 354, 0, 0, 354, 354, 354, 0, 354, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 354, 0, 354,
- 0, 354, 0, 354, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 355, 355, 0,
- 355, 0, 0, 355, 355, 0, 0, 354, 355, 354,
- 0, 354, 355, 354, 0, 354, 0, 354, 355, 354,
- 0, 355, 0, 0, 0, 0, 0, 0, 355, 0,
- 0, 0, 0, 355, 0, 355, 355, 355, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 355,
- 0, 355, 355, 0, 355, 0, 0, 355, 0, 355,
- 0, 355, 355, 355, 355, 0, 355, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 355, 0, 355, 355,
- 355, 0, 355, 355, 355, 355, 355, 355, 355, 0,
- 0, 0, 355, 355, 355, 0, 0, 355, 355, 355,
- 0, 355, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 355, 0, 355, 0, 355, 0, 355, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 356, 356, 0, 356, 0, 0, 356, 356, 0,
- 0, 355, 356, 355, 0, 355, 356, 355, 0, 355,
- 0, 355, 356, 355, 0, 356, 0, 0, 0, 0,
- 0, 0, 356, 0, 0, 0, 0, 356, 0, 356,
- 356, 356, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 356, 0, 356, 356, 0, 356, 0,
- 0, 356, 0, 356, 0, 356, 356, 356, 356, 0,
- 356, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 356, 0, 356, 356, 356, 0, 356, 356, 356, 356,
- 356, 356, 356, 0, 0, 0, 356, 356, 356, 0,
- 0, 356, 356, 356, 0, 356, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 356, 0, 356, 0, 356,
- 0, 356, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 357, 357, 0, 357, 0,
- 0, 357, 357, 0, 0, 356, 357, 356, 0, 356,
- 357, 356, 0, 356, 0, 356, 357, 356, 0, 357,
- 0, 0, 0, 0, 0, 0, 357, 0, 0, 0,
- 0, 357, 0, 357, 357, 357, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 357, 0, 357,
- 357, 0, 357, 0, 0, 357, 0, 357, 0, 357,
- 357, 357, 357, 0, 357, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 357, 0, 357, 357, 357, 0,
- 357, 357, 357, 357, 357, 357, 357, 0, 0, 0,
- 357, 357, 357, 0, 0, 357, 357, 357, 0, 357,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 357, 0, 357, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 358,
- 358, 0, 358, 0, 0, 358, 358, 0, 0, 357,
- 358, 357, 0, 357, 358, 357, 0, 357, 0, 357,
- 358, 357, 0, 358, 0, 0, 0, 0, 0, 0,
- 358, 0, 0, 0, 0, 358, 0, 358, 358, 358,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 358, 0, 358, 358, 0, 358, 0, 0, 358,
- 0, 358, 0, 358, 358, 358, 358, 0, 358, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 358, 0,
- 358, 358, 358, 0, 358, 358, 358, 358, 358, 358,
- 358, 0, 0, 0, 358, 358, 358, 0, 0, 358,
- 358, 358, 0, 358, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 358, 0, 358,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 359, 359, 0, 359, 0, 0, 359,
- 359, 0, 0, 358, 359, 358, 0, 358, 359, 358,
- 0, 358, 0, 358, 359, 358, 0, 359, 0, 0,
- 0, 0, 0, 0, 359, 0, 0, 0, 0, 359,
- 0, 359, 359, 359, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 359, 0, 359, 359, 0,
- 359, 0, 0, 359, 0, 359, 0, 359, 359, 359,
- 359, 0, 359, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 359, 0, 359, 359, 359, 0, 359, 359,
- 359, 359, 359, 359, 359, 0, 0, 0, 0, 359,
- 359, 0, 0, 359, 359, 359, 0, 359, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 359, 0, 359, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 361, 361, 0,
- 361, 0, 0, 361, 361, 0, 0, 359, 361, 359,
- 0, 359, 361, 359, 0, 359, 0, 359, 361, 359,
- 0, 361, 0, 0, 0, 0, 0, 0, 361, 0,
- 0, 0, 0, 361, 0, 361, 361, 361, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 361,
- 0, 361, 361, 0, 361, 0, 0, 361, 0, 361,
- 0, 361, 361, 361, 361, 0, 361, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 361, 0, 361, 361,
- 361, 0, 361, 361, 361, 361, 361, 361, 361, 0,
- 0, 0, 361, 361, 361, 0, 0, 0, 361, 361,
- 0, 361, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 361, 0, 361, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 360, 360, 0, 360, 0, 0, 360, 360, 0,
- 0, 361, 360, 361, 0, 361, 360, 361, 0, 361,
- 0, 361, 360, 361, 0, 360, 0, 0, 0, 0,
- 0, 0, 360, 0, 0, 0, 0, 360, 0, 360,
- 360, 360, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 360, 0, 360, 360, 0, 360, 0,
- 0, 360, 0, 360, 0, 360, 360, 360, 360, 0,
- 360, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 360, 0, 360, 360, 360, 0, 360, 360, 360, 360,
- 360, 360, 360, 0, 0, 0, 0, 360, 360, 0,
- 0, 360, 360, 360, 0, 360, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 360,
- 0, 360, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 362, 362, 0, 362, 0,
- 0, 362, 362, 0, 0, 360, 362, 360, 0, 360,
- 362, 360, 0, 360, 0, 360, 362, 360, 0, 362,
- 0, 0, 0, 0, 0, 0, 362, 0, 0, 0,
- 0, 362, 0, 362, 362, 362, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 362, 0, 362,
- 362, 0, 362, 0, 0, 362, 0, 362, 0, 362,
- 362, 362, 362, 0, 362, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 362, 0, 362, 362, 362, 0,
- 362, 362, 362, 362, 362, 362, 362, 0, 0, 0,
- 362, 362, 362, 0, 0, 0, 362, 362, 0, 362,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 362, 0, 362, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 363,
- 363, 0, 363, 0, 0, 363, 363, 0, 0, 362,
- 363, 362, 0, 362, 363, 362, 0, 362, 0, 362,
- 363, 362, 0, 363, 0, 0, 0, 0, 0, 0,
- 363, 0, 0, 0, 0, 363, 0, 363, 363, 363,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 363, 0, 363, 363, 0, 363, 0, 0, 363,
- 0, 363, 0, 363, 363, 363, 363, 0, 363, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 363, 0,
- 363, 363, 363, 0, 363, 363, 363, 363, 363, 363,
- 363, 0, 0, 0, 363, 0, 363, 0, 0, 0,
- 363, 363, 0, 363, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 363, 0, 363,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 364, 364, 0, 364, 0, 0, 364,
- 364, 0, 0, 363, 364, 363, 0, 363, 364, 363,
- 0, 363, 0, 363, 364, 363, 0, 364, 0, 0,
- 0, 0, 0, 0, 364, 0, 0, 0, 0, 364,
- 0, 364, 364, 364, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 364, 0, 364, 364, 0,
- 364, 0, 0, 364, 0, 364, 0, 364, 364, 364,
- 364, 0, 364, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 364, 0, 364, 364, 364, 0, 364, 364,
- 364, 364, 364, 364, 364, 0, 0, 0, 364, 0,
- 364, 0, 0, 0, 364, 364, 0, 364, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 364, 0, 364, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 365, 365, 0,
- 365, 0, 0, 365, 365, 0, 0, 364, 365, 364,
- 0, 364, 365, 364, 0, 364, 0, 364, 365, 364,
- 0, 365, 0, 0, 0, 0, 0, 0, 365, 0,
- 0, 0, 0, 365, 0, 365, 365, 365, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 365,
- 0, 365, 365, 0, 365, 0, 0, 365, 0, 365,
- 0, 365, 365, 365, 365, 0, 365, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 365, 0, 365, 365,
- 365, 0, 365, 365, 365, 365, 365, 365, 365, 0,
- 0, 0, 365, 0, 365, 0, 0, 0, 365, 365,
- 0, 365, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 365, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 366, 366, 0, 366, 0, 0, 366, 366, 0,
- 0, 365, 366, 365, 0, 365, 366, 365, 0, 365,
- 0, 365, 366, 365, 0, 366, 0, 0, 0, 0,
- 0, 0, 366, 0, 0, 0, 0, 366, 0, 366,
- 366, 366, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 366, 0, 366, 366, 0, 366, 0,
- 0, 366, 0, 366, 0, 366, 366, 366, 366, 0,
- 366, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 366, 0, 366, 366, 366, 0, 366, 366, 366, 366,
- 366, 366, 366, 0, 0, 0, 366, 0, 366, 0,
- 0, 0, 366, 366, 0, 366, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 366, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 367, 367, 0, 367, 0,
- 0, 367, 367, 0, 0, 366, 367, 366, 0, 366,
- 367, 366, 0, 366, 0, 366, 367, 366, 0, 367,
- 0, 0, 0, 0, 0, 0, 367, 0, 0, 0,
- 0, 367, 0, 367, 367, 367, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 367, 0, 367,
- 367, 0, 367, 0, 0, 367, 0, 367, 0, 367,
- 367, 367, 367, 0, 367, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 367, 0, 367, 367, 367, 0,
- 367, 367, 367, 367, 367, 367, 367, 0, 0, 0,
- 367, 0, 367, 0, 0, 0, 0, 367, 0, 367,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 70,
- 71, 0, 72, 0, 0, 73, 74, 0, 0, 367,
- 75, 367, 0, 367, 76, 367, 0, 367, 0, 367,
- 77, 367, 0, 78, 0, 0, 0, 0, 0, 0,
- 79, 0, 0, 0, 0, 80, 0, 81, 82, 83,
- 0, 246, 0, 0, 0, 0, 0, 0, 247, 0,
- 0, 84, 0, 85, 86, 0, 87, 0, 0, 88,
- 0, 89, 0, 90, 91, 92, 93, 0, 94, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 95, 0, 0, 0, 0, 0, 96, 97, 98,
- 99, 0, 0, 0, 100, 0, 101, 0, 0, 0,
- 0, 102, 0, 103, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 70, 71, 0, 72, 0, 0, 73,
- 74, 0, 0, 104, 75, 105, 0, 106, 76, 107,
- 0, 108, 0, 109, 77, 40, 0, 78, 0, 0,
- 0, 0, 0, 0, 79, 0, 0, 0, 0, 80,
- 0, 81, 82, 83, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 84, 0, 85, 86, 0,
- 87, 0, 0, 88, 0, 89, 0, 90, 91, 92,
- 93, 0, 94, 0, 0, 0, 0, 0, 0, 0,
- 0, 416, 442, 0, 0, 95, 0, 0, 0, 0,
- 0, 96, 97, 98, 99, 0, 0, 0, 100, 0,
- 101, 0, 0, 0, 0, 102, 0, 103, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 70, 71, 0,
- 72, 0, 0, 73, 74, 0, 0, 104, 75, 105,
- 0, 106, 76, 107, 0, 108, 0, 109, 77, 40,
- 0, 78, 0, 0, 0, 0, 0, 0, 79, 0,
- 0, 0, 0, 80, 0, 81, 82, 83, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 84,
- 0, 85, 86, 0, 87, 0, 0, 88, 0, 89,
- 0, 90, 91, 92, 93, 0, 94, 0, 0, 0,
- 0, 0, 0, 0, 0, 416, 554, 0, 0, 95,
- 0, 0, 0, 0, 0, 96, 97, 98, 99, 0,
- 0, 0, 100, 0, 101, 0, 0, 0, 0, 102,
- 0, 103, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 102, 102, 0, 102, 0, 0, 102, 102, 0,
- 0, 104, 102, 105, 0, 106, 102, 107, 0, 108,
- 0, 109, 102, 40, 0, 102, 0, 0, 0, 0,
- 0, 0, 102, 0, 0, 0, 0, 102, 0, 102,
- 102, 102, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 102, 0, 102, 102, 0, 102, 0,
- 0, 102, 0, 102, 0, 102, 102, 102, 102, 0,
- 102, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 102, 0, 0, 102, 0, 102, 102,
- 102, 102, 102, 0, 0, 0, 102, 0, 102, 0,
- 0, 0, 0, 102, 0, 102, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 70, 71, 0, 72, 0,
- 0, 73, 74, 0, 0, 102, 75, 102, 0, 102,
- 76, 102, 0, 102, 0, 102, 77, 102, 0, 78,
- 0, 0, 0, 0, 0, 0, 79, 0, 0, 0,
- 0, 80, 0, 81, 82, 83, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 84, 0, 85,
- 86, 0, 87, 0, 0, 88, 0, 89, 0, 90,
- 91, 92, 93, 0, 94, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 95, 0, 0,
- 300, 0, 0, 96, 97, 98, 99, 0, 0, 0,
- 100, 0, 101, 0, 0, 0, 0, 102, 0, 103,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 70,
- 71, 0, 72, 0, 0, 73, 74, 0, 0, 104,
- 75, 105, 0, 106, 76, 107, 0, 108, 0, 109,
- 77, 40, 0, 78, 0, 0, 0, 0, 0, 0,
- 79, 0, 0, 0, 0, 80, 0, 81, 82, 83,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 84, 0, 85, 86, 0, 87, 0, 0, 88,
- 0, 89, 0, 90, 91, 92, 93, 0, 94, 0,
- 0, 0, 0, 0, 0, 0, 0, 416, 0, 0,
- 0, 95, 0, 0, 0, 0, 0, 96, 97, 98,
- 99, 0, 0, 0, 100, 0, 101, 0, 0, 0,
- 0, 102, 0, 103, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 70, 71, 0, 72, 0, 0, 73,
- 74, 0, 0, 104, 75, 105, 0, 106, 76, 107,
- 0, 108, 0, 109, 77, 40, 0, 78, 0, 0,
- 0, 0, 0, 0, 79, 0, 0, 0, 0, 80,
- 0, 81, 82, 83, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 84, 0, 85, 86, 0,
- 87, 0, 0, 88, 0, 89, 0, 90, 91, 92,
- 93, 0, 94, 0, 0, 503, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 95, 0, 0, 0, 0,
- 0, 96, 97, 98, 99, 0, 0, 0, 100, 0,
- 101, 0, 0, 0, 0, 102, 0, 103, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 437, 437, 0,
- 437, 0, 0, 437, 437, 0, 0, 104, 437, 105,
- 0, 106, 437, 107, 0, 108, 0, 109, 437, 40,
- 0, 437, 0, 0, 0, 0, 0, 0, 437, 0,
- 0, 0, 0, 437, 0, 437, 437, 437, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 437,
- 0, 437, 437, 0, 437, 0, 0, 437, 0, 437,
- 0, 437, 437, 437, 437, 0, 437, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 437,
- 0, 0, 0, 0, 437, 437, 437, 437, 437, 0,
- 0, 0, 437, 0, 437, 0, 0, 0, 0, 437,
- 0, 437, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 70, 71, 0, 72, 0, 0, 73, 74, 0,
- 0, 437, 75, 437, 0, 437, 76, 437, 0, 437,
- 0, 437, 77, 437, 0, 78, 0, 0, 0, 0,
- 0, 0, 79, 0, 0, 0, 0, 80, 0, 81,
- 82, 83, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 84, 0, 85, 86, 0, 87, 0,
- 0, 88, 0, 89, 0, 90, 91, 92, 93, 0,
- 94, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 95, 0, 0, 0, 0, 0, 96,
- 97, 98, 99, 0, 0, 0, 100, 0, 101, 0,
- 0, 0, 0, 102, 0, 103, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 70, 71, 0, 72, 0,
- 0, 73, 74, 0, 0, 104, 75, 105, 0, 106,
- 76, 107, 0, 108, 0, 109, 77, 40, 0, 78,
- 0, 0, 0, 0, 0, 0, 79, 0, 0, 0,
- 0, 80, 0, 81, 82, 83, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 84, 0, 85,
- 86, 0, 87, 0, 0, 88, 0, 89, 0, 90,
- 91, 92, 93, 0, 94, 0, 71, 503, 72, 0,
- 0, 73, 0, 155, 448, 0, 75, 694, 156, 0,
- 76, 0, 157, 449, 450, 0, 0, 0, 0, 78,
- 0, 0, 0, 0, 451, 0, 79, 158, 0, 0,
- 0, 80, 0, 0, 0, 83, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 84, 0, 85,
- 0, 0, 87, 159, 0, 0, 0, 0, 0, 0,
- 91, 92, 0, 0, 94, 0, 0, 452, 0, 104,
- 0, 105, 0, 106, 0, 107, 0, 108, 387, 109,
- 387, 40, 0, 387, 0, 387, 387, 0, 387, 0,
- 387, 0, 387, 0, 387, 387, 387, 0, 0, 0,
- 0, 387, 0, 0, 0, 0, 387, 0, 387, 387,
- 0, 0, 0, 387, 0, 0, 0, 387, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 387,
- 0, 387, 0, 0, 387, 387, 0, 0, 0, 0,
- 0, 0, 387, 387, 0, 386, 387, 386, 0, 387,
- 386, 453, 386, 386, 0, 386, 0, 386, 0, 386,
- 0, 386, 386, 386, 0, 0, 0, 0, 386, 0,
- 0, 0, 0, 386, 0, 386, 386, 0, 0, 0,
- 386, 0, 0, 0, 386, 0, 0, 0, 0, 33,
- 0, 33, 0, 0, 33, 0, 386, 0, 386, 33,
- 0, 386, 386, 33, 0, 0, 33, 0, 0, 386,
- 386, 0, 33, 386, 0, 0, 386, 0, 0, 33,
- 0, 0, 0, 0, 33, 0, 33, 0, 33, 0,
- 0, 0, 0, 387, 0, 0, 0, 0, 0, 0,
- 33, 33, 33, 33, 0, 33, 33, 0, 0, 0,
- 0, 33, 0, 33, 33, 33, 0, 33, 33, 0,
- 33, 0, 0, 0, 33, 0, 0, 147, 0, 0,
- 0, 33, 33, 0, 33, 0, 33, 33, 33, 0,
- 33, 0, 33, 0, 0, 0, 33, 0, 0, 0,
- 0, 0, 33, 0, 33, 33, 0, 33, 0, 0,
- 386, 0, 33, 0, 0, 33, 33, 33, 0, 33,
- 0, 33, 33, 33, 0, 33, 33, 0, 33, 148,
- 33, 33, 0, 33, 0, 33, 33, 0, 33, 0,
- 33, 0, 0, 0, 0, 0, 33, 33, 0, 33,
- 33, 0, 0, 0, 33, 0, 33, 0, 71, 0,
- 72, 33, 0, 73, 110, 33, 0, 33, 75, 33,
- 0, 0, 76, 0, 33, 463, 0, 33, 0, 33,
- 0, 78, 33, 0, 0, 0, 0, 0, 79, 0,
- 33, 33, 0, 80, 33, 0, 0, 83, 0, 0,
- 0, 0, 0, 0, 0, 231, 33, 231, 0, 84,
- 231, 85, 0, 0, 87, 231, 0, 0, 0, 231,
- 0, 0, 91, 92, 0, 0, 94, 0, 231, 464,
- 0, 0, 0, 0, 0, 231, 0, 33, 0, 0,
- 231, 232, 0, 232, 231, 0, 232, 0, 0, 0,
- 0, 232, 0, 0, 0, 232, 231, 0, 231, 0,
- 0, 231, 0, 0, 232, 0, 0, 0, 0, 231,
- 231, 232, 0, 231, 0, 0, 232, 0, 0, 0,
- 232, 33, 231, 0, 0, 0, 0, 0, 0, 0,
- 231, 0, 232, 155, 232, 155, 0, 232, 155, 0,
- 0, 0, 0, 155, 0, 232, 232, 155, 0, 232,
- 155, 252, 0, 40, 0, 118, 155, 118, 232, 0,
- 118, 0, 0, 155, 0, 118, 232, 0, 155, 118,
- 0, 0, 155, 0, 0, 0, 0, 0, 118, 0,
- 0, 0, 0, 0, 155, 118, 155, 252, 0, 155,
- 118, 0, 0, 0, 118, 0, 0, 155, 155, 0,
- 231, 155, 0, 0, 155, 0, 118, 0, 118, 0,
- 0, 118, 0, 0, 0, 0, 0, 0, 0, 118,
- 118, 0, 0, 118, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 252, 0, 252, 232, 0, 0, 0,
- 0, 0, 252, 252, 0, 252, 252, 252, 252, 252,
- 252, 252, 252, 252, 252, 252, 0, 252, 0, 252,
- 0, 252, 0, 252, 0, 252, 0, 252, 0, 252,
- 0, 252, 0, 252, 0, 252, 0, 252, 0, 252,
- 0, 252, 0, 252, 0, 252, 0, 252, 155, 252,
- 0, 252, 21, 252, 0, 21, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 21, 0, 0, 0,
- 118, 21, 0, 0, 0, 21, 0, 0, 21, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 21, 21, 0, 0, 0, 21, 21, 0, 0, 0,
- 0, 21, 0, 21, 21, 21, 21, 12, 0, 0,
- 12, 21, 0, 0, 21, 0, 21, 0, 0, 0,
- 0, 12, 0, 0, 0, 0, 12, 0, 0, 21,
- 12, 0, 0, 12, 0, 0, 0, 21, 21, 0,
- 0, 0, 0, 0, 0, 12, 12, 0, 0, 0,
- 12, 12, 0, 0, 0, 0, 12, 0, 12, 12,
- 12, 12, 20, 0, 0, 20, 12, 0, 0, 12,
- 0, 12, 0, 0, 0, 0, 20, 0, 0, 0,
- 0, 20, 0, 0, 12, 20, 0, 0, 20, 0,
- 0, 0, 12, 12, 0, 0, 0, 0, 0, 0,
- 20, 20, 0, 0, 0, 20, 20, 0, 0, 0,
- 0, 20, 0, 20, 20, 20, 20, 23, 0, 0,
- 33, 20, 0, 0, 20, 0, 20, 0, 0, 0,
- 0, 33, 0, 0, 0, 0, 33, 0, 0, 20,
- 33, 0, 20, 33, 0, 0, 0, 0, 20, 0,
- 0, 0, 0, 20, 0, 33, 33, 0, 20, 0,
- 0, 33, 20, 0, 0, 20, 33, 0, 33, 33,
- 33, 33, 0, 0, 0, 0, 33, 20, 20, 33,
- 0, 33, 20, 20, 0, 0, 0, 0, 20, 0,
- 20, 20, 20, 20, 33, 33, 0, 0, 20, 0,
- 0, 20, 23, 20, 0, 0, 33, 0, 0, 33,
- 0, 33, 33, 0, 0, 33, 20, 0, 33, 0,
- 0, 0, 0, 33, 20, 20, 0, 0, 33, 0,
- 33, 33, 33, 0, 0, 33, 33, 0, 0, 0,
- 0, 33, 0, 33, 33, 33, 33, 33, 33, 0,
- 0, 33, 33, 33, 33, 0, 33, 0, 33, 0,
- 33, 33, 33, 33, 22, 0, 0, 33, 33, 33,
- 0, 33, 0, 33, 0, 0, 0, 22, 33, 0,
- 0, 0, 0, 33, 0, 0, 33, 33, 0, 0,
- 33, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 33, 33, 0, 0, 0, 255, 33, 255,
- 440, 255, 440, 33, 440, 33, 33, 33, 33, 255,
- 0, 0, 0, 33, 0, 0, 33, 0, 33, 255,
- 259, 255, 259, 443, 259, 443, 0, 443, 0, 0,
- 0, 33, 259, 0, 0, 0, 0, 0, 0, 255,
- 0, 255, 259, 255, 259, 255, 0, 255, 0, 255,
- 0, 255, 0, 255, 0, 255, 0, 255, 0, 0,
- 0, 0, 259, 0, 259, 0, 259, 0, 259, 0,
- 259, 0, 259, 255, 259, 0, 259, 0, 259, 260,
- 259, 260, 444, 260, 444, 0, 444, 0, 0, 0,
- 299, 260, 299, 447, 299, 447, 259, 447, 0, 0,
- 0, 260, 299, 260, 0, 0, 0, 0, 0, 0,
- 0, 0, 299, 0, 299, 0, 0, 0, 0, 0,
- 0, 260, 0, 260, 0, 260, 0, 260, 0, 260,
- 0, 260, 299, 260, 299, 260, 299, 260, 299, 260,
- 299, 16, 299, 16, 299, 16, 299, 0, 299, 0,
- 299, 0, 0, 16, 0, 260, 0, 0, 0, 0,
- 0, 0, 0, 16, 0, 16, 299, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 16, 0, 16, 0, 16, 0, 16,
- 0, 16, 0, 16, 0, 16, 0, 16, 0, 16,
- 0, 16, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 16,
- };
- protected static short [] yyCheck = { 3,
- 235, 24, 322, 267, 326, 519, 491, 281, 1, 13,
- 607, 275, 236, 467, 323, 625, 345, 43, 643, 347,
- 333, 257, 263, 342, 260, 18, 268, 31, 264, 459,
- 266, 24, 343, 269, 27, 271, 272, 343, 274, 313,
- 276, 341, 278, 285, 280, 281, 282, 283, 607, 262,
- 350, 287, 346, 347, 470, 343, 292, 323, 294, 295,
- 296, 620, 564, 299, 300, 301, 343, 303, 364, 95,
- 306, 393, 308, 309, 310, 311, 343, 343, 304, 315,
- 316, 317, 323, 319, 320, 321, 343, 383, 81, 519,
- 419, 419, 328, 329, 596, 304, 332, 323, 334, 335,
- 419, 314, 95, 343, 343, 261, 342, 343, 419, 343,
- 419, 343, 626, 419, 323, 351, 343, 343, 728, 729,
- 536, 347, 96, 97, 98, 99, 100, 101, 102, 103,
- 153, 419, 454, 730, 343, 161, 638, 163, 592, 641,
- 364, 297, 419, 267, 170, 419, 262, 81, 343, 604,
- 161, 275, 419, 419, 361, 419, 343, 183, 184, 346,
- 153, 95, 419, 156, 190, 191, 192, 193, 194, 195,
- 196, 197, 198, 199, 200, 168, 169, 607, 803, 419,
- 419, 454, 419, 419, 343, 419, 337, 419, 381, 644,
- 620, 342, 419, 419, 220, 1, 626, 470, 314, 361,
- 356, 357, 361, 800, 361, 267, 413, 361, 234, 300,
- 419, 370, 18, 275, 361, 208, 209, 373, 342, 375,
- 246, 247, 156, 234, 419, 361, 343, 201, 202, 203,
- 204, 205, 206, 207, 168, 169, 210, 211, 212, 213,
- 214, 215, 216, 217, 218, 219, 355, 221, 733, 734,
- 361, 413, 343, 361, 413, 343, 413, 355, 346, 413,
- 341, 746, 455, 748, 457, 459, 413, 241, 349, 243,
- 347, 591, 298, 350, 208, 209, 385, 413, 387, 325,
- 389, 342, 391, 287, 393, 344, 395, 348, 397, 348,
- 399, 317, 401, 350, 403, 488, 266, 491, 344, 269,
- 352, 353, 413, 326, 341, 413, 271, 500, 501, 81,
- 419, 276, 342, 350, 621, 280, 362, 802, 348, 639,
- 324, 628, 342, 343, 294, 519, 319, 841, 341, 299,
- 295, 347, 345, 326, 347, 348, 329, 350, 823, 343,
- 339, 337, 305, 342, 307, 315, 342, 317, 341, 312,
- 360, 361, 362, 838, 358, 271, 321, 361, 328, 329,
- 276, 343, 332, 556, 280, 347, 370, 360, 503, 419,
- 393, 344, 345, 508, 419, 348, 344, 344, 344, 295,
- 348, 348, 348, 341, 156, 319, 339, 345, 392, 342,
- 416, 384, 396, 386, 341, 329, 168, 169, 345, 829,
- 393, 204, 205, 723, 341, 321, 432, 341, 345, 413,
- 341, 841, 350, 607, 345, 341, 343, 349, 345, 345,
- 347, 343, 257, 345, 344, 347, 360, 420, 348, 452,
- 345, 454, 626, 346, 345, 348, 208, 209, 365, 345,
- 367, 467, 345, 365, 437, 367, 369, 470, 371, 377,
- 384, 379, 386, 206, 207, 448, 449, 347, 343, 452,
- 345, 454, 210, 211, 212, 213, 348, 660, 350, 358,
- 463, 497, 348, 499, 350, 459, 381, 470, 471, 472,
- 363, 348, 486, 350, 359, 459, 420, 343, 343, 345,
- 345, 337, 337, 339, 339, 688, 489, 346, 341, 348,
- 344, 419, 346, 437, 345, 419, 347, 491, 337, 419,
- 339, 214, 215, 346, 448, 449, 346, 491, 419, 419,
- 419, 419, 350, 349, 346, 459, 343, 346, 346, 463,
- 341, 345, 348, 348, 727, 519, 730, 471, 472, 733,
- 734, 349, 349, 344, 349, 519, 739, 349, 348, 346,
- 743, 342, 746, 341, 748, 489, 341, 341, 793, 794,
- 346, 754, 755, 342, 341, 348, 592, 419, 348, 341,
- 348, 342, 459, 355, 350, 301, 342, 342, 345, 304,
- 419, 304, 419, 609, 345, 519, 612, 613, 360, 341,
- 616, 341, 419, 347, 343, 346, 600, 601, 345, 625,
- 355, 347, 628, 345, 491, 350, 800, 350, 802, 459,
- 345, 345, 384, 345, 386, 608, 345, 643, 345, 459,
- 350, 343, 342, 607, 345, 349, 341, 419, 345, 823,
- 343, 350, 519, 607, 350, 829, 346, 355, 831, 345,
- 342, 491, 626, 647, 838, 419, 336, 841, 420, 350,
- 350, 491, 626, 657, 350, 648, 649, 350, 350, 348,
- 653, 419, 346, 349, 344, 437, 459, 346, 694, 519,
- 696, 343, 339, 607, 608, 337, 448, 449, 348, 519,
- 345, 350, 350, 346, 285, 346, 620, 346, 345, 268,
- 268, 463, 626, 346, 344, 346, 344, 346, 491, 471,
- 472, 705, 728, 729, 346, 342, 293, 711, 712, 341,
- 350, 341, 350, 262, 648, 649, 350, 489, 314, 653,
- 607, 459, 346, 346, 345, 345, 519, 342, 344, 346,
- 349, 264, 350, 266, 279, 342, 269, 350, 350, 626,
- 350, 274, 346, 736, 342, 278, 730, 773, 337, 733,
- 734, 346, 346, 491, 287, 346, 730, 607, 346, 733,
- 734, 294, 746, 349, 748, 339, 299, 607, 350, 346,
- 303, 342, 746, 341, 748, 350, 626, 803, 347, 346,
- 341, 519, 315, 355, 317, 344, 626, 320, 346, 341,
- 341, 341, 419, 341, 350, 328, 329, 344, 341, 332,
- 342, 341, 736, 796, 342, 419, 342, 341, 812, 813,
- 814, 350, 314, 385, 607, 387, 800, 389, 802, 391,
- 419, 393, 350, 395, 262, 397, 800, 399, 802, 401,
- 350, 403, 342, 626, 346, 346, 608, 342, 346, 823,
- 223, 287, 4, 730, 31, 829, 733, 734, 15, 823,
- 153, 370, 28, 331, 838, 829, 329, 841, 413, 746,
- 593, 748, 796, 389, 838, 365, 389, 841, 657, 607,
- 601, 396, 600, 727, 712, 711, 648, 649, 293, 812,
- 730, 653, 334, 733, 734, 392, 419, 316, 626, 247,
- 730, 216, 218, 733, 734, 829, 746, 217, 748, 221,
- 219, 65, 806, -1, 829, 800, 746, 841, 748, 623,
- 691, 808, -1, 800, 499, 802, 689, 692, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, 346,
- -1, 348, -1, 350, -1, -1, 823, 730, 355, -1,
- 733, 734, 829, -1, 284, -1, -1, -1, -1, -1,
- 800, 838, 802, 746, 841, 748, -1, -1, -1, -1,
- 800, -1, 802, -1, 736, -1, -1, -1, 385, -1,
- 387, -1, 389, 823, 391, -1, 393, -1, 395, 829,
- 397, -1, 399, 823, 401, 325, 403, -1, 838, 829,
- -1, 841, 730, -1, -1, 733, 734, -1, 838, -1,
- -1, 841, -1, -1, -1, -1, -1, 800, 746, 802,
- 748, 351, 352, 353, 354, -1, 356, 357, 358, 359,
- 360, 361, 362, 363, 796, 365, -1, 367, -1, 369,
- 823, 371, -1, 373, -1, 375, 829, 377, -1, 379,
- -1, -1, -1, -1, -1, 838, -1, -1, 841, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, 800, -1, 802, -1, -1, -1, -1, 257,
- -1, -1, 260, -1, 262, -1, 264, -1, 266, -1,
- -1, 269, -1, 271, 272, 823, 274, -1, 276, -1,
- 278, 829, 280, 281, 282, 283, -1, -1, -1, 287,
- 838, -1, -1, 841, 292, -1, 294, 295, 296, -1,
- -1, 299, 300, 301, -1, 303, -1, 305, 306, 307,
- 308, 309, 310, 311, 312, -1, 314, 315, 316, 317,
- -1, 319, 320, 321, -1, -1, -1, -1, -1, -1,
- 328, 329, -1, -1, 332, -1, 334, 335, 260, 337,
- -1, 339, 264, -1, 266, -1, -1, 269, -1, 271,
- 272, -1, 274, 351, 276, -1, 278, -1, 280, 281,
- 282, 283, -1, -1, -1, 287, -1, -1, -1, -1,
- 292, -1, 294, 295, 296, -1, -1, 299, -1, 301,
- -1, 303, -1, -1, 306, -1, 308, 309, 310, 311,
- -1, -1, -1, 315, 316, 317, -1, 319, 320, 321,
- -1, -1, -1, -1, -1, -1, 328, 329, -1, -1,
- 332, -1, 334, 335, -1, -1, -1, -1, -1, 260,
- 342, 419, -1, 264, -1, 266, -1, -1, 269, 351,
- 271, 272, -1, 274, -1, 276, -1, 278, -1, 280,
- 281, 282, 283, -1, -1, -1, 287, -1, -1, -1,
- -1, 292, -1, 294, 295, 296, -1, -1, 299, -1,
- 301, -1, 303, -1, -1, 306, -1, 308, 309, 310,
- 311, -1, -1, -1, 315, 316, 317, -1, 319, 320,
- 321, -1, -1, -1, -1, -1, -1, 328, 329, -1,
- -1, 332, -1, 334, 335, -1, -1, 419, -1, -1,
- 260, 342, -1, -1, 264, -1, 266, -1, -1, 269,
- 351, 271, 272, -1, 274, -1, 276, -1, 278, -1,
- 280, 281, 282, 283, -1, -1, -1, 287, -1, -1,
- -1, -1, 292, -1, 294, 295, 296, -1, -1, 299,
- -1, 301, -1, 303, -1, -1, 306, -1, 308, 309,
- 310, 311, -1, -1, -1, 315, 316, 317, -1, 319,
- 320, 321, -1, -1, -1, -1, -1, -1, 328, 329,
- -1, -1, 332, -1, 334, 335, -1, -1, 419, 260,
- -1, -1, 342, 264, -1, 266, -1, -1, 269, -1,
- 271, 272, -1, 274, -1, 276, -1, 278, -1, 280,
- 281, 282, 283, -1, -1, -1, 287, -1, -1, -1,
- -1, 292, -1, 294, 295, 296, -1, -1, 299, -1,
- 301, -1, 303, -1, -1, 306, -1, 308, 309, 310,
- 311, -1, -1, -1, 315, 316, 317, -1, 319, 320,
- 321, -1, -1, -1, -1, -1, -1, 328, 329, -1,
- -1, 332, -1, 334, 335, -1, -1, -1, -1, 419,
- 261, 342, 263, 264, -1, 266, -1, -1, 269, 270,
- -1, -1, -1, 274, -1, -1, -1, 278, -1, -1,
- -1, -1, -1, 284, -1, -1, 287, -1, -1, -1,
- -1, -1, -1, 294, -1, -1, 297, -1, 299, -1,
- 301, 302, 303, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, 315, -1, 317, 318, -1, 320,
- -1, -1, 323, -1, 325, -1, 327, 328, 329, 330,
- 346, 332, 348, -1, 350, -1, -1, -1, 419, 355,
- 341, 342, -1, 344, 345, 346, 347, 348, 349, 350,
- 351, 352, 353, 354, 355, 356, 357, 358, 359, 360,
- 361, 362, 363, 364, 365, -1, 367, -1, 369, 385,
- 371, 387, 373, 389, 375, 391, 377, 393, 379, 395,
- 381, 397, 383, 399, 385, 401, 387, 403, 389, -1,
- 391, -1, 393, -1, 395, -1, 397, -1, 399, -1,
- 401, -1, 403, -1, -1, -1, 407, -1, 409, -1,
- 411, -1, 413, -1, 415, -1, 417, 261, 419, 263,
- 264, -1, 266, -1, -1, 269, 270, -1, -1, -1,
- 274, -1, -1, -1, 278, -1, -1, -1, -1, -1,
- 284, -1, -1, 287, -1, -1, -1, -1, -1, -1,
- 294, -1, -1, 297, -1, 299, -1, 301, 302, 303,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, 315, -1, 317, 318, -1, 320, -1, -1, 323,
- -1, 325, -1, 327, 328, 329, 330, -1, 332, -1,
- -1, -1, -1, -1, -1, -1, -1, 341, 342, -1,
- 344, 345, 346, 347, 348, 349, 350, 351, 352, 353,
- 354, 355, 356, 357, 358, 359, 360, 361, 362, 363,
- 364, 365, -1, 367, -1, 369, -1, 371, -1, 373,
- -1, 375, -1, 377, -1, 379, -1, 381, -1, 383,
- -1, 385, -1, 387, -1, 389, -1, 391, -1, 393,
- -1, 395, -1, 397, -1, 399, -1, 401, -1, 403,
- -1, -1, -1, 407, -1, 409, -1, 411, -1, 413,
- -1, 415, -1, 417, 261, 419, 263, 264, -1, 266,
- -1, -1, 269, 270, -1, -1, -1, 274, -1, -1,
- -1, 278, -1, -1, -1, -1, -1, 284, -1, -1,
- 287, -1, -1, -1, -1, -1, -1, 294, -1, -1,
- 297, -1, 299, -1, 301, 302, 303, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, 315, -1,
- 317, 318, -1, 320, -1, -1, 323, -1, 325, -1,
- 327, 328, 329, 330, -1, 332, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, 342, 343, 344, 345, 346,
- 347, 348, 349, 350, 351, 352, 353, 354, 355, 356,
- 357, 358, 359, 360, 361, 362, 363, 364, 365, -1,
- 367, -1, 369, -1, 371, -1, 373, -1, 375, -1,
- 377, -1, 379, -1, 381, -1, 383, -1, 385, -1,
- 387, -1, 389, -1, 391, -1, 393, -1, 395, -1,
- 397, -1, 399, -1, 401, -1, 403, -1, -1, -1,
- 407, -1, 409, -1, 411, -1, 413, -1, 415, -1,
- 417, 261, 419, 263, 264, -1, 266, -1, -1, 269,
- 270, -1, -1, -1, 274, -1, -1, -1, 278, -1,
- -1, -1, -1, -1, 284, -1, -1, 287, -1, -1,
- -1, -1, -1, -1, 294, -1, -1, 297, -1, 299,
- -1, 301, 302, 303, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, 315, -1, 317, 318, -1,
- 320, -1, -1, 323, -1, 325, -1, 327, 328, 329,
- 330, -1, 332, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, 342, 343, 344, 345, 346, -1, 348, 349,
- 350, 351, 352, 353, 354, 355, 356, 357, 358, 359,
- 360, 361, 362, 363, 364, 365, -1, 367, -1, 369,
- -1, 371, -1, 373, -1, 375, -1, 377, -1, 379,
- -1, 381, -1, 383, -1, 385, -1, 387, -1, 389,
- -1, 391, -1, 393, -1, 395, -1, 397, -1, 399,
- -1, 401, -1, 403, -1, -1, -1, 407, -1, 409,
- -1, 411, -1, 413, -1, 415, -1, 417, 261, 419,
- 263, 264, -1, 266, -1, -1, 269, 270, -1, -1,
- -1, 274, -1, -1, -1, 278, -1, -1, -1, -1,
- -1, 284, -1, -1, 287, -1, -1, -1, -1, -1,
- -1, 294, -1, -1, 297, -1, 299, -1, 301, 302,
- 303, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, 315, -1, 317, 318, -1, 320, -1, -1,
- 323, -1, 325, -1, 327, 328, 329, 330, -1, 332,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, 342,
- -1, 344, -1, 346, -1, 348, 349, 350, 351, 352,
- 353, 354, 355, 356, 357, 358, 359, 360, 361, 362,
- 363, 364, -1, -1, -1, -1, 369, -1, 371, -1,
- 373, -1, 375, -1, 377, -1, 379, -1, 381, -1,
- 383, -1, 385, -1, 387, -1, 389, -1, 391, -1,
- 393, -1, 395, -1, 397, -1, 399, -1, 401, -1,
- 403, -1, -1, -1, 407, -1, 409, -1, 411, -1,
- 413, -1, 415, -1, 417, 261, 419, 263, 264, -1,
- 266, -1, -1, 269, 270, -1, -1, -1, 274, -1,
- -1, -1, 278, -1, -1, -1, -1, -1, 284, -1,
- -1, 287, -1, -1, -1, -1, -1, -1, 294, -1,
- -1, 297, -1, 299, -1, 301, 302, 303, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, 315,
- -1, 317, 318, -1, 320, -1, -1, 323, -1, 325,
- -1, 327, 328, 329, 330, -1, 332, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, 342, -1, 344, 345,
- 346, -1, 348, 349, 350, 351, 352, 353, 354, -1,
- 356, 357, 358, 359, 360, 361, 362, 363, 364, 365,
- -1, 367, -1, 369, -1, 371, -1, 373, -1, 375,
- -1, 377, -1, 379, -1, 381, -1, 383, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, 261,
- -1, 263, 264, -1, 266, -1, -1, 269, 270, -1,
- -1, 407, 274, 409, -1, 411, 278, 413, -1, 415,
- -1, 417, 284, 419, -1, 287, -1, -1, -1, -1,
- -1, -1, 294, -1, -1, 297, -1, 299, -1, 301,
- 302, 303, 304, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, 315, -1, 317, 318, -1, 320, -1,
- -1, 323, -1, 325, -1, 327, 328, 329, 330, -1,
- 332, -1, -1, -1, -1, -1, -1, -1, -1, 341,
- 342, 343, 344, 345, 346, -1, 348, 349, 350, 351,
- 352, 353, 354, -1, 356, 357, 358, 359, 360, -1,
- -1, 363, 364, 365, -1, 367, -1, -1, -1, -1,
- -1, 373, -1, 375, -1, 377, -1, 379, -1, 381,
- -1, 383, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, 261, -1, 263, 264, -1, 266, -1,
- -1, 269, 270, -1, -1, 407, 274, 409, -1, 411,
- 278, 413, -1, 415, -1, 417, 284, 419, -1, 287,
- -1, -1, -1, -1, -1, -1, 294, -1, -1, 297,
- -1, 299, -1, 301, 302, 303, 304, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, 315, -1, 317,
- 318, -1, 320, -1, -1, 323, -1, 325, -1, 327,
- 328, 329, 330, -1, 332, -1, -1, -1, -1, -1,
- -1, -1, -1, 341, 342, -1, 344, 345, 346, -1,
- 348, 349, 350, 351, 352, 353, 354, -1, 356, 357,
- 358, 359, 360, -1, -1, 363, 364, 365, -1, 367,
- -1, -1, -1, -1, -1, 373, -1, 375, -1, 377,
- -1, 379, -1, 381, -1, 383, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, 261, -1, 263,
- 264, -1, 266, -1, -1, 269, 270, -1, -1, 407,
- 274, 409, -1, 411, 278, 413, -1, 415, -1, 417,
- 284, 419, -1, 287, -1, -1, -1, -1, -1, -1,
- 294, -1, -1, 297, -1, 299, -1, 301, 302, 303,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, 315, -1, 317, 318, -1, 320, -1, -1, 323,
- -1, 325, -1, 327, 328, 329, 330, -1, 332, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, 342, -1,
- 344, 345, 346, -1, 348, 349, 350, 351, 352, 353,
- 354, -1, 356, 357, 358, 359, -1, -1, -1, 363,
- 364, 365, -1, 367, -1, 369, -1, 371, -1, 373,
- -1, 375, -1, 377, -1, 379, -1, 381, -1, 383,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, 261, -1, 263, 264, -1, 266, -1, -1, 269,
- 270, -1, -1, 407, 274, 409, -1, 411, 278, 413,
- -1, 415, -1, 417, 284, 419, -1, 287, -1, -1,
- -1, -1, -1, -1, 294, -1, -1, 297, -1, 299,
- -1, 301, 302, 303, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, 315, -1, 317, 318, -1,
- 320, -1, -1, 323, -1, 325, -1, 327, 328, 329,
- 330, -1, 332, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, 342, -1, 344, 345, 346, -1, 348, 349,
- 350, 351, 352, 353, 354, -1, 356, 357, 358, 359,
- -1, -1, -1, 363, 364, 365, -1, 367, -1, 369,
- -1, 371, -1, 373, -1, 375, -1, 377, -1, 379,
- -1, 381, -1, 383, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, 261, -1, 263, 264, -1,
- 266, -1, -1, 269, 270, -1, -1, 407, 274, 409,
- -1, 411, 278, 413, -1, 415, -1, 417, 284, 419,
- -1, 287, -1, -1, -1, -1, -1, -1, 294, -1,
- -1, 297, -1, 299, -1, 301, 302, 303, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, 315,
- -1, 317, 318, -1, 320, -1, -1, 323, -1, 325,
- -1, 327, 328, 329, 330, -1, 332, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, 342, -1, 344, 345,
- 346, -1, 348, 349, 350, 351, 352, 353, 354, -1,
- 356, 357, 358, 359, -1, -1, -1, 363, 364, 365,
- -1, 367, -1, 369, -1, 371, -1, 373, -1, 375,
- -1, 377, -1, 379, -1, 381, -1, 383, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, 261,
- -1, 263, 264, -1, 266, -1, -1, 269, 270, -1,
- -1, 407, 274, 409, -1, 411, 278, 413, -1, 415,
- -1, 417, 284, 419, -1, 287, -1, -1, -1, -1,
- -1, -1, 294, -1, -1, 297, -1, 299, -1, 301,
- 302, 303, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, 315, -1, 317, 318, -1, 320, -1,
- -1, 323, -1, 325, -1, 327, 328, 329, 330, -1,
- 332, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- 342, -1, 344, 345, 346, -1, 348, 349, 350, 351,
- -1, -1, 354, -1, 356, 357, 358, 359, 360, -1,
- -1, 363, 364, 365, -1, 367, -1, 369, -1, 371,
- -1, 373, -1, 375, -1, 377, -1, 379, -1, 381,
- -1, 383, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, 261, -1, 263, 264, -1, 266, -1,
- -1, 269, 270, -1, -1, 407, 274, 409, -1, 411,
- 278, 413, -1, 415, -1, 417, 284, 419, -1, 287,
- -1, -1, -1, -1, -1, -1, 294, -1, -1, 297,
- -1, 299, -1, 301, 302, 303, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, 315, -1, 317,
- 318, -1, 320, -1, -1, 323, -1, 325, -1, 327,
- 328, 329, 330, -1, 332, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, 342, -1, 344, 345, 346, -1,
- 348, 349, 350, 351, 352, 353, 354, -1, 356, 357,
- 358, 359, 360, -1, -1, 363, 364, 365, -1, 367,
- -1, -1, -1, -1, -1, 373, -1, 375, -1, 377,
- -1, 379, -1, 381, -1, 383, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, 261, -1, 263,
- 264, -1, 266, -1, -1, 269, 270, -1, -1, 407,
- 274, 409, -1, 411, 278, 413, -1, 415, -1, 417,
- 284, 419, -1, 287, -1, -1, -1, -1, -1, -1,
- 294, -1, -1, 297, -1, 299, -1, 301, 302, 303,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, 315, -1, 317, 318, -1, 320, -1, -1, 323,
- -1, 325, -1, 327, 328, 329, 330, -1, 332, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, 342, -1,
- 344, 345, 346, -1, 348, 349, 350, 351, -1, -1,
- 354, -1, 356, 357, 358, 359, 360, -1, -1, 363,
- 364, 365, -1, 367, -1, 369, -1, 371, -1, 373,
- -1, 375, -1, 377, -1, 379, -1, 381, -1, 383,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, 261, -1, 263, 264, -1, 266, -1, -1, 269,
- 270, -1, -1, 407, 274, 409, -1, 411, 278, 413,
- -1, 415, -1, 417, 284, 419, -1, 287, -1, -1,
- -1, -1, -1, -1, 294, -1, -1, 297, -1, 299,
- -1, 301, 302, 303, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, 315, -1, 317, 318, -1,
- 320, -1, -1, 323, -1, 325, -1, 327, 328, 329,
- 330, -1, 332, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, 342, -1, 344, 345, 346, -1, 348, 349,
- 350, 351, -1, -1, 354, -1, 356, 357, 358, 359,
- 360, -1, -1, 363, 364, 365, -1, 367, -1, 369,
- -1, 371, -1, 373, -1, 375, -1, 377, -1, 379,
- -1, 381, -1, 383, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, 261, -1, 263, 264, -1,
- 266, -1, -1, 269, 270, -1, -1, 407, 274, 409,
- -1, 411, 278, 413, -1, 415, -1, 417, 284, 419,
- -1, 287, -1, -1, -1, -1, -1, -1, 294, -1,
- -1, 297, -1, 299, -1, 301, 302, 303, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, 315,
- -1, 317, 318, -1, 320, -1, -1, 323, -1, 325,
- -1, 327, 328, 329, 330, -1, 332, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, 342, -1, 344, 345,
- 346, -1, 348, 349, 350, 351, 352, 353, 354, -1,
- 356, 357, 358, 359, 360, -1, -1, 363, 364, 365,
- -1, 367, -1, -1, -1, -1, -1, 373, -1, 375,
- -1, 377, -1, 379, -1, 381, -1, 383, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, 261,
- -1, 263, 264, -1, 266, -1, -1, 269, 270, -1,
- -1, 407, 274, 409, -1, 411, 278, 413, -1, 415,
- -1, 417, 284, 419, -1, 287, -1, -1, -1, -1,
- -1, -1, 294, -1, -1, 297, -1, 299, -1, 301,
- 302, 303, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, 315, -1, 317, 318, -1, 320, -1,
- -1, 323, -1, 325, -1, 327, 328, 329, 330, -1,
- 332, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- 342, -1, 344, 345, 346, -1, 348, 349, 350, 351,
- 352, 353, 354, -1, 356, 357, 358, 359, 360, -1,
- -1, 363, 364, 365, -1, 367, -1, -1, -1, -1,
- -1, 373, -1, 375, -1, 377, -1, 379, -1, 381,
- -1, 383, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, 261, -1, 263, 264, -1, 266, -1,
- -1, 269, 270, -1, -1, 407, 274, 409, -1, 411,
- 278, 413, -1, 415, -1, 417, 284, 419, -1, 287,
- -1, -1, -1, -1, -1, -1, 294, -1, -1, 297,
- -1, 299, -1, 301, 302, 303, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, 315, -1, 317,
- 318, -1, 320, -1, -1, 323, -1, 325, -1, 327,
- 328, 329, 330, -1, 332, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, 342, -1, 344, 345, 346, -1,
- 348, 349, 350, 351, 352, 353, 354, -1, 356, 357,
- 358, 359, 360, -1, -1, 363, 364, 365, -1, 367,
- -1, -1, -1, -1, -1, 373, -1, 375, -1, 377,
- -1, 379, -1, 381, -1, 383, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, 261, -1, 263,
- 264, -1, 266, -1, -1, 269, 270, -1, -1, 407,
- 274, 409, -1, 411, 278, 413, -1, 415, -1, 417,
- 284, 419, -1, 287, -1, -1, -1, -1, -1, -1,
- 294, -1, -1, 297, -1, 299, -1, 301, 302, 303,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, 315, -1, 317, 318, -1, 320, -1, -1, 323,
- -1, 325, -1, 327, 328, 329, 330, -1, 332, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, 342, -1,
- 344, 345, 346, -1, 348, 349, 350, 351, 352, 353,
- 354, -1, 356, 357, 358, 359, 360, -1, -1, 363,
- 364, 365, -1, 367, -1, -1, -1, -1, -1, 373,
- -1, 375, -1, 377, -1, 379, -1, 381, -1, 383,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, 261, -1, 263, 264, -1, 266, -1, -1, 269,
- 270, -1, -1, 407, 274, 409, -1, 411, 278, 413,
- -1, 415, -1, 417, 284, 419, -1, 287, -1, -1,
- -1, -1, -1, -1, 294, -1, -1, 297, -1, 299,
- -1, 301, 302, 303, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, 315, -1, 317, 318, -1,
- 320, -1, -1, 323, -1, 325, -1, 327, 328, 329,
- 330, -1, 332, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, 342, -1, 344, 345, 346, -1, 348, 349,
- 350, 351, 352, 353, 354, -1, 356, 357, 358, 359,
- 360, -1, -1, 363, 364, 365, -1, 367, -1, -1,
- -1, -1, -1, 373, -1, 375, -1, 377, -1, 379,
- -1, 381, -1, 383, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, 261, -1, 263, 264, -1,
- 266, -1, -1, 269, 270, -1, -1, 407, 274, 409,
- -1, 411, 278, 413, -1, 415, -1, 417, 284, 419,
- -1, 287, -1, -1, -1, -1, -1, -1, 294, -1,
- -1, 297, -1, 299, -1, 301, 302, 303, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, 315,
- -1, 317, 318, -1, 320, -1, -1, 323, -1, 325,
- -1, 327, 328, 329, 330, -1, 332, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, 342, -1, 344, 345,
- 346, -1, 348, 349, 350, 351, 352, 353, 354, -1,
- 356, 357, 358, 359, 360, -1, -1, 363, 364, 365,
- -1, 367, -1, -1, -1, -1, -1, 373, -1, 375,
- -1, 377, -1, 379, -1, 381, -1, 383, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, 407, -1, 409, -1, 411, -1, 413, -1, 415,
- -1, 417, -1, 419, 263, 264, 265, 266, 267, -1,
- 269, 270, -1, 272, 273, 274, 275, -1, 277, 278,
- 279, -1, -1, -1, -1, 284, 285, -1, 287, 288,
- 289, 290, 291, -1, -1, 294, -1, -1, -1, 298,
- 299, -1, 301, 302, 303, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, 313, -1, 315, -1, 317, 318,
- -1, 320, -1, 322, 323, 324, 325, 326, 327, 328,
- 329, 330, -1, 332, 333, 260, 335, 336, -1, -1,
- -1, -1, 341, 342, -1, -1, 345, -1, -1, -1,
- -1, 350, 351, 352, 353, 354, -1, -1, 283, 358,
- -1, 360, -1, -1, -1, -1, 365, -1, 367, -1,
- -1, 296, -1, -1, -1, -1, 301, -1, -1, -1,
- -1, 306, -1, 308, 309, 310, 311, -1, -1, -1,
- -1, 316, -1, -1, 319, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, 407, 334,
- 409, -1, 411, -1, 413, -1, 415, -1, 417, -1,
- 419, 263, 264, 265, 266, 267, 351, 269, 270, -1,
- 272, 273, 274, 275, -1, 277, 278, 279, -1, -1,
- -1, -1, 284, -1, -1, 287, 288, 289, 290, 291,
- -1, -1, 294, -1, -1, -1, 298, 299, -1, 301,
- 302, 303, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, 313, -1, 315, -1, 317, 318, -1, 320, -1,
- 322, 323, 324, 325, 326, 327, 328, 329, 330, -1,
- 332, 333, 260, 335, 336, -1, -1, -1, -1, 341,
- 342, -1, -1, 345, -1, -1, -1, -1, 350, 351,
- 352, 353, 354, -1, -1, 283, 358, -1, 360, -1,
- -1, -1, -1, 365, -1, 367, -1, -1, 296, -1,
- -1, -1, -1, 301, -1, -1, -1, -1, 306, -1,
- 308, 309, 310, 311, -1, -1, -1, -1, 316, -1,
- -1, 319, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, 407, 334, 409, -1, 411,
- -1, 413, -1, 415, -1, 417, -1, 419, 263, 264,
- 265, 266, 267, -1, 269, 270, -1, 272, 273, 274,
- 275, -1, 277, 278, -1, -1, -1, -1, -1, 284,
- -1, -1, 287, 288, 289, 290, 291, -1, -1, 294,
- -1, -1, -1, 298, 299, -1, 301, 302, 303, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, 313, -1,
- 315, -1, 317, 318, -1, 320, -1, 322, 323, 324,
- 325, 326, 327, 328, 329, 330, -1, 332, 333, -1,
- 335, 336, -1, -1, -1, -1, 341, 342, -1, -1,
- 345, -1, -1, -1, -1, 350, 351, 352, 353, 354,
- -1, -1, -1, 358, -1, 360, -1, -1, -1, -1,
- 365, -1, 367, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, 407, -1, 409, -1, 411, -1, 413, -1,
- 415, -1, 417, -1, 419, 263, 264, 265, 266, -1,
- -1, 269, 270, -1, 272, 273, 274, -1, -1, 277,
- 278, -1, -1, -1, -1, -1, 284, -1, -1, 287,
- 288, 289, 290, 291, -1, -1, 294, -1, -1, -1,
- 298, 299, -1, 301, 302, 303, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, 313, -1, 315, -1, 317,
- 318, -1, 320, -1, 322, 323, 324, 325, 326, 327,
- 328, 329, 330, -1, 332, 333, -1, 335, 336, -1,
- -1, -1, -1, 341, -1, -1, -1, 345, -1, -1,
- -1, -1, 350, 351, 352, 353, 354, -1, -1, -1,
- 358, -1, 360, -1, -1, -1, -1, 365, -1, 367,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, 407,
- -1, 409, -1, 411, -1, 413, -1, 415, -1, 417,
- -1, 419, 263, 264, 265, 266, -1, -1, 269, 270,
- -1, 272, 273, 274, -1, -1, 277, 278, -1, -1,
- -1, -1, -1, 284, -1, -1, 287, 288, 289, 290,
- 291, -1, -1, 294, -1, -1, -1, 298, 299, -1,
- 301, 302, 303, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, 313, -1, 315, -1, 317, 318, -1, 320,
- -1, 322, 323, 324, 325, 326, 327, 328, 329, 330,
- -1, 332, 333, -1, 335, 336, -1, -1, -1, -1,
- 341, -1, -1, -1, 345, -1, -1, -1, -1, 350,
- 351, 352, 353, 354, -1, -1, -1, 358, -1, 360,
- -1, -1, -1, -1, 365, -1, 367, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, 407, -1, 409, -1,
- 411, -1, 413, -1, 415, -1, 417, -1, 419, 263,
- 264, 265, 266, -1, -1, 269, 270, -1, -1, 273,
- 274, -1, -1, 277, 278, -1, -1, -1, -1, -1,
- 284, -1, -1, 287, 288, 289, 290, 291, -1, -1,
- 294, -1, -1, -1, 298, 299, -1, 301, 302, 303,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, 313,
- -1, 315, -1, 317, 318, -1, 320, -1, 322, 323,
- 324, 325, 326, 327, 328, 329, 330, -1, 332, 333,
- -1, -1, 336, -1, -1, -1, -1, 341, -1, -1,
- -1, 345, -1, -1, -1, -1, 350, 351, 352, 353,
- 354, -1, -1, -1, 358, -1, 360, -1, -1, -1,
- -1, 365, -1, 367, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, 263, 264, -1, 266, -1, -1, 269,
- 270, -1, -1, 407, 274, 409, -1, 411, 278, 413,
- -1, 415, -1, 417, 284, 419, -1, 287, -1, -1,
- -1, -1, -1, -1, 294, -1, -1, -1, -1, 299,
- -1, 301, 302, 303, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, 315, -1, 317, 318, -1,
- 320, -1, -1, 323, -1, 325, -1, 327, 328, 329,
- 330, -1, 332, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, 342, -1, 344, 345, 346, -1, 348, 349,
- 350, 351, 352, 353, 354, -1, -1, -1, 358, 359,
- 360, -1, -1, 363, 364, 365, -1, 367, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, 377, -1, 379,
- -1, 381, -1, 383, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, 263, 264, -1,
- 266, -1, -1, 269, 270, -1, -1, 407, 274, 409,
- -1, 411, 278, 413, -1, 415, -1, 417, 284, 419,
- -1, 287, -1, -1, -1, -1, -1, -1, 294, -1,
- -1, -1, -1, 299, -1, 301, 302, 303, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, 315,
- -1, 317, 318, -1, 320, -1, -1, 323, -1, 325,
- -1, 327, 328, 329, 330, -1, 332, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, 342, -1, 344, 345,
- 346, -1, 348, 349, 350, 351, 352, 353, 354, -1,
- -1, -1, 358, 359, 360, -1, -1, 363, 364, 365,
- -1, 367, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, 377, -1, 379, -1, 381, -1, 383, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, 263, 264, -1, 266, -1, -1, 269, 270, -1,
- -1, 407, 274, 409, -1, 411, 278, 413, -1, 415,
- -1, 417, 284, 419, -1, 287, -1, -1, -1, -1,
- -1, -1, 294, -1, -1, -1, -1, 299, -1, 301,
- 302, 303, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, 315, -1, 317, 318, -1, 320, -1,
- -1, 323, -1, 325, -1, 327, 328, 329, 330, -1,
- 332, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- 342, -1, 344, 345, 346, -1, 348, 349, 350, 351,
- 352, 353, 354, -1, -1, -1, 358, 359, 360, -1,
- -1, 363, 364, 365, -1, 367, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, 377, -1, 379, -1, 381,
- -1, 383, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, 263, 264, -1, 266, -1,
- -1, 269, 270, -1, -1, 407, 274, 409, -1, 411,
- 278, 413, -1, 415, -1, 417, 284, 419, -1, 287,
- -1, -1, -1, -1, -1, -1, 294, -1, -1, -1,
- -1, 299, -1, 301, 302, 303, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, 315, -1, 317,
- 318, -1, 320, -1, -1, 323, -1, 325, -1, 327,
- 328, 329, 330, -1, 332, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, 342, -1, 344, 345, 346, -1,
- 348, 349, 350, 351, 352, 353, 354, -1, -1, -1,
- 358, 359, 360, -1, -1, 363, 364, 365, -1, 367,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, 381, -1, 383, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, 263,
- 264, -1, 266, -1, -1, 269, 270, -1, -1, 407,
- 274, 409, -1, 411, 278, 413, -1, 415, -1, 417,
- 284, 419, -1, 287, -1, -1, -1, -1, -1, -1,
- 294, -1, -1, -1, -1, 299, -1, 301, 302, 303,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, 315, -1, 317, 318, -1, 320, -1, -1, 323,
- -1, 325, -1, 327, 328, 329, 330, -1, 332, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, 342, -1,
- 344, 345, 346, -1, 348, 349, 350, 351, 352, 353,
- 354, -1, -1, -1, 358, 359, 360, -1, -1, 363,
- 364, 365, -1, 367, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, 381, -1, 383,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, 263, 264, -1, 266, -1, -1, 269,
- 270, -1, -1, 407, 274, 409, -1, 411, 278, 413,
- -1, 415, -1, 417, 284, 419, -1, 287, -1, -1,
- -1, -1, -1, -1, 294, -1, -1, -1, -1, 299,
- -1, 301, 302, 303, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, 315, -1, 317, 318, -1,
- 320, -1, -1, 323, -1, 325, -1, 327, 328, 329,
- 330, -1, 332, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, 342, -1, 344, 345, 346, -1, 348, 349,
- 350, 351, 352, 353, 354, -1, -1, -1, -1, 359,
- 360, -1, -1, 363, 364, 365, -1, 367, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, 381, -1, 383, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, 263, 264, -1,
- 266, -1, -1, 269, 270, -1, -1, 407, 274, 409,
- -1, 411, 278, 413, -1, 415, -1, 417, 284, 419,
- -1, 287, -1, -1, -1, -1, -1, -1, 294, -1,
- -1, -1, -1, 299, -1, 301, 302, 303, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, 315,
- -1, 317, 318, -1, 320, -1, -1, 323, -1, 325,
- -1, 327, 328, 329, 330, -1, 332, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, 342, -1, 344, 345,
- 346, -1, 348, 349, 350, 351, 352, 353, 354, -1,
- -1, -1, 358, 359, 360, -1, -1, -1, 364, 365,
- -1, 367, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, 381, -1, 383, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, 263, 264, -1, 266, -1, -1, 269, 270, -1,
- -1, 407, 274, 409, -1, 411, 278, 413, -1, 415,
- -1, 417, 284, 419, -1, 287, -1, -1, -1, -1,
- -1, -1, 294, -1, -1, -1, -1, 299, -1, 301,
- 302, 303, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, 315, -1, 317, 318, -1, 320, -1,
- -1, 323, -1, 325, -1, 327, 328, 329, 330, -1,
- 332, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- 342, -1, 344, 345, 346, -1, 348, 349, 350, 351,
- 352, 353, 354, -1, -1, -1, -1, 359, 360, -1,
- -1, 363, 364, 365, -1, 367, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, 381,
- -1, 383, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, 263, 264, -1, 266, -1,
- -1, 269, 270, -1, -1, 407, 274, 409, -1, 411,
- 278, 413, -1, 415, -1, 417, 284, 419, -1, 287,
- -1, -1, -1, -1, -1, -1, 294, -1, -1, -1,
- -1, 299, -1, 301, 302, 303, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, 315, -1, 317,
- 318, -1, 320, -1, -1, 323, -1, 325, -1, 327,
- 328, 329, 330, -1, 332, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, 342, -1, 344, 345, 346, -1,
- 348, 349, 350, 351, 352, 353, 354, -1, -1, -1,
- 358, 359, 360, -1, -1, -1, 364, 365, -1, 367,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, 381, -1, 383, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, 263,
- 264, -1, 266, -1, -1, 269, 270, -1, -1, 407,
- 274, 409, -1, 411, 278, 413, -1, 415, -1, 417,
- 284, 419, -1, 287, -1, -1, -1, -1, -1, -1,
- 294, -1, -1, -1, -1, 299, -1, 301, 302, 303,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, 315, -1, 317, 318, -1, 320, -1, -1, 323,
- -1, 325, -1, 327, 328, 329, 330, -1, 332, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, 342, -1,
- 344, 345, 346, -1, 348, 349, 350, 351, 352, 353,
- 354, -1, -1, -1, 358, -1, 360, -1, -1, -1,
- 364, 365, -1, 367, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, 381, -1, 383,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, 263, 264, -1, 266, -1, -1, 269,
- 270, -1, -1, 407, 274, 409, -1, 411, 278, 413,
- -1, 415, -1, 417, 284, 419, -1, 287, -1, -1,
- -1, -1, -1, -1, 294, -1, -1, -1, -1, 299,
- -1, 301, 302, 303, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, 315, -1, 317, 318, -1,
- 320, -1, -1, 323, -1, 325, -1, 327, 328, 329,
- 330, -1, 332, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, 342, -1, 344, 345, 346, -1, 348, 349,
- 350, 351, 352, 353, 354, -1, -1, -1, 358, -1,
- 360, -1, -1, -1, 364, 365, -1, 367, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, 381, -1, 383, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, 263, 264, -1,
- 266, -1, -1, 269, 270, -1, -1, 407, 274, 409,
- -1, 411, 278, 413, -1, 415, -1, 417, 284, 419,
- -1, 287, -1, -1, -1, -1, -1, -1, 294, -1,
- -1, -1, -1, 299, -1, 301, 302, 303, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, 315,
- -1, 317, 318, -1, 320, -1, -1, 323, -1, 325,
- -1, 327, 328, 329, 330, -1, 332, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, 342, -1, 344, 345,
- 346, -1, 348, 349, 350, 351, 352, 353, 354, -1,
- -1, -1, 358, -1, 360, -1, -1, -1, 364, 365,
- -1, 367, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, 383, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, 263, 264, -1, 266, -1, -1, 269, 270, -1,
- -1, 407, 274, 409, -1, 411, 278, 413, -1, 415,
- -1, 417, 284, 419, -1, 287, -1, -1, -1, -1,
- -1, -1, 294, -1, -1, -1, -1, 299, -1, 301,
- 302, 303, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, 315, -1, 317, 318, -1, 320, -1,
- -1, 323, -1, 325, -1, 327, 328, 329, 330, -1,
- 332, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- 342, -1, 344, 345, 346, -1, 348, 349, 350, 351,
- 352, 353, 354, -1, -1, -1, 358, -1, 360, -1,
- -1, -1, 364, 365, -1, 367, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, 383, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, 263, 264, -1, 266, -1,
- -1, 269, 270, -1, -1, 407, 274, 409, -1, 411,
- 278, 413, -1, 415, -1, 417, 284, 419, -1, 287,
- -1, -1, -1, -1, -1, -1, 294, -1, -1, -1,
- -1, 299, -1, 301, 302, 303, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, 315, -1, 317,
- 318, -1, 320, -1, -1, 323, -1, 325, -1, 327,
- 328, 329, 330, -1, 332, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, 342, -1, 344, 345, 346, -1,
- 348, 349, 350, 351, 352, 353, 354, -1, -1, -1,
- 358, -1, 360, -1, -1, -1, -1, 365, -1, 367,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, 263,
- 264, -1, 266, -1, -1, 269, 270, -1, -1, 407,
- 274, 409, -1, 411, 278, 413, -1, 415, -1, 417,
- 284, 419, -1, 287, -1, -1, -1, -1, -1, -1,
- 294, -1, -1, -1, -1, 299, -1, 301, 302, 303,
- -1, 305, -1, -1, -1, -1, -1, -1, 312, -1,
- -1, 315, -1, 317, 318, -1, 320, -1, -1, 323,
- -1, 325, -1, 327, 328, 329, 330, -1, 332, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, 345, -1, -1, -1, -1, -1, 351, 352, 353,
- 354, -1, -1, -1, 358, -1, 360, -1, -1, -1,
- -1, 365, -1, 367, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, 263, 264, -1, 266, -1, -1, 269,
- 270, -1, -1, 407, 274, 409, -1, 411, 278, 413,
- -1, 415, -1, 417, 284, 419, -1, 287, -1, -1,
- -1, -1, -1, -1, 294, -1, -1, -1, -1, 299,
- -1, 301, 302, 303, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, 315, -1, 317, 318, -1,
- 320, -1, -1, 323, -1, 325, -1, 327, 328, 329,
- 330, -1, 332, -1, -1, -1, -1, -1, -1, -1,
- -1, 341, 342, -1, -1, 345, -1, -1, -1, -1,
- -1, 351, 352, 353, 354, -1, -1, -1, 358, -1,
- 360, -1, -1, -1, -1, 365, -1, 367, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, 263, 264, -1,
- 266, -1, -1, 269, 270, -1, -1, 407, 274, 409,
- -1, 411, 278, 413, -1, 415, -1, 417, 284, 419,
- -1, 287, -1, -1, -1, -1, -1, -1, 294, -1,
- -1, -1, -1, 299, -1, 301, 302, 303, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, 315,
- -1, 317, 318, -1, 320, -1, -1, 323, -1, 325,
- -1, 327, 328, 329, 330, -1, 332, -1, -1, -1,
- -1, -1, -1, -1, -1, 341, 342, -1, -1, 345,
- -1, -1, -1, -1, -1, 351, 352, 353, 354, -1,
- -1, -1, 358, -1, 360, -1, -1, -1, -1, 365,
- -1, 367, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, 263, 264, -1, 266, -1, -1, 269, 270, -1,
- -1, 407, 274, 409, -1, 411, 278, 413, -1, 415,
- -1, 417, 284, 419, -1, 287, -1, -1, -1, -1,
- -1, -1, 294, -1, -1, -1, -1, 299, -1, 301,
- 302, 303, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, 315, -1, 317, 318, -1, 320, -1,
- -1, 323, -1, 325, -1, 327, 328, 329, 330, -1,
- 332, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, 345, -1, -1, 348, -1, 350, 351,
- 352, 353, 354, -1, -1, -1, 358, -1, 360, -1,
- -1, -1, -1, 365, -1, 367, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, 263, 264, -1, 266, -1,
- -1, 269, 270, -1, -1, 407, 274, 409, -1, 411,
- 278, 413, -1, 415, -1, 417, 284, 419, -1, 287,
- -1, -1, -1, -1, -1, -1, 294, -1, -1, -1,
- -1, 299, -1, 301, 302, 303, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, 315, -1, 317,
- 318, -1, 320, -1, -1, 323, -1, 325, -1, 327,
- 328, 329, 330, -1, 332, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, 345, -1, -1,
- 348, -1, -1, 351, 352, 353, 354, -1, -1, -1,
- 358, -1, 360, -1, -1, -1, -1, 365, -1, 367,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, 263,
- 264, -1, 266, -1, -1, 269, 270, -1, -1, 407,
- 274, 409, -1, 411, 278, 413, -1, 415, -1, 417,
- 284, 419, -1, 287, -1, -1, -1, -1, -1, -1,
- 294, -1, -1, -1, -1, 299, -1, 301, 302, 303,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, 315, -1, 317, 318, -1, 320, -1, -1, 323,
- -1, 325, -1, 327, 328, 329, 330, -1, 332, -1,
- -1, -1, -1, -1, -1, -1, -1, 341, -1, -1,
- -1, 345, -1, -1, -1, -1, -1, 351, 352, 353,
- 354, -1, -1, -1, 358, -1, 360, -1, -1, -1,
- -1, 365, -1, 367, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, 263, 264, -1, 266, -1, -1, 269,
- 270, -1, -1, 407, 274, 409, -1, 411, 278, 413,
- -1, 415, -1, 417, 284, 419, -1, 287, -1, -1,
- -1, -1, -1, -1, 294, -1, -1, -1, -1, 299,
- -1, 301, 302, 303, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, 315, -1, 317, 318, -1,
- 320, -1, -1, 323, -1, 325, -1, 327, 328, 329,
- 330, -1, 332, -1, -1, 335, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, 345, -1, -1, -1, -1,
- -1, 351, 352, 353, 354, -1, -1, -1, 358, -1,
- 360, -1, -1, -1, -1, 365, -1, 367, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, 263, 264, -1,
- 266, -1, -1, 269, 270, -1, -1, 407, 274, 409,
- -1, 411, 278, 413, -1, 415, -1, 417, 284, 419,
- -1, 287, -1, -1, -1, -1, -1, -1, 294, -1,
- -1, -1, -1, 299, -1, 301, 302, 303, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, 315,
- -1, 317, 318, -1, 320, -1, -1, 323, -1, 325,
- -1, 327, 328, 329, 330, -1, 332, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, 345,
- -1, -1, -1, -1, 350, 351, 352, 353, 354, -1,
- -1, -1, 358, -1, 360, -1, -1, -1, -1, 365,
- -1, 367, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, 263, 264, -1, 266, -1, -1, 269, 270, -1,
- -1, 407, 274, 409, -1, 411, 278, 413, -1, 415,
- -1, 417, 284, 419, -1, 287, -1, -1, -1, -1,
- -1, -1, 294, -1, -1, -1, -1, 299, -1, 301,
- 302, 303, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, 315, -1, 317, 318, -1, 320, -1,
- -1, 323, -1, 325, -1, 327, 328, 329, 330, -1,
- 332, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, 345, -1, -1, -1, -1, -1, 351,
- 352, 353, 354, -1, -1, -1, 358, -1, 360, -1,
- -1, -1, -1, 365, -1, 367, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, 263, 264, -1, 266, -1,
- -1, 269, 270, -1, -1, 407, 274, 409, -1, 411,
- 278, 413, -1, 415, -1, 417, 284, 419, -1, 287,
- -1, -1, -1, -1, -1, -1, 294, -1, -1, -1,
- -1, 299, -1, 301, 302, 303, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, 315, -1, 317,
- 318, -1, 320, -1, -1, 323, -1, 325, -1, 327,
- 328, 329, 330, -1, 332, -1, 264, 335, 266, -1,
- -1, 269, -1, 271, 272, -1, 274, 345, 276, -1,
- 278, -1, 280, 281, 282, -1, -1, -1, -1, 287,
- -1, -1, -1, -1, 292, -1, 294, 295, -1, -1,
- -1, 299, -1, -1, -1, 303, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, 315, -1, 317,
- -1, -1, 320, 321, -1, -1, -1, -1, -1, -1,
- 328, 329, -1, -1, 332, -1, -1, 335, -1, 407,
- -1, 409, -1, 411, -1, 413, -1, 415, 264, 417,
- 266, 419, -1, 269, -1, 271, 272, -1, 274, -1,
- 276, -1, 278, -1, 280, 281, 282, -1, -1, -1,
- -1, 287, -1, -1, -1, -1, 292, -1, 294, 295,
- -1, -1, -1, 299, -1, -1, -1, 303, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, 315,
- -1, 317, -1, -1, 320, 321, -1, -1, -1, -1,
- -1, -1, 328, 329, -1, 264, 332, 266, -1, 335,
- 269, 419, 271, 272, -1, 274, -1, 276, -1, 278,
- -1, 280, 281, 282, -1, -1, -1, -1, 287, -1,
- -1, -1, -1, 292, -1, 294, 295, -1, -1, -1,
- 299, -1, -1, -1, 303, -1, -1, -1, -1, 264,
- -1, 266, -1, -1, 269, -1, 315, -1, 317, 274,
- -1, 320, 321, 278, -1, -1, 281, -1, -1, 328,
- 329, -1, 287, 332, -1, -1, 335, -1, -1, 294,
- -1, -1, -1, -1, 299, -1, 301, -1, 303, -1,
- -1, -1, -1, 419, -1, -1, -1, -1, -1, -1,
- 315, 264, 317, 266, -1, 320, 269, -1, -1, -1,
- -1, 274, -1, 328, 329, 278, -1, 332, 281, -1,
- 335, -1, -1, -1, 287, -1, -1, 342, -1, -1,
- -1, 294, 264, -1, 266, -1, 299, 269, 301, -1,
- 303, -1, 274, -1, -1, -1, 278, -1, -1, -1,
- -1, -1, 315, -1, 317, 287, -1, 320, -1, -1,
- 419, -1, 294, -1, -1, 328, 329, 299, -1, 332,
- -1, 303, 335, 305, -1, 307, 264, -1, 266, 342,
- 312, 269, -1, 315, -1, 317, 274, -1, 320, -1,
- 278, -1, -1, -1, -1, -1, 328, 329, -1, 287,
- 332, -1, -1, -1, 419, -1, 294, -1, 264, -1,
- 266, 299, -1, 269, 346, 303, -1, 305, 274, 307,
- -1, -1, 278, -1, 312, 281, -1, 315, -1, 317,
- -1, 287, 320, -1, -1, -1, -1, -1, 294, -1,
- 328, 329, -1, 299, 332, -1, -1, 303, -1, -1,
- -1, -1, -1, -1, -1, 264, 419, 266, -1, 315,
- 269, 317, -1, -1, 320, 274, -1, -1, -1, 278,
- -1, -1, 328, 329, -1, -1, 332, -1, 287, 335,
- -1, -1, -1, -1, -1, 294, -1, 419, -1, -1,
- 299, 264, -1, 266, 303, -1, 269, -1, -1, -1,
- -1, 274, -1, -1, -1, 278, 315, -1, 317, -1,
- -1, 320, -1, -1, 287, -1, -1, -1, -1, 328,
- 329, 294, -1, 332, -1, -1, 299, -1, -1, -1,
- 303, 419, 341, -1, -1, -1, -1, -1, -1, -1,
- 349, -1, 315, 264, 317, 266, -1, 320, 269, -1,
- -1, -1, -1, 274, -1, 328, 329, 278, -1, 332,
- 281, 261, -1, 419, -1, 264, 287, 266, 341, -1,
- 269, -1, -1, 294, -1, 274, 349, -1, 299, 278,
- -1, -1, 303, -1, -1, -1, -1, -1, 287, -1,
- -1, -1, -1, -1, 315, 294, 317, 297, -1, 320,
- 299, -1, -1, -1, 303, -1, -1, 328, 329, -1,
- 419, 332, -1, -1, 335, -1, 315, -1, 317, -1,
- -1, 320, -1, -1, -1, -1, -1, -1, -1, 328,
- 329, -1, -1, 332, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, 343, -1, 345, 419, -1, -1, -1,
- -1, -1, 352, 353, -1, 355, 356, 357, 358, 359,
- 360, 361, 362, 363, 364, 365, -1, 367, -1, 369,
- -1, 371, -1, 373, -1, 375, -1, 377, -1, 379,
- -1, 381, -1, 383, -1, 385, -1, 387, -1, 389,
- -1, 391, -1, 393, -1, 395, -1, 397, 419, 399,
- -1, 401, 257, 403, -1, 260, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, 271, -1, -1, -1,
- 419, 276, -1, -1, -1, 280, -1, -1, 283, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- 295, 296, -1, -1, -1, 300, 301, -1, -1, -1,
- -1, 306, -1, 308, 309, 310, 311, 257, -1, -1,
- 260, 316, -1, -1, 319, -1, 321, -1, -1, -1,
- -1, 271, -1, -1, -1, -1, 276, -1, -1, 334,
- 280, -1, -1, 283, -1, -1, -1, 342, 343, -1,
- -1, -1, -1, -1, -1, 295, 296, -1, -1, -1,
- 300, 301, -1, -1, -1, -1, 306, -1, 308, 309,
- 310, 311, 257, -1, -1, 260, 316, -1, -1, 319,
- -1, 321, -1, -1, -1, -1, 271, -1, -1, -1,
- -1, 276, -1, -1, 334, 280, -1, -1, 283, -1,
- -1, -1, 342, 343, -1, -1, -1, -1, -1, -1,
- 295, 296, -1, -1, -1, 300, 301, -1, -1, -1,
- -1, 306, -1, 308, 309, 310, 311, 257, -1, -1,
- 260, 316, -1, -1, 319, -1, 321, -1, -1, -1,
- -1, 271, -1, -1, -1, -1, 276, -1, -1, 334,
- 280, -1, 260, 283, -1, -1, -1, -1, 343, -1,
- -1, -1, -1, 271, -1, 295, 296, -1, 276, -1,
- -1, 301, 280, -1, -1, 283, 306, -1, 308, 309,
- 310, 311, -1, -1, -1, -1, 316, 295, 296, 319,
- -1, 321, 300, 301, -1, -1, -1, -1, 306, -1,
- 308, 309, 310, 311, 334, 260, -1, -1, 316, -1,
- -1, 319, 342, 321, -1, -1, 271, -1, -1, 257,
- -1, 276, 260, -1, -1, 280, 334, -1, 283, -1,
- -1, -1, -1, 271, 342, 343, -1, -1, 276, -1,
- 295, 296, 280, -1, -1, 283, 301, -1, -1, -1,
- -1, 306, -1, 308, 309, 310, 311, 295, 296, -1,
- -1, 316, 300, 301, 319, -1, 321, -1, 306, -1,
- 308, 309, 310, 311, 257, -1, -1, 260, 316, 334,
- -1, 319, -1, 321, -1, -1, -1, 342, 271, -1,
- -1, -1, -1, 276, -1, -1, 334, 280, -1, -1,
- 283, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, 295, 296, -1, -1, -1, 343, 301, 345,
- 346, 347, 348, 306, 350, 308, 309, 310, 311, 355,
- -1, -1, -1, 316, -1, -1, 319, -1, 321, 365,
- 343, 367, 345, 346, 347, 348, -1, 350, -1, -1,
- -1, 334, 355, -1, -1, -1, -1, -1, -1, 385,
- -1, 387, 365, 389, 367, 391, -1, 393, -1, 395,
- -1, 397, -1, 399, -1, 401, -1, 403, -1, -1,
- -1, -1, 385, -1, 387, -1, 389, -1, 391, -1,
- 393, -1, 395, 419, 397, -1, 399, -1, 401, 343,
- 403, 345, 346, 347, 348, -1, 350, -1, -1, -1,
- 343, 355, 345, 346, 347, 348, 419, 350, -1, -1,
- -1, 365, 355, 367, -1, -1, -1, -1, -1, -1,
- -1, -1, 365, -1, 367, -1, -1, -1, -1, -1,
- -1, 385, -1, 387, -1, 389, -1, 391, -1, 393,
- -1, 395, 385, 397, 387, 399, 389, 401, 391, 403,
- 393, 343, 395, 345, 397, 347, 399, -1, 401, -1,
- 403, -1, -1, 355, -1, 419, -1, -1, -1, -1,
- -1, -1, -1, 365, -1, 367, 419, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, 385, -1, 387, -1, 389, -1, 391,
- -1, 393, -1, 395, -1, 397, -1, 399, -1, 401,
- -1, 403, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, 419,
- };
-
-#line 2535 "cs-parser.jay"
-
-
-// <summary>
-// A class used to pass around variable declarations and constants
-// </summary>
-public class VariableDeclaration {
- public string identifier;
- public object expression_or_array_initializer;
-
- public VariableDeclaration (string id, object eoai){
- this.identifier = id;
- this.expression_or_array_initializer = eoai;
- }
-}
-
-// <summary>
-// Given the @class_name name, it creates a fully qualified name
-// based on the containing declaration space
-// </summary>
-string
-MakeName (string class_name)
-{
- string ns = current_namespace.Name;
- string container_name = current_container.Name;
-
- if (container_name == ""){
- if (ns != "")
- return ns + "." + class_name;
- else
- return class_name;
- } else
- return container_name + "." + class_name;
-}
-
-// <summary>
-// Used to report back to the user the result of a declaration
-// in the current declaration space
-// </summary>
-void
-CheckDef (DeclSpace.AdditionResult result, string name)
-{
- if (result == DeclSpace.AdditionResult.Success)
- return;
-
- switch (result){
- case DeclSpace.AdditionResult.NameExists:
- error (102, "The namespace `" + current_container.Name +
- "' already contains a definition for `"+
- name + "'");
- break;
-
-/*
- NEED TO HANDLE THIS IN SEMANTIC ANALYSIS:
-
- case DeclSpace.AdditionResult.MethodDuplicated:
- error (111, "Class `"+current_container.Name+
- "' already defines a member called '" +
- name + "' with the same parameter types");
- break;
-*/
- case DeclSpace.AdditionResult.EnclosingClash:
- error (542, "Member names cannot be the same as their enclosing type");
- break;
-
- case DeclSpace.AdditionResult.NotAConstructor:
- error (1520, "Class, struct, or interface method must have a return type");
- break;
- }
-}
-
-void
-CheckDef (bool result, string name)
-{
- if (result)
- return;
- CheckDef (DeclSpace.AdditionResult.NameExists, name);
-}
-
-Block declare_local_variables (TypeRef typeref, ArrayList variable_declarators)
-{
- Block implicit_block;
- ArrayList inits = null;
-
- //
- // We use the `Used' property to check whether statements
- // have been added to the current block. If so, we need
- // to create another block to contain the new declaration
- // otherwise, as an optimization, we use the same block to
- // add the declaration.
- //
- // FIXME: A further optimization is to check if the statements
- // that were added were added as part of the initialization
- // below. In which case, no other statements have been executed
- // and we might be able to reduce the number of blocks for
- // situations like this:
- //
- // int j = 1; int k = j + 1;
- //
- if (current_block.Used)
- implicit_block = new Block (current_block, true);
- else
- implicit_block = new Block (current_block, true);
-
- foreach (VariableDeclaration decl in variable_declarators){
- if (implicit_block.AddVariable (typeref, decl.identifier)){
- if (decl.expression_or_array_initializer != null){
- if (inits == null)
- inits = new ArrayList ();
- inits.Add (decl);
- }
- } else {
- error (128, "A local variable `" + decl.identifier +
- "' is already defined in this scope");
- }
- }
-
- if (inits == null)
- return implicit_block;
-
- foreach (VariableDeclaration decl in inits){
- if (decl.expression_or_array_initializer is Expression){
- Expression expr = (Expression) decl.expression_or_array_initializer;
- Assign assign;
-
- assign = new Assign (new LocalVariableReference (implicit_block, decl.identifier), expr);
- implicit_block.AddStatement (new StatementExpression (assign));
- } else {
- }
- }
-
- return implicit_block;
-}
-
-void CheckConstant (Expression expr)
-{
- // finishme
-}
-
-void CheckBoolean (Expression expr)
-{
- // finishme
-}
-
-static public void error (int code, string desc)
-{
- Console.WriteLine ("Error CS"+code+": "+desc);
- global_errors++;
-}
-
-void output (string s)
-{
- Console.WriteLine (s);
-}
-
-void note (string s)
-{
- // Used to put annotations
-}
-
-TypeRef type (string type_name)
-{
- return type_references.GetTypeRef (current_container, type_name);
-}
-
-Tokenizer lexer;
-
-public CSharpParser(CIR.Tree tree, string name, System.IO.Stream input)
- : base (tree, name, input)
-{
- current_namespace = new Namespace (null, "");
- current_container = tree.Types;
- current_container.Namespace = current_namespace;
-
- lexer = new Tokenizer (input, name);
- type_references = new TypeRefManager ();
-}
-
-public override int parse ()
-{
- StringBuilder value = new StringBuilder ();
-
- global_errors = 0;
- try {
- if (yacc_verbose_flag)
- yyparse (lexer, new yydebug.yyDebugSimple ());
- else
- yyparse (lexer);
- } catch (Exception e){
- Console.WriteLine ("Fatal error: "+name);
- Console.WriteLine (e);
- Console.WriteLine (lexer.location);
- global_errors++;
- }
-
- return global_errors;
-}
-
-bool yacc_verbose_flag = false;
-
-public bool yacc_verbose {
- set {
- yacc_verbose_flag = value;
- }
-
- get {
- return yacc_verbose_flag;
- }
-}
-
-/* end end end */
-}
-}
-
-#line 5289 "-"
-namespace yydebug {
- using System;
- public interface yyDebug {
- void push (int state, Object value);
- void lex (int state, int token, string name, Object value);
- void shift (int from, int to, int errorFlag);
- void pop (int state);
- void discard (int state, int token, string name, Object value);
- void reduce (int from, int to, int rule, string text, int len);
- void shift (int from, int to);
- void accept (Object value);
- void error (string message);
- void reject ();
- }
-
- class yyDebugSimple : yyDebug {
- void println (string s){
- Console.WriteLine (s);
- }
-
- public void push (int state, Object value) {
- println ("push\tstate "+state+"\tvalue "+value);
- }
-
- public void lex (int state, int token, string name, Object value) {
- println("lex\tstate "+state+"\treading "+name+"\tvalue "+value);
- }
-
- public void shift (int from, int to, int errorFlag) {
- switch (errorFlag) {
- default: // normally
- println("shift\tfrom state "+from+" to "+to);
- break;
- case 0: case 1: case 2: // in error recovery
- println("shift\tfrom state "+from+" to "+to
- +"\t"+errorFlag+" left to recover");
- break;
- case 3: // normally
- println("shift\tfrom state "+from+" to "+to+"\ton error");
- break;
- }
- }
-
- public void pop (int state) {
- println("pop\tstate "+state+"\ton error");
- }
-
- public void discard (int state, int token, string name, Object value) {
- println("discard\tstate "+state+"\ttoken "+name+"\tvalue "+value);
- }
-
- public void reduce (int from, int to, int rule, string text, int len) {
- println("reduce\tstate "+from+"\tuncover "+to
- +"\trule ("+rule+") "+text);
- }
-
- public void shift (int from, int to) {
- println("goto\tfrom state "+from+" to "+to);
- }
-
- public void accept (Object value) {
- println("accept\tvalue "+value);
- }
-
- public void error (string message) {
- println("error\t"+message);
- }
-
- public void reject () {
- println("reject");
- }
-
- }
-}
-// %token constants
- class Token {
- public const int EOF = 257;
- public const int NONE = 258;
- public const int ERROR = 259;
- public const int ABSTRACT = 260;
- public const int AS = 261;
- public const int ADD = 262;
- public const int BASE = 263;
- public const int BOOL = 264;
- public const int BREAK = 265;
- public const int BYTE = 266;
- public const int CASE = 267;
- public const int CATCH = 268;
- public const int CHAR = 269;
- public const int CHECKED = 270;
- public const int CLASS = 271;
- public const int CONST = 272;
- public const int CONTINUE = 273;
- public const int DECIMAL = 274;
- public const int DEFAULT = 275;
- public const int DELEGATE = 276;
- public const int DO = 277;
- public const int DOUBLE = 278;
- public const int ELSE = 279;
- public const int ENUM = 280;
- public const int EVENT = 281;
- public const int EXPLICIT = 282;
- public const int EXTERN = 283;
- public const int FALSE = 284;
- public const int FINALLY = 285;
- public const int FIXED = 286;
- public const int FLOAT = 287;
- public const int FOR = 288;
- public const int FOREACH = 289;
- public const int GOTO = 290;
- public const int IF = 291;
- public const int IMPLICIT = 292;
- public const int IN = 293;
- public const int INT = 294;
- public const int INTERFACE = 295;
- public const int INTERNAL = 296;
- public const int IS = 297;
- public const int LOCK = 298;
- public const int LONG = 299;
- public const int NAMESPACE = 300;
- public const int NEW = 301;
- public const int NULL = 302;
- public const int OBJECT = 303;
- public const int OPERATOR = 304;
- public const int OUT = 305;
- public const int OVERRIDE = 306;
- public const int PARAMS = 307;
- public const int PRIVATE = 308;
- public const int PROTECTED = 309;
- public const int PUBLIC = 310;
- public const int READONLY = 311;
- public const int REF = 312;
- public const int RETURN = 313;
- public const int REMOVE = 314;
- public const int SBYTE = 315;
- public const int SEALED = 316;
- public const int SHORT = 317;
- public const int SIZEOF = 318;
- public const int STATIC = 319;
- public const int STRING = 320;
- public const int STRUCT = 321;
- public const int SWITCH = 322;
- public const int THIS = 323;
- public const int THROW = 324;
- public const int TRUE = 325;
- public const int TRY = 326;
- public const int TYPEOF = 327;
- public const int UINT = 328;
- public const int ULONG = 329;
- public const int UNCHECKED = 330;
- public const int UNSAFE = 331;
- public const int USHORT = 332;
- public const int USING = 333;
- public const int VIRTUAL = 334;
- public const int VOID = 335;
- public const int WHILE = 336;
- public const int GET = 337;
- public const int get = 338;
- public const int SET = 339;
- public const int set = 340;
- public const int OPEN_BRACE = 341;
- public const int CLOSE_BRACE = 342;
- public const int OPEN_BRACKET = 343;
- public const int CLOSE_BRACKET = 344;
- public const int OPEN_PARENS = 345;
- public const int CLOSE_PARENS = 346;
- public const int DOT = 347;
- public const int COMMA = 348;
- public const int COLON = 349;
- public const int SEMICOLON = 350;
- public const int TILDE = 351;
- public const int PLUS = 352;
- public const int MINUS = 353;
- public const int BANG = 354;
- public const int ASSIGN = 355;
- public const int OP_LT = 356;
- public const int OP_GT = 357;
- public const int BITWISE_AND = 358;
- public const int BITWISE_OR = 359;
- public const int STAR = 360;
- public const int PERCENT = 361;
- public const int DIV = 362;
- public const int CARRET = 363;
- public const int INTERR = 364;
- public const int OP_INC = 365;
- public const int OP_DEC = 367;
- public const int OP_SHIFT_LEFT = 369;
- public const int OP_SHIFT_RIGHT = 371;
- public const int OP_LE = 373;
- public const int OP_GE = 375;
- public const int OP_EQ = 377;
- public const int OP_NE = 379;
- public const int OP_AND = 381;
- public const int OP_OR = 383;
- public const int OP_MULT_ASSIGN = 385;
- public const int OP_DIV_ASSIGN = 387;
- public const int OP_MOD_ASSIGN = 389;
- public const int OP_ADD_ASSIGN = 391;
- public const int OP_SUB_ASSIGN = 393;
- public const int OP_SHIFT_LEFT_ASSIGN = 395;
- public const int OP_SHIFT_RIGHT_ASSIGN = 397;
- public const int OP_AND_ASSIGN = 399;
- public const int OP_XOR_ASSIGN = 401;
- public const int OP_OR_ASSIGN = 403;
- public const int OP_PTR = 405;
- public const int LITERAL_INTEGER = 407;
- public const int LITERAL_FLOAT = 409;
- public const int LITERAL_DOUBLE = 411;
- public const int LITERAL_DECIMAL = 413;
- public const int LITERAL_CHARACTER = 415;
- public const int LITERAL_STRING = 417;
- public const int IDENTIFIER = 419;
- public const int yyErrorCode = 256;
- }
- namespace yyParser {
- using System;
- /** thrown for irrecoverable syntax errors and stack overflow.
- */
- public class yyException : System.Exception {
- public yyException (string message) : base (message) {
- }
- }
-
- /** must be implemented by a scanner object to supply input to the parser.
- */
- public interface yyInput {
- /** move on to next token.
- @return false if positioned beyond tokens.
- @throws IOException on input error.
- */
- bool advance (); // throws java.io.IOException;
- /** classifies current token.
- Should not be called if advance() returned false.
- @return current %token or single character.
- */
- int token ();
- /** associated with current token.
- Should not be called if advance() returned false.
- @return value for token().
- */
- Object value ();
- }
- }
diff --git a/mcs/mcs/cs-parser.jay b/mcs/mcs/cs-parser.jay
index 3b792896953..31cfc646fa9 100755
--- a/mcs/mcs/cs-parser.jay
+++ b/mcs/mcs/cs-parser.jay
@@ -24,20 +24,17 @@
// separate problem
//
using System.Text;
-using CSC;
+using CIR;
using System;
-namespace CSC
+namespace CIR
{
using System.Collections;
- using Compiler;
- using CSC;
- using CIR;
/// <summary>
/// The C# Parser
/// </summary>
- public class CSharpParser : Parser {
+ public class CSharpParser {
static int global_errors;
Namespace current_namespace;
@@ -68,17 +65,20 @@ namespace CSC
// value parameter that is passed to the "set" accesor
// method
// </summary>
- ParameterCollection implicit_value_parameters;
-
- // <summary>
- // Here we keep track of type references.
- // </summary>
- TypeRefManager type_references;
+ Parameter [] implicit_value_parameters;
// <summary>
// Used to record all types defined
// </summary>
- CIR.Tree tree;
+ Tree tree;
+ RootContext rc;
+
+ // Name of the file we are parsing
+ public string name;
+
+ // Input stream to parse from.
+ public System.IO.Stream input;
+
%}
%token EOF
@@ -232,8 +232,23 @@ namespace CSC
%token IDENTIFIER
/* Add precedence rules to solve dangling else s/r conflict */
+%nonassoc LOWPREC
%nonassoc IF
%nonassoc ELSE
+%right ASSIGN
+%left OP_OR
+%left OP_AND
+%left BITWISE_OR
+%left BITWISE_AND
+%left OP_SHIFT_LEFT OP_SHIFT_RIGHT
+%left PLUS MINUS
+%left STAR DIV PERCENT
+%right BANG CARRET UMINUS
+%nonassoc OP_INC OP_DEC
+%left OPEN_PARENS
+%left OPEN_BRACKET OPEN_BRACE
+%left DOT
+%nonassoc HIGHPREC
%start compilation_unit
/*%start namespace_declaration */
@@ -369,16 +384,7 @@ type_declaration
//
opt_attributes
: /* empty */
- | attributes
- ;
-
-attributes
- : attribute_sections
- ;
-
-attribute_sections
- : attribute_section
- | attribute_sections attribute_section
+ | attribute_section opt_attributes
;
attribute_section
@@ -477,10 +483,10 @@ struct_declaration
Struct new_struct;
string full_struct_name = MakeName ((string) $4);
- new_struct = new Struct (current_container, full_struct_name, (int) $2);
+ new_struct = new Struct (rc, current_container, full_struct_name, (int) $2);
current_container = new_struct;
current_container.Namespace = current_namespace;
- tree.RecordType (full_class_name, new_struct);
+ tree.RecordStruct (full_struct_name, new_struct);
}
opt_struct_interfaces
struct_body
@@ -546,8 +552,8 @@ constant_declaration
foreach (DictionaryEntry constant in (ArrayList) $5){
Constant c = new Constant (
- (TypeRef) $4, (string) constant.Key,
- (Expression) constant.Value);
+ (string) $4, (string) constant.Key,
+ (Expression) constant.Value, (int) $2);
CheckDef (current_container.AddConstant (c), c.Name);
}
@@ -582,11 +588,11 @@ field_declaration
variable_declarators
SEMICOLON
{
- TypeRef typeref = (TypeRef) $3;
+ string type = (string) $3;
int mod = (int) $2;
foreach (VariableDeclaration var in (ArrayList) $4){
- Field field = new Field (typeref, mod, var.identifier,
+ Field field = new Field (type, mod, var.identifier,
var.expression_or_array_initializer);
CheckDef (current_container.AddField (field), field.Name);
@@ -646,7 +652,7 @@ method_header
member_name
OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS
{
- Method method = new Method ((TypeRef) $3, (int) $2, (string) $4, (Parameters) $6);
+ Method method = new Method ((string) $3, (int) $2, (string) $4, (Parameters) $6);
current_local_parameters = (Parameters) $6;
@@ -658,7 +664,7 @@ method_header
member_name
OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS
{
- Method method = new Method (type ("void"), (int) $2, (string) $4, (Parameters) $6);
+ Method method = new Method ("System.Void", (int) $2, (string) $4, (Parameters) $6);
current_local_parameters = (Parameters) $6;
$$ = method;
@@ -678,11 +684,21 @@ opt_formal_parameter_list
formal_parameter_list
: fixed_parameters
{
- $$ = new Parameters ((ParameterCollection) $1, null);
+ ArrayList pars_list = (ArrayList) $1;
+
+ Parameter [] pars = new Parameter [pars_list.Count];
+ pars_list.CopyTo (pars);
+
+ $$ = new Parameters (pars, null);
}
| fixed_parameters COMMA parameter_array
{
- $$ = new Parameters ((ParameterCollection) $1, (Parameter) $3);
+ ArrayList pars_list = (ArrayList) $1;
+
+ Parameter [] pars = new Parameter [pars_list.Count];
+ pars_list.CopyTo (pars);
+
+ $$ = new Parameters (pars, (Parameter) $3);
}
| parameter_array
{
@@ -693,14 +709,16 @@ formal_parameter_list
fixed_parameters
: fixed_parameter
{
- ParameterCollection pars = new ParameterCollection ();
- pars.Add ((Parameter) $1);
+ ArrayList pars = new ArrayList ();
+
+ pars.Add ($1);
$$ = pars;
}
| fixed_parameters COMMA fixed_parameter
{
- ParameterCollection pars = (ParameterCollection) $1;
- pars.Add ((Parameter) $3);
+ ArrayList pars = (ArrayList) $1;
+
+ pars.Add ($3);
$$ = $1;
}
;
@@ -711,7 +729,7 @@ fixed_parameter
type
IDENTIFIER
{
- $$ = new Parameter ((TypeRef) $3, (string) $4, (Parameter.Modifier) $2);
+ $$ = new Parameter ((string) $3, (string) $4, (Parameter.Modifier) $2);
}
;
@@ -728,7 +746,7 @@ parameter_modifier
parameter_array
: opt_attributes PARAMS type IDENTIFIER
{
- $$ = new Parameter ((TypeRef) $3, (string) $4, Parameter.Modifier.PARAMS);
+ $$ = new Parameter ((string) $3, (string) $4, Parameter.Modifier.PARAMS);
note ("type must be a single-dimension array type");
}
;
@@ -745,12 +763,12 @@ property_declaration
OPEN_BRACE
{
Parameter implicit_value_parameter;
- implicit_value_parameter = new Parameter ((TypeRef) $3, "value", Parameter.Modifier.NONE);
+ implicit_value_parameter = new Parameter ((string) $3, "value", Parameter.Modifier.NONE);
lexer.properties = true;
- implicit_value_parameters = new ParameterCollection ();
- implicit_value_parameters.Add (implicit_value_parameter);
+ implicit_value_parameters = new Parameter [1];
+ implicit_value_parameters [0] = implicit_value_parameter;
}
accessor_declarations
{
@@ -768,7 +786,7 @@ property_declaration
if (pair.Value != null)
set_block = (Block) pair.Value;
- prop = new Property ((TypeRef) $3, (string) $4, (int) $2, get_block, set_block);
+ prop = new Property ((string) $3, (string) $4, (int) $2, get_block, set_block);
CheckDef (current_container.AddProperty (prop), prop.Name);
implicit_value_parameters = null;
@@ -832,7 +850,7 @@ interface_declaration
if (current_interface != null)
error (-2, "Internal compiler error: interface inside interface");
current_interface = new_interface;
- tree.RecordType (full_class_name, new_interface);
+ tree.RecordInterface (full_interface_name, new_interface);
}
opt_interface_base
interface_body
@@ -862,6 +880,7 @@ interface_type_list
ArrayList interfaces = new ArrayList ();
interfaces.Add ($1);
+ $$ = interfaces;
}
| interface_type_list COMMA interface_type
{
@@ -924,13 +943,13 @@ interface_method_declaration
OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS
SEMICOLON
{
- $$ = new InterfaceMethod ((TypeRef) $3, (string) $4, (bool) $2, (Parameters) $6);
+ $$ = new InterfaceMethod ((string) $3, (string) $4, (bool) $2, (Parameters) $6);
}
| opt_attributes opt_new VOID IDENTIFIER
OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS
SEMICOLON
{
- $$ = new InterfaceMethod (type ("void"), (string) $4, (bool) $2, (Parameters) $6);
+ $$ = new InterfaceMethod ("System.Void", (string) $4, (bool) $2, (Parameters) $6);
}
;
@@ -946,7 +965,7 @@ interface_property_declaration
{
int gs = (int) $7;
- $$ = new InterfaceProperty ((TypeRef) $3, (string) $4, (bool) $2,
+ $$ = new InterfaceProperty ((string) $3, (string) $4, (bool) $2,
(gs & 1) == 1, (gs & 2) == 2);
}
;
@@ -963,7 +982,7 @@ interface_accesors
interface_event_declaration
: opt_attributes opt_new EVENT type IDENTIFIER SEMICOLON
{
- $$ = new InterfaceEvent ((TypeRef) $4, (string) $5, (bool) $2);
+ $$ = new InterfaceEvent ((string) $4, (string) $5, (bool) $2);
}
;
@@ -981,7 +1000,7 @@ interface_indexer_declaration
bool do_get = (a_flags & 1) == 1;
bool do_set = (a_flags & 2) == 2;
- $$ = new InterfaceIndexer ((TypeRef) $3, (Parameters) $6, do_get, do_set, (bool) $2);
+ $$ = new InterfaceIndexer ((string) $3, (Parameters) $6, do_get, do_set, (bool) $2);
}
;
@@ -1072,7 +1091,9 @@ constructor_declarator
{
ConstructorInitializer i = null;
- if ($5 != null)
+ if ($5 == null)
+ i = new ConstructorBaseInitializer (null);
+ else
i = (ConstructorInitializer) $5;
$$ = new Constructor ((string) $1, (Parameters) $3, i);
@@ -1100,7 +1121,7 @@ constructor_initializer
destructor_declaration
: opt_attributes TILDE IDENTIFIER OPEN_PARENS CLOSE_PARENS block
{
- Method d = new Method (type ("void"), 0, "Finalize", new Parameters (null, null));
+ Method d = new Method ("System.Void", 0, "Finalize", new Parameters (null, null));
d.Block = (Block) $6;
CheckDef (current_container.AddMethod (d), d.Name);
@@ -1134,7 +1155,11 @@ remove_accessor_declaration
indexer_declaration
: opt_attributes opt_modifiers indexer_declarator
- OPEN_BRACE accessor_declarations CLOSE_BRACE
+ OPEN_BRACE
+ { lexer.properties = true; }
+ accessor_declarations
+ { lexer.properties = false; }
+ CLOSE_BRACE
{
// The signature is computed from the signature of the indexer. Look
// at section 3.6 on the spec
@@ -1156,7 +1181,7 @@ enum_declaration
opt_semicolon
{
string name = (string) $4;
- Enum e = new Enum ((TypeRef) $5, (int) $2, name);
+ Enum e = new Enum ((string) $5, (int) $2, name);
foreach (VariableDeclaration ev in (ArrayList) $6){
CheckDef (
@@ -1171,7 +1196,7 @@ enum_declaration
;
opt_enum_base
- : /* empty */ { $$ = type ("System.Int32"); }
+ : /* empty */ { $$ = "System.Int32"; }
| COLON integral_type { $$ = $2; }
;
@@ -1180,15 +1205,11 @@ enum_body
{
$$ = $2;
}
- | OPEN_BRACE enum_member_declarations COMMA CLOSE_BRACE
- {
- $$ = $2;
- }
;
opt_enum_member_declarations
: /* empty */ { $$ = new ArrayList (); }
- | enum_member_declarations { $$ = $1; }
+ | enum_member_declarations opt_comma { $$ = $1; }
;
enum_member_declarations
@@ -1229,6 +1250,15 @@ delegate_declaration
CLOSE_PARENS
SEMICOLON
{ note ("validate that modifiers only contains NEW PUBLIC PROTECTED INTERNAL PRIVATE"); }
+
+ | opt_attributes
+ opt_modifiers
+ DELEGATE VOID
+ IDENTIFIER OPEN_PARENS
+ formal_parameter_list
+ CLOSE_PARENS
+ SEMICOLON
+ { note ("validate that modifiers only contains NEW PUBLIC PROTECTED INTERNAL PRIVATE"); }
;
type_name
@@ -1251,7 +1281,7 @@ type
This does interfaces, delegates, struct_types, class_types,
parent classes, and more! 4.2
*/
- $$ = type ((string) $1);
+ $$ = $1;
}
| builtin_types
| array_type
@@ -1265,10 +1295,11 @@ type_list
types.Add ($1);
$$ = types;
}
- | type_list type
+ | type_list COMMA type
{
- ArrayList types = new ArrayList ();
- types.Add ($2);
+ ArrayList types = (ArrayList) $1;
+
+ types.Add ($3);
$$ = types;
}
;
@@ -1278,25 +1309,25 @@ type_list
* simple types, but we need this to reuse it easily in local_variable_type
*/
builtin_types
- : OBJECT { $$ = type ("System.Object"); }
- | STRING { $$ = type ("System.String"); }
- | BOOL { $$ = type ("System.Boolean"); }
- | DECIMAL { $$ = type ("System.Decimal"); }
- | FLOAT { $$ = type ("System.Single"); }
- | DOUBLE { $$ = type ("System.Double"); }
+ : OBJECT { $$ = "System.Object"; }
+ | STRING { $$ = "System.String"; }
+ | BOOL { $$ = "System.Boolean"; }
+ | DECIMAL { $$ = "System.Decimal"; }
+ | FLOAT { $$ = "System.Single"; }
+ | DOUBLE { $$ = "System.Double"; }
| integral_type
;
integral_type
- : SBYTE { $$ = type ("System.SByte"); }
- | BYTE { $$ = type ("System.Byte"); }
- | SHORT { $$ = type ("System.Int16"); }
- | USHORT { $$ = type ("System.UInt16"); }
- | INT { $$ = type ("System.Int32"); }
- | UINT { $$ = type ("System.UInt32"); }
- | LONG { $$ = type ("System.Int64"); }
- | ULONG { $$ = type ("System.UInt64"); }
- | CHAR { $$ = type ("System.Char"); }
+ : SBYTE { $$ = "System.SByte"; }
+ | BYTE { $$ = "System.Byte"; }
+ | SHORT { $$ = "System.Int16"; }
+ | USHORT { $$ = "System.UInt16"; }
+ | INT { $$ = "System.Int32"; }
+ | UINT { $$ = "System.UInt32"; }
+ | LONG { $$ = "System.Int64"; }
+ | ULONG { $$ = "System.UInt64"; }
+ | CHAR { $$ = "System.Char"; }
;
interface_type
@@ -1396,7 +1427,7 @@ member_access
}
| predefined_type DOT IDENTIFIER
{
- $$ = new BuiltinTypeAccess ((TypeRef) $1, (string) $3);
+ $$ = new BuiltinTypeAccess ((string) $1, (string) $3);
}
;
@@ -1420,7 +1451,7 @@ invocation_expression
;
opt_argument_list
- : /* empty */ { $$ = new ArrayList (); }
+ : /* empty */ { $$ = null; }
| argument_list
;
@@ -1504,7 +1535,7 @@ new_expression
object_or_delegate_creation_expression
: NEW type OPEN_PARENS opt_argument_list CLOSE_PARENS
{
- $$ = new New ((TypeRef) $2, (ArrayList) $4);
+ $$ = new New ((string) $2, (ArrayList) $4);
}
;
@@ -1522,7 +1553,7 @@ opt_rank_specifier
rank_specifiers
: rank_specifier
- | rank_specifiers rank_specifier
+ | rank_specifier rank_specifiers
// finishme
;
@@ -1550,8 +1581,7 @@ opt_array_initializer
array_initializer
: OPEN_BRACE CLOSE_BRACE
- | OPEN_BRACE variable_initializer_list CLOSE_BRACE
- | OPEN_BRACE variable_initializer_list COMMA CLOSE_BRACE
+ | OPEN_BRACE variable_initializer_list opt_comma CLOSE_BRACE
// finishme
;
@@ -1564,13 +1594,13 @@ variable_initializer_list
typeof_expression
: TYPEOF OPEN_PARENS type CLOSE_PARENS
{
- $$ = new TypeOf ((TypeRef) $3);
+ $$ = new TypeOf ((string) $3);
}
;
sizeof_expression
: SIZEOF OPEN_PARENS type CLOSE_PARENS {
- $$ = new SizeOf ((TypeRef) $3);
+ $$ = new SizeOf ((string) $3);
note ("Verify type is unmanaged");
note ("if (5.8) builtin, yield constant expression");
@@ -1610,8 +1640,14 @@ unary_expression
{
$$ = new Unary (Unary.Operator.AddressOf, (Expression) $2);
}
- | pre_increment_expression
- | pre_decrement_expression
+ | OP_INC unary_expression
+ {
+ $$ = new Unary (Unary.Operator.PreIncrement, (Expression) $2);
+ }
+ | OP_DEC unary_expression
+ {
+ $$ = new Unary (Unary.Operator.PreDecrement, (Expression) $2);
+ }
| cast_expression
/*
we can not do cast expressions at this level,
@@ -1635,16 +1671,21 @@ pre_decrement_expression
;
cast_expression
- /* FIXME: This is actually wrong, it should be `type' but that
+ /*
+ * FIXME: This is actually wrong, it should be `type' but that
* introduces a lot of {shift,reduce}/reduces
+ *
+ * This is really really wrong. We need to track down
+ * the source of problems with QIs because expressions like:
+ * foreach (string s in (string []) object) wont be parsed.
*/
: OPEN_PARENS qualified_identifier CLOSE_PARENS unary_expression
{
- $$ = new Cast (type ((string) $2), (Expression) $4);
+ $$ = new Cast ((string) $2, (Expression) $4);
}
| OPEN_PARENS builtin_types CLOSE_PARENS unary_expression
{
- $$ = new Cast ((TypeRef) $2, (Expression) $4);
+ $$ = new Cast ((string) $2, (Expression) $4);
}
;
@@ -1720,12 +1761,12 @@ relational_expression
| relational_expression IS type
{
$$ = new Probe (Probe.Operator.Is,
- (Expression) $1, (TypeRef) $3);
+ (Expression) $1, (string) $3);
}
| relational_expression AS type
{
$$ = new Probe (Probe.Operator.As,
- (Expression) $1, (TypeRef) $3);
+ (Expression) $1, (string) $3);
}
;
@@ -1897,10 +1938,10 @@ class_declaration
Class new_class;
string full_class_name = MakeName ((string) $4);
- new_class = new Class (current_container, full_class_name, (int) $2);
+ new_class = new Class (rc, current_container, full_class_name, (int) $2);
current_container = new_class;
current_container.Namespace = current_namespace;
- tree.RecordType (full_class_name, new_class);
+ tree.RecordClass (full_class_name, new_class);
}
opt_class_base
class_body
@@ -1953,7 +1994,7 @@ modifier
opt_class_base
: /* empty */ { $$ = null; }
- | class_base { $$ = $1; }
+ | class_base { $$ = $1; }
;
class_base
@@ -2080,10 +2121,10 @@ local_variable_type
// SimpleName Expression.
//
if (((Expression) $1) is SimpleName)
- $$ = type (((SimpleName) $1).Name);
+ $$ = ((SimpleName) $1).Name;
else {
error (-1, "Invalid Type definition");
- $$ = type ("object");
+ $$ = "System.Object";
}
}
| builtin_types type_suffixes
@@ -2093,7 +2134,9 @@ local_variable_type
}
| VOID type_suffixes
{
- $$ = type ("VOID SOMETHING TYPE");
+ // FIXME: this is a string that represents the type
+ // Figure out something to make this work.
+ $$ = "VOID SOMETHING TYPE FIXME";
}
;
@@ -2115,7 +2158,7 @@ type_suffix
local_variable_declaration
: local_variable_type variable_declarators
{
- $$ = declare_local_variables ((TypeRef) $1, (ArrayList) $2);
+ $$ = declare_local_variables ((string) $1, (ArrayList) $2);
}
;
@@ -2328,8 +2371,8 @@ foreach_statement
foreach_block = new Block (current_block, true);
- foreach_block.AddVariable (type ("IEnumerator"), temp_id);
- foreach_block.AddVariable ((TypeRef) $3, (string) $4);
+ foreach_block.AddVariable ("System.IEnumerator", temp_id);
+ foreach_block.AddVariable ((string) $3, (string) $4);
assign_e = new Assign (new LocalVariableReference (foreach_block, temp_id),
new Invocation (
new MemberAccess ((Expression) $6, "GetEnumerator"), null));
@@ -2341,7 +2384,7 @@ foreach_statement
new Assign (
new LocalVariableReference (foreach_block, (string) $4),
new Cast (
- (TypeRef) $3,
+ (string) $3,
new MemberAccess (
new LocalVariableReference (foreach_block, temp_id), "Current"))));
@@ -2414,11 +2457,11 @@ try_statement
$$ = new Try ((Block) $2, s, (Catch) cc.Value, null);
}
- | TRY block finalize_clause
+ | TRY block FINALLY block
{
- $$ = new Try ((Block) $2, null, null, (Block) $3);
+ $$ = new Try ((Block) $2, null, null, (Block) $4);
}
- | TRY block catch_clauses finalize_clause
+ | TRY block catch_clauses FINALLY block
{
DictionaryEntry cc = (DictionaryEntry) $3;
ArrayList s = null;
@@ -2426,7 +2469,7 @@ try_statement
if (cc.Key != null)
s = (ArrayList) cc.Key;
- $$ = new Try ((Block) $2, s, (Catch) cc.Value, (Block) $4);
+ $$ = new Try ((Block) $2, s, (Catch) cc.Value, (Block) $5);
}
;
@@ -2485,7 +2528,7 @@ specific_catch_clause
if ($4 != null)
id = (string) $4;
- $$ = new Catch ((TypeRef) $3, id, (Block) $6);
+ $$ = new Catch ((string) $3, id, (Block) $6);
}
;
@@ -2501,13 +2544,6 @@ general_catch_clause
}
;
-finalize_clause
- : FINALLY block
- {
- $$ = $2;
- }
- ;
-
checked_statement
: CHECKED block
{
@@ -2618,7 +2654,7 @@ CheckDef (bool result, string name)
CheckDef (DeclSpace.AdditionResult.NameExists, name);
}
-Block declare_local_variables (TypeRef typeref, ArrayList variable_declarators)
+Block declare_local_variables (string type, ArrayList variable_declarators)
{
Block implicit_block;
ArrayList inits = null;
@@ -2644,7 +2680,7 @@ Block declare_local_variables (TypeRef typeref, ArrayList variable_declarators)
implicit_block = new Block (current_block, true);
foreach (VariableDeclaration decl in variable_declarators){
- if (implicit_block.AddVariable (typeref, decl.identifier)){
+ if (implicit_block.AddVariable (type, decl.identifier)){
if (decl.expression_or_array_initializer != null){
if (inits == null)
inits = new ArrayList ();
@@ -2699,26 +2735,22 @@ void note (string s)
// Used to put annotations
}
-TypeRef type (string type_name)
-{
- return type_references.GetTypeRef (current_container, type_name);
-}
-
Tokenizer lexer;
-public CSharpParser(CIR.Tree tree, string name, System.IO.Stream input)
- : base (tree, name, input)
+public CSharpParser(RootContext rc, string name, System.IO.Stream input)
{
current_namespace = new Namespace (null, "");
- this.tree = tree;
+ this.rc = rc;
+ this.tree = rc.Tree;
+ this.name = name;
+ this.input = input;
current_container = tree.Types;
current_container.Namespace = current_namespace;
lexer = new Tokenizer (input, name);
- type_references = tree.TypeRefManager;
}
-public override int parse ()
+public int parse ()
{
StringBuilder value = new StringBuilder ();
diff --git a/mcs/mcs/cs-tokenizer.cs b/mcs/mcs/cs-tokenizer.cs
index 5cb184e93f7..7d309a6e8dd 100755
--- a/mcs/mcs/cs-tokenizer.cs
+++ b/mcs/mcs/cs-tokenizer.cs
@@ -57,19 +57,16 @@
using System;
using System.Text;
-using CSC;
using System.Collections;
using System.IO;
using System.Globalization;
-namespace CSC
+namespace CIR
{
- using CSC;
-
/// <summary>
/// Tokenizer for C# source code.
/// </summary>
-
+
public class Tokenizer : yyParser.yyInput
{
StreamReader reader;
@@ -80,6 +77,9 @@ namespace CSC
public int current_token;
bool handle_get_set = false;
+ //
+ // Returns a verbose representation of the current location
+ //
public string location {
get {
string det;
@@ -250,6 +250,12 @@ namespace CSC
{
return (int) (keywords [name]);
}
+
+ public Location Location {
+ get {
+ return new Location (ref_name, col, ref_line);
+ }
+ }
public Tokenizer (System.IO.Stream input, string fname)
{
@@ -260,12 +266,12 @@ namespace CSC
bool is_identifier_start_character (char c)
{
- return CharacterInfo.IsLetter (c) || c == '_' ;
+ return Char.IsLetter (c) || c == '_' ;
}
bool is_identifier_part_character (char c)
{
- return (CharacterInfo.IsLetter (c) || CharacterInfo.IsDigit (c) || c == '_');
+ return (Char.IsLetter (c) || Char.IsDigit (c) || c == '_');
}
int is_punct (char c, ref bool doread)
@@ -441,7 +447,7 @@ namespace CSC
number.Append ((char) c);
while ((d = peekChar ()) != -1){
- if (CharacterInfo.IsDigit ((char)d)){
+ if (Char.IsDigit ((char)d)){
number.Append ((char) d);
getChar ();
seen_digits = true;
@@ -460,7 +466,7 @@ namespace CSC
while ((d = peekChar ()) != -1){
char e = Char.ToUpper ((char) d);
- if (CharacterInfo.IsDigit (e) ||
+ if (Char.IsDigit (e) ||
(e >= 'A' && e <= 'F')){
number.Append ((char) e);
getChar ();
@@ -547,8 +553,8 @@ namespace CSC
number.Length = 0;
- if (CharacterInfo.IsDigit ((char)c)){
- if (peekChar () == 'x' || peekChar () == 'X'){
+ if (Char.IsDigit ((char)c)){
+ if (c == '0' && peekChar () == 'x' || peekChar () == 'X'){
getChar ();
hex_digits (-1);
val = new System.Int32 ();
@@ -700,7 +706,7 @@ namespace CSC
public int xtoken ()
{
int t;
- bool allow_keyword = false;
+ bool allow_keyword_as_ident = false;
bool doread = false;
int c;
@@ -722,34 +728,24 @@ namespace CSC
}
ids = id.ToString ();
-
- if (!is_keyword (ids)){
- val = id.ToString ();
- return Token.IDENTIFIER;
- }
-
- if (allow_keyword) {
+
+ if (!is_keyword (ids) || allow_keyword_as_ident) {
val = ids;
return Token.IDENTIFIER;
}
- if (ids == "true")
- return Token.TRUE;
- else if (ids == "false")
- return Token.FALSE;
- else if (ids == "null")
- return Token.NULL;
-
+ // true, false and null are in the hash anyway.
return getKeyword (ids);
+
}
if (c == '.'){
- if (CharacterInfo.IsDigit ((char) peekChar ()))
+ if (Char.IsDigit ((char) peekChar ()))
return is_number (c);
return Token.DOT;
}
- if (CharacterInfo.IsDigit ((char) c))
+ if (Char.IsDigit ((char) c))
return is_number (c);
// Handle double-slash comments.
@@ -874,7 +870,7 @@ namespace CSC
}
if (c == '@'){
- allow_keyword = true;
+ allow_keyword_as_ident = true;
continue;
}
@@ -886,4 +882,18 @@ namespace CSC
return Token.EOF;
}
}
+
+ public struct Location {
+ public readonly string Name;
+ public readonly int Col;
+ public readonly int Row;
+
+ public Location (string name, int col, int row)
+ {
+ Name = name;
+ Col = col;
+ Row = row;
+ }
+ }
+
}
diff --git a/mcs/mcs/decl.cs b/mcs/mcs/decl.cs
index 36235f0f8fc..2f09a1ee316 100755
--- a/mcs/mcs/decl.cs
+++ b/mcs/mcs/decl.cs
@@ -12,6 +12,7 @@
using System;
using System.Collections;
+using System.Reflection.Emit;
namespace CIR {
@@ -22,6 +23,12 @@ namespace CIR {
// </summary>
public abstract class DeclSpace {
+ // <summary>
+ // this points to the actual definition that is being
+ // created with System.Reflection.Emit
+ // </summary>
+ TypeBuilder definition;
+
string name, basename;
// <summary>
@@ -122,6 +129,14 @@ namespace CIR {
}
}
- abstract public Type Define (Tree tree);
+ public TypeBuilder TypeBuilder {
+ get {
+ return definition;
+ }
+
+ set {
+ definition = value;
+ }
+ }
}
}
diff --git a/mcs/mcs/driver.cs b/mcs/mcs/driver.cs
index f4b36acfc59..5a9bfc0e72d 100755
--- a/mcs/mcs/driver.cs
+++ b/mcs/mcs/driver.cs
@@ -8,7 +8,7 @@
// (C) 2001 Ximian, Inc (http://www.ximian.com)
//
-namespace CSC
+namespace CIR
{
using System;
using System.Reflection;
@@ -17,10 +17,9 @@ namespace CSC
using System.IO;
using CIR;
using Generator;
- using CSC;
/// <summary>
- /// Summary description for Class1.
+ /// The compiler driver.
/// </summary>
public class Driver
{
@@ -32,14 +31,13 @@ namespace CSC
// Lookup paths
ArrayList link_paths;
- // Our parser context.
- Tree context;
-
+ RootContext context;
+
bool yacc_verbose = false;
int error_count = 0;
- public int parse (Tree context, string input_file)
+ public int parse (string input_file)
{
CSharpParser parser;
System.IO.Stream input;
@@ -67,20 +65,22 @@ namespace CSC
public void Usage ()
{
Console.WriteLine (
- "compiler [-v] [-t tree] [-o output] [-L path] [-r reference] sources.cs\n" +
- "-v Verbose parsing\n"+
- "-o Specifies output file\n" +
- "-L Specifies path for loading assemblies\n" +
- "-r References an assembly\n");
+ "compiler [options] source-files\n\n" +
+ "-v Verbose parsing\n"+
+ "-o Specifies output file\n" +
+ "-L Specifies path for loading assemblies\n" +
+ "--nostdlib Does not load core libraries\n" +
+ "-r References an assembly\n");
}
- public IGenerator lookup_output (string name)
+ public ITreeDump lookup_dumper (string name)
{
if (name == "tree")
return new Generator.TreeDump ();
- if (name == "il")
- return new MSIL.Generator ();
+
+ // if (name == "il")
+ // return new MSIL.Generator ();
return null;
}
@@ -107,23 +107,35 @@ namespace CSC
Assembly a;
foreach (string dir in link_paths){
- string full_path = dir + "\\" + assembly;
+ string full_path = dir + "/" + assembly;
try {
- a = Assembly.Load (full_path);
- } catch (FileNotFoundException) {
+ Console.WriteLine ("Loading: " + assembly);
+ a = Assembly.Load (assembly);
+ } catch (FileNotFoundException f) {
error ("// File not found: " + full_path);
+ error ("Log: " + f.FusionLog);
return 1;
} catch (BadImageFormatException) {
error ("// Bad file format: " + full_path);
return 1;
+ } catch (FileLoadException f){
+ error ("// File Load Exception: " + full_path);
+ error ("Log: " + f.FusionLog);
+ return 1;
+ } catch (ArgumentNullException){
+ error ("// Argument Null exception " + full_path);
+ return 1;
}
- context.AddAssembly (a);
+ context.TypeManager.AddAssembly (a);
}
return 0;
}
-
+
+ // <summary>
+ // Loads all assemblies referenced on the command line
+ // </summary>
public int LoadReferences ()
{
int errors = 0;
@@ -135,22 +147,27 @@ namespace CSC
return errors;
}
-
+ // <summary>
+ // Parses the arguments, and drives the compilation
+ // process.
+ //
+ // TODO: Mostly structured to debug the compiler
+ // now, needs to be turned into a real driver soon.
+ // </summary>
public Driver (string [] args)
{
- Stream output_stream = Console.OpenStandardOutput ();
- IGenerator generator = null;
+ ITreeDump generator = null;
int errors = 0, i;
+ string output_file = null;
- context = new Tree ();
+ context = new RootContext ();
references = new ArrayList ();
link_paths = new ArrayList ();
//
// Setup defaults
//
- references.Add ("mscorlib.dll");
- link_paths.Add ("C://WINNT/Microsoft.Net/Framework/v1.0.2204");
+ link_paths.Add ("file:///C:/WINNT/Microsoft.NET/Framework/v1.0.2914");
for (i = 0; i < args.Length; i++){
string arg = args [i];
@@ -162,7 +179,7 @@ namespace CSC
}
if (arg.StartsWith ("-t")){
- generator = lookup_output (args [++i]);
+ generator = lookup_dumper (args [++i]);
continue;
}
@@ -173,7 +190,7 @@ namespace CSC
if (arg.StartsWith ("-o")){
try {
- output_stream = File.Create (args [++i]);
+ output_file = args [++i];
} catch (Exception){
error ("Could not write to `"+args [i]);
error_count++;
@@ -192,6 +209,10 @@ namespace CSC
continue;
}
+ if (arg == "--nostdlib"){
+ context.StdLib = false;
+ }
+
Usage ();
error_count++;
return;
@@ -203,51 +224,91 @@ namespace CSC
continue;
}
- errors += parse (context, arg);
+ errors += parse (arg);
}
- if (errors > 0)
- error ("// Parsing failed");
- else
- notice ("// Parsing successful");
+
+ //
+ // Load Core Library for default compilation
+ //
+ if (context.StdLib)
+ references.Insert (0, "mscorlib");
+
+ if (errors > 0){
+ error ("Parsing failed");
+ return;
+ } else
+ notice ("Parsing successful");
//
// Load assemblies required
//
errors += LoadReferences ();
- if (errors > 0)
- error ("// Could not load one or more assemblies");
- else
- notice ("// Assemblies loaded");
-
+ if (errors > 0){
+ error ("Could not load one or more assemblies");
+ return;
+ }
- errors += context.BuilderInit ("Module", "Module.exe");
//
- // Name resolution on the tree.
+ // Dumping the parsed tree.
//
- errors += context.Resolve ();
-
- //
- // Code generation from the tree
+ // This code generation interface is only here
+ // for debugging the parser.
//
if (generator != null){
+ if (output_file == null){
+ error ("Error: no output file specified");
+ return;
+ }
+
+ Stream output_stream = File.Create (output_file);
StreamWriter output = new StreamWriter (output_stream);
- errors += generator.GenerateFromTree (context, output);
+ errors += generator.Dump (context.Tree, output);
- if (errors > 0)
- error ("// Compilation failed");
- else
- notice ("// Compilation successful");
+ if (errors > 0){
+ error ("Compilation failed");
+ return;
+ } else
+ notice ("Compilation successful");
output.Flush ();
output.Close ();
- }
+ }
+
error_count = errors;
+
+ //
+ // Quick hack
+ //
+ if (output_file == null)
+ output_file = "a.exe";
+
+ context.CodeGen = new CodeGen (output_file, output_file);
+
+ //
+ // The second pass of the compiler
+ //
+ context.ResolveTree ();
+ context.PopulateTypes ();
+ context.EmitCode ();
+
+ if (context.Report.Errors > 0){
+ error ("Compilation failed");
+ return;
+ }
+
+ context.CloseTypes ();
+
+ context.CodeGen.Save (output_file);
+
+ notice ("Success");
}
}
}
+
+
diff --git a/mcs/mcs/enum.cs b/mcs/mcs/enum.cs
index 3278e6ef5e8..c54c258613c 100755
--- a/mcs/mcs/enum.cs
+++ b/mcs/mcs/enum.cs
@@ -15,7 +15,7 @@ namespace CIR {
public class Enum : DeclSpace {
ArrayList ordered_enums;
- TypeRef typeref;
+ string type;
string name;
int mod_flags;
@@ -26,9 +26,9 @@ namespace CIR {
Modifiers.INTERNAL |
Modifiers.PRIVATE;
- public Enum (TypeRef typeref, int mod_flags, string name) : base (name)
+ public Enum (string type, int mod_flags, string name) : base (name)
{
- this.typeref = typeref;
+ this.type = type;
this.name = name;
this.mod_flags = Modifiers.Check (AllowedModifiers, mod_flags, Modifiers.PUBLIC);
@@ -50,9 +50,9 @@ namespace CIR {
return AdditionResult.Success;
}
- public Type Type {
+ public string Type {
get {
- return typeref.Type;
+ return type;
}
}
@@ -74,10 +74,5 @@ namespace CIR {
return (Expression) defined_names [name];
}
}
-
- public override Type Define (Tree tree)
- {
- return null;
- }
}
}
diff --git a/mcs/mcs/errors.cs b/mcs/mcs/errors.cs
index 8d3377de693..213500bbd96 100755
--- a/mcs/mcs/errors.cs
+++ b/mcs/mcs/errors.cs
@@ -1,7 +1,7 @@
using System.IO;
using System;
-namespace CSC {
+namespace CIR {
public class Error {
public static void report_error (string error)
{
diff --git a/mcs/mcs/expression.cs b/mcs/mcs/expression.cs
index 3f12e7dada5..05f15941b07 100755
--- a/mcs/mcs/expression.cs
+++ b/mcs/mcs/expression.cs
@@ -12,10 +12,10 @@ namespace CIR {
using System;
public abstract class Expression {
- Type type;
+ string type;
bool is_lvalue;
- public Type Type {
+ public string Type {
get {
return type;
}
@@ -48,7 +48,7 @@ namespace CIR {
type = null;
}
- static bool EvaluateType (Expression expr, out Type setType)
+ static bool EvaluateType (Expression expr, out string setType)
{
setType = null;
return true;
@@ -93,7 +93,7 @@ namespace CIR {
}
public class Probe : Expression {
- TypeRef typeref;
+ string type;
Expression expr;
Operator oper;
@@ -101,10 +101,10 @@ namespace CIR {
Is, As
}
- public Probe (Operator oper, Expression expr, TypeRef typeref)
+ public Probe (Operator oper, Expression expr, string type)
{
this.oper = oper;
- this.typeref = typeref;
+ this.type = type;
this.expr = expr;
}
@@ -120,27 +120,27 @@ namespace CIR {
}
}
- public Type ProbeType {
+ public string ProbeType {
get {
- return typeref.Type;
+ return type;
}
}
}
public class Cast : Expression {
- TypeRef typeref;
+ string type;
Expression expr;
- public Cast (TypeRef typeref, Expression expr)
+ public Cast (string type, Expression expr)
{
- this.typeref = typeref;
+ this.type = type;
this.expr = expr;
}
- public Type TargetType {
+ public string TargetType {
get {
- return typeref.Type;
+ return type;
}
}
@@ -357,11 +357,11 @@ namespace CIR {
public class New : Expression {
ArrayList arguments;
- TypeRef requested_ref;
+ string requested_type;
- public New (TypeRef requested_ref, ArrayList arguments)
+ public New (string requested_type, ArrayList arguments)
{
- this.requested_ref = requested_ref;
+ this.requested_type = requested_type;
this.arguments = arguments;
}
@@ -371,9 +371,9 @@ namespace CIR {
}
}
- public Type RequestedType {
+ public string RequestedType {
get {
- return requested_ref.Type;
+ return requested_type;
}
}
}
@@ -382,31 +382,31 @@ namespace CIR {
}
public class TypeOf : Expression {
- TypeRef queried_ref;
+ string queried_type;
- public TypeOf (TypeRef queried_ref)
+ public TypeOf (string queried_type)
{
- this.queried_ref = queried_ref;
+ this.queried_type = queried_type;
}
- public Type QueriedType {
+ public string QueriedType {
get {
- return queried_ref.Type;
+ return queried_type;
}
}
}
public class SizeOf : Expression {
- TypeRef queried_ref;
+ string queried_type;
- public SizeOf (TypeRef queried_ref)
+ public SizeOf (string queried_type)
{
- this.queried_ref = queried_ref;
+ this.queried_type = queried_type;
}
- public Type QueriedType {
+ public string QueriedType {
get {
- return queried_ref.Type;
+ return queried_type;
}
}
}
@@ -435,19 +435,19 @@ namespace CIR {
}
public class BuiltinTypeAccess : Expression {
- TypeRef access_base;
+ string access_base;
string method;
- public BuiltinTypeAccess (TypeRef typeref, string method)
+ public BuiltinTypeAccess (string type, string method)
{
- System.Console.WriteLine ("DUDE! This TypeRef should be fully resolved!");
+ System.Console.WriteLine ("DUDE! This type should be fully resolved!");
this.access_base = access_base;
this.method = method;
}
- public Type AccessBase {
+ public string AccessBase {
get {
- return access_base.Type;
+ return access_base;
}
}
@@ -457,40 +457,6 @@ namespace CIR {
}
}
}
-
- public class MethodGroup : Expression {
- Hashtable signatures;
- string name;
-
- public MethodGroup (string name)
- {
- signatures = new Hashtable ();
- this.name = name;
- }
-
- public bool Add (Method method)
- {
- string sig = method.ArgumentSignature;
-
- if (signatures.Contains (sig))
- return false;
-
- signatures.Add (sig, method);
- return true;
- }
-
- public string Name {
- get {
- return name;
- }
- }
-
- public Hashtable Methods {
- get {
- return signatures;
- }
- }
- }
}
diff --git a/mcs/mcs/gen-il.cs b/mcs/mcs/gen-il.cs
index d365441fb99..2dfeecc974c 100755
--- a/mcs/mcs/gen-il.cs
+++ b/mcs/mcs/gen-il.cs
@@ -14,7 +14,7 @@ using CIR;
namespace MSIL {
- public class Generator : CIR.IGenerator {
+ public class Generator : CIR.ITreeDump {
StreamWriter o;
int indent = 0;
diff --git a/mcs/mcs/gen-treedump.cs b/mcs/mcs/gen-treedump.cs
index b7a6bf1fc6c..5f0a38f290c 100755
--- a/mcs/mcs/gen-treedump.cs
+++ b/mcs/mcs/gen-treedump.cs
@@ -18,7 +18,7 @@ using CIR;
namespace Generator {
- public class TreeDump : CIR.IGenerator {
+ public class TreeDump : CIR.ITreeDump {
StreamWriter o;
int indent;
bool indented;
@@ -55,11 +55,6 @@ namespace Generator {
output (s);
}
- string GetType (Type type)
- {
- return type.Name;
- }
-
string GetParameter (Parameter par)
{
Parameter.Modifier f = par.ModFlags;
@@ -75,7 +70,7 @@ namespace Generator {
case Parameter.Modifier.NONE:
mod = ""; break;
}
- return mod + GetType (par.Type) + " " + par.Name;
+ return mod + par.Type + " " + par.Name;
}
string GetUnary (Unary u, int paren_level)
@@ -243,7 +238,7 @@ namespace Generator {
string GetCast (Cast c)
{
- return "(" + c.TargetType.Name + ") (" + GetExpression (c.Expr, 0) + ")";
+ return "(" + c.TargetType + ") (" + GetExpression (c.Expr, 0) + ")";
}
string GetConditional (Conditional c)
@@ -291,17 +286,17 @@ namespace Generator {
string GetNew (New n)
{
- return "new " + n.RequestedType.Name + GetArguments (n.Arguments);
+ return "new " + n.RequestedType + GetArguments (n.Arguments);
}
string GetTypeOf (TypeOf t)
{
- return "typeof (" + t.QueriedType.Name + ")";
+ return "typeof (" + t.QueriedType + ")";
}
string GetSizeOf (SizeOf t)
{
- return "sizeof (" + t.QueriedType.Name + ")";
+ return "sizeof (" + t.QueriedType + ")";
}
string GetMemberAccess (MemberAccess m)
@@ -332,7 +327,7 @@ namespace Generator {
else
s += "UNHANDLED";
- s += GetType (p.ProbeType);
+ s += p.ProbeType;
return s;
}
@@ -397,15 +392,15 @@ namespace Generator {
void GenerateParameters (Parameters pars)
{
- ParameterCollection pfixed;
+ Parameter [] pfixed;
Parameter parray;
pfixed = pars.FixedParameters;
if (pfixed != null){
- for (int i = 0; i < pfixed.Count; i++){
- output (GetParameter ((Parameter) pfixed [i]));
- if (i+1 != pfixed.Count)
+ for (int i = 0; i < pfixed.Length; i++){
+ output (GetParameter (pfixed [i]));
+ if (i+1 != pfixed.Length)
output (", ");
}
}
@@ -532,7 +527,7 @@ namespace Generator {
output ("catch ");
if (c.Type != null){
- output ("(" + GetType (c.Type) +
+ output ("(" + c.Type +
(c.Name != null ? " " + c.Name : "") + ")");
}
GenerateBlock (c.Block, false, false);
@@ -636,10 +631,12 @@ namespace Generator {
if (b.Variables != null){
foreach (DictionaryEntry entry in b.Variables){
+ VariableInfo vi = (VariableInfo) entry.Value;
+
space ();
output_newline (
- (((CIR.TypeRef)entry.Value).Type).Name + " " +
- (string)entry.Key + ";");
+ vi.Type + " " +
+ (string) entry.Key + ";");
}
newline ();
}
@@ -659,7 +656,7 @@ namespace Generator {
void GenerateMethod (Method m)
{
ioutput (GetModifiers (m.ModFlags) +
- GetType (m.ReturnType) + " " +
+ m.ReturnType + " " +
m.Name + " (");
GenerateParameters (m.Parameters);
output_newline (")");
@@ -669,20 +666,11 @@ namespace Generator {
newline ();
}
- void GenerateMethodGroup (MethodGroup mg)
- {
- foreach (DictionaryEntry de in mg.Methods){
- Method m = (Method) de.Value;
-
- GenerateMethod (m);
- }
- }
-
void GenerateInterfaceMethod (InterfaceMethod imethod)
{
space ();
output (imethod.IsNew ? "new " : "");
- output (GetType (imethod.ReturnType) + " " + imethod.Name + " (");
+ output (imethod.ReturnType + " " + imethod.Name + " (");
GenerateParameters (imethod.Parameters);
output (");");
newline ();
@@ -692,7 +680,7 @@ namespace Generator {
{
space ();
output (iprop.IsNew ? "new " : "");
- output (GetType (iprop.Type) + " " + iprop.Name + " { ");
+ output (iprop.Type + " " + iprop.Name + " { ");
if (iprop.HasGet) output ("get; ");
if (iprop.HasSet) output ("set; ");
output ("}");
@@ -703,7 +691,7 @@ namespace Generator {
{
space ();
output ((ievent.IsNew ? "new " : "") + "event ");
- output (GetType (ievent.Type) + " " + ievent.Name + ";");
+ output (ievent.Type + " " + ievent.Name + ";");
newline ();
}
@@ -711,7 +699,7 @@ namespace Generator {
{
space ();
output (iindexer.IsNew ? "new " : "");
- output (GetType (iindexer.Type) + " this [");
+ output (iindexer.Type + " this [");
output (iindexer.Parameters + "] {");
if (iindexer.HasGet) output ("get; ");
if (iindexer.HasSet) output ("set; ");
@@ -768,7 +756,7 @@ namespace Generator {
{
space ();
output (GetModifiers (f.ModFlags) +
- GetType (f.Type) + " " + f.Name);
+ f.Type + " " + f.Name);
if (f.Initializer != null){
if (f.Initializer is Expression)
output (" = " + GetExpression ((Expression) f.Initializer, 0));
@@ -803,7 +791,7 @@ namespace Generator {
void GenerateProperty (Property prop)
{
space ();
- output (GetModifiers (prop.ModFlags) + GetType (prop.Type) +
+ output (GetModifiers (prop.ModFlags) + prop.Type +
" " + prop.Name + " {");
newline ();
indent++;
@@ -852,12 +840,10 @@ namespace Generator {
void GenerateTypeContainerData (TypeContainer tc)
{
if (tc.Constants != null){
- foreach (DictionaryEntry cde in tc.Constants){
- Constant c = tc.GetConstant ((string) cde.Key);
-
+ foreach (Constant c in tc.Constants){
space ();
- output ("const " + c.ConstantType.Name + " " + c.name + " = " +
+ output ("const " + c.ConstantType + " " + c.Name + " = " +
GetExpression (c.Expr, 0) + ";");
newline ();
}
@@ -865,47 +851,34 @@ namespace Generator {
}
if (tc.Enums != null){
- foreach (DictionaryEntry ede in tc.Enums){
- CIR.Enum e = (CIR.Enum) ede.Value;
-
+ foreach (CIR.Enum e in tc.Enums)
GenerateEnum (e);
- }
}
if (tc.Fields != null){
- foreach (DictionaryEntry de in tc.Fields){
- Field f = (Field) de.Value;
-
+ foreach (Field f in tc.Fields)
GenerateField (f);
- }
newline ();
}
if (tc.Constructors != null){
- foreach (DictionaryEntry de in tc.Constructors){
- Constructor c = (Constructor) de.Value;
-
+ foreach (Constructor c in tc.Constructors)
GenerateConstructor (c);
- }
+
newline ();
}
if (tc.Properties != null){
- foreach (DictionaryEntry de in tc.Properties){
- Property prop = (Property) de.Value;
-
+ foreach (Property prop in tc.Properties)
GenerateProperty (prop);
- }
}
GenerateFromTypes (tc);
- if (tc.MethodGroups != null){
- foreach (DictionaryEntry de in tc.MethodGroups){
- MethodGroup mg = (MethodGroup) de.Value;
-
- GenerateMethodGroup (mg);
+ if (tc.Methods != null){
+ foreach (Method m in tc.Methods){
+ GenerateMethod (m);
}
}
}
@@ -994,7 +967,7 @@ namespace Generator {
}
}
- public int GenerateFromTree (Tree tree, StreamWriter output)
+ public int Dump (Tree tree, StreamWriter output)
{
this.o = output;
diff --git a/mcs/mcs/interface.cs b/mcs/mcs/interface.cs
index 968fbfb11eb..8d955044294 100755
--- a/mcs/mcs/interface.cs
+++ b/mcs/mcs/interface.cs
@@ -17,15 +17,31 @@ using System.Reflection.Emit;
namespace CIR {
public class Interface : DeclSpace {
+ const MethodAttributes interface_method_attributes =
+ MethodAttributes.Public |
+ MethodAttributes.Abstract |
+ MethodAttributes.HideBySig |
+ MethodAttributes.NewSlot |
+ MethodAttributes.Virtual;
+
+ const MethodAttributes property_attributes =
+ MethodAttributes.Public |
+ MethodAttributes.Abstract |
+ MethodAttributes.HideBySig |
+ MethodAttributes.NewSlot |
+ MethodAttributes.SpecialName |
+ MethodAttributes.Virtual;
+
ArrayList bases;
int mod_flags;
- ArrayList defined_method_list;
- ArrayList defined_indexer_list;
-
- Hashtable defined_events;
- Hashtable defined_properties;
+ ArrayList defined_method;
+ ArrayList defined_indexer;
+ ArrayList defined_events;
+ ArrayList defined_properties;
+ TypeContainer parent;
+
// These will happen after the semantic analysis
// Hashtable defined_indexers;
@@ -43,12 +59,8 @@ namespace CIR {
public Interface (TypeContainer parent, string name, int mod) : base (name)
{
- defined_events = new Hashtable ();
- defined_method_list = new ArrayList ();
- defined_indexer_list = new ArrayList ();
- defined_properties = new Hashtable ();
-
this.mod_flags = Modifiers.Check (AllowedModifiers, mod, Modifiers.PUBLIC);
+ this.parent = parent;
}
public AdditionResult AddMethod (InterfaceMethod imethod)
@@ -61,7 +73,10 @@ namespace CIR {
return AdditionResult.NameExists;
}
- defined_method_list.Add (imethod);
+ if (defined_method == null)
+ defined_method = new ArrayList ();
+
+ defined_method.Add (imethod);
if (value == null)
DefineName (name, imethod);
@@ -78,7 +93,10 @@ namespace CIR {
DefineName (name, iprop);
- defined_properties.Add (name, iprop);
+ if (defined_properties == null)
+ defined_properties = new ArrayList ();
+
+ defined_properties.Add (iprop);
return AdditionResult.Success;
}
@@ -92,37 +110,43 @@ namespace CIR {
DefineName (name, ievent);
- defined_events.Add (name, ievent);
+ if (defined_events == null)
+ defined_events = new ArrayList ();
+
+ defined_events.Add (ievent);
return AdditionResult.Success;
}
public bool AddIndexer (InterfaceIndexer iindexer)
{
- defined_indexer_list.Add (iindexer);
+ if (defined_indexer == null)
+ defined_indexer = new ArrayList ();
+
+ defined_indexer.Add (iindexer);
return true;
}
- public Hashtable InterfaceMethods {
+ public ArrayList InterfaceMethods {
get {
- return null; // defined_methods;
+ return defined_method;
}
}
- public Hashtable InterfaceProperties {
+ public ArrayList InterfaceProperties {
get {
return defined_properties;
}
}
- public Hashtable InterfaceEvents {
+ public ArrayList InterfaceEvents {
get {
return defined_events;
}
}
- public Hashtable InterfaceIndexers {
+ public ArrayList InterfaceIndexers {
get {
- return null; // defined_indexers;
+ return defined_indexer;
}
}
@@ -142,190 +166,306 @@ namespace CIR {
}
}
- Type def;
- bool in_transit = false;
- public override Type Define (Tree tree)
+ void Error111 (InterfaceMethod im)
{
- if (in_transit){
- CSC.CSharpParser.error (529, "There is a cycle in interface " + Name);
- return null;
- }
- in_transit = true;
-
- ModuleBuilder mb = tree.ModuleBuilder;
+ parent.RootContext.Report.Error (
+ 111,
+ "Interface `" + Name + "' already contains a definition with the " +
+ "same return value and paramenter types for method `" + im.Name + "'");
+ }
- if (bases != null){
- // FIXME: Go over each one of the TypeRefs
- // in Bases and resolve.
- Console.WriteLine ("Base interfaces not yet supported");
- return null;
+ //
+ // Populates the methods in the interface
+ //
+ void PopulateMethod (InterfaceMethod im)
+ {
+ Type return_type = parent.LookupType (im.ReturnType, true);
+ Type [] arg_types = im.ParameterTypes (parent);
+ MethodBuilder mb;
+ Parameter [] p;
+ int i;
+
+ //
+ // Create the method
+ //
+ mb = TypeBuilder.DefineMethod (
+ im.Name, interface_method_attributes,
+ return_type, arg_types);
+
+ //
+ // Define each type attribute (in/out/ref) and
+ // the argument names.
+ //
+ p = im.Parameters.FixedParameters;
+ if (p != null){
+ for (i = 0; i < p.Length; i++)
+ mb.DefineParameter (i + 1, p [i].Attributes, p [i].Name);
+
+ if (i != arg_types.Length)
+ Console.WriteLine ("Implement the type definition for params");
}
+ }
- TypeAttributes attr = TypeAttributes.Interface;
+ //
+ // Populates the properties in the interface
+ //
+ void PopulateProperty (InterfaceProperty ip)
+ {
+ PropertyBuilder pb;
+ MethodBuilder mb;
+ Type prop_type = parent.LookupType (ip.Type, true);
+ Type [] setter_args = new Type [1];
+
+ setter_args [0] = prop_type;
+
+ //
+ // FIXME: properties are missing the following
+ // flags: hidebysig newslot specialname
+ //
+ pb = TypeBuilder.DefineProperty (
+ ip.Name, PropertyAttributes.None,
+ prop_type, null);
+
+ if (ip.HasGet){
+ mb = TypeBuilder.DefineMethod (
+ "get_" + ip.Name, property_attributes ,
+ prop_type, null);
+
+ pb.SetGetMethod (mb);
+ }
- attr |= Modifiers.TypeAttr (mod_flags);
-
- def = mb.DefineType (Name, attr);
+ if (ip.HasSet){
+ setter_args [0] = prop_type;
- in_transit = false;
+ mb = TypeBuilder.DefineMethod (
+ "set_" + ip.Name, property_attributes,
+ null, setter_args);
- return def;
+ mb.DefineParameter (1, ParameterAttributes.None, "value");
+ pb.SetSetMethod (mb);
+ }
}
- }
-
- public class InterfaceMemberBase {
- string name;
- public InterfaceMemberBase (string name)
+ //
+ // Populates the events in the interface
+ //
+ void PopulateEvent (InterfaceEvent ie)
{
- this.name = name;
+ //
+ // FIXME: We need to do this after delegates have been
+ // declared or we declare them recursively.
+ //
}
-
- public string Name {
- get {
- return name;
- }
- }
- }
-
- public class InterfaceProperty : InterfaceMemberBase {
- bool has_get, has_set, is_new;
- TypeRef typeref;
-
- public InterfaceProperty (TypeRef typeref, string name,
- bool is_new, bool has_get, bool has_set)
- : base (name)
+
+ //
+ // Populates the indexers in the interface
+ //
+ void PopulateIndexer (InterfaceIndexer ii)
{
- this.typeref = typeref;
- this.is_new = is_new;
- this.has_get = has_get;
- this.has_set = has_set;
- }
+ PropertyBuilder pb;
+ Type prop_type = parent.LookupType (ii.Type, true);
+ Type [] arg_types = ii.ParameterTypes (parent);
+ Type [] value_arg_types;
+
+ //
+ // Sets up the extra invisible `value' argument for setters.
+ //
+ if (arg_types != null){
+ int count = arg_types.Length;
+ value_arg_types = new Type [count + 1];
+
+ arg_types.CopyTo (value_arg_types, 0);
+ value_arg_types [count] = prop_type;
+ } else {
+ value_arg_types = new Type [1];
+
+ value_arg_types [1] = prop_type;
+ }
- public bool HasGet {
- get {
- return has_get;
+ pb = TypeBuilder.DefineProperty (
+ "Item", PropertyAttributes.None,
+ prop_type, arg_types);
+
+ if (ii.HasGet){
+ MethodBuilder get_item;
+ Parameter [] p = ii.Parameters.FixedParameters;
+
+ get_item = TypeBuilder.DefineMethod (
+ "get_Item", property_attributes, prop_type, arg_types);
+ pb.SetGetMethod (get_item);
+
+ if (p != null){
+ for (int i = 0; i < p.Length; i++)
+ get_item.DefineParameter (
+ i + 1,
+ p [i].Attributes, p [i].Name);
+ }
}
- }
- public bool HasSet {
- get {
- return has_set;
+ if (ii.HasSet){
+ Parameter [] p = ii.Parameters.FixedParameters;
+ MethodBuilder set_item;
+ int i = 0;
+
+ set_item = TypeBuilder.DefineMethod (
+ "set_Item", property_attributes, null, value_arg_types);
+ pb.SetSetMethod (set_item);
+
+ if (p != null){
+ for (; i < p.Length; i++)
+ set_item.DefineParameter (
+ i + 1,
+ p [i].Attributes, p [i].Name);
+ }
+ set_item.DefineParameter (i + 1, ParameterAttributes.None, "value");
}
}
- public bool IsNew {
- get {
- return is_new;
+ // <summary>
+ // Performs the semantic analysis for all the interface members
+ // that were declared
+ // </summary>
+ bool SemanticAnalysis ()
+ {
+ Hashtable methods = new Hashtable ();
+
+
+ if (defined_method != null){
+ foreach (InterfaceMethod im in defined_method){
+ string sig = im.GetSignature (parent);
+
+ //
+ // If there was an undefined Type on the signatures
+ //
+ if (sig == null)
+ continue;
+
+ if (methods [sig] != null){
+ Error111 (im);
+ return false;
+ }
+ }
}
+
+ //
+ // FIXME: Here I should check i
+ //
+ return true;
}
- public Type Type {
- get {
- return typeref.Type;
+ // <summary>
+ // Performs semantic analysis, and then generates the IL interfaces
+ // </summary>
+ public void Populate ()
+ {
+ if (!SemanticAnalysis ())
+ return;
+
+ if (defined_method != null){
+ foreach (InterfaceMethod im in defined_method)
+ PopulateMethod (im);
}
+
+ if (defined_properties != null){
+ foreach (InterfaceProperty ip in defined_properties)
+ PopulateProperty (ip);
+ }
+
+ if (defined_events != null)
+ foreach (InterfaceEvent ie in defined_events)
+ PopulateEvent (ie);
+
+ if (defined_indexer != null)
+ foreach (InterfaceIndexer ii in defined_indexer)
+ PopulateIndexer (ii);
}
}
- public class InterfaceEvent : InterfaceMemberBase {
- TypeRef typeref;
- bool is_new;
+ public class InterfaceMemberBase {
+ public readonly string Name;
+ public readonly bool IsNew;
- public InterfaceEvent (TypeRef typeref, string name, bool is_new)
- : base (name)
+ public InterfaceMemberBase (string name, bool is_new)
{
- this.typeref = typeref;
- this.is_new = is_new;
+ Name = name;
+ IsNew = is_new;
}
-
- public Type Type {
- get {
- return typeref.Type;
- }
+ }
+
+ public class InterfaceProperty : InterfaceMemberBase {
+ public readonly bool HasSet;
+ public readonly bool HasGet;
+ public readonly string Type;
+ public readonly string type;
+
+ public InterfaceProperty (string type, string name,
+ bool is_new, bool has_get, bool has_set)
+ : base (name, is_new)
+ {
+ Type = type;
+ HasGet = has_get;
+ HasSet = has_set;
}
+ }
- public bool IsNew {
- get {
- return is_new;
- }
+ public class InterfaceEvent : InterfaceMemberBase {
+ public readonly string Type;
+
+ public InterfaceEvent (string type, string name, bool is_new)
+ : base (name, is_new)
+ {
+ Type = type;
}
}
public class InterfaceMethod : InterfaceMemberBase {
- TypeRef return_type;
- bool is_new;
- Parameters args;
+ public readonly string ReturnType;
+ public readonly Parameters Parameters;
- public InterfaceMethod (TypeRef return_type, string name, bool is_new, Parameters args)
- : base (name)
+ public InterfaceMethod (string return_type, string name, bool is_new, Parameters args)
+ : base (name, is_new)
{
- this.return_type = return_type;
- this.is_new = is_new;
- this.args = args;
+ this.ReturnType = return_type;
+ this.Parameters = args;
}
- public Type ReturnType {
- get {
- return return_type.Type;
- }
- }
+ // <summary>
+ // Returns the signature for this interface method
+ // </summary>
+ public string GetSignature (TypeContainer tc)
+ {
+ Type ret = tc.LookupType (ReturnType, false);
+ string args = Parameters.GetSignature (tc);
- public bool IsNew {
- get {
- return is_new;
- }
+ if ((ret == null) || (args == null))
+ return null;
+
+ return (IsNew ? "new-" : "") + ret.FullName + "(" + args + ")";
}
- public Parameters Parameters {
- get {
- return args;
- }
+ public Type [] ParameterTypes (TypeContainer tc)
+ {
+ return Parameters.GetParameterInfo (tc);
}
}
public class InterfaceIndexer : InterfaceMemberBase {
- bool do_get, do_set, is_new;
- Parameters args;
- TypeRef typeref;
+ public readonly bool HasGet, HasSet;
+ public readonly Parameters Parameters;
+ public readonly string Type;
- public InterfaceIndexer (TypeRef typeref, Parameters args, bool do_get, bool do_set, bool is_new)
- : base ("")
+ public InterfaceIndexer (string type, Parameters args, bool do_get, bool do_set, bool is_new)
+ : base ("", is_new)
{
- this.typeref = typeref;
- this.args = args;
- this.do_get = do_get;
- this.do_set = do_set;
- this.is_new = is_new;
- }
-
- public Type Type {
- get {
- return typeref.Type;
- }
- }
-
- public Parameters Parameters {
- get {
- return args;
- }
+ Type = type;
+ Parameters = args;
+ HasGet = do_get;
+ HasSet = do_set;
}
- public bool HasGet {
- get {
- return do_get;
- }
- }
-
- public bool HasSet {
- get {
- return do_set;
- }
- }
-
- public bool IsNew {
- get {
- return is_new;
- }
+ public Type [] ParameterTypes (TypeContainer tc)
+ {
+ return Parameters.GetParameterInfo (tc);
}
}
}
diff --git a/mcs/mcs/makefile b/mcs/mcs/makefile
index 56a8664f1e0..0694b75a3fb 100755
--- a/mcs/mcs/makefile
+++ b/mcs/mcs/makefile
@@ -1,60 +1,57 @@
+ROOT=//$(subst \,/,$(subst :\,/,$(SYSTEMROOT)))
+CSC=$(ROOT)/microsoft.net/framework/v1.0.2914/csc.exe
+CSCFLAGS=/nologo /debug+ /debug:full
+
VERSION=0.13
-COMMON_SOURCES = cs-parser.cs cs-tokenizer.cs parser.cs errors.cs tree.cs
+COMMON_SOURCES = cs-parser.cs cs-tokenizer.cs tree.cs
COMPILER_SOURCES = \
assign.cs \
driver.cs $(COMMON_SOURCES) \
class.cs \
+ codegen.cs \
constant.cs \
decl.cs \
enum.cs \
expression.cs \
- generator.cs \
- gen-il.cs \
gen-treedump.cs \
interface.cs \
literal.cs \
modifiers.cs \
namespace.cs \
parameter.cs \
- parameterCollection.cs \
+ report.cs \
+ rootcontext.cs \
statement.cs \
statementCollection.cs \
- type.cs
+ typemanager.cs
TEST_TOKENIZER_SOURCES = test-token.cs $(COMMON_SOURCES)
-all:
- -rm compiler.exe
- csc /target:exe /r:System.dll /debug+ /debug:full /out:compiler.exe $(COMPILER_SOURCES)
+all: cs-parser.cs
+ $(CSC) $(CSCFLAGS) /target:exe /r:System.dll /out:compiler.exe $(COMPILER_SOURCES)
+
+windows: all
+
+unix: all
opt:
- -rm compiler.exe
- csc /optimize+ /target:exe /r:System.dll /debug+ /debug:full /out:compiler.exe $(COMPILER_SOURCES)
+ $(CSC) /optimize+ /target:exe /r:System.dll /out:compiler.exe $(COMPILER_SOURCES)
old: test-tokenizer.exe
test-tokenizer.exe: $(TEST_TOKENIZER_SOURCES)
- csc /target:exe /out:test-tokenizer.exe $(TEST_TOKENIZER_SOURCES)
+ $(CSC) /target:exe /out:test-tokenizer.exe $(TEST_TOKENIZER_SOURCES)
bison:
perl -pe 's/\015//' < cs-parser.jay > x.y
bison --debug --verbose x.y
-parser:
- jay -tv cs-parser.jay > cs-parser.cs
-
-parsernoline:
- jay -tv cs-parser.jay | grep -v '^#line' > cs-parser.cs
+cs-parser.cs: cs-parser.jay
+ ../jay/jay -ctv < ../jay/skeleton.cs cs-parser.jay > cs-parser.cs
-syncunix:
- rsync -v -a /quack/Barra ~/Barra
-
-syncquack:
- rsync -v -a ~/Barra /quack/Barra
-
-syncnt:
- rsync -v -a ~/Barra /quack/nt
+pn:
+ ../jay/jay -ctv < ../jay/skeleton.cs cs-parser.jay | grep -v '#line' > cs-parser.cs
statementCollection.cs: X-Collection.cs
sed -e "s/@CONTAINEE@/Statement/g" -e "s/@arrayname@/statements/g" < X-Collection.cs > statementCollection.cs
@@ -81,3 +78,6 @@ try:
for i in $(COMPILER_SOURCES); do \
./compiler -t tree $$i > try-dir/$$i; \
done
+
+clean:
+ rm -f compiler.exe cs-parser.cs y.output compiler.pdb *~ .*~
diff --git a/mcs/mcs/modifiers.cs b/mcs/mcs/modifiers.cs
index e05159285e0..0886456ac2e 100755
--- a/mcs/mcs/modifiers.cs
+++ b/mcs/mcs/modifiers.cs
@@ -73,6 +73,42 @@ namespace CIR {
return t;
}
+
+ public static FieldAttributes FieldAttr (int mod_flags)
+ {
+ FieldAttributes fa = 0;
+
+ if ((mod_flags & Modifiers.PUBLIC) != 0)
+ fa |= FieldAttributes.Public;
+ if ((mod_flags & Modifiers.PRIVATE) != 0)
+ fa |= FieldAttributes.Private;
+ if ((mod_flags & Modifiers.STATIC) != 0)
+ fa |= FieldAttributes.Static;
+ if ((mod_flags & Modifiers.READONLY) != 0)
+ fa |= FieldAttributes.InitOnly;
+
+ return fa;
+ }
+
+ public static MethodAttributes MethodAttr (int mod_flags)
+ {
+ MethodAttributes ma = 0;
+
+ if ((mod_flags & Modifiers.PUBLIC) != 0)
+ ma |= MethodAttributes.Public;
+ if ((mod_flags & Modifiers.PRIVATE) != 0)
+ ma |= MethodAttributes.Private;
+ if ((mod_flags & Modifiers.STATIC) != 0)
+ ma |= MethodAttributes.Static;
+ if ((mod_flags & Modifiers.ABSTRACT) != 0)
+ ma |= MethodAttributes.Abstract;
+ if ((mod_flags & Modifiers.SEALED) != 0)
+ ma |= MethodAttributes.Final;
+ if ((mod_flags & Modifiers.VIRTUAL) != 0)
+ ma |= MethodAttributes.Virtual;
+
+ return ma;
+ }
// <summary>
// Checks the object @mod modifiers to be in @allowed.
@@ -107,7 +143,7 @@ namespace CIR {
a = ((a & 2) >> 1) + (a & 5);
a = ((a & 4) >> 2) + (a & 3);
if (a > 1)
- CSC.CSharpParser.error (107, "More than one protecion modifier specified");
+ CSharpParser.error (107, "More than one protecion modifier specified");
return mod;
}
@@ -116,7 +152,7 @@ namespace CIR {
if ((i & invalid_flags) == 0)
continue;
- CSC.CSharpParser.error (106, "the modifier `" + Name (i) + "' is not valid for this item");
+ CSharpParser.error (106, "the modifier `" + Name (i) + "' is not valid for this item");
}
return allowed & mod;
diff --git a/mcs/mcs/namespace.cs b/mcs/mcs/namespace.cs
index 17a98230791..9dbfaffbdda 100755
--- a/mcs/mcs/namespace.cs
+++ b/mcs/mcs/namespace.cs
@@ -1,8 +1,7 @@
using System;
using System.Collections;
-using CIR;
-namespace CSC {
+namespace CIR {
// <summary>
// Keeps track of the namespaces defined in the C# code.
@@ -10,7 +9,7 @@ namespace CSC {
public class Namespace {
Namespace parent;
string name;
- Hashtable using_clauses;
+ ArrayList using_clauses;
bool decl_found = false;
// <summary>
@@ -29,10 +28,12 @@ namespace CSC {
// </summary>
public string Name {
get {
- if (parent != null)
+ string pname = parent != null ? parent.Name : "";
+
+ if (pname == "")
+ return name;
+ else
return parent.Name + "." + name;
-
- return name;
}
}
@@ -67,12 +68,12 @@ namespace CSC {
}
if (using_clauses == null)
- using_clauses = new Hashtable ();
+ using_clauses = new ArrayList ();
- using_clauses.Add (ns, null);
+ using_clauses.Add (ns);
}
- public Hashtable UsingTable {
+ public ArrayList UsingTable {
get {
return using_clauses;
}
diff --git a/mcs/mcs/parameter.cs b/mcs/mcs/parameter.cs
index 63f6854fb29..8e3d1811825 100755
--- a/mcs/mcs/parameter.cs
+++ b/mcs/mcs/parameter.cs
@@ -8,19 +8,14 @@
// (C) 2001 Ximian, Inc (http://www.ximian.com)
//
//
-// FIXME: We should deprecate ParameterCollection as it is mostly slow
-// to access (it uses an arraylist instead of a hashtable) and exposes
-// no method to quickly locate parameters by name.
-//
-// Look at the implementation for GetParameterByName for an example.
//
namespace CIR {
using System;
-
- public class Parameter {
+ using System.Reflection;
+ public class Parameter {
public enum Modifier {
NONE,
REF,
@@ -28,20 +23,37 @@ namespace CIR {
PARAMS,
}
- TypeRef typeref;
- string name;
- Modifier mod;
+ public readonly string Type;
+ public readonly string Name;
+ public readonly Modifier ModFlags;
- public Parameter (TypeRef typeref, string name, Modifier mod)
+ public Parameter (string type, string name, Modifier mod)
{
- this.name = name;
- this.mod = mod;
- this.typeref = typeref;
+ Name = name;
+ ModFlags = mod;
+ Type = type = type;
}
+ public ParameterAttributes Attributes {
+ get {
+ switch (ModFlags){
+ case Modifier.NONE:
+ return ParameterAttributes.None;
+ case Modifier.REF:
+ return ParameterAttributes.Retval;
+ case Modifier.OUT:
+ return ParameterAttributes.Out | ParameterAttributes.Retval;
+ case Modifier.PARAMS:
+ return 0;
+ }
+
+ return ParameterAttributes.None;
+ }
+ }
+
string ModSignature ()
{
- switch (mod){
+ switch (ModFlags){
case Modifier.NONE:
return "";
case Modifier.REF:
@@ -54,92 +66,116 @@ namespace CIR {
// This should not happen.
return (string) null;
}
-
- public string Signature {
- get {
- return ModSignature (); // TYPEFIX: + Type.GetTypeEncoding (typeref.Type);
- }
- }
-
- public Type Type {
- get {
- return typeref.Type;
- }
- }
- public string Name {
- get {
- return name;
- }
- }
+ // <summary>
+ // Returns the signature for this parameter evaluating it on the
+ // @tc context
+ // </summary>
+ public string GetSignature (TypeContainer tc)
+ {
+ Type t = tc.LookupType (Type, false);
- public Modifier ModFlags {
- get {
- return mod;
- }
+ if (t == null)
+ return "";
+
+ return ModSignature () + t.FullName;
}
}
public class Parameters {
- ParameterCollection fixed_parameters;
- Parameter array_parameter;
+ public readonly Parameter [] FixedParameters;
+ public readonly Parameter ArrayParameter;
string signature;
- public Parameters (ParameterCollection fixed_parameters, Parameter array_parameter)
+ public Parameters (Parameter [] fixed_parameters, Parameter array_parameter)
{
- this.fixed_parameters = fixed_parameters;
- this.array_parameter = array_parameter;
+ FixedParameters = fixed_parameters;
+ ArrayParameter = array_parameter;
}
- void compute_signature ()
+ public void ComputeSignature (TypeContainer tc)
{
signature = "";
-
- if (fixed_parameters != null){
- for (int i = 0; i < fixed_parameters.Count; i++){
- Parameter par = (Parameter) fixed_parameters [i];
+ if (FixedParameters != null){
+ for (int i = 0; i < FixedParameters.Length; i++){
+ Parameter par = FixedParameters [i];
- signature += par.Signature;
+ signature += par.GetSignature (tc);
}
}
-
//
- // Note: as per the spec, the `params' arguments (array_parameter)
+ // Note: as per the spec, the `params' arguments (ArrayParameter)
// are not used in the signature computation for a method
//
}
-
- public ParameterCollection FixedParameters {
- get {
- return fixed_parameters;
- }
- }
- public Parameter ArrayParameter {
- get {
- return array_parameter;
- }
- }
-
- // Removed for now, as we can not compute this at
- // boot strap.
- public string Signature {
- get {
- return signature;
- }
+ // <summary>
+ // Returns the signature of the Parameters evaluated in
+ // the @tc environment
+ // </summary>
+ public string GetSignature (TypeContainer tc)
+ {
+ if (signature == null)
+ ComputeSignature (tc);
+
+ return signature;
}
-
+
+ // <summary>
+ // Returns the paramenter information based on the name
+ // </summary>
public Parameter GetParameterByName (string name)
{
- if (fixed_parameters == null)
+ if (FixedParameters == null)
return null;
- foreach (Parameter par in fixed_parameters)
+ foreach (Parameter par in FixedParameters)
if (par.Name == name)
return par;
+
return null;
}
+
+ // <summary>
+ // Returns the argument types as an array
+ // </summary>
+ public Type [] GetParameterInfo (TypeContainer tc)
+ {
+ if (FixedParameters == null)
+ return null;
+
+ Type [] types;
+ int extra = (ArrayParameter != null) ? 1 : 0;
+ int i = 0;
+ int pc = FixedParameters.Length + extra;
+
+ types = new Type [pc];
+
+ foreach (Parameter p in FixedParameters){
+ Type t = tc.LookupType (p.Type, false);
+
+ if ((p.ModFlags & (Parameter.Modifier.REF | Parameter.Modifier.OUT)) != 0){
+ t = Type.GetType (t.FullName + "&");
+ }
+ types [i] = t;
+ i++;
+ }
+
+ if (extra > 0)
+ types [i] = Type.GetType ("System.Object");
+
+ return types;
+ }
+
+ public CallingConventions GetCallingConvention ()
+ {
+ if (ArrayParameter != null)
+ return CallingConventions.VarArgs;
+ else
+ return CallingConventions.Standard;
+ }
}
}
+
diff --git a/mcs/mcs/parameterCollection.cs b/mcs/mcs/parameterCollection.cs
index 77d895c3b4b..86a7c0ce1ae 100755
--- a/mcs/mcs/parameterCollection.cs
+++ b/mcs/mcs/parameterCollection.cs
@@ -156,5 +156,11 @@ namespace CIR {
return parameters.IsSynchronized;
}
}
+
+ public bool IsFixedSize {
+ get {
+ return false;
+ }
+ }
}
}
diff --git a/mcs/mcs/parser.cs b/mcs/mcs/parser.cs
index 08cca9bb487..7c12cf96c7b 100755
--- a/mcs/mcs/parser.cs
+++ b/mcs/mcs/parser.cs
@@ -5,7 +5,6 @@ namespace Compiler {
abstract public class Parser {
public string name;
public System.IO.Stream input;
- public CIR.Tree tree;
public Parser (CIR.Tree tree, string name, System.IO.Stream stream)
{
diff --git a/mcs/mcs/report.cs b/mcs/mcs/report.cs
new file mode 100644
index 00000000000..6390eb4d2ca
--- /dev/null
+++ b/mcs/mcs/report.cs
@@ -0,0 +1,97 @@
+//
+// report.cs: report errors and warnings.
+//
+// Author: Miguel de Icaza (miguel@ximian.com)
+//
+// (C) 2001 Ximian, Inc. (http://www.ximian.com)
+//
+
+using System;
+
+namespace CIR {
+
+ public class Report {
+ int errors;
+ int warnings;
+
+ public void Error (int code, Location l, string text)
+ {
+ Console.WriteLine (l.Name + "(" + l.Row + "," + l.Col +
+ "): Error CS"+code+": " + text);
+ errors++;
+ }
+
+ public void Warning (int code, Location l, string text)
+ {
+ Console.WriteLine (l.Name + "(" + l.Row + "," + l.Col +
+ "): Warning CS"+code+": " + text);
+ warnings++;
+ }
+
+ public void Error (int code, string text)
+ {
+ Console.WriteLine ("Error CS"+code+": "+text);
+ errors++;
+ }
+
+ public void Warning (int code, string text)
+ {
+ Console.WriteLine ("Warning CS"+code+": "+text);
+ warnings++;
+ }
+
+ public void Message (Message m)
+ {
+ if (m is Error)
+ Error (m.code, m.text);
+ else
+ Warning (m.code, m.text);
+ }
+
+ public int Errors {
+ get {
+ return errors;
+ }
+ }
+
+ public int Warnings {
+ get {
+ return warnings;
+ }
+ }
+ }
+
+ public class Message {
+ public int code;
+ public string text;
+
+ public Message (int code, string text)
+ {
+ this.code = code;
+ this.text = text;
+ }
+ }
+
+ public class Warning : Message {
+ public Warning (int code, string text) : base (code, text)
+ {
+ }
+ }
+
+ public class Error : Message {
+ public Error (int code, string text) : base (code, text)
+ {
+ }
+
+ //
+ // For compatibility reasons with old code.
+ //
+ public static void report_error (string error)
+ {
+ Console.Write ("ERROR: ");
+ Console.WriteLine (error);
+ }
+ }
+}
+
+
diff --git a/mcs/mcs/rootcontext.cs b/mcs/mcs/rootcontext.cs
new file mode 100755
index 00000000000..0fa5a5a4117
--- /dev/null
+++ b/mcs/mcs/rootcontext.cs
@@ -0,0 +1,619 @@
+//
+// rootcontext.cs: keeps track of our tree representation, and assemblies loaded.
+//
+// Author: Miguel de Icaza (miguel@ximian.com)
+//
+// Licensed under the terms of the GNU GPL
+//
+// (C) 2001 Ximian, Inc (http://www.ximian.com)
+
+using System;
+using System.Collections;
+using System.Reflection;
+using System.Reflection.Emit;
+using System.Diagnostics;
+
+namespace CIR {
+
+ public class RootContext {
+
+ //
+ // Contains the parsed tree
+ //
+ Tree tree;
+
+ //
+ // Contains loaded assemblies and our generated code as we go.
+ //
+ TypeManager type_manager;
+
+ //
+ // The System.Reflection.Emit CodeGenerator
+ //
+ CodeGen cg;
+
+ //
+ // The module builder pointer
+ //
+ ModuleBuilder mb;
+
+ //
+ // Error reporting object
+ //
+ Report report;
+
+ //
+ // The `System.Object' and `System.ValueType' types, as they
+ // are used often
+ //
+ Type object_type;
+ Type value_type;
+
+ //
+ // Whether we are being linked against the standard libraries.
+ // This is only used to tell whether `System.Object' should
+ // have a parent or not.
+ //
+ bool stdlib = true;
+
+ public RootContext ()
+ {
+ tree = new Tree (this);
+ type_manager = new TypeManager ();
+ report = new Report ();
+
+ object_type = System.Type.GetType ("System.Object");
+ value_type = System.Type.GetType ("System.ValueType");
+ }
+
+ public TypeManager TypeManager {
+ get {
+ return type_manager;
+ }
+ }
+
+ public Tree Tree {
+ get {
+ return tree;
+ }
+ }
+
+ public CodeGen CodeGen {
+ get {
+ return cg;
+ }
+
+ set {
+ //
+ // Temporary hack, we should probably
+ // intialize `cg' rather than depending on
+ // external initialization of it.
+ //
+ cg = value;
+ mb = cg.ModuleBuilder;
+ }
+ }
+
+ //
+ // Returns the Type that represents the interface whose name
+ // is `name'.
+ //
+
+ Type GetInterfaceTypeByName (string name)
+ {
+ Interface parent;
+ Type t = type_manager.LookupType (name);
+
+ if (t != null) {
+
+ if (t.IsInterface)
+ return t;
+
+ string cause;
+
+ if (t.IsValueType)
+ cause = "is a struct";
+ else if (t.IsClass)
+ cause = "is a class";
+ else
+ cause = "Should not happen.";
+
+ report.Error (527, "`"+name+"' " + cause + ", need an interface instead");
+
+ return null;
+ }
+
+ parent = (Interface) tree.Interfaces [name];
+ if (parent == null){
+ string cause = "is undefined";
+
+ if (tree.Classes [name] != null)
+ cause = "is a class";
+ else if (tree.Structs [name] != null)
+ cause = "is a struct";
+
+ report.Error (527, "`"+name+"' " + cause + ", need an interface instead");
+ return null;
+ }
+
+ t = CreateInterface ((Interface) parent);
+ if (t == null){
+ report.Error (529,
+ "Inherited interface `"+name+"' is circular");
+ return null;
+ }
+
+ return t;
+ }
+
+ //
+ // Returns the list of interfaces that this interface implements
+ // Or null if it does not implement any interface.
+ //
+ // Sets the error boolean accoringly.
+ //
+ Type [] GetInterfaceBases (Interface iface, out bool error)
+ {
+ ArrayList bases = iface.Bases;
+ Type [] tbases;
+ int i;
+
+ error = false;
+ if (bases == null)
+ return null;
+
+ tbases = new Type [bases.Count];
+ i = 0;
+
+ foreach (string name in iface.Bases){
+ Type t;
+
+ t = GetInterfaceTypeByName (name);
+ if (t == null){
+ error = true;
+ return null;
+ }
+
+ tbases [i++] = t;
+ }
+
+ return tbases;
+ }
+
+ //
+ // Creates the Interface @iface using the ModuleBuilder
+ //
+ // TODO:
+ // Rework the way we recurse, because for recursive
+ // definitions of interfaces (A:B and B:A) we report the
+ // error twice, rather than once.
+ //
+ TypeBuilder CreateInterface (Interface iface)
+ {
+ TypeBuilder tb = iface.TypeBuilder;
+ Type [] ifaces;
+ string name;
+ bool error;
+
+ if (tb != null)
+ return tb;
+
+ if (iface.InTransit)
+ return null;
+
+ iface.InTransit = true;
+
+ name = iface.Name;
+
+ ifaces = GetInterfaceBases (iface, out error);
+
+ if (error)
+ return null;
+
+ // FIXME: use the actual accesibility here, not
+ // TypeAttributes.Public.
+ tb = mb.DefineType (name,
+ TypeAttributes.Interface |
+ TypeAttributes.Public |
+ TypeAttributes.Abstract,
+ null, // Parent Type
+ ifaces);
+ iface.TypeBuilder = tb;
+
+ type_manager.AddUserType (name, tb);
+
+ iface.InTransit = false;
+ return tb;
+ }
+
+ string MakeFQN (string nsn, string name)
+ {
+ string prefix = (nsn == "" ? "" : nsn + ".");
+
+ return prefix + name;
+ }
+
+ Type LookupInterfaceOrClass (string ns, string name, bool is_class, out bool error)
+ {
+ TypeContainer parent;
+ Type t;
+
+ error = false;
+ name = MakeFQN (ns, name);
+ Console.WriteLine ("Attempting to locate " + name);
+
+ t = type_manager.LookupType (name);
+ if (t != null)
+ return t;
+
+ if (is_class){
+ parent = (Class) tree.Classes [name];
+ } else {
+ parent = (Struct) tree.Structs [name];
+ }
+
+ if (parent != null){
+ t = CreateType (parent, is_class);
+ if (t == null){
+ report.Error (146, "Class definition is circular: `"+name+"'");
+ error = true;
+ return null;
+ }
+
+ return t;
+ }
+
+ return null;
+ }
+
+ //
+ // returns the type for an interface or a class, this will recursively
+ // try to define the types that it depends on.
+ //
+ Type GetInterfaceOrClass (TypeContainer tc, string name, bool is_class)
+ {
+ Type t;
+ bool error;
+
+ //
+ // Attempt to lookup the class on our namespace
+ //
+ t = LookupInterfaceOrClass (tc.Namespace.Name, name, is_class, out error);
+ if (error)
+ return null;
+
+ if (t != null)
+ return t;
+
+ //
+ // Attempt to lookup the class on any of the `using'
+ // namespaces
+ //
+ for (Namespace ns = tc.Namespace; ns != null; ns = ns.Parent){
+ ArrayList using_list = ns.UsingTable;
+
+ if (using_list == null)
+ continue;
+
+ foreach (string n in using_list){
+ t = LookupInterfaceOrClass (n, name, is_class, out error);
+ if (error)
+ return null;
+
+ if (t != null)
+ return t;
+ }
+
+ }
+ report.Error (246, "Can not find type `"+name+"'");
+ return null;
+ }
+
+ //
+ // This function computes the Base class and also the
+ // list of interfaces that the class or struct @c implements.
+ //
+ // The return value is an array (might be null) of
+ // interfaces implemented (as Types).
+ //
+ // The @parent argument is set to the parent object or null
+ // if this is `System.Object'.
+ //
+ Type [] GetClassBases (TypeContainer tc, bool is_class, out Type parent, out bool error)
+ {
+ ArrayList bases = tc.Bases;
+ int count;
+ int start, j, i;
+
+ error = false;
+
+ if (is_class)
+ parent = null;
+ else
+ parent = value_type;
+
+ if (bases == null){
+ if (is_class){
+ if (stdlib)
+ parent = object_type;
+ else if (tc.Name != "System.Object")
+ parent = object_type;
+ } else {
+ //
+ // If we are compiling our runtime,
+ // and we are defining ValueType, then our
+ // parent is `System.Object'.
+ //
+ if (!stdlib && tc. Name == "System.ValueType")
+ parent = object_type;
+ }
+
+ return null;
+ }
+
+ //
+ // Bases should be null if there are no bases at all
+ //
+ count = bases.Count;
+ Debug.Assert (count > 0);
+
+ if (is_class){
+ string name = (string) bases [0];
+ Type first = GetInterfaceOrClass (tc, name, is_class);
+
+ if (first == null){
+ error = true;
+ return null;
+ }
+
+ if (first.IsClass){
+ parent = first;
+ start = 1;
+ } else {
+ parent = object_type;
+ start = 0;
+ }
+ } else {
+ start = 0;
+ }
+
+ Type [] ifaces = new Type [count-start];
+
+ for (i = start, j = 0; i < count; i++, j++){
+ string name = (string) bases [i];
+ Type t = GetInterfaceOrClass (tc, name, is_class);
+
+ if (t == null){
+ error = true;
+ return null;
+ }
+
+ if (is_class == false && !t.IsInterface){
+ report.Error (527, "In Struct `"+tc.Name+"', type `"+
+ name+"' is not an interface");
+ error = true;
+ return null;
+ }
+
+ if (t.IsSealed) {
+ string detail = "";
+
+ if (t.IsValueType)
+ detail = " (a class can not inherit from a struct)";
+
+ report.Error (509, "class `"+tc.Name+
+ "': Cannot inherit from sealed class `"+
+ bases [i]+"'"+detail);
+ error = true;
+ return null;
+ }
+
+ if (t.IsClass) {
+ if (parent != null){
+ report.Error (527, "In Class `"+tc.Name+"', type `"+
+ name+"' is not an interface");
+ error = true;
+ return null;
+ }
+ }
+
+ ifaces [j] = t;
+ }
+
+ return ifaces;
+ }
+
+ // <remarks>
+ // Creates the TypeBuilder for the TypeContainer @tc (a Class or a Struct)
+ // </remarks>
+ //
+ TypeBuilder CreateType (TypeContainer tc, bool is_class)
+ {
+ TypeBuilder tb = tc.TypeBuilder;
+ Type parent;
+ Type [] ifaces;
+ bool error;
+ string name;
+
+ if (tb != null)
+ return tb;
+
+ if (tc.InTransit)
+ return null;
+ tc.InTransit = true;
+
+ name = tc.Name;
+
+ ifaces = GetClassBases (tc, is_class, out parent, out error);
+
+ if (error)
+ return null;
+
+ tb = mb.DefineType (name,
+ tc.TypeAttr | TypeAttributes.Class,
+ parent,
+ ifaces);
+
+ tc.TypeBuilder = tb;
+ type_manager.AddUserType (name, tb);
+ tc.InTransit = false;
+
+ return tb;
+ }
+
+ // <remarks>
+ // This function is used to resolve the hierarchy tree.
+ // It processes interfaces, structs and classes in that order.
+ //
+ // It creates the TypeBuilder's as it processes the user defined
+ // types.
+ // </remarks>
+ public void ResolveTree ()
+ {
+ Hashtable ifaces, classes, structs;
+
+ //
+ // Interfaces are processed first, as classes and
+ // structs might inherit from an object or implement
+ // a set of interfaces, we need to be able to tell
+ // them appart by just using the TypeManager.
+ //
+ ifaces = tree.Interfaces;
+ if (ifaces != null){
+ foreach (DictionaryEntry de in ifaces)
+ CreateInterface ((Interface) de.Value);
+ }
+
+ //
+ // Process structs and classes next. Our code assumes
+ // this order (just for error reporting purposes).
+ //
+ structs = tree.Structs;
+ if (structs != null){
+ foreach (DictionaryEntry de in structs)
+ CreateType ((Struct) de.Value, false);
+ }
+
+ classes = tree.Classes;
+ if (classes != null){
+ foreach (DictionaryEntry de in classes)
+ CreateType ((Class) de.Value, true);
+ }
+ }
+
+ // <summary>
+ // Closes all open types
+ // </summary>
+ //
+ // <remarks>
+ // We usually use TypeBuilder types. When we are done
+ // creating the type (which will happen after we have addded
+ // methods, fields, etc) we need to "Define" them before we
+ // can save the Assembly
+ // </remarks>
+ public void CloseTypes ()
+ {
+ foreach (TypeBuilder t in type_manager.UserTypes){
+ t.CreateType ();
+ }
+ }
+
+ //
+ // Public function used to locate types, this can only
+ // be used after the ResolveTree function has been invoked.
+ //
+ // Returns: Type or null if they type can not be found.
+ //
+ public Type LookupType (TypeContainer tc, string name, bool silent)
+ {
+ Type t;
+
+ t = type_manager.LookupType (MakeFQN (tc.Namespace.Name, name));
+ if (t != null)
+ return t;
+
+ for (Namespace ns = tc.Namespace; ns != null; ns = ns.Parent){
+ ArrayList using_list = ns.UsingTable;
+
+ if (using_list == null)
+ continue;
+
+ foreach (string n in using_list){
+ t = type_manager.LookupType (MakeFQN (n, name));
+ if (t != null)
+ return t;
+ }
+ }
+
+ if (!silent)
+ report.Error (246, "Can not find type `"+name+"'");
+
+ return null;
+ }
+
+ public Type LookupType (TypeContainer tc, string name)
+ {
+ return LookupType (tc, name, true);
+ }
+
+ // <summary>
+ // Populates the structs and classes with fields and methods
+ // </summary>
+ //
+ // This is invoked after all interfaces, structs and classes
+ // have been defined through `ResolveTree'
+ public void PopulateTypes ()
+ {
+ Hashtable ifaces, classes;
+
+ if ((ifaces = tree.Interfaces) != null){
+ foreach (DictionaryEntry de in ifaces){
+ Interface iface = (Interface) de.Value;
+
+ iface.Populate ();
+ }
+ }
+
+ if ((classes = tree.Classes) != null){
+ foreach (DictionaryEntry de in classes){
+ TypeContainer tc = (TypeContainer) de.Value;
+
+ tc.Populate ();
+ }
+ }
+ }
+
+ public void EmitCode ()
+ {
+ Hashtable classes;
+
+ if ((classes = tree.Classes) != null){
+ foreach (DictionaryEntry de in classes){
+ TypeContainer tc = (TypeContainer) de.Value;
+
+ tc.Emit ();
+ }
+ }
+ }
+
+ // <summary>
+ // Compiling against Standard Libraries property.
+ // </summary>
+ public bool StdLib {
+ get {
+ return stdlib;
+ }
+
+ set {
+ stdlib = value;
+ }
+ }
+
+ public Report Report {
+ get {
+ return report;
+ }
+ }
+ }
+}
+
diff --git a/mcs/mcs/statement.cs b/mcs/mcs/statement.cs
index 31e664d2f85..d8a5bbd6df0 100755
--- a/mcs/mcs/statement.cs
+++ b/mcs/mcs/statement.cs
@@ -8,6 +8,8 @@
//
using System;
+using System.Reflection;
+using System.Reflection.Emit;
namespace CIR {
@@ -213,58 +215,91 @@ namespace CIR {
}
}
+ public struct VariableInfo {
+ public readonly string Type;
+ public LocalBuilder LocalBuilder ;
+
+ public VariableInfo (string type)
+ {
+ Type = type;
+ LocalBuilder = null;
+ }
+ }
+
// <summary>
// Used for Label management
// </summary>
//
public class Block : Statement {
- Block parent;
+ public readonly Block Parent;
+ public readonly bool Implicit;
+ public readonly string Label;
+
+ //
+ // The statements in this block
+ //
StatementCollection statements;
+
+ //
+ // Labels. (label, block) pairs.
+ //
Hashtable labels;
- Hashtable labels_referenced;
- bool implicit_block;
+
+ //
+ // Keeps track of (name, type) pairs
+ //
Hashtable variables;
- string label;
- int internal_id_serial;
- bool used = false;
+
+ //
+ // Maps variable names to ILGenerator.LocalBuilders
+ //
+ Hashtable local_builders;
+
+ //
+ // If we have a child, here it is
+ //
+ Block child;
+ bool used = false;
+
public Block (Block parent)
{
- this.parent = parent;
- this.implicit_block = false;
+ if (parent != null)
+ parent.Child = this;
+
+ this.Parent = parent;
+ this.Implicit = false;
}
public Block (Block parent, bool implicit_block)
{
- this.parent = parent;
- this.implicit_block = true;
+ if (parent != null)
+ parent.Child = this;
+
+ this.Parent = parent;
+ this.Implicit = true;
}
public Block (Block parent, string labeled)
{
- this.parent = parent;
- this.implicit_block = true;
- label = labeled;
+ if (parent != null)
+ parent.Child = this;
+
+ this.Parent = parent;
+ this.Implicit = true;
+ Label = labeled;
}
- public Block Parent {
+ public Block Child {
get {
- return parent;
+ return child;
}
- }
- public bool Implicit {
- get {
- return implicit_block;
+ set {
+ child = value;
}
}
- public string Label {
- get {
- return label;
- }
- }
-
// <summary>
// Adds a label to the current block.
// </summary>
@@ -285,15 +320,17 @@ namespace CIR {
return true;
}
- public bool AddVariable (TypeRef typeref, string name)
+ public bool AddVariable (string type, string name)
{
if (variables == null)
variables = new Hashtable ();
- if (GetVariableTypeRef (name) != null)
+ if (GetVariableType (name) != null)
return false;
+
+ VariableInfo vi = new VariableInfo (type);
- variables.Add (name, typeref);
+ variables.Add (name, vi);
return true;
}
@@ -303,16 +340,16 @@ namespace CIR {
}
}
- public TypeRef GetVariableTypeRef (string name)
+ public string GetVariableType (string name)
{
- TypeRef tr = null;
+ string type = null;
if (variables != null)
- tr = (TypeRef) variables [name];
- if (tr != null)
- return tr;
- else if (parent != null)
- return parent.GetVariableTypeRef (name);
+ type = (string) variables [name];
+ if (type != null)
+ return type;
+ else if (Parent != null)
+ return Parent.GetVariableType (name);
return null;
}
@@ -322,7 +359,7 @@ namespace CIR {
// </summary>
public bool IsVariableDefined (string name)
{
- return GetVariableTypeRef (name) != null;
+ return GetVariableType (name) != null;
}
// <summary>
@@ -334,31 +371,13 @@ namespace CIR {
}
}
- // <summary>
- // Call this to label the label as used in a block
- // </summary>
- public void Reference (string name)
- {
- if (labels_referenced == null)
- labels_referenced = new Hashtable ();
- labels_referenced.Add (name, null);
- }
-
// <returns>
// A list of labels that were not used within this block
// </returns>
public string [] GetUnreferenced ()
{
- ArrayList unrefs = new ArrayList ();
-
- foreach (string s in (string []) labels.Keys) {
- if (labels_referenced [s] == null)
- unrefs.Add (s);
- }
-
- string [] result = new string [unrefs.Count];
- unrefs.CopyTo (result);
- return result;
+ // FIXME: Implement me
+ return null;
}
public StatementCollection Statements {
@@ -390,12 +409,45 @@ namespace CIR {
// used to create temporary variables that should not
// be seen by the application
// </summary
+ int internal_id_serial;
public string MakeInternalID () {
string ret = internal_id_serial.ToString ();
internal_id_serial++;
return "0_" + ret;
}
+
+ // <summary>
+ // Emits the variable declarations
+ // </summary>
+
+ public void EmitVariables (TypeContainer tc, ILGenerator ig)
+ {
+ //
+ // Process this block variables
+ //
+ if (variables != null){
+ local_builders = new Hashtable ();
+
+ foreach (DictionaryEntry de in variables){
+ string name = (string) de.Key;
+ VariableInfo vi = (VariableInfo) de.Value;
+ Type t;
+
+ t = tc.LookupType (vi.Type, false);
+ if (t == null)
+ continue;
+
+ vi.LocalBuilder = ig.DeclareLocal (t);
+ }
+ }
+
+ //
+ // Now, handle the children
+ //
+ if (Child != null)
+ Child.EmitVariables (tc, ig);
+ }
}
public class SwitchLabel {
@@ -563,13 +615,13 @@ namespace CIR {
}
public class Catch {
- TypeRef typeref;
+ string type;
string name;
Block block;
- public Catch (TypeRef typeref, string name, Block block)
+ public Catch (string type, string name, Block block)
{
- this.typeref = typeref;
+ this.type = type;
this.name = name;
this.block = block;
}
@@ -586,9 +638,9 @@ namespace CIR {
}
}
- public Type Type {
+ public string Type {
get {
- return typeref.Type;
+ return type;
}
}
}
diff --git a/mcs/mcs/statementCollection.cs b/mcs/mcs/statementCollection.cs
index 475b17b1279..9d235ce6c78 100755
--- a/mcs/mcs/statementCollection.cs
+++ b/mcs/mcs/statementCollection.cs
@@ -156,5 +156,11 @@ namespace CIR {
return statements.IsSynchronized;
}
}
+
+ public bool IsFixedSize {
+ get {
+ return false;
+ }
+ }
}
}
diff --git a/mcs/mcs/tree.cs b/mcs/mcs/tree.cs
index f08c5a27dac..7b651dbc14c 100755
--- a/mcs/mcs/tree.cs
+++ b/mcs/mcs/tree.cs
@@ -13,79 +13,72 @@ using System;
using System.Collections;
using System.Reflection;
using System.Reflection.Emit;
+using System.IO;
namespace CIR
{
+ public interface ITreeDump {
+ int Dump (Tree tree, StreamWriter output);
+ void ParseOptions (string options);
+ }
+
// <summary>
- // A storage for temporary IL trees
+ //
+ // We store here all the toplevel types that we have parsed,
+ // this is the root of all information we have parsed.
+ //
// </summary>
public class Tree {
TypeContainer root_types;
// <summary>
- // Holds the Array of Assemblies that have been loaded
- // (either because it is the default or the user used the
- // -r command line option)
+ // Keeps track of the interfaces defined in the source code
// </summary>
- ArrayList assemblies;
+ Hashtable ifaces;
// <summary>
- // This is used to map defined FQN to Types
+ // Keeps track of the structs defined in the source code
// </summary>
- Hashtable types;
+ Hashtable structs;
// <summary>
- // This maps source defined types that are defined
- // in the source code to their object holders (Class, Struct,
- // Interface) and that have not yet been made into real
- // types.
+ // Keeps track of the classes defined in the source code
// </summary>
- Hashtable source_types;
+ Hashtable classes;
- AppDomain current_domain;
- AssemblyBuilder assembly_builder;
- ModuleBuilder module_builder;
+ RootContext rc;
- public Tree ()
+ public Tree (RootContext rc)
{
- root_types = new TypeContainer (null, "");
- assemblies = new ArrayList ();
- types = new Hashtable ();
- source_types = new Hashtable ();
+ root_types = new TypeContainer (rc, null, "");
+ this.rc = rc;
}
- public int BuilderInit (string name, string output)
- {
- AssemblyName an;
-
- an = new AssemblyName ();
- an.Name = "AssemblyName";
- current_domain = AppDomain.CurrentDomain;
- assembly_builder = current_domain.DefineDynamicAssembly (
- an, AssemblyBuilderAccess.RunAndSave);
- module_builder = assembly_builder.DefineDynamicModule (name, output);
+ public void RecordInterface (string name, Interface iface)
+ {
+ if (ifaces == null)
+ ifaces = new Hashtable ();
- return 0;
- }
-
- public AssemblyBuilder AssemblyBuilder {
- get {
- return assembly_builder;
- }
+ ifaces.Add (name, iface);
}
+
+ public void RecordStruct (string name, Struct s)
+ {
+ if (structs == null)
+ structs = new Hashtable ();
- public ModuleBuilder ModuleBuilder {
- get {
- return module_builder;
- }
+ structs.Add (name, s);
}
-
- public void RecordType (string name, DeclSpace decl)
+
+ public void RecordClass (string name, Class c)
{
- source_types.Add (name, decl);
+ if (classes == null)
+ classes = new Hashtable ();
+
+ classes.Add (name, c);
}
public TypeContainer Types {
@@ -94,89 +87,21 @@ namespace CIR
}
}
- public int ResolveTypeContainerTypes (TypeContainer type)
- {
- return 0;
- }
-
- public int ResolveNames (TypeContainer types)
- {
- int errors = 0;
-
- if (types == null)
- return 0;
-
- foreach (DictionaryEntry de in types.Types){
- TypeContainer type = (TypeContainer) de.Value;
-
- errors += ResolveTypeContainerTypes (type);
+ public Hashtable Interfaces {
+ get {
+ return ifaces;
}
-
- return errors;
}
- public Type ResolveType (string name)
- {
- Type t = (Type) types [name];
-
- if (t != null)
- return t;
-
- DeclSpace decl;
- decl = (DeclSpace) source_types [name];
-
- // FIXME: handle using here.
- if (decl == null){
- CSC.CSharpParser.error (234, "The type or namespace name '" + name
- + "' does not exist in the current space");
- return null;
- }
-
- return decl.Define (this);
- }
-
- int iscan_errors = 0;
- void interface_scan (TypeContainer container, object data)
- {
- foreach (Interface iface in container.Interfaces){
- Type t = ResolveType (iface.Name);
-
- if (t != null){
- CSC.CSharpParser.error (101, "There is already a definition for " + iface.Name);
- iscan_errors++;
- }
- iface.Define (this);
+ public Hashtable Classes {
+ get {
+ return classes;
}
}
- public int ResolveInterfaces (TypeContainer type)
- {
- TypeContainer.VisitContainer iscanner;
-
- iscanner = new TypeContainer.VisitContainer (interface_scan);
- type.VisitTypes (iscanner, this);
- return iscan_errors;
- }
-
- public int ResolveTypeContainerParents (TypeContainer type)
- {
- return type.ResolveParents (this);
- }
-
- public int Resolve ()
- {
- int errors = 0;
-
- errors += ResolveInterfaces (root_types);
- errors += ResolveTypeContainerParents (root_types);
- return 0;
- }
-
- public void AddAssembly (Assembly a)
- {
- assemblies.Add (a);
- foreach (Type t in a.GetExportedTypes ()){
- types.Add (t.FullName, t);
+ public Hashtable Structs {
+ get {
+ return structs;
}
}
}
diff --git a/mcs/mcs/type.cs b/mcs/mcs/type.cs
index 021b00f823a..65a59146e53 100755
--- a/mcs/mcs/type.cs
+++ b/mcs/mcs/type.cs
@@ -12,11 +12,11 @@ namespace CIR {
using System.Collections;
using System;
- public class UnresolvedType {
+ public class xUnresolvedType {
TypeContainer parent;
string name;
- public UnresolvedType (TypeContainer parent, string name)
+ public xUnresolvedType (TypeContainer parent, string name)
{
this.parent = parent;
this.name = name;
@@ -35,10 +35,10 @@ namespace CIR {
}
}
- public class TypeRef {
+ public class xTypeRef {
object data;
- public TypeRef (object data)
+ public xTypeRef (object data)
{
this.data = data;
}
@@ -49,7 +49,7 @@ namespace CIR {
}
}
- public UnresolvedType UnresolvedData {
+ public xUnresolvedType UnresolvedData {
get {
if (data is UnresolvedType)
return (UnresolvedType) data;
@@ -78,10 +78,10 @@ namespace CIR {
}
}
- public class TypeRefManager {
+ public class xTypeRefManager {
ArrayList pending_types;
- public TypeRefManager ()
+ public xTypeRefManager ()
{
pending_types = new ArrayList ();
}
diff --git a/mcs/mcs/typemanager.cs b/mcs/mcs/typemanager.cs
new file mode 100755
index 00000000000..a936c314ff5
--- /dev/null
+++ b/mcs/mcs/typemanager.cs
@@ -0,0 +1,94 @@
+//
+// typegen.cs: type generation
+//
+// Author: Miguel de Icaza (miguel@gnu.org)
+//
+// Licensed under the terms of the GNU GPL
+//
+// (C) 2001 Ximian, Inc (http://www.ximian.com)
+//
+//
+
+using System;
+using System.Collections;
+using System.Reflection;
+using System.Reflection.Emit;
+
+public class TypeManager {
+
+ // <remarks>
+ // Holds the Array of Assemblies that have been loaded
+ // (either because it is the default or the user used the
+ // -r command line option)
+ // </remarks>
+ ArrayList assemblies;
+
+ // <remarks>
+ // This is the type_cache from the assemblies to avoid
+ // hitting System.Reflection on every lookup.
+ // </summary>
+ Hashtable types;
+
+ // <remarks>
+ // Keeps track of those types that are defined by the
+ // user's program
+ // </remarks>
+ ArrayList user_types;
+
+ public TypeManager ()
+ {
+ assemblies = new ArrayList ();
+ user_types = new ArrayList ();
+ types = new Hashtable ();
+ }
+
+ public void AddUserType (string name, TypeBuilder t)
+ {
+ types.Add (t.FullName, t);
+ user_types.Add (t);
+ }
+
+ // <summary>
+ // Registers an assembly to load types from.
+ // </summary>
+ public void AddAssembly (Assembly a)
+ {
+ assemblies.Add (a);
+ }
+
+ // <summary>
+ // Returns the Type associated with @name
+ // </summary>
+ public Type LookupType (string name)
+ {
+ Type t;
+
+ //
+ // First lookup in user defined and cached values
+ //
+ t = (Type) types [name];
+ if (t != null)
+ return t;
+
+ foreach (Assembly a in assemblies){
+ t = a.GetType (name);
+ if (t != null){
+ types [name] = t;
+
+ return t;
+ }
+ }
+
+ return null;
+ }
+
+ // <summary>
+ // Returns the User Defined Types
+ // </summary>
+ public ArrayList UserTypes {
+ get {
+ return user_types;
+ }
+ }
+}
+
diff --git a/mcs/tests/c1.cs b/mcs/tests/c1.cs
new file mode 100755
index 00000000000..8b81c046864
--- /dev/null
+++ b/mcs/tests/c1.cs
@@ -0,0 +1,7 @@
+// cs0146.cs: circular class definition
+// Line: 6
+class A : B {
+}
+
+class B : A {
+}
diff --git a/mcs/tests/c2.cs b/mcs/tests/c2.cs
new file mode 100755
index 00000000000..eeeb6f19e74
--- /dev/null
+++ b/mcs/tests/c2.cs
@@ -0,0 +1,2 @@
+class X {
+}
diff --git a/mcs/tests/co1.cs b/mcs/tests/co1.cs
new file mode 100755
index 00000000000..da1bdaab246
--- /dev/null
+++ b/mcs/tests/co1.cs
@@ -0,0 +1,4 @@
+class X {
+ const int x = 1;
+ const string s = "Hello";
+}
diff --git a/mcs/tests/cs1.cs b/mcs/tests/cs1.cs
new file mode 100755
index 00000000000..bfb3c74b3c8
--- /dev/null
+++ b/mcs/tests/cs1.cs
@@ -0,0 +1,5 @@
+class X {
+}
+
+struct Y {
+}
diff --git a/mcs/tests/i-recursive.cs b/mcs/tests/i-recursive.cs
new file mode 100644
index 00000000000..9c22e5876cc
--- /dev/null
+++ b/mcs/tests/i-recursive.cs
@@ -0,0 +1,5 @@
+interface A : B {
+}
+
+interface B : A {
+}
diff --git a/mcs/tests/i-three.cs b/mcs/tests/i-three.cs
new file mode 100755
index 00000000000..7c473f21657
--- /dev/null
+++ b/mcs/tests/i-three.cs
@@ -0,0 +1,11 @@
+interface A {
+}
+
+interface B : A{
+}
+
+interface C : A {
+}
+
+interface D : C {
+}
diff --git a/mcs/tests/i-undefined.cs b/mcs/tests/i-undefined.cs
new file mode 100644
index 00000000000..496795cd6db
--- /dev/null
+++ b/mcs/tests/i-undefined.cs
@@ -0,0 +1,2 @@
+interface A : B {
+}
diff --git a/mcs/tests/i1.cs b/mcs/tests/i1.cs
new file mode 100755
index 00000000000..00141820820
--- /dev/null
+++ b/mcs/tests/i1.cs
@@ -0,0 +1,2 @@
+interface A {
+}
diff --git a/mcs/tests/i2.cs b/mcs/tests/i2.cs
new file mode 100755
index 00000000000..9c22e5876cc
--- /dev/null
+++ b/mcs/tests/i2.cs
@@ -0,0 +1,5 @@
+interface A : B {
+}
+
+interface B : A {
+}
diff --git a/mcs/tests/i3.cs b/mcs/tests/i3.cs
new file mode 100755
index 00000000000..dff6c54db9d
--- /dev/null
+++ b/mcs/tests/i3.cs
@@ -0,0 +1,5 @@
+class X {
+}
+
+interface A : X {
+}
diff --git a/mcs/tests/i4.cs b/mcs/tests/i4.cs
new file mode 100755
index 00000000000..f89988f2cb3
--- /dev/null
+++ b/mcs/tests/i4.cs
@@ -0,0 +1,8 @@
+// cs0509.cs: base class is sealed
+// Line: 7
+struct V {
+ int v;
+}
+
+class X : V {
+}
diff --git a/mcs/tests/i5.cs b/mcs/tests/i5.cs
new file mode 100755
index 00000000000..e312377061b
--- /dev/null
+++ b/mcs/tests/i5.cs
@@ -0,0 +1,8 @@
+class A1 {
+}
+
+class A2 {
+}
+
+class B : A1, A2 {
+}
diff --git a/mcs/tests/i6.cs b/mcs/tests/i6.cs
new file mode 100755
index 00000000000..fa20da0ada8
--- /dev/null
+++ b/mcs/tests/i6.cs
@@ -0,0 +1,4 @@
+// cs0246.cs: can not find type `B'
+// Line: 4
+class X : D {
+}
diff --git a/mcs/tests/ix1.cs b/mcs/tests/ix1.cs
new file mode 100755
index 00000000000..984391d2fda
--- /dev/null
+++ b/mcs/tests/ix1.cs
@@ -0,0 +1,3 @@
+interface INTERFACE {
+ string PROPERTY { get; set; }
+}
diff --git a/mcs/tests/ix2.cs b/mcs/tests/ix2.cs
new file mode 100755
index 00000000000..714fa7b1594
--- /dev/null
+++ b/mcs/tests/ix2.cs
@@ -0,0 +1,5 @@
+interface INTERFACE {
+ string this [ int INDEX ] { get; set; }
+ string Item (int index);
+}
+
diff --git a/mcs/tests/n1.cs b/mcs/tests/n1.cs
new file mode 100755
index 00000000000..b47fd24b2ca
--- /dev/null
+++ b/mcs/tests/n1.cs
@@ -0,0 +1,11 @@
+namespace A {
+ class X {
+ void Y () {}
+ }
+}
+
+namespace A {
+ class XX : X {
+ void YY () {}
+ }
+}
diff --git a/mcs/tests/n2.cs b/mcs/tests/n2.cs
new file mode 100755
index 00000000000..34c210e1fe7
--- /dev/null
+++ b/mcs/tests/n2.cs
@@ -0,0 +1,4 @@
+using System.Collections;
+
+class X : Queue {
+}
diff --git a/mcs/tests/s1.cs b/mcs/tests/s1.cs
new file mode 100755
index 00000000000..6c1191a86a0
--- /dev/null
+++ b/mcs/tests/s1.cs
@@ -0,0 +1,7 @@
+struct A {
+ int x;
+}
+
+struct B : A {
+ int y;
+}
diff --git a/mcs/tools/makefile b/mcs/tools/makefile
new file mode 100644
index 00000000000..9193c6939ff
--- /dev/null
+++ b/mcs/tools/makefile
@@ -0,0 +1,8 @@
+ROOT=//$(subst \,/,$(subst :\,/,$(SYSTEMROOT)))
+CSC=$(ROOT)/microsoft.net/framework/v1.0.2914/csc.exe
+CSCFLAGS=/nologo /debug+ /debug:full
+
+windows: verifier.exe
+
+verifier.exe: verifier.cs
+ $(CSC) $(CSCFLAGS) verifier.cs
diff --git a/mcs/tools/verifier.cs b/mcs/tools/verifier.cs
new file mode 100644
index 00000000000..7c00c5e663b
--- /dev/null
+++ b/mcs/tools/verifier.cs
@@ -0,0 +1,1079 @@
+//
+// verifier.cs: compares two assemblies and reports differences.
+//
+// Author:
+// Sergey Chaban (serge@wildwestsoftware.com)
+//
+// (C) Sergey Chaban (serge@wildwestsoftware.com)
+//
+
+using System;
+using System.IO;
+using System.Collections;
+using System.Reflection;
+
+namespace Mono.Verifier {
+
+
+
+ ////////////////////////////////
+ // Collections
+ ////////////////////////////////
+
+
+ public abstract class MemberCollection : IEnumerable {
+
+ public delegate MemberInfo [] InfoQuery (Type type, BindingFlags bindings);
+ public delegate bool MemberComparer (MemberInfo mi1, MemberInfo mi2);
+
+ protected SortedList list;
+ protected MemberComparer comparer;
+
+ protected BindingFlags bindings;
+
+ protected MemberCollection (Type type, InfoQuery query, MemberComparer comparer, BindingFlags bindings)
+ {
+ if (query == null)
+ throw new NullReferenceException ("Invalid query delegate.");
+
+ if (comparer == null)
+ throw new NullReferenceException ("Invalid comparer.");
+
+ this.comparer = comparer;
+ this.bindings = bindings;
+
+ this.list = new SortedList ();
+
+ MemberInfo [] data = query (type, bindings);
+ foreach (MemberInfo info in data) {
+ this.list [info.Name] = info;
+ }
+ }
+
+
+
+ public MemberInfo this [string name] {
+ get {
+ return list [name] as MemberInfo;
+ }
+ }
+
+
+ public override int GetHashCode ()
+ {
+ return list.GetHashCode ();
+ }
+
+
+ public override bool Equals (object o)
+ {
+ bool res = (o is MemberCollection);
+ if (res) {
+ MemberCollection another = o as MemberCollection;
+ IEnumerator it = GetEnumerator ();
+ while (it.MoveNext () && res) {
+ MemberInfo inf1 = it.Current as MemberInfo;
+ MemberInfo inf2 = another [inf1.Name];
+ res &= comparer (inf1, inf2);
+ }
+ }
+ return res;
+ }
+
+
+
+ public static bool operator == (MemberCollection c1, MemberCollection c2)
+ {
+ return c1.Equals (c2);
+ }
+
+ public static bool operator != (MemberCollection c1, MemberCollection c2)
+ {
+ return !(c1 == c2);
+ }
+
+
+
+ public IEnumerator GetEnumerator() {
+ return new Iterator (this);
+ }
+
+
+ internal class Iterator : IEnumerator {
+ private MemberCollection host;
+ private int pos;
+
+ internal Iterator (MemberCollection host)
+ {
+ this.host=host;
+ this.Reset ();
+ }
+
+ /// <summary></summary>
+ public object Current
+ {
+ get {
+ if (host != null && pos >=0 && pos < host.list.Count) {
+ return host.list.GetByIndex (pos);
+ } else {
+ return null;
+ }
+ }
+ }
+
+ /// <summary></summary>
+ public bool MoveNext ()
+ {
+ if (host!=null) {
+ return (++pos) < host.list.Count;
+ } else {
+ return false;
+ }
+ }
+
+ /// <summary></summary>
+ public void Reset ()
+ {
+ this.pos = -1;
+ }
+ }
+
+ }
+
+
+
+
+ //--- Method collections
+
+ public abstract class MethodCollectionBase : MemberCollection {
+
+
+ protected MethodCollectionBase (Type type, BindingFlags bindings)
+ : base (type, new InfoQuery (Query), new MemberComparer (Comparer), bindings)
+ {
+ }
+
+
+ private static MemberInfo [] Query (Type type, BindingFlags bindings)
+ {
+ // returns MethodInfo []
+ return type.GetMethods (bindings);
+ }
+
+ private static bool Comparer (MemberInfo mi1, MemberInfo mi2)
+ {
+ bool res = false;
+ if (mi1 is MethodInfo && (mi2 == null || mi2 is MethodInfo)) {
+ MethodInfo inf1 = mi1 as MethodInfo;
+ MethodInfo inf2 = mi2 as MethodInfo;
+ res = Compare.Methods (inf1, inf2);
+ } else {
+ Verifier.log.Write ("internal-error", "Wrong comparer arguments.", ImportanceLevel.HIGH);
+ }
+ return res;
+ }
+ }
+
+
+
+ public class PublicMethods : MethodCollectionBase {
+
+ public PublicMethods (Type type)
+ : base (type, BindingFlags.Public | BindingFlags.Instance)
+ {
+ }
+ }
+
+ public class PublicStaticMethods : MethodCollectionBase {
+
+ public PublicStaticMethods (Type type)
+ : base (type, BindingFlags.Public | BindingFlags.Static)
+ {
+ }
+ }
+
+ public class NonPublicMethods : MethodCollectionBase {
+
+ public NonPublicMethods (Type type)
+ : base (type, BindingFlags.NonPublic | BindingFlags.Instance)
+ {
+ }
+ }
+
+ public class NonPublicStaticMethods : MethodCollectionBase {
+
+ public NonPublicStaticMethods (Type type)
+ : base (type, BindingFlags.NonPublic | BindingFlags.Static)
+ {
+ }
+ }
+
+
+
+
+
+ //--- Field collections
+
+ public abstract class FieldCollectionBase : MemberCollection {
+
+
+ protected FieldCollectionBase (Type type, BindingFlags bindings)
+ : base (type, new InfoQuery (Query), new MemberComparer (Comparer), bindings)
+ {
+ }
+
+
+ private static MemberInfo [] Query (Type type, BindingFlags bindings)
+ {
+ // returns FieldInfo []
+ return type.GetFields (bindings);
+ }
+
+ private static bool Comparer (MemberInfo mi1, MemberInfo mi2)
+ {
+ bool res = false;
+ if (mi1 is FieldInfo && (mi2 == null || mi2 is FieldInfo)) {
+ FieldInfo inf1 = mi1 as FieldInfo;
+ FieldInfo inf2 = mi2 as FieldInfo;
+ res = Compare.Fields (inf1, inf2);
+ } else {
+ Verifier.log.Write ("internal-error", "Wrong comparer arguments.", ImportanceLevel.HIGH);
+ }
+ return res;
+ }
+ }
+
+
+ public class PublicFields : FieldCollectionBase {
+
+ public PublicFields (Type type)
+ : base (type, BindingFlags.Public | BindingFlags.Instance)
+ {
+ }
+ }
+
+ public class PublicStaticFields : FieldCollectionBase {
+
+ public PublicStaticFields (Type type)
+ : base (type, BindingFlags.Public | BindingFlags.Static)
+ {
+ }
+ }
+
+ public class NonPublicFields : FieldCollectionBase {
+
+ public NonPublicFields (Type type)
+ : base (type, BindingFlags.NonPublic | BindingFlags.Instance)
+ {
+ }
+ }
+
+ public class NonPublicStaticFields : FieldCollectionBase {
+
+ public NonPublicStaticFields (Type type)
+ : base (type, BindingFlags.NonPublic | BindingFlags.Static)
+ {
+ }
+ }
+
+
+
+
+
+
+
+
+ public class ClassStuff {
+
+ public Type type;
+ public PublicMethods publicMethods;
+ public PublicStaticMethods publicStaticMethods;
+ public NonPublicMethods nonpublicMethods;
+ public NonPublicStaticMethods nonpublicStaticMethods;
+
+ public ClassStuff (Type type)
+ {
+ if (type == null)
+ throw new NullReferenceException ("Invalid type.");
+
+ this.type = type;
+ publicMethods = new PublicMethods (type);
+ publicStaticMethods = new PublicStaticMethods (type);
+ nonpublicMethods = new NonPublicMethods (type);
+ nonpublicStaticMethods = new NonPublicStaticMethods (type);
+ }
+ }
+
+
+
+ public class InterfaceStuff {
+
+ public Type type;
+ public PublicMethods publicMethods;
+
+ public InterfaceStuff (Type type)
+ {
+ if (type == null)
+ throw new NullReferenceException ("Invalid type.");
+
+ this.type = type;
+ publicMethods = new PublicMethods (type);
+ }
+ }
+
+
+
+ public sealed class TypeArray {
+ public static readonly TypeArray empty = new TypeArray (Type.EmptyTypes);
+
+ public Type [] types;
+
+ public TypeArray (Type [] types)
+ {
+ this.types = new Type [types.Length];
+ for (int i = 0; i < types.Length; i++) {
+ this.types.SetValue (types.GetValue (i), i);
+ }
+ }
+ }
+
+
+
+ public class AssemblyLoader {
+ public delegate void Hook (TypeArray assemblyExports);
+
+ private static Hashtable cache;
+
+ private Hook hook;
+
+ static AssemblyLoader ()
+ {
+ cache = new Hashtable (11);
+ }
+
+ public AssemblyLoader (Hook hook)
+ {
+ if (hook == null)
+ throw new NullReferenceException ("Invalid loader hook.");
+
+ this.hook = hook;
+ }
+
+
+ public bool LoadFrom (string assemblyName)
+ {
+ bool res = false;
+ try {
+ TypeArray exports = TypeArray.empty;
+
+ lock (cache) {
+ if (cache.Contains (assemblyName)) {
+ exports = (cache [assemblyName] as TypeArray);
+ } else {
+ Assembly asm = Assembly.LoadFrom (assemblyName);
+ Type [] types = asm.GetExportedTypes ();
+ if (types == null) types = Type.EmptyTypes;
+ exports = new TypeArray (types);
+ cache [assemblyName] = exports;
+ }
+ }
+ hook (exports);
+ res = true;
+ } catch (ReflectionTypeLoadException rtle) {
+ Type [] loaded = rtle.Types;
+ for (int i = 0; i < loaded.Length; i++) {
+ Verifier.log.Write ("fatal error",
+ String.Format ("Unable to load {0}, reason - {1}", loaded [i], rtle.LoaderExceptions [i]),
+ ImportanceLevel.LOW);
+ }
+ } catch (FileNotFoundException fnfe) {
+ Verifier.log.Write ("fatal error", fnfe.ToString (), ImportanceLevel.LOW);
+ } catch (Exception x) {
+ Verifier.log.Write ("fatal error", x.ToString (), ImportanceLevel.LOW);
+ }
+
+ return res;
+ }
+
+ }
+
+
+
+
+ public abstract class AbstractTypeCollection : SortedList {
+
+ private AssemblyLoader loader;
+
+ public AbstractTypeCollection ()
+ {
+ loader = new AssemblyLoader (new AssemblyLoader.Hook (LoaderHook));
+ }
+
+ public AbstractTypeCollection (string assemblyName) : this ()
+ {
+ LoadFrom (assemblyName);
+ }
+
+ public abstract void LoaderHook (TypeArray exports);
+
+
+ public bool LoadFrom (string assemblyName)
+ {
+ return loader.LoadFrom (assemblyName);
+ }
+
+ }
+
+
+
+ public class ClassCollection : AbstractTypeCollection {
+
+ public ClassCollection () : base ()
+ {
+ }
+
+ public ClassCollection (string assemblyName)
+ : base (assemblyName)
+ {
+ }
+
+
+ public override void LoaderHook (TypeArray exports)
+ {
+ foreach (Type type in exports.types) {
+ if (type.IsClass) {
+ this [type.FullName] = new ClassStuff (type);
+ }
+ }
+ }
+
+ }
+
+
+ public class InterfaceCollection : AbstractTypeCollection {
+
+ public InterfaceCollection () : base ()
+ {
+ }
+
+ public InterfaceCollection (string assemblyName)
+ : base (assemblyName)
+ {
+ }
+
+
+ public override void LoaderHook (TypeArray exports)
+ {
+ foreach (Type type in exports.types) {
+ if (type.IsInterface) {
+ this [type.FullName] = new InterfaceStuff (type);
+ }
+ }
+ }
+
+ }
+
+
+
+ public class AssemblyStuff {
+
+ public string name;
+ public bool valid;
+
+ public ClassCollection classes;
+ public InterfaceCollection interfaces;
+
+
+
+ protected delegate bool Comparer (AssemblyStuff asm1, AssemblyStuff asm2);
+ private static ArrayList comparers;
+
+ static AssemblyStuff ()
+ {
+ comparers = new ArrayList ();
+ comparers.Add (new Comparer (CompareNumClasses));
+ comparers.Add (new Comparer (CompareNumInterfaces));
+ comparers.Add (new Comparer (CompareClasses));
+ comparers.Add (new Comparer (CompareInterfaces));
+ }
+
+ protected static bool CompareNumClasses (AssemblyStuff asm1, AssemblyStuff asm2)
+ {
+ bool res = (asm1.classes.Count == asm2.classes.Count);
+ if (!res) Verifier.Log.Write ("error", "Number of classes mismatch.", ImportanceLevel.MEDIUM);
+ return res;
+ }
+
+ protected static bool CompareNumInterfaces (AssemblyStuff asm1, AssemblyStuff asm2)
+ {
+ bool res = (asm1.interfaces.Count == asm2.interfaces.Count);
+ if (!res) Verifier.Log.Write ("error", "Number of interfaces mismatch.", ImportanceLevel.MEDIUM);
+ return res;
+ }
+
+
+ protected static bool CompareClasses (AssemblyStuff asm1, AssemblyStuff asm2)
+ {
+ bool res = true;
+ bool ok;
+ Verifier.Log.Write ("info", "Comparing classes.");
+ foreach (DictionaryEntry c in asm1.classes) {
+ string className = c.Key as string;
+ Verifier.Log.Write ("class", className);
+
+ ClassStuff class1 = c.Value as ClassStuff;
+ ClassStuff class2 = asm2.classes [className] as ClassStuff;
+
+ if (class2 == null) {
+ Verifier.Log.Write ("error", String.Format ("There is no such class in {0}", asm2.name));
+ return false;
+ }
+
+ Verifier.Log.Write ("info", "Comparing public instance methods.", ImportanceLevel.LOW);
+ ok = (class1.publicMethods == class2.publicMethods);
+ res &= ok;
+ if (!ok && Verifier.stopOnError) return res;
+
+ Verifier.Log.Write ("info", "Comparing public static methods.", ImportanceLevel.LOW);
+ ok = (class1.publicStaticMethods == class2.publicStaticMethods);
+ res &= ok;
+ if (!ok && Verifier.stopOnError) return res;
+
+ Verifier.Log.Write ("info", "Comparing non-public instance methods.", ImportanceLevel.LOW);
+ ok = (class1.nonpublicMethods == class2.nonpublicMethods);
+ res &= ok;
+ if (!ok && Verifier.stopOnError) return res;
+
+ Verifier.Log.Write ("info", "Comparing non-public static methods.", ImportanceLevel.LOW);
+ ok = (class1.nonpublicStaticMethods == class2.nonpublicStaticMethods);
+ res &= ok;
+ if (!ok && Verifier.stopOnError) return res;
+
+ }
+ return res;
+ }
+
+
+ protected static bool CompareInterfaces (AssemblyStuff asm1, AssemblyStuff asm2)
+ {
+ bool res = true;
+ bool ok;
+ Verifier.Log.Write ("info", "Comparing interfaces.");
+ foreach (DictionaryEntry ifc in asm1.interfaces) {
+ string ifcName = ifc.Key as string;
+ Verifier.Log.Write ("interface", ifcName);
+
+ InterfaceStuff ifc1 = ifc.Value as InterfaceStuff;
+ InterfaceStuff ifc2 = asm2.interfaces [ifcName] as InterfaceStuff;
+
+ if (ifc2 == null) {
+ Verifier.Log.Write ("error", String.Format ("There is no such interface in {0}", asm2.name));
+ return false;
+ }
+
+ Verifier.Log.Write ("info", "Comparing interface methods.", ImportanceLevel.LOW);
+ ok = (ifc1.publicMethods == ifc2.publicMethods);
+ res &= ok;
+ if (!ok && Verifier.stopOnError) return res;
+ }
+ return res;
+ }
+
+
+
+ public AssemblyStuff (string assemblyName)
+ {
+ this.name = assemblyName;
+ valid = false;
+ }
+
+ public bool Load ()
+ {
+ bool res = true;
+ bool ok;
+
+ classes = new ClassCollection ();
+ ok = classes.LoadFrom (name);
+ res &= ok;
+ if (!ok) Verifier.log.Write ("error", String.Format ("Unable to load classes from {0}.", name), ImportanceLevel.HIGH);
+
+ interfaces = new InterfaceCollection ();
+ ok = interfaces.LoadFrom (name);
+ res &= ok;
+ if (!ok) Verifier.log.Write ("error", String.Format ("Unable to load interfaces from {0}.", name), ImportanceLevel.HIGH);
+
+ valid = res;
+ return res;
+ }
+
+
+ public override bool Equals (object o)
+ {
+ bool res = (o is AssemblyStuff);
+ if (res) {
+ AssemblyStuff that = o as AssemblyStuff;
+ IEnumerator it = comparers.GetEnumerator ();
+ while ((res || !Verifier.stopOnError) && it.MoveNext ()) {
+ Comparer compare = it.Current as Comparer;
+ res &= compare (this, that);
+ }
+ }
+ return res;
+ }
+
+
+ public static bool operator == (AssemblyStuff asm1, AssemblyStuff asm2)
+ {
+ return asm1.Equals (asm2);
+ }
+
+ public static bool operator != (AssemblyStuff asm1, AssemblyStuff asm2)
+ {
+ return !(asm1 == asm2);
+ }
+
+ public override int GetHashCode ()
+ {
+ return classes.GetHashCode () ^ interfaces.GetHashCode ();
+ }
+
+
+ public override string ToString ()
+ {
+ string res;
+ if (valid) {
+ res = String.Format ("Asssembly {0}, valid, {1} classes, {2} interfaces.",
+ name, classes.Count, interfaces.Count);
+ } else {
+ res = String.Format ("Asssembly {0}, invalid.", name);
+ }
+ return res;
+ }
+
+ }
+
+
+
+
+
+
+
+ ////////////////////////////////
+ // Compare
+ ////////////////////////////////
+
+ public sealed class Compare {
+
+ private Compare ()
+ {
+ }
+
+
+ public static bool Parameters (ParameterInfo[] params1, ParameterInfo[] params2)
+ {
+ bool res = true;
+ if (params1.Length != params2.Length) {
+ Verifier.Log.Write ("Parameter count mismatch.");
+ return false;
+ }
+
+ int count = params1.Length;
+
+ for (int i = 0; i < count && res; i++) {
+ if (params1 [i].Name != params2 [i].Name) {
+ Verifier.Log.Write ("error", String.Format ("Parameters names mismatch {0}, {1}.", params1 [i].Name, params2 [i].Name));
+ res = false;
+ if (Verifier.stopOnError) break;
+ }
+
+ Verifier.Log.Write ("parameter", params1 [i].Name);
+
+ if (params1 [i].ParameterType != params2 [i].ParameterType) {
+ Verifier.Log.Write ("error", String.Format ("Parameters types mismatch {0}, {1}.", params1 [i].ParameterType, params2 [i].ParameterType));
+ res = false;
+ if (Verifier.stopOnError) break;
+ }
+
+
+ if (Verifier.checkOptionalFlags) {
+ if (params1 [i].IsIn != params2 [i].IsIn) {
+ Verifier.Log.Write ("error", "[in] mismatch.");
+ res = false;
+ if (Verifier.stopOnError) break;
+ }
+
+ if (params1 [i].IsIn != params2 [i].IsIn) {
+ Verifier.Log.Write ("error", "[in] mismatch.");
+ res = false;
+ if (Verifier.stopOnError) break;
+ }
+
+ if (params1 [i].IsIn != params2 [i].IsIn) {
+ Verifier.Log.Write ("error", "[in] mismatch.");
+ res = false;
+ if (Verifier.stopOnError) break;
+ }
+
+ if (params1 [i].IsOut != params2 [i].IsOut) {
+ Verifier.Log.Write ("error", "[out] mismatch.");
+ res = false;
+ if (Verifier.stopOnError) break;
+ }
+
+ if (params1 [i].IsRetval != params2 [i].IsRetval) {
+ Verifier.Log.Write ("error", "[in] mismatch.");
+ res = false;
+ if (Verifier.stopOnError) break;
+ }
+
+ if (params1 [i].IsOptional != params2 [i].IsOptional) {
+ Verifier.Log.Write ("error", "Optional flag mismatch.");
+ res = false;
+ if (Verifier.stopOnError) break;
+ }
+
+ } // checkOptionalFlags
+
+
+ }
+
+ return res;
+ }
+
+
+
+ public static bool Methods (MethodInfo mi1, MethodInfo mi2)
+ {
+
+ if (mi2 == null) {
+ Verifier.Log.Write ("error", String.Format ("There is no such method {0}.", mi1.Name));
+ return false;
+ }
+
+ Verifier.Log.Write ("method", String.Format ("{0}.", mi1.Name));
+ bool res = true;
+ bool ok;
+
+ ok = mi1.ReturnType.Equals (mi2.ReturnType);
+ res &= ok;
+ if (!ok) {
+ Verifier.Log.Write ("error", "Return types mismatch.");
+ if (Verifier.stopOnError) return res;
+ }
+
+ ok = Compare.Parameters (mi1.GetParameters (), mi2.GetParameters ());
+ res &= ok;
+ if (!ok && Verifier.stopOnError) return res;
+
+ ok = (mi1.CallingConvention == mi2.CallingConvention);
+ res &= ok;
+ if (!ok) {
+ Verifier.Log.Write ("error", "Calling conventions mismatch.");
+ if (Verifier.stopOnError) return res;
+ }
+
+ return res;
+ }
+
+
+ public static bool Fields (FieldInfo fi1, FieldInfo fi2)
+ {
+ if (fi2 == null) {
+ Verifier.Log.Write ("error", String.Format ("There is no such field {0}.", fi1.Name));
+ return false;
+ }
+
+ bool res = true;
+ bool ok;
+
+ Verifier.Log.Write ("field", String.Format ("{0}.", fi1.Name));
+
+ ok = (fi1.IsPrivate == fi2.IsPrivate);
+ res &= ok;
+
+ return res;
+ }
+
+ }
+
+
+
+
+ ////////////////////////////////
+ // Log
+ ////////////////////////////////
+
+ public enum ImportanceLevel : int {
+ LOW = 0, MEDIUM, HIGH
+ }
+
+
+ public interface ILogger {
+
+ void Write (string tag, string msg, ImportanceLevel importance);
+ void Write (string msg, ImportanceLevel level);
+ void Write (string tag, string msg);
+ void Write (string msg);
+ ImportanceLevel DefaultImportance {get; set;}
+ void Flush ();
+ void Close ();
+ }
+
+
+ public abstract class AbstractLogger : ILogger {
+ private ImportanceLevel defImportance = ImportanceLevel.MEDIUM;
+
+ public abstract void Write (string tag, string msg, ImportanceLevel importance);
+ public abstract void Write (string msg, ImportanceLevel level);
+
+ public virtual void Write (string tag, string msg)
+ {
+ Write (tag, msg, DefaultImportance);
+ }
+
+ public virtual void Write (string msg)
+ {
+ Write (msg, DefaultImportance);
+ }
+
+ public virtual ImportanceLevel DefaultImportance {
+ get {
+ return defImportance;
+ }
+ set {
+ defImportance = value < ImportanceLevel.LOW
+ ? ImportanceLevel.LOW
+ : value > ImportanceLevel.HIGH
+ ? ImportanceLevel.HIGH
+ : value;
+ }
+ }
+
+ public abstract void Flush ();
+ public abstract void Close ();
+
+ }
+
+
+
+ public class TextLogger : AbstractLogger {
+
+ private TextWriter writer;
+
+ public TextLogger (TextWriter writer)
+ {
+ if (writer == null)
+ throw new NullReferenceException ();
+
+ this.writer = writer;
+ }
+
+ private void DoWrite (string tag, string msg)
+ {
+ if (tag != null && tag.Length > 0) {
+ writer.WriteLine ("[{0}]\t{1}", tag, msg);
+ } else {
+ writer.WriteLine ("\t\t" + msg);
+ }
+ }
+
+ public override void Write (string tag, string msg, ImportanceLevel importance)
+ {
+ int v = Log.VerboseLevel;
+ switch (v) {
+ case 0 :
+ break;
+ case 1 :
+ if (importance >= ImportanceLevel.HIGH) {
+ DoWrite (tag, msg);
+ }
+ break;
+ case 2 :
+ if (importance >= ImportanceLevel.MEDIUM) {
+ DoWrite (tag, msg);
+ }
+ break;
+ case 3 :
+ DoWrite (tag, msg);
+ break;
+ default:
+ break;
+ }
+ }
+
+ public override void Write (string msg, ImportanceLevel importance)
+ {
+ Write (null, msg, importance);
+ }
+
+ public override void Flush ()
+ {
+ Console.Out.Flush ();
+ }
+
+ public override void Close ()
+ {
+ if (writer != Console.Out && writer != Console.Error) {
+ writer.Close ();
+ }
+ }
+ }
+
+
+
+ public sealed class Log {
+
+ private static int verbose = 3;
+
+ private ArrayList consumers;
+
+ public Log (bool useDefault)
+ {
+ consumers = new ArrayList ();
+ if (useDefault) AddConsumer (new TextLogger (Console.Out));
+ }
+
+ public Log () : this (true)
+ {
+ }
+
+
+ public static int VerboseLevel {
+ get {
+ return verbose;
+ }
+ set {
+ verbose = (value < 0)
+ ? 0
+ : (value > 3)
+ ? 3 : value;
+ }
+ }
+
+ public void AddConsumer (ILogger consumer)
+ {
+ consumers.Add (consumer);
+ }
+
+
+ public void Write (string tag, string msg, ImportanceLevel importance)
+ {
+ foreach (ILogger logger in consumers) {
+ if (tag == null || tag == "") {
+ logger.Write (msg, importance);
+ } else {
+ logger.Write (tag, msg, importance);
+ }
+ }
+ }
+
+ public void Write (string msg, ImportanceLevel importance)
+ {
+ Write (null, msg, importance);
+ }
+
+
+ public void Write (string tag, string msg)
+ {
+ foreach (ILogger logger in consumers) {
+ if (tag == null || tag == "") {
+ logger.Write (msg);
+ } else {
+ logger.Write (tag, msg);
+ }
+ }
+ }
+
+ public void Write (string msg)
+ {
+ Write (null, msg);
+ }
+
+
+ public void Flush ()
+ {
+ foreach (ILogger logger in consumers) {
+ logger.Flush ();
+ }
+ }
+
+
+ public void Close ()
+ {
+ foreach (ILogger logger in consumers) {
+ logger.Flush ();
+ logger.Close ();
+ }
+ }
+
+ }
+
+
+
+
+
+ ////////////////////////////////
+ // Main
+ ////////////////////////////////
+
+ public class Verifier {
+
+ public static Log log = new Log ();
+ public static bool stopOnError = false;
+ public static bool checkOptionalFlags = true;
+
+
+ private Verifier ()
+ {
+ }
+
+ public static Log Log {
+ get {
+ return log;
+ }
+ }
+
+
+
+ public static void Main (String [] args) {
+ if (args.Length < 2) {
+ Console.WriteLine ("Usage: verifier asm1 asm2");
+ } else {
+ string name1 = args [0];
+ string name2 = args [1];
+
+ bool ok = false;
+
+ AssemblyStuff asm1 = new AssemblyStuff (name1);
+ AssemblyStuff asm2 = new AssemblyStuff (name2);
+ ok = asm1.Load ();
+ if (!ok) {
+ Console.WriteLine ("Unable to load assembly {0}.", name1);
+ Environment.Exit (-1);
+ }
+
+ ok = asm2.Load ();
+ if (!ok) {
+ Console.WriteLine ("Unable to load assembly {0}.", name2);
+ Environment.Exit (-1);
+ }
+
+ try {
+ ok = (asm1 == asm2);
+ } catch {
+ ok = false;
+ } finally {
+ Log.Close ();
+ }
+
+ if (!ok) {
+ Console.WriteLine ("--- not equal");
+ Environment.Exit (-1);
+ }
+ }
+ }
+
+ }
+
+}
+
diff --git a/mono/.cvsignore b/mono/.cvsignore
new file mode 100644
index 00000000000..282522db034
--- /dev/null
+++ b/mono/.cvsignore
@@ -0,0 +1,2 @@
+Makefile
+Makefile.in
diff --git a/mono/Makefile.am b/mono/Makefile.am
index 89d68d86d83..4e595711c97 100644
--- a/mono/Makefile.am
+++ b/mono/Makefile.am
@@ -1 +1 @@
-SUBDIRS = metadata dis \ No newline at end of file
+SUBDIRS = metadata cil dis interpreter wrapper
diff --git a/mono/arch/ChangeLog b/mono/arch/ChangeLog
new file mode 100644
index 00000000000..31eecbfec39
--- /dev/null
+++ b/mono/arch/ChangeLog
@@ -0,0 +1,10 @@
+
+Sat Aug 18 12:40:32 CEST 2001 Paolo Molaro <lupus@ximian.com>
+
+ * x86/x86-codegen.h: fix a couple of buglets and add x86_regp_emit().
+
+Wed Aug 8 15:30:05 CEST 2001 Paolo Molaro <lupus@ximian.com>
+
+ * x86/x86-codegen.h, x86/test.c: added x86 code emitter with
+ test.
+
diff --git a/mono/arch/x86/test.c b/mono/arch/x86/test.c
new file mode 100644
index 00000000000..231b7f665e7
--- /dev/null
+++ b/mono/arch/x86/test.c
@@ -0,0 +1,211 @@
+#include "x86-codegen.h"
+#include <stdio.h>
+
+/* don't run the resulting program, it will destroy your computer,
+ * just objdump -d it to inspect we generated the correct assembler.
+ */
+
+int main() {
+ unsigned char code [16000];
+ unsigned char *p = code;
+ unsigned char *target;
+ unsigned long mem_addr = 0xdeadbeef;
+ int size, i;
+
+ printf (".text\n.align 4\n.globl main\n.type main,@function\nmain:\n");
+
+ x86_prolog (p, 16, X86_CALLER_REGS);
+
+ x86_cmpxchg_reg_reg (p, X86_EAX, X86_EBP);
+ x86_cmpxchg_membase_reg (p, X86_EAX, 12, X86_EBP);
+
+ x86_xchg_reg_reg (p, X86_EAX, X86_EBP, 4);
+ x86_xchg_reg_reg (p, X86_EAX, X86_EBP, 1); // FIXME?
+ x86_xchg_membase_reg (p, X86_EAX, 12, X86_EBP, 4);
+ x86_xchg_membase_reg (p, X86_EAX, 12, X86_EBP, 2);
+ x86_xchg_membase_reg (p, X86_EAX, 12, X86_EBX, 1); // FIXME?
+
+ x86_inc_reg (p, X86_EAX);
+ x86_inc_mem (p, mem_addr);
+ x86_inc_membase (p, X86_ESP, 4);
+
+ x86_nop (p);
+ x86_nop (p);
+
+ x86_dec_reg (p, X86_EAX);
+ x86_dec_reg (p, X86_ECX);
+ x86_dec_mem (p, mem_addr);
+ x86_dec_membase (p, X86_ESP, 4);
+
+ x86_not_reg (p, X86_EDX);
+ x86_not_reg (p, X86_ECX);
+ x86_not_mem (p, mem_addr);
+ x86_not_membase (p, X86_ESP, 4);
+ x86_not_membase (p, X86_ESP, 0x4444444);
+ x86_not_membase (p, X86_EBP, 0x4444444);
+ x86_not_membase (p, X86_ECX, 0x4444444);
+ x86_not_membase (p, X86_EDX, 0);
+ x86_not_membase (p, X86_EBP, 0);
+
+ x86_neg_reg (p, X86_EAX);
+ x86_neg_reg (p, X86_ECX);
+ x86_neg_mem (p, mem_addr);
+ x86_neg_membase (p, X86_ESP, 8);
+
+ x86_alu_reg_imm (p, X86_ADD, X86_EAX, 5);
+ x86_alu_reg_imm (p, X86_ADD, X86_EBX, -10);
+ x86_alu_reg_imm (p, X86_SUB, X86_EDX, 7);
+ x86_alu_reg_imm (p, X86_OR, X86_ESP, 0xffffedaf);
+ x86_alu_reg_imm (p, X86_CMP, X86_ECX, 1);
+ x86_alu_mem_imm (p, X86_ADC, mem_addr, 2);
+ x86_alu_membase_imm (p, X86_ADC, X86_ESP, -4, 4);
+ x86_alu_membase_imm (p, X86_ADC, X86_ESP, -12, 0xffffedaf);
+
+ x86_alu_mem_reg (p, X86_SUB, mem_addr, X86_EDX);
+ x86_alu_reg_reg (p, X86_ADD, X86_EAX, X86_EBX);
+ x86_alu_reg_mem (p, X86_ADD, X86_EAX, mem_addr);
+ x86_alu_reg_imm (p, X86_ADD, X86_EAX, 0xdeadbeef);
+ x86_alu_reg_membase (p, X86_XOR, X86_EDX, X86_ESP, 4);
+ x86_alu_membase_reg (p, X86_XOR, X86_EBP, 8, X86_ESI);
+
+ x86_test_reg_imm (p, X86_EAX, 16);
+ x86_test_reg_imm (p, X86_EDX, -16);
+ x86_test_mem_imm (p, mem_addr, 1);
+ x86_test_membase_imm (p, X86_EBP, 8, 1);
+
+ x86_test_reg_reg (p, X86_EAX, X86_EDX);
+ x86_test_mem_reg (p, mem_addr, X86_EDX);
+ x86_test_membase_reg (p, X86_ESI, 4, X86_EDX);
+
+ x86_shift_reg_imm (p, X86_SHL, X86_EAX, 1);
+ x86_shift_reg_imm (p, X86_SHL, X86_EDX, 2);
+
+ x86_shift_mem_imm (p, X86_SHL, mem_addr, 2);
+ x86_shift_membase_imm (p, X86_SHLR, X86_EBP, 8, 4);
+
+ /*
+ * Shift by CL
+ */
+ x86_shift_reg (p, X86_SHL, X86_EAX);
+ x86_shift_mem (p, X86_SHL, mem_addr);
+
+ x86_mul_reg (p, X86_EAX, 0);
+ x86_mul_reg (p, X86_EAX, 1);
+ x86_mul_membase (p, X86_EBP, 8, 1);
+
+ x86_imul_reg_reg (p, X86_EBX, X86_EDX);
+ x86_imul_reg_membase (p, X86_EBX, X86_EBP, 12);
+
+ x86_imul_reg_reg_imm (p, X86_EBX, X86_EDX, 10);
+ x86_imul_reg_mem_imm (p, X86_EBX, mem_addr, 20);
+ x86_imul_reg_membase_imm (p, X86_EBX, X86_EBP, 16, 300);
+
+ x86_div_reg (p, X86_EDX, 0);
+ x86_div_reg (p, X86_EDX, 1);
+ x86_div_mem (p, mem_addr, 1);
+ x86_div_membase (p, X86_ESI, 4, 1);
+
+ x86_mov_mem_reg (p, mem_addr, X86_EAX, 4);
+ x86_mov_mem_reg (p, mem_addr, X86_EAX, 2);
+ x86_mov_mem_reg (p, mem_addr, X86_EAX, 1);
+ x86_mov_membase_reg (p, X86_EBP, 4, X86_EAX, 1);
+
+ x86_mov_reg_reg (p, X86_EAX, X86_EAX, 1);
+ x86_mov_reg_reg (p, X86_EAX, X86_EAX, 4);
+ x86_mov_reg_mem (p, X86_EAX, mem_addr, 4);
+
+ x86_mov_reg_imm (p, X86_EAX, 10);
+ x86_mov_mem_imm (p, mem_addr, 54, 4);
+ x86_mov_mem_imm (p, mem_addr, 54, 1);
+
+ x86_lea_mem (p, X86_EDX, mem_addr);
+ /* test widen */
+
+ x86_cdq (p);
+ x86_wait (p);
+
+ x86_fp_op_mem (p, X86_FADD, mem_addr, 1);
+ x86_fp_op_mem (p, X86_FSUB, mem_addr, 0);
+ x86_fp_op (p, X86_FSUB, 2);
+ x86_fp_op_reg (p, X86_FMUL, 1, 0);
+ x86_fstp (p, 2);
+ x86_fcompp (p);
+ x86_fnstsw (p);
+ x86_fnstcw (p, mem_addr);
+ x86_fnstcw_membase (p, X86_ESP, -8);
+
+ x86_fldcw_membase (p, X86_ESP, -8);
+ x86_fchs (p);
+ x86_frem (p);
+ x86_fxch (p, 3);
+ x86_fcomip (p, 3);
+ x86_fld_membase (p, X86_ESP, -8, 1);
+ x86_fld_membase (p, X86_ESP, -8, 0);
+ x86_fld80_membase (p, X86_ESP, -8);
+ x86_fild_membase (p, X86_ESP, -8, 1);
+ x86_fild_membase (p, X86_ESP, -8, 0);
+ x86_fld_reg (p, 4);
+ x86_fldz (p);
+ x86_fld1 (p);
+
+ x86_fst (p, mem_addr, 1, 0);
+ x86_fst (p, mem_addr, 1, 1);
+ x86_fst (p, mem_addr, 0, 1);
+
+ x86_fist_pop_membase (p, X86_EDX, 4, 1);
+ x86_fist_pop_membase (p, X86_EDX, 4, 0);
+
+ x86_push_reg (p, X86_EBX);
+ x86_push_membase (p, X86_EBP, 8);
+ x86_push_imm (p, -1);
+ x86_pop_reg (p, X86_EBX);
+
+ x86_pushad (p);
+ x86_pushfd (p);
+ x86_popfd (p);
+ x86_popad (p);
+
+ target = p;
+
+ x86_jump32 (p, mem_addr);
+ x86_jump8 (p, 12);
+ x86_jump_reg (p, X86_EAX);
+ x86_jump_membase (p, X86_EDX, 16);
+
+ x86_jump_code (p, target);
+
+ x86_branch8 (p, X86_CC_EQ, 54, 1);
+ x86_branch32 (p, X86_CC_LT, 54, 0);
+ x86_branch (p, X86_CC_GT, target, 0);
+ x86_branch_disp (p, X86_CC_NE, -4, 0);
+
+ x86_call_imm (p, printf);
+ x86_call_reg (p, X86_ECX);
+
+ x86_sahf (p);
+
+ x86_fsin (p);
+ x86_fcos (p);
+ x86_fabs (p);
+ x86_fpatan (p);
+ x86_fprem (p);
+ x86_fprem1 (p);
+ x86_frndint (p);
+ x86_fsqrt (p);
+ x86_fptan (p);
+
+ x86_leave (p);
+ x86_ret (p);
+ x86_ret_imm (p, 24);
+
+ x86_cmov_reg (p, X86_CC_GT, 1, X86_EAX, X86_EDX);
+ x86_cmov_membase (p, X86_CC_GT, 0, X86_EAX, X86_EDX, -4);
+
+ x86_nop (p);
+ x86_epilog (p, X86_CALLER_REGS);
+
+ size = p-code;
+ for (i = 0; i < size; ++i)
+ printf (".byte %d\n", (unsigned int) code [i]);
+ return 0;
+}
diff --git a/mono/arch/x86/x86-codegen.h b/mono/arch/x86/x86-codegen.h
new file mode 100644
index 00000000000..166030eb957
--- /dev/null
+++ b/mono/arch/x86/x86-codegen.h
@@ -0,0 +1,1238 @@
+/* Copyright (C) 2000 Intel Corporation. All rights reserved.
+ Copyright (C) 2001 Ximian, Inc.
+//
+// $Header: /home/miguel/third-conversion/public/mono/mono/arch/x86/x86-codegen.h,v 1.4 2001/08/18 06:55:29 lupus Exp $
+*/
+
+#ifndef X86_H
+#define X86_H
+#include <assert.h>
+/*
+// x86 register numbers
+*/
+typedef enum {
+ X86_EAX = 0,
+ X86_ECX = 1,
+ X86_EDX = 2,
+ X86_EBX = 3,
+ X86_ESP = 4,
+ X86_EBP = 5,
+ X86_ESI = 6,
+ X86_EDI = 7,
+ X86_NREG
+} X86_Reg_No;
+/*
+// opcodes for alu instructions
+*/
+typedef enum {
+ X86_ADD = 0,
+ X86_OR = 1,
+ X86_ADC = 2,
+ X86_SBB = 3,
+ X86_AND = 4,
+ X86_SUB = 5,
+ X86_XOR = 6,
+ X86_CMP = 7,
+ X86_NALU
+} X86_ALU_Opcode;
+/*
+// opcodes for shift instructions
+*/
+typedef enum {
+ X86_SHLD,
+ X86_SHLR,
+ X86_SHL = 4,
+ X86_SHR = 5,
+ X86_SAR = 7,
+ X86_NSHIFT = 8
+} X86_Shift_Opcode;
+/*
+// opcodes for floating-point instructions
+*/
+typedef enum {
+ X86_FADD = 0,
+ X86_FMUL = 1,
+ X86_FCOM = 2,
+ X86_FCOMP = 3,
+ X86_FSUB = 4,
+ X86_FSUBR = 5,
+ X86_FDIV = 6,
+ X86_FDIVR = 7,
+ X86_NFP = 8
+} X86_FP_Opcode;
+/*
+// integer conditions codes
+*/
+typedef enum {
+ X86_CC_EQ = 0,
+ X86_CC_NE,
+ X86_CC_LT,
+ X86_CC_LE,
+ X86_CC_GT,
+ X86_CC_GE,
+ X86_CC_LZ,
+ X86_CC_GEZ,
+ X86_CC_P,
+ X86_CC_NP,
+ X86_NCC
+} X86_CC;
+/*
+// prefix code
+*/
+typedef enum {
+ X86_LOCK_PREFIX = 0xF0,
+ X86_REPNZ_PREFIX = 0xF2,
+ X86_REPZ_PREFIX = 0xF3,
+ X86_REP_PREFIX = 0xF3,
+ X86_CS_PREFIX = 0x2E,
+ X86_SS_PREFIX = 0x36,
+ X86_DS_PREFIX = 0x3E,
+ X86_ES_PREFIX = 0x26,
+ X86_FS_PREFIX = 0x64,
+ X86_GS_PREFIX = 0x65,
+ X86_OPERAND_PREFIX = 0x66,
+ X86_ADDRESS_PREFIX = 0x67
+} X86_Prefix;
+
+static const unsigned char
+x86_cc_unsigned_map [X86_NCC] = {
+ 0x74, // eq
+ 0x75, // ne
+ 0x72, // lt
+ 0x76, // le
+ 0x77, // gt
+ 0x73, // ge
+ 0x78, // lz
+ 0x79, // gez
+ 0x7a, // p
+ 0x7b, // np
+};
+
+static const unsigned char
+x86_cc_signed_map [X86_NCC] = {
+ 0x74, // eq
+ 0x75, // ne
+ 0x7c, // lt
+ 0x7e, // le
+ 0x7f, // gt
+ 0x7d, // ge
+ 0x78, // lz
+ 0x79, // gez
+ 0x7a, // p
+ 0x7b, // np
+};
+
+typedef union {
+ int val;
+ unsigned char b [4];
+} x86_imm_buf;
+
+/*
+// bitvector mask for callee-saved registers
+*/
+#define X86_ESI_MASK (1<<X86_ESI)
+#define X86_EDI_MASK (1<<X86_EDI)
+#define X86_EBX_MASK (1<<X86_EBX)
+#define X86_EBP_MASK (1<<X86_EBP)
+
+#define X86_CALLEE_REGS ((1<<X86_EAX) | (1<<X86_ECX) | (1<<X86_EDX))
+#define X86_CALLER_REGS ((1<<X86_EBX) | (1<<X86_EBP) | (1<<X86_ESI) | (1<<X86_EDI))
+#define X86_BYTE_REGS ((1<<X86_EAX) | (1<<X86_ECX) | (1<<X86_EDX) | (1<<X86_EBX))
+
+#define X86_IS_SCRATCH(reg) (X86_CALLER_REGS & (1 << (reg))) /* X86_EAX, X86_ECX, or X86_EDX */
+#define X86_IS_CALLEE(reg) (X86_CALLEE_REGS & (1 << (reg))) /* X86_ESI, X86_EDI, X86_EBX, or X86_EBP */
+
+/*
+// Frame structure:
+//
+// +--------------------------------+
+// | in_arg[0] = var[0] |
+// | in_arg[1] = var[1] |
+// | . . . |
+// | in_arg[n_arg-1] = var[n_arg-1] |
+// +--------------------------------+
+// | return IP |
+// +--------------------------------+
+// | saved EBP | <-- frame pointer (EBP)
+// +--------------------------------+
+// | ... | n_extra
+// +--------------------------------+
+// | var[n_arg] |
+// | var[n_arg+1] | local variables area
+// | . . . |
+// | var[n_var-1] |
+// +--------------------------------+
+// | |
+// | |
+// | spill area | area for spilling mimic stack
+// | |
+// +--------------------------------|
+// | ebx |
+// | ebp [ESP_Frame only] |
+// | esi | 0..3 callee-saved regs
+// | edi | <-- stack pointer (ESP)
+// +--------------------------------+
+// | stk0 |
+// | stk1 | operand stack area/
+// | . . . | out args
+// | stkn-1 |
+// +--------------------------------|
+//
+//
+*/
+
+
+/*
+ * useful building blocks
+ */
+#define x86_address_byte(inst,m,o,r) do { *(inst)++ = ((((m)&0x03)<<6)|(((o)&0x07)<<3)|(((r)&0x07))); } while (0)
+#define x86_imm_emit32(inst,imm) \
+ do { \
+ x86_imm_buf imb; imb.val = (int) (imm); \
+ *(inst)++ = imb.b [0]; \
+ *(inst)++ = imb.b [1]; \
+ *(inst)++ = imb.b [2]; \
+ *(inst)++ = imb.b [3]; \
+ } while (0)
+#define x86_imm_emit16(inst,imm) do { *(short*)(inst) = (imm); (inst) += 2; } while (0)
+#define x86_imm_emit8(inst,imm) do { *(inst) = (unsigned char)((imm) & 0xff); ++(inst); } while (0)
+#define x86_is_imm8(imm) (((int)(imm) >= -128 && (int)(imm) <= 127))
+#define x86_is_imm16(imm) (((int)(imm) >= -(1<<16) && (int)(imm) <= ((1<<16)-1)))
+
+#define x86_reg_emit(inst,r,regno) do { x86_address_byte ((inst), 3, (r), (regno)); } while (0)
+#define x86_regp_emit(inst,r,regno) do { x86_address_byte ((inst), 0, (r), (regno)); } while (0)
+#define x86_mem_emit(inst,r,disp) do { x86_address_byte ((inst), 0, (r), 5); x86_imm_emit32((inst), (disp)); } while (0)
+
+#define x86_membase_emit(inst,r,basereg,disp) do {\
+ if ((basereg) == X86_ESP) { \
+ if ((disp) == 0) { \
+ x86_address_byte ((inst), 0, (r), X86_ESP); \
+ x86_address_byte ((inst), 0, X86_ESP, X86_ESP); \
+ } else if (x86_is_imm8((disp))) { \
+ x86_address_byte ((inst), 1, (r), X86_ESP); \
+ x86_address_byte ((inst), 0, X86_ESP, X86_ESP); \
+ x86_imm_emit8 ((inst), (disp)); \
+ } else { \
+ x86_address_byte ((inst), 2, (r), X86_ESP); \
+ x86_address_byte ((inst), 0, X86_ESP, X86_ESP); \
+ x86_imm_emit32 ((inst), (disp)); \
+ } \
+ break; \
+ } \
+ if ((disp) == 0 && (basereg) != X86_EBP) { \
+ x86_address_byte ((inst), 0, (r), (basereg)); \
+ break; \
+ } \
+ if (x86_is_imm8((disp))) { \
+ x86_address_byte ((inst), 1, (r), (basereg)); \
+ x86_imm_emit8 ((inst), (disp)); \
+ } else { \
+ x86_address_byte ((inst), 2, (r), (basereg)); \
+ x86_imm_emit32 ((inst), (disp)); \
+ } \
+ } while (0)
+
+/*
+ * TODO: memindex_emit
+ */
+
+#define x86_prefix(inst,p) do { *(inst)++ =(unsigned char) (p); } while (0)
+
+#define x86_cmpxchg_reg_reg(inst,dreg,reg) \
+ do { \
+ *(inst)++ = (unsigned char)0x0f; \
+ *(inst)++ = (unsigned char)0xb1; \
+ x86_reg_emit ((inst), (reg), (dreg)); \
+ } while (0)
+
+#define x86_cmpxchg_mem_reg(inst,mem,reg) \
+ do { \
+ *(inst)++ = (unsigned char)0x0f; \
+ *(inst)++ = (unsigned char)0xb1; \
+ x86_mem_emit ((inst), (reg), (mem)); \
+ } while (0)
+
+#define x86_cmpxchg_membase_reg(inst,basereg,disp,reg) \
+ do { \
+ *(inst)++ = (unsigned char)0x0f; \
+ *(inst)++ = (unsigned char)0xb1; \
+ x86_membase_emit ((inst), (reg), (basereg), (disp)); \
+ } while (0)
+
+#define x86_xchg_reg_reg(inst,dreg,reg,size) \
+ do { \
+ if ((size) == 1) \
+ *(inst)++ = (unsigned char)0x86; \
+ else \
+ *(inst)++ = (unsigned char)0x87; \
+ x86_reg_emit ((inst), (reg), (dreg)); \
+ } while (0)
+
+#define x86_xchg_mem_reg(inst,mem,reg,size) \
+ do { \
+ if ((size) == 1) \
+ *(inst)++ = (unsigned char)0x86; \
+ else \
+ *(inst)++ = (unsigned char)0x87; \
+ x86_mem_emit ((inst), (reg), (mem)); \
+ } while (0)
+
+#define x86_xchg_membase_reg(inst,basereg,disp,reg,size) \
+ do { \
+ if ((size) == 1) \
+ *(inst)++ = (unsigned char)0x86; \
+ else \
+ *(inst)++ = (unsigned char)0x87; \
+ x86_membase_emit ((inst), (reg), (basereg), (disp)); \
+ } while (0)
+
+#define x86_inc_mem(inst,mem) \
+ do { \
+ *(inst)++ = (unsigned char)0xff; \
+ x86_mem_emit ((inst), 0, (mem)); \
+ } while (0)
+
+#define x86_inc_membase(inst,basereg,disp) \
+ do { \
+ *(inst)++ = (unsigned char)0xff; \
+ x86_membase_emit ((inst), 0, (basereg), (disp)); \
+ } while (0)
+
+#define x86_inc_reg(inst,reg) do { *(inst)++ = (unsigned char)0x40 + (reg); } while (0)
+
+#define x86_dec_mem(inst,mem) \
+ do { \
+ *(inst)++ = (unsigned char)0xff; \
+ x86_mem_emit ((inst), 1, (mem)); \
+ } while (0)
+
+#define x86_dec_membase(inst,basereg,disp) \
+ do { \
+ *(inst)++ = (unsigned char)0xff; \
+ x86_membase_emit ((inst), 1, (basereg), (disp)); \
+ } while (0)
+
+#define x86_dec_reg(inst,reg) do { *(inst)++ = (unsigned char)0x48 + (reg); } while (0)
+
+#define x86_not_mem(inst,mem) \
+ do { \
+ *(inst)++ = (unsigned char)0xf7; \
+ x86_mem_emit ((inst), 2, (mem)); \
+ } while (0)
+
+#define x86_not_membase(inst,basereg,disp) \
+ do { \
+ *(inst)++ = (unsigned char)0xf7; \
+ x86_membase_emit ((inst), 2, (basereg), (disp)); \
+ } while (0)
+
+#define x86_not_reg(inst,reg) \
+ do { \
+ *(inst)++ = (unsigned char)0xf7; \
+ x86_reg_emit ((inst), 2, (reg)); \
+ } while (0)
+
+#define x86_neg_mem(inst,mem) \
+ do { \
+ *(inst)++ = (unsigned char)0xf7; \
+ x86_mem_emit ((inst), 3, (mem)); \
+ } while (0)
+
+#define x86_neg_membase(inst,basereg,disp) \
+ do { \
+ *(inst)++ = (unsigned char)0xf7; \
+ x86_membase_emit ((inst), 3, (basereg), (disp)); \
+ } while (0)
+
+#define x86_neg_reg(inst,reg) \
+ do { \
+ *(inst)++ = (unsigned char)0xf7; \
+ x86_reg_emit ((inst), 3, (reg)); \
+ } while (0)
+
+#define x86_nop(inst) do { *(inst)++ = (unsigned char)0x90; } while (0)
+
+#define x86_alu_reg_imm(inst,opc,reg,imm) \
+ do { \
+ if ((reg) == X86_EAX) { \
+ *(inst)++ = (((unsigned char)(opc)) << 3) + 5; \
+ x86_imm_emit32 ((inst), (imm)); \
+ break; \
+ } \
+ if (x86_is_imm8((imm))) { \
+ *(inst)++ = (unsigned char)0x83; \
+ x86_reg_emit ((inst), (opc), (reg)); \
+ x86_imm_emit8 ((inst), (imm)); \
+ } else { \
+ *(inst)++ = (unsigned char)0x81; \
+ x86_reg_emit ((inst), (opc), (reg)); \
+ x86_imm_emit32 ((inst), (imm)); \
+ } \
+ } while (0)
+
+#define x86_alu_mem_imm(inst,opc,mem,imm) \
+ do { \
+ if (x86_is_imm8((imm))) { \
+ *(inst)++ = (unsigned char)0x83; \
+ x86_mem_emit ((inst), (opc), (mem)); \
+ x86_imm_emit8 ((inst), (imm)); \
+ } else { \
+ *(inst)++ = (unsigned char)0x81; \
+ x86_mem_emit ((inst), (opc), (mem)); \
+ x86_imm_emit32 ((inst), (imm)); \
+ } \
+ } while (0)
+
+#define x86_alu_membase_imm(inst,opc,basereg,disp,imm) \
+ do { \
+ if (x86_is_imm8((imm))) { \
+ *(inst)++ = (unsigned char)0x83; \
+ x86_membase_emit ((inst), (opc), (basereg), (disp)); \
+ x86_imm_emit8 ((inst), (imm)); \
+ } else { \
+ *(inst)++ = (unsigned char)0x81; \
+ x86_membase_emit ((inst), (opc), (basereg), (disp)); \
+ x86_imm_emit32 ((inst), (imm)); \
+ } \
+ } while (0)
+
+#define x86_alu_mem_reg(inst,opc,mem,reg) \
+ do { \
+ *(inst)++ = (((unsigned char)(opc)) << 3) + 1; \
+ x86_mem_emit ((inst), (reg), (mem)); \
+ } while (0)
+
+#define x86_alu_membase_reg(inst,opc,basereg,disp,reg) \
+ do { \
+ *(inst)++ = (((unsigned char)(opc)) << 3) + 1; \
+ x86_membase_emit ((inst), (reg), (basereg), (disp)); \
+ } while (0)
+
+#define x86_alu_reg_reg(inst,opc,dreg,reg) \
+ do { \
+ *(inst)++ = (((unsigned char)(opc)) << 3) + 3; \
+ x86_reg_emit ((inst), (reg), (dreg)); \
+ } while (0)
+
+#define x86_alu_reg_mem(inst,opc,reg,mem) \
+ do { \
+ *(inst)++ = (((unsigned char)(opc)) << 3) + 3; \
+ x86_mem_emit ((inst), (reg), (mem)); \
+ } while (0)
+
+#define x86_alu_reg_membase(inst,opc,reg,basereg,disp) \
+ do { \
+ *(inst)++ = (((unsigned char)(opc)) << 3) + 3; \
+ x86_membase_emit ((inst), (reg), (basereg), (disp)); \
+ } while (0)
+
+#define x86_test_reg_imm(inst,reg,imm) \
+ do { \
+ if ((reg) == X86_EAX) { \
+ *(inst)++ = (unsigned char)0xa9; \
+ } else { \
+ *(inst)++ = (unsigned char)0xf7; \
+ x86_reg_emit ((inst), 0, (reg)); \
+ } \
+ x86_imm_emit32 ((inst), (imm)); \
+ } while (0)
+
+#define x86_test_mem_imm(inst,mem,imm) \
+ do { \
+ *(inst)++ = (unsigned char)0xf7; \
+ x86_mem_emit ((inst), 0, (mem)); \
+ x86_imm_emit32 ((inst), (imm)); \
+ } while (0)
+
+#define x86_test_membase_imm(inst,basereg,disp,imm) \
+ do { \
+ *(inst)++ = (unsigned char)0xf7; \
+ x86_membase_emit ((inst), 0, (basereg), (disp)); \
+ x86_imm_emit32 ((inst), (imm)); \
+ } while (0)
+
+#define x86_test_reg_reg(inst,dreg,reg) \
+ do { \
+ *(inst)++ = (unsigned char)0x85; \
+ x86_reg_emit ((inst), (reg), (dreg)); \
+ } while (0)
+
+#define x86_test_mem_reg(inst,mem,reg) \
+ do { \
+ *(inst)++ = (unsigned char)0x85; \
+ x86_mem_emit ((inst), (reg), (mem)); \
+ } while (0)
+
+#define x86_test_membase_reg(inst,basereg,disp,reg) \
+ do { \
+ *(inst)++ = (unsigned char)0x85; \
+ x86_membase_emit ((inst), (reg), (basereg), (disp)); \
+ } while (0)
+
+#define x86_shift_reg_imm(inst,opc,reg,imm) \
+ do { \
+ if ((imm) == 1) { \
+ *(inst)++ = (unsigned char)0xd1; \
+ x86_reg_emit ((inst), (opc), (reg)); \
+ } else { \
+ *(inst)++ = (unsigned char)0xc1; \
+ x86_reg_emit ((inst), (opc), (reg)); \
+ x86_imm_emit8 ((inst), (imm)); \
+ } \
+ } while (0)
+
+#define x86_shift_mem_imm(inst,opc,mem,imm) \
+ do { \
+ if ((imm) == 1) { \
+ *(inst)++ = (unsigned char)0xd1; \
+ x86_mem_emit ((inst), (opc), (mem)); \
+ } else { \
+ *(inst)++ = (unsigned char)0xc1; \
+ x86_mem_emit ((inst), (opc), (mem)); \
+ x86_imm_emit8 ((inst), (imm)); \
+ } \
+ } while (0)
+
+#define x86_shift_membase_imm(inst,opc,basereg,disp,imm) \
+ do { \
+ if ((imm) == 1) { \
+ *(inst)++ = (unsigned char)0xd1; \
+ x86_membase_emit ((inst), (opc), (basereg), (disp)); \
+ } else { \
+ *(inst)++ = (unsigned char)0xc1; \
+ x86_membase_emit ((inst), (opc), (basereg), (disp)); \
+ x86_imm_emit8 ((inst), (imm)); \
+ } \
+ } while (0)
+
+#define x86_shift_reg(inst,opc,reg) \
+ do { \
+ *(inst)++ = (unsigned char)0xd3; \
+ x86_reg_emit ((inst), (opc), (reg)); \
+ } while (0)
+
+#define x86_shift_mem(inst,opc,mem) \
+ do { \
+ *(inst)++ = (unsigned char)0xd3; \
+ x86_mem_emit ((inst), (opc), (mem)); \
+ } while (0)
+
+#define x86_shift_membase(inst,opc,basereg,disp) \
+ do { \
+ *(inst)++ = (unsigned char)0xd3; \
+ x86_membase_emit ((inst), (opc), (basereg), (disp)); \
+ } while (0)
+
+/*
+ * Multi op shift missing.
+ */
+
+/*
+ * EDX:EAX = EAX * rm
+ */
+#define x86_mul_reg(inst,reg,is_signed) \
+ do { \
+ *(inst)++ = (unsigned char)0xf7; \
+ x86_reg_emit ((inst), 4 + ((is_signed) ? 1 : 0), (reg)); \
+ } while (0)
+
+#define x86_mul_mem(inst,mem,is_signed) \
+ do { \
+ *(inst)++ = (unsigned char)0xf7; \
+ x86_mem_emit ((inst), 4 + ((is_signed) ? 1 : 0), (mem)); \
+ } while (0)
+
+#define x86_mul_membase(inst,basereg,disp,is_signed) \
+ do { \
+ *(inst)++ = (unsigned char)0xf7; \
+ x86_membase_emit ((inst), 4 + ((is_signed) ? 1 : 0), (basereg), (disp)); \
+ } while (0)
+
+/*
+ * r *= rm
+ */
+#define x86_imul_reg_reg(inst,dreg,reg) \
+ do { \
+ *(inst)++ = (unsigned char)0x0f; \
+ *(inst)++ = (unsigned char)0xaf; \
+ x86_reg_emit ((inst), (dreg), (reg)); \
+ } while (0)
+
+#define x86_imul_reg_mem(inst,reg,mem) \
+ do { \
+ *(inst)++ = (unsigned char)0x0f; \
+ *(inst)++ = (unsigned char)0xaf; \
+ x86_mem_emit ((inst), (reg), (mem)); \
+ } while (0)
+
+#define x86_imul_reg_membase(inst,reg,basereg,disp) \
+ do { \
+ *(inst)++ = (unsigned char)0x0f; \
+ *(inst)++ = (unsigned char)0xaf; \
+ x86_membase_emit ((inst), (reg), (basereg), (disp)); \
+ } while (0)
+
+/*
+ * dreg = rm * imm
+ */
+#define x86_imul_reg_reg_imm(inst,dreg,reg,imm) \
+ do { \
+ if (x86_is_imm8 ((imm))) { \
+ *(inst)++ = (unsigned char)0x6b; \
+ x86_reg_emit ((inst), (dreg), (reg)); \
+ x86_imm_emit8 ((inst), (imm)); \
+ } else { \
+ *(inst)++ = (unsigned char)0x69; \
+ x86_reg_emit ((inst), (dreg), (reg)); \
+ x86_imm_emit32 ((inst), (imm)); \
+ } \
+ } while (0)
+
+#define x86_imul_reg_mem_imm(inst,reg,mem,imm) \
+ do { \
+ if (x86_is_imm8 ((imm))) { \
+ *(inst)++ = (unsigned char)0x6b; \
+ x86_mem_emit ((inst), (reg), (mem)); \
+ x86_imm_emit8 ((inst), (imm)); \
+ } else { \
+ *(inst)++ = (unsigned char)0x69; \
+ x86_reg_emit ((inst), (reg), (mem)); \
+ x86_imm_emit32 ((inst), (imm)); \
+ } \
+ } while (0)
+
+#define x86_imul_reg_membase_imm(inst,reg,basereg,disp,imm) \
+ do { \
+ if (x86_is_imm8 ((imm))) { \
+ *(inst)++ = (unsigned char)0x6b; \
+ x86_membase_emit ((inst), (reg), (basereg), (disp)); \
+ x86_imm_emit8 ((inst), (imm)); \
+ } else { \
+ *(inst)++ = (unsigned char)0x69; \
+ x86_membase_emit ((inst), (reg), (basereg), (disp)); \
+ x86_imm_emit32 ((inst), (imm)); \
+ } \
+ } while (0)
+
+/*
+ * divide EDX:EAX by rm;
+ * eax = quotient, edx = remainder
+ */
+
+#define x86_div_reg(inst,reg,is_signed) \
+ do { \
+ *(inst)++ = (unsigned char)0xf7; \
+ x86_reg_emit ((inst), 6 + ((is_signed) ? 1 : 0), (reg)); \
+ } while (0)
+
+#define x86_div_mem(inst,mem,is_signed) \
+ do { \
+ *(inst)++ = (unsigned char)0xf7; \
+ x86_mem_emit ((inst), 6 + ((is_signed) ? 1 : 0), (mem)); \
+ } while (0)
+
+#define x86_div_membase(inst,basereg,disp,is_signed) \
+ do { \
+ *(inst)++ = (unsigned char)0xf7; \
+ x86_membase_emit ((inst), 6 + ((is_signed) ? 1 : 0), (basereg), (disp)); \
+ } while (0)
+
+#define x86_mov_mem_reg(inst,mem,reg,size) \
+ do { \
+ switch ((size)) { \
+ case 1: *(inst)++ = (unsigned char)0x88; break; \
+ case 2: *(inst)++ = (unsigned char)0x66; /* fall through */ \
+ case 4: *(inst)++ = (unsigned char)0x89; break; \
+ default: assert (0); \
+ } \
+ x86_mem_emit ((inst), (reg), (mem)); \
+ } while (0)
+
+#define x86_mov_membase_reg(inst,basereg,disp,reg,size) \
+ do { \
+ switch ((size)) { \
+ case 1: *(inst)++ = (unsigned char)0x88; break; \
+ case 2: *(inst)++ = (unsigned char)0x66; /* fall through */ \
+ case 4: *(inst)++ = (unsigned char)0x89; break; \
+ default: assert (0); \
+ } \
+ x86_membase_emit ((inst), (reg), (basereg), (disp)); \
+ } while (0)
+
+#define x86_mov_reg_reg(inst,dreg,reg,size) \
+ do { \
+ switch ((size)) { \
+ case 1: *(inst)++ = (unsigned char)0x8a; break; \
+ case 2: *(inst)++ = (unsigned char)0x66; /* fall through */ \
+ case 4: *(inst)++ = (unsigned char)0x8b; break; \
+ default: assert (0); \
+ } \
+ x86_reg_emit ((inst), (dreg), (reg)); \
+ } while (0)
+
+#define x86_mov_reg_mem(inst,reg,mem,size) \
+ do { \
+ switch ((size)) { \
+ case 1: *(inst)++ = (unsigned char)0x8a; break; \
+ case 2: *(inst)++ = (unsigned char)0x66; /* fall through */ \
+ case 4: *(inst)++ = (unsigned char)0x8b; break; \
+ default: assert (0); \
+ } \
+ x86_mem_emit ((inst), (reg), (mem)); \
+ } while (0)
+
+#define x86_mov_reg_membase(inst,reg,basereg,disp,size) \
+ do { \
+ switch ((size)) { \
+ case 1: *(inst)++ = (unsigned char)0x8a; break; \
+ case 2: *(inst)++ = (unsigned char)0x66; /* fall through */ \
+ case 4: *(inst)++ = (unsigned char)0x8b; break; \
+ default: assert (0); \
+ } \
+ x86_membase_emit ((inst), (reg), (basereg), (disp)); \
+ } while (0)
+
+#define x86_mov_reg_imm(inst,reg,imm) \
+ do { \
+ if ((imm) == 0) { \
+ x86_alu_reg_reg ((inst), X86_XOR, (reg), (reg)); \
+ } else { \
+ *(inst)++ = (unsigned char)0xb8 + (reg); \
+ x86_imm_emit32 ((inst), (imm)); \
+ } \
+ } while (0)
+
+#define x86_mov_mem_imm(inst,mem,imm,size) \
+ do { \
+ if ((size) == 1) { \
+ *(inst)++ = (unsigned char)0xc6; \
+ x86_mem_emit ((inst), 0, (mem)); \
+ x86_imm_emit8 ((inst), (imm)); \
+ } else if ((size) == 4) { \
+ *(inst)++ = (unsigned char)0x66; \
+ *(inst)++ = (unsigned char)0xc7; \
+ x86_mem_emit ((inst), 0, (mem)); \
+ x86_imm_emit16 ((inst), (imm)); \
+ } else { \
+ *(inst)++ = (unsigned char)0xc7; \
+ x86_mem_emit ((inst), 0, (mem)); \
+ x86_imm_emit32 ((inst), (imm)); \
+ } \
+ } while (0)
+
+#define x86_lea_mem(inst,reg,mem) \
+ do { \
+ *(inst)++ = (unsigned char)0x8d; \
+ x86_mem_emit ((inst), (reg), (mem)); \
+ } while (0)
+
+#define x86_lea_membase(inst,reg,basereg,disp) \
+ do { \
+ *(inst)++ = (unsigned char)0x8d; \
+ x86_membase_emit ((inst), (reg), (basereg), (disp)); \
+ } while (0)
+
+#define x86_widen_reg(inst,dreg,reg,is_signed,is_half) \
+ do { \
+ unsigned char op = 0xb6; \
+ *(inst)++ = (unsigned char)0x0f; \
+ if ((is_signed)) op += 0x08; \
+ if ((is_half)) op += 0x01; \
+ *(inst)++ = op; \
+ x86_reg_emit ((inst), (dreg), (reg)); \
+ } while (0)
+
+#define x86_widen_mem(inst,dreg,mem,is_signed,is_half) \
+ do { \
+ unsigned char op = 0xb6; \
+ *(inst)++ = (unsigned char)0x0f; \
+ if ((is_signed)) op += 0x08; \
+ if ((is_half)) op += 0x01; \
+ *(inst)++ = op; \
+ x86_mem_emit ((inst), (reg), (mem)); \
+ } while (0)
+
+#define x86_widen_membase(inst,dreg,basereg,disp,is_signed,is_half) \
+ do { \
+ unsigned char op = 0xb6; \
+ *(inst)++ = (unsigned char)0x0f; \
+ if ((is_signed)) op += 0x08; \
+ if ((is_half)) op += 0x01; \
+ *(inst)++ = op; \
+ x86_membase_emit ((inst), (reg), (basereg), (disp)); \
+ } while (0)
+
+#define x86_cdq(inst) do { *(inst)++ = (unsigned char)0x99; } while (0)
+#define x86_wait(inst) do { *(inst)++ = (unsigned char)0x9b; } while (0)
+
+#define x86_fp_op_mem(inst,opc,mem,is_double) \
+ do { \
+ *(inst)++ = (is_double) ? (unsigned char)0xdc : (unsigned char)0xd8; \
+ x86_mem_emit ((inst), (opc), (mem)); \
+ } while (0)
+
+#define x86_fp_op(inst,opc,index) \
+ do { \
+ *(inst)++ = (unsigned char)0xd8; \
+ *(inst)++ = (unsigned char)0xc0+((opc)<<3)+((index)&0x07); \
+ } while (0)
+
+#define x86_fp_op_reg(inst,opc,index,pop_stack) \
+ do { \
+ static const unsigned char map[] = { 0, 1, 2, 3, 5, 4, 7, 6, 8}; \
+ *(inst)++ = (pop_stack) ? (unsigned char)0xde : (unsigned char)0xdc; \
+ *(inst)++ = (unsigned char)0xc0+(map[(opc)]<<3)+((index)&0x07); \
+ } while (0)
+
+#define x86_fstp(inst,index) \
+ do { \
+ *(inst)++ = (unsigned char)0xdd; \
+ *(inst)++ = (unsigned char)0xd8+(index); \
+ } while (0)
+
+#define x86_fcompp(inst) \
+ do { \
+ *(inst)++ = (unsigned char)0xde; \
+ *(inst)++ = (unsigned char)0xd9; \
+ } while (0)
+
+#define x86_fnstsw(inst) \
+ do { \
+ *(inst)++ = (unsigned char)0xdf; \
+ *(inst)++ = (unsigned char)0xe0; \
+ } while (0)
+
+#define x86_fnstcw(inst,mem) \
+ do { \
+ *(inst)++ = (unsigned char)0xd9; \
+ x86_mem_emit ((inst), 7, (mem)); \
+ } while (0)
+
+#define x86_fnstcw_membase(inst,basereg,disp) \
+ do { \
+ *(inst)++ = (unsigned char)0xd9; \
+ x86_membase_emit ((inst), 7, (basereg), (disp)); \
+ } while (0)
+
+#define x86_fldcw(inst,mem) \
+ do { \
+ *(inst)++ = (unsigned char)0xd9; \
+ x86_mem_emit ((inst), 5, (mem)); \
+ } while (0)
+
+#define x86_fldcw_membase(inst,basereg,disp) \
+ do { \
+ *(inst)++ = (unsigned char)0xd9; \
+ x86_membase_emit ((inst), 5, (basereg), (disp)); \
+ } while (0)
+
+#define x86_fchs(inst) \
+ do { \
+ *(inst)++ = (unsigned char)0xd9; \
+ *(inst)++ = (unsigned char)0xe0; \
+ } while (0)
+
+#define x86_frem(inst) \
+ do { \
+ *(inst)++ = (unsigned char)0xd9; \
+ *(inst)++ = (unsigned char)0xf8; \
+ } while (0)
+
+#define x86_fxch(inst,index) \
+ do { \
+ *(inst)++ = (unsigned char)0xd9; \
+ *(inst)++ = (unsigned char)0xc8 + ((index) & 0x07); \
+ } while (0)
+
+#define x86_fcomip(inst,index) \
+ do { \
+ *(inst)++ = (unsigned char)0xdf; \
+ *(inst)++ = (unsigned char)0xf0 + ((index) & 0x07); \
+ } while (0)
+
+#define x86_fld(inst,mem,is_double) \
+ do { \
+ *(inst)++ = (is_double) ? (unsigned char)0xdd : (unsigned char)0xd9; \
+ x86_mem_emit ((inst), 0, (mem)); \
+ } while (0)
+
+#define x86_fld_membase(inst,basereg,disp,is_double) \
+ do { \
+ *(inst)++ = (is_double) ? (unsigned char)0xdd : (unsigned char)0xd9; \
+ x86_membase_emit ((inst), 0, (basereg), (disp)); \
+ } while (0)
+
+#define x86_fld80(inst,mem) \
+ do { \
+ *(inst)++ = (unsigned char)0xdb; \
+ x86_mem_emit ((inst), 5, (mem)); \
+ } while (0)
+
+#define x86_fld80_membase(inst,basereg,disp) \
+ do { \
+ *(inst)++ = (unsigned char)0xdb; \
+ x86_membase_emit ((inst), 5, (basereg), (disp)); \
+ } while (0)
+
+#define x86_fild(inst,mem,is_long) \
+ do { \
+ if ((is_long)) { \
+ *(inst)++ = (unsigned char)0xdf; \
+ x86_mem_emit ((inst), 5, (mem)); \
+ } else { \
+ *(inst)++ = (unsigned char)0xdb; \
+ x86_mem_emit ((inst), 0, (mem)); \
+ } \
+ } while (0)
+
+#define x86_fild_membase(inst,basereg,disp,is_long) \
+ do { \
+ if ((is_long)) { \
+ *(inst)++ = (unsigned char)0xdf; \
+ x86_membase_emit ((inst), 5, (basereg), (disp)); \
+ } else { \
+ *(inst)++ = (unsigned char)0xdb; \
+ x86_membase_emit ((inst), 0, (basereg), (disp)); \
+ } \
+ } while (0)
+
+#define x86_fld_reg(inst,index) \
+ do { \
+ *(inst)++ = (unsigned char)0xd9; \
+ *(inst)++ = (unsigned char)0xc0 + ((index) & 0x07); \
+ } while (0)
+
+#define x86_fldz(inst) \
+ do { \
+ *(inst)++ = (unsigned char)0xd9; \
+ *(inst)++ = (unsigned char)0xee; \
+ } while (0)
+
+#define x86_fld1(inst) \
+ do { \
+ *(inst)++ = (unsigned char)0xd9; \
+ *(inst)++ = (unsigned char)0xe8; \
+ } while (0)
+
+#define x86_fst(inst,mem,is_double,pop_stack) \
+ do { \
+ *(inst)++ = (is_double) ? (unsigned char)0xdd: (unsigned char)0xd9; \
+ x86_mem_emit ((inst), 2 + ((pop_stack) ? 1 : 0), (mem)); \
+ } while (0)
+
+#define x86_fst_membase(inst,basereg,disp,is_double,pop_stack) \
+ do { \
+ *(inst)++ = (is_double) ? (unsigned char)0xdd: (unsigned char)0xd9; \
+ x86_membase_emit ((inst), 2 + ((pop_stack) ? 1 : 0), (basereg), (disp)); \
+ } while (0)
+
+#define x86_fist_pop(inst,mem,is_long) \
+ do { \
+ if ((is_long)) { \
+ *(inst)++ = (unsigned char)0xdf; \
+ x86_mem_emit ((inst), 7, (mem)); \
+ } else { \
+ *(inst)++ = (unsigned char)0xdb; \
+ x86_mem_emit ((inst), 3, (mem)); \
+ } \
+ } while (0)
+
+#define x86_fist_pop_membase(inst,basereg,disp,is_long) \
+ do { \
+ if ((is_long)) { \
+ *(inst)++ = (unsigned char)0xdf; \
+ x86_membase_emit ((inst), 7, (basereg), (disp)); \
+ } else { \
+ *(inst)++ = (unsigned char)0xdb; \
+ x86_membase_emit ((inst), 3, (basereg), (disp)); \
+ } \
+ } while (0)
+
+#define x86_push_reg(inst,reg) \
+ do { \
+ *(inst)++ = (unsigned char)0x50 + (reg); \
+ } while (0)
+
+#define x86_push_regp(inst,reg) \
+ do { \
+ *(inst)++ = (unsigned char)0xff; \
+ x86_regp_emit ((inst), 6, (reg)); \
+ } while (0)
+
+#define x86_push_mem(inst,mem) \
+ do { \
+ *(inst)++ = (unsigned char)0xff; \
+ x86_mem_emit ((inst), 6, (mem)); \
+ } while (0)
+
+#define x86_push_membase(inst,basereg,disp) \
+ do { \
+ *(inst)++ = (unsigned char)0xff; \
+ x86_membase_emit ((inst), 6, (basereg), (disp)); \
+ } while (0)
+
+#define x86_push_imm(inst,imm) \
+ do { \
+ *(inst)++ = (unsigned char)0x68; \
+ x86_imm_emit32 ((inst), (imm)); \
+ } while (0)
+
+#define x86_pop_reg(inst,reg) \
+ do { \
+ *(inst)++ = (unsigned char)0x58 + (reg); \
+ } while (0)
+
+#define x86_pop_mem(inst,mem) \
+ do { \
+ *(inst)++ = (unsigned char)0x87; \
+ x86_mem_emit ((inst), 0, (mem)); \
+ } while (0)
+
+#define x86_pop_membase(inst,basereg,disp) \
+ do { \
+ *(inst)++ = (unsigned char)0x87; \
+ x86_membase_emit ((inst), 0, (basereg), (disp)); \
+ } while (0)
+
+#define x86_pushad(inst) do { *(inst)++ = (unsigned char)0x60; } while (0)
+#define x86_pushfd(inst) do { *(inst)++ = (unsigned char)0x9c; } while (0)
+#define x86_popad(inst) do { *(inst)++ = (unsigned char)0x61; } while (0)
+#define x86_popfd(inst) do { *(inst)++ = (unsigned char)0x9d; } while (0)
+
+#define x86_jump32(inst,imm) \
+ do { \
+ *(inst)++ = (unsigned char)0xe9; \
+ x86_imm_emit32 ((inst), (imm)); \
+ } while (0)
+
+#define x86_jump8(inst,imm) \
+ do { \
+ *(inst)++ = (unsigned char)0xeb; \
+ x86_imm_emit8 ((inst), (imm)); \
+ } while (0)
+
+#define x86_jump_reg(inst,reg) \
+ do { \
+ *(inst)++ = (unsigned char)0xff; \
+ x86_reg_emit ((inst), 4, (reg)); \
+ } while (0)
+
+#define x86_jump_mem(inst,mem) \
+ do { \
+ *(inst)++ = (unsigned char)0xff; \
+ x86_mem_emit ((inst), 4, (mem)); \
+ } while (0)
+
+#define x86_jump_membase(inst,basereg,disp) \
+ do { \
+ *(inst)++ = (unsigned char)0xff; \
+ x86_membase_emit ((inst), 4, (basereg), (disp)); \
+ } while (0)
+
+/*
+ * target is a pointer in our buffer.
+ */
+#define x86_jump_code(inst,target) \
+ do { \
+ int t = (target) - (inst) - 2; \
+ if (x86_is_imm8(t)) { \
+ x86_jump8 ((inst), t); \
+ } else { \
+ t -= 3; \
+ x86_jump32 ((inst), t); \
+ } \
+ } while (0)
+
+#define x86_jump_disp(inst,disp) \
+ do { \
+ int t = (disp) - 2; \
+ if (x86_is_imm8(t)) { \
+ x86_jump8 ((inst), t); \
+ } else { \
+ t -= 3; \
+ x86_jump32 ((inst), t); \
+ } \
+ } while (0)
+
+#define x86_branch8(inst,cond,imm,is_signed) \
+ do { \
+ if ((is_signed)) \
+ *(inst)++ = x86_cc_signed_map [(cond)]; \
+ else \
+ *(inst)++ = x86_cc_unsigned_map [(cond)]; \
+ x86_imm_emit8 ((inst), (imm)); \
+ } while (0)
+
+#define x86_branch32(inst,cond,imm,is_signed) \
+ do { \
+ *(inst)++ = (unsigned char)0x0f; \
+ if ((is_signed)) \
+ *(inst)++ = x86_cc_signed_map [(cond)] + 0x10; \
+ else \
+ *(inst)++ = x86_cc_unsigned_map [(cond)] + 0x10; \
+ x86_imm_emit32 ((inst), (imm)); \
+ } while (0)
+
+#define x86_branch(inst,cond,target,is_signed) \
+ do { \
+ int offset = (target) - (inst) - 2; \
+ if (x86_is_imm8 ((offset))) \
+ x86_branch8 ((inst), (cond), offset, (is_signed)); \
+ else { \
+ offset -= 4; \
+ x86_branch32 ((inst), (cond), offset, (is_signed)); \
+ } \
+ } while (0)
+
+#define x86_branch_disp(inst,cond,disp,is_signed) \
+ do { \
+ int offset = (disp) - 2; \
+ if (x86_is_imm8 ((offset))) \
+ x86_branch8 ((inst), (cond), offset, (is_signed)); \
+ else { \
+ offset -= 4; \
+ x86_branch32 ((inst), (cond), offset, (is_signed)); \
+ } \
+ } while (0)
+
+#define x86_call_imm(inst,disp) \
+ do { \
+ *(inst)++ = (unsigned char)0xe8; \
+ x86_imm_emit32 ((inst), (int)(disp)); \
+ } while (0)
+
+#define x86_call_reg(inst,reg) \
+ do { \
+ *(inst)++ = (unsigned char)0xff; \
+ x86_reg_emit ((inst), 2, (reg)); \
+ } while (0)
+
+#define x86_call_mem(inst,mem) \
+ do { \
+ *(inst)++ = (unsigned char)0xff; \
+ x86_mem_emit ((inst), 2, (mem)); \
+ } while (0)
+
+#define x86_call_membase(inst,basereg,disp) \
+ do { \
+ *(inst)++ = (unsigned char)0xff; \
+ x86_membase_emit ((inst), 2, (basereg), (disp)); \
+ } while (0)
+
+#define x86_call_code(inst,target) \
+ do { \
+ int offset = (target) - (inst); \
+ offset -= 5 \
+ x86_call_imm ((inst), offset); \
+ } while (0)
+
+#define x86_ret(inst) do { *(inst)++ = (unsigned char)0xc3; } while (0)
+
+#define x86_ret_imm(inst,imm) \
+ do { \
+ if ((imm) == 0) { \
+ x86_ret ((inst)); \
+ } else { \
+ *(inst)++ = (unsigned char)0xc2; \
+ x86_imm_emit16 ((inst), (imm)); \
+ } \
+ } while (0)
+
+#define x86_cmov_reg(inst,cond,is_signed,dreg,reg) \
+ do { \
+ *(inst)++ = (unsigned char) 0x0f; \
+ if ((is_signed)) \
+ *(inst)++ = x86_cc_signed_map [(cond)] - 0x30; \
+ else \
+ *(inst)++ = x86_cc_unsigned_map [(cond)] - 0x30; \
+ x86_reg_emit ((inst), (dreg), (reg)); \
+ } while (0)
+
+#define x86_cmov_mem(inst,cond,is_signed,reg,mem) \
+ do { \
+ *(inst)++ = (unsigned char) 0x0f; \
+ if ((is_signed)) \
+ *(inst)++ = x86_cc_signed_map [(cond)] - 0x30; \
+ else \
+ *(inst)++ = x86_cc_unsigned_map [(cond)] - 0x30; \
+ x86_mem_emit ((inst), (reg), (mem)); \
+ } while (0)
+
+#define x86_cmov_membase(inst,cond,is_signed,reg,basereg,disp) \
+ do { \
+ *(inst)++ = (unsigned char) 0x0f; \
+ if ((is_signed)) \
+ *(inst)++ = x86_cc_signed_map [(cond)] - 0x30; \
+ else \
+ *(inst)++ = x86_cc_unsigned_map [(cond)] - 0x30; \
+ x86_membase_emit ((inst), (reg), (basereg), (disp)); \
+ } while (0)
+
+#define x86_enter(inst,framesize) \
+ do { \
+ *(inst)++ = (unsigned char)0xc8; \
+ x86_imm_emit16 ((inst), (framesize)); \
+ *(inst)++ = 0; \
+ } while (0)
+
+#define x86_leave(inst) do { *(inst)++ = (unsigned char)0xc9; } while (0)
+#define x86_sahf(inst) do { *(inst)++ = (unsigned char)0x9e; } while (0)
+
+#define x86_fsin(inst) do { *(inst)++ = (unsigned char)0xd9; *(inst)++ = (unsigned char)0xfe; } while (0)
+#define x86_fcos(inst) do { *(inst)++ = (unsigned char)0xd9; *(inst)++ = (unsigned char)0xff; } while (0)
+#define x86_fabs(inst) do { *(inst)++ = (unsigned char)0xd9; *(inst)++ = (unsigned char)0xe1; } while (0)
+#define x86_fpatan(inst) do { *(inst)++ = (unsigned char)0xd9; *(inst)++ = (unsigned char)0xf3; } while (0)
+#define x86_fprem(inst) do { *(inst)++ = (unsigned char)0xd9; *(inst)++ = (unsigned char)0xf8; } while (0)
+#define x86_fprem1(inst) do { *(inst)++ = (unsigned char)0xd9; *(inst)++ = (unsigned char)0xf5; } while (0)
+#define x86_frndint(inst) do { *(inst)++ = (unsigned char)0xd9; *(inst)++ = (unsigned char)0xfc; } while (0)
+#define x86_fsqrt(inst) do { *(inst)++ = (unsigned char)0xd9; *(inst)++ = (unsigned char)0xfa; } while (0)
+#define x86_fptan(inst) do { *(inst)++ = (unsigned char)0xd9; *(inst)++ = (unsigned char)0xf2; } while (0)
+
+#define x86_padding(inst,size) \
+ do { \
+ switch ((size)) { \
+ case 1: x86_nop ((inst)); break; \
+ case 2: *(inst)++ = 0x8b; \
+ *(inst)++ = 0xc0; break; \
+ case 3: *(inst)++ = 0x8d; *(inst)++ = 0x6d; \
+ *(inst)++ = 0x00; break; \
+ case 4: *(inst)++ = 0x8d; *(inst)++ = 0x64; \
+ *(inst)++ = 0x24; *(inst)++ = 0x00; \
+ break; \
+ case 5: *(inst)++ = 0x8d; *(inst)++ = 0x64; \
+ *(inst)++ = 0x24; *(inst)++ = 0x00; \
+ x86_nop ((inst)); break; \
+ case 6: *(inst)++ = 0x8d; *(inst)++ = 0xad; \
+ *(inst)++ = 0x00; *(inst)++ = 0x00; \
+ *(inst)++ = 0x00; *(inst)++ = 0x00; \
+ break; \
+ case 7: *(inst)++ = 0x8d; *(inst)++ = 0xa4; \
+ *(inst)++ = 0x24; *(inst)++ = 0x00; \
+ *(inst)++ = 0x00; *(inst)++ = 0x00; \
+ *(inst)++ = 0x00; break; \
+ default: assert (0); \
+ } \
+ } while (0)
+
+#define x86_prolog(inst,frame_size,reg_mask) \
+ do { \
+ unsigned i, m = 1; \
+ x86_enter ((inst), (frame_size)); \
+ for (i = 0; i < X86_NREG; ++i, m <<= 1) { \
+ if ((reg_mask) & m) \
+ x86_push_reg ((inst), i); \
+ } \
+ } while (0)
+
+#define x86_epilog(inst,reg_mask) \
+ do { \
+ unsigned i, m = 1 << X86_EDI; \
+ for (i = X86_EDI; m != 0; i--, m=m>>1) { \
+ if ((reg_mask) & m) \
+ x86_pop_reg ((inst), i); \
+ } \
+ x86_leave ((inst)); \
+ x86_ret ((inst)); \
+ } while (0)
+
+#endif // X86_H
diff --git a/mono/cil/.cvsignore b/mono/cil/.cvsignore
new file mode 100644
index 00000000000..10dae49ad16
--- /dev/null
+++ b/mono/cil/.cvsignore
@@ -0,0 +1,3 @@
+Makefile
+Makefile.in
+opcode.def
diff --git a/mono/cil/ChangeLog b/mono/cil/ChangeLog
new file mode 100644
index 00000000000..d9869c03c99
--- /dev/null
+++ b/mono/cil/ChangeLog
@@ -0,0 +1,19 @@
+Wed Jul 11 18:50:12 CEST 2001 Paolo Molaro <lupus@ximian.com>
+
+ * cil-opcodes.xml: change duplicate unused entry.
+
+Mon Jul 2 15:31:31 CEST 2001 Paolo Molaro <lupus@ximian.com>
+
+ * cil-opcodes.xml: use a more proper XML format (single root tag).
+ * make-opcodes-def.pl: use XML::Parser, remove debugging print that
+ broke compilation, corrected opcode byte len.
+
+2001-07-01 Miguel de Icaza <miguel@ximian.com>
+
+ * cil-opcodes.xml: New file that describes the CIL opcodes in
+ XML format.
+
+ * make-opcodes-def.pl: Perl script that parses the above file and
+ generates a Annex V/C.2 compliant opcode.def file.
+
+
diff --git a/mono/cil/Makefile.am b/mono/cil/Makefile.am
new file mode 100644
index 00000000000..4fa1bade5f6
--- /dev/null
+++ b/mono/cil/Makefile.am
@@ -0,0 +1,11 @@
+
+opcode.def: make-opcodes-def.pl cil-opcodes.xml
+ perl make-opcodes-def.pl < $(srcdir)/cil-opcodes.xml > opcode.def
+
+defdir = $(includedir)/mono/cil
+def_DATA = opcode.def
+
+xmldir = $(share)/mono/cil
+xml_DATA = cil-opcodes.xml
+
+EXTRA_DIST=opcode.def make-opcodes-def.pl make-opcode-def.xsl $(xml_DATA) $(def_DATA) \ No newline at end of file
diff --git a/mono/cil/TODO b/mono/cil/TODO
new file mode 100644
index 00000000000..6175693d3f6
--- /dev/null
+++ b/mono/cil/TODO
@@ -0,0 +1,3 @@
+* Replace make-opcodes-def.pl with XLST process
+
+ We should use an XSLT file to do the conversion there.
diff --git a/mono/cil/cil-opcodes.xml b/mono/cil/cil-opcodes.xml
new file mode 100644
index 00000000000..dfd5fb106cb
--- /dev/null
+++ b/mono/cil/cil-opcodes.xml
@@ -0,0 +1,297 @@
+<opdesc>
+<opcode name="nop" input="Pop0" output="Push0" args="InlineNone" o1="0xFF" o2="0x00" flow="next"/>
+<opcode name="break" input="Pop0" output="Push0" args="InlineNone" o1="0xFF" o2="0x01" flow="break"/>
+<opcode name="ldarg.0" input="Pop0" output="Push1" args="InlineNone" o1="0xFF" o2="0x02" flow="next"/>
+<opcode name="ldarg.1" input="Pop0" output="Push1" args="InlineNone" o1="0xFF" o2="0x03" flow="next"/>
+<opcode name="ldarg.2" input="Pop0" output="Push1" args="InlineNone" o1="0xFF" o2="0x04" flow="next"/>
+<opcode name="ldarg.3" input="Pop0" output="Push1" args="InlineNone" o1="0xFF" o2="0x05" flow="next"/>
+<opcode name="ldloc.0" input="Pop0" output="Push1" args="InlineNone" o1="0xFF" o2="0x06" flow="next"/>
+<opcode name="ldloc.1" input="Pop0" output="Push1" args="InlineNone" o1="0xFF" o2="0x07" flow="next"/>
+<opcode name="ldloc.2" input="Pop0" output="Push1" args="InlineNone" o1="0xFF" o2="0x08" flow="next"/>
+<opcode name="ldloc.3" input="Pop0" output="Push1" args="InlineNone" o1="0xFF" o2="0x09" flow="next"/>
+<opcode name="stloc.0" input="Pop1" output="Push0" args="InlineNone" o1="0xFF" o2="0x0A" flow="next"/>
+<opcode name="stloc.1" input="Pop1" output="Push0" args="InlineNone" o1="0xFF" o2="0x0B" flow="next"/>
+<opcode name="stloc.2" input="Pop1" output="Push0" args="InlineNone" o1="0xFF" o2="0x0C" flow="next"/>
+<opcode name="stloc.3" input="Pop1" output="Push0" args="InlineNone" o1="0xFF" o2="0x0D" flow="next"/>
+<opcode name="ldarg.s" input="Pop0" output="Push1" args="ShortInlineVar" o1="0xFF" o2="0x0E" flow="next"/>
+<opcode name="ldarga.s" input="Pop0" output="PushI" args="ShortInlineVar" o1="0xFF" o2="0x0F" flow="next"/>
+<opcode name="starg.s" input="Pop1" output="Push0" args="ShortInlineVar" o1="0xFF" o2="0x10" flow="next"/>
+<opcode name="ldloc.s" input="Pop0" output="Push1" args="ShortInlineVar" o1="0xFF" o2="0x11" flow="next"/>
+<opcode name="ldloca.s" input="Pop0" output="PushI" args="ShortInlineVar" o1="0xFF" o2="0x12" flow="next"/>
+<opcode name="stloc.s" input="Pop1" output="Push0" args="ShortInlineVar" o1="0xFF" o2="0x13" flow="next"/>
+<opcode name="ldnull" input="Pop0" output="PushRef" args="InlineNone" o1="0xFF" o2="0x14" flow="next"/>
+<opcode name="ldc.i4.m1" input="Pop0" output="PushI" args="InlineNone" o1="0xFF" o2="0x15" flow="next"/>
+<opcode name="ldc.i4.0" input="Pop0" output="PushI" args="InlineNone" o1="0xFF" o2="0x16" flow="next"/>
+<opcode name="ldc.i4.1" input="Pop0" output="PushI" args="InlineNone" o1="0xFF" o2="0x17" flow="next"/>
+<opcode name="ldc.i4.2" input="Pop0" output="PushI" args="InlineNone" o1="0xFF" o2="0x18" flow="next"/>
+<opcode name="ldc.i4.3" input="Pop0" output="PushI" args="InlineNone" o1="0xFF" o2="0x19" flow="next"/>
+<opcode name="ldc.i4.4" input="Pop0" output="PushI" args="InlineNone" o1="0xFF" o2="0x1A" flow="next"/>
+<opcode name="ldc.i4.5" input="Pop0" output="PushI" args="InlineNone" o1="0xFF" o2="0x1B" flow="next"/>
+<opcode name="ldc.i4.6" input="Pop0" output="PushI" args="InlineNone" o1="0xFF" o2="0x1C" flow="next"/>
+<opcode name="ldc.i4.7" input="Pop0" output="PushI" args="InlineNone" o1="0xFF" o2="0x1D" flow="next"/>
+<opcode name="ldc.i4.8" input="Pop0" output="PushI" args="InlineNone" o1="0xFF" o2="0x1E" flow="next"/>
+<opcode name="ldc.i4.s" input="Pop0" output="PushI" args="ShortInlineI" o1="0xFF" o2="0x1F" flow="next"/>
+<opcode name="ldc.i4" input="Pop0" output="PushI" args="InlineI" o1="0xFF" o2="0x20" flow="next"/>
+<opcode name="ldc.i8" input="Pop0" output="PushI8" args="InlineI8" o1="0xFF" o2="0x21" flow="next"/>
+<opcode name="ldc.r4" input="Pop0" output="PushR4" args="ShortInlineR" o1="0xFF" o2="0x22" flow="next"/>
+<opcode name="ldc.r8" input="Pop0" output="PushR8" args="InlineR" o1="0xFF" o2="0x23" flow="next"/>
+<opcode name="unused99" input="Pop0" output="Push0" args="InlineNone" o1="0xFF" o2="0x24" flow="next"/>
+<opcode name="dup" input="Pop1" output="Push1+Push1" args="InlineNone" o1="0xFF" o2="0x25" flow="next"/>
+<opcode name="pop" input="Pop1" output="Push0" args="InlineNone" o1="0xFF" o2="0x26" flow="next"/>
+<opcode name="jmp" input="Pop0" output="Push0" args="InlineMethod" o1="0xFF" o2="0x27" flow="call"/>
+<opcode name="call" input="VarPop" output="VarPush" args="InlineMethod" o1="0xFF" o2="0x28" flow="call"/>
+<opcode name="calli" input="VarPop" output="VarPush" args="InlineSig" o1="0xFF" o2="0x29" flow="call"/>
+<opcode name="ret" input="VarPop" output="Push0" args="InlineNone" o1="0xFF" o2="0x2A" flow="return"/>
+<opcode name="br.s" input="Pop0" output="Push0" args="ShortInlineBrTarget" o1="0xFF" o2="0x2B" flow="branch"/>
+<opcode name="brfalse.s" input="PopI" output="Push0" args="ShortInlineBrTarget" o1="0xFF" o2="0x2C" flow="cond-branch"/>
+<opcode name="brtrue.s" input="PopI" output="Push0" args="ShortInlineBrTarget" o1="0xFF" o2="0x2D" flow="cond-branch"/>
+<opcode name="beq.s" input="Pop1+Pop1" output="Push0" args="ShortInlineBrTarget" o1="0xFF" o2="0x2E" flow="cond-branch"/>
+<opcode name="bge.s" input="Pop1+Pop1" output="Push0" args="ShortInlineBrTarget" o1="0xFF" o2="0x2F" flow="cond-branch"/>
+<opcode name="bgt.s" input="Pop1+Pop1" output="Push0" args="ShortInlineBrTarget" o1="0xFF" o2="0x30" flow="cond-branch"/>
+<opcode name="ble.s" input="Pop1+Pop1" output="Push0" args="ShortInlineBrTarget" o1="0xFF" o2="0x31" flow="cond-branch"/>
+<opcode name="blt.s" input="Pop1+Pop1" output="Push0" args="ShortInlineBrTarget" o1="0xFF" o2="0x32" flow="cond-branch"/>
+<opcode name="bne.un.s" input="Pop1+Pop1" output="Push0" args="ShortInlineBrTarget" o1="0xFF" o2="0x33" flow="cond-branch"/>
+<opcode name="bge.un.s" input="Pop1+Pop1" output="Push0" args="ShortInlineBrTarget" o1="0xFF" o2="0x34" flow="cond-branch"/>
+<opcode name="bgt.un.s" input="Pop1+Pop1" output="Push0" args="ShortInlineBrTarget" o1="0xFF" o2="0x35" flow="cond-branch"/>
+<opcode name="ble.un.s" input="Pop1+Pop1" output="Push0" args="ShortInlineBrTarget" o1="0xFF" o2="0x36" flow="cond-branch"/>
+<opcode name="blt.un.s" input="Pop1+Pop1" output="Push0" args="ShortInlineBrTarget" o1="0xFF" o2="0x37" flow="cond-branch"/>
+<opcode name="br" input="Pop0" output="Push0" args="InlineBrTarget" o1="0xFF" o2="0x38" flow="branch"/>
+<opcode name="brfalse" input="PopI" output="Push0" args="InlineBrTarget" o1="0xFF" o2="0x39" flow="cond-branch"/>
+<opcode name="brtrue" input="PopI" output="Push0" args="InlineBrTarget" o1="0xFF" o2="0x3A" flow="cond-branch"/>
+<opcode name="beq" input="Pop1+Pop1" output="Push0" args="InlineBrTarget" o1="0xFF" o2="0x3B" flow="cond-branch"/>
+<opcode name="bge" input="Pop1+Pop1" output="Push0" args="InlineBrTarget" o1="0xFF" o2="0x3C" flow="cond-branch"/>
+<opcode name="bgt" input="Pop1+Pop1" output="Push0" args="InlineBrTarget" o1="0xFF" o2="0x3D" flow="cond-branch"/>
+<opcode name="ble" input="Pop1+Pop1" output="Push0" args="InlineBrTarget" o1="0xFF" o2="0x3E" flow="cond-branch"/>
+<opcode name="blt" input="Pop1+Pop1" output="Push0" args="InlineBrTarget" o1="0xFF" o2="0x3F" flow="cond-branch"/>
+<opcode name="bne.un" input="Pop1+Pop1" output="Push0" args="InlineBrTarget" o1="0xFF" o2="0x40" flow="cond-branch"/>
+<opcode name="bge.un" input="Pop1+Pop1" output="Push0" args="InlineBrTarget" o1="0xFF" o2="0x41" flow="cond-branch"/>
+<opcode name="bgt.un" input="Pop1+Pop1" output="Push0" args="InlineBrTarget" o1="0xFF" o2="0x42" flow="cond-branch"/>
+<opcode name="ble.un" input="Pop1+Pop1" output="Push0" args="InlineBrTarget" o1="0xFF" o2="0x43" flow="cond-branch"/>
+<opcode name="blt.un" input="Pop1+Pop1" output="Push0" args="InlineBrTarget" o1="0xFF" o2="0x44" flow="cond-branch"/>
+<opcode name="switch" input="PopI" output="Push0" args="InlineSwitch" o1="0xFF" o2="0x45" flow="cond-branch"/>
+<opcode name="ldind.i1" input="PopI" output="PushI" args="InlineNone" o1="0xFF" o2="0x46" flow="next"/>
+<opcode name="ldind.u1" input="PopI" output="PushI" args="InlineNone" o1="0xFF" o2="0x47" flow="next"/>
+<opcode name="ldind.i2" input="PopI" output="PushI" args="InlineNone" o1="0xFF" o2="0x48" flow="next"/>
+<opcode name="ldind.u2" input="PopI" output="PushI" args="InlineNone" o1="0xFF" o2="0x49" flow="next"/>
+<opcode name="ldind.i4" input="PopI" output="PushI" args="InlineNone" o1="0xFF" o2="0x4A" flow="next"/>
+<opcode name="ldind.u4" input="PopI" output="PushI" args="InlineNone" o1="0xFF" o2="0x4B" flow="next"/>
+<opcode name="ldind.i8" input="PopI" output="PushI8" args="InlineNone" o1="0xFF" o2="0x4C" flow="next"/>
+<opcode name="ldind.i" input="PopI" output="PushI" args="InlineNone" o1="0xFF" o2="0x4D" flow="next"/>
+<opcode name="ldind.r4" input="PopI" output="PushR4" args="InlineNone" o1="0xFF" o2="0x4E" flow="next"/>
+<opcode name="ldind.r8" input="PopI" output="PushR8" args="InlineNone" o1="0xFF" o2="0x4F" flow="next"/>
+<opcode name="ldind.ref" input="PopI" output="PushRef" args="InlineNone" o1="0xFF" o2="0x50" flow="next"/>
+<opcode name="stind.ref" input="PopI+PopI" output="Push0" args="InlineNone" o1="0xFF" o2="0x51" flow="next"/>
+<opcode name="stind.i1" input="PopI+PopI" output="Push0" args="InlineNone" o1="0xFF" o2="0x52" flow="next"/>
+<opcode name="stind.i2" input="PopI+PopI" output="Push0" args="InlineNone" o1="0xFF" o2="0x53" flow="next"/>
+<opcode name="stind.i4" input="PopI+PopI" output="Push0" args="InlineNone" o1="0xFF" o2="0x54" flow="next"/>
+<opcode name="stind.i8" input="PopI+PopI8" output="Push0" args="InlineNone" o1="0xFF" o2="0x55" flow="next"/>
+<opcode name="stind.r4" input="PopI+PopR4" output="Push0" args="InlineNone" o1="0xFF" o2="0x56" flow="next"/>
+<opcode name="stind.r8" input="PopI+PopR8" output="Push0" args="InlineNone" o1="0xFF" o2="0x57" flow="next"/>
+<opcode name="add" input="Pop1+Pop1" output="Push1" args="InlineNone" o1="0xFF" o2="0x58" flow="next"/>
+<opcode name="sub" input="Pop1+Pop1" output="Push1" args="InlineNone" o1="0xFF" o2="0x59" flow="next"/>
+<opcode name="mul" input="Pop1+Pop1" output="Push1" args="InlineNone" o1="0xFF" o2="0x5A" flow="next"/>
+<opcode name="div" input="Pop1+Pop1" output="Push1" args="InlineNone" o1="0xFF" o2="0x5B" flow="next"/>
+<opcode name="div.un" input="Pop1+Pop1" output="Push1" args="InlineNone" o1="0xFF" o2="0x5C" flow="next"/>
+<opcode name="rem" input="Pop1+Pop1" output="Push1" args="InlineNone" o1="0xFF" o2="0x5D" flow="next"/>
+<opcode name="rem.un" input="Pop1+Pop1" output="Push1" args="InlineNone" o1="0xFF" o2="0x5E" flow="next"/>
+<opcode name="and" input="Pop1+Pop1" output="Push1" args="InlineNone" o1="0xFF" o2="0x5F" flow="next"/>
+<opcode name="or" input="Pop1+Pop1" output="Push1" args="InlineNone" o1="0xFF" o2="0x60" flow="next"/>
+<opcode name="xor" input="Pop1+Pop1" output="Push1" args="InlineNone" o1="0xFF" o2="0x61" flow="next"/>
+<opcode name="shl" input="Pop1+Pop1" output="Push1" args="InlineNone" o1="0xFF" o2="0x62" flow="next"/>
+<opcode name="shr" input="Pop1+Pop1" output="Push1" args="InlineNone" o1="0xFF" o2="0x63" flow="next"/>
+<opcode name="shr.un" input="Pop1+Pop1" output="Push1" args="InlineNone" o1="0xFF" o2="0x64" flow="next"/>
+<opcode name="neg" input="Pop1" output="Push1" args="InlineNone" o1="0xFF" o2="0x65" flow="next"/>
+<opcode name="not" input="Pop1" output="Push1" args="InlineNone" o1="0xFF" o2="0x66" flow="next"/>
+<opcode name="conv.i1" input="Pop1" output="PushI" args="InlineNone" o1="0xFF" o2="0x67" flow="next"/>
+<opcode name="conv.i2" input="Pop1" output="PushI" args="InlineNone" o1="0xFF" o2="0x68" flow="next"/>
+<opcode name="conv.i4" input="Pop1" output="PushI" args="InlineNone" o1="0xFF" o2="0x69" flow="next"/>
+<opcode name="conv.i8" input="Pop1" output="PushI8" args="InlineNone" o1="0xFF" o2="0x6A" flow="next"/>
+<opcode name="conv.r4" input="Pop1" output="PushR4" args="InlineNone" o1="0xFF" o2="0x6B" flow="next"/>
+<opcode name="conv.r8" input="Pop1" output="PushR8" args="InlineNone" o1="0xFF" o2="0x6C" flow="next"/>
+<opcode name="conv.u4" input="Pop1" output="PushI" args="InlineNone" o1="0xFF" o2="0x6D" flow="next"/>
+<opcode name="conv.u8" input="Pop1" output="PushI8" args="InlineNone" o1="0xFF" o2="0x6E" flow="next"/>
+<opcode name="callvirt" input="VarPop" output="VarPush" args="InlineMethod" o1="0xFF" o2="0x6F" flow="call"/>
+<opcode name="cpobj" input="PopI+PopI" output="Push0" args="InlineType" o1="0xFF" o2="0x70" flow="next"/>
+<opcode name="ldobj" input="PopI" output="Push1" args="InlineType" o1="0xFF" o2="0x71" flow="next"/>
+<opcode name="ldstr" input="Pop0" output="PushRef" args="InlineString" o1="0xFF" o2="0x72" flow="next"/>
+<opcode name="newobj" input="VarPop" output="PushRef" args="InlineMethod" o1="0xFF" o2="0x73" flow="call"/>
+<opcode name="castclass" input="PopRef" output="PushRef" args="InlineType" o1="0xFF" o2="0x74" flow="next"/>
+<opcode name="isinst" input="PopRef" output="PushI" args="InlineType" o1="0xFF" o2="0x75" flow="next"/>
+<opcode name="conv.r.un" input="Pop1" output="PushR8" args="InlineNone" o1="0xFF" o2="0x76" flow="next"/>
+<opcode name="unused58" input="Pop0" output="Push0" args="InlineNone" o1="0xFF" o2="0x77" flow="next"/>
+<opcode name="unused1" input="Pop0" output="Push0" args="InlineNone" o1="0xFF" o2="0x78" flow="next"/>
+<opcode name="unbox" input="PopRef" output="PushI" args="InlineType" o1="0xFF" o2="0x79" flow="next"/>
+<opcode name="throw" input="PopRef" output="Push0" args="InlineNone" o1="0xFF" o2="0x7A" flow="throw"/>
+<opcode name="ldfld" input="PopRef" output="Push1" args="InlineField" o1="0xFF" o2="0x7B" flow="next"/>
+<opcode name="ldflda" input="PopRef" output="PushI" args="InlineField" o1="0xFF" o2="0x7C" flow="next"/>
+<opcode name="stfld" input="PopRef+Pop1" output="Push0" args="InlineField" o1="0xFF" o2="0x7D" flow="next"/>
+<opcode name="ldsfld" input="Pop0" output="Push1" args="InlineField" o1="0xFF" o2="0x7E" flow="next"/>
+<opcode name="ldsflda" input="Pop0" output="PushI" args="InlineField" o1="0xFF" o2="0x7F" flow="next"/>
+<opcode name="stsfld" input="Pop1" output="Push0" args="InlineField" o1="0xFF" o2="0x80" flow="next"/>
+<opcode name="stobj" input="PopI+Pop1" output="Push0" args="InlineType" o1="0xFF" o2="0x81" flow="next"/>
+<opcode name="conv.ovf.i1.un" input="Pop1" output="PushI" args="InlineNone" o1="0xFF" o2="0x82" flow="next"/>
+<opcode name="conv.ovf.i2.un" input="Pop1" output="PushI" args="InlineNone" o1="0xFF" o2="0x83" flow="next"/>
+<opcode name="conv.ovf.i4.un" input="Pop1" output="PushI" args="InlineNone" o1="0xFF" o2="0x84" flow="next"/>
+<opcode name="conv.ovf.i8.un" input="Pop1" output="PushI8" args="InlineNone" o1="0xFF" o2="0x85" flow="next"/>
+<opcode name="conv.ovf.u1.un" input="Pop1" output="PushI" args="InlineNone" o1="0xFF" o2="0x86" flow="next"/>
+<opcode name="conv.ovf.u2.un" input="Pop1" output="PushI" args="InlineNone" o1="0xFF" o2="0x87" flow="next"/>
+<opcode name="conv.ovf.u4.un" input="Pop1" output="PushI" args="InlineNone" o1="0xFF" o2="0x88" flow="next"/>
+<opcode name="conv.ovf.u8.un" input="Pop1" output="PushI8" args="InlineNone" o1="0xFF" o2="0x89" flow="next"/>
+<opcode name="conv.ovf.i.un" input="Pop1" output="PushI" args="InlineNone" o1="0xFF" o2="0x8A" flow="next"/>
+<opcode name="conv.ovf.u.un" input="Pop1" output="PushI" args="InlineNone" o1="0xFF" o2="0x8B" flow="next"/>
+<opcode name="box" input="Pop1" output="PushRef" args="InlineType" o1="0xFF" o2="0x8C" flow="next"/>
+<opcode name="newarr" input="PopI" output="PushRef" args="InlineType" o1="0xFF" o2="0x8D" flow="next"/>
+<opcode name="ldlen" input="PopRef" output="PushI" args="InlineNone" o1="0xFF" o2="0x8E" flow="next"/>
+<opcode name="ldelema" input="PopRef+PopI" output="PushI" args="InlineType" o1="0xFF" o2="0x8F" flow="next"/>
+<opcode name="ldelem.i1" input="PopRef+PopI" output="PushI" args="InlineNone" o1="0xFF" o2="0x90" flow="next"/>
+<opcode name="ldelem.u1" input="PopRef+PopI" output="PushI" args="InlineNone" o1="0xFF" o2="0x91" flow="next"/>
+<opcode name="ldelem.i2" input="PopRef+PopI" output="PushI" args="InlineNone" o1="0xFF" o2="0x92" flow="next"/>
+<opcode name="ldelem.u2" input="PopRef+PopI" output="PushI" args="InlineNone" o1="0xFF" o2="0x93" flow="next"/>
+<opcode name="ldelem.i4" input="PopRef+PopI" output="PushI" args="InlineNone" o1="0xFF" o2="0x94" flow="next"/>
+<opcode name="ldelem.u4" input="PopRef+PopI" output="PushI" args="InlineNone" o1="0xFF" o2="0x95" flow="next"/>
+<opcode name="ldelem.i8" input="PopRef+PopI" output="PushI8" args="InlineNone" o1="0xFF" o2="0x96" flow="next"/>
+<opcode name="ldelem.i" input="PopRef+PopI" output="PushI" args="InlineNone" o1="0xFF" o2="0x97" flow="next"/>
+<opcode name="ldelem.r4" input="PopRef+PopI" output="PushR4" args="InlineNone" o1="0xFF" o2="0x98" flow="next"/>
+<opcode name="ldelem.r8" input="PopRef+PopI" output="PushR8" args="InlineNone" o1="0xFF" o2="0x99" flow="next"/>
+<opcode name="ldelem.ref" input="PopRef+PopI" output="PushRef" args="InlineNone" o1="0xFF" o2="0x9A" flow="next"/>
+<opcode name="stelem.i" input="PopRef+PopI+PopI" output="Push0" args="InlineNone" o1="0xFF" o2="0x9B" flow="next"/>
+<opcode name="stelem.i1" input="PopRef+PopI+PopI" output="Push0" args="InlineNone" o1="0xFF" o2="0x9C" flow="next"/>
+<opcode name="stelem.i2" input="PopRef+PopI+PopI" output="Push0" args="InlineNone" o1="0xFF" o2="0x9D" flow="next"/>
+<opcode name="stelem.i4" input="PopRef+PopI+PopI" output="Push0" args="InlineNone" o1="0xFF" o2="0x9E" flow="next"/>
+<opcode name="stelem.i8" input="PopRef+PopI+PopI8" output="Push0" args="InlineNone" o1="0xFF" o2="0x9F" flow="next"/>
+<opcode name="stelem.r4" input="PopRef+PopI+PopR4" output="Push0" args="InlineNone" o1="0xFF" o2="0xA0" flow="next"/>
+<opcode name="stelem.r8" input="PopRef+PopI+PopR8" output="Push0" args="InlineNone" o1="0xFF" o2="0xA1" flow="next"/>
+<opcode name="stelem.ref" input="PopRef+PopI+PopRef" output="Push0" args="InlineNone" o1="0xFF" o2="0xA2" flow="next"/>
+<opcode name="unused2" input="Pop0" output="Push0" args="InlineNone" o1="0xFF" o2="0xA3" flow="next"/>
+<opcode name="unused3" input="Pop0" output="Push0" args="InlineNone" o1="0xFF" o2="0xA4" flow="next"/>
+<opcode name="unused4" input="Pop0" output="Push0" args="InlineNone" o1="0xFF" o2="0xA5" flow="next"/>
+<opcode name="unused5" input="Pop0" output="Push0" args="InlineNone" o1="0xFF" o2="0xA6" flow="next"/>
+<opcode name="unused6" input="Pop0" output="Push0" args="InlineNone" o1="0xFF" o2="0xA7" flow="next"/>
+<opcode name="unused7" input="Pop0" output="Push0" args="InlineNone" o1="0xFF" o2="0xA8" flow="next"/>
+<opcode name="unused8" input="Pop0" output="Push0" args="InlineNone" o1="0xFF" o2="0xA9" flow="next"/>
+<opcode name="unused9" input="Pop0" output="Push0" args="InlineNone" o1="0xFF" o2="0xAA" flow="next"/>
+<opcode name="unused10" input="Pop0" output="Push0" args="InlineNone" o1="0xFF" o2="0xAB" flow="next"/>
+<opcode name="unused11" input="Pop0" output="Push0" args="InlineNone" o1="0xFF" o2="0xAC" flow="next"/>
+<opcode name="unused12" input="Pop0" output="Push0" args="InlineNone" o1="0xFF" o2="0xAD" flow="next"/>
+<opcode name="unused13" input="Pop0" output="Push0" args="InlineNone" o1="0xFF" o2="0xAE" flow="next"/>
+<opcode name="unused14" input="Pop0" output="Push0" args="InlineNone" o1="0xFF" o2="0xAF" flow="next"/>
+<opcode name="unused15" input="Pop0" output="Push0" args="InlineNone" o1="0xFF" o2="0xB0" flow="next"/>
+<opcode name="unused16" input="Pop0" output="Push0" args="InlineNone" o1="0xFF" o2="0xB1" flow="next"/>
+<opcode name="unused17" input="Pop0" output="Push0" args="InlineNone" o1="0xFF" o2="0xB2" flow="next"/>
+<opcode name="conv.ovf.i1" input="Pop1" output="PushI" args="InlineNone" o1="0xFF" o2="0xB3" flow="next"/>
+<opcode name="conv.ovf.u1" input="Pop1" output="PushI" args="InlineNone" o1="0xFF" o2="0xB4" flow="next"/>
+<opcode name="conv.ovf.i2" input="Pop1" output="PushI" args="InlineNone" o1="0xFF" o2="0xB5" flow="next"/>
+<opcode name="conv.ovf.u2" input="Pop1" output="PushI" args="InlineNone" o1="0xFF" o2="0xB6" flow="next"/>
+<opcode name="conv.ovf.i4" input="Pop1" output="PushI" args="InlineNone" o1="0xFF" o2="0xB7" flow="next"/>
+<opcode name="conv.ovf.u4" input="Pop1" output="PushI" args="InlineNone" o1="0xFF" o2="0xB8" flow="next"/>
+<opcode name="conv.ovf.i8" input="Pop1" output="PushI8" args="InlineNone" o1="0xFF" o2="0xB9" flow="next"/>
+<opcode name="conv.ovf.u8" input="Pop1" output="PushI8" args="InlineNone" o1="0xFF" o2="0xBA" flow="next"/>
+<opcode name="unused50" input="Pop0" output="Push0" args="InlineNone" o1="0xFF" o2="0xBB" flow="next"/>
+<opcode name="unused18" input="Pop0" output="Push0" args="InlineNone" o1="0xFF" o2="0xBC" flow="next"/>
+<opcode name="unused19" input="Pop0" output="Push0" args="InlineNone" o1="0xFF" o2="0xBD" flow="next"/>
+<opcode name="unused20" input="Pop0" output="Push0" args="InlineNone" o1="0xFF" o2="0xBE" flow="next"/>
+<opcode name="unused21" input="Pop0" output="Push0" args="InlineNone" o1="0xFF" o2="0xBF" flow="next"/>
+<opcode name="unused22" input="Pop0" output="Push0" args="InlineNone" o1="0xFF" o2="0xC0" flow="next"/>
+<opcode name="unused23" input="Pop0" output="Push0" args="InlineNone" o1="0xFF" o2="0xC1" flow="next"/>
+<opcode name="refanyval" input="Pop1" output="PushI" args="InlineType" o1="0xFF" o2="0xC2" flow="next"/>
+<opcode name="ckfinite" input="Pop1" output="PushR8" args="InlineNone" o1="0xFF" o2="0xC3" flow="next"/>
+<opcode name="unused24" input="Pop0" output="Push0" args="InlineNone" o1="0xFF" o2="0xC4" flow="next"/>
+<opcode name="unused25" input="Pop0" output="Push0" args="InlineNone" o1="0xFF" o2="0xC5" flow="next"/>
+<opcode name="mkrefany" input="PopI" output="Push1" args="InlineType" o1="0xFF" o2="0xC6" flow="next"/>
+<opcode name="unused59" input="Pop0" output="Push0" args="InlineNone" o1="0xFF" o2="0xC7" flow="next"/>
+<opcode name="unused60" input="Pop0" output="Push0" args="InlineNone" o1="0xFF" o2="0xC8" flow="next"/>
+<opcode name="unused61" input="Pop0" output="Push0" args="InlineNone" o1="0xFF" o2="0xC9" flow="next"/>
+<opcode name="unused62" input="Pop0" output="Push0" args="InlineNone" o1="0xFF" o2="0xCA" flow="next"/>
+<opcode name="unused63" input="Pop0" output="Push0" args="InlineNone" o1="0xFF" o2="0xCB" flow="next"/>
+<opcode name="unused64" input="Pop0" output="Push0" args="InlineNone" o1="0xFF" o2="0xCC" flow="next"/>
+<opcode name="unused65" input="Pop0" output="Push0" args="InlineNone" o1="0xFF" o2="0xCD" flow="next"/>
+<opcode name="unused66" input="Pop0" output="Push0" args="InlineNone" o1="0xFF" o2="0xCE" flow="next"/>
+<opcode name="unused67" input="Pop0" output="Push0" args="InlineNone" o1="0xFF" o2="0xCF" flow="next"/>
+<opcode name="ldtoken" input="Pop0" output="PushI" args="InlineTok" o1="0xFF" o2="0xD0" flow="next"/>
+<opcode name="conv.u2" input="Pop1" output="PushI" args="InlineNone" o1="0xFF" o2="0xD1" flow="next"/>
+<opcode name="conv.u1" input="Pop1" output="PushI" args="InlineNone" o1="0xFF" o2="0xD2" flow="next"/>
+<opcode name="conv.i" input="Pop1" output="PushI" args="InlineNone" o1="0xFF" o2="0xD3" flow="next"/>
+<opcode name="conv.ovf.i" input="Pop1" output="PushI" args="InlineNone" o1="0xFF" o2="0xD4" flow="next"/>
+<opcode name="conv.ovf.u" input="Pop1" output="PushI" args="InlineNone" o1="0xFF" o2="0xD5" flow="next"/>
+<opcode name="add.ovf" input="Pop1+Pop1" output="Push1" args="InlineNone" o1="0xFF" o2="0xD6" flow="next"/>
+<opcode name="add.ovf.un" input="Pop1+Pop1" output="Push1" args="InlineNone" o1="0xFF" o2="0xD7" flow="next"/>
+<opcode name="mul.ovf" input="Pop1+Pop1" output="Push1" args="InlineNone" o1="0xFF" o2="0xD8" flow="next"/>
+<opcode name="mul.ovf.un" input="Pop1+Pop1" output="Push1" args="InlineNone" o1="0xFF" o2="0xD9" flow="next"/>
+<opcode name="sub.ovf" input="Pop1+Pop1" output="Push1" args="InlineNone" o1="0xFF" o2="0xDA" flow="next"/>
+<opcode name="sub.ovf.un" input="Pop1+Pop1" output="Push1" args="InlineNone" o1="0xFF" o2="0xDB" flow="next"/>
+<opcode name="endfinally" input="Pop0" output="Push0" args="InlineNone" o1="0xFF" o2="0xDC" flow="return"/>
+<opcode name="leave" input="Pop0" output="Push0" args="InlineBrTarget" o1="0xFF" o2="0xDD" flow="branch"/>
+<opcode name="leave.s" input="Pop0" output="Push0" args="ShortInlineBrTarget" o1="0xFF" o2="0xDE" flow="branch"/>
+<opcode name="stind.i" input="PopI+PopI" output="Push0" args="InlineNone" o1="0xFF" o2="0xDF" flow="next"/>
+<opcode name="conv.u" input="Pop1" output="PushI" args="InlineNone" o1="0xFF" o2="0xE0" flow="next"/>
+<opcode name="unused26" input="Pop0" output="Push0" args="InlineNone" o1="0xFF" o2="0xE1" flow="next"/>
+<opcode name="unused27" input="Pop0" output="Push0" args="InlineNone" o1="0xFF" o2="0xE2" flow="next"/>
+<opcode name="unused28" input="Pop0" output="Push0" args="InlineNone" o1="0xFF" o2="0xE3" flow="next"/>
+<opcode name="unused29" input="Pop0" output="Push0" args="InlineNone" o1="0xFF" o2="0xE4" flow="next"/>
+<opcode name="unused30" input="Pop0" output="Push0" args="InlineNone" o1="0xFF" o2="0xE5" flow="next"/>
+<opcode name="unused31" input="Pop0" output="Push0" args="InlineNone" o1="0xFF" o2="0xE6" flow="next"/>
+<opcode name="unused32" input="Pop0" output="Push0" args="InlineNone" o1="0xFF" o2="0xE7" flow="next"/>
+<opcode name="unused33" input="Pop0" output="Push0" args="InlineNone" o1="0xFF" o2="0xE8" flow="next"/>
+<opcode name="unused34" input="Pop0" output="Push0" args="InlineNone" o1="0xFF" o2="0xE9" flow="next"/>
+<opcode name="unused35" input="Pop0" output="Push0" args="InlineNone" o1="0xFF" o2="0xEA" flow="next"/>
+<opcode name="unused36" input="Pop0" output="Push0" args="InlineNone" o1="0xFF" o2="0xEB" flow="next"/>
+<opcode name="unused37" input="Pop0" output="Push0" args="InlineNone" o1="0xFF" o2="0xEC" flow="next"/>
+<opcode name="unused38" input="Pop0" output="Push0" args="InlineNone" o1="0xFF" o2="0xED" flow="next"/>
+<opcode name="unused39" input="Pop0" output="Push0" args="InlineNone" o1="0xFF" o2="0xEE" flow="next"/>
+<opcode name="unused40" input="Pop0" output="Push0" args="InlineNone" o1="0xFF" o2="0xEF" flow="next"/>
+<opcode name="unused41" input="Pop0" output="Push0" args="InlineNone" o1="0xFF" o2="0xF0" flow="next"/>
+<opcode name="unused42" input="Pop0" output="Push0" args="InlineNone" o1="0xFF" o2="0xF1" flow="next"/>
+<opcode name="unused43" input="Pop0" output="Push0" args="InlineNone" o1="0xFF" o2="0xF2" flow="next"/>
+<opcode name="unused44" input="Pop0" output="Push0" args="InlineNone" o1="0xFF" o2="0xF3" flow="next"/>
+<opcode name="unused45" input="Pop0" output="Push0" args="InlineNone" o1="0xFF" o2="0xF4" flow="next"/>
+<opcode name="unused46" input="Pop0" output="Push0" args="InlineNone" o1="0xFF" o2="0xF5" flow="next"/>
+<opcode name="unused47" input="Pop0" output="Push0" args="InlineNone" o1="0xFF" o2="0xF6" flow="next"/>
+<opcode name="unused48" input="Pop0" output="Push0" args="InlineNone" o1="0xFF" o2="0xF7" flow="next"/>
+<opcode name="prefix7" input="Pop0" output="Push0" args="InlineNone" o1="0xFF" o2="0xF8" flow="meta"/>
+<opcode name="prefix6" input="Pop0" output="Push0" args="InlineNone" o1="0xFF" o2="0xF9" flow="meta"/>
+<opcode name="prefix5" input="Pop0" output="Push0" args="InlineNone" o1="0xFF" o2="0xFA" flow="meta"/>
+<opcode name="prefix4" input="Pop0" output="Push0" args="InlineNone" o1="0xFF" o2="0xFB" flow="meta"/>
+<opcode name="prefix3" input="Pop0" output="Push0" args="InlineNone" o1="0xFF" o2="0xFC" flow="meta"/>
+<opcode name="prefix2" input="Pop0" output="Push0" args="InlineNone" o1="0xFF" o2="0xFD" flow="meta"/>
+<opcode name="prefix1" input="Pop0" output="Push0" args="InlineNone" o1="0xFF" o2="0xFE" flow="meta"/>
+<opcode name="prefixref" input="Pop0" output="Push0" args="InlineNone" o1="0xFF" o2="0xFF" flow="meta"/>
+<opcode name="arglist" input="Pop0" output="PushI" args="InlineNone" o1="0xFE" o2="0x00" flow="next"/>
+<opcode name="ceq" input="Pop1+Pop1" output="PushI" args="InlineNone" o1="0xFE" o2="0x01" flow="next"/>
+<opcode name="cgt" input="Pop1+Pop1" output="PushI" args="InlineNone" o1="0xFE" o2="0x02" flow="next"/>
+<opcode name="cgt.un" input="Pop1+Pop1" output="PushI" args="InlineNone" o1="0xFE" o2="0x03" flow="next"/>
+<opcode name="clt" input="Pop1+Pop1" output="PushI" args="InlineNone" o1="0xFE" o2="0x04" flow="next"/>
+<opcode name="clt.un" input="Pop1+Pop1" output="PushI" args="InlineNone" o1="0xFE" o2="0x05" flow="next"/>
+<opcode name="ldftn" input="Pop0" output="PushI" args="InlineMethod" o1="0xFE" o2="0x06" flow="next"/>
+<opcode name="ldvirtftn" input="PopRef" output="PushI" args="InlineMethod" o1="0xFE" o2="0x07" flow="next"/>
+<opcode name="unused56" input="Pop0" output="Push0" args="InlineNone" o1="0xFE" o2="0x08" flow="next"/>
+<opcode name="ldarg" input="Pop0" output="Push1" args="InlineVar" o1="0xFE" o2="0x09" flow="next"/>
+<opcode name="ldarga" input="Pop0" output="PushI" args="InlineVar" o1="0xFE" o2="0x0A" flow="next"/>
+<opcode name="starg" input="Pop1" output="Push0" args="InlineVar" o1="0xFE" o2="0x0B" flow="next"/>
+<opcode name="ldloc" input="Pop0" output="Push1" args="InlineVar" o1="0xFE" o2="0x0C" flow="next"/>
+<opcode name="ldloca" input="Pop0" output="PushI" args="InlineVar" o1="0xFE" o2="0x0D" flow="next"/>
+<opcode name="stloc" input="Pop1" output="Push0" args="InlineVar" o1="0xFE" o2="0x0E" flow="next"/>
+<opcode name="localloc" input="PopI" output="PushI" args="InlineNone" o1="0xFE" o2="0x0F" flow="next"/>
+<opcode name="unused57" input="Pop0" output="Push0" args="InlineNone" o1="0xFE" o2="0x10" flow="next"/>
+<opcode name="endfilter" input="PopI" output="Push0" args="InlineNone" o1="0xFE" o2="0x11" flow="return"/>
+<opcode name="unaligned." input="Pop0" output="Push0" args="ShortInlineI" o1="0xFE" o2="0x12" flow="meta"/>
+<opcode name="volatile." input="Pop0" output="Push0" args="InlineNone" o1="0xFE" o2="0x13" flow="meta"/>
+<opcode name="tail." input="Pop0" output="Push0" args="InlineNone" o1="0xFE" o2="0x14" flow="meta"/>
+<opcode name="initobj" input="PopI" output="Push0" args="InlineType" o1="0xFE" o2="0x15" flow="next"/>
+<opcode name="unused68" input="Pop0" output="Push0" args="InlineNone" o1="0xFE" o2="0x16" flow="next"/>
+<opcode name="cpblk" input="PopI+PopI+PopI" output="Push0" args="InlineNone" o1="0xFE" o2="0x17" flow="next"/>
+<opcode name="initblk" input="PopI+PopI+PopI" output="Push0" args="InlineNone" o1="0xFE" o2="0x18" flow="next"/>
+<opcode name="unused69" input="Pop0" output="Push0" args="InlineNone" o1="0xFE" o2="0x19" flow="next"/>
+<opcode name="rethrow" input="Pop0" output="Push0" args="InlineNone" o1="0xFE" o2="0x1A" flow="throw"/>
+<opcode name="unused" input="Pop0" output="Push0" args="InlineNone" o1="0xFE" o2="0x1B" flow="next"/>
+<opcode name="sizeof" input="Pop0" output="PushI" args="InlineType" o1="0xFE" o2="0x1C" flow="next"/>
+<opcode name="refanytype" input="Pop1" output="PushI" args="InlineNone" o1="0xFE" o2="0x1D" flow="next"/>
+<opcode name="unused52" input="Pop0" output="Push0" args="InlineNone" o1="0xFE" o2="0x1E" flow="next"/>
+<opcode name="unused53" input="Pop0" output="Push0" args="InlineNone" o1="0xFE" o2="0x1F" flow="next"/>
+<opcode name="unused54" input="Pop0" output="Push0" args="InlineNone" o1="0xFE" o2="0x20" flow="next"/>
+<opcode name="unused55" input="Pop0" output="Push0" args="InlineNone" o1="0xFE" o2="0x21" flow="next"/>
+<opcode name="unused70" input="Pop0" output="Push0" args="InlineNone" o1="0xFE" o2="0x22" flow="next"/>
+<opcode name="illegal" input="Pop0" output="Push0" args="InlineNone" o1="0x00" o2="0x00" flow="meta"/>
+<opcode name="endmac" input="Pop0" output="Push0" args="InlineNone" o1="0x00" o2="0x00" flow="meta"/>
+
+
+</opdesc>
diff --git a/mono/cil/make-opcode-def.xsl b/mono/cil/make-opcode-def.xsl
new file mode 100644
index 00000000000..9ad799f4ba9
--- /dev/null
+++ b/mono/cil/make-opcode-def.xsl
@@ -0,0 +1,100 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+
+
+<!--
+ | make-opcode-def.xsl: Translates opcodes from the CIL-opcodes.xml into
+ | a spec compliant opcodes.def file
+ | Converted to XSLT from make-opcodes-def.pl
+ |
+ | See: Common Language Infrastructure (CLI) Part 5: Annexes
+ |
+ | Author: Sergey Chaban
+ |
+ | $Id: make-opcode-def.xsl,v 1.1 2001/07/13 01:04:23 miguel Exp $
+ -->
+
+
+
+<xsl:stylesheet version="1.0"
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+
+
+
+<xsl:output method="text"/>
+
+
+<xsl:template match="/">
+ <xsl:apply-templates/>
+ <xsl:call-template name="print-trailer"/>
+</xsl:template>
+
+<xsl:template name="to-upper">
+ <xsl:param name="string"/>
+ <xsl:value-of select="translate($string,
+ 'abcdefghijklmnopqrstuvwxyz.-',
+ 'ABCDEFGHIJKLMNOPQRSTUVWXYZ__')"/>
+</xsl:template>
+
+
+<xsl:template name="get-flow">
+ <xsl:param name="flow" select="@flow"/>
+ <xsl:choose>
+ <xsl:when
+ test="contains('next call return branch meta cond-branch',$flow)">
+ <xsl:call-template name="to-upper">
+ <xsl:with-param name="string" select="$flow"/>
+ </xsl:call-template>
+ </xsl:when>
+ <xsl:otherwise><xsl:value-of select="'ERROR'"/></xsl:otherwise>
+ </xsl:choose>
+</xsl:template>
+
+
+<xsl:template match="opdesc/opcode">
+ <xsl:variable name="uname">
+ <xsl:call-template name="to-upper">
+ <xsl:with-param name="string" select="@name"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:variable name="o1">
+ <xsl:call-template name="to-upper">
+ <xsl:with-param name="string" select="@o1"/>
+ </xsl:call-template>
+ </xsl:variable>
+ <xsl:variable name="f">
+ <xsl:call-template name="get-flow"/>
+ </xsl:variable>
+ <xsl:variable name="count"
+ select="number(not(contains($o1,'FF')))+1"/>OPDEF(CEE_<xsl:value-of
+ select="concat($uname,', &#x22;',@name,'&#x22;, ',
+ @input,', ',@output,', ',@args,', X, ',
+ $count,', ',@o1,', ',@o2,', ',$f
+ )"/>)
+</xsl:template>
+
+
+<xsl:template name="print-trailer">
+#ifndef OPALIAS
+#define _MONO_CIL_OPALIAS_DEFINED_
+#define OPALIAS(a,s,r)
+#endif
+
+OPALIAS(CEE_BRNULL, "brnull", CEE_BRFALSE)
+OPALIAS(CEE_BRNULL_S, "brnull.s", CEE_BRFALSE_S)
+OPALIAS(CEE_BRZERO, "brzero", CEE_BRFALSE)
+OPALIAS(CEE_BRZERO_S, "brzero.s", CEE_BRFALSE_S)
+OPALIAS(CEE_BRINST, "brinst", CEE_BRTRUE)
+OPALIAS(CEE_BRINST_S, "brinst.s", CEE_BRTRUE_S)
+OPALIAS(CEE_LDIND_U8, "ldind.u8", CEE_LDIND_I8)
+OPALIAS(CEE_LDELEM_U8, "ldelem.u8", CEE_LDELEM_I8)
+OPALIAS(CEE_LDX_I4_MIX, "ldc.i4.M1", CEE_LDC_I4_M1)
+OPALIAS(CEE_ENDFAULT, "endfault", CEE_ENDFINALLY)
+
+#ifdef _MONO_CIL_OPALIAS_DEFINED_
+#undef OPALIAS
+#undef _MONO_CIL_OPALIAS_DEFINED_
+#endif
+</xsl:template>
+
+
+</xsl:stylesheet>
diff --git a/mono/cil/make-opcodes-def.pl b/mono/cil/make-opcodes-def.pl
new file mode 100644
index 00000000000..3114918bb65
--- /dev/null
+++ b/mono/cil/make-opcodes-def.pl
@@ -0,0 +1,80 @@
+#!/usr/bin/perl
+#
+# make-opcodes-def.pl: Loads the opcodes from the CIL-opcodes.xml and
+# generates a spec compliant opcodes.def file
+#
+# Author:
+# Miguel de Icaza (miguel@ximian.com)
+#
+# (C) 2001 Ximian, Inc.
+#
+# We should really be doing this with XSLT, but I know nothing about XSLT
+# ;-)
+# or maybe just an XML::Parser... - lupus
+
+use strict;
+use XML::Parser;
+
+my %valid_flow;
+# the XML file also includes "throw"
+@valid_flow{qw(next call return branch meta cond-branch)} = ();
+
+open OUTPUT, ">opcode.def" || die "Can not create opcode.def file: $!";
+
+my $parser = new XML::Parser (Handlers => {Start => \&handle_opcode});
+$parser->parsefile("cil-opcodes.xml");
+print_trailer();
+close(OUTPUT) || die "Can not close file: $!";
+
+sub handle_opcode {
+ my ($parser, $elem, %attrs) = @_;
+ my ($name, $input, $output, $args, $o1, $o2, $flow, $uname, $count, $ff);
+
+ return if ($elem ne 'opcode');
+
+ ($name, $input, $output, $args, $o1, $o2, $flow) =
+ @attrs{qw(name input output args o1 o2 flow)};
+
+ $uname = uc $name;
+ $uname =~ tr/./_/;
+ if (hex($o1) == 0xff){
+ $count = 1;
+ } else {
+ $count = 2;
+ }
+
+ $ff = "ERROR";
+ if (exists $valid_flow{$flow}) {
+ $ff = uc $flow;
+ $ff =~ tr/-/_/;
+ }
+
+ print OUTPUT "OPDEF(CEE_$uname, \"$name\", $input, $output, $args, X, $count, $o1, $o2, $ff)\n";
+
+}
+
+sub print_trailer {
+print OUTPUT<<EOF;
+#ifndef OPALIAS
+#define _MONO_CIL_OPALIAS_DEFINED_
+#define OPALIAS(a,s,r)
+#endif
+
+OPALIAS(CEE_BRNULL, "brnull", CEE_BRFALSE)
+OPALIAS(CEE_BRNULL_S, "brnull.s", CEE_BRFALSE_S)
+OPALIAS(CEE_BRZERO, "brzero", CEE_BRFALSE)
+OPALIAS(CEE_BRZERO_S, "brzero.s", CEE_BRFALSE_S)
+OPALIAS(CEE_BRINST, "brinst", CEE_BRTRUE)
+OPALIAS(CEE_BRINST_S, "brinst.s", CEE_BRTRUE_S)
+OPALIAS(CEE_LDIND_U8, "ldind.u8", CEE_LDIND_I8)
+OPALIAS(CEE_LDELEM_U8, "ldelem.u8", CEE_LDELEM_I8)
+OPALIAS(CEE_LDX_I4_MIX, "ldc.i4.M1", CEE_LDC_I4_M1)
+OPALIAS(CEE_ENDFAULT, "endfault", CEE_ENDFINALLY)
+
+#ifdef _MONO_CIL_OPALIAS_DEFINED_
+#undef OPALIAS
+#undef _MONO_CIL_OPALIAS_DEFINED_
+#endif
+EOF
+}
+
diff --git a/mono/dis/.cvsignore b/mono/dis/.cvsignore
new file mode 100644
index 00000000000..45b45b2bee5
--- /dev/null
+++ b/mono/dis/.cvsignore
@@ -0,0 +1,5 @@
+Makefile
+Makefile.in
+.libs
+.deps
+monodis
diff --git a/mono/dis/ChangeLog b/mono/dis/ChangeLog
new file mode 100644
index 00000000000..f25271f12eb
--- /dev/null
+++ b/mono/dis/ChangeLog
@@ -0,0 +1,180 @@
+
+Wed Aug 22 16:22:22 CEST 2001 Paolo Molaro <lupus@ximian.com>
+
+ * dis-cil.c: add a newline after branch instructions. Move
+ end of exception handler code at the end.
+
+Tue Aug 21 18:51:05 CEST 2001 Paolo Molaro <lupus@ximian.com>
+
+ * dis-cil.c: correctly print the label for multi-byte opcodes.
+
+Mon Aug 20 19:33:34 CEST 2001 Paolo Molaro <lupus@ximian.com>
+
+ * util.c: add a space when decoding multiple flags.
+ * dump.c, dump.h, main.c: decode the property map and
+ methodsemantics tables. Disassemble property information
+ to .property IL directives.
+ * get.c: allow passing a NULL as method in dis_stringify_method ()
+ if a methoddef_row is given.
+
+2001-08-20 Dietmar Maurer <dietmar@ximian.com>
+
+ * get.c (dis_stringify_type): support pinned values
+
+Sat Aug 18 11:24:07 CEST 2001 Paolo Molaro <lupus@ximian.com>
+
+ * dump.c, get.c, get.h, main.c: dis_stringify_method_signature()
+ gets an optional methodef_row index instead of a name, so it
+ can figure out also the names and attributes of params.
+ parse_method_signature() and free_method_signature() removed as
+ they are useless now.
+
+2001-08-17 Dietmar Maurer <dietmar@ximian.com>
+
+ * main.c (pinvoke_info): bug fix - use the right column in the table
+
+2001-08-14 Dietmar Maurer <dietmar@ximian.com>
+
+ * get.c (dis_stringify_type): use strconcat instead of strjoin
+
+Sat Aug 4 12:36:54 CEST 2001 Paolo Molaro <lupus@ximian.com>
+
+ * get.c, get.h, main.c, dump.c: implement dis_stringify_method_signature().
+ More magic constants replaced by enum values (spotted at least 3 real bugs
+ doing this). Print usage information if an unknown option is given.
+ Print the full signature when dumping the method table.
+ Changed method and field table dumps to show the typedef name the field
+ or method belongs to.
+
+Fri Aug 3 18:30:16 CEST 2001 Paolo Molaro <lupus@ximian.com>
+
+ * get.c (get_method): fix use of unitialized variable and
+ remove magic constants all over the place.
+
+Wed Aug 1 22:46:45 CEST 2001 Paolo Molaro <lupus@ximian.com>
+
+ * dis-cil.c: properly decode the switch opcode.
+
+2001-08-01 Dietmar Maurer <dietmar@ximian.com>
+
+ * get.c (get_token): decode typedef and typeref tokens
+
+ * main.c (dis_method_list): don't decode the next row, that is
+ totally unnecessary
+
+Tue Jul 31 17:48:11 CEST 2001 Paolo Molaro <lupus@ximian.com>
+
+ * dis-cil.c, dis-cil.h, dump.c, dump.h, get.c, get.h, main.c, push-pop.h:
+ massive namespace cleanup.
+ * main.c: dis_locals() now just strigifies a MonoMethodHeader.
+
+2001-07-31 Dietmar Maurer <dietmar@ximian.com>
+
+ * main.c (pinvoke_flags): impl.
+
+Mon Jul 30 20:08:37 CEST 2001 Paolo Molaro <lupus@ximian.com>
+
+ * dis-cil.c, dis-cil.h, main.c: changes to disassemble also
+ the information about try/catch/finally blocks.
+
+2001-07-27 Dietmar Maurer <dietmar@ximian.com>
+
+ * get.c (dis_stringify_type): return "void" if !type
+ (dis_stringify_type): print type* instead of *type
+
+Thu Jul 26 13:22:28 CEST 2001 Paolo Molaro <lupus@ximian.com>
+
+ * dis-cil.c, dump.c, get.c, main.c: updates to match changes in metadata.
+ Removed dead code.
+
+2001-07-17 Miguel de Icaza <miguel@ximian.com>
+
+ * main.c (usage): Print out all the arguments.
+
+ * get.c, main.c, dump.c: Remove `expand', `get_encoded_value',
+ `get_blob_encoded_size' and replaced with the proper functions
+ from metadata.c
+
+2001-07-15 Miguel de Icaza <miguel@ximian.com>
+
+ * main.c (dis_code): Only display .entrypoint when we are dealing
+ with a module that contains an entry point. This removes a bunch
+ of warnings for .dll dumping
+
+Sun Jul 15 17:29:10 CEST 2001 Paolo Molaro <lupus@ximian.com>
+
+ * get.h,get.c: added some dis_stringify_object() functions:
+ metadata decoding is now done in libmetadata. Still need to use
+ them throughhout the code (and move other decode code to
+ metadata). Fix also field decoding (band-aid until we load
+ also referenced assemblies).
+ * dis/main.c: start using the new routines.
+
+2001-07-13 Miguel de Icaza <miguel@ximian.com>
+
+ * get.c (get_method): GOOD. Implemented this other bad boy.
+
+2001-07-12 Miguel de Icaza <miguel@ximian.com>
+
+ * get.c (get_token_type): Implement TOKEN_TYPE_TYPE_SPEC.
+ (get_typespec): Implement.
+ (get_typedef_or_ref): Use get_typespec.
+
+ * dis-cil.c (dissasemble_cil): Implement InlineField
+ (dissasemble_cil): Implement InlineTok.
+
+ * get.c (get_token, get_field): Implemented. Worked around lame
+ tables in the spec.
+
+Wed Jul 11 18:52:15 CEST 2001 Paolo Molaro <lupus@ximian.com>
+
+ * dis-cil.c: output real name of local var.
+ * dump.c: output more info about fields (flags and type). Properly decode
+ Property signatures. Decode also method table.
+ * main.c: Fix local variable info. Hopefully fix field and property list.
+
+Mon Jul 9 16:39:41 CEST 2001 Paolo Molaro <lupus@ximian.com>
+
+ * dump.c: write stuff to output, not stderr. Give more info for properties.
+ * dump.c,dump.h,main.c: implement dump_table_event(), dump_table_file(),
+ dump_table_moduleref().
+ * get.c: first attempt to decode string constants, need to find if and where
+ this is actually specified.
+
+Fri Jul 6 19:49:21 CEST 2001 Paolo Molaro <lupus@ximian.com>
+
+ * dump.c,dump.h: implement dump_table_property().
+ * main.c: implement local variable info disassembling.
+ Annotate entrypoint method. Remove memory leak in
+ parse_method_signature ().
+
+2001-07-04 Miguel de Icaza <miguel@ximian.com>
+
+ * get.c (get_methodref_signature): Implement.
+
+ * dump.c (dump_table_memberref): Add memberref dumping.
+
+Tue, 3 Jul 2001 18:32:10 +0200 Paolo Molaro <lupus@ximian.com>
+
+ * main.c: return on failure.
+
+2001-07-02 Miguel de Icaza <miguel@ximian.com>
+
+ * dis-cil.c (get_encoded_user_string): Return a string from the
+ #US heap. o
+
+ * get.c (get_blob_encoded_size): Implement 23.1.4 decoding.
+
+2001-07-01 Miguel de Icaza <miguel@ximian.com>
+
+ * dis-cil.c: New file. CIL opcode dissasembler.
+
+2001-06-27 Miguel de Icaza <miguel@ximian.com>
+
+ * main.c: Split code.
+
+2001-06-22 Miguel de Icaza <miguel@ximian.com>
+
+ * main.c: More work on the disassembler and on the understanding
+ of the metadata file format.
+
diff --git a/mono/dis/Makefile.am b/mono/dis/Makefile.am
index fdb8662c28c..479cc7c6852 100644
--- a/mono/dis/Makefile.am
+++ b/mono/dis/Makefile.am
@@ -2,9 +2,27 @@ INCLUDES = $(GLIB_CFLAGS) -I$(top_srcdir)
bin_PROGRAMS = monodis
+lib_LIBRARIES = libmonodis.a
+
+libmonodis_a_SOURCES = \
+ get.c \
+ get.h \
+ dis-cil.c \
+ dis-cil.h \
+ util.c \
+ util.h
+
monodis_SOURCES = \
- main.c
+ dump.c \
+ dump.h \
+ main.c \
+ meta.h
monodis_LDADD = \
../metadata/libmetadata.a \
+ libmonodis.a \
$(GLIB_LIBS)
+
+man_MANS = monodis.1
+
+EXTRA_DIST = $(man_MANS) \ No newline at end of file
diff --git a/mono/dis/TODO b/mono/dis/TODO
new file mode 100644
index 00000000000..fb42dc0758a
--- /dev/null
+++ b/mono/dis/TODO
@@ -0,0 +1,5 @@
+* Write test cases
+
+ Write test cases to stress test TypeSpec. This is done by
+ creating arrays of various dimensions, sizes, and lower
+ bounds.
diff --git a/mono/dis/dis-cil.c b/mono/dis/dis-cil.c
new file mode 100644
index 00000000000..7ffa55381fd
--- /dev/null
+++ b/mono/dis/dis-cil.c
@@ -0,0 +1,298 @@
+/*
+ * dis-cil.c: Disassembles CIL byte codes
+ *
+ * Author:
+ * Miguel de Icaza (miguel@ximian.com)
+ *
+ * (C) 2001 Ximian, Inc.
+ */
+#include <config.h>
+#include <glib.h>
+#include <stdio.h>
+#include <wchar.h>
+#include "meta.h"
+#include "get.h"
+#include "dump.h"
+#include "dis-cil.h"
+
+enum {
+ InlineBrTarget,
+ InlineField,
+ InlineI,
+ InlineI8,
+ InlineMethod,
+ InlineNone,
+ InlineR,
+ InlineSig,
+ InlineString,
+ InlineSwitch,
+ InlineTok,
+ InlineType,
+ InlineVar,
+ ShortInlineBrTarget,
+ ShortInlineI,
+ ShortInlineR,
+ ShortInlineVar
+};
+
+#define OPDEF(a,b,c,d,e,f,g,h,i,j) \
+ { b, e, g, h, i },
+
+typedef struct {
+ char *name;
+ int argument;
+
+ /*
+ * we are not really using any of the following:
+ */
+ int bytes;
+ unsigned char o1, o2;
+} opcode_t;
+
+static opcode_t opcodes [300] = {
+#include "mono/cil/opcode.def"
+};
+
+/*
+ * Strings on the US heap are encoded using UTF-16. Poor man's
+ * UTF-16 to UTF-8. I know its broken, use libunicode later.
+ */
+static char *
+get_encoded_user_string (const char *ptr)
+{
+ char *res;
+ int len, i, j;
+
+ len = mono_metadata_decode_blob_size (ptr, &ptr);
+ res = g_malloc (len + 1);
+
+ /*
+ * I should really use some kind of libunicode here
+ */
+ for (i = 0, j = 0; i < len; j++, i += 2)
+ res [j] = ptr [i];
+
+ res [j] = 0;
+
+ return res;
+}
+
+#define CODE_INDENT g_assert (indent_level < 512); \
+ indent[indent_level*2] = ' '; \
+ indent[indent_level*2+1] = ' '; \
+ ++indent_level; \
+ indent[indent_level*2] = 0;
+#define CODE_UNINDENT g_assert (indent_level); \
+ --indent_level; \
+ indent[indent_level*2] = 0;
+
+void
+dissasemble_cil (MonoMetadata *m, MonoMethodHeader *mh)
+{
+ const unsigned char *start = mh->code;
+ int size = mh->code_size;
+ const unsigned char *end = start + size;
+ const unsigned char *ptr = start;
+ opcode_t *entry;
+ char indent[1024];
+ int i, indent_level = 0;
+ char *clause_names[] = {"catch", "filter", "finally", "fault"};
+
+ indent [0] = 0;
+
+ while (ptr < end){
+ for (i = 0; i < mh->num_clauses; ++i) {
+ if (!mh->clauses[i].flags && ptr == start + mh->clauses[i].try_offset) {
+ fprintf (output, "\t%s.try { // %d\n", indent, i);
+ CODE_INDENT;
+ }
+ if (ptr == start + mh->clauses[i].handler_offset) {
+ char * klass = mh->clauses[i].flags ? g_strdup ("") : dis_stringify_token (m, mh->clauses[i].token_or_filter);
+ fprintf (output, "\t%s%s %s { // %d\n", indent, clause_names [mh->clauses[i].flags], klass, i);
+ CODE_INDENT;
+ g_free (klass);
+ }
+ }
+ fprintf (output, "\t%sIL_%04x: ", indent, (int) (ptr - start));
+ if (*ptr == 0xfe){
+ ptr++;
+ entry = &opcodes [*ptr + 256];
+ } else
+ entry = &opcodes [*ptr];
+
+ fprintf (output, "%s ", entry->name);
+ ptr++;
+ switch (entry->argument){
+ case InlineBrTarget: {
+ gint target = *(gint32 *) ptr;
+ fprintf (output, "IL_%04x\n", ((int) (ptr - start)) + 4 + target);
+ ptr += 4;
+ break;
+ }
+
+ case InlineField: {
+ guint32 token = *(guint32 *) ptr;
+ char *s;
+
+ s = get_field (m, token);
+ fprintf (output, "%s", s);
+ g_free (s);
+ ptr += 4;
+ break;
+ }
+
+ case InlineI: {
+ int value = *(int *) ptr;
+
+ fprintf (output, "%d", value);
+ ptr += 4;
+ break;
+ }
+
+ case InlineI8: {
+ gint64 top = *(guint64 *) ptr;
+
+ fprintf (output, "%lld", (long long) top);
+ ptr += 8;
+ break;
+ }
+
+ case InlineMethod: {
+ guint32 token = *(guint32 *) ptr;
+ char *s;
+
+ s = get_method (m, token);
+ fprintf (output, "%s", s);
+ g_free (s);
+ ptr += 4;
+ break;
+ }
+
+ case InlineNone:
+ break;
+
+ case InlineR: {
+ double r = *(double *) ptr;
+ fprintf (output, "%g", r);
+ ptr += 8;
+ break;
+ }
+
+ case InlineSig: {
+ guint32 token = *(guint32 *) ptr;
+ fprintf (output, "signature-0x%08x", token);
+ ptr += 4;
+ break;
+ }
+
+ case InlineString: {
+ guint32 token = *(guint32 *) ptr;
+
+ char *s = get_encoded_user_string (
+ mono_metadata_user_string (m, token & 0xffffff));
+
+ /*
+ * See section 23.1.4 on the encoding of the #US heap
+ */
+ fprintf (output, "\"%s\"", s);
+ g_free (s);
+ ptr += 4;
+ break;
+ }
+
+ case InlineSwitch: {
+ guint32 count = read32 (ptr);
+ const unsigned char *endswitch;
+ guint32 i;
+
+ ptr += 4;
+ endswitch = ptr + sizeof (guint32) * count;
+ fprintf (output, "(\n");
+ CODE_INDENT;
+ for (i = 0; i < count; i++){
+ fprintf (output, "\t%sIL_%04x%s", indent,
+ endswitch-start+read32 (ptr),
+ i == count - 1 ? ")" : ",\n");
+ ptr += 4;
+ }
+ CODE_UNINDENT;
+ break;
+ }
+
+ case InlineTok: {
+ guint32 token = *(guint32 *) ptr;
+ char *s;
+
+ s = get_token (m, token);
+ fprintf (output, "%s", s);
+ g_free (s);
+
+ ptr += 4;
+ break;
+ }
+
+ case InlineType: {
+ guint32 token = *(guint32 *) ptr;
+ char *s = get_token_type (m, token);
+ fprintf (output, "%s", s);
+ g_free (s);
+ ptr += 4;
+ break;
+ }
+
+ case InlineVar: {
+ gint16 var_idx = *(gint16 *) ptr;
+
+ fprintf (output, "variable-%d\n", var_idx);
+ ptr += 2;
+ break;
+ }
+
+ case ShortInlineBrTarget: {
+ signed char x = *ptr;
+
+ fprintf (output, "IL_%04x\n", ptr - start + 1 + x);
+ ptr++;
+ break;
+ }
+
+ case ShortInlineI: {
+ char x = *ptr;
+
+ fprintf (output, "0x%02x", x);
+ ptr++;
+ break;
+ }
+
+ case ShortInlineR: {
+ float f = *(float *) ptr;
+
+ fprintf (output, "%g", (double) f);
+ ptr += 4;
+ break;
+ }
+
+ case ShortInlineVar: {
+ signed char x = *ptr;
+
+ fprintf (output, "V_%d", (int) x);
+ ptr++;
+ break;
+ }
+ default:
+ break;
+ }
+
+ fprintf (output, "\n");
+ for (i = 0; i < mh->num_clauses; ++i) {
+ if (!mh->clauses[i].flags && ptr == start + mh->clauses[i].try_offset + mh->clauses[i].try_len) {
+ CODE_UNINDENT;
+ fprintf (output, "\t%s} // end .try %d\n", indent, i);
+ }
+ if (ptr == start + mh->clauses[i].handler_offset + mh->clauses[i].handler_len) {
+ CODE_UNINDENT;
+ fprintf (output, "\t%s} // end handler %d\n", indent, i);
+ }
+ }
+ }
+}
diff --git a/mono/dis/dis-cil.h b/mono/dis/dis-cil.h
new file mode 100644
index 00000000000..df686247fcc
--- /dev/null
+++ b/mono/dis/dis-cil.h
@@ -0,0 +1 @@
+void dissasemble_cil (MonoMetadata *m, MonoMethodHeader *mh);
diff --git a/mono/dis/dump.c b/mono/dis/dump.c
new file mode 100644
index 00000000000..db914cd1791
--- /dev/null
+++ b/mono/dis/dump.c
@@ -0,0 +1,471 @@
+/*
+ * dump.c: Dumping routines for the disassembler.
+ *
+ * Author:
+ * Miguel de Icaza (miguel@ximian.com)
+ *
+ * (C) 2001 Ximian, Inc.
+ */
+#include <config.h>
+#include <stdio.h>
+#include <string.h>
+#include <glib.h>
+#include "meta.h"
+#include "util.h"
+#include "dump.h"
+#include "get.h"
+
+void
+dump_table_assembly (MonoMetadata *m)
+{
+ MonoTableInfo *t = &m->tables [MONO_TABLE_ASSEMBLY];
+ guint32 cols [MONO_ASSEMBLY_SIZE];
+ const char *ptr;
+ int len;
+
+ mono_metadata_decode_row (t, 0, cols, MONO_ASSEMBLY_SIZE);
+ fprintf (output, "Assembly Table\n");
+
+ fprintf (output, "Name: %s\n", mono_metadata_string_heap (m, cols [MONO_ASSEMBLY_NAME]));
+ fprintf (output, "Hash Algoritm: 0x%08x\n", cols [MONO_ASSEMBLY_HASH_ALG]);
+ fprintf (output, "Version: %d.%d.%d.%d\n", cols [MONO_ASSEMBLY_MAJOR_VERSION],
+ cols [MONO_ASSEMBLY_MINOR_VERSION],
+ cols [MONO_ASSEMBLY_BUILD_NUMBER],
+ cols [MONO_ASSEMBLY_REV_NUMBER]);
+ fprintf (output, "Flags: 0x%08x\n", cols [MONO_ASSEMBLY_FLAGS]);
+ fprintf (output, "PublicKey: BlobPtr (0x%08x)\n", cols [MONO_ASSEMBLY_PUBLIC_KEY]);
+
+ ptr = mono_metadata_blob_heap (m, cols [MONO_ASSEMBLY_PUBLIC_KEY]);
+ len = mono_metadata_decode_value (ptr, &ptr);
+ if (len > 0){
+ fprintf (output, "\tDump:");
+ hex_dump (ptr, 0, len);
+ fprintf (output, "\n");
+ } else
+ fprintf (output, "\tZero sized public key\n");
+
+ fprintf (output, "Culture: %s\n", mono_metadata_string_heap (m, cols [MONO_ASSEMBLY_CULTURE]));
+ fprintf (output, "\n");
+}
+
+void
+dump_table_typeref (MonoMetadata *m)
+{
+ MonoTableInfo *t = &m->tables [MONO_TABLE_TYPEREF];
+ int i;
+
+ fprintf (output, "Typeref Table\n");
+
+ for (i = 1; i <= t->rows; i++){
+ char *s = get_typeref (m, i);
+
+ fprintf (output, "%d: %s\n", i, s);
+ g_free (s);
+ }
+ fprintf (output, "\n");
+}
+
+void
+dump_table_typedef (MonoMetadata *m)
+{
+ MonoTableInfo *t = &m->tables [MONO_TABLE_TYPEDEF];
+ int i;
+
+ fprintf (output, "Typedef Table\n");
+
+ for (i = 1; i <= t->rows; i++){
+ char *s = get_typedef (m, i);
+ guint32 cols [MONO_TYPEDEF_SIZE];
+
+ mono_metadata_decode_row (&m->tables [MONO_TABLE_TYPEDEF], i - 1, cols, MONO_TYPEDEF_SIZE);
+
+ fprintf (output, "%d: %s (flist=%d, mlist=%d)\n", i, s, cols [MONO_TYPEDEF_FIELD_LIST], cols [MONO_TYPEDEF_METHOD_LIST]);
+ g_free (s);
+ }
+ fprintf (output, "\n");
+}
+
+void
+dump_table_assemblyref (MonoMetadata *m)
+{
+ MonoTableInfo *t = &m->tables [MONO_TABLE_ASSEMBLYREF];
+ int i;
+
+ fprintf (output, "AssemblyRef Table\n");
+
+ for (i = 0; i < t->rows; i++){
+ const char *ptr;
+ int len;
+ guint32 cols [MONO_ASSEMBLYREF_SIZE];
+
+ mono_metadata_decode_row (t, i, cols, MONO_ASSEMBLYREF_SIZE);
+ fprintf (output, "%d: Version=%d.%d.%d.%d\n\tName=%s\n", i,
+ cols [MONO_ASSEMBLYREF_MAJOR_VERSION],
+ cols [MONO_ASSEMBLYREF_MINOR_VERSION],
+ cols [MONO_ASSEMBLYREF_BUILD_NUMBER],
+ cols [MONO_ASSEMBLYREF_REV_NUMBER],
+ mono_metadata_string_heap (m, cols [MONO_ASSEMBLYREF_NAME]));
+ ptr = mono_metadata_blob_heap (m, cols [MONO_ASSEMBLYREF_PUBLIC_KEY]);
+ len = mono_metadata_decode_value (ptr, &ptr);
+ if (len > 0){
+ fprintf (output, "\tPublic Key:");
+ hex_dump (ptr, 0, len);
+ fprintf (output, "\n");
+ } else
+ fprintf (output, "\tZero sized public key\n");
+
+ }
+ fprintf (output, "\n");
+}
+
+void
+dump_table_param (MonoMetadata *m)
+{
+ MonoTableInfo *t = &m->tables [MONO_TABLE_PARAM];
+ int i;
+
+ fprintf (output, "Param Table\n");
+
+ for (i = 0; i < t->rows; i++){
+ guint32 cols [MONO_PARAM_SIZE];
+
+ mono_metadata_decode_row (t, i, cols, CSIZE (cols));
+ fprintf (output, "%d: 0x%04x %d %s\n",
+ i,
+ cols [MONO_PARAM_FLAGS], cols [MONO_PARAM_SEQUENCE],
+ mono_metadata_string_heap (m, cols [MONO_PARAM_NAME]));
+ }
+ fprintf (output, "\n");
+}
+
+void
+dump_table_field (MonoMetadata *m)
+{
+ MonoTableInfo *t = &m->tables [MONO_TABLE_FIELD];
+ MonoTableInfo *td = &m->tables [MONO_TABLE_TYPEDEF];
+ int i, current_type;
+ guint32 first_m, last_m;
+
+ fprintf (output, "Field Table (1..%d)\n", t->rows);
+
+ current_type = 1;
+ last_m = first_m = 1;
+ for (i = 1; i <= t->rows; i++){
+ guint32 cols [MONO_FIELD_SIZE];
+ char *sig, *flags;
+
+ /*
+ * Find the next type.
+ */
+ while (current_type <= td->rows && i >= (last_m = mono_metadata_decode_row_col (td, current_type - 1, MONO_TYPEDEF_FIELD_LIST))) {
+ current_type++;
+ }
+ if (i == first_m) {
+ fprintf (output, "########## %s.%s\n",
+ mono_metadata_string_heap (m, mono_metadata_decode_row_col (td, current_type - 2, MONO_TYPEDEF_NAMESPACE)),
+ mono_metadata_string_heap (m, mono_metadata_decode_row_col (td, current_type - 2, MONO_TYPEDEF_NAME)));
+ first_m = last_m;
+ }
+ mono_metadata_decode_row (t, i - 1, cols, MONO_FIELD_SIZE);
+ sig = get_field_signature (m, cols [MONO_FIELD_SIGNATURE]);
+ flags = field_flags (cols [MONO_FIELD_FLAGS]);
+ fprintf (output, "%d: %s %s: %s\n",
+ i,
+ sig,
+ mono_metadata_string_heap (m, cols [MONO_FIELD_NAME]),
+ flags);
+ g_free (sig);
+ g_free (flags);
+ }
+ fprintf (output, "\n");
+}
+
+void
+dump_table_memberref (MonoMetadata *m)
+{
+ MonoTableInfo *t = &m->tables [MONO_TABLE_MEMBERREF];
+ int i, kind, idx;
+ char *ks, *x, *xx;
+
+ fprintf (output, "MemberRef Table (0..%d)\n", t->rows);
+
+ for (i = 0; i < t->rows; i++){
+ guint32 cols [MONO_MEMBERREF_SIZE];
+
+ mono_metadata_decode_row (t, i, cols, MONO_MEMBERREF_SIZE);
+
+ kind = cols [MONO_MEMBERREF_CLASS] & 7;
+ idx = cols [MONO_MEMBERREF_CLASS] >> 3;
+
+ x = g_strdup ("UNHANDLED CASE");
+
+ switch (kind){
+ case 0:
+ ks = "TypeDef"; break;
+ case 1:
+ ks = "TypeRef";
+ xx = get_typeref (m, idx);
+ x = g_strconcat (xx, ".", mono_metadata_string_heap (m, cols [MONO_MEMBERREF_NAME]), NULL);
+ g_free (xx);
+ break;
+ case 2:
+ ks = "ModuleRef"; break;
+ case 3:
+ ks = "MethodDef"; break;
+ case 4:
+ ks = "TypeSpec"; break;
+ default:
+ g_error ("Unknown tag: %d\n", kind);
+ }
+
+ fprintf (output, "%d: %s[%d] %s\n\tResolved: %s\n\tSignature: %s\n\t\n",
+ i,
+ ks, idx,
+ mono_metadata_string_heap (m, cols [MONO_MEMBERREF_NAME]),
+ x ? x : "",
+ get_methodref_signature (m, cols [MONO_MEMBERREF_SIGNATURE], NULL));
+
+ if (x)
+ g_free (x);
+ }
+}
+
+void
+dump_table_class_layout (MonoMetadata *m)
+{
+ MonoTableInfo *t = &m->tables [MONO_TABLE_CLASSLAYOUT];
+ int i;
+ fprintf (output, "ClassLayout Table (0..%d)\n", t->rows);
+
+ for (i = 0; i < t->rows; i++){
+ guint32 cols [MONO_CLASS_LAYOUT_SIZE];
+
+ mono_metadata_decode_row (t, i, cols, CSIZE (cols));
+
+ fprintf (output, "%d: PackingSize=%d ClassSize=%d Parent=%s\n",
+ i, cols [MONO_CLASS_LAYOUT_PACKING_SIZE],
+ cols [MONO_CLASS_LAYOUT_CLASS_SIZE],
+ get_typedef (m, cols [MONO_CLASS_LAYOUT_PARENT]));
+ }
+}
+
+void
+dump_table_constant (MonoMetadata *m)
+{
+ MonoTableInfo *t = &m->tables [MONO_TABLE_CONSTANT];
+ int i;
+ fprintf (output, "Constant Table (0..%d)\n", t->rows);
+
+ for (i = 0; i < t->rows; i++){
+ guint32 cols [MONO_CONSTANT_SIZE];
+
+ mono_metadata_decode_row (t, i, cols, MONO_CONSTANT_SIZE);
+
+ fprintf (output, "%d: Parent=0x%08x %s\n",
+ i, cols [MONO_CONSTANT_PARENT],
+ get_constant (m, (MonoTypeEnum) cols [MONO_CONSTANT_TYPE], cols [MONO_CONSTANT_VALUE]));
+ }
+
+}
+
+void
+dump_table_property_map (MonoMetadata *m)
+{
+ MonoTableInfo *t = &m->tables [MONO_TABLE_PROPERTYMAP];
+ int i;
+ char *s;
+
+ fprintf (output, "Property Map Table (1..%d)\n", t->rows);
+
+ for (i = 0; i < t->rows; i++){
+ guint32 cols [MONO_PROPERTY_MAP_SIZE];
+
+ mono_metadata_decode_row (t, i, cols, MONO_PROPERTY_MAP_SIZE);
+ s = get_typedef (m, cols [MONO_PROPERTY_MAP_PARENT]);
+ fprintf (output, "%d: %s %d\n", i + 1, s, cols [MONO_PROPERTY_MAP_PROPERTY_LIST]);
+ g_free (s);
+ }
+}
+
+void
+dump_table_property (MonoMetadata *m)
+{
+ MonoTableInfo *t = &m->tables [MONO_TABLE_PROPERTY];
+ int i, j, pcount;
+ const char *ptr;
+ char flags[128];
+
+ fprintf (output, "Property Table (1..%d)\n", t->rows);
+
+ for (i = 0; i < t->rows; i++){
+ guint32 cols [MONO_PROPERTY_SIZE];
+ char *type;
+ int bsize;
+ int prop_flags;
+
+ mono_metadata_decode_row (t, i, cols, MONO_PROPERTY_SIZE);
+ flags [0] = 0;
+ prop_flags = cols [MONO_PROPERTY_FLAGS];
+ if (prop_flags & 0x0200)
+ strcat (flags, "special ");
+ if (prop_flags & 0x0400)
+ strcat (flags, "runtime ");
+ if (prop_flags & 0x1000)
+ strcat (flags, "hasdefault ");
+
+ ptr = mono_metadata_blob_heap (m, cols [MONO_PROPERTY_TYPE]);
+ bsize = mono_metadata_decode_blob_size (ptr, &ptr);
+ /* ECMA claims 0x08 ... */
+ if (*ptr != 0x28 && *ptr != 0x08)
+ g_warning("incorrect signature in propert blob: 0x%x", *ptr);
+ ptr++;
+ pcount = mono_metadata_decode_value (ptr, &ptr);
+ ptr = get_type (m, ptr, &type);
+ fprintf (output, "%d: %s %s (",
+ i + 1, type, mono_metadata_string_heap (m, cols [MONO_PROPERTY_NAME]));
+ g_free (type);
+
+ for (j = 0; j < pcount; j++){
+ ptr = get_param (m, ptr, &type);
+ fprintf (output, "%s%s", j > 0? ", " : "",type);
+ g_free (type);
+ }
+ fprintf (output, ") %s\n", flags);
+ }
+}
+
+void
+dump_table_event (MonoMetadata *m)
+{
+ MonoTableInfo *t = &m->tables [MONO_TABLE_EVENT];
+ int i;
+ fprintf (output, "Event Table (0..%d)\n", t->rows);
+
+ for (i = 0; i < t->rows; i++){
+ guint32 cols [MONO_EVENT_SIZE];
+ const char *name;
+ char *type;
+
+ mono_metadata_decode_row (t, i, cols, MONO_EVENT_SIZE);
+
+ name = mono_metadata_string_heap (m, cols [MONO_EVENT_NAME]);
+ type = get_typedef_or_ref (m, cols [MONO_EVENT_TYPE]);
+ fprintf (output, "%d: %s %s %s\n", i, type, name,
+ cols [MONO_EVENT_FLAGS] & 0x200 ? "specialname " : "");
+ g_free (type);
+ }
+
+}
+
+void
+dump_table_file (MonoMetadata *m)
+{
+ MonoTableInfo *t = &m->tables [MONO_TABLE_FILE];
+ int i;
+ fprintf (output, "File Table (0..%d)\n", t->rows);
+
+ for (i = 0; i < t->rows; i++){
+ guint32 cols [MONO_FILE_SIZE];
+ const char *name;
+
+ mono_metadata_decode_row (t, i, cols, MONO_FILE_SIZE);
+
+ name = mono_metadata_string_heap (m, cols [MONO_FILE_NAME]);
+ fprintf (output, "%d: %s %s\n", i, name,
+ cols [MONO_FILE_FLAGS] & 0x1 ? "nometadata" : "containsmetadata");
+ }
+
+}
+
+void
+dump_table_moduleref (MonoMetadata *m)
+{
+ MonoTableInfo *t = &m->tables [MONO_TABLE_MODULEREF];
+ int i;
+ fprintf (output, "ModuleRef Table (0..%d)\n", t->rows);
+
+ for (i = 0; i < t->rows; i++){
+ guint32 cols [MONO_MODULEREF_SIZE];
+ const char *name;
+
+ mono_metadata_decode_row (t, i, cols, MONO_MODULEREF_SIZE);
+
+ name = mono_metadata_string_heap (m, cols [MONO_MODULEREF_NAME]);
+ fprintf (output, "%d: %s\n", i, name);
+ }
+
+}
+
+void
+dump_table_method (MonoMetadata *m)
+{
+ MonoTableInfo *t = &m->tables [MONO_TABLE_METHOD];
+ MonoTableInfo *td = &m->tables [MONO_TABLE_TYPEDEF];
+ int i, current_type;
+ guint32 first_m, last_m;
+ fprintf (output, "Method Table (1..%d)\n", t->rows);
+
+ current_type = 1;
+ last_m = first_m = 1;
+ for (i = 1; i <= t->rows; i++){
+ guint32 cols [MONO_METHOD_SIZE];
+ char *sig;
+ const char *sigblob;
+ MonoMethodSignature *method;
+
+ /*
+ * Find the next type.
+ */
+ while (current_type <= td->rows && i >= (last_m = mono_metadata_decode_row_col (td, current_type - 1, MONO_TYPEDEF_METHOD_LIST))) {
+ current_type++;
+ }
+ if (i == first_m) {
+ fprintf (output, "########## %s.%s\n",
+ mono_metadata_string_heap (m, mono_metadata_decode_row_col (td, current_type - 2, MONO_TYPEDEF_NAMESPACE)),
+ mono_metadata_string_heap (m, mono_metadata_decode_row_col (td, current_type - 2, MONO_TYPEDEF_NAME)));
+ first_m = last_m;
+ }
+ mono_metadata_decode_row (t, i - 1, cols, MONO_METHOD_SIZE);
+ sigblob = mono_metadata_blob_heap (m, cols [MONO_METHOD_SIGNATURE]);
+ mono_metadata_decode_blob_size (sigblob, &sigblob);
+ method = mono_metadata_parse_method_signature (m, 1, sigblob, &sigblob);
+ sig = dis_stringify_method_signature (m, method, i);
+ fprintf (output, "%d: %s\n", i, sig);
+ g_free (sig);
+ mono_metadata_free_method_signature (method);
+ }
+
+}
+
+static map_t semantics_map [] = {
+ {1, "setter"},
+ {2, "getter"},
+ {4, "other"},
+ {8, "add-on"},
+ {0x10, "remove-on"},
+ {0x20, "fire"},
+ {0, NULL},
+};
+
+void
+dump_table_methodsem (MonoMetadata *m)
+{
+ MonoTableInfo *t = &m->tables [MONO_TABLE_METHODSEMANTICS];
+ int i, is_property, index;
+ const char *semantics;
+
+ fprintf (output, "Method Semantics Table (1..%d)\n", t->rows);
+ for (i = 1; i <= t->rows; i++){
+ guint32 cols [MONO_METHOD_SEMA_SIZE];
+
+ mono_metadata_decode_row (t, i - 1, cols, MONO_METHOD_SEMA_SIZE);
+ semantics = flags (cols [MONO_METHOD_SEMA_SEMANTICS], semantics_map);
+ is_property = cols [MONO_METHOD_SEMA_ASSOCIATION] & 1;
+ index = cols [MONO_METHOD_SEMA_ASSOCIATION] >> 1;
+ fprintf (output, "%d: %s method: %d %s %d\n", i, semantics,
+ cols [MONO_METHOD_SEMA_METHOD] - 1,
+ is_property? "property" : "event",
+ index);
+ }
+}
+
diff --git a/mono/dis/dump.h b/mono/dis/dump.h
new file mode 100644
index 00000000000..e52aa3a0324
--- /dev/null
+++ b/mono/dis/dump.h
@@ -0,0 +1,18 @@
+extern FILE *output;
+
+void dump_table_assembly (MonoMetadata *m);
+void dump_table_assemblyref (MonoMetadata *m);
+void dump_table_class_layout (MonoMetadata *m);
+void dump_table_constant (MonoMetadata *m);
+void dump_table_property (MonoMetadata *m);
+void dump_table_property_map (MonoMetadata *m);
+void dump_table_event (MonoMetadata *m);
+void dump_table_file (MonoMetadata *m);
+void dump_table_moduleref (MonoMetadata *m);
+void dump_table_method (MonoMetadata *m);
+void dump_table_methodsem (MonoMetadata *m);
+void dump_table_field (MonoMetadata *m);
+void dump_table_memberref (MonoMetadata *m);
+void dump_table_param (MonoMetadata *m);
+void dump_table_typedef (MonoMetadata *m);
+void dump_table_typeref (MonoMetadata *m);
diff --git a/mono/dis/get.c b/mono/dis/get.c
new file mode 100644
index 00000000000..a6b8acfc8eb
--- /dev/null
+++ b/mono/dis/get.c
@@ -0,0 +1,1194 @@
+/*
+ * get.c: Functions to get stringified values from the metadata tables.
+ *
+ * Author:
+ * Miguel de Icaza (miguel@ximian.com)
+ *
+ * (C) 2001 Ximian, Inc.
+ */
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <glib.h>
+#include "meta.h"
+#include "util.h"
+#include "get.h"
+
+char *
+get_typedef (MonoMetadata *m, int idx)
+{
+ guint32 cols [MONO_TYPEDEF_SIZE];
+
+ mono_metadata_decode_row (&m->tables [MONO_TABLE_TYPEDEF], idx - 1, cols, MONO_TYPEDEF_SIZE);
+
+ return g_strdup_printf (
+ "%s.%s",
+ mono_metadata_string_heap (m, cols [MONO_TYPEDEF_NAMESPACE]),
+ mono_metadata_string_heap (m, cols [MONO_TYPEDEF_NAME]));
+}
+
+char *
+get_module (MonoMetadata *m, int idx)
+{
+ guint32 cols [MONO_MODULE_SIZE];
+
+ /*
+ * There MUST BE only one module in the Module table
+ */
+ g_assert (idx == 1);
+
+ mono_metadata_decode_row (&m->tables [MONO_TABLE_MODULEREF], idx - 1, cols, MONO_MODULE_SIZE);
+
+ return g_strdup (mono_metadata_string_heap (m, cols [MONO_MODULE_NAME]));
+}
+
+char *
+get_assemblyref (MonoMetadata *m, int idx)
+{
+ guint32 cols [MONO_ASSEMBLYREF_SIZE];
+
+ mono_metadata_decode_row (&m->tables [MONO_TABLE_ASSEMBLYREF], idx - 1, cols, MONO_ASSEMBLYREF_SIZE);
+
+ return g_strdup (mono_metadata_string_heap (m, cols [MONO_ASSEMBLYREF_NAME]));
+}
+
+/*
+ *
+ * Returns a string representing the ArrayShape (22.2.16).
+ */
+static const char *
+get_array_shape (MonoMetadata *m, const char *ptr, char **result)
+{
+ GString *res = g_string_new ("[");
+ guint32 rank, num_sizes, num_lo_bounds;
+ guint32 *sizes = NULL, *lo_bounds = NULL;
+ int i, r;
+ char buffer [80];
+
+ rank = mono_metadata_decode_value (ptr, &ptr);
+ num_sizes = mono_metadata_decode_value (ptr, &ptr);
+
+ if (num_sizes > 0)
+ sizes = g_new (guint32, num_sizes);
+
+ for (i = 0; i < num_sizes; i++)
+ sizes [i] = mono_metadata_decode_value (ptr, &ptr);
+
+ num_lo_bounds = mono_metadata_decode_value (ptr, &ptr);
+ if (num_lo_bounds > 0)
+ lo_bounds = g_new (guint32, num_lo_bounds);
+
+ for (i = 0; i < num_lo_bounds; i++)
+ lo_bounds [i] = mono_metadata_decode_value (ptr, &ptr);
+
+ for (r = 0; r < rank; r++){
+ if (r < num_sizes){
+ if (r < num_lo_bounds){
+ sprintf (buffer, "%d..%d", lo_bounds [r], lo_bounds [r] + sizes [r] - 1);
+ } else {
+ sprintf (buffer, "0..%d", sizes [r] - 1);
+ }
+ } else
+ buffer [0] = 0;
+
+ g_string_append (res, buffer);
+ if ((r + 1) != rank)
+ g_string_append (res, ", ");
+ }
+ g_string_append (res, "]");
+
+ if (sizes)
+ g_free (sizes);
+
+ if (lo_bounds)
+ g_free (lo_bounds);
+
+ *result = res->str;
+ g_string_free (res, FALSE);
+
+ return ptr;
+}
+
+/**
+ * get_typespec:
+ * @m: metadata context
+ * @blob_idx: index into the blob heap
+ *
+ * Returns the stringified representation of a TypeSpec signature (22.2.17)
+ */
+char *
+get_typespec (MonoMetadata *m, guint32 idx)
+{
+ guint32 cols [MONO_TYPESPEC_SIZE];
+ const char *ptr;
+ char *s, *result;
+ GString *res = g_string_new ("");
+ int len;
+
+ mono_metadata_decode_row (&m->tables [MONO_TABLE_TYPESPEC], idx-1, cols, MONO_TYPESPEC_SIZE);
+ ptr = mono_metadata_blob_heap (m, cols [MONO_TYPESPEC_SIGNATURE]);
+ len = mono_metadata_decode_value (ptr, &ptr);
+
+ switch (*ptr++){
+ case MONO_TYPE_PTR:
+ ptr = get_custom_mod (m, ptr, &s);
+ if (s){
+ g_string_append (res, s);
+ g_string_append_c (res, ' ');
+ g_free (s);
+ }
+
+ if (*ptr == MONO_TYPE_VOID)
+ g_string_append (res, "void");
+ else {
+ ptr = get_type (m, ptr, &s);
+ if (s)
+ g_string_append (res, s);
+ }
+ break;
+
+ case MONO_TYPE_FNPTR:
+ g_string_append (res, "FNPTR ");
+ /*
+ * we assume MethodRefSig, as we do not know
+ * whether it is a MethodDefSig or a MethodRefSig.
+ */
+ printf ("\n FNPTR:\n");
+
+ hex_dump (ptr, 0, 40);
+ break;
+
+ case MONO_TYPE_ARRAY:
+ ptr = get_type (m, ptr, &s);
+ g_string_append (res, s);
+ g_free (s);
+ g_string_append_c (res, ' ');
+ ptr = get_array_shape (m, ptr, &s);
+ g_string_append (res, s);
+ g_free (s);
+ break;
+
+ case MONO_TYPE_SZARRAY:
+ ptr = get_custom_mod (m, ptr, &s);
+ if (s){
+ g_string_append (res, s);
+ g_string_append_c (res, ' ');
+ g_free (s);
+ }
+ ptr = get_type (m, ptr, &s);
+ g_string_append (res, s);
+ g_string_append (res, "[]");
+ g_free (s);
+ }
+
+ result = res->str;
+ g_string_free (res, FALSE);
+
+ return result;
+}
+
+char *
+get_typeref (MonoMetadata *m, int idx)
+{
+ guint32 cols [MONO_TYPEREF_SIZE];
+ const char *s, *t;
+ char *x, *ret;
+ guint32 rs_idx, table;
+
+ mono_metadata_decode_row (&m->tables [MONO_TABLE_TYPEREF], idx - 1, cols, MONO_TYPEREF_SIZE);
+
+ t = mono_metadata_string_heap (m, cols [MONO_TYPEREF_NAME]);
+ s = mono_metadata_string_heap (m, cols [MONO_TYPEREF_NAMESPACE]);
+
+ rs_idx = cols [MONO_TYPEREF_SCOPE] >> 2;
+ /*
+ * Two bits in Beta2.
+ * ECMA spec claims 3 bits
+ */
+ table = cols [MONO_TYPEREF_SCOPE] & 3;
+
+ switch (table){
+ case 0: /* Module */
+ x = get_module (m, rs_idx);
+ ret = g_strdup_printf ("TODO:TypeRef-Module [%s] %s.%s", x, s, t);
+ g_free (x);
+ break;
+
+ case 1: /* ModuleRef */
+ ret = g_strdup_printf ("TODO:TypeRef-ModuleRef (%s.%s)", s, t);
+ break;
+
+ case 2: /*
+ * AssemblyRef (ECMA docs claim it is 3, but it looks to
+ * me like it is 2 (tokens are prefixed with 0x23)
+ */
+ x = get_assemblyref (m, rs_idx);
+ ret = g_strdup_printf ("[%s] %s.%s", x, s, t);
+ g_free (x);
+ break;
+
+ case 4: /* TypeRef */
+ ret = g_strdup_printf ("TODO:TypeRef-TypeRef: TYPEREF! (%s.%s)", s, t);
+ break;
+
+ default:
+ ret = g_strdup_printf ("Unknown table in TypeRef %d", table);
+ }
+
+ return ret;
+}
+
+/**
+ * get_typedef_or_ref:
+ * @m: metadata context
+ * @dor_token: def or ref encoded index
+ *
+ * Low two bits contain table to lookup from
+ * high bits contain the index into the def or ref table
+ *
+ * Returns: a stringified version of the MethodDef or MethodRef
+ * at (dor_token >> 2)
+ */
+char *
+get_typedef_or_ref (MonoMetadata *m, guint32 dor_token)
+{
+ char *temp = NULL, *s;
+ int table, idx;
+
+ /*
+ * low 2 bits contain encoding
+ */
+ table = dor_token & 0x03;
+ idx = dor_token >> 2;
+
+ switch (table){
+ case 0: /* TypeDef */
+ temp = get_typedef (m, idx);
+ s = g_strdup_printf ("%s", temp);
+ break;
+
+ case 1: /* TypeRef */
+ temp = get_typeref (m, idx);
+ s = g_strdup_printf ("%s", temp);
+ break;
+
+ case 2: /* TypeSpec */
+ s = get_typespec (m, idx);
+ break;
+
+ default:
+ g_error ("Unhandled encoding for typedef-or-ref coded index");
+
+ }
+
+ if (temp)
+ g_free (temp);
+
+ return s;
+}
+
+/**
+ * get_encoded_typedef_or_ref:
+ * @m: metadata context
+ * @ptr: location to decode from.
+ * @result: pointer to string where resulting decoded string is stored
+ *
+ * result will point to a g_malloc()ed string.
+ *
+ * Returns: the new ptr to continue decoding
+ */
+const char *
+get_encoded_typedef_or_ref (MonoMetadata *m, const char *ptr, char **result)
+{
+ guint32 token;
+
+ token = mono_metadata_decode_value (ptr, &ptr);
+
+ *result = get_typedef_or_ref (m, token);
+
+ return ptr;
+}
+
+/**
+ * get_custom_mod:
+ *
+ * Decodes a CustomMod (22.2.7)
+ *
+ * Returns: updated pointer location
+ */
+const char *
+get_custom_mod (MonoMetadata *m, const char *ptr, char **return_value)
+{
+ char *s;
+
+ if ((*ptr == MONO_TYPE_CMOD_OPT) ||
+ (*ptr == MONO_TYPE_CMOD_REQD)){
+ ptr++;
+ ptr = get_encoded_typedef_or_ref (m, ptr, &s);
+
+ *return_value = g_strconcat ("CMOD ", s, NULL);
+ g_free (s);
+ } else
+ *return_value = NULL;
+ return ptr;
+}
+
+
+static map_t element_type_map [] = {
+ { MONO_TYPE_END , "end" },
+ { MONO_TYPE_VOID , "void" },
+ { MONO_TYPE_BOOLEAN , "bool" },
+ { MONO_TYPE_CHAR , "char" },
+ { MONO_TYPE_I1 , "sbyte" },
+ { MONO_TYPE_U1 , "byte" },
+ { MONO_TYPE_I2 , "int16" },
+ { MONO_TYPE_U2 , "uint16" },
+ { MONO_TYPE_I4 , "int32" },
+ { MONO_TYPE_U4 , "uint32" },
+ { MONO_TYPE_I8 , "int64" },
+ { MONO_TYPE_U8 , "uint64" },
+ { MONO_TYPE_R4 , "float32" },
+ { MONO_TYPE_R8 , "float64" },
+ { MONO_TYPE_STRING , "string" },
+ { MONO_TYPE_TYPEDBYREF , "TypedByRef" },
+ { MONO_TYPE_I , "native int" },
+ { MONO_TYPE_U , "native unsigned int" },
+ { MONO_TYPE_OBJECT , "object" },
+ { 0, NULL }
+};
+
+static map_t call_conv_type_map [] = {
+ { MONO_CALL_DEFAULT , "default" },
+ { MONO_CALL_C , "c" },
+ { MONO_CALL_STDCALL , "stdcall" },
+ { MONO_CALL_THISCALL , "thiscall" },
+ { MONO_CALL_FASTCALL , "fastcall" },
+ { MONO_CALL_VARARG , "vararg" },
+ { 0, NULL }
+};
+
+char*
+dis_stringify_token (MonoMetadata *m, guint32 token)
+{
+ guint idx = token & 0xffffff;
+ switch (token >> 24) {
+ case MONO_TABLE_TYPEDEF: return get_typedef (m, idx);
+ case MONO_TABLE_TYPEREF: return get_typeref (m, idx);
+ case MONO_TABLE_TYPESPEC: return get_typespec (m, idx);
+ default:
+ break;
+ }
+ return g_strdup_printf("0x%08x", token);
+}
+
+char*
+dis_stringify_array (MonoMetadata *m, MonoArray *array)
+{
+ char *type;
+ GString *s = g_string_new("");
+ int i;
+
+ type = dis_stringify_type (m, array->type);
+ g_string_append (s, type);
+ g_free (type);
+ g_string_append_c (s, '[');
+ for (i = 0; i < array->rank; ++i) {
+ if (i)
+ g_string_append_c (s, ',');
+ if (i < array->numsizes) {
+ if (i < array->numlobounds && array->lobounds[i] != 0)
+ g_string_sprintfa (s, "%d..%d", array->lobounds[i], array->sizes[i]);
+ else
+ g_string_sprintfa (s, "%d", array->sizes[i]);
+ }
+ }
+ g_string_append_c (s, ']');
+ type = s->str;
+ g_string_free (s, FALSE);
+ return type;
+}
+
+char*
+dis_stringify_modifiers (MonoMetadata *m, int n, MonoCustomMod *mod)
+{
+ GString *s = g_string_new("");
+ char *result;
+ int i;
+ for (i = 0; i < n; ++i) {
+ char *tok = dis_stringify_token (m, mod[i].token);
+ g_string_sprintfa (s, "%s %s", mod[i].mod == MONO_TYPE_CMOD_OPT ? "opt": "reqd", tok);
+ g_free (tok);
+ }
+ g_string_append_c (s, ' ');
+ result = s->str;
+ g_string_free (s, FALSE);
+ return result;
+}
+
+char*
+dis_stringify_param (MonoMetadata *m, MonoParam *param)
+{
+ char *mods = NULL;
+ char *t;
+ char *result;
+ char *out = param->param_attrs & 2 ? "[out] ": "";
+ if (param->num_modifiers)
+ mods = dis_stringify_modifiers (m, param->num_modifiers, param->modifiers);
+ if (param->typedbyref)
+ t = g_strdup ("TypedByRef");
+ else if (!param->type)
+ t = g_strdup ("void");
+ else
+ t = dis_stringify_type (m, param->type);
+ result = g_strconcat (mods ? mods : "", out, t, NULL);
+ g_free (t);
+ g_free (mods);
+ return result;
+}
+
+char*
+dis_stringify_method_signature (MonoMetadata *m, MonoMethodSignature *method, int methoddef_row)
+{
+ guint32 cols [MONO_METHOD_SIZE];
+ guint32 pcols [MONO_PARAM_SIZE];
+ guint32 param_index = 0;
+ const char *name = "";
+ int free_method = 0;
+ char *retval;
+ GString *result = g_string_new ("");
+ int i;
+
+ g_assert (method || methoddef_row);
+
+ if (methoddef_row) {
+ mono_metadata_decode_row (&m->tables [MONO_TABLE_METHOD], methoddef_row -1, cols, MONO_METHOD_SIZE);
+ name = mono_metadata_string_heap (m, cols [MONO_METHOD_NAME]);
+ param_index = cols [MONO_METHOD_PARAMLIST];
+ if (!method) {
+ const char *sig = mono_metadata_blob_heap (m, cols [MONO_METHOD_SIGNATURE]);
+ mono_metadata_decode_blob_size (sig, &sig);
+ method = mono_metadata_parse_method_signature (m, 1, sig, &sig);
+ free_method = 1;
+ }
+ }
+
+ retval = dis_stringify_param (m, method->ret);
+ if (method->hasthis)
+ g_string_append (result, "instance ");
+ g_string_append (result, map (method->call_convention, call_conv_type_map));
+ g_string_sprintfa (result, " %s %s (", retval, name);
+ g_free (retval);
+ for (i = 0; i < method->param_count; ++i) {
+ if (param_index) {
+ mono_metadata_decode_row (&m->tables [MONO_TABLE_PARAM], param_index - 1, pcols, MONO_PARAM_SIZE);
+ name = mono_metadata_string_heap (m, pcols [MONO_PARAM_NAME]);
+ method->params [i]->param_attrs = pcols [MONO_PARAM_FLAGS];
+ param_index++;
+ } else {
+ name = "";
+ }
+ if (i)
+ g_string_append (result, ", ");
+ retval = dis_stringify_param (m, method->params [i]);
+ g_string_sprintfa (result, "%s %s", retval, name);
+ g_free (retval);
+ }
+ g_string_append (result, ") ");
+
+ if (free_method)
+ mono_metadata_free_method_signature (method);
+ retval = result->str;
+ g_string_free (result, FALSE);
+
+ return retval;
+}
+
+char*
+dis_stringify_type (MonoMetadata *m, MonoType *type)
+{
+ char *bare = NULL, *pinned = "", *byref = "";
+ char *result;
+
+ switch (type->type){
+ case MONO_TYPE_BOOLEAN:
+ case MONO_TYPE_CHAR:
+ case MONO_TYPE_I1:
+ case MONO_TYPE_U1:
+ case MONO_TYPE_I2:
+ case MONO_TYPE_U2:
+ case MONO_TYPE_I4:
+ case MONO_TYPE_U4:
+ case MONO_TYPE_I8:
+ case MONO_TYPE_U8:
+ case MONO_TYPE_R4:
+ case MONO_TYPE_R8:
+ case MONO_TYPE_I:
+ case MONO_TYPE_U:
+ case MONO_TYPE_STRING:
+ case MONO_TYPE_OBJECT:
+ case MONO_TYPE_TYPEDBYREF:
+ bare = g_strdup (map (type->type, element_type_map));
+ break;
+
+ case MONO_TYPE_VALUETYPE:
+ case MONO_TYPE_CLASS:
+ bare = dis_stringify_token (m, type->data.token);
+ break;
+
+ case MONO_TYPE_FNPTR:
+ bare = dis_stringify_method_signature (m, type->data.method, 0);
+ break;
+ case MONO_TYPE_PTR:
+ case MONO_TYPE_SZARRAY: {
+ char *child_type;
+ char *mods;
+ if (type->custom_mod) {
+ mods = dis_stringify_modifiers (m, type->data.mtype->num_modifiers, type->data.mtype->modifiers);
+ child_type = dis_stringify_type (m, type->data.mtype->type);
+ } else {
+ mods = g_strdup("");
+ child_type = dis_stringify_type (m, type->data.type);
+ }
+
+ bare = g_strdup_printf (type->type == MONO_TYPE_PTR ? "%s%s*" : "%s%s[]", mods, child_type);
+ g_free (child_type);
+ g_free (mods);
+ break;
+ }
+ case MONO_TYPE_ARRAY:
+ bare = dis_stringify_array (m, type->data.array);
+ break;
+ case MONO_TYPE_VOID:
+ bare = g_strdup ("void");
+ break;
+ default:
+ g_error ("Do not know how to stringify type 0x%x", type->type);
+ }
+
+ if (type->constraint == MONO_TYPE_PINNED)
+ pinned = " pinned";
+
+ if (type->byref)
+ byref = "&";
+
+ result = g_strconcat (bare, byref, pinned, NULL);
+
+ g_free (bare);
+
+ return result;
+}
+
+/**
+ * get_type:
+ * @m: metadata context
+ * @ptr: location to decode from.
+ * @result: pointer to string where resulting decoded string is stored
+ *
+ * This routine returs in @result the stringified type pointed by @ptr.
+ * (22.2.12)
+ *
+ * Returns: the new ptr to continue decoding
+ */
+const char *
+get_type (MonoMetadata *m, const char *ptr, char **result)
+{
+ MonoType *type = mono_metadata_parse_type (m, ptr, &ptr);
+ *result = dis_stringify_type (m, type);
+ mono_metadata_free_type (type);
+ return ptr;
+}
+
+/**
+ *
+ * Returns a stringified representation of a FieldSig (22.2.4)
+ */
+char *
+get_field_signature (MonoMetadata *m, guint32 blob_signature)
+{
+ char *allocated_modifier_string, *allocated_type_string;
+ const char *ptr = mono_metadata_blob_heap (m, blob_signature);
+ const char *base;
+ char *res;
+ int len;
+
+ len = mono_metadata_decode_value (ptr, &ptr);
+ base = ptr;
+ /* FIELD is 0x06 */
+ g_assert (*ptr == 0x06);
+/* hex_dump (ptr, 0, len); */
+ ptr++; len--;
+
+ ptr = get_custom_mod (m, ptr, &allocated_modifier_string);
+ ptr = get_type (m, ptr, &allocated_type_string);
+
+ res = g_strdup_printf (
+ "%s %s",
+ allocated_modifier_string ? allocated_modifier_string : "",
+ allocated_type_string);
+
+ if (allocated_modifier_string)
+ g_free (allocated_modifier_string);
+ if (allocated_type_string)
+ g_free (allocated_modifier_string);
+
+ return res;
+}
+
+MonoTypeEnum
+get_field_literal_type (MonoMetadata *m, guint32 blob_signature)
+{
+ const char *ptr = mono_metadata_blob_heap (m, blob_signature);
+ int len;
+ char *allocated_modifier_string;
+
+ len = mono_metadata_decode_value (ptr, &ptr);
+
+ /* FIELD is 0x06 */
+ g_assert (*ptr == 0x06);
+ ptr++; len--;
+
+ ptr = get_custom_mod (m, ptr, &allocated_modifier_string);
+ if (allocated_modifier_string)
+ g_free (allocated_modifier_string);
+
+ return (MonoTypeEnum) *ptr;
+
+}
+
+/**
+ * decode_literal:
+ * @m: metadata context
+ * @token: token to decode
+ *
+ * decodes the literal indexed by @token.
+ */
+char *
+decode_literal (MonoMetadata *m, guint32 token)
+{
+ return g_strdup ("LITERAL_VALUE");
+}
+
+/**
+ * get_ret_type:
+ * @m: metadata context
+ * @ptr: location to decode from.
+ * @result: pointer to string where resulting decoded string is stored
+ *
+ * This routine returns in @result the stringified RetType (22.2.11)
+ *
+ * Returns: the new ptr to continue decoding.
+ */
+const char *
+get_ret_type (MonoMetadata *m, const char *ptr, char **ret_type)
+{
+ GString *str = g_string_new ("");
+ char *mod = NULL;
+ char *allocated_type_string;
+
+ ptr = get_custom_mod (m, ptr, &mod);
+ if (mod){
+ g_string_append (str, mod);
+ g_string_append_c (str, ' ');
+ g_free (mod);
+ }
+
+ if (*ptr == MONO_TYPE_TYPEDBYREF){
+ /* TODO: what does `typedbyref' mean? */
+ g_string_append (str, "/* FIXME: What does this mean? */ typedbyref ");
+ ptr++;
+ } else if (*ptr == MONO_TYPE_VOID){
+ g_string_append (str, "void");
+ ptr++;
+ } else {
+ if (*ptr == MONO_TYPE_BYREF){
+ g_string_append (str, "[out] ");
+ ptr++;
+ }
+
+ ptr = get_type (m, ptr, &allocated_type_string);
+ g_string_append (str, allocated_type_string);
+ g_free (allocated_type_string);
+ }
+
+ *ret_type = str->str;
+ g_string_free (str, FALSE);
+
+ return ptr;
+}
+
+/**
+ * get_param:
+ * @m: metadata context
+ * @ptr: location to decode from.
+ * @result: pointer to string where resulting decoded string is stored
+ *
+ * This routine returns in @result the stringified Param (22.2.10)
+ *
+ * Returns: the new ptr to continue decoding.
+ */
+const char *
+get_param (MonoMetadata *m, const char *ptr, char **retval)
+{
+ GString *str = g_string_new ("");
+ char *allocated_mod_string, *allocated_type_string;
+
+ ptr = get_custom_mod (m, ptr, &allocated_mod_string);
+ if (allocated_mod_string){
+ g_string_append (str, allocated_mod_string);
+ g_string_append_c (str, ' ');
+ g_free (allocated_mod_string);
+ }
+
+ if (*ptr == MONO_TYPE_TYPEDBYREF){
+ g_string_append (str, "/*FIXME: what does typedbyref mean? */ typedbyref ");
+ ptr++;
+ } else {
+ if (*ptr == MONO_TYPE_BYREF){
+ g_string_append (str, "[out] ");
+ ptr++;
+ }
+ ptr = get_type (m, ptr, &allocated_type_string);
+ g_string_append (str, allocated_type_string);
+ g_free (allocated_type_string);
+ }
+
+ *retval = str->str;
+ g_string_free (str, FALSE);
+ return ptr;
+}
+
+static map_t param_map [] = {
+ { PARAM_ATTRIBUTE_IN, "[in] " },
+ { PARAM_ATTRIBUTE_OUT, "[out] " },
+ { PARAM_ATTRIBUTE_OPTIONAL, "optional " },
+ { PARAM_ATTRIBUTE_HAS_DEFAULT, "hasdefault " },
+ { PARAM_ATTRIBUTE_HAS_FIELD_MARSHAL, "fieldmarshal " },
+ { 0, NULL }
+};
+
+char *
+param_flags (guint32 f)
+{
+ return g_strdup (flags (f, param_map));
+}
+
+static map_t field_access_map [] = {
+ { FIELD_ATTRIBUTE_COMPILER_CONTROLLED, "compilercontrolled " },
+ { FIELD_ATTRIBUTE_PRIVATE, "private " },
+ { FIELD_ATTRIBUTE_FAM_AND_ASSEM, "famandassem " },
+ { FIELD_ATTRIBUTE_ASSEMBLY, "assembly " },
+ { FIELD_ATTRIBUTE_FAMILY, "family " },
+ { FIELD_ATTRIBUTE_FAM_OR_ASSEM, "famorassem " },
+ { FIELD_ATTRIBUTE_PUBLIC, "public " },
+ { 0, NULL }
+};
+
+static map_t field_flags_map [] = {
+ { FIELD_ATTRIBUTE_STATIC, "static " },
+ { FIELD_ATTRIBUTE_INIT_ONLY, "initonly " },
+ { FIELD_ATTRIBUTE_LITERAL, "literal " },
+ { FIELD_ATTRIBUTE_NOT_SERIALIZED, "notserialized " },
+ { FIELD_ATTRIBUTE_SPECIAL_NAME, "specialname " },
+ { FIELD_ATTRIBUTE_PINVOKE_IMPL, "FIXME:pinvokeimpl " },
+ { 0, NULL }
+};
+
+/**
+ * field_flags:
+ *
+ * Returns a stringified version of a Field's flags
+ */
+char *
+field_flags (guint32 f)
+{
+ char buffer [1024];
+ int access = f & FIELD_ATTRIBUTE_FIELD_ACCESS_MASK;
+
+ buffer [0] = 0;
+
+ strcat (buffer, map (access, field_access_map));
+ strcat (buffer, flags (f, field_flags_map));
+ return g_strdup (buffer);
+}
+
+/**
+ * Returns a stringifed representation of a MethodRefSig (22.2.2)
+ */
+char *
+get_methodref_signature (MonoMetadata *m, guint32 blob_signature, const char *fancy_name)
+{
+ GString *res = g_string_new ("");
+ const char *ptr = mono_metadata_blob_heap (m, blob_signature);
+ char *allocated_ret_type, *s;
+ gboolean seen_vararg = 0;
+ int param_count, signature_len;
+ int i;
+
+ signature_len = mono_metadata_decode_value (ptr, &ptr);
+
+ if (*ptr & 0x20){
+ if (*ptr & 0x40)
+ g_string_append (res, "explicit-this ");
+ else
+ g_string_append (res, "instance "); /* has-this */
+ }
+
+ if (*ptr & 0x05)
+ seen_vararg = 1;
+
+ ptr++;
+ param_count = mono_metadata_decode_value (ptr, &ptr);
+ ptr = get_ret_type (m, ptr, &allocated_ret_type);
+
+ g_string_append (res, allocated_ret_type);
+
+ if (fancy_name){
+ g_string_append_c (res, ' ');
+ g_string_append (res, fancy_name);
+ }
+
+ g_string_append (res, " (");
+
+ /*
+ * param_count describes parameters *before* and *after*
+ * the vararg sentinel
+ */
+ for (i = 0; i < param_count; i++){
+ char *param = NULL;
+
+ /*
+ * If ptr is a SENTINEL
+ */
+ if (*ptr == 0x41){
+ g_string_append (res, " varargs ");
+ continue;
+ }
+
+ ptr = get_param (m, ptr, &param);
+ g_string_append (res, param);
+ if (i+1 != param_count)
+ g_string_append (res, ", ");
+ g_free (param);
+ }
+ g_string_append (res, ")");
+
+ /*
+ * cleanup and return
+ */
+ g_free (allocated_ret_type);
+ s = res->str;
+ g_string_free (res, FALSE);
+ return s;
+}
+
+/**
+ * get_field:
+ * @m: metadata context
+ * @token: a FIELD_DEF token
+ *
+ * This routine has to locate the TypeDef that "owns" this Field.
+ * Since there is no backpointer in the Field table, we have to scan
+ * the TypeDef table and locate the actual "owner" of the field
+ */
+char *
+get_field (MonoMetadata *m, guint32 token)
+{
+ int idx = mono_metadata_token_index (token);
+ guint32 cols [MONO_FIELD_SIZE];
+ char *sig, *res, *type;
+ guint32 type_idx;
+
+ /*
+ * We can get here also with a MenberRef token (for a field
+ * defined in another module/assembly, just like in get_method ()
+ */
+ if (mono_metadata_token_code (token) == MONO_TOKEN_MEMBER_REF) {
+ return g_strdup_printf ("fieldref-0x%08x", token);
+ }
+ g_assert (mono_metadata_token_code (token) == MONO_TOKEN_FIELD_DEF);
+
+ mono_metadata_decode_row (&m->tables [MONO_TABLE_FIELD], idx - 1, cols, MONO_FIELD_SIZE);
+ sig = get_field_signature (m, cols [MONO_FIELD_SIGNATURE]);
+
+ /*
+ * To locate the actual "container" for this field, we have to scan
+ * the TypeDef table. LAME!
+ */
+ type_idx = mono_metadata_typedef_from_field (m, idx);
+
+ type = get_typedef (m, type_idx);
+ res = g_strdup_printf ("%s %s.%s",
+ sig, type,
+ mono_metadata_string_heap (m, cols [MONO_FIELD_NAME]));
+ g_free (type);
+ g_free (sig);
+
+ return res;
+}
+
+static char *
+get_memberref_parent (MonoMetadata *m, guint32 mrp_token)
+{
+ /*
+ * mrp_index is a MemberRefParent coded index
+ */
+ guint32 table = mrp_token & 7;
+ guint32 idx = mrp_token >> 3;
+
+ switch (table){
+ case 0: /* TypeDef */
+ return get_typedef (m, idx);
+
+ case 1: /* TypeRef */
+ return get_typeref (m, idx);
+
+ case 2: /* ModuleRef */
+ return g_strdup_printf ("TODO:MemberRefParent-ModuleRef");
+
+ case 3: /* MethodDef */
+ return g_strdup ("TODO:MethodDef");
+
+ case 4: /* TypeSpec */
+ return get_typespec (m, idx);
+ }
+ g_assert_not_reached ();
+ return NULL;
+}
+
+/**
+ * get_method:
+ * @m: metadata context
+ * @token: a METHOD_DEF or MEMBER_REF token
+ *
+ * This routine has to locate the TypeDef that "owns" this Field.
+ * Since there is no backpointer in the Field table, we have to scan
+ * the TypeDef table and locate the actual "owner" of the field
+ */
+char *
+get_method (MonoMetadata *m, guint32 token)
+{
+ int idx = mono_metadata_token_index (token);
+ guint32 member_cols [MONO_MEMBERREF_SIZE], method_cols [MONO_METHOD_SIZE];
+ char *res, *class, *fancy_name, *sig;
+ const char *name;
+
+ switch (mono_metadata_token_code (token)){
+ case MONO_TOKEN_METHOD_DEF:
+ mono_metadata_decode_row (&m->tables [MONO_TABLE_METHOD],
+ idx - 1, method_cols, MONO_METHOD_SIZE);
+
+ name = mono_metadata_string_heap (m, method_cols [MONO_METHOD_NAME]);
+
+ sig = get_methodref_signature (m, method_cols [MONO_METHOD_SIGNATURE], name);
+ return sig;
+
+ case MONO_TOKEN_MEMBER_REF: {
+
+ mono_metadata_decode_row (&m->tables [MONO_TABLE_MEMBERREF],
+ idx - 1, member_cols, MONO_MEMBERREF_SIZE);
+ class = get_memberref_parent (m, member_cols [MONO_MEMBERREF_CLASS]);
+ fancy_name = g_strconcat (
+ class, "::",
+ mono_metadata_string_heap (m, member_cols [MONO_MEMBERREF_NAME]),
+ NULL);
+
+ sig = get_methodref_signature (
+ m, member_cols [MONO_MEMBERREF_SIGNATURE], fancy_name);
+ g_free (fancy_name);
+
+ res = g_strdup_printf ("%s", sig);
+ g_free (sig);
+ return res;
+ }
+
+ default:
+ g_assert_not_reached ();
+ }
+ g_assert_not_reached ();
+ return NULL;
+}
+
+/**
+ * get_constant:
+ * @m: metadata context
+ * @blob_index: index into the blob where the constant is stored
+ *
+ * Returns: An allocated value representing a stringified version of the
+ * constant.
+ */
+char *
+get_constant (MonoMetadata *m, MonoTypeEnum t, guint32 blob_index)
+{
+ const char *ptr = mono_metadata_blob_heap (m, blob_index);
+ int len;
+
+ len = mono_metadata_decode_value (ptr, &ptr);
+
+ switch (t){
+ case MONO_TYPE_BOOLEAN:
+ return g_strdup_printf ("%s", *ptr ? "true" : "false");
+
+ case MONO_TYPE_CHAR:
+ return g_strdup_printf ("%c", *ptr);
+
+ case MONO_TYPE_U1:
+ return g_strdup_printf ("0x%02x", (int) (*ptr));
+ break;
+
+ case MONO_TYPE_I2:
+ return g_strdup_printf ("%d", (int) (*(gint16 *) ptr));
+
+ case MONO_TYPE_I4:
+ return g_strdup_printf ("%d", *(gint32 *) ptr);
+
+ case MONO_TYPE_I8:
+ /*
+ * FIXME: This is not endian portable, does only
+ * matter for debugging, but still.
+ */
+ return g_strdup_printf ("0x%08x%08x", *(guint32 *) ptr, *(guint32 *) (ptr + 4));
+
+ case MONO_TYPE_U8:
+ return g_strdup_printf ("0x%08x%08x", *(guint32 *) ptr, *(guint32 *) (ptr + 4));
+ case MONO_TYPE_R4:
+ return g_strdup_printf ("%g", (double) (* (float *) ptr));
+
+ case MONO_TYPE_R8:
+ return g_strdup_printf ("%g", * (double *) ptr);
+
+ case MONO_TYPE_STRING: {
+ int len, i, j, e;
+ char *res;
+ e = len = 0;
+ for (i = 0; !ptr [i+1]; i += 2){
+ len++;
+ switch (ptr [i]) {
+ case '"':
+ case '\\':
+ case '\n': /* add more */
+ e++;
+ }
+ }
+ res = g_malloc (len + e + 3);
+ j = 1;
+ res [0] = '"';
+
+ for (i = 0; i < len; i += 2){
+ switch(ptr[i]) {
+ case '"':
+ res[j++] = '\\';
+ res[j++] = '"';
+ case '\\':
+ res[j++] = '\\';
+ res[j++] = '\\';
+ case '\n':
+ res[j++] = '\\';
+ res[j++] = 'n';
+ break;
+ default:
+ res[j++] = isprint (ptr [i]) ? ptr [i] : '.';
+ break;
+ }
+ }
+ res[j++] = '"';
+ res[j] = 0;
+ return res;
+ }
+
+ case MONO_TYPE_CLASS:
+ return g_strdup ("CLASS CONSTANT. MUST BE ZERO");
+
+ /*
+ * These are non CLS compliant:
+ */
+ case MONO_TYPE_I1:
+ return g_strdup_printf ("%d", (int) *ptr);
+
+ case MONO_TYPE_U2:
+ return g_strdup_printf ("0x%04x", (unsigned int) (*(guint16 *) ptr));
+
+ case MONO_TYPE_U4:
+ return g_strdup_printf ("0x%04x", (unsigned int) (*(guint32 *) ptr));
+
+ default:
+ g_error ("Unknown MONO_TYPE (%d) on constant at Blob index (0x%08x)\n",
+ (int) *ptr, blob_index);
+ return g_strdup_printf ("Unknown");
+ }
+
+}
+
+/**
+ * get_token:
+ * @m: metadata context
+ * @token: token that we want to decode.
+ *
+ * Returns: An allocated value representing a stringified version of the
+ * constant.
+ */
+char *
+get_token (MonoMetadata *m, guint32 token)
+{
+ guint32 idx = mono_metadata_token_index (token);
+
+ switch (mono_metadata_token_code (token)){
+ case MONO_TOKEN_FIELD_DEF:
+ return (get_field (m, token));
+ case MONO_TOKEN_TYPE_DEF:
+ return get_typedef (m, idx);
+ case MONO_TOKEN_TYPE_REF:
+ return get_typeref (m, idx);
+ case MONO_TOKEN_TYPE_SPEC:
+ return get_typespec (m, idx);
+ default:
+ g_error ("Do not know how to decode tokens of type 0x%08x", token);
+ }
+
+ g_assert_not_reached ();
+ return g_strdup ("ERROR");
+}
+
+/**
+ * get_token_type:
+ * @m: metadata context
+ * @token: the token can belong to any of the following tables:
+ * MONO_TOKEN_TYPE_REF, MONO_TOKEN_TYPE_DEF, MONO_TOKEN_TYPE_SPEC
+ *
+ * Returns: a stringified version of the MethodDef or MethodRef or TypeSpecn
+ * at (token & 0xffffff)
+ */
+char *
+get_token_type (MonoMetadata *m, guint32 token)
+{
+ char *temp = NULL, *s;
+ int idx;
+
+ idx = mono_metadata_token_index (token);
+
+ switch (mono_metadata_token_code (token)){
+ case MONO_TOKEN_TYPE_DEF:
+ temp = get_typedef (m, idx);
+ s = g_strdup_printf ("%s", temp);
+ break;
+
+ case MONO_TOKEN_TYPE_REF:
+ temp = get_typeref (m, idx);
+ s = g_strdup_printf ("%s", temp);
+ break;
+
+ case MONO_TOKEN_TYPE_SPEC:
+ s = get_typespec (m, idx);
+ break;
+
+ default:
+ g_error ("Unhandled encoding for typedef-or-ref coded index");
+
+ }
+
+ if (temp)
+ g_free (temp);
+
+ return s;
+}
diff --git a/mono/dis/get.h b/mono/dis/get.h
new file mode 100644
index 00000000000..37137b917b1
--- /dev/null
+++ b/mono/dis/get.h
@@ -0,0 +1,54 @@
+
+/*
+ * These return allocated strings
+ */
+char *get_typedef (MonoMetadata *m, int idx);
+char *get_module (MonoMetadata *m, int idx);
+char *get_assemblyref (MonoMetadata *m, int idx);
+char *get_typeref (MonoMetadata *m, int idx);
+char *get_typedef_or_ref (MonoMetadata *m, guint32 dor_token);
+char *get_field_signature (MonoMetadata *m, guint32 blob_signature);
+char *decode_literal (MonoMetadata *m, guint32 token);
+char *get_field (MonoMetadata *m, guint32 token);
+char *param_flags (guint32 f);
+char *field_flags (guint32 f);
+char *get_methodref_signature (MonoMetadata *m, guint32 blob_signature, const char *fancy);
+char *get_constant (MonoMetadata *m, MonoTypeEnum t, guint32 blob_index);
+char *get_token (MonoMetadata *m, guint32 token);
+char *get_token_type (MonoMetadata *m, guint32 token);
+char *get_typespec (MonoMetadata *m, guint32 blob_idx);
+char *get_method (MonoMetadata *m, guint32 token);
+
+
+char *dis_stringify_type (MonoMetadata *m, MonoType *type);
+char *dis_stringify_token (MonoMetadata *m, guint32 token);
+char *dis_stringify_array (MonoMetadata *m, MonoArray *array);
+char *dis_stringify_modifiers (MonoMetadata *m, int n, MonoCustomMod *mod);
+char *dis_stringify_param (MonoMetadata *m, MonoParam *param);
+char *dis_stringify_method_signature (MonoMetadata *m, MonoMethodSignature *method, int methoddef_row);
+
+/*
+ * These functions are used during the decoding of streams in the
+ * metadata heaps (a simple parsing).
+ *
+ * They return the `next' location to continue parsing from (ptr is
+ * the starting location).
+ *
+ * Results are returning in the pointer argument.
+ */
+const char *get_encoded_typedef_or_ref (MonoMetadata *m, const char *ptr,
+ char **result);
+const char *get_encoded_value (const char *_ptr,
+ guint32 *len);
+const char *get_custom_mod (MonoMetadata *m, const char *ptr,
+ char **return_value);
+const char *get_type (MonoMetadata *m, const char *ptr,
+ char **result);
+const char *get_ret_type (MonoMetadata *m, const char *ptr,
+ char **ret_type);
+const char *get_param (MonoMetadata *m, const char *ptr,
+ char **retval);
+const char *get_blob_encoded_size (const char *ptr, int *size);
+
+MonoTypeEnum get_field_literal_type (MonoMetadata *m, guint32 blob_signature);
+
diff --git a/mono/dis/main.c b/mono/dis/main.c
index 49f9027c1e2..955e23c258f 100644
--- a/mono/dis/main.c
+++ b/mono/dis/main.c
@@ -1,24 +1,37 @@
/*
- * dis.c: Sample disassembler
+ * main.c: Sample disassembler
*
* Author:
* Miguel de Icaza (miguel@ximian.com)
*
* (C) 2001 Ximian, Inc.
+ *
+ * TODO:
+ * Investigate how interface inheritance works and how it should be dumped.
+ * Structs are not being labeled as `valuetype' classes
+ *
+ * How are fields with literals mapped to constants?
*/
#include <config.h>
#include <stdio.h>
+#include <string.h>
#include <glib.h>
-#include <mono/metadata/assembly.h>
-#include <mono/metadata/cil-coff.h>
+#include <stdlib.h>
+#include "meta.h"
+#include "util.h"
+#include "dump.h"
+#include "get.h"
+#include "dis-cil.h"
FILE *output;
/* True if you want to get a dump of the header data */
gboolean dump_header_data_p = FALSE;
+int dump_table = -1;
+
static void
-dump_header_data (MonoAssembly *ass)
+dump_header_data (MonoImage *img)
{
if (!dump_header_data_p)
return;
@@ -29,26 +42,738 @@ dump_header_data (MonoAssembly *ass)
}
static void
-disassemble_file (const char *file)
+dis_directive_assembly (MonoMetadata *m)
{
- enum MonoAssemblyOpenStatus status;
- MonoAssembly *ass;
+ MonoTableInfo *t = &m->tables [MONO_TABLE_ASSEMBLY];
+ guint32 cols [MONO_ASSEMBLY_SIZE];
+
+ if (t->base == NULL)
+ return;
- ass = mono_assembly_open (file, &status);
- if (ass == NULL){
- fprintf (stderr, "Error while trying to process %s\n", file);
+ mono_metadata_decode_row (t, 0, cols, MONO_ASSEMBLY_SIZE);
+
+ fprintf (output,
+ ".assembly %s\n"
+ "{\n"
+ " .hash algorithm 0x%08x\n"
+ " .ver %d.%d.%d.%d"
+ "%s %s"
+ "%s"
+ "\n"
+ "}\n",
+ mono_metadata_string_heap (m, cols [MONO_ASSEMBLY_NAME]),
+ cols [MONO_ASSEMBLY_HASH_ALG],
+ cols [MONO_ASSEMBLY_MAJOR_VERSION], cols [MONO_ASSEMBLY_MINOR_VERSION],
+ cols [MONO_ASSEMBLY_BUILD_NUMBER], cols [MONO_ASSEMBLY_REV_NUMBER],
+ cols [MONO_ASSEMBLY_CULTURE] ? "\n .locale" : "",
+ cols [MONO_ASSEMBLY_CULTURE] ? mono_metadata_string_heap (m, cols [MONO_ASSEMBLY_CULTURE]) : "",
+ cols [MONO_ASSEMBLY_PUBLIC_KEY] ? "\n .publickey" : ""
+ );
+}
+
+static void
+dis_directive_assemblyref (MonoMetadata *m)
+{
+ MonoTableInfo *t = &m->tables [MONO_TABLE_ASSEMBLYREF];
+ guint32 cols [MONO_ASSEMBLYREF_SIZE];
+ int i;
+
+ if (t->base == NULL)
+ return;
+
+ for (i = 0; i < t->rows; i++){
+ mono_metadata_decode_row (t, i, cols, MONO_ASSEMBLYREF_SIZE);
+
+ fprintf (output,
+ ".assembly extern %s\n"
+ "{\n"
+ " .ver %d.%d.%d.%d\n"
+ "}\n",
+ mono_metadata_string_heap (m, cols [MONO_ASSEMBLYREF_NAME]),
+ cols [MONO_ASSEMBLYREF_MAJOR_VERSION], cols [MONO_ASSEMBLYREF_MINOR_VERSION],
+ cols [MONO_ASSEMBLYREF_BUILD_NUMBER], cols [MONO_ASSEMBLYREF_REV_NUMBER]
+ );
+ }
+}
+
+static map_t visibility_map [] = {
+ { TYPE_ATTRIBUTE_NOT_PUBLIC, "private " },
+ { TYPE_ATTRIBUTE_PUBLIC, "public " },
+ { TYPE_ATTRIBUTE_NESTED_PUBLIC, "nested-public " },
+ { TYPE_ATTRIBUTE_NESTED_PRIVATE, "nested-private " },
+ { TYPE_ATTRIBUTE_NESTED_FAMILY, "family " },
+ { TYPE_ATTRIBUTE_NESTED_ASSEMBLY, "nested-assembly" },
+ { TYPE_ATTRIBUTE_NESTED_FAM_AND_ASSEM, "nested-fam-and-assembly" },
+ { TYPE_ATTRIBUTE_NESTED_FAM_OR_ASSEM, "nested-fam-or-assembly" },
+ { 0, NULL }
+};
+
+static map_t layout_map [] = {
+ { TYPE_ATTRIBUTE_AUTO_LAYOUT, "auto " },
+ { TYPE_ATTRIBUTE_SEQUENTIAL_LAYOUT, "sequential " },
+ { TYPE_ATTRIBUTE_EXPLICIT_LAYOUT, "explicit " },
+ { 0, NULL }
+};
+
+static map_t format_map [] = {
+ { TYPE_ATTRIBUTE_ANSI_CLASS, "ansi " },
+ { TYPE_ATTRIBUTE_UNICODE_CLASS, "unicode " },
+ { TYPE_ATTRIBUTE_AUTO_CLASS, "auto " },
+ { 0, NULL }
+};
+
+static char *
+typedef_flags (guint32 flags)
+{
+ static char buffer [1024];
+ int visibility = flags & TYPE_ATTRIBUTE_VISIBILITY_MASK;
+ int layout = flags & TYPE_ATTRIBUTE_LAYOUT_MASK;
+ int format = flags & TYPE_ATTRIBUTE_STRING_FORMAT_MASK;
+
+ buffer [0] = 0;
+
+ strcat (buffer, map (visibility, visibility_map));
+ strcat (buffer, map (layout, layout_map));
+ strcat (buffer, map (format, format_map));
+
+ if (flags & TYPE_ATTRIBUTE_ABSTRACT)
+ strcat (buffer, "abstract ");
+ if (flags & TYPE_ATTRIBUTE_SEALED)
+ strcat (buffer, "sealed ");
+ if (flags & TYPE_ATTRIBUTE_SPECIAL_NAME)
+ strcat (buffer, "special-name ");
+ if (flags & TYPE_ATTRIBUTE_IMPORT)
+ strcat (buffer, "import ");
+ if (flags & TYPE_ATTRIBUTE_SERIALIZABLE)
+ strcat (buffer, "serializable ");
+ if (flags & TYPE_ATTRIBUTE_BEFORE_FIELD_INIT)
+ strcat (buffer, "beforefieldinit ");
+
+ return buffer;
+}
+
+/**
+ * dis_field_list:
+ * @m: metadata context
+ * @start: starting index into the Field Table.
+ * @end: ending index into Field table.
+ *
+ * This routine displays all the decoded fields from @start to @end
+ */
+static void
+dis_field_list (MonoMetadata *m, guint32 start, guint32 end)
+{
+ MonoTableInfo *t = &m->tables [MONO_TABLE_FIELD];
+ guint32 cols [MONO_FIELD_SIZE];
+ int i;
+
+ if (end > t->rows + 1) {
+ g_warning ("ERROR index out of range in fields");
+ end = t->rows;
+ }
+
+ for (i = start; i < end; i++){
+ char *sig, *flags;
+
+ mono_metadata_decode_row (t, i, cols, MONO_FIELD_SIZE);
+ sig = get_field_signature (m, cols [MONO_FIELD_SIGNATURE]);
+ flags = field_flags (cols [MONO_FIELD_FLAGS]);
+
+ if (cols [MONO_FIELD_FLAGS] & FIELD_ATTRIBUTE_LITERAL){
+ MonoTypeEnum type;
+ char *lit;
+
+ type = get_field_literal_type (m, cols [MONO_FIELD_SIGNATURE]);
+ lit = g_strdup ("FIXME:Do-not-know-how-to-get-this-from-the-constants-table");
+ /* get_constant (m, type, cols [2]); */
+
+ fprintf (output, " .field %s %s %s = ",
+ flags, sig,
+ mono_metadata_string_heap (m, cols [MONO_FIELD_NAME]));
+ fprintf (output, "%s\n", lit);
+ g_free (lit);
+ } else
+ fprintf (output, " .field %s %s %s\n",
+ flags, sig,
+ mono_metadata_string_heap (m, cols [MONO_FIELD_NAME]));
+ g_free (flags);
+ g_free (sig);
+ }
+}
+
+static map_t method_access_map [] = {
+ { METHOD_ATTRIBUTE_COMPILER_CONTROLLED, "compilercontrolled " },
+ { METHOD_ATTRIBUTE_PRIVATE, "private" },
+ { METHOD_ATTRIBUTE_FAM_AND_ASSEM, "famandassem" },
+ { METHOD_ATTRIBUTE_ASSEM, "assembly " },
+ { METHOD_ATTRIBUTE_FAMILY, "family " },
+ { METHOD_ATTRIBUTE_FAM_OR_ASSEM, "famorassem " },
+ { METHOD_ATTRIBUTE_PUBLIC, "public " },
+ { 0, NULL }
+};
+
+static map_t method_flags_map [] = {
+ { METHOD_ATTRIBUTE_STATIC, "static " },
+ { METHOD_ATTRIBUTE_FINAL, "final " },
+ { METHOD_ATTRIBUTE_VIRTUAL, "virtual " },
+ { METHOD_ATTRIBUTE_HIDE_BY_SIG, "hidebysig " },
+ { METHOD_ATTRIBUTE_VTABLE_LAYOUT_MASK, "newslot " },
+ { METHOD_ATTRIBUTE_ABSTRACT, "abstract " },
+ { METHOD_ATTRIBUTE_SPECIAL_NAME, "specialname " },
+ { METHOD_ATTRIBUTE_RT_SPECIAL_NAME, "rtspecialname " },
+ { METHOD_ATTRIBUTE_UNMANAGED_EXPORT, "export " },
+ { METHOD_ATTRIBUTE_HAS_SECURITY, "hassecurity" },
+ { METHOD_ATTRIBUTE_REQUIRE_SEC_OBJECT, "requiresecobj" },
+ { METHOD_ATTRIBUTE_PINVOKE_IMPL, "pinvokeimpl " },
+ { 0, NULL }
+};
+
+/**
+ * method_flags:
+ *
+ * Returns a stringified version of the Method's flags
+ */
+static char *
+method_flags (guint32 f)
+{
+ GString *str = g_string_new ("");
+ int access = f & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK;
+ char *s;
+
+ g_string_append (str, map (access, method_access_map));
+ g_string_append (str, flags (f, method_flags_map));
+
+ s = str->str;
+ g_string_free (str, FALSE);
+
+ return s;
+}
+
+static map_t pinvoke_flags_map [] = {
+ { PINVOKE_ATTRIBUTE_NO_MANGLE , "nomangle " },
+ { PINVOKE_ATTRIBUTE_SUPPORTS_LAST_ERROR, "lasterr " },
+ { 0, NULL }
+};
+
+static map_t pinvoke_call_conv_map [] = {
+ { PINVOKE_ATTRIBUTE_CALL_CONV_WINAPI, "winapi " },
+ { PINVOKE_ATTRIBUTE_CALL_CONV_CDECL, "cdecl " },
+ { PINVOKE_ATTRIBUTE_CALL_CONV_STDCALL, "stdcall " },
+ { PINVOKE_ATTRIBUTE_CALL_CONV_THISCALL, "thiscall " },
+ { PINVOKE_ATTRIBUTE_CALL_CONV_FASTCALL, "fastcall " },
+ { 0, NULL }
+};
+
+static map_t pinvoke_char_set_map [] = {
+ { PINVOKE_ATTRIBUTE_CHAR_SET_NOT_SPEC, "" },
+ { PINVOKE_ATTRIBUTE_CHAR_SET_ANSI, "ansi " },
+ { PINVOKE_ATTRIBUTE_CHAR_SET_UNICODE , "unicode " },
+ { PINVOKE_ATTRIBUTE_CHAR_SET_AUTO, "autochar " },
+ { 0, NULL }
+};
+
+/**
+ * pinvoke_flags:
+ *
+ * Returns a stringified version of the Method's pinvoke flags
+ */
+static char *
+pinvoke_flags (guint32 f)
+{
+ GString *str = g_string_new ("");
+ int cset = f & PINVOKE_ATTRIBUTE_CHAR_SET_MASK;
+ int cconv = f & PINVOKE_ATTRIBUTE_CALL_CONV_MASK;
+ char *s;
+
+ g_string_append (str, map (cset, pinvoke_char_set_map));
+ g_string_append (str, map (cconv, pinvoke_call_conv_map));
+ g_string_append (str, flags (f, pinvoke_flags_map));
+
+ s = g_strdup(str->str);
+ g_string_free (str, FALSE);
+
+ return s;
+}
+
+static map_t method_impl_map [] = {
+ { METHOD_IMPL_ATTRIBUTE_IL, "cil " },
+ { METHOD_IMPL_ATTRIBUTE_NATIVE, "native " },
+ { METHOD_IMPL_ATTRIBUTE_OPTIL, "optil " },
+ { METHOD_IMPL_ATTRIBUTE_RUNTIME, "runtime " },
+ { 0, NULL }
+};
+
+static map_t managed_type_map [] = {
+ { METHOD_IMPL_ATTRIBUTE_UNMANAGED, "unmanaged " },
+ { METHOD_IMPL_ATTRIBUTE_MANAGED, "managed " },
+ { 0, NULL }
+};
+
+static map_t managed_impl_flags [] = {
+ { METHOD_IMPL_ATTRIBUTE_FORWARD_REF, "fwdref " },
+ { METHOD_IMPL_ATTRIBUTE_PRESERVE_SIG, "preservesig " },
+ { METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL, "internalcall " },
+ { METHOD_IMPL_ATTRIBUTE_SYNCHRONIZED, "synchronized " },
+ { METHOD_IMPL_ATTRIBUTE_NOINLINING, "noinline " },
+ { 0, NULL }
+};
+
+static char *
+method_impl_flags (guint32 f)
+{
+ GString *str = g_string_new ("");
+ char *s;
+ int code_type = f & METHOD_IMPL_ATTRIBUTE_CODE_TYPE_MASK;
+ int managed_type = f & METHOD_IMPL_ATTRIBUTE_MANAGED_MASK;
+
+ g_string_append (str, map (code_type, method_impl_map));
+ g_string_append (str, map (managed_type, managed_type_map));
+ g_string_append (str, flags (f, managed_impl_flags));
+
+ s = str->str;
+ g_string_free (str, FALSE);
+ return s;
+}
+
+static void
+dis_locals (MonoMetadata *m, MonoMethodHeader *mh)
+{
+ int i;
+
+ fprintf(output, "\t.locals %s(\n", mh->init_locals ? "init " : "");
+ for (i=0; i < mh->num_locals; ++i) {
+ char * desc;
+ /* print also byref and pinned attributes */
+ desc = dis_stringify_type (m, mh->locals[i]);
+ fprintf(output, "\t\t%s\tV_%d\n", desc, i);
+ g_free(desc);
+ }
+ fprintf(output, "\t)\n");
+}
+
+static void
+dis_code (MonoMetadata *m, guint32 rva)
+{
+ MonoMethodHeader *mh;
+ MonoCLIImageInfo *ii = m->image_info;
+ const char *ptr = mono_cli_rva_map (ii, rva);
+ char *loc;
+
+ if (rva == 0)
+ return;
+
+ mh = mono_metadata_parse_mh (m, ptr);
+ if (ii->cli_cli_header.ch_entry_point){
+ loc = mono_metadata_locate_token (m, ii->cli_cli_header.ch_entry_point);
+ if (rva == read32 (loc))
+ fprintf (output, "\t.entrypoint\n");
+ }
+
+ fprintf (output, "\t.maxstack %d\n", mh->max_stack);
+ fprintf (output, "\t// Code size=%d (0x%x)\n", mh->code_size, mh->code_size);
+ printf ("\t// Values Code Size=%d/0x%x\n\n",
+ mh->code_size, mh->code_size);
+ if (mh->num_locals)
+ dis_locals (m, mh);
+ dissasemble_cil (m, mh);
+
+/*
+ hex_dump (mh->code, 0, mh->code_size);
+ printf ("\nAfter the code\n");
+ hex_dump (mh->code + mh->code_size, 0, 64);
+*/
+ mono_metadata_free_mh (mh);
+}
+
+static char *
+pinvoke_info (MonoMetadata *m, guint32 mindex)
+{
+ MonoTableInfo *im = &m->tables [MONO_TABLE_IMPLMAP];
+ MonoTableInfo *mr = &m->tables [MONO_TABLE_MODULEREF];
+ guint32 im_cols [MONO_IMPLMAP_SIZE];
+ guint32 mr_cols [MONO_MODULEREF_SIZE];
+ const char *import, *scope;
+ char *flags;
+ int i;
+
+ for (i = 0; i < im->rows; i++) {
+
+ mono_metadata_decode_row (im, i, im_cols, MONO_IMPLMAP_SIZE);
+
+ if ((im_cols [MONO_IMPLMAP_MEMBER] >> 1) == mindex + 1) {
+
+ flags = pinvoke_flags (im_cols [MONO_IMPLMAP_FLAGS]);
+
+ import = mono_metadata_string_heap (m, im_cols [MONO_IMPLMAP_NAME]);
+
+ mono_metadata_decode_row (mr, im_cols [MONO_IMPLMAP_SCOPE] - 1,
+ mr_cols, MONO_MODULEREF_SIZE);
+
+ scope = mono_metadata_string_heap (m, mr_cols [MONO_MODULEREF_NAME]);
+
+ return g_strdup_printf ("(%s as %s %s)", scope, import,
+ flags);
+ g_free (flags);
+ }
+ }
+
+ return NULL;
+}
+
+/**
+ * dis_method_list:
+ * @m: metadata context
+ * @start: starting index into the Method Table.
+ * @end: ending index into Method table.
+ *
+ * This routine displays the methods in the Method Table from @start to @end
+ */
+static void
+dis_method_list (MonoMetadata *m, guint32 start, guint32 end)
+{
+ MonoTableInfo *t = &m->tables [MONO_TABLE_METHOD];
+ guint32 cols [MONO_METHOD_SIZE];
+ int i;
+
+ if (end > t->rows){
+ fprintf (output, "ERROR index out of range in methods");
+ /*exit (1);*/
+ end = t->rows;
+ }
+
+ for (i = start; i < end; i++){
+ MonoMethodSignature *ms;
+ char *flags, *impl_flags;
+ const char *sig;
+ char *sig_str;
+ mono_metadata_decode_row (t, i, cols, MONO_METHOD_SIZE);
+
+ flags = method_flags (cols [MONO_METHOD_FLAGS]);
+ impl_flags = method_impl_flags (cols [MONO_METHOD_IMPLFALGS]);
+
+ sig = mono_metadata_blob_heap (m, cols [MONO_METHOD_SIGNATURE]);
+ mono_metadata_decode_blob_size (sig, &sig);
+ ms = mono_metadata_parse_method_signature (m, 1, sig, &sig);
+ sig_str = dis_stringify_method_signature (m, ms, i + 1);
+
+ fprintf (output, " .method %s", flags);
+
+ if (cols [MONO_METHOD_FLAGS] & METHOD_ATTRIBUTE_PINVOKE_IMPL)
+ fprintf (output, "%s", pinvoke_info (m, i));
+
+ fprintf (output, "\n %s", sig_str);
+ fprintf (output, " %s\n", impl_flags);
+ g_free (flags);
+ g_free (impl_flags);
+
+ fprintf (output, " {\n");
+ fprintf (output, " // Method begins at RVA 0x%x\n", cols [MONO_METHOD_RVA]);
+ dis_code (m, cols [MONO_METHOD_RVA]);
+ fprintf (output, " }\n\n");
+ mono_metadata_free_method_signature (ms);
+ g_free (sig_str);
+ }
+}
+
+typedef struct {
+ MonoTableInfo *t;
+ guint32 col_idx;
+ guint32 idx;
+ guint32 result;
+} plocator_t;
+
+static int
+table_locator (const void *a, const void *b)
+{
+ plocator_t *loc = (plocator_t *) a;
+ char *bb = (char *) b;
+ guint32 table_index = (bb - loc->t->base) / loc->t->row_size;
+ guint32 col;
+
+ col = mono_metadata_decode_row_col (loc->t, table_index, loc->col_idx);
+
+ if (loc->idx == col) {
+ loc->result = table_index;
+ return 0;
+ }
+ if (loc->idx < col)
+ return -1;
+ else
+ return 1;
+}
+
+static void
+dis_property_methods (MonoMetadata *m, guint32 prop)
+{
+ plocator_t loc;
+ guint start;
+ guint32 cols [MONO_METHOD_SEMA_SIZE];
+ MonoTableInfo *msemt = &m->tables [MONO_TABLE_METHODSEMANTICS];
+ char *sig;
+ char *type[] = {NULL, ".set", ".get", NULL, ".other"};
+
+ loc.t = msemt;
+ loc.col_idx = MONO_METHOD_SEMA_ASSOCIATION;
+ loc.idx = (prop << 1) | 1; /* Method association coded index */
+
+ if (!bsearch (&loc, msemt->base, msemt->rows, msemt->row_size, table_locator))
+ return;
+
+ start = loc.result;
+ /*
+ * We may end up in the middle of the rows...
+ */
+ while (start > 0) {
+ if (loc.idx == mono_metadata_decode_row_col (msemt, start - 1, MONO_METHOD_SEMA_ASSOCIATION))
+ start--;
+ else
+ break;
+ }
+ while (start < msemt->rows) {
+ mono_metadata_decode_row (msemt, start, cols, MONO_METHOD_SEMA_SIZE);
+ if (cols [MONO_METHOD_SEMA_ASSOCIATION] != loc.idx)
+ break;
+ sig = dis_stringify_method_signature (m, NULL, cols [MONO_METHOD_SEMA_METHOD]);
+ fprintf (output, "\t\t%s %s\n", type [cols [MONO_METHOD_SEMA_SEMANTICS]], sig);
+ g_free (sig);
+ ++start;
+ }
+}
+
+static char*
+dis_property_signature (MonoMetadata *m, guint32 prop_idx)
+{
+ MonoTableInfo *propt = &m->tables [MONO_TABLE_PROPERTY];
+ const char *ptr;
+ guint32 pcount, i;
+ guint32 cols [MONO_PROPERTY_SIZE];
+ MonoType *type;
+ MonoParam *param;
+ char *blurb;
+ const char *name;
+ int prop_flags;
+ GString *res = g_string_new ("");
+
+ mono_metadata_decode_row (propt, prop_idx, cols, MONO_PROPERTY_SIZE);
+ name = mono_metadata_string_heap (m, cols [MONO_PROPERTY_NAME]);
+ prop_flags = cols [MONO_PROPERTY_FLAGS];
+ ptr = mono_metadata_blob_heap (m, cols [MONO_PROPERTY_TYPE]);
+ mono_metadata_decode_blob_size (ptr, &ptr);
+ /* ECMA claims 0x08 ... */
+ if (*ptr != 0x28 && *ptr != 0x08)
+ g_warning("incorrect signature in propert blob: 0x%x", *ptr);
+ ptr++;
+ pcount = mono_metadata_decode_value (ptr, &ptr);
+ type = mono_metadata_parse_type (m, ptr, &ptr);
+ blurb = dis_stringify_type (m, type);
+ if (prop_flags & 0x0200)
+ g_string_append (res, "special ");
+ if (prop_flags & 0x0400)
+ g_string_append (res, "runtime ");
+ if (prop_flags & 0x1000)
+ g_string_append (res, "hasdefault ");
+ g_string_sprintfa (res, "%s %s (", blurb, name);
+ g_free (blurb);
+ mono_metadata_free_type (type);
+ for (i = 0; i < pcount; i++) {
+ if (i)
+ g_string_append (res, ", ");
+ param = mono_metadata_parse_param (m, 0, ptr, &ptr);
+ blurb = dis_stringify_param (m, param);
+ g_string_append (res, blurb);
+ mono_metadata_free_param (param);
+ g_free (blurb);
+ }
+ g_string_append_c (res, ')');
+ blurb = res->str;
+ g_string_free (res, FALSE);
+ return blurb;
+
+}
+
+static void
+dis_property_list (MonoMetadata *m, guint32 typedef_row)
+{
+ plocator_t loc;
+ guint32 start, end, i;
+ MonoTableInfo *tdef = &m->tables [MONO_TABLE_PROPERTYMAP];
+
+ loc.t = tdef;
+ loc.col_idx = MONO_PROPERTY_MAP_PARENT;
+ loc.idx = typedef_row + 1;
+
+ if (!bsearch (&loc, tdef->base, tdef->rows, tdef->row_size, table_locator))
+ return;
+
+ start = mono_metadata_decode_row_col (tdef, loc.result, MONO_PROPERTY_MAP_PROPERTY_LIST);
+ if (loc.result + 1 < tdef->rows) {
+ end = mono_metadata_decode_row_col (tdef, loc.result + 1, MONO_PROPERTY_MAP_PROPERTY_LIST) - 1;
+ } else {
+ end = m->tables [MONO_TABLE_PROPERTY].rows;
}
- dump_header_data (ass);
+ for (i = start - 1; i < end; ++i) {
+ char *sig = dis_property_signature (m, i);
+ fprintf (output, "\t.property %s\n\t{\n", sig);
+ dis_property_methods (m, i + 1);
+ fprintf (output, "\t}\n");
+ g_free (sig);
+ }
+}
+
+/**
+ * dis_type:
+ * @m: metadata context
+ * @n: index of type to disassemble
+ *
+ * Disassembles the type whose index in the TypeDef table is @n.
+ */
+static void
+dis_type (MonoMetadata *m, int n)
+{
+ MonoTableInfo *t = &m->tables [MONO_TABLE_TYPEDEF];
+ guint32 cols [MONO_TYPEDEF_SIZE];
+ guint32 cols_next [MONO_TYPEDEF_SIZE];
+ const char *name;
+ gboolean next_is_valid, last;
+
+ mono_metadata_decode_row (t, n, cols, MONO_TYPEDEF_SIZE);
+
+ if (t->rows > n + 1) {
+ mono_metadata_decode_row (t, n + 1, cols_next, MONO_TYPEDEF_SIZE);
+ next_is_valid = 1;
+ } else
+ next_is_valid = 0;
+
+ fprintf (output, ".namespace %s\n{\n", mono_metadata_string_heap (m, cols [MONO_TYPEDEF_NAMESPACE]));
+ name = mono_metadata_string_heap (m, cols [MONO_TYPEDEF_NAME]);
+
+ if ((cols [MONO_TYPEDEF_FLAGS] & TYPE_ATTRIBUTE_CLASS_SEMANTIC_MASK) == TYPE_ATTRIBUTE_CLASS){
+ char *base = get_typedef_or_ref (m, cols [MONO_TYPEDEF_EXTENDS]);
+ fprintf (output, " .class %s%s\n", typedef_flags (cols [MONO_TYPEDEF_FLAGS]), name);
+ fprintf (output, " \textends %s\n", base);
+ g_free (base);
+ } else
+ fprintf (output, " .class interface %s%s\n", typedef_flags (cols [MONO_TYPEDEF_FLAGS]), name);
+
+ fprintf (output, " {\n");
+
+ /*
+ * The value in the table is always valid, we know we have fields
+ * if the value stored is different than the next record.
+ */
- mono_assembly_close (ass);
+ if (next_is_valid)
+ last = cols_next [MONO_TYPEDEF_FIELD_LIST] - 1;
+ else
+ last = m->tables [MONO_TABLE_FIELD].rows;
+
+ if (cols [MONO_TYPEDEF_FIELD_LIST] && cols [MONO_TYPEDEF_FIELD_LIST] <= m->tables [MONO_TABLE_FIELD].rows)
+ dis_field_list (m, cols [MONO_TYPEDEF_FIELD_LIST] - 1, last);
+ fprintf (output, "\n");
+
+ if (next_is_valid)
+ last = cols_next [MONO_TYPEDEF_METHOD_LIST] - 1;
+ else
+ last = m->tables [MONO_TABLE_METHOD].rows;
+
+ if (cols [MONO_TYPEDEF_METHOD_LIST] < m->tables [MONO_TABLE_METHOD].rows)
+ dis_method_list (m, cols [MONO_TYPEDEF_METHOD_LIST] - 1, last);
+
+ dis_property_list (m, n);
+
+ fprintf (output, " }\n}\n\n");
+}
+
+/**
+ * dis_types:
+ * @m: metadata context
+ *
+ * disassembles all types in the @m context
+ */
+static void
+dis_types (MonoMetadata *m)
+{
+ MonoTableInfo *t = &m->tables [MONO_TABLE_TYPEDEF];
+ int i;
+
+ for (i = 1; i < t->rows; i++)
+ dis_type (m, i);
+}
+
+struct {
+ char *name;
+ int table;
+ void (*dumper) (MonoMetadata *m);
+} table_list [] = {
+ { "--assembly", MONO_TABLE_ASSEMBLY, dump_table_assembly },
+ { "--assemblyref", MONO_TABLE_ASSEMBLYREF, dump_table_assemblyref },
+ { "--fields", MONO_TABLE_FIELD, dump_table_field },
+ { "--memberref", MONO_TABLE_MEMBERREF, dump_table_memberref },
+ { "--param", MONO_TABLE_PARAM, dump_table_param },
+ { "--typedef", MONO_TABLE_TYPEDEF, dump_table_typedef },
+ { "--typeref", MONO_TABLE_TYPEREF, dump_table_typeref },
+ { "--classlayout", MONO_TABLE_CLASSLAYOUT, dump_table_class_layout },
+ { "--constant", MONO_TABLE_CONSTANT, dump_table_constant },
+ { "--property", MONO_TABLE_PROPERTY, dump_table_property },
+ { "--propertymap", MONO_TABLE_PROPERTYMAP, dump_table_property_map },
+ { "--event", MONO_TABLE_EVENT, dump_table_event },
+ { "--file", MONO_TABLE_FILE, dump_table_file },
+ { "--moduleref", MONO_TABLE_MODULEREF, dump_table_moduleref },
+ { "--method", MONO_TABLE_METHOD, dump_table_method },
+ { "--methodsem", MONO_TABLE_METHODSEMANTICS, dump_table_methodsem },
+ { NULL, -1 }
+};
+
+/**
+ * disassemble_file:
+ * @file: file containing CIL code.
+ *
+ * Disassembles the @file file.
+ */
+static void
+disassemble_file (const char *file)
+{
+ enum MonoImageOpenStatus status;
+ MonoImage *img;
+
+ fprintf (output, "// Disassembling %s\n", file);
+
+ img = mono_image_open (file, &status);
+ if (img == NULL){
+ fprintf (stderr, "Error while trying to process %s\n", file);
+ return;
+ }
+
+ if (dump_table != -1){
+ (*table_list [dump_table].dumper) (img);
+ } else {
+ dump_header_data (img);
+
+ dis_directive_assemblyref (img);
+ dis_directive_assembly (img);
+ dis_types (img);
+ }
+
+ mono_image_close (img);
}
static void
usage (void)
{
- fprintf (stderr, "Usage is: monodis file1 ..\n");
+ GString *args = g_string_new ("[--help] ");
+ int i;
+
+ for (i = 0; table_list [i].name != NULL; i++){
+ g_string_append (args, "[");
+ g_string_append (args, table_list [i].name);
+ g_string_append (args, "] ");
+ if (((i-2) % 5) == 0)
+ g_string_append_c (args, '\n');
+ }
+ fprintf (stderr,
+ "Usage is: monodis %s file ..\n", args->str);
exit (1);
}
@@ -56,7 +781,7 @@ int
main (int argc, char *argv [])
{
GList *input_files = NULL, *l;
- int i;
+ int i, j;
output = stdout;
for (i = 1; i < argc; i++){
@@ -65,6 +790,14 @@ main (int argc, char *argv [])
usage ();
else if (argv [i][1] == 'd')
dump_header_data_p = TRUE;
+ else if (strcmp (argv [i], "--help") == 0)
+ usage ();
+ for (j = 0; table_list [j].name != NULL; j++) {
+ if (strcmp (argv [i], table_list [j].name) == 0)
+ dump_table = j;
+ }
+ if (dump_table < 0)
+ usage ();
} else
input_files = g_list_append (input_files, argv [i]);
}
@@ -74,4 +807,6 @@ main (int argc, char *argv [])
for (l = input_files; l; l = l->next)
disassemble_file (l->data);
+
+ return 0;
}
diff --git a/mono/dis/meta.h b/mono/dis/meta.h
new file mode 100644
index 00000000000..cacf06523f8
--- /dev/null
+++ b/mono/dis/meta.h
@@ -0,0 +1,7 @@
+#include <mono/metadata/image.h>
+#include <mono/metadata/cil-coff.h>
+#include <mono/metadata/endian.h>
+#include <mono/metadata/tabledefs.h>
+#include <mono/metadata/tokentype.h>
+#include <mono/metadata/blob.h>
+
diff --git a/mono/dis/monodis.1 b/mono/dis/monodis.1
new file mode 100644
index 00000000000..3ee8e160cdb
--- /dev/null
+++ b/mono/dis/monodis.1
@@ -0,0 +1,41 @@
+.\"
+.\" monodis manual page.
+.\" (C) Ximian, Inc.
+.\" Author:
+.\" Miguel de Icaza (miguel@gnu.org)
+.\"
+.TH Mono "Mono 1.0"
+.SH NAME
+monodis \- CIL image content dumper and disassembler.
+.SH SYNOPSIS
+.PP
+.B monodis
+[\-hd] [\-\-help]
+[\-\-typeref]
+[\-\-typedefl]
+[\-\-assemblyref]
+[FILES...]
+.SH DESCRIPTION
+The \fImonodis\fP program is used to dump the contents a CIL image
+(contained in .EXE files that contain extended PE/COFF CIL code).
+.SH OPTIONS
+The following Generic options are supported:
+.TP
+.I "--help", "-h"
+Displays usage instructions.
+.TP
+.I "--typeref"
+Dumps the contents of the typeref table.
+.TP
+.I "--typedef"
+Dumps the contents of the typedef table.
+.TP
+.I "--assemblyref"
+Dumps the contents of the assemblyref table.
+.PP
+If no flags are specified the program dumps the content of the image
+in a format that can be used to rountrip the code.
+.SH AUTHOR
+monodis was written by Miguel de Icaza
+.SH SEE ALSO
+.BR pedump(1),
diff --git a/mono/dis/push-pop.h b/mono/dis/push-pop.h
new file mode 100644
index 00000000000..98da16824ad
--- /dev/null
+++ b/mono/dis/push-pop.h
@@ -0,0 +1,265 @@
+/* Poping */
+/* 1 bit */
+#define Pop0 1
+/* 2 bits */
+#define Pop1 2
+/* 3 bits */
+#define PopI 8
+/* 1 bit */
+#define PopI8 64
+/* 1 bit */
+#define Pop8 128
+/* 1 bit */
+#define PopR4 256
+/* 1 bit */
+#define PopR8 512
+/* 1 bit */
+#define PopRef 1024
+/* 1 bit */
+#define VarPop 2048
+
+/* Pushing */
+#define Push0 1
+#define PushI 2
+#define PushI8 4
+#define PushR4 8
+#define PushR8 16
+#define PushRef 32
+#define VarPush 64
+#define Push1 128
+
+/*
+ * dis-cil.c: Disassembles CIL byte codes
+ *
+ * Author:
+ * Miguel de Icaza (miguel@ximian.com)
+ *
+ * (C) 2001 Ximian, Inc.
+ */
+#include <config.h>
+#include <glib.h>
+#include <stdio.h>
+#include "meta.h"
+#include "dump.h"
+#include "dis-cil.h"
+
+/* Poping */
+/* 1 bit */
+#define Pop0 1
+/* 2 bits */
+#define Pop1 2
+/* 3 bits */
+#define PopI 8
+/* 1 bit */
+#define PopI8 64
+/* 1 bit */
+#define Pop8 128
+/* 1 bit */
+#define PopR4 256
+/* 1 bit */
+#define PopR8 512
+/* 1 bit */
+#define PopRef 1024
+/* 1 bit */
+#define VarPop 2048
+
+/* Pushing */
+#define Push0 1
+#define PushI 2
+#define PushI8 4
+#define PushR4 8
+#define PushR8 16
+#define PushRef 32
+#define VarPush 64
+#define Push1 128
+
+enum {
+ InlineBrTarget,
+ InlineField,
+ InlineI,
+ InlineI8,
+ InlineMethod,
+ InlineNone,
+ InlineR,
+ InlineSig,
+ InlineString,
+ InlineSwitch,
+ InlineTok,
+ InlineType,
+ InlineVar,
+ ShortInlineBrTarget,
+ ShortInlineI,
+ ShortInlineR,
+ ShortInlineVar
+};
+
+#define OPDEF(a,b,c,d,e,f,g,h,i,j) \
+ { b, c, d, e, g, h, i },
+
+typedef struct {
+ char *name;
+ int pop, push;
+ int argument;
+ int bytes;
+ unsigned char o1, o2;
+} opcode_t;
+
+static opcode_t opcodes [300] = {
+#include "mono/cil/opcode.def"
+};
+
+void
+dissasemble_cil (MonoMetadata *m, const unsigned char *start, int size)
+{
+ const unsigned char *end = start + size;
+ const unsigned char *ptr = start;
+ opcode_t *entry;
+
+ while (ptr < end){
+ if (*ptr == 0xfe){
+ ptr++;
+ entry = &opcodes [*ptr + 256];
+ } else
+ entry = &opcodes [*ptr];
+
+ ptr++;
+
+ fprintf (output, "\tIL_%04x: %s ", ptr - start, entry->name);
+ switch (entry->argument){
+ case InlineBrTarget: {
+ gint target = *(gint32 *) ptr;
+ fprintf (output, "IL_%04x", ptr + 4 + target);
+ ptr += 4;
+ break;
+ }
+
+ case InlineField: {
+ token = *(guint32 *) ptr;
+ fprintf (output, "fieldref-0x%08x", token);
+ ptr += 4;
+ break;
+ }
+
+ case InlineI: {
+ int value = *(int *) ptr;
+
+ fprintf (output, "%d", value);
+ ptr += 4;
+ break;
+ }
+
+ case InlineI8: {
+ gint64 top = *(guint64 *) value;
+
+ fprintf (output, "%ld", top);
+ ptr += 8;
+ break;
+ }
+
+ case InlineMethod: {
+ token = *(guint32 *) ptr;
+ fprintf (output, "method-0x%08x", token);
+ ptr += 4;
+ break;
+ }
+
+ case InlineNone:
+ break;
+
+ case InlineR: {
+ double r = *(double *) ptr;
+ fprintf (output, "%g", r);
+ ptr += 8;
+ break;
+ }
+
+ case InlineSig: {
+ guint32 token = *(guint32 *) ptr;
+ fprintf (output, "signature-0x%08x", token);
+ ptr += 4;
+ break;
+ }
+
+ case InlineString: {
+ guint32 token = *(guint32 *) ptr;
+
+ fprintf (output, "string-%0x08x", token);
+ ptr += 4;
+ break;
+ }
+
+ case InlineSwitch: {
+ guint32 count = *(guint32 *) ptr;
+ guint32 i;
+
+ ptr += 4;
+ fprintf (output, "(\n\t\t\t");
+ for (i = 0; i < count; i++){
+ fprintf (output, "IL_%x", *(guint32 *) ptr);
+ ptr += 4;
+ }
+ fprintf (output, "\t\t\t)");
+ break;
+ }
+
+ case InlineTok: {
+ guint32 token = *(guint32 *) ptr;
+
+ fprintf (output, "TOKEN_%08x", token);
+ ptr += 4;
+ break;
+ }
+
+ case InlineType: {
+ guint32 token = *(guint32 *) ptr;
+
+ fprintf (output, "Type-%08x", token);
+ ptr += 4;
+ break;
+ }
+
+ case InlineVar: {
+ gint16 var_idx = *(gint16 *) ptr;
+
+ fprintf (output, "variable-%d\n", var_idx);
+ ptr += 2;
+ break;
+ }
+
+ case ShortInlineBrTarget: {
+ signed char x = *ptr;
+
+ fprintf (output, "IL_%04x", ptr - start + 1 + x);
+ ptr++:
+ break;
+ }
+
+ case ShortInlineI: {
+ char x = *ptr;
+
+ fprintf (output, "0x%02x", x);
+ ptr++;
+ break;
+ }
+
+ case ShortInlineR: {
+ float f = *(float *) ptr;
+
+ fprintf (output, "%g", (double) f);
+ ptr += 4;
+ break;
+ }
+
+ case ShortInlineVar: {
+ signed char x = *ptr;
+
+ fprintf (output, "Varidx-%d", (int) x);
+ ptr++;
+ break;
+ }m
+
+ }
+
+ fprintf (output, "\n");
+ }
+}
diff --git a/mono/dis/util.c b/mono/dis/util.c
new file mode 100644
index 00000000000..004bbd683bc
--- /dev/null
+++ b/mono/dis/util.c
@@ -0,0 +1,85 @@
+/*
+ * util.c: Assorted utilities for the dissasembler
+ *
+ * Author:
+ * Miguel de Icaza (miguel@ximian.com)
+ *
+ * (C) 2001 Ximian, Inc (http://www.ximian.com)
+ */
+#include <config.h>
+#include <glib.h>
+#include <string.h>
+#include <stdio.h>
+#include "util.h"
+
+/**
+ * map:
+ * @code: code to lookup in table
+ * @table: table to decode code
+ *
+ * Warning: returns static buffer.
+ */
+const char *
+map (guint32 code, map_t *table)
+{
+ int i;
+
+ for (i = 0; table [i].str != NULL; i++)
+ if (table [i].code == code)
+ return table [i].str;
+ g_assert_not_reached ();
+ return "";
+}
+
+/**
+ * flags:
+ * @code: bitfield
+ * @table: table to decode bitfield
+ *
+ * Warning: returns static buffer.
+ */
+const char *
+flags (guint32 code, map_t *table)
+{
+ static char buffer [1024];
+ int i;
+
+ buffer [0] = 0;
+
+ for (i = 0; table [i].str != NULL; i++)
+ if (table [i].code & code) {
+ if (buffer [0])
+ strcat (buffer, " ");
+ strcat (buffer, table [i].str);
+ }
+
+ return buffer;
+}
+
+/**
+ * hex_dump:
+ * @buffer: pointer to buffer to dump
+ * @base: numbering base to use
+ * @count: number of bytes to dump
+ */
+void
+hex_dump (const char *buffer, int base, int count)
+{
+ int show_header = 1;
+ int i;
+
+ if (count < 0){
+ count = -count;
+ show_header = 0;
+ }
+
+ for (i = 0; i < count; i++){
+ if (show_header)
+ if ((i % 16) == 0)
+ printf ("\n0x%08x: ", (unsigned char) base + i);
+
+ printf ("%02x ", (unsigned char) (buffer [i]));
+ }
+ fflush (stdout);
+}
+
diff --git a/mono/dis/util.h b/mono/dis/util.h
new file mode 100644
index 00000000000..c6647c7d2ec
--- /dev/null
+++ b/mono/dis/util.h
@@ -0,0 +1,11 @@
+
+typedef struct {
+ int code;
+ char *str;
+} map_t;
+
+const char *map (guint32 code, map_t *table);
+const char *flags (guint32 code, map_t *table);
+void hex_dump (const char *buffer, int base, int count);
+
+#define CSIZE(x) (sizeof (x) / 4)
diff --git a/mono/interpreter/.cvsignore b/mono/interpreter/.cvsignore
new file mode 100644
index 00000000000..d1628f487a6
--- /dev/null
+++ b/mono/interpreter/.cvsignore
@@ -0,0 +1,6 @@
+Makefile
+Makefile.in
+mint
+*.o
+.libs
+.deps
diff --git a/mono/interpreter/ChangeLog b/mono/interpreter/ChangeLog
new file mode 100644
index 00000000000..ca11d986971
--- /dev/null
+++ b/mono/interpreter/ChangeLog
@@ -0,0 +1,208 @@
+2001-08-22 Miguel de Icaza <miguel@ximian.com>
+
+ * interp.c (usage): Add version information
+ (ves_pinvoke_method): Typo fix.
+
+Wed Aug 22 20:37:51 CEST 2001 Paolo Molaro <lupus@ximian.com>
+
+ * interp.c: simplified init_class (). Make sure a class
+ is fully initialized before executing a method in the class.
+ Search for the class constructor only on beforefieldinit classes.
+ Implement a bunch of opcodes: br, brfalse, brtrue, beq, bge,
+ bgt, blt, ble, bne.un, bge.un, bgt.un, ble.un, blt.un, stind.i,
+ ldflda, ldsflda, ldelem.i8, stelem.i8, leave.
+
+Wed Aug 22 16:34:03 CEST 2001 Paolo Molaro <lupus@ximian.com>
+
+ * interp.c: Updates for changes in metadata/. Better output in debug mode
+ and in the stack trace. Completed rethrow handling
+
+Tue Aug 21 18:56:19 CEST 2001 Paolo Molaro <lupus@ximian.com>
+
+ * interp.c: new macro INIT_FRAME() to properly
+ initialize a MonoInvocation. Fixed a couple of buglets in exception code:
+ increase stack pointer when pushing the exception for catch blocks,
+ initialize frame->ex_handler to NULL, correctly try all the
+ catch blocks (don't incorrectly fallback on filter handling).
+ Added a couple more checks where we may need to throw an
+ exception. Added more exception creation functions.
+ Changed stackval_from_data() to take the target stackval as
+ argument. Implemented a couple more opcodes.
+ * interp.h: prepare stackval for value type code.
+
+2001-08-21 Miguel de Icaza <miguel@ximian.com>
+
+ * Makefile.am (mint_LDADD): Renamed interpreter to mint.
+
+2001-08-21 Dietmar Maurer <dietmar@ximian.com>
+
+ * interp.c (get_named_exception): use the right constructor.
+
+Mon Aug 20 18:58:36 CEST 2001 Paolo Molaro <lupus@ximian.com>
+
+ * interp.c: fix buglet with the leave.s opcode.
+
+2001-08-20 Dietmar Maurer <dietmar@ximian.com>
+
+ * icall.c: changed everything to support the new calling convention
+
+ * hacks.h: added some macros for FreeBSD
+
+ * interp.c (get_named_exception): use mono_object_new instead of
+ newobj, initialize the stack before we call the constructor.
+
+Sat Aug 18 12:43:38 CEST 2001 Paolo Molaro <lupus@ximian.com>
+
+ * interp.c, interp.h: added support code to create exceptions.
+ Changed interncal calling convnetion over to MonoInvocation, to support
+ exceptions, walking the stack back and forward and passing the 'this'
+ pointer separately (remove the cludges required before to pass this on the
+ stack). Use alloca heavily for both local vars and a copy of the incoming
+ arguments. Init local vars to zero.
+ Simplify stackval_from_data() and stackval_to_data() to only take a pointer
+ instead of pointer + offset.
+ Implement a few exceptions-related opcodes and the code to run finally, fault and
+ catch blocks as well as a stack trace if no handler is found.
+
+2001-08-16 Alex Graveley <alex@ximian.com>
+
+ * Makefile.am (mono_int_LDADD): Link with ../../libffi/libffi.a
+ instead of ../../libffi/.libs/libffi.a.
+
+2001-08-10 Dietmar Maurer <dietmar@ximian.com>
+
+ * interp.c (ves_exec_method): impl CASTCLASS
+
+ * icall.c: moved the internal call stuff to this file
+
+ * interp.c (ves_exec_method): impl. BOX/UNBOX
+ (ves_icall_System_Array_GetValue): impl.
+ (ves_icall_System_Array_SetValue): impl.
+ added myself to Authors
+
+2001-08-09 Dietmar Maurer <dietmar@ximian.com>
+
+ * implemented arrays, but you will need a modified version of
+ Array.cs to get arrays working (will commit soon)
+
+ * interp.c (ves_icall_array_Set): impl.
+ (ves_icall_array_Get): impl.
+ (ves_icall_array_ctor): impl.
+ (ves_icall_System_Array_GetRank): impl.
+ (ves_icall_System_Array_GetLength): impl.
+ (ves_icall_System_Array_GetLowerBound): impl.
+ (mono_lookup_internal_call): impl.
+
+2001-08-06 Dietmar Maurer <dietmar@ximian.com>
+
+ * interp.c (ves_exec_method): impl. NEWARR
+ (ves_exec_method): impl. most LDELEM/STELEM opcodes, LDLEN
+ (newarr): impl.
+ (mono_get_ansi_string): impl.
+ (mono_lookup_internal_call): impl.
+ (ves_exec_method): implemented internal calls
+
+2001-08-05 Dietmar Maurer <dietmar@ximian.com>
+
+ * interp.c (ves_pinvoke_method): removed all static vars.
+
+2001-08-02 Dietmar Maurer <dietmar@ximian.com>
+
+ * interp.c (ves_exec_method): found a way to do unordered
+ compares, implemented CEE_BNE_UN_S, CEE_BGE_UN_S, CEE_BGT_UN_S,
+ CEE_BLE_UN_S, CEE_BLT_UN_S
+
+Wed Aug 1 22:51:38 CEST 2001 Paolo Molaro <lupus@ximian.com>
+
+ * interp.c: handle also MONO_TYPE_CLASS to/from the stack.
+ Change locals to be a memory blob, instead of the structured
+ (but wrong) stackval. Implement bne.un.s opcode. Make the program
+ exit with the error code from Main().
+
+2001-08-01 Dietmar Maurer <dietmar@ximian.com>
+
+ * interp.c (ves_exec_method): implemented LDSTR
+
+2001-07-31 Miguel de Icaza <miguel@ximian.com>
+
+ * interp.c (GET_NATI): Switched from using nati_t to cli/types.h
+ m_i type. Maybe we should rename the types to be m_i_t instead of
+ m_i alone.
+
+ Make the code compile after I broke it.
+
+Tue Jul 31 23:46:33 CEST 2001 Paolo Molaro <lupus@ximian.com>
+
+ * interp.c: fix cleanup.
+ * Makefile.am: don't link with disassembler library.
+
+2001-07-31 Miguel de Icaza <miguel@ximian.com>
+
+ (ves_exec_method): Cleanup of the source code.
+
+Tue Jul 31 20:13:59 CEST 2001 Paolo Molaro <lupus@ximian.com>
+
+ * interp.c: implement stind.*, ldind.*, ldloca.s opcodes.
+ Provide better tracing with DEBUG_INTERP.
+
+Tue Jul 31 17:52:53 CEST 2001 Paolo Molaro <lupus@ximian.com>
+
+ * interp.c: massive namespace cleanup.
+
+Mon Jul 30 20:09:58 CEST 2001 Paolo Molaro <lupus@ximian.com>
+
+ * interp.c: update to use mono_method->name.
+
+Fri Jul 27 20:54:00 CEST 2001 Paolo Molaro <lupus@ximian.com>
+
+ * interp.c: start implementing callvirt. Classes with
+ class constructors are properly initialized when needed.
+ Fix error introduced in version 1.17.
+
+Fri Jul 27 14:03:19 CEST 2001 Paolo Molaro <lupus@ximian.com>
+
+ * interp.c: implement static field loading and storing.
+
+2001-07-27 Dietmar Maurer <dietmar@ximian.com>
+
+ * interp.c (ves_pinvoke_method): impl.
+
+Fri Jul 27 11:49:19 CEST 2001 Paolo Molaro <lupus@ximian.com>
+
+ * interp.c: Removed some debugging printouts. Made stackval_to_data
+ static. Handle also instance methods in CALL opcode. Fix ret to properly
+ deal with void functions. Fixed constructor to leave the object on
+ the stack.
+
+Thu Jul 26 13:24:51 CEST 2001 Paolo Molaro <lupus@ximian.com>
+
+ * interp.c: ves_exec_method () doesn't take a MonoImage arg
+ anymore. Use the method cache in MonoImage. Updates to
+ mache recent changes in metadata.
+ Fix newobj code to use new metadata features. Call the class
+ constructor after allocationg the object. Implemented load field
+ and store field opcodes (the support functions need to be finished).
+
+Tue Jul 24 16:51:09 CEST 2001 Paolo Molaro <lupus@ximian.com>
+
+ * interp.c, hacks.h: moved a few ugly macros out of the code.
+ Implemented switch opcode.
+
+2001-07-23 Miguel de Icaza <miguel@ximian.com>
+
+ * interp.c (newobj): Added function to handle newobj opcode.
+
+2001-07-18 Miguel de Icaza <miguel@ximian.com>
+
+ * interp.c (ves_exec_method): Make the interpreter abort with more
+ information than it currently does.
+
+ Enable the slow processor, as it is easier to debug.
+
+Sun Jul 15 17:50:23 CEST 2001 Paolo Molaro <lupus@ximian.com>
+
+ * Started changelog.
+ * interp.c: use new mono_get_method () function to get the complete
+ info on a method invocation: we support now method invocation with
+ multiple (or zero) simple arguments and with or without a return value.
+ Implement also a couple more opcodes.
diff --git a/mono/interpreter/Makefile.am b/mono/interpreter/Makefile.am
new file mode 100644
index 00000000000..f721ddebef1
--- /dev/null
+++ b/mono/interpreter/Makefile.am
@@ -0,0 +1,20 @@
+INCLUDES = \
+ -I$(top_srcdir) \
+ -I$(top_srcdir)/libffi/include \
+ $(GMODULE_CFLAGS) \
+ $(GLIB_CFLAGS)
+
+bin_PROGRAMS = mint
+
+mint_SOURCES = \
+ hacks.h \
+ interp.h \
+ interp.c \
+ icall.c
+
+mint_LDADD = \
+ ../metadata/libmetadata.a \
+ $(GLIB_LIBS) \
+ $(GMODULE_LIBS) \
+ ../../libffi/libffi.a
+ -lm
diff --git a/mono/interpreter/hacks.h b/mono/interpreter/hacks.h
new file mode 100644
index 00000000000..8b62bd5a0d3
--- /dev/null
+++ b/mono/interpreter/hacks.h
@@ -0,0 +1,114 @@
+/* we need some special math function */
+#define _ISOC99_SOURCE
+#include <math.h>
+
+/* which are not defined on FreeBSD */
+#ifndef isunordered
+# define isunordered(u, v) \
+ (__extension__ \
+ ({ __typeof__(u) __u = (u); __typeof__(v) __v = (v); \
+ isnan(__u) || isnan(__v); }))
+#endif
+
+#ifndef islessgreater
+# define islessgreater(x, u) \
+ (__extension__ \
+ ({ __typeof__(x) __x = (x); __typeof__(y) __y = (y); \
+ !isunordered (__x, __y) && (__x < __y) || (__y < __x); }))
+#endif
+
+#ifndef islessequal
+# define islessequal(x, y) \
+ (__extension__ \
+ ({ __typeof__(x) __x = (x); __typeof__(y) __y = (y); \
+ !isunordered(__x, __y) && __x <= __y; }))
+#endif
+
+#ifndef isless
+# define isless(x, y) \
+ (__extension__ \
+ ({ __typeof__(x) __x = (x); __typeof__(y) __y = (y); \
+ !isunordered(__x, __y) && __x < __y; }))
+#endif
+
+#ifndef isgreater
+# define isgreater(x, y) \
+ (__extension__ \
+ ({ __typeof__(x) __x = (x); __typeof__(y) __y = (y); \
+ !isunordered(__x, __y) && __x > __y; }))
+#endif
+
+/*
+ * Attempt at using the goto label construct of GNU GCC:
+ * it turns out this does give some benefit: 5-15% speedup.
+ * Don't look at these macros, it hurts...
+ */
+#define GOTO_LABEL
+#undef GOTO_LABEL
+#ifdef GOTO_LABEL
+
+#define SWITCH(a) goto *goto_map [(a)];
+#define BREAK SWITCH(*ip)
+#define CASE(l) l ## _LABEL:
+#define DEFAULT \
+ CEE_ILLEGAL_LABEL: \
+ CEE_ENDMAC_LABEL:
+#define SUB_SWITCH \
+ CEE_PREFIX1_LABEL: \
+ CEE_ARGLIST_LABEL: \
+ CEE_CEQ_LABEL: \
+ CEE_CGT_LABEL: \
+ CEE_CGT_UN_LABEL: \
+ CEE_CLT_LABEL: \
+ CEE_CLT_UN_LABEL: \
+ CEE_LDFTN_LABEL: \
+ CEE_LDVIRTFTN_LABEL: \
+ CEE_UNUSED56_LABEL: \
+ CEE_LDARG_LABEL: \
+ CEE_LDARGA_LABEL: \
+ CEE_STARG_LABEL: \
+ CEE_LDLOC_LABEL: \
+ CEE_LDLOCA_LABEL: \
+ CEE_STLOC_LABEL: \
+ CEE_LOCALLOC_LABEL: \
+ CEE_UNUSED57_LABEL: \
+ CEE_ENDFILTER_LABEL: \
+ CEE_UNALIGNED__LABEL: \
+ CEE_VOLATILE__LABEL: \
+ CEE_TAIL__LABEL: \
+ CEE_INITOBJ_LABEL: \
+ CEE_UNUSED68_LABEL: \
+ CEE_CPBLK_LABEL: \
+ CEE_INITBLK_LABEL: \
+ CEE_UNUSED69_LABEL: \
+ CEE_RETHROW_LABEL: \
+ CEE_UNUSED_LABEL: \
+ CEE_SIZEOF_LABEL: \
+ CEE_REFANYTYPE_LABEL: \
+ CEE_UNUSED52_LABEL: \
+ CEE_UNUSED53_LABEL: \
+ CEE_UNUSED54_LABEL: \
+ CEE_UNUSED55_LABEL: \
+ CEE_UNUSED70_LABEL:
+#define GOTO_LABEL_VARS \
+ const static void * const goto_map [] = {\
+#define OPDEF(a,b,c,d,e,f,g,h,i,j) \ \
+ && a ## _LABEL, \
+#include "mono/cil/opcode.def" \
+#undef OPDEF \
+ &&DUMMY_LABEL \
+ }; \
+ DUMMY_LABEL:
+
+#else
+
+#define SWITCH(a) switch(a)
+#define BREAK break
+#define CASE(l) case l:
+#define DEFAULT \
+ default: \
+ g_error ("Unimplemented opcode: %x at 0x%x\n", *ip, ip-header->code);
+#define SUB_SWITCH case 0xFE:
+#define GOTO_LABEL_VARS
+
+#endif
diff --git a/mono/interpreter/icall.c b/mono/interpreter/icall.c
new file mode 100644
index 00000000000..fbddc8cb02e
--- /dev/null
+++ b/mono/interpreter/icall.c
@@ -0,0 +1,287 @@
+/*
+ * icall.c:
+ *
+ * Authors:
+ * Dietmar Maurer (dietmar@ximian.com)
+ *
+ * (C) 2001 Ximian, Inc.
+ */
+
+#include <config.h>
+#include <glib.h>
+
+#include <mono/metadata/loader.h>
+
+#include "interp.h"
+
+static void
+ves_icall_array_Set (MonoInvocation *frame)
+{
+ stackval *sp = frame->stack_args;
+ MonoObject *o;
+ MonoArrayObject *ao;
+ MonoArrayClass *ac;
+ gint32 i, t, pos, esize;
+ gpointer ea;
+
+ o = frame->obj;
+ ao = (MonoArrayObject *)o;
+ ac = (MonoArrayClass *)o->klass;
+
+ g_assert (ac->rank >= 1);
+
+ pos = sp [0].data.i - ao->bounds [0].lower_bound;
+ for (i = 1; i < ac->rank; i++) {
+ if ((t = sp [i].data.i - ao->bounds [i].lower_bound) >=
+ ao->bounds [i].length) {
+ g_warning ("wrong array index");
+ g_assert_not_reached ();
+ }
+ pos = pos*ao->bounds [i].length + sp [i].data.i -
+ ao->bounds [i].lower_bound;
+ }
+
+ esize = mono_array_element_size (ac);
+ ea = ao->vector + (pos * esize);
+ memcpy (ea, &sp [ac->rank].data.p, esize);
+}
+
+static void
+ves_icall_array_Get (MonoInvocation *frame)
+{
+ stackval *sp = frame->stack_args;
+ MonoObject *o;
+ MonoArrayObject *ao;
+ MonoArrayClass *ac;
+ gint32 i, pos, esize;
+ gpointer ea;
+
+ o = frame->obj;
+ ao = (MonoArrayObject *)o;
+ ac = (MonoArrayClass *)o->klass;
+
+ g_assert (ac->rank >= 1);
+
+ pos = sp [0].data.i - ao->bounds [0].lower_bound;
+ for (i = 1; i < ac->rank; i++)
+ pos = pos*ao->bounds [i].length + sp [i].data.i -
+ ao->bounds [i].lower_bound;
+
+ esize = mono_array_element_size (ac);
+ ea = ao->vector + (pos * esize);
+
+ frame->retval->type = VAL_I32; /* fixme: not really true */
+ memcpy (&frame->retval->data.p, ea, esize);
+}
+
+static void
+ves_icall_System_Array_GetValue (MonoInvocation *frame)
+{
+ stackval *sp = frame->stack_args;
+ MonoArrayObject *ao, *io;
+ MonoArrayClass *ac, *ic;
+ gint32 i, pos, *ind, esize;
+ gpointer *ea;
+
+ g_assert (sp [0].type == VAL_OBJ); /* expect an array of integers */
+
+ io = sp [0].data.p;
+ ic = (MonoArrayClass *)io->obj.klass;
+
+ ao = (MonoArrayObject *)frame->obj;
+ ac = (MonoArrayClass *)ao->obj.klass;
+
+ g_assert (ic->rank == 1);
+ g_assert (io->bounds [0].length == ac->rank);
+
+ ind = (guint32 *)io->vector;
+
+ pos = ind [0] - ao->bounds [0].lower_bound;
+ for (i = 1; i < ac->rank; i++)
+ pos = pos*ao->bounds [i].length + ind [i] -
+ ao->bounds [i].lower_bound;
+
+ esize = mono_array_element_size (ac);
+ ea = ao->vector + (pos * esize);
+
+ frame->retval->type = VAL_OBJ;
+
+ if (ac->element_class->valuetype)
+ frame->retval->data.p = mono_value_box (ac->element_class, ea);
+ else
+ frame->retval->data.p = ea;
+}
+
+static void
+ves_icall_System_Array_SetValue (MonoInvocation *frame)
+{
+ stackval *sp = frame->stack_args;
+ MonoArrayObject *ao, *io, *vo;
+ MonoArrayClass *ac, *ic, *vc;
+ gint32 i, pos, *ind, esize;
+ gpointer *ea;
+
+ g_assert (sp [0].type == VAL_OBJ); /* the value object */
+ g_assert (sp [1].type == VAL_OBJ); /* expect an array of integers */
+
+ vo = sp [0].data.p;
+ vc = (MonoArrayClass *)vo->obj.klass;
+
+ io = sp [1].data.p;
+ ic = (MonoArrayClass *)io->obj.klass;
+
+ ao = (MonoArrayObject *)frame->obj;
+ ac = (MonoArrayClass *)ao->obj.klass;
+
+ g_assert (ic->rank == 1);
+ g_assert (io->bounds [0].length == ac->rank);
+
+ g_assert (ac->element_class == vo->obj.klass);
+
+ ind = (guint32 *)io->vector;
+
+ pos = ind [0] - ao->bounds [0].lower_bound;
+ for (i = 1; i < ac->rank; i++)
+ pos = pos*ao->bounds [i].length + ind [i] -
+ ao->bounds [i].lower_bound;
+
+ esize = mono_array_element_size (ac);
+ ea = ao->vector + (pos * esize);
+
+ if (ac->element_class->valuetype) {
+ g_assert (vc->class.valuetype);
+
+ memcpy (ea, (char *)vo + sizeof (MonoObject), esize);
+ } else
+ ea = (gpointer)vo;
+}
+
+static void
+ves_icall_array_ctor (MonoInvocation *frame)
+{
+ stackval *sp = frame->stack_args;
+ MonoObject *o;
+ MonoArrayObject *ao;
+ MonoArrayClass *ac;
+ gint32 i, len, esize;
+
+ o = frame->obj;
+ ao = (MonoArrayObject *)o;
+ ac = (MonoArrayClass *)o->klass;
+
+ g_assert (ac->rank >= 1);
+
+ len = sp [0].data.i;
+ for (i = 1; i < ac->rank; i++)
+ len *= sp [i].data.i;
+
+ esize = mono_array_element_size (ac);
+ ao->vector = g_malloc0 (len * esize);
+ ao->bounds = g_malloc0 (ac->rank * sizeof (MonoArrayBounds));
+
+ for (i = 0; i < ac->rank; i++)
+ ao->bounds [i].length = sp [i].data.i;
+}
+
+static void
+ves_icall_array_bound_ctor (MonoInvocation *frame)
+{
+ MonoObject *o;
+ MonoArrayClass *ac;
+
+ o = frame->obj;
+ ac = (MonoArrayClass *)o->klass;
+
+ g_warning ("experimental implementation");
+ g_assert_not_reached ();
+}
+
+static void
+ves_icall_System_Array_CreateInstance (MonoInvocation *frame)
+{
+ g_warning ("not implemented");
+ g_assert_not_reached ();
+}
+
+static void
+ves_icall_System_Array_GetRank (MonoInvocation *frame)
+{
+ MonoObject *o;
+
+ o = frame->obj;
+
+ frame->retval->data.i = ((MonoArrayClass *)o->klass)->rank;
+ frame->retval->type = VAL_I32;
+}
+
+static void
+ves_icall_System_Array_GetLength (MonoInvocation *frame)
+{
+ stackval *sp = frame->stack_args;
+ MonoObject *o;
+
+ o = frame->obj;
+
+ frame->retval->data.i = ((MonoArrayObject *)o)->bounds [sp [0].data.i].length;
+ frame->retval->type = VAL_I32;
+}
+
+static void
+ves_icall_System_Array_GetLowerBound (MonoInvocation *frame)
+{
+ stackval *sp = frame->stack_args;
+ MonoArrayObject *ao;
+
+ ao = (MonoArrayObject *)frame->obj;
+
+ frame->retval->data.i = ao->bounds [sp [0].data.i].lower_bound;
+ frame->retval->type = VAL_I32;
+}
+
+static void
+ves_icall_System_Object_MemberwiseClone (MonoInvocation *frame)
+{
+ frame->retval->type = VAL_OBJ;
+ frame->retval->data.p = mono_object_clone (frame->obj);
+}
+
+static gpointer icall_map [] = {
+ /*
+ * System.Array
+ */
+ "__array_Set", ves_icall_array_Set,
+ "__array_Get", ves_icall_array_Get,
+ "__array_ctor", ves_icall_array_ctor,
+ "__array_bound_ctor", ves_icall_array_bound_ctor,
+ "System.Array::GetValue", ves_icall_System_Array_GetValue,
+ "System.Array::SetValue", ves_icall_System_Array_SetValue,
+ "System.Array::GetRank", ves_icall_System_Array_GetRank,
+ "System.Array::GetLength", ves_icall_System_Array_GetLength,
+ "System.Array::GetLowerBound", ves_icall_System_Array_GetLowerBound,
+ "System.Array::CreateInstance", ves_icall_System_Array_CreateInstance,
+
+ /*
+ * System.Object
+ */
+ "System.Object::MemberwiseClone", ves_icall_System_Object_MemberwiseClone,
+
+ /*
+ * add other internal calls here
+ */
+ NULL, NULL
+};
+
+void
+mono_init_icall ()
+{
+ char *n;
+ int i = 0;
+
+ while ((n = icall_map [i])) {
+ mono_add_internal_call (n, icall_map [i+1]);
+ i += 2;
+ }
+
+}
+
+
diff --git a/mono/interpreter/interp.c b/mono/interpreter/interp.c
new file mode 100644
index 00000000000..a0bb6f9c2f4
--- /dev/null
+++ b/mono/interpreter/interp.c
@@ -0,0 +1,2383 @@
+/*
+ * PLEASE NOTE: This is a research prototype.
+ *
+ *
+ * interp.c: Interpreter for CIL byte codes
+ *
+ * Authors:
+ * Paolo Molaro (lupus@ximian.com)
+ * Miguel de Icaza (miguel@ximian.com)
+ * Dietmar Maurer (dietmar@ximian.com)
+ *
+ * (C) 2001 Ximian, Inc.
+ */
+#include <config.h>
+#include <stdio.h>
+#include <string.h>
+#include <glib.h>
+#include <ffi.h>
+
+
+#ifdef HAVE_ALLOCA_H
+# include <alloca.h>
+#else
+# ifdef __CYGWIN__
+# define alloca __builtin_alloca
+# endif
+#endif
+
+/* trim excessive headers */
+#include <mono/metadata/image.h>
+#include <mono/metadata/assembly.h>
+#include <mono/metadata/cil-coff.h>
+#include <mono/metadata/endian.h>
+#include <mono/metadata/tabledefs.h>
+#include <mono/metadata/blob.h>
+#include <mono/metadata/tokentype.h>
+#include <mono/metadata/loader.h>
+//#include <mono/cli/types.h>
+#include "interp.h"
+#include "hacks.h"
+
+#define OPDEF(a,b,c,d,e,f,g,h,i,j) \
+ a = i,
+
+enum {
+#include "mono/cil/opcode.def"
+ LAST = 0xff
+};
+#undef OPDEF
+
+ static int debug_indent_level = 0;
+
+#define GET_NATI(sp) ((guint32)(sp).data.i)
+#define CSIZE(x) (sizeof (x) / 4)
+
+#define INIT_FRAME(frame,parent_frame,obj_this,method_args,method_retval,mono_method) \
+ do { \
+ (frame)->parent = (parent_frame); \
+ (frame)->obj = (obj_this); \
+ (frame)->stack_args = (method_args); \
+ (frame)->retval = (method_retval); \
+ (frame)->method = (mono_method); \
+ (frame)->ex_handler = NULL; \
+ (frame)->ex = NULL; \
+ } while (0)
+
+static void ves_exec_method (MonoInvocation *frame);
+
+typedef void (*ICallMethod) (MonoInvocation *frame);
+
+static void
+ves_real_abort (int line, MonoMethod *mh,
+ const unsigned char *ip, stackval *stack, stackval *sp)
+{
+ MonoMethodNormal *mm = (MonoMethodNormal *)mh;
+ fprintf (stderr, "Execution aborted in method: %s\n", mh->name);
+ fprintf (stderr, "Line=%d IP=0x%04x, Aborted execution\n", line,
+ ip-mm->header->code);
+ g_print ("0x%04x %02x\n",
+ ip-mm->header->code, *ip);
+ if (sp > stack)
+ printf ("\t[%d] %d 0x%08x %0.5f\n", sp-stack, sp[-1].type, sp[-1].data.i, sp[-1].data.f);
+ exit (1);
+}
+#define ves_abort() ves_real_abort(__LINE__, frame->method, ip, frame->stack, sp)
+
+/*
+ * init_class:
+ * @klass: klass that needs to be initialized
+ *
+ * This routine calls the class constructor for @class if it needs it.
+ */
+static void
+init_class (MonoClass *klass)
+{
+ MonoMethod *method;
+ MonoInvocation call;
+ int i;
+
+ if (klass->inited)
+ return;
+ if (klass->parent && !klass->parent->inited)
+ init_class (klass->parent);
+
+ klass->inited = 1;
+ /*
+ * No need to call the class constructor.
+ */
+ if (!(klass->flags & TYPE_ATTRIBUTE_BEFORE_FIELD_INIT))
+ return;
+
+ for (i = 0; i < klass->method.count; ++i) {
+ method = klass->methods [i];
+ if ((method->flags & METHOD_ATTRIBUTE_SPECIAL_NAME) && (strcmp (".cctor", method->name) == 0)) {
+ INIT_FRAME (&call, NULL, NULL, NULL, NULL, method);
+
+ ves_exec_method (&call);
+ mono_free_method (call.method);
+ return;
+ }
+ }
+ /* No class constructor found */
+}
+
+/*
+ * newobj:
+ * @image: image where the object is being referenced
+ * @token: method token to invoke
+ *
+ * This routine creates a new object based on the class where the
+ * constructor lives.x
+ */
+static MonoObject *
+newobj (MonoImage *image, guint32 token)
+{
+ MonoObject *result = NULL;
+
+ switch (mono_metadata_token_code (token)){
+ case MONO_TOKEN_METHOD_DEF: {
+ guint32 idx;
+
+ idx = mono_metadata_typedef_from_method (image, token);
+ result = mono_object_new (image, MONO_TOKEN_TYPE_DEF | idx);
+ break;
+ }
+ case MONO_TOKEN_MEMBER_REF: {
+ guint32 member_cols [MONO_MEMBERREF_SIZE];
+ guint32 mpr_token, table, idx;
+
+ mono_metadata_decode_row (
+ &image->tables [MONO_TABLE_MEMBERREF],
+ mono_metadata_token_index (token) - 1,
+ member_cols, CSIZE (member_cols));
+ mpr_token = member_cols [MONO_MEMBERREF_CLASS];
+ table = mpr_token & 7;
+ idx = mpr_token >> 3;
+
+ if (strcmp (mono_metadata_string_heap (image, member_cols[1]), ".ctor"))
+ g_error ("Unhandled: call to non constructor");
+
+ switch (table){
+ case 0: /* TypeDef */
+ result = mono_object_new (image, MONO_TOKEN_TYPE_DEF | idx);
+ break;
+ case 1: /* TypeRef */
+ result = mono_object_new (image, MONO_TOKEN_TYPE_REF | idx);
+ break;
+ case 2: /* ModuleRef */
+ g_error ("Unhandled: ModuleRef");
+
+ case 3: /* MethodDef */
+ g_error ("Unhandled: MethodDef");
+
+ case 4: /* TypeSpec */
+ result = mono_object_new (image, MONO_TOKEN_TYPE_SPEC | idx);
+ }
+ break;
+ }
+ default:
+ g_warning ("dont know how to handle token %08x\n", token);
+ g_assert_not_reached ();
+ }
+
+ if (result)
+ init_class (result->klass);
+ return result;
+}
+
+static MonoMethod*
+get_virtual_method (MonoImage *image, guint32 token, stackval *args)
+{
+ switch (mono_metadata_token_table (token)) {
+ case MONO_TABLE_METHOD:
+ case MONO_TABLE_MEMBERREF:
+ return mono_get_method (image, token, NULL);
+ }
+ g_error ("got virtual method: 0x%x\n", token);
+ return NULL;
+}
+
+/*
+ * When this is tested, export it from cli/.
+ */
+static int
+match_signature (const char *name, MonoMethodSignature *sig, MonoMethod *method)
+{
+ int i;
+ MonoMethodSignature *sig2 = method->signature;
+ /*
+ * compare the signatures.
+ * First the cheaper comparisons.
+ */
+ if (sig->param_count != sig2->param_count)
+ return 0;
+ if (sig->hasthis != sig2->hasthis)
+ return 0;
+ /*if (!sig->ret) {
+ if (sig2->ret) return 0;
+ } else {
+ if (!sig2->ret) return 0;
+ if (sig->ret->type->type != sig2->ret->type->type)
+ return 0;
+ }*/
+ for (i = sig->param_count - 1; i >= 0; ++i) {
+ if (sig->params [i]->type->type != sig2->params [i]->type->type)
+ return 0;
+ }
+ /* compare the function name */
+ return strcmp (name, method->name) == 0;
+}
+
+static MonoObject*
+get_named_exception (const char *name)
+{
+ MonoClass *klass;
+ MonoInvocation call;
+ MonoMethod *method = NULL;
+ MonoObject *o;
+ int i;
+ guint32 tdef;
+
+ tdef = mono_class_token_from_name (mono_defaults.corlib, "System", name);
+
+ o = mono_object_new (mono_defaults.corlib, tdef);
+ g_assert (o != NULL);
+
+ klass = mono_class_get (mono_defaults.corlib, tdef);
+
+ for (i = 0; i < klass->method.count; ++i) {
+ if (!strcmp (".ctor", klass->methods [i]->name) &&
+ klass->methods [i]->signature->param_count == 0) {
+ method = klass->methods [i];
+ break;
+ }
+ }
+
+ call.obj = o;
+
+ g_assert (method);
+ INIT_FRAME (&call, NULL, o, NULL, NULL, method);
+
+ ves_exec_method (&call);
+ return o;
+}
+
+static MonoObject*
+get_exception_divide_by_zero ()
+{
+ static MonoObject *ex = NULL;
+ if (ex)
+ return ex;
+ ex = get_named_exception ("DivideByZeroException");
+ return ex;
+}
+
+static MonoObject*
+get_exception_security ()
+{
+ static MonoObject *ex = NULL;
+ if (ex)
+ return ex;
+ ex = get_named_exception ("SecurityException");
+ return ex;
+}
+
+static MonoObject*
+get_exception_arithmetic ()
+{
+ static MonoObject *ex = NULL;
+ if (ex)
+ return ex;
+ ex = get_named_exception ("ArithmeticException");
+ return ex;
+}
+
+static MonoObject*
+get_exception_overflow ()
+{
+ static MonoObject *ex = NULL;
+ if (ex)
+ return ex;
+ ex = get_named_exception ("OverflowException");
+ return ex;
+}
+
+static MonoObject*
+get_exception_null_reference ()
+{
+ static MonoObject *ex = NULL;
+ if (ex)
+ return ex;
+ ex = get_named_exception ("NullReferenceException");
+ return ex;
+}
+
+static MonoObject*
+get_exception_execution_engine ()
+{
+ static MonoObject *ex = NULL;
+ if (ex)
+ return ex;
+ ex = get_named_exception ("ExecutionEngineException");
+ return ex;
+}
+
+static void
+stackval_from_data (MonoType *type, stackval *result, const char *data)
+{
+ if (type->byref) {
+ result->type = VAL_OBJ;
+ result->data.p = *(gpointer*)data;
+ return;
+ }
+ switch (type->type) {
+ case MONO_TYPE_I1:
+ result->type = VAL_I32;
+ result->data.i = *(gint8*)data;
+ return;
+ case MONO_TYPE_U1:
+ case MONO_TYPE_BOOLEAN:
+ result->type = VAL_I32;
+ result->data.i = *(guint8*)data;
+ return;
+ case MONO_TYPE_I2:
+ result->type = VAL_I32;
+ result->data.i = *(gint16*)data;
+ return;
+ case MONO_TYPE_U2:
+ case MONO_TYPE_CHAR:
+ result->type = VAL_I32;
+ result->data.i = *(guint16*)data;
+ return;
+ case MONO_TYPE_I4:
+ result->type = VAL_I32;
+ result->data.i = *(gint32*)data;
+ return;
+ case MONO_TYPE_U4:
+ result->type = VAL_I32;
+ result->data.i = *(guint32*)data;
+ return;
+ case MONO_TYPE_R4:
+ result->type = VAL_DOUBLE;
+ result->data.f = *(float*)data;
+ return;
+ case MONO_TYPE_R8:
+ result->type = VAL_DOUBLE;
+ result->data.f = *(double*)data;
+ return;
+ case MONO_TYPE_STRING:
+ case MONO_TYPE_SZARRAY:
+ case MONO_TYPE_CLASS:
+ case MONO_TYPE_OBJECT:
+ case MONO_TYPE_ARRAY:
+ case MONO_TYPE_PTR:
+ result->type = VAL_OBJ;
+ result->data.p = *(gpointer*)data;
+ return;
+ default:
+ g_warning ("got type %x", type->type);
+ g_assert_not_reached ();
+ }
+}
+
+static void
+stackval_to_data (MonoType *type, stackval *val, char *data)
+{
+ if (type->byref) {
+ *(gpointer*)data = val->data.p;
+ return;
+ }
+ switch (type->type) {
+ case MONO_TYPE_I1:
+ case MONO_TYPE_U1:
+ *(guint8*)data = val->data.i;
+ break;
+ case MONO_TYPE_BOOLEAN:
+ *(guint8*)data = (val->data.i != 0);
+ break;
+ case MONO_TYPE_I2:
+ case MONO_TYPE_U2:
+ *(guint16*)data = val->data.i;
+ break;
+ case MONO_TYPE_I4:
+ case MONO_TYPE_U4:
+ *(gint32*)data = val->data.i;
+ break;
+ case MONO_TYPE_R4:
+ *(float*)data = val->data.f;
+ break;
+ case MONO_TYPE_R8:
+ *(double*)data = val->data.f;
+ break;
+ case MONO_TYPE_STRING:
+ case MONO_TYPE_SZARRAY:
+ case MONO_TYPE_CLASS:
+ case MONO_TYPE_OBJECT:
+ case MONO_TYPE_ARRAY:
+ case MONO_TYPE_PTR:
+ *(gpointer*)data = val->data.p;
+ break;
+ default:
+ g_warning ("got type %x", type->type);
+ g_assert_not_reached ();
+ }
+}
+
+static char *
+mono_get_ansi_string (MonoObject *o)
+{
+ MonoStringObject *s = (MonoStringObject *)o;
+ char *as, *vector;
+ int i;
+
+ g_assert (o != NULL);
+
+ if (!s->length)
+ return g_strdup ("");
+
+ vector = s->c_str->vector;
+
+ g_assert (vector != NULL);
+
+ as = g_malloc (s->length + 1);
+
+ /* fixme: replace with a real unicode/ansi conversion */
+ for (i = 0; i < s->length; i++) {
+ as [i] = vector [i*2];
+ }
+
+ as [i] = '\0';
+
+ return as;
+}
+
+static void
+ves_pinvoke_method (MonoInvocation *frame)
+{
+ MonoMethodPInvoke *piinfo = (MonoMethodPInvoke *)frame->method;
+ MonoMethodSignature *sig = frame->method->signature;
+ gpointer *values;
+ float *tmp_float;
+ char **tmp_string;
+ int i, acount, rsize, align;
+ stackval *sp = frame->stack_args;
+ gpointer res = NULL;
+ GSList *t, *l = NULL;
+
+ acount = sig->param_count;
+
+ values = alloca (sizeof (gpointer) * acount);
+
+ /* fixme: only works on little endian machines */
+
+ for (i = 0; i < acount; i++) {
+
+ switch (sig->params [i]->type->type) {
+
+ case MONO_TYPE_I1:
+ case MONO_TYPE_U1:
+ case MONO_TYPE_BOOLEAN:
+ case MONO_TYPE_I2:
+ case MONO_TYPE_U2:
+ case MONO_TYPE_CHAR:
+ case MONO_TYPE_I4:
+ case MONO_TYPE_U4:
+ values[i] = &sp [i].data.i;
+ break;
+ case MONO_TYPE_R4:
+ tmp_float = alloca (sizeof (float));
+ *tmp_float = sp [i].data.f;
+ values[i] = tmp_float;
+ break;
+ case MONO_TYPE_R8:
+ values[i] = &sp [i].data.f;
+ break;
+ case MONO_TYPE_STRING:
+ g_assert (sp [i].type == VAL_OBJ);
+
+ if (frame->method->flags & PINVOKE_ATTRIBUTE_CHAR_SET_ANSI && sp [i].data.p) {
+ tmp_string = alloca (sizeof (char *));
+ *tmp_string = mono_get_ansi_string (sp [i].data.p);
+ l = g_slist_prepend (l, *tmp_string);
+ values[i] = tmp_string;
+ } else {
+ /*
+ * fixme: may we pass the object - I assume
+ * that is wrong ??
+ */
+ values[i] = &sp [i].data.p;
+ }
+
+ break;
+ default:
+ g_warning ("not implemented %x",
+ sig->params [i]->type->type);
+ g_assert_not_reached ();
+ }
+
+ }
+
+ if ((rsize = mono_type_size (sig->ret->type, &align)))
+ res = alloca (rsize);
+
+ ffi_call (piinfo->cif, frame->method->addr, res, values);
+
+ t = l;
+ while (t) {
+ g_free (t->data);
+ t = t->next;
+ }
+
+ g_slist_free (l);
+
+ if (sig->ret->type->type != MONO_TYPE_VOID)
+ stackval_from_data (sig->ret->type, frame->retval, res);
+}
+
+#define DEBUG_INTERP 0
+#if DEBUG_INTERP
+#define OPDEF(a,b,c,d,e,f,g,h,i,j) b,
+static char *opcode_names[] = {
+#include "mono/cil/opcode.def"
+ NULL
+};
+#undef OPDEF
+
+static void
+output_indent (void)
+{
+ int h;
+
+ for (h = 0; h < debug_indent_level; h++)
+ g_print (" ");
+}
+
+static void
+dump_stack (stackval *stack, stackval *sp)
+{
+ stackval *s = stack;
+
+ if (sp == stack)
+ return;
+
+ output_indent ();
+ g_print ("stack: ");
+
+ while (s < sp) {
+ switch (s->type) {
+ case VAL_I32: g_print ("[%d] ", s->data.i); break;
+ case VAL_I64: g_print ("[%lld] ", s->data.l); break;
+ case VAL_DOUBLE: g_print ("[%0.5f] ", s->data.f); break;
+ default: g_print ("[%p] ", s->data.p); break;
+ }
+ ++s;
+ }
+}
+
+#define DEBUG_ENTER() \
+ do { \
+ MonoClass *klass = frame->method->klass; \
+ debug_indent_level++; \
+ output_indent (); \
+ g_print ("Entering %s.%s::%s\n", klass->name_space, klass->name, frame->method->name); \
+ } while (0)
+#define DEBUG_LEAVE() \
+ do { \
+ MonoClass *klass = frame->method->klass; \
+ output_indent (); \
+ g_print ("Leaving %s.%s::%s\n", klass->name_space, klass->name, frame->method->name); \
+ debug_indent_level--; \
+ } while (0)
+
+#else
+
+#define DEBUG_ENTER()
+#define DEBUG_LEAVE()
+
+#endif
+
+static MonoType
+method_this = {
+ MONO_TYPE_CLASS,
+ 0,
+ 1, /* byref */
+ 0,
+ {0}
+};
+
+#define LOCAL_POS(n) (locals_pointers [(n)])
+#define LOCAL_TYPE(header, n) ((header)->locals [(n)])
+
+#define ARG_POS(n) (args_pointers [(n)])
+#define ARG_TYPE(sig, n) ((n) ? (sig)->params [(n) - (sig)->hasthis]->type : \
+ (sig)->hasthis ? &method_this: (sig)->params [(0)]->type)
+
+#define THROW_EX(exception,ex_ip) \
+ do {\
+ frame->ip = (ex_ip); \
+ frame->ex = (exception); \
+ goto handle_exception; \
+ } while (0)
+
+/*
+ * Need to optimize ALU ops when natural int == int32
+ *
+ * IDEA: if we maintain a stack of ip, sp to be checked
+ * in the return opcode, we could inline simple methods that don't
+ * use the stack or local variables....
+ *
+ * The {,.S} versions of many opcodes can/should be merged to reduce code
+ * duplication.
+ *
+ */
+static void
+ves_exec_method (MonoInvocation *frame)
+{
+ MonoInvocation child_frame;
+ MonoMethodHeader *header;
+ MonoMethodSignature *signature;
+ MonoImage *image;
+ const unsigned char *endfinally_ip;
+ register const unsigned char *ip;
+ register stackval *sp;
+ void **locals_pointers;
+ void **args_pointers;
+ unsigned char tail_recursion = 0;
+ unsigned char unaligned_address = 0;
+ unsigned char volatile_address = 0;
+ GOTO_LABEL_VARS;
+
+ if (!frame->method->klass->inited)
+ init_class (frame->method->klass);
+
+ if (frame->method->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL) {
+ ICallMethod icall = frame->method->addr;
+ icall (frame);
+ return;
+ }
+
+ if (frame->method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL) {
+ ves_pinvoke_method (frame);
+ return;
+ }
+
+ header = ((MonoMethodNormal *)frame->method)->header;
+ signature = frame->method->signature;
+ image = frame->method->klass->image;
+
+ DEBUG_ENTER ();
+
+ /*
+ * with alloca we get the expected huge performance gain
+ * stackval *stack = g_new0(stackval, header->max_stack);
+ */
+
+ sp = frame->stack = alloca (sizeof (stackval) * header->max_stack);
+
+ if (header->num_locals) {
+ int i, align, size, offset = 0;
+
+ frame->locals = alloca (header->locals_size);
+ locals_pointers = alloca (sizeof(void*) * header->num_locals);
+ /*
+ * yes, we do it unconditionally, because it needs to be done for
+ * some cases anyway and checking for that would be even slower.
+ */
+ memset (frame->locals, 0, header->locals_size);
+ for (i = 0; i < header->num_locals; ++i) {
+ locals_pointers [i] = frame->locals + offset;
+ size = mono_type_size (header->locals [i], &align);
+ offset += offset % align;
+ offset += size;
+ }
+ }
+ /*
+ * Copy args from stack_args to args.
+ */
+ if (signature->params_size) {
+ int i, align, size, offset = 0;
+ int has_this = signature->hasthis;
+
+ frame->args = alloca (signature->params_size);
+ args_pointers = alloca (sizeof(void*) * (signature->param_count + has_this));
+ if (has_this) {
+ args_pointers [0] = frame->args;
+ *(gpointer*) frame->args = frame->obj;
+ offset += sizeof (gpointer);
+ }
+ for (i = 0; i < signature->param_count; ++i) {
+ args_pointers [i + has_this] = frame->args + offset;
+ stackval_to_data (signature->params [i]->type, frame->stack_args + i, frame->args + offset);
+ size = mono_type_size (signature->params [i]->type, &align);
+ offset += offset % align;
+ offset += size;
+ }
+ }
+
+ child_frame.parent = frame;
+ frame->child = &child_frame;
+ frame->ex = NULL;
+
+ /* ready to go */
+ ip = header->code;
+
+ /*
+ * using while (ip < end) may result in a 15% performance drop,
+ * but it may be useful for debug
+ */
+ while (1) {
+ main_loop:
+ /*g_assert (sp >= stack);*/
+#if DEBUG_INTERP
+ dump_stack (frame->stack, sp);
+ g_print ("\n");
+ output_indent ();
+ g_print ("0x%04x: %s\n", ip-header->code,
+ *ip == 0xfe ? opcode_names [256 + ip [1]] : opcode_names [*ip]);
+#endif
+
+ SWITCH (*ip) {
+ CASE (CEE_NOP)
+ ++ip;
+ BREAK;
+ CASE (CEE_BREAK)
+ ++ip;
+ G_BREAKPOINT (); /* this is not portable... */
+ BREAK;
+ CASE (CEE_LDARG_0)
+ CASE (CEE_LDARG_1)
+ CASE (CEE_LDARG_2)
+ CASE (CEE_LDARG_3) {
+ int n = (*ip)-CEE_LDARG_0;
+ ++ip;
+ stackval_from_data (ARG_TYPE (signature, n), sp, ARG_POS (n));
+ ++sp;
+ BREAK;
+ }
+ CASE (CEE_LDLOC_0)
+ CASE (CEE_LDLOC_1)
+ CASE (CEE_LDLOC_2)
+ CASE (CEE_LDLOC_3) {
+ int n = (*ip)-CEE_LDLOC_0;
+ ++ip;
+ stackval_from_data (LOCAL_TYPE (header, n), sp, LOCAL_POS (n));
+ ++sp;
+ BREAK;
+ }
+ CASE (CEE_STLOC_0)
+ CASE (CEE_STLOC_1)
+ CASE (CEE_STLOC_2)
+ CASE (CEE_STLOC_3) {
+ int n = (*ip)-CEE_STLOC_0;
+ ++ip;
+ --sp;
+ stackval_to_data (LOCAL_TYPE (header, n), sp, LOCAL_POS (n));
+ BREAK;
+ }
+ CASE (CEE_LDARG_S)
+ ++ip;
+ stackval_from_data (ARG_TYPE (signature, *ip), sp, ARG_POS (*ip));
+ ++sp;
+ ++ip;
+ BREAK;
+ CASE (CEE_LDARGA_S)
+ ++ip;
+ sp->type = VAL_TP;
+ sp->data.p = ARG_POS (*ip);
+ ++sp;
+ ++ip;
+ BREAK;
+ CASE (CEE_STARG_S) ves_abort(); BREAK;
+ CASE (CEE_LDLOC_S)
+ ++ip;
+ stackval_from_data (LOCAL_TYPE (header, *ip), sp, LOCAL_POS (*ip));
+ ++ip;
+ ++sp;
+ BREAK;
+ CASE (CEE_LDLOCA_S)
+ ++ip;
+ sp->type = VAL_TP;
+ sp->data.p = LOCAL_POS (*ip);
+ ++sp;
+ ++ip;
+ BREAK;
+ CASE (CEE_STLOC_S)
+ ++ip;
+ --sp;
+ stackval_to_data (LOCAL_TYPE (header, *ip), sp, LOCAL_POS (*ip));
+ ++ip;
+ BREAK;
+ CASE (CEE_LDNULL)
+ ++ip;
+ sp->type = VAL_OBJ;
+ sp->data.p = NULL;
+ ++sp;
+ BREAK;
+ CASE (CEE_LDC_I4_M1)
+ ++ip;
+ sp->type = VAL_I32;
+ sp->data.i = -1;
+ ++sp;
+ BREAK;
+ CASE (CEE_LDC_I4_0)
+ CASE (CEE_LDC_I4_1)
+ CASE (CEE_LDC_I4_2)
+ CASE (CEE_LDC_I4_3)
+ CASE (CEE_LDC_I4_4)
+ CASE (CEE_LDC_I4_5)
+ CASE (CEE_LDC_I4_6)
+ CASE (CEE_LDC_I4_7)
+ CASE (CEE_LDC_I4_8)
+ sp->type = VAL_I32;
+ sp->data.i = (*ip) - CEE_LDC_I4_0;
+ ++sp;
+ ++ip;
+ BREAK;
+ CASE (CEE_LDC_I4_S)
+ ++ip;
+ sp->type = VAL_I32;
+ sp->data.i = *ip; /* FIXME: signed? */
+ ++ip;
+ ++sp;
+ BREAK;
+ CASE (CEE_LDC_I4)
+ ++ip;
+ sp->type = VAL_I32;
+ sp->data.i = read32 (ip);
+ ip += 4;
+ ++sp;
+ BREAK;
+ CASE (CEE_LDC_I8)
+ ++ip;
+ sp->type = VAL_I64;
+ sp->data.i = read64 (ip);
+ ip += 8;
+ ++sp;
+ BREAK;
+ CASE (CEE_LDC_R4)
+ ++ip;
+ sp->type = VAL_DOUBLE;
+ /* FIXME: ENOENDIAN */
+ sp->data.f = *(float*)(ip);
+ ip += sizeof (float);
+ ++sp;
+ BREAK;
+ CASE (CEE_LDC_R8)
+ ++ip;
+ sp->type = VAL_DOUBLE;
+ /* FIXME: ENOENDIAN */
+ sp->data.f = *(double*) (ip);
+ ip += sizeof (double);
+ ++sp;
+ BREAK;
+ CASE (CEE_UNUSED99) ves_abort (); BREAK;
+ CASE (CEE_DUP)
+ *sp = sp [-1];
+ ++sp;
+ ++ip;
+ BREAK;
+ CASE (CEE_POP)
+ ++ip;
+ --sp;
+ BREAK;
+ CASE (CEE_JMP) ves_abort(); BREAK;
+ CASE (CEE_CALLVIRT) /* Fall through */
+ CASE (CEE_CALL) {
+ MonoMethodSignature *csignature;
+ stackval retval;
+ guint32 token;
+ int virtual = *ip == CEE_CALLVIRT;
+
+ /*
+ * We ignore tail recursion for now.
+ */
+ tail_recursion = 0;
+
+ frame->ip = ip;
+
+ ++ip;
+ token = read32 (ip);
+ ip += 4;
+ if (virtual)
+ child_frame.method = get_virtual_method (image, token, sp);
+ else
+ child_frame.method = mono_get_method (image, token, NULL);
+ csignature = child_frame.method->signature;
+ g_assert (csignature->call_convention == MONO_CALL_DEFAULT);
+
+ /* decrement by the actual number of args */
+ if (csignature->param_count) {
+ sp -= csignature->param_count;
+ child_frame.stack_args = sp;
+ } else {
+ child_frame.stack_args = NULL;
+ }
+ if (csignature->hasthis) {
+ g_assert (sp >= frame->stack);
+ --sp;
+ g_assert (sp->type == VAL_OBJ);
+ child_frame.obj = sp->data.p;
+ } else {
+ child_frame.obj = NULL;
+ }
+ if (csignature->ret->type->type != MONO_TYPE_VOID) {
+ /* FIXME: handle valuetype */
+ child_frame.retval = &retval;
+ } else {
+ child_frame.retval = NULL;
+ }
+
+ child_frame.ex = NULL;
+ child_frame.ex_handler = NULL;
+
+ ves_exec_method (&child_frame);
+
+ if (child_frame.ex) {
+ /*
+ * An exception occurred, need to run finally, fault and catch handlers..
+ */
+ frame->ex = child_frame.ex;
+ goto handle_finally;
+ }
+
+ /* need to handle typedbyref ... */
+ if (csignature->ret->type->type != MONO_TYPE_VOID) {
+ *sp = retval;
+ sp++;
+ }
+ BREAK;
+ }
+ CASE (CEE_CALLI) ves_abort(); BREAK;
+ CASE (CEE_RET)
+ if (signature->ret->type->type != MONO_TYPE_VOID) {
+ --sp;
+ *frame->retval = *sp;
+ }
+ if (sp > frame->stack)
+ g_warning ("more values on stack: %d", sp-frame->stack);
+
+ DEBUG_LEAVE ();
+ return;
+ CASE (CEE_BR_S) /* Fall through */
+ CASE (CEE_BR)
+ if (*ip == CEE_BR) {
+ ++ip;
+ ip += (gint32) read32(ip);
+ ip += 4;
+ } else {
+ ++ip;
+ ip += (signed char) *ip;
+ ++ip;
+ }
+ BREAK;
+ CASE (CEE_BRFALSE) /* Fall through */
+ CASE (CEE_BRFALSE_S) {
+ int result;
+ int near_jump = *ip == CEE_BRFALSE_S;
+ ++ip;
+ --sp;
+ switch (sp->type) {
+ case VAL_I32: result = sp->data.i == 0; break;
+ case VAL_I64: result = sp->data.l == 0; break;
+ case VAL_DOUBLE: result = sp->data.f ? 0: 1; break;
+ default: result = sp->data.p == NULL; break;
+ }
+ if (result) {
+ if (near_jump)
+ ip += (signed char)*ip;
+ else
+ ip += (gint32) read32 (ip);
+ }
+ ip += near_jump ? 1: 4;
+ BREAK;
+ }
+ CASE (CEE_BRTRUE) /* Fall through */
+ CASE (CEE_BRTRUE_S) {
+ int result;
+ int near_jump = *ip == CEE_BRTRUE_S;
+ ++ip;
+ --sp;
+ switch (sp->type) {
+ case VAL_I32: result = sp->data.i != 0; break;
+ case VAL_I64: result = sp->data.l != 0; break;
+ case VAL_DOUBLE: result = sp->data.f ? 1 : 0; break;
+ default: result = sp->data.p != NULL; break;
+ }
+ if (result) {
+ if (near_jump)
+ ip += (signed char)*ip;
+ else
+ ip += (gint32) read32 (ip);
+ }
+ ip += near_jump ? 1: 4;
+ BREAK;
+ }
+ CASE (CEE_BEQ) /* Fall through */
+ CASE (CEE_BEQ_S) {
+ int result;
+ int near_jump = *ip == CEE_BEQ_S;
+ ++ip;
+ sp -= 2;
+ if (sp->type == VAL_I32)
+ result = sp [0].data.i == GET_NATI (sp [1]);
+ else if (sp->type == VAL_I64)
+ result = sp [0].data.l == sp [1].data.l;
+ else if (sp->type == VAL_DOUBLE)
+ result = sp [0].data.f == sp [1].data.f;
+ else
+ result = GET_NATI (sp [0]) == GET_NATI (sp [1]);
+ if (result) {
+ if (near_jump)
+ ip += (signed char)*ip;
+ else
+ ip += (gint32) read32 (ip);
+ }
+ ip += near_jump ? 1: 4;
+ BREAK;
+ }
+ CASE (CEE_BGE) /* Fall through */
+ CASE (CEE_BGE_S) {
+ int result;
+ int near_jump = *ip == CEE_BGE_S;
+ ++ip;
+ sp -= 2;
+ if (sp->type == VAL_I32)
+ result = sp [0].data.i >= GET_NATI (sp [1]);
+ else if (sp->type == VAL_I64)
+ result = sp [0].data.l >= sp [1].data.l;
+ else if (sp->type == VAL_DOUBLE)
+ result = sp [0].data.f >= sp [1].data.f;
+ else
+ result = GET_NATI (sp [0]) >= GET_NATI (sp [1]);
+ if (result) {
+ if (near_jump)
+ ip += (signed char)*ip;
+ else
+ ip += (gint32) read32 (ip);
+ }
+ ip += near_jump ? 1: 4;
+ BREAK;
+ }
+ CASE (CEE_BGT) /* Fall through */
+ CASE (CEE_BGT_S) {
+ int result;
+ int near_jump = *ip == CEE_BGT_S;
+ ++ip;
+ sp -= 2;
+ if (sp->type == VAL_I32)
+ result = sp [0].data.i > GET_NATI (sp [1]);
+ else if (sp->type == VAL_I64)
+ result = sp [0].data.l > sp [1].data.l;
+ else if (sp->type == VAL_DOUBLE)
+ result = sp [0].data.f > sp [1].data.f;
+ else
+ result = GET_NATI (sp [0]) > GET_NATI (sp [1]);
+ if (result) {
+ if (near_jump)
+ ip += (signed char)*ip;
+ else
+ ip += (gint32) read32 (ip);
+ }
+ ip += near_jump ? 1: 4;
+ BREAK;
+ }
+ CASE (CEE_BLT) /* Fall through */
+ CASE (CEE_BLT_S) {
+ int result;
+ int near_jump = *ip == CEE_BLT_S;
+ ++ip;
+ sp -= 2;
+ if (sp->type == VAL_I32)
+ result = sp[0].data.i < GET_NATI(sp[1]);
+ else if (sp->type == VAL_I64)
+ result = sp[0].data.l < sp[1].data.l;
+ else if (sp->type == VAL_DOUBLE)
+ result = sp[0].data.f < sp[1].data.f;
+ else
+ result = GET_NATI(sp[0]) < GET_NATI(sp[1]);
+ if (result) {
+ if (near_jump)
+ ip += (signed char)*ip;
+ else
+ ip += (gint32) read32 (ip);
+ }
+ ip += near_jump ? 1: 4;
+ BREAK;
+ }
+ CASE (CEE_BLE) /* fall through */
+ CASE (CEE_BLE_S) {
+ int result;
+ int near_jump = *ip == CEE_BLE_S;
+ ++ip;
+ sp -= 2;
+
+ if (sp->type == VAL_I32)
+ result = sp [0].data.i <= GET_NATI (sp [1]);
+ else if (sp->type == VAL_I64)
+ result = sp [0].data.l <= sp [1].data.l;
+ else if (sp->type == VAL_DOUBLE)
+ result = sp [0].data.f <= sp [1].data.f;
+ else {
+ /*
+ * FIXME: here and in other places GET_NATI on the left side
+ * _will_ be wrong when we change the macro to work on 64 buts
+ * systems.
+ */
+ result = GET_NATI (sp [0]) <= GET_NATI (sp [1]);
+ }
+ if (result) {
+ if (near_jump)
+ ip += (signed char)*ip;
+ else
+ ip += (gint32) read32 (ip);
+ }
+ ip += near_jump ? 1: 4;
+ BREAK;
+ }
+ CASE (CEE_BNE_UN) /* Fall through */
+ CASE (CEE_BNE_UN_S) {
+ int result;
+ int near_jump = *ip == CEE_BNE_UN_S;
+ ++ip;
+ sp -= 2;
+ if (sp->type == VAL_I32)
+ result = (guint32)sp [0].data.i != (guint32)GET_NATI (sp [1]);
+ else if (sp->type == VAL_I64)
+ result = (guint64)sp [0].data.l != (guint64)sp [1].data.l;
+ else if (sp->type == VAL_DOUBLE)
+ result = isunordered (sp [0].data.f, sp [1].data.f) ||
+ (sp [0].data.f != sp [1].data.f);
+ else
+ result = GET_NATI (sp [0]) != GET_NATI (sp [1]);
+ if (result) {
+ if (near_jump)
+ ip += (signed char)*ip;
+ else
+ ip += (gint32) read32 (ip);
+ }
+ ip += near_jump ? 1: 4;
+ BREAK;
+ }
+ CASE (CEE_BGE_UN) /* Fall through */
+ CASE (CEE_BGE_UN_S) {
+ int result;
+ int near_jump = *ip == CEE_BGE_UN_S;
+ ++ip;
+ sp -= 2;
+ if (sp->type == VAL_I32)
+ result = (guint32)sp [0].data.i >= (guint32)GET_NATI (sp [1]);
+ else if (sp->type == VAL_I64)
+ result = (guint64)sp [0].data.l >= (guint64)sp [1].data.l;
+ else if (sp->type == VAL_DOUBLE)
+ result = !isless (sp [0].data.f,sp [1].data.f);
+ else
+ result = GET_NATI (sp [0]) >= GET_NATI (sp [1]);
+ if (result) {
+ if (near_jump)
+ ip += (signed char)*ip;
+ else
+ ip += (gint32) read32 (ip);
+ }
+ ip += near_jump ? 1: 4;
+ BREAK;
+ }
+ CASE (CEE_BGT_UN) /* Fall through */
+ CASE (CEE_BGT_UN_S) {
+ int result;
+ int near_jump = *ip == CEE_BGT_UN_S;
+ ++ip;
+ sp -= 2;
+ if (sp->type == VAL_I32)
+ result = (guint32)sp [0].data.i > (guint32)GET_NATI (sp [1]);
+ else if (sp->type == VAL_I64)
+ result = (guint64)sp [0].data.l > (guint64)sp [1].data.l;
+ else if (sp->type == VAL_DOUBLE)
+ result = isgreater (sp [0].data.f, sp [1].data.f);
+ else
+ result = GET_NATI (sp [0]) > GET_NATI (sp [1]);
+ if (result) {
+ if (near_jump)
+ ip += (signed char)*ip;
+ else
+ ip += (gint32) read32 (ip);
+ }
+ ip += near_jump ? 1: 4;
+ BREAK;
+ }
+ CASE (CEE_BLE_UN) /* Fall through */
+ CASE (CEE_BLE_UN_S) {
+ int result;
+ int near_jump = *ip == CEE_BLE_UN_S;
+ ++ip;
+ sp -= 2;
+ if (sp->type == VAL_I32)
+ result = (guint32)sp [0].data.i <= (guint32)GET_NATI (sp [1]);
+ else if (sp->type == VAL_I64)
+ result = (guint64)sp [0].data.l <= (guint64)sp [1].data.l;
+ else if (sp->type == VAL_DOUBLE)
+ result = islessequal (sp [0].data.f, sp [1].data.f);
+ else
+ result = GET_NATI (sp [0]) <= GET_NATI (sp [1]);
+ if (result) {
+ if (near_jump)
+ ip += (signed char)*ip;
+ else
+ ip += (gint32) read32 (ip);
+ }
+ ip += near_jump ? 1: 4;
+ BREAK;
+ }
+ CASE (CEE_BLT_UN) /* Fall through */
+ CASE (CEE_BLT_UN_S) {
+ int result;
+ int near_jump = *ip == CEE_BLT_UN_S;
+ ++ip;
+ sp -= 2;
+ if (sp->type == VAL_I32)
+ result = (guint32)sp[0].data.i < (guint32)GET_NATI(sp[1]);
+ else if (sp->type == VAL_I64)
+ result = (guint64)sp[0].data.l < (guint64)sp[1].data.l;
+ else if (sp->type == VAL_DOUBLE)
+ result = isunordered (sp [0].data.f, sp [1].data.f) ||
+ (sp [0].data.f < sp [1].data.f);
+ else
+ result = GET_NATI(sp[0]) < GET_NATI(sp[1]);
+ if (result) {
+ if (near_jump)
+ ip += (signed char)*ip;
+ else
+ ip += (gint32) read32 (ip);
+ }
+ ip += near_jump ? 1: 4;
+ BREAK;
+ }
+ CASE (CEE_SWITCH) {
+ guint32 n;
+ const unsigned char *st;
+ ++ip;
+ n = read32 (ip);
+ ip += 4;
+ st = ip + sizeof (gint32) * n;
+ --sp;
+ if ((guint32)sp->data.i < n) {
+ gint offset;
+ ip += sizeof (gint32) * (guint32)sp->data.i;
+ offset = read32 (ip);
+ ip = st + offset;
+ } else {
+ ip = st;
+ }
+ BREAK;
+ }
+ CASE (CEE_LDIND_I1)
+ ++ip;
+ sp[-1].type = VAL_I32;
+ sp[-1].data.i = *(gint8*)sp[-1].data.p;
+ BREAK;
+ CASE (CEE_LDIND_U1)
+ ++ip;
+ sp[-1].type = VAL_I32;
+ sp[-1].data.i = *(guint8*)sp[-1].data.p;
+ BREAK;
+ CASE (CEE_LDIND_I2)
+ ++ip;
+ sp[-1].type = VAL_I32;
+ sp[-1].data.i = *(gint16*)sp[-1].data.p;
+ BREAK;
+ CASE (CEE_LDIND_U2)
+ ++ip;
+ sp[-1].type = VAL_I32;
+ sp[-1].data.i = *(guint16*)sp[-1].data.p;
+ BREAK;
+ CASE (CEE_LDIND_I4) /* Fall through */
+ CASE (CEE_LDIND_U4)
+ ++ip;
+ sp[-1].type = VAL_I32;
+ sp[-1].data.i = *(gint32*)sp[-1].data.p;
+ BREAK;
+ CASE (CEE_LDIND_I8)
+ ++ip;
+ sp[-1].type = VAL_I64;
+ sp[-1].data.l = *(gint64*)sp[-1].data.p;
+ BREAK;
+ CASE (CEE_LDIND_I)
+ ++ip;
+ sp[-1].type = VAL_NATI;
+ sp[-1].data.p = *(gpointer*)sp[-1].data.p;
+ BREAK;
+ CASE (CEE_LDIND_R4)
+ ++ip;
+ sp[-1].type = VAL_DOUBLE;
+ sp[-1].data.i = *(gfloat*)sp[-1].data.p;
+ BREAK;
+ CASE (CEE_LDIND_R8)
+ ++ip;
+ sp[-1].type = VAL_DOUBLE;
+ sp[-1].data.i = *(gdouble*)sp[-1].data.p;
+ BREAK;
+ CASE (CEE_LDIND_REF)
+ ++ip;
+ sp[-1].type = VAL_OBJ;
+ sp[-1].data.p = *(gpointer*)sp[-1].data.p;
+ BREAK;
+ CASE (CEE_STIND_REF)
+ ++ip;
+ sp -= 2;
+ *(gpointer*)sp->data.p = sp[1].data.p;
+ BREAK;
+ CASE (CEE_STIND_I1)
+ ++ip;
+ sp -= 2;
+ *(gint8*)sp->data.p = (gint8)sp[1].data.i;
+ BREAK;
+ CASE (CEE_STIND_I2)
+ ++ip;
+ sp -= 2;
+ *(gint16*)sp->data.p = (gint16)sp[1].data.i;
+ BREAK;
+ CASE (CEE_STIND_I4)
+ ++ip;
+ sp -= 2;
+ *(gint32*)sp->data.p = sp[1].data.i;
+ BREAK;
+ CASE (CEE_STIND_I)
+ ++ip;
+ sp -= 2;
+ *(gint64*)sp->data.p = sp[1].data.l;
+ BREAK;
+ CASE (CEE_STIND_I8)
+ ++ip;
+ sp -= 2;
+ *(gint64*)sp->data.p = sp[1].data.l;
+ BREAK;
+ CASE (CEE_STIND_R4)
+ ++ip;
+ sp -= 2;
+ *(gfloat*)sp->data.p = (gfloat)sp[1].data.f;
+ BREAK;
+ CASE (CEE_STIND_R8)
+ ++ip;
+ sp -= 2;
+ *(gdouble*)sp->data.p = sp[1].data.f;
+ BREAK;
+ CASE (CEE_ADD)
+ ++ip;
+ --sp;
+ /* should probably consider the pointers as unsigned */
+ if (sp->type == VAL_I32)
+ sp [-1].data.i += GET_NATI (sp [0]);
+ else if (sp->type == VAL_I64)
+ sp [-1].data.l += sp [0].data.l;
+ else if (sp->type == VAL_DOUBLE)
+ sp [-1].data.f += sp [0].data.f;
+ else
+ (char*)sp [-1].data.p += GET_NATI (sp [0]);
+ BREAK;
+ CASE (CEE_SUB)
+ ++ip;
+ --sp;
+ /* should probably consider the pointers as unsigned */
+ if (sp->type == VAL_I32)
+ sp [-1].data.i -= GET_NATI (sp [0]);
+ else if (sp->type == VAL_I64)
+ sp [-1].data.l -= sp [0].data.l;
+ else if (sp->type == VAL_DOUBLE)
+ sp [-1].data.f -= sp [0].data.f;
+ else
+ (char*)sp [-1].data.p -= GET_NATI (sp [0]);
+ BREAK;
+ CASE (CEE_MUL)
+ ++ip;
+ --sp;
+ if (sp->type == VAL_I32)
+ sp [-1].data.i *= GET_NATI (sp [0]);
+ else if (sp->type == VAL_I64)
+ sp [-1].data.l *= sp [0].data.l;
+ else if (sp->type == VAL_DOUBLE)
+ sp [-1].data.f *= sp [0].data.f;
+ BREAK;
+ CASE (CEE_DIV)
+ ++ip;
+ --sp;
+ if (sp->type == VAL_I32) {
+ if (GET_NATI (sp [0]) == 0)
+ THROW_EX (get_exception_divide_by_zero (), ip - 1);
+ sp [-1].data.i /= GET_NATI (sp [0]);
+ } else if (sp->type == VAL_I64) {
+ if (sp [0].data.l == 0)
+ THROW_EX (get_exception_divide_by_zero (), ip - 1);
+ sp [-1].data.l /= sp [0].data.l;
+ } else if (sp->type == VAL_DOUBLE) {
+ /* set NaN is divisor is 0.0 */
+ sp [-1].data.f /= sp [0].data.f;
+ }
+ BREAK;
+ CASE (CEE_DIV_UN)
+ ++ip;
+ --sp;
+ if (sp->type == VAL_I32) {
+ if (GET_NATI (sp [0]) == 0)
+ THROW_EX (get_exception_divide_by_zero (), ip - 1);
+ (guint32)sp [-1].data.i /= (guint32)GET_NATI (sp [0]);
+ } else if (sp->type == VAL_I64) {
+ if (sp [0].data.l == 0)
+ THROW_EX (get_exception_divide_by_zero (), ip - 1);
+ (guint64)sp [-1].data.l /= (guint64)sp [0].data.l;
+ } else if (sp->type == VAL_NATI) {
+ if (GET_NATI (sp [0]) == 0)
+ THROW_EX (get_exception_divide_by_zero (), ip - 1);
+ (gulong)sp [-1].data.p /= (gulong)sp [0].data.p;
+ }
+ BREAK;
+ CASE (CEE_REM)
+ ++ip;
+ --sp;
+ if (sp->type == VAL_I32) {
+ if (GET_NATI (sp [0]) == 0)
+ THROW_EX (get_exception_divide_by_zero (), ip - 1);
+ sp [-1].data.i %= GET_NATI (sp [0]);
+ } else if (sp->type == VAL_I64) {
+ if (sp [0].data.l == 0)
+ THROW_EX (get_exception_divide_by_zero (), ip - 1);
+ sp [-1].data.l %= sp [0].data.l;
+ } else if (sp->type == VAL_DOUBLE) {
+ /* FIXME: what do we actually do here? */
+ sp [-1].data.f = 0;
+ } else {
+ if (GET_NATI (sp [0]) == 0)
+ THROW_EX (get_exception_divide_by_zero (), ip - 1);
+ GET_NATI (sp [-1]) %= GET_NATI (sp [0]);
+ }
+ BREAK;
+ CASE (CEE_REM_UN) ves_abort(); BREAK;
+ CASE (CEE_AND)
+ ++ip;
+ --sp;
+ if (sp->type == VAL_I32)
+ sp [-1].data.i &= GET_NATI (sp [0]);
+ else if (sp->type == VAL_I64)
+ sp [-1].data.l &= sp [0].data.l;
+ else
+ GET_NATI (sp [-1]) &= GET_NATI (sp [0]);
+ BREAK;
+ CASE (CEE_OR)
+ ++ip;
+ --sp;
+ if (sp->type == VAL_I32)
+ sp [-1].data.i |= GET_NATI (sp [0]);
+ else if (sp->type == VAL_I64)
+ sp [-1].data.l |= sp [0].data.l;
+ else
+ GET_NATI (sp [-1]) |= GET_NATI (sp [0]);
+ BREAK;
+ CASE (CEE_XOR)
+ ++ip;
+ --sp;
+ if (sp->type == VAL_I32)
+ sp [-1].data.i ^= GET_NATI (sp [0]);
+ else if (sp->type == VAL_I64)
+ sp [-1].data.l ^= sp [0].data.l;
+ else
+ GET_NATI (sp [-1]) ^= GET_NATI (sp [0]);
+ BREAK;
+ CASE (CEE_SHL)
+ ++ip;
+ --sp;
+ if (sp->type == VAL_I32)
+ sp [-1].data.i <<= GET_NATI (sp [0]);
+ else if (sp->type == VAL_I64)
+ sp [-1].data.l <<= GET_NATI (sp [0]);
+ else
+ GET_NATI (sp [-1]) <<= GET_NATI (sp [0]);
+ BREAK;
+ CASE (CEE_SHR)
+ ++ip;
+ --sp;
+ if (sp->type == VAL_I32)
+ sp [-1].data.i >>= GET_NATI (sp [0]);
+ else if (sp->type == VAL_I64)
+ sp [-1].data.l >>= GET_NATI (sp [0]);
+ else
+ GET_NATI (sp [-1]) >>= GET_NATI (sp [0]);
+ BREAK;
+ CASE (CEE_SHR_UN) ves_abort(); BREAK;
+ CASE (CEE_NEG)
+ ++ip;
+ if (sp->type == VAL_I32)
+ sp->data.i = - sp->data.i;
+ else if (sp->type == VAL_I64)
+ sp->data.l = - sp->data.l;
+ else if (sp->type == VAL_DOUBLE)
+ sp->data.f = - sp->data.f;
+ else if (sp->type == VAL_NATI)
+ sp->data.p = (gpointer)(- (int)sp->data.p);
+ BREAK;
+ CASE (CEE_NOT)
+ ++ip;
+ if (sp->type == VAL_I32)
+ sp->data.i = ~ sp->data.i;
+ else if (sp->type == VAL_I64)
+ sp->data.l = ~ sp->data.l;
+ else if (sp->type == VAL_NATI)
+ sp->data.p = (gpointer)(~ (int)sp->data.p);
+ BREAK;
+ CASE (CEE_CONV_I1) ves_abort(); BREAK;
+ CASE (CEE_CONV_I2) ves_abort(); BREAK;
+ CASE (CEE_CONV_I4) {
+ ++ip;
+ /* FIXME: handle other cases. what about sign? */
+
+ switch (sp [-1].type) {
+ case VAL_DOUBLE:
+ sp [-1].data.i = (gint32)sp [-1].data.f;
+ sp [-1].type = VAL_I32;
+ break;
+ case VAL_I32:
+ break;
+ default:
+ ves_abort();
+ }
+ BREAK;
+ }
+ CASE (CEE_CONV_I8) ves_abort(); BREAK;
+ CASE (CEE_CONV_R4) ves_abort(); BREAK;
+ CASE (CEE_CONV_R8)
+ ++ip;
+ /* FIXME: handle other cases. what about sign? */
+ if (sp [-1].type == VAL_I32) {
+ sp [-1].data.f = (double)sp [-1].data.i;
+ sp [-1].type = VAL_DOUBLE;
+ } else {
+ ves_abort();
+ }
+ BREAK;
+ CASE (CEE_CONV_U4)
+ ++ip;
+ /* FIXME: handle other cases. what about sign? */
+ if (sp [-1].type == VAL_DOUBLE) {
+ sp [-1].data.i = (guint32)sp [-1].data.f;
+ sp [-1].type = VAL_I32;
+ } else {
+ ves_abort();
+ }
+ BREAK;
+ CASE (CEE_CONV_U)
+ ++ip;
+ /* FIXME: handle other cases */
+ if (sp [-1].type == VAL_I32) {
+ /* defined as NOP */
+ } else {
+ ves_abort();
+ }
+ BREAK;
+ CASE (CEE_CONV_U8) ves_abort(); BREAK;
+ CASE (CEE_CPOBJ) ves_abort(); BREAK;
+ CASE (CEE_LDOBJ) ves_abort(); BREAK;
+ CASE (CEE_LDSTR) {
+ MonoObject *o;
+ const char *name;
+ int len;
+ guint32 index;
+
+ ip++;
+ index = mono_metadata_token_index (read32 (ip));
+ ip += 4;
+
+ name = mono_metadata_user_string (image, index);
+ len = mono_metadata_decode_blob_size (name, &name);
+
+ o = mono_new_utf16_string (name, len);
+
+ sp->type = VAL_OBJ;
+ sp->data.p = o;
+
+ ++sp;
+ BREAK;
+ }
+ CASE (CEE_NEWOBJ) {
+ MonoObject *o;
+ MonoMethodSignature *csig;
+ guint32 token;
+
+ frame->ip = ip;
+
+ ip++;
+ token = read32 (ip);
+ o = newobj (image, token);
+ ip += 4;
+
+ /* call the contructor */
+ child_frame.method = mono_get_method (image, token, o->klass);
+ csig = child_frame.method->signature;
+
+ /*
+ * First arg is the object.
+ */
+ child_frame.obj = o;
+
+ if (csig->param_count) {
+ sp -= csig->param_count;
+ child_frame.stack_args = sp;
+ } else {
+ child_frame.stack_args = NULL;
+ }
+
+ g_assert (csig->call_convention == MONO_CALL_DEFAULT);
+
+ child_frame.ex = NULL;
+ child_frame.ex_handler = NULL;
+
+ ves_exec_method (&child_frame);
+
+ if (child_frame.ex) {
+ /*
+ * An exception occurred, need to run finally, fault and catch handlers..
+ */
+ frame->ex = child_frame.ex;
+ goto handle_finally;
+ }
+ /*
+ * a constructor returns void, but we need to return the object we created
+ */
+ sp->type = VAL_OBJ;
+ sp->data.p = o;
+ ++sp;
+ BREAK;
+ }
+ CASE (CEE_CASTCLASS) {
+ MonoObject *o;
+ MonoClass *c;
+ guint32 token;
+ gboolean found = FALSE;
+
+ ++ip;
+ token = read32 (ip);
+
+ g_assert (sp [-1].type == VAL_OBJ);
+
+ if ((o = sp [-1].data.p)) {
+ c = o->klass;
+
+ /*
+ * fixme: this only works for class casts, but not for
+ * interface casts.
+ */
+ while (c) {
+ if (c->type_token == token) {
+ found = TRUE;
+ break;
+ }
+ c = c->parent;
+ }
+
+ g_assert (found);
+
+ }
+
+ ip += 4;
+ BREAK;
+ }
+ CASE (CEE_ISINST) ves_abort(); BREAK;
+ CASE (CEE_CONV_R_UN) ves_abort(); BREAK;
+ CASE (CEE_UNUSED58) ves_abort(); BREAK;
+ CASE (CEE_UNUSED1) ves_abort(); BREAK;
+ CASE (CEE_UNBOX) {
+ MonoObject *o;
+ MonoClass *c;
+ guint32 token;
+
+ ++ip;
+ token = read32 (ip);
+
+ c = mono_class_get (image, token);
+
+ o = sp [-1].data.p;
+
+ g_assert (o->klass->type_token == c->type_token);
+
+ sp [-1].type = VAL_MP;
+ sp [-1].data.p = (char *)o + sizeof (MonoObject);
+
+ ip += 4;
+ BREAK;
+ }
+ CASE (CEE_THROW)
+ --sp;
+ THROW_EX (sp->data.p, ip);
+ BREAK;
+ CASE (CEE_LDFLDA) /* Fall through */
+ CASE (CEE_LDFLD) {
+ MonoObject *obj;
+ MonoClassField *field;
+ guint32 token;
+ int load_addr = *ip == CEE_LDFLDA;
+
+ ++ip;
+ token = read32 (ip);
+ ip += 4;
+
+ g_assert (sp [-1].type == VAL_OBJ);
+ obj = sp [-1].data.p;
+ field = mono_class_get_field (obj->klass, token);
+ g_assert (field);
+ if (load_addr) {
+ sp->type = VAL_TP;
+ sp->data.p = (char*)obj + field->offset;
+ } else {
+ stackval_from_data (field->type->type, &sp [-1], (char*)obj + field->offset);
+ }
+ BREAK;
+ }
+ CASE (CEE_STFLD) {
+ MonoObject *obj;
+ MonoClassField *field;
+ guint32 token;
+
+ ++ip;
+ token = read32 (ip);
+ ip += 4;
+
+ sp -= 2;
+
+ g_assert (sp [0].type == VAL_OBJ);
+ obj = sp [0].data.p;
+ field = mono_class_get_field (obj->klass, token);
+ g_assert (field);
+ stackval_to_data (field->type->type, &sp [1], (char*)obj + field->offset);
+ BREAK;
+ }
+ CASE (CEE_LDSFLD) /* Fall through */
+ CASE (CEE_LDSFLDA) {
+ MonoClass *klass;
+ MonoClassField *field;
+ guint32 token;
+ int load_addr = *ip == CEE_LDSFLDA;
+
+ ++ip;
+ token = read32 (ip);
+ ip += 4;
+
+ /* need to handle fieldrefs */
+ klass = mono_class_get (image,
+ MONO_TOKEN_TYPE_DEF | mono_metadata_typedef_from_field (image, token & 0xffffff));
+ if (!klass->inited)
+ init_class (klass);
+ field = mono_class_get_field (klass, token);
+ g_assert (field);
+ if (load_addr) {
+ sp->type = VAL_TP;
+ sp->data.p = (char*)klass + field->offset;
+ } else {
+ stackval_from_data (field->type->type, sp, (char*)klass + field->offset);
+ }
+ ++sp;
+ BREAK;
+ }
+ CASE (CEE_STSFLD) {
+ MonoClass *klass;
+ MonoClassField *field;
+ guint32 token;
+
+ ++ip;
+ token = read32 (ip);
+ ip += 4;
+ --sp;
+
+ /* need to handle fieldrefs */
+ klass = mono_class_get (image,
+ MONO_TOKEN_TYPE_DEF | mono_metadata_typedef_from_field (image, token & 0xffffff));
+ if (!klass->inited)
+ init_class (klass);
+ field = mono_class_get_field (klass, token);
+ g_assert (field);
+ stackval_to_data (field->type->type, sp, (char*)klass + field->offset);
+ BREAK;
+ }
+ CASE (CEE_STOBJ) ves_abort(); BREAK;
+ CASE (CEE_CONV_OVF_I1_UN) ves_abort(); BREAK;
+ CASE (CEE_CONV_OVF_I2_UN) ves_abort(); BREAK;
+ CASE (CEE_CONV_OVF_I4_UN) ves_abort(); BREAK;
+ CASE (CEE_CONV_OVF_I8_UN) ves_abort(); BREAK;
+ CASE (CEE_CONV_OVF_U1_UN) ves_abort(); BREAK;
+ CASE (CEE_CONV_OVF_U2_UN) ves_abort(); BREAK;
+ CASE (CEE_CONV_OVF_U4_UN) ves_abort(); BREAK;
+ CASE (CEE_CONV_OVF_U8_UN) ves_abort(); BREAK;
+ CASE (CEE_CONV_OVF_I_UN) ves_abort(); BREAK;
+ CASE (CEE_CONV_OVF_U_UN) ves_abort(); BREAK;
+ CASE (CEE_BOX) {
+ guint32 token;
+ MonoClass *class;
+
+ ip++;
+ token = read32 (ip);
+
+ class = mono_class_get (image, token);
+ g_assert (class != NULL);
+
+ sp [-1].type = VAL_OBJ;
+ sp [-1].data.p = mono_value_box (class, &sp [-1]);
+
+ ip += 4;
+
+ BREAK;
+ }
+ CASE (CEE_NEWARR) {
+ MonoObject *o;
+ guint32 token;
+
+ ip++;
+ token = read32 (ip);
+ o = mono_new_szarray (image, token, sp [-1].data.i);
+ ip += 4;
+
+ sp [-1].type = VAL_OBJ;
+ sp [-1].data.p = o;
+
+ BREAK;
+ }
+ CASE (CEE_LDLEN) {
+ MonoArrayObject *o;
+
+ ip++;
+
+ g_assert (sp [-1].type == VAL_OBJ);
+
+ o = sp [-1].data.p;
+ g_assert (o != NULL);
+
+ g_assert (MONO_CLASS_IS_ARRAY (o->obj.klass));
+
+ sp [-1].type = VAL_I32;
+ sp [-1].data.i = o->bounds [0].length;
+
+ BREAK;
+ }
+ CASE (CEE_LDELEMA) ves_abort(); BREAK;
+ CASE (CEE_LDELEM_I1) /* fall through */
+ CASE (CEE_LDELEM_U1) /* fall through */
+ CASE (CEE_LDELEM_I2) /* fall through */
+ CASE (CEE_LDELEM_U2) /* fall through */
+ CASE (CEE_LDELEM_I4) /* fall through */
+ CASE (CEE_LDELEM_U4) /* fall through */
+ CASE (CEE_LDELEM_I8) /* fall through */
+ CASE (CEE_LDELEM_I) /* fall through */
+ CASE (CEE_LDELEM_R4) /* fall through */
+ CASE (CEE_LDELEM_R8) /* fall through */
+ CASE (CEE_LDELEM_REF) {
+ MonoArrayObject *o;
+
+ sp -= 2;
+
+ g_assert (sp [0].type == VAL_OBJ);
+ o = sp [0].data.p;
+
+ g_assert (MONO_CLASS_IS_ARRAY (o->obj.klass));
+
+ g_assert (sp [1].data.i >= 0);
+ g_assert (sp [1].data.i < o->bounds [0].length);
+
+ switch (*ip) {
+ case CEE_LDELEM_I1:
+ sp [0].data.i = ((gint8 *)o->vector)[sp [1].data.i];
+ sp [0].type = VAL_I32;
+ break;
+ case CEE_LDELEM_U1:
+ sp [0].data.i = ((guint8 *)o->vector)[sp [1].data.i];
+ sp [0].type = VAL_I32;
+ break;
+ case CEE_LDELEM_I2:
+ sp [0].data.i = ((gint16 *)o->vector)[sp [1].data.i];
+ sp [0].type = VAL_I32;
+ break;
+ case CEE_LDELEM_U2:
+ sp [0].data.i = ((guint16 *)o->vector)[sp [1].data.i];
+ sp [0].type = VAL_I32;
+ break;
+ case CEE_LDELEM_I:
+ sp [0].data.i = ((gint32 *)o->vector)[sp [1].data.i];
+ sp [0].type = VAL_NATI;
+ break;
+ case CEE_LDELEM_I4:
+ sp [0].data.i = ((gint32 *)o->vector)[sp [1].data.i];
+ sp [0].type = VAL_I32;
+ break;
+ case CEE_LDELEM_U4:
+ sp [0].data.i = ((guint32 *)o->vector)[sp [1].data.i];
+ sp [0].type = VAL_I32;
+ break;
+ case CEE_LDELEM_I8:
+ sp [0].data.l = ((gint64 *)o->vector)[sp [1].data.i];
+ sp [0].type = VAL_I64;
+ break;
+ case CEE_LDELEM_R4:
+ sp [0].data.f = ((float *)o->vector)[sp [1].data.i];
+ sp [0].type = VAL_DOUBLE;
+ break;
+ case CEE_LDELEM_R8:
+ sp [0].data.i = ((double *)o->vector)[sp [1].data.i];
+ sp [0].type = VAL_DOUBLE;
+ break;
+ case CEE_LDELEM_REF:
+ sp [0].data.p = ((gpointer *)o->vector)[sp [1].data.i];
+ sp [0].type = VAL_OBJ;
+ break;
+ default:
+ ves_abort();
+ }
+
+ ++ip;
+ ++sp;
+
+ BREAK;
+ }
+ CASE (CEE_STELEM_I) /* fall through */
+ CASE (CEE_STELEM_I1) /* fall through */
+ CASE (CEE_STELEM_I2) /* fall through */
+ CASE (CEE_STELEM_I4) /* fall through */
+ CASE (CEE_STELEM_I8) /* fall through */
+ CASE (CEE_STELEM_R4) /* fall through */
+ CASE (CEE_STELEM_R8) /* fall through */
+ CASE (CEE_STELEM_REF) {
+ MonoArrayObject *o;
+ MonoArrayClass *ac;
+ MonoObject *v;
+
+ sp -= 3;
+
+ g_assert (sp [0].type == VAL_OBJ);
+ o = sp [0].data.p;
+
+ g_assert (MONO_CLASS_IS_ARRAY (o->obj.klass));
+ ac = (MonoArrayClass *)o->obj.klass;
+
+ g_assert (sp [1].data.i >= 0);
+ g_assert (sp [1].data.i < o->bounds [0].length);
+
+ switch (*ip) {
+ case CEE_STELEM_I:
+ ((gint32 *)o->vector)[sp [1].data.i] =
+ sp [2].data.i;
+ break;
+ case CEE_STELEM_I1:
+ ((gint8 *)o->vector)[sp [1].data.i] =
+ sp [2].data.i;
+ break;
+ case CEE_STELEM_I2:
+ ((gint16 *)o->vector)[sp [1].data.i] =
+ sp [2].data.i;
+ break;
+ case CEE_STELEM_I4:
+ ((gint32 *)o->vector)[sp [1].data.i] =
+ sp [2].data.i;
+ break;
+ case CEE_STELEM_I8:
+ ((gint64 *)o->vector)[sp [1].data.i] =
+ sp [2].data.l;
+ break;
+ case CEE_STELEM_R4:
+ ((float *)o->vector)[sp [1].data.i] =
+ sp [2].data.f;
+ break;
+ case CEE_STELEM_R8:
+ ((double *)o->vector)[sp [1].data.i] =
+ sp [2].data.f;
+ break;
+ case CEE_STELEM_REF:
+ g_assert (sp [2].type == VAL_OBJ);
+
+ v = sp [2].data.p;
+
+ //fixme: what about type conversions ?
+ g_assert (v->klass == ac->element_class);
+
+ ((gpointer *)o->vector)[sp [1].data.i] =
+ sp [2].data.p;
+ break;
+ default:
+ ves_abort();
+ }
+
+ ++ip;
+
+ BREAK;
+ }
+ CASE (CEE_UNUSED2)
+ CASE (CEE_UNUSED3)
+ CASE (CEE_UNUSED4)
+ CASE (CEE_UNUSED5)
+ CASE (CEE_UNUSED6)
+ CASE (CEE_UNUSED7)
+ CASE (CEE_UNUSED8)
+ CASE (CEE_UNUSED9)
+ CASE (CEE_UNUSED10)
+ CASE (CEE_UNUSED11)
+ CASE (CEE_UNUSED12)
+ CASE (CEE_UNUSED13)
+ CASE (CEE_UNUSED14)
+ CASE (CEE_UNUSED15)
+ CASE (CEE_UNUSED16)
+ CASE (CEE_UNUSED17) ves_abort(); BREAK;
+ CASE (CEE_CONV_OVF_I1) ves_abort(); BREAK;
+ CASE (CEE_CONV_OVF_U1) ves_abort(); BREAK;
+ CASE (CEE_CONV_OVF_I2) ves_abort(); BREAK;
+ CASE (CEE_CONV_OVF_U2) ves_abort(); BREAK;
+ CASE (CEE_CONV_OVF_I4) ves_abort(); BREAK;
+ CASE (CEE_CONV_OVF_U4)
+ ++ip;
+ /* FIXME: handle other cases */
+ if (sp [-1].type == VAL_I32) {
+ /* defined as NOP */
+ } else {
+ ves_abort();
+ }
+ BREAK;
+ CASE (CEE_CONV_OVF_I8) ves_abort(); BREAK;
+ CASE (CEE_CONV_OVF_U8) ves_abort(); BREAK;
+ CASE (CEE_UNUSED50)
+ CASE (CEE_UNUSED18)
+ CASE (CEE_UNUSED19)
+ CASE (CEE_UNUSED20)
+ CASE (CEE_UNUSED21)
+ CASE (CEE_UNUSED22)
+ CASE (CEE_UNUSED23) ves_abort(); BREAK;
+ CASE (CEE_REFANYVAL) ves_abort(); BREAK;
+ CASE (CEE_CKFINITE) ves_abort(); BREAK;
+ CASE (CEE_UNUSED24) ves_abort(); BREAK;
+ CASE (CEE_UNUSED25) ves_abort(); BREAK;
+ CASE (CEE_MKREFANY) ves_abort(); BREAK;
+ CASE (CEE_UNUSED59)
+ CASE (CEE_UNUSED60)
+ CASE (CEE_UNUSED61)
+ CASE (CEE_UNUSED62)
+ CASE (CEE_UNUSED63)
+ CASE (CEE_UNUSED64)
+ CASE (CEE_UNUSED65)
+ CASE (CEE_UNUSED66)
+ CASE (CEE_UNUSED67) ves_abort(); BREAK;
+ CASE (CEE_LDTOKEN)
+ CASE (CEE_CONV_U2) ves_abort(); BREAK;
+ CASE (CEE_CONV_U1) ves_abort(); BREAK;
+ CASE (CEE_CONV_I) ves_abort(); BREAK;
+ CASE (CEE_CONV_OVF_I) ves_abort(); BREAK;
+ CASE (CEE_CONV_OVF_U) ves_abort(); BREAK;
+ CASE (CEE_ADD_OVF) ves_abort(); BREAK;
+ CASE (CEE_ADD_OVF_UN) ves_abort(); BREAK;
+ CASE (CEE_MUL_OVF) ves_abort(); BREAK;
+ CASE (CEE_MUL_OVF_UN) ves_abort(); BREAK;
+ CASE (CEE_SUB_OVF) ves_abort(); BREAK;
+ CASE (CEE_SUB_OVF_UN) ves_abort(); BREAK;
+ CASE (CEE_ENDFINALLY)
+ if (frame->ex)
+ goto handle_fault;
+ /*
+ * There was no exception, we continue normally at the target address.
+ */
+ ip = endfinally_ip;
+ BREAK;
+ CASE (CEE_LEAVE) /* Fall through */
+ CASE (CEE_LEAVE_S)
+ if (*ip == CEE_LEAVE_S) {
+ ++ip;
+ ip += (signed char) *ip;
+ ++ip;
+ } else {
+ ++ip;
+ ip += (gint32) read32 (ip);
+ ip += 4;
+ }
+ /*
+ * We may be either inside a try block or inside an handler.
+ * In the first case there was no exception and we go on
+ * executing the finally handlers and after that resume control
+ * at endfinally_ip.
+ * In the second case we need to clear the exception and
+ * continue directly at the target ip.
+ */
+ if (frame->ex) {
+ frame->ex = NULL;
+ frame->ex_handler = NULL;
+ } else {
+ endfinally_ip = ip;
+ goto handle_finally;
+ }
+ BREAK;
+ CASE (CEE_UNUSED26)
+ CASE (CEE_UNUSED27)
+ CASE (CEE_UNUSED28)
+ CASE (CEE_UNUSED29)
+ CASE (CEE_UNUSED30)
+ CASE (CEE_UNUSED31)
+ CASE (CEE_UNUSED32)
+ CASE (CEE_UNUSED33)
+ CASE (CEE_UNUSED34)
+ CASE (CEE_UNUSED35)
+ CASE (CEE_UNUSED36)
+ CASE (CEE_UNUSED37)
+ CASE (CEE_UNUSED38)
+ CASE (CEE_UNUSED39)
+ CASE (CEE_UNUSED40)
+ CASE (CEE_UNUSED41)
+ CASE (CEE_UNUSED42)
+ CASE (CEE_UNUSED43)
+ CASE (CEE_UNUSED44)
+ CASE (CEE_UNUSED45)
+ CASE (CEE_UNUSED46)
+ CASE (CEE_UNUSED47)
+ CASE (CEE_UNUSED48) ves_abort(); BREAK;
+ CASE (CEE_PREFIX7) ves_abort(); BREAK;
+ CASE (CEE_PREFIX6) ves_abort(); BREAK;
+ CASE (CEE_PREFIX5) ves_abort(); BREAK;
+ CASE (CEE_PREFIX4) ves_abort(); BREAK;
+ CASE (CEE_PREFIX3) ves_abort(); BREAK;
+ CASE (CEE_PREFIX2) ves_abort(); BREAK;
+ CASE (CEE_PREFIXREF) ves_abort(); BREAK;
+ SUB_SWITCH
+ ++ip;
+ switch (*ip) {
+ case CEE_ARGLIST: ves_abort(); break;
+ case CEE_CEQ: ves_abort(); break;
+ case CEE_CGT: ves_abort(); break;
+ case CEE_CGT_UN: ves_abort(); break;
+ case CEE_CLT: ves_abort(); break;
+ case CEE_CLT_UN: ves_abort(); break;
+ case CEE_LDFTN: ves_abort(); break;
+ case CEE_LDVIRTFTN: ves_abort(); break;
+ case CEE_UNUSED56: ves_abort(); break;
+ case CEE_LDARG: ves_abort(); break;
+ case CEE_LDARGA: ves_abort(); break;
+ case CEE_STARG: ves_abort(); break;
+ case CEE_LDLOC: ves_abort(); break;
+ case CEE_LDLOCA: ves_abort(); break;
+ case CEE_STLOC: ves_abort(); break;
+ case CEE_LOCALLOC:
+ if (sp != frame->stack)
+ THROW_EX (get_exception_execution_engine (), ip - 1);
+ ++ip;
+ sp->data.p = alloca (sp->data.i);
+ sp->type = VAL_TP;
+ break;
+ case CEE_UNUSED57: ves_abort(); break;
+ case CEE_ENDFILTER: ves_abort(); break;
+ case CEE_UNALIGNED_:
+ ++ip;
+ unaligned_address = 1;
+ break;
+ case CEE_VOLATILE_:
+ ++ip;
+ volatile_address = 1;
+ break;
+ case CEE_TAIL_:
+ ++ip;
+ tail_recursion = 1;
+ break;
+ case CEE_INITOBJ: ves_abort(); break;
+ case CEE_UNUSED68: ves_abort(); break;
+ case CEE_CPBLK: ves_abort(); break;
+ case CEE_INITBLK:
+ sp -= 3;
+ if (!sp [0].data.p)
+ THROW_EX (get_exception_null_reference(), ip);
+ ++ip;
+ /* FIXME: value and size may be int64... */
+ memset (sp [0].data.p, sp [1].data.i, sp [2].data.i);
+ break;
+ case CEE_UNUSED69: ves_abort(); break;
+ case CEE_RETHROW:
+ /*
+ * need to clarify what this should actually do:
+ * start the search from the last found handler in
+ * this method or continue in the caller or what.
+ * Also, do we need to run finally/fault handlers after a retrow?
+ * Well, this implementation will follow the usual search
+ * for an handler, considering the current ip as throw spot.
+ * We need to NULL frame->ex_handler for the later code to
+ * actually run the new found handler.
+ */
+ frame->ex_handler = NULL;
+ THROW_EX (frame->ex, ip - 1);
+ break;
+ case CEE_UNUSED: ves_abort(); break;
+ case CEE_SIZEOF: ves_abort(); break;
+ case CEE_REFANYTYPE: ves_abort(); break;
+ case CEE_UNUSED52:
+ case CEE_UNUSED53:
+ case CEE_UNUSED54:
+ case CEE_UNUSED55:
+ case CEE_UNUSED70:
+ default:
+ g_error ("Unimplemented opcode: 0xFE %02x at 0x%x\n", *ip, ip-header->code);
+ }
+ continue;
+ DEFAULT;
+ }
+ }
+
+ g_assert_not_reached ();
+ /*
+ * Exception handling code.
+ * The exception object is stored in frame->ex.
+ */
+#define OFFSET_IN_CLAUSE(clause,offset) \
+ ((clause)->try_offset <= (offset) && (offset) < ((clause)->try_offset + (clause)->try_len))
+
+ handle_exception:
+ {
+ int i;
+ guint32 ip_offset;
+ MonoInvocation *inv;
+ MonoMethodHeader *hd;
+ MonoExceptionClause *clause;
+
+ for (inv = frame; inv; inv = inv->parent) {
+ hd = ((MonoMethodNormal*)inv->method)->header;
+ ip_offset = inv->ip - hd->code;
+ for (i = 0; i < hd->num_clauses; ++i) {
+ clause = &hd->clauses [i];
+ if (clause->flags <= 1 && OFFSET_IN_CLAUSE (clause, ip_offset)) {
+ if (!clause->flags) {
+ if (mono_object_isinst (frame->ex, mono_class_get (inv->method->klass->image, clause->token_or_filter))) {
+ /*
+ * OK, we found an handler, now we need to execute the finally
+ * and fault blocks before branching to the handler code.
+ */
+ inv->ex_handler = clause;
+ goto handle_finally;
+ }
+ } else {
+ /* FIXME: handle filter clauses */
+ g_assert (0);
+ }
+ }
+ }
+ }
+ /*
+ * If we get here, no handler was found: print a stack trace.
+ */
+ g_print ("Unhandled exception.\n");
+ for (inv = frame, i = 0; inv; inv = inv->parent, ++i) {
+ MonoClass *k = inv->method->klass;
+ MonoMethodHeader *hd = ((MonoMethodNormal *)inv->method)->header;
+ /*
+ * FIXME: print out also the arguments passed to the func.
+ */
+ g_print ("#%d: 0x%05x in %s.%s::%s ()\n", i, inv->ip - hd->code,
+ k->name_space, k->name, inv->method->name);
+ }
+ exit (1);
+ }
+ handle_finally:
+ {
+ int i;
+ guint32 ip_offset;
+ MonoExceptionClause *clause;
+
+ ip_offset = frame->ip - header->code;
+ for (i = 0; i < header->num_clauses; ++i) {
+ clause = &header->clauses [i];
+ if (clause->flags == 2 && OFFSET_IN_CLAUSE (clause, ip_offset)) {
+ ip = header->code + clause->handler_offset;
+ goto main_loop;
+ }
+ }
+ /*
+ * If an exception is set, we need to execute the fault handler, too,
+ * otherwise, we continue normally.
+ */
+ if (frame->ex)
+ goto handle_fault;
+ ip = endfinally_ip;
+ goto main_loop;
+ }
+ handle_fault:
+ {
+ int i;
+ guint32 ip_offset;
+ MonoExceptionClause *clause;
+
+ ip_offset = frame->ip - header->code;
+ for (i = 0; i < header->num_clauses; ++i) {
+ clause = &header->clauses [i];
+ if (clause->flags == 3 && OFFSET_IN_CLAUSE (clause, ip_offset)) {
+ ip = header->code + clause->handler_offset;
+ goto main_loop;
+ }
+ }
+ /*
+ * If the handler for the exception was found in this method, we jump
+ * to it right away, otherwise we return and let the caller run
+ * the finally, fault and catch blocks.
+ * This same code should be present in the endfault opcode, but it
+ * is corrently not assigned in the ECMA specs: LAMESPEC.
+ */
+ if (frame->ex_handler) {
+ ip = header->code + frame->ex_handler->handler_offset;
+ sp = frame->stack;
+ sp->type = VAL_OBJ;
+ sp->data.p = frame->ex;
+ ++sp;
+ goto main_loop;
+ }
+ DEBUG_LEAVE ();
+ return;
+ }
+
+}
+
+static int
+ves_exec (MonoAssembly *assembly)
+{
+ MonoImage *image = assembly->image;
+ MonoCLIImageInfo *iinfo;
+ stackval result;
+ MonoInvocation call;
+ MonoMethod *method;
+
+ iinfo = image->image_info;
+ method = mono_get_method (image, iinfo->cli_cli_header.ch_entry_point, NULL);
+
+ INIT_FRAME (&call, NULL, NULL, NULL, &result, method);
+
+ ves_exec_method (&call);
+ mono_free_method (call.method);
+
+ return result.data.i;
+}
+
+static void
+usage (void)
+{
+ fprintf (stderr,
+ "mint %s, the Mono ECMA CLI interpreter, (C) 2001 Ximian, Inc.\n\n"
+ "Usage is: mint executable args...\n", VERSION);
+ exit (1);
+}
+
+int
+main (int argc, char *argv [])
+{
+ MonoAssembly *assembly;
+ int retval = 0;
+ char *file;
+
+ if (argc < 2)
+ usage ();
+
+ file = argv [1];
+
+ mono_init ();
+ mono_init_icall ();
+
+ assembly = mono_assembly_open (file, NULL, NULL);
+ if (!assembly){
+ fprintf (stderr, "Can not open image %s\n", file);
+ exit (1);
+ }
+ retval = ves_exec (assembly);
+ mono_assembly_close (assembly);
+
+ return retval;
+}
+
+
+
diff --git a/mono/interpreter/interp.h b/mono/interpreter/interp.h
new file mode 100644
index 00000000000..1d85d6eaf80
--- /dev/null
+++ b/mono/interpreter/interp.h
@@ -0,0 +1,57 @@
+
+#include <glib.h>
+#include <mono/metadata/loader.h>
+#include <mono/metadata/object.h>
+
+enum {
+ VAL_I32 = 0,
+ VAL_DOUBLE = 1,
+ VAL_I64 = 2,
+ VAL_VALUET = 3,
+ VAL_POINTER = 4,
+ VAL_NATI = 0 + VAL_POINTER,
+ VAL_MP = 1 + VAL_POINTER,
+ VAL_TP = 2 + VAL_POINTER,
+ VAL_OBJ = 3 + VAL_POINTER
+};
+
+/*
+ * Value types are represented on the eval stack as pointers to the
+ * actual storage. The size field tells how much storage is allocated.
+ * A value type can't be larger than 16 MB.
+ */
+typedef struct {
+ union {
+ gint32 i;
+ gint64 l;
+ double f;
+ /* native size integer and pointer types */
+ gpointer p;
+ struct {
+ gpointer vt;
+ MonoClass *klass;
+ } vt;
+ } data;
+ unsigned int type;
+} stackval;
+
+typedef struct _MonoInvocation MonoInvocation;
+
+struct _MonoInvocation {
+ MonoInvocation *parent; /* parent */
+ MonoInvocation *child;
+ MonoMethod *method; /* parent */
+ stackval *retval; /* parent */
+ void *obj; /* this - parent */
+ char *locals;
+ char *args;
+ stackval *stack_args; /* parent */
+ stackval *stack;
+ /* exception info */
+ const unsigned char *ip;
+ MonoObject *ex;
+ MonoExceptionClause *ex_handler;
+};
+
+void mono_init_icall ();
+
diff --git a/mono/metadata/.cvsignore b/mono/metadata/.cvsignore
new file mode 100644
index 00000000000..896769d89cf
--- /dev/null
+++ b/mono/metadata/.cvsignore
@@ -0,0 +1,5 @@
+Makefile
+Makefile.in
+pedump
+.libs
+.deps
diff --git a/mono/metadata/ChangeLog b/mono/metadata/ChangeLog
new file mode 100644
index 00000000000..b7ca98d8d6e
--- /dev/null
+++ b/mono/metadata/ChangeLog
@@ -0,0 +1,252 @@
+
+Wed Aug 22 16:27:30 CEST 2001 Paolo Molaro <lupus@ximian.com>
+
+ * metadata.c, loader.h, loader.c, image.h, image.c, class.h, class.c:
+ MonoClass now has the name and name_space fields.
+ MonoMethod has a pointer to its MonoClass, instead of MonoImage.
+ mono_get_method () takes and optional MonoClass as argument.
+ Removed mono_typedef_from_name() and added mono_class_token_from_name()
+ instead that takes advantage of a map from class names to typedef
+ tokens in MonoImage.
+
+Tue Aug 21 18:54:58 CEST 2001 Paolo Molaro <lupus@ximian.com>
+
+ * metadata.c: zero is not a valid alignment boundary.
+ Merge MONO_TYPE_VOID in default decoding code.
+
+2001-08-21 Dietmar Maurer <dietmar@ximian.com>
+
+ * image.h: merged MonoMetadata into MonoImage
+
+ * class.h: cleanup of MonoArrayClass, use a MonoClass pointer to
+ identify the type of elements.
+
+Mon Aug 20 19:39:00 CEST 2001 Paolo Molaro <lupus@ximian.com>
+
+ * blob.h: fix MONO_TYPE_TYPEDBYREF value.
+ * cil-coff.h: split MonoMSDOSHeader and add size info.
+ * image.c: add some consistency checks.
+ * metadata.c: fix row size computation: one programmer
+ error and one LAMESPEC. Handle MONO_TYPE_TYPEDBYREF.
+ add explanation for the locator routine.
+ Fix decoding of size in method header.
+
+2001-08-20 Miguel de Icaza <miguel@ximian.com>
+
+ * assembly.c (g_concat_dir_and_file): Use _S for string concat.
+ (g_concat_dir_and_file): Bring g_concat_dir_and_file
+ function from gnome-libs. This uses the right path separator
+ based on the OS, and also works around a bug in some systems where
+ a double slash is not allowed.
+ (default_assembly_name_resolver): Use g_concat_dir_and_file
+ (mono_assembly_open): ditto.
+
+2001-08-20 Dietmar Maurer <dietmar@ximian.com>
+
+ * metadata.c (mono_metadata_signature_equal): impl.
+
+ * *: void is now a realy MonoType (instead of using NULL)
+
+ * metadata.c (do_mono_metadata_parse_type): use
+ mono_metadata_parse_type to parse void value.
+
+Sat Aug 18 12:51:28 CEST 2001 Paolo Molaro <lupus@ximian.com>
+
+ * metadata.c, metadata.h: in the signature and method header store
+ only the space required for holding the loca vars and incoming arguments.
+
+2001-08-15 Dietmar Maurer <dietmar@ximian.com>
+
+ * metadata.c (do_mono_metadata_parse_type): treat void like any
+ other type (instead of assigning NULL);
+
+2001-08-14 Dietmar Maurer <dietmar@ximian.com>
+
+ * metadata.c (mono_metadata_parse_mh): fixxed pinned/byref value
+
+2001-08-09 Dietmar Maurer <dietmar@ximian.com>
+
+ * image.c (do_mono_image_open): added a cache for arrays.
+
+Sat Aug 4 12:46:02 CEST 2001 Paolo Molaro <lupus@ximian.com>
+
+ * metadata.h, metadata.c: add mono_metadata_decode_row_col () to
+ decode a single column from a row in a metadata table and changes
+ to take advantage of it in the typedef locator (gives a nice speed up).
+ Store offset info for function params.
+
+2001-08-02 Dietmar Maurer <dietmar@ximian.com>
+
+ * image.h (MONO_IMAGE_IS_CORLIB): removed
+
+Wed Aug 1 22:54:08 CEST 2001 Paolo Molaro <lupus@ximian.com>
+
+ * assembly.c: how could mono_assembly_close () had ever worked?
+ * metadata.c, metadata.h: provide offset info for local vars.
+ Implement mono_type_size () to take care of alignment as well
+ as size (it was mono_field_type_size in cli/class.c before).
+
+2001-08-01 Dietmar Maurer <dietmar@ximian.com>
+
+ * image.h (MONO_IMAGE_IS_CORLIB): new macro to check root image
+
+ * assembly.h (CORLIB_NAME): set to corlib.dll
+
+ * assembly.c (mono_assembly_open): replaced strcmp() with !strcmp()
+
+Tue Jul 31 17:54:02 CEST 2001 Paolo Molaro <lupus@ximian.com>
+
+ * metadata.h, metadata.c, Makefile.am, private.h, assembly.c, blob.h,
+ cil-coff.h, image.c, image.h, pedump.c, rawbuffer.c, rawbuffer.h, row-indexes.h,
+ tokentype.h: massive namespace cleanup.
+
+Mon Jul 30 20:11:01 CEST 2001 Paolo Molaro <lupus@ximian.com>
+
+ * metadata.h, metadata.c: decode exception clauses when parsing method header.
+
+2001-07-27 Dietmar Maurer <dietmar@ximian.com>
+
+ * metadata.c (mono_metadata_free_type): added check for type !=
+ NULL (void) before calling mono_metadata_free_type()
+
+Thu Jul 26 19:11:19 CEST 2001 Paolo Molaro <lupus@ximian.com>
+
+ * metadata.h, row_indexes.h: added header with enumerations to use
+ to index in the columns from tables in metadata and to decode coded
+ tokens: we should start using this instead of embedding magic numbers
+ all over the code.
+
+Thu Jul 26 13:03:27 CEST 2001 Paolo Molaro <lupus@ximian.com>
+
+ * assembly.c, cil-coff.h, image.c, image.h, pedump.c, typedef.c:
+ Move metadata_t info from cli_image_info_t to MonoImage, where
+ it's easily accessible. Changed all the uses accordingly.
+ Added the method and class caches to MonoImage.
+ * metadata.c, metadata.h: Changed mono_metadata_decode_blob_size ()
+ and mono_metadata_decode_value () signature to be more consistent
+ with the other parse functions (and simplify code). Taken advantage
+ of zero-length array allocation with GCC. Removed reduntant (and
+ wrong) MonoFieldType struct and use MonoParam instead. Changed
+ mono_metadata_parse_field_type () to use common code for parsing.
+ Added mono_metadata_typedef_from_field () and
+ mono_metadata_typedef_from_method () to lookup a typedef index from a
+ field or method token.
+ Pack the MonoRetType structure more tightly (fits in 8 bytes now).
+
+2001-07-23 Miguel de Icaza <miguel@ximian.com>
+
+ * metadata.c (mono_metadata_parse_field_type): Implement.
+ (do_mono_metadata_parse_type): Split engine from
+ mono_metadata_parse_type, so that we can create smaller structures
+ for things that just have one pointer to the MonoType (look at
+ the MonoFieldType)
+
+2001-07-20 Miguel de Icaza <miguel@ximian.com>
+
+ * metadata.c (mono_metadata_parse_mh): Correct the implementation,
+ as Jan Gray found out, it is incorrect.
+
+2001-07-18 Miguel de Icaza <miguel@ximian.com>
+
+ * assembly.c: Implement asssembly loading. This loads an image
+ and loads all the referenced assemblies. Come to think of it, we
+ could always do lazy loading of the assemblies.
+
+ * image.c (mono_image_open): Keep loaded images in a hashtable.
+
+ * image.h (MonoImage): Add reference count.
+
+2001-07-17 Miguel de Icaza <miguel@ximian.com>
+
+ * assembly.c (mono_assembly_open): Keep track of the file name in
+ case the assembly has no ASSEMBLY table.
+
+ * metadata.h: Fixed Paolo's quick hack. Put the documnentation
+ from get.c here.
+
+Sun Jul 15 19:39:06 CEST 2001 Paolo Molaro <lupus@ximian.com>
+
+ * metadata.c, metadata.h: decode local vars in method header
+ parse function. Change callers accordingly.
+
+Sun Jul 15 17:40:47 CEST 2001 Paolo Molaro <lupus@ximian.com>
+
+ * metadata.h, cil-coff.h: protect against multiple inclusion.
+ Added some new structures to hold information decoded from metadata:
+ MonoType, MonoParam, MonoArray, MonoMethod, MonoMethodSignature
+ and relevant decoding/free functions.
+ * metadata.c: implement decoding functions. Add warning for out of bounds
+ index in mono_metadata_locate(). Implement mono_get_method () to retreive
+ all the info about a method signature and invocation. Remove check on
+ uninitialized local var in parse_mh() and fix memory leak.
+
+2001-07-12 Miguel de Icaza <miguel@ximian.com>
+
+ * metadata.h: More macros.
+
+ * tokentype.h: New file.
+
+Fri Jul 6 11:30:53 CEST 2001 Paolo Molaro <lupus@ximian.com>
+
+ * assembly.c: added a consistency check and initialize
+ some structures with g_new0().
+ * metadata.c: fixed a couple more bugs in table size computation
+ and add other checks for out-of bound access to metadata.
+
+Thu Jul 5 22:34:21 CEST 2001 Paolo Molaro <lupus@ximian.com>
+
+ * metatada.c: fix bugs computing table sizes. Spew a
+ warning when index in string heap is out of bounds.
+
+2001-07-04 Miguel de Icaza <miguel@ximian.com>
+
+ * metadata.h: Add a couple of macros to manipulate tokens.
+
+Tue Jul 3 18:33:32 CEST 2001 Paolo Molaro <lupus@ximian.com>
+
+ * assembly.c: g_free(ii->cli_sections) (and avoid double free of
+ cli_section_tables).
+
+2001-07-01 Miguel de Icaza <miguel@ximian.com>
+
+ * metadata.c (mono_metadata_user_string): New function, provides
+ access to the UserString heap.
+
+2001-06-27 Miguel de Icaza <miguel@ximian.com>
+
+ * metadata.c: Add inline documentation.
+
+2001-06-26 Miguel de Icaza <miguel@ximian.com>
+
+ * propertyattr.h, paramattr.h, methodsem.h, methodattr.h: New
+ files.
+
+2001-06-22 Miguel de Icaza <miguel@ximian.com>
+
+ * typeattr.h: New file, TypeAttribute flags.
+
+2001-06-21 Miguel de Icaza <miguel@ximian.com>
+
+ * mono/metadata/assembly.c (mono_assembly_ensure_section_idx,
+ mono_assembly_ensure_section): Section loading code.
+ (load_section_tables): Load the sections.
+
+ * mono/metadata/metadata.c (mono_metadata_locate_token,
+ mono_metadata_locate): Functions to locate the information
+ definition given a token or a table and an index.
+ (mono_metadata_compute_table_bases): New.
+ (compute_size): New function to compute the sizes of the various
+ tables.
+
+ * mono/metadata/metadata.h: Finish listing the different index
+ types.
+
+ * mono/metadata/pedump.c: Improve to dump new information.
+
+2001-06-19 Miguel de Icaza <miguel@ximian.com>
+
+ * mono/metadata/metadata.c: Entered all the tables matching
+ Beta2.
+
+ * mono/metadata/assembly.c (load_metadata_ptrs): Fix for Beta2
+
diff --git a/mono/metadata/Makefile.am b/mono/metadata/Makefile.am
index 505141d5abc..c0fe32cc47d 100644
--- a/mono/metadata/Makefile.am
+++ b/mono/metadata/Makefile.am
@@ -2,18 +2,44 @@ noinst_PROGRAMS = pedump
lib_LIBRARIES = libmetadata.a
-INCLUDES = $(GLIB_CFLAGS) -I$(top_srcdir)
+#
+# Keep in sync with mono/runtime/Makefile.am
+#
+assembliesdir = $(libdir)
+
+INCLUDES = $(GLIB_CFLAGS) $(GMODULE_CFLAGS) -I$(top_srcdir) \
+ -DMONO_ASSEMBLIES=\""$(assembliesdir)"\" \
+ -I$(top_srcdir)/libffi/include
+
libmetadata_a_SOURCES = \
- assembly.h \
assembly.c \
- cil-coff.h \
+ image.c \
metadata.c \
- metadata.h \
+ private.h \
rawbuffer.c \
- rawbuffer.h
+ loader.c \
+ class.c \
+ object.c
+
+libmetadataincludedir = $(includedir)/mono/metadata
+
+libmetadatainclude_HEADERS = \
+ assembly.h \
+ blob.h \
+ cil-coff.h \
+ endian.h \
+ image.h \
+ metadata.h \
+ rawbuffer.h \
+ row-indexes.h \
+ tabledefs.h \
+ tokentype.h \
+ loader.h \
+ class.h \
+ object.h
pedump_SOURCES = \
pedump.c $(libmetadata_a_SOURCES)
-pedump_LDADD = $(GLIB_LIBS)
+pedump_LDADD = $(GLIB_LIBS) $(GMODULE_LIBS) ../../libffi/libffi.a
diff --git a/mono/metadata/TODO b/mono/metadata/TODO
new file mode 100644
index 00000000000..7c7da2c7aef
--- /dev/null
+++ b/mono/metadata/TODO
@@ -0,0 +1,5 @@
+
+* Rename assembly.c to module.c
+
+ * Rename all symbols called `assembly' to module, because that is
+ what they actually are. \ No newline at end of file
diff --git a/mono/metadata/assembly.c b/mono/metadata/assembly.c
index 6d6b2602d7f..8b7dae43eb7 100644
--- a/mono/metadata/assembly.c
+++ b/mono/metadata/assembly.c
@@ -1,6 +1,5 @@
/*
- * assembly.c: Routines for manipulating and assembly stored in an
- * extended PE/COFF file.
+ * assembly.c: Routines for loading assemblies.
*
* Author:
* Miguel de Icaza (miguel@ximian.com)
@@ -8,7 +7,7 @@
* (C) 2001 Ximian, Inc. http://www.ximian.com
*
* TODO:
- * Do byteswaps for big-endian systems on the various headers.
+ * Implement big-endian versions of the reading routines.
*/
#include <config.h>
#include <stdio.h>
@@ -16,288 +15,175 @@
#include <errno.h>
#include <string.h>
#include "assembly.h"
+#include "image.h"
#include "cil-coff.h"
#include "rawbuffer.h"
-#define INVALID_ADDRESS 0xffffffff
+#define CSIZE(x) (sizeof (x) / 4)
-/* FIXME: implement big endian versions */
-#define le64_to_cpu(x) (x)
-#define le32_to_cpu(x) (x)
-#define le16_to_cpu(x) (x)
-#define read32(x) le32_to_cpu (*((guint32 *) (x)))
-#define read16(x) le16_to_cpu (*((guint16 *) (x)))
-#define read64(x) le64_to_cpu (*((guint64 *) (x)))
-
-static guint32
-coff_map (dotnet_image_info_t *iinfo, guint32 addr)
+/**
+ * g_concat_dir_and_file:
+ * @dir: directory name
+ * @file: filename.
+ *
+ * returns a new allocated string that is the concatenation of dir and file,
+ * takes care of the exact details for concatenating them.
+ */
+static char *
+g_concat_dir_and_file (const char *dir, const char *file)
{
- const int top = iinfo->dn_section_count;
- section_table_t *tables = iinfo->dn_section_tables;
- int i;
-
- for (i = 0; i < top; i++){
- if ((addr >= tables->st_virtual_address) &&
- (addr < tables->st_virtual_address + tables->st_raw_data_size)){
- return addr - tables->st_virtual_address + tables->st_raw_data_ptr;
- }
- tables++;
- }
- return INVALID_ADDRESS;
-}
+ g_return_val_if_fail (dir != NULL, NULL);
+ g_return_val_if_fail (file != NULL, NULL);
-static int
-load_section_tables (MonoAssembly *assembly, dotnet_image_info_t *iinfo)
-{
- const int top = iinfo->dn_header.coff.coff_sections;
- int i;
-
- iinfo->dn_section_count = top;
- iinfo->dn_section_tables = g_new (section_table_t, top);
-
- for (i = 0; i < top; i++){
- section_table_t *t = &iinfo->dn_section_tables [i];
-
- if (fread (t, sizeof (section_table_t), 1, assembly->f) != 1)
- return FALSE;
-
- t->st_virtual_size = le32_to_cpu (t->st_virtual_size);
- t->st_virtual_address = le32_to_cpu (t->st_virtual_address);
- t->st_raw_data_size = le32_to_cpu (t->st_raw_data_size);
- t->st_raw_data_ptr = le32_to_cpu (t->st_raw_data_ptr);
- t->st_reloc_ptr = le32_to_cpu (t->st_reloc_ptr);
- t->st_lineno_ptr = le32_to_cpu (t->st_lineno_ptr);
- t->st_reloc_count = le16_to_cpu (t->st_reloc_count);
- t->st_line_count = le16_to_cpu (t->st_line_count);
- }
-
- return TRUE;
+ /*
+ * If the directory name doesn't have a / on the end, we need
+ * to add one so we get a proper path to the file
+ */
+ if (dir [strlen(dir) - 1] != G_DIR_SEPARATOR)
+ return g_strconcat (dir, G_DIR_SEPARATOR_S, file, NULL);
+ else
+ return g_strconcat (dir, file, NULL);
}
-static gboolean
-load_cli_header (MonoAssembly *assembly, dotnet_image_info_t *iinfo)
+static char *
+default_assembly_name_resolver (const char *name)
{
- guint32 offset;
- int n;
-
- offset = coff_map (iinfo, iinfo->dn_header.datadir.pe_cli_header.rva);
- if (offset == INVALID_ADDRESS)
- return FALSE;
-
- if (fseek (assembly->f, offset, 0) != 0)
- return FALSE;
+ char *file, *path;
- if ((n = fread (&iinfo->dn_cli_header, sizeof (cli_header_t), 1, assembly->f)) != 1)
- return FALSE;
+ if (strcmp (name, "mscorlib") == 0)
+ return g_concat_dir_and_file (MONO_ASSEMBLIES, CORLIB_NAME);
- /* Catch new uses of the fields that are supposed to be zero */
+ file = g_strconcat (name, ".dll", NULL);
+ path = g_concat_dir_and_file (MONO_ASSEMBLIES, file);
+ g_free (file);
- if ((iinfo->dn_cli_header.ch_eeinfo_table.rva != 0) ||
- (iinfo->dn_cli_header.ch_helper_table.rva != 0) ||
- (iinfo->dn_cli_header.ch_dynamic_info.rva != 0) ||
- (iinfo->dn_cli_header.ch_delay_load_info.rva != 0) ||
- (iinfo->dn_cli_header.ch_module_image.rva != 0) ||
- (iinfo->dn_cli_header.ch_external_fixups.rva != 0) ||
- (iinfo->dn_cli_header.ch_ridmap.rva != 0) ||
- (iinfo->dn_cli_header.ch_debug_map.rva != 0) ||
- (iinfo->dn_cli_header.ch_ip_map.rva != 0)){
- g_message ("Some fields in the CLI header which should have been zero are not zero");
- }
-
- return TRUE;
+ return path;
}
-static gboolean
-load_metadata_ptrs (MonoAssembly *assembly, dotnet_image_info_t *iinfo)
+/**
+ * mono_assembly_open:
+ * @filename: Opens the assembly pointed out by this name
+ * @resolver: A user provided function to resolve assembly references
+ * @status: where a status code can be returned
+ *
+ * mono_assembly_open opens the PE-image pointed by @filename, and
+ * loads any external assemblies referenced by it.
+ *
+ * NOTE: we could do lazy loading of the assemblies. Or maybe not worth
+ * it.
+ */
+MonoAssembly *
+mono_assembly_open (const char *filename, MonoAssemblyResolverFn resolver,
+ enum MonoImageOpenStatus *status)
{
- metadata_t *metadata = &iinfo->dn_metadata;
- guint32 offset, size;
- guint16 records;
+ MonoAssembly *ass;
+ MonoImage *image;
+ MonoTableInfo *t;
int i;
- char *ptr;
+ const char *basename = strrchr (filename, '/');
+ static MonoAssembly *corlib;
- offset = coff_map (iinfo, iinfo->dn_cli_header.ch_metadata.rva);
- size = iinfo->dn_cli_header.ch_metadata.size;
-
- metadata->raw_metadata = raw_buffer_load (fileno (assembly->f), FALSE, offset, size);
- if (metadata->raw_metadata == NULL)
- return FALSE;
+ g_return_val_if_fail (filename != NULL, NULL);
- ptr = metadata->raw_metadata;
+ if (basename == NULL)
+ basename = filename;
+ else
+ basename++;
/*
- * Handle Beta 1 and ECMA versions of the metadata root
+ * Temporary hack until we have a complete corlib.dll
*/
- if (strncmp (ptr, "COM+", 4) == 0){
- ptr += 10;
- } else if (strncmp (ptr, "BSJB", 4) == 0){
- guint32 version_string_len;
-
- ptr += 8;
- version_string_len = read32 (ptr);
- ptr += version_string_len;
- if (((guint32) ptr) % 4)
- ptr += 4 - (((guint32) ptr) %4);
- }
-
- records = read16 (ptr);
- ptr += 2;
-
- for (i = 0; i < records; i++){
- if (strncmp (ptr + 8, "#~", 3) == 0){
- metadata->heap_tables.sh_offset = read32 (ptr);
- metadata->heap_tables.sh_size = read32 (ptr + 4);
- ptr += 8 + 3;
- } else if (strncmp (ptr + 8, "#Strings", 9) == 0){
- metadata->heap_strings.sh_offset = read32 (ptr);
- metadata->heap_strings.sh_size = read32 (ptr + 4);
- ptr += 8 + 9;
- } else if (strncmp (ptr + 8, "#US", 4) == 0){
- metadata->heap_us.sh_offset = read32 (ptr);
- metadata->heap_us.sh_size = read32 (ptr + 4);
- ptr += 8 + 4;
- } else if (strncmp (ptr + 8, "#Blob", 6) == 0){
- metadata->heap_blob.sh_offset = read32 (ptr);
- metadata->heap_blob.sh_size = read32 (ptr + 4);
- ptr += 8 + 6;
- } else if (strncmp (ptr + 8, "#GUID", 6) == 0){
- metadata->heap_guid.sh_offset = read32 (ptr);
- metadata->heap_guid.sh_size = read32 (ptr + 4);
- ptr += 8 + 6;
- } else
- g_message ("Unknown heap type: %s\n", ptr + 8);
- if (((guint32)ptr) % 4){
- ptr += 4 - (((guint32)ptr) % 4);
- }
- }
- return TRUE;
-}
-
-static gboolean
-load_tables (MonoAssembly *assembly, metadata_t *meta)
-{
- char *heap_tables = meta->raw_metadata + meta->heap_tables.sh_offset;
- guint32 *rows;
- guint64 valid_mask;
- int valid = 0, table;
-
- valid_mask = read64 (heap_tables + 8);
- rows = (guint32 *) (heap_tables + 24);
+ if (strcmp (basename, CORLIB_NAME) == 0) {
+ char *fullname;
+
+ if (corlib != NULL)
+ return corlib;
+ fullname = g_concat_dir_and_file (MONO_ASSEMBLIES, CORLIB_NAME);
+ image = mono_image_open (fullname, status);
+ g_free (fullname);
+ } else
+ image = mono_image_open (filename, status);
- for (table = 0; table < 64; table++){
- if ((valid_mask & ((guint64) 1 << table)) == 0){
- meta->rows [table] = 0;
- continue;
- }
- meta->rows [table] = *rows;
- rows++;
- valid++;
+ if (!image){
+ if (status)
+ *status = MONO_IMAGE_ERROR_ERRNO;
+ return NULL;
}
- return TRUE;
-}
-
-static gboolean
-load_metadata (MonoAssembly *assembly, dotnet_image_info_t *iinfo)
-{
- if (!load_metadata_ptrs (assembly, iinfo))
- return FALSE;
-
- return load_tables (assembly, &iinfo->dn_metadata);
-}
+ if (resolver == NULL)
+ resolver = default_assembly_name_resolver;
-MonoAssembly *
-mono_assembly_open (const char *fname, enum MonoAssemblyOpenStatus *status)
-{
- dotnet_image_info_t *iinfo;
- dotnet_header_t *header;
- msdos_header_t msdos;
- MonoAssembly *assembly;
- int n;
+ t = &image->tables [MONO_TABLE_ASSEMBLYREF];
- assembly = g_new (MonoAssembly, 1);
- assembly->f = fopen (fname, "r");
- iinfo = g_new (dotnet_image_info_t, 1);
- assembly->image_info = iinfo;
+ image->references = g_new0 (MonoAssembly *, t->rows + 1);
- header = &iinfo->dn_header;
-
- if (assembly->f == NULL){
- if (status)
- *status = MONO_ASSEMBLY_ERROR_ERRNO;
- mono_assembly_close (assembly);
- return NULL;
- }
-
- if (status)
- *status = MONO_ASSEMBLY_IMAGE_INVALID;
-
- if (fread (&msdos, sizeof (msdos), 1, assembly->f) != 1)
- goto invalid_image;
-
- if (!(msdos.msdos_header [0] == 0x4d && msdos.msdos_header [1] == 0x5a))
- goto invalid_image;
+ ass = g_new (MonoAssembly, 1);
+ ass->image = image;
- if ((n = fread (header, sizeof (dotnet_header_t), 1, assembly->f)) != 1)
- goto invalid_image;
-
/*
- * FIXME: byte swap all addresses here for header.
+ * Load any assemblies this image references
*/
-
- if (!load_section_tables (assembly, iinfo))
- goto invalid_image;
-
- /* Load the CLI header */
- if (!load_cli_header (assembly, iinfo))
- goto invalid_image;
-
- if (!load_metadata (assembly, iinfo))
- goto invalid_image;
-
- if (status)
- *status = MONO_ASSEMBLY_OK;
-
- return assembly;
+ for (i = 0; i < t->rows; i++){
+ char *assembly_ref;
+ const char *name;
+ guint32 cols [MONO_ASSEMBLYREF_SIZE];
+
+ mono_metadata_decode_row (t, i, cols, CSIZE (cols));
+ name = mono_metadata_string_heap (image, cols [MONO_ASSEMBLYREF_NAME]);
+
+ /*
+ * Special case until we have a passable corlib:
+ *
+ * ie, references to mscorlib from corlib.dll are ignored
+ * and we do not load corlib twice.
+ */
+ if (strcmp (basename, CORLIB_NAME) == 0){
+ if (corlib == NULL)
+ corlib = ass;
+
+ if (strcmp (name, "mscorlib") == 0)
+ continue;
+ }
+
+ assembly_ref = (*resolver) (name);
+
+ image->references [i] = mono_assembly_open (assembly_ref, resolver, status);
+ if (image->references [i] == NULL){
+ int j;
+
+ for (j = 0; j < i; j++)
+ mono_assembly_close (image->references [j]);
+ g_free (image->references);
+ mono_image_close (image);
+
+ g_warning ("Could not find assembly %s %s", name, assembly_ref);
+ g_free (assembly_ref);
+ if (status)
+ *status = MONO_IMAGE_MISSING_ASSEMBLYREF;
+ g_free (ass);
+ return NULL;
+ }
+ g_free (assembly_ref);
+ }
+ image->references [i] = NULL;
-invalid_image:
- mono_assembly_close (assembly);
- return NULL;
+ return ass;
}
void
mono_assembly_close (MonoAssembly *assembly)
{
- g_return_if_fail (assembly != NULL);
-
- if (assembly->f)
- fclose (assembly->f);
-
- if (assembly->image_info){
- dotnet_image_info_t *ii = assembly->image_info;
-
- if (ii->dn_metadata.raw_metadata != NULL)
- raw_buffer_free (ii->dn_metadata.raw_metadata);
+ MonoImage *image;
+ int i;
- if (ii->dn_section_tables)
- g_free (ii->dn_section_tables);
+ g_return_if_fail (assembly != NULL);
- g_free (assembly->image_info);
- }
-
+ image = assembly->image;
+ for (i = 0; image->references [i] != NULL; i++)
+ mono_image_close (image->references [i]->image);
+ g_free (image->references);
+
+ mono_image_close (assembly->image);
g_free (assembly);
}
-const char *
-mono_assembly_strerror (enum MonoAssemblyOpenStatus status)
-{
- switch (status){
- case MONO_ASSEMBLY_OK:
- return "succes";
- case MONO_ASSEMBLY_ERROR_ERRNO:
- return strerror (errno);
- case MONO_ASSEMBLY_IMAGE_INVALID:
- return "File does not contain a valid CIL image";
- }
- return "Internal error";
-}
diff --git a/mono/metadata/assembly.h b/mono/metadata/assembly.h
index dcec354f007..07a2f00d2d9 100644
--- a/mono/metadata/assembly.h
+++ b/mono/metadata/assembly.h
@@ -1,20 +1,15 @@
#ifndef _MONONET_METADATA_ASSEMBLY_H_
#define _MONONET_METADATA_ASSEMBLY_H_
-typedef struct {
- FILE *f;
- void *image_info;
-} MonoAssembly;
+#include <mono/metadata/image.h>
-enum MonoAssemblyOpenStatus {
- MONO_ASSEMBLY_OK,
- MONO_ASSEMBLY_ERROR_ERRNO,
- MONO_ASSEMBLY_IMAGE_INVALID
-};
+#define CORLIB_NAME "corlib.dll"
-MonoAssembly *mono_assembly_open (const char *fname, enum MonoAssemblyOpenStatus *status);
-void mono_assembly_close (MonoAssembly *assembly);
+typedef char * (*MonoAssemblyResolverFn)(const char *name);
-const char *mono_assembly_strerror (enum MonoAssemblyOpenStatus status);
+MonoAssembly *mono_assembly_open (const char *fname,
+ MonoAssemblyResolverFn resolver,
+ enum MonoImageOpenStatus *status);
+void mono_assembly_close (MonoAssembly *assembly);
#endif
diff --git a/mono/metadata/blob.h b/mono/metadata/blob.h
new file mode 100644
index 00000000000..e5cb42b3616
--- /dev/null
+++ b/mono/metadata/blob.h
@@ -0,0 +1,51 @@
+/*
+ * blob.h: Definitions used to pull information out of the Blob
+ *
+ */
+#ifndef _MONO_METADATA_BLOB_H_
+#define _MONO_METADATA_BLOB_H_
+
+#define SIGNATURE_HAS_THIS 0x20
+#define SIGNATURE_EXPLICIT_THIS 0x40
+#define SIGNATURE_VARARG 0x05
+
+/*
+ * Encoding for type signatures used in the Metadata
+ */
+typedef enum {
+ MONO_TYPE_END = 0x00, /* End of List */
+ MONO_TYPE_VOID = 0x01,
+ MONO_TYPE_BOOLEAN = 0x02,
+ MONO_TYPE_CHAR = 0x03,
+ MONO_TYPE_I1 = 0x04,
+ MONO_TYPE_U1 = 0x05,
+ MONO_TYPE_I2 = 0x06,
+ MONO_TYPE_U2 = 0x07,
+ MONO_TYPE_I4 = 0x08,
+ MONO_TYPE_U4 = 0x09,
+ MONO_TYPE_I8 = 0x0a,
+ MONO_TYPE_U8 = 0x0b,
+ MONO_TYPE_R4 = 0x0c,
+ MONO_TYPE_R8 = 0x0d,
+ MONO_TYPE_STRING = 0x0e,
+ MONO_TYPE_PTR = 0x0f, /* arg: <type> token */
+ MONO_TYPE_BYREF = 0x10, /* arg: <type> token */
+ MONO_TYPE_VALUETYPE = 0x11, /* arg: <type> token */
+ MONO_TYPE_CLASS = 0x12, /* arg: <type> token */
+ MONO_TYPE_ARRAY = 0x14, /* type, rank, boundsCount, bound1, loCount, lo1 */
+ MONO_TYPE_TYPEDBYREF = 0x16,
+ MONO_TYPE_I = 0x18,
+ MONO_TYPE_U = 0x19,
+ MONO_TYPE_FNPTR = 0x1b, /* arg: full method signature */
+ MONO_TYPE_OBJECT = 0x1c,
+ MONO_TYPE_SZARRAY = 0x1d, /* 0-based one-dim-array */
+ MONO_TYPE_CMOD_REQD = 0x1f, /* arg: typedef or typeref token */
+ MONO_TYPE_CMOD_OPT = 0x20, /* optional arg: typedef or typref token */
+ MONO_TYPE_INTERNAL = 0x21, /* CLR internal type */
+
+ MONO_TYPE_MODIFIER = 0x40, /* Or with the following types */
+ MONO_TYPE_SENTINEL = 0x41, /* Sentinel for varargs method signature */
+ MONO_TYPE_PINNED = 0x45, /* Local var that points to pinned object */
+} MonoTypeEnum;
+
+#endif
diff --git a/mono/metadata/cil-coff.h b/mono/metadata/cil-coff.h
index ee4f001e2b0..1393c801306 100644
--- a/mono/metadata/cil-coff.h
+++ b/mono/metadata/cil-coff.h
@@ -1,12 +1,40 @@
-#include <mono/metadata/metadata.h>
-/* A metadata token */
-typedef guint32 mtoken_t;
+#ifndef __MONO_CIL_COFF_H__
+#define __MONO_CIL_COFF_H__
+
+#include <mono/metadata/metadata.h>
+/*
+ * 25.2.1: Method header type values
+ */
+#define METHOD_HEADER_FORMAT_MASK 7
+#define METHOD_HEADER_TINY_FORMAT 2
+#define METHOD_HEADER_TINY_FORMAT1 6
+#define METHOD_HEADER_FAT_FORMAT 3
+
+/*
+ * 25.2.3.1: Flags for method headers
+ */
+#define METHOD_HEADER_INIT_LOCALS 0x10
+#define METHOD_HEADER_MORE_SECTS 0x08
+
+/*
+ * For section data (25.3)
+ */
+#define METHOD_HEADER_SECTION_RESERVED 0
+#define METHOD_HEADER_SECTION_EHTABLE 1
+#define METHOD_HEADER_SECTION_OPTIL_TABLE 2
+#define METHOD_HEADER_SECTION_FAT_FORMAT 0x40
+#define METHOD_HEADER_SECTION_MORE_SECTS 0x80
+
+/* 128 bytes */
typedef struct {
- char msdos_header [128];
-} msdos_header_t;
+ char msdos_header [60];
+ guint32 pe_offset;
+ char msdos_header2 [64];
+} MonoMSDOSHeader;
+/* 20 bytes */
typedef struct {
guint16 coff_machine;
guint16 coff_sections;
@@ -15,11 +43,12 @@ typedef struct {
guint32 coff_symcount;
guint16 coff_opt_header_size;
guint16 coff_attributes;
-} coff_header_t;
+} MonoCOFFHeader;
#define COFF_ATTRIBUTE_EXECUTABLE_IMAGE 0x0002
#define COFF_ATTRIBUTE_LIBRARY_IMAGE 0x2000
+/* 28 bytes */
typedef struct {
guint16 pe_magic;
guchar pe_major;
@@ -30,8 +59,9 @@ typedef struct {
guint32 pe_rva_entry_point;
guint32 pe_rva_code_base;
guint32 pe_rva_data_base;
-} pe_header_t;
+} MonoPEHeader;
+/* 68 bytes */
typedef struct {
guint32 pe_image_base; /* must be 0x400000 */
guint32 pe_section_align; /* must be 8192 */
@@ -54,39 +84,41 @@ typedef struct {
guint32 pe_heap_commit;
guint32 pe_loader_flags;
guint32 pe_data_dir_count;
-} pe_header_nt_t;
+} MonoPEHeaderNT;
typedef struct {
guint32 rva;
guint32 size;
-} pe_dir_entry_t;
+} MonoPEDirEntry;
+/* 128 bytes */
typedef struct {
- pe_dir_entry_t pe_export_table;
- pe_dir_entry_t pe_import_table;
- pe_dir_entry_t pe_resource_table;
- pe_dir_entry_t pe_exception_table;
- pe_dir_entry_t pe_certificate_table;
- pe_dir_entry_t pe_reloc_table;
- pe_dir_entry_t pe_debug;
- pe_dir_entry_t pe_copyright;
- pe_dir_entry_t pe_global_ptr;
- pe_dir_entry_t pe_tls_table;
- pe_dir_entry_t pe_load_config_table;
- pe_dir_entry_t pe_bound_import;
- pe_dir_entry_t pe_iat;
- pe_dir_entry_t pe_delay_import_desc;
- pe_dir_entry_t pe_cli_header;
- pe_dir_entry_t pe_reserved;
-} pe_datadir_t;
-
+ MonoPEDirEntry pe_export_table;
+ MonoPEDirEntry pe_import_table;
+ MonoPEDirEntry pe_resource_table;
+ MonoPEDirEntry pe_exception_table;
+ MonoPEDirEntry pe_certificate_table;
+ MonoPEDirEntry pe_reloc_table;
+ MonoPEDirEntry pe_debug;
+ MonoPEDirEntry pe_copyright;
+ MonoPEDirEntry pe_global_ptr;
+ MonoPEDirEntry pe_tls_table;
+ MonoPEDirEntry pe_load_config_table;
+ MonoPEDirEntry pe_bound_import;
+ MonoPEDirEntry pe_iat;
+ MonoPEDirEntry pe_delay_import_desc;
+ MonoPEDirEntry pe_cli_header;
+ MonoPEDirEntry pe_reserved;
+} MonoPEDatadir;
+
+/* 248 bytes */
typedef struct {
char pesig [4];
- coff_header_t coff;
- pe_header_t pe;
- pe_header_nt_t nt;
- pe_datadir_t datadir;
-} dotnet_header_t;
+ MonoCOFFHeader coff;
+ MonoPEHeader pe;
+ MonoPEHeaderNT nt;
+ MonoPEDatadir datadir;
+} MonoDotNetHeader;
typedef struct {
char st_name [8];
@@ -110,47 +142,49 @@ typedef struct {
#define SECT_FLAGS_MEM_READ 0x40000000
#define SECT_FLAGS_MEM_WRITE 0x80000000
guint32 st_flags;
-} section_table_t;
+
+} MonoSectionTable;
typedef struct {
guint32 ch_size;
guint16 ch_runtime_major;
guint16 ch_runtime_minor;
- pe_dir_entry_t ch_metadata;
+ MonoPEDirEntry ch_metadata;
#define CLI_FLAGS_ILONLY 0x01
#define CLI_FLAGS_32BITREQUIRED 0x02
#define CLI_FLAGS_TRACKDEBUGDATA 0x00010000
guint32 ch_flags;
- mtoken_t ch_entry_point;
- pe_dir_entry_t ch_resources;
- pe_dir_entry_t ch_strong_name;
- pe_dir_entry_t ch_code_manager_table;
- pe_dir_entry_t ch_vtable_fixups;
- pe_dir_entry_t ch_export_address_table_jumps;
+ guint32 ch_entry_point;
+ MonoPEDirEntry ch_resources;
+ MonoPEDirEntry ch_strong_name;
+ MonoPEDirEntry ch_code_manager_table;
+ MonoPEDirEntry ch_vtable_fixups;
+ MonoPEDirEntry ch_export_address_table_jumps;
/* The following are zero in the current docs */
- pe_dir_entry_t ch_eeinfo_table;
- pe_dir_entry_t ch_helper_table;
- pe_dir_entry_t ch_dynamic_info;
- pe_dir_entry_t ch_delay_load_info;
- pe_dir_entry_t ch_module_image;
- pe_dir_entry_t ch_external_fixups;
- pe_dir_entry_t ch_ridmap;
- pe_dir_entry_t ch_debug_map;
- pe_dir_entry_t ch_ip_map;
-} cli_header_t;
+ MonoPEDirEntry ch_eeinfo_table;
+ MonoPEDirEntry ch_helper_table;
+ MonoPEDirEntry ch_dynamic_info;
+ MonoPEDirEntry ch_delay_load_info;
+ MonoPEDirEntry ch_module_image;
+ MonoPEDirEntry ch_external_fixups;
+ MonoPEDirEntry ch_ridmap;
+ MonoPEDirEntry ch_debug_map;
+ MonoPEDirEntry ch_ip_map;
+} MonoCLIHeader;
/* This is not an on-disk structure */
typedef struct {
- dotnet_header_t dn_header;
- int dn_section_count;
- section_table_t *dn_section_tables;
- cli_header_t dn_cli_header;
-
- metadata_t dn_metadata;
-} dotnet_image_info_t;
-
+ MonoDotNetHeader cli_header;
+ int cli_section_count;
+ MonoSectionTable *cli_section_tables;
+ void **cli_sections;
+ MonoCLIHeader cli_cli_header;
+} MonoCLIImageInfo;
+guint32 mono_cli_rva_image_map (MonoCLIImageInfo *iinfo, guint32 rva);
+char *mono_cli_rva_map (MonoCLIImageInfo *iinfo, guint32 rva);
+#endif /* __MONO_CIL_COFF_H__ */
diff --git a/mono/metadata/class.c b/mono/metadata/class.c
new file mode 100644
index 00000000000..da211964588
--- /dev/null
+++ b/mono/metadata/class.c
@@ -0,0 +1,504 @@
+/*
+ * class.c: Class management for the Mono runtime
+ *
+ * Author:
+ * Miguel de Icaza (miguel@ximian.com)
+ *
+ * (C) 2001 Ximian, Inc.
+ *
+ * Possible Optimizations:
+ * in mono_class_create, do not allocate the class right away,
+ * but wait until you know the size of the FieldMap, so that
+ * the class embeds directly the FieldMap after the vtable.
+ *
+ *
+ */
+#include <config.h>
+#include <glib.h>
+#include <stdio.h>
+#include <mono/metadata/image.h>
+#include <mono/metadata/cil-coff.h>
+#include <mono/metadata/metadata.h>
+#include <mono/metadata/tabledefs.h>
+#include <mono/metadata/tokentype.h>
+#include <mono/metadata/class.h>
+#include <mono/metadata/object.h>
+
+#define CSIZE(x) (sizeof (x) / 4)
+
+static void
+typedef_from_typeref (MonoImage *image, guint32 type_token, MonoImage **rimage, guint32 *index)
+{
+ guint32 cols [MONO_TYPEREF_SIZE];
+ MonoTableInfo *t = &image->tables [MONO_TABLE_TYPEREF];
+ guint32 idx;
+ const char *name, *nspace;
+
+ mono_metadata_decode_row (t, (type_token&0xffffff)-1, cols, MONO_TYPEREF_SIZE);
+ g_assert ((cols [MONO_TYPEREF_SCOPE] & 0x3) == 2);
+ idx = cols [MONO_TYPEREF_SCOPE] >> 2;
+ name = mono_metadata_string_heap (image, cols [MONO_TYPEREF_NAME]);
+ nspace = mono_metadata_string_heap (image, cols [MONO_TYPEREF_NAMESPACE]);
+ /* load referenced assembly */
+ *rimage = image = image->references [idx-1]->image;
+ *index = mono_class_token_from_name (image, nspace, name);
+
+}
+
+/**
+ * class_compute_field_layout:
+ * @m: pointer to the metadata.
+ * @class: The class to initialize
+ *
+ * Initializes the class->fields.
+ *
+ * Currently we only support AUTO_LAYOUT, and do not even try to do
+ * a good job at it. This is temporary to get the code for Paolo.
+ */
+static void
+class_compute_field_layout (MonoMetadata *m, MonoClass *class)
+{
+ const int top = class->field.count;
+ guint32 layout = class->flags & TYPE_ATTRIBUTE_LAYOUT_MASK;
+ MonoTableInfo *t = &m->tables [MONO_TABLE_FIELD];
+ int i, j;
+
+ /*
+ * Fetch all the field information.
+ */
+ for (i = 0; i < top; i++){
+ const char *sig;
+ guint32 cols [3];
+ int idx = class->field.first + i;
+
+ mono_metadata_decode_row (t, idx, cols, CSIZE (cols));
+ sig = mono_metadata_blob_heap (m, cols [2]);
+ mono_metadata_decode_value (sig, &sig);
+ /* FIELD signature == 0x06 */
+ g_assert (*sig == 0x06);
+ class->fields [i].type = mono_metadata_parse_field_type (
+ m, sig + 1, &sig);
+ class->fields [i].flags = cols [0];
+ }
+ /*
+ * Compute field layout and total size.
+ */
+ switch (layout){
+ case TYPE_ATTRIBUTE_AUTO_LAYOUT:
+ case TYPE_ATTRIBUTE_SEQUENTIAL_LAYOUT:
+ for (i = 0; i < top; i++){
+ int size, align;
+
+ size = mono_type_size (class->fields [i].type->type, &align);
+ if (class->fields [i].flags & FIELD_ATTRIBUTE_STATIC) {
+ class->fields [i].offset = class->class_size;
+ class->class_size += (class->class_size % align);
+ class->class_size += size;
+ } else {
+ class->fields [i].offset = class->instance_size;
+ class->instance_size += (class->instance_size % align);
+ class->instance_size += size;
+ }
+ }
+ break;
+ case TYPE_ATTRIBUTE_EXPLICIT_LAYOUT:
+ for (i = 0; i < top; i++){
+ guint32 cols [2];
+ int size, align;
+ int idx = class->field.first + i;
+
+ t = &m->tables [MONO_TABLE_FIELDLAYOUT];
+
+ for (j = 0; j < t->rows; j++) {
+
+ mono_metadata_decode_row (t, j, cols, CSIZE (cols));
+ if (cols [1] == idx) {
+ g_warning ("TODO: Explicit layout not supported yet");
+ }
+ }
+
+ size = mono_type_size (class->fields [i].type->type, &align);
+ if (class->fields [i].flags & FIELD_ATTRIBUTE_STATIC) {
+ class->fields [i].offset = class->class_size;
+ class->class_size += (class->class_size % align);
+ class->class_size += size;
+ } else {
+ class->fields [i].offset = class->instance_size;
+ class->instance_size += (class->instance_size % align);
+ class->instance_size += size;
+ }
+ }
+ break;
+ }
+}
+
+/**
+ * @image: context where the image is created
+ * @type_token: typedef token
+ */
+static MonoClass *
+mono_class_create_from_typedef (MonoImage *image, guint32 type_token)
+{
+ MonoTableInfo *tt = &image->tables [MONO_TABLE_TYPEDEF];
+ MonoClass stack_class;
+ MonoClass *class = &stack_class;
+ guint32 cols [MONO_TYPEDEF_SIZE], parent_token;
+ guint tidx = mono_metadata_token_index (type_token);
+ const char *name, *nspace;
+
+ g_assert (mono_metadata_token_table (type_token) == MONO_TABLE_TYPEDEF);
+
+ memset (class, 0, sizeof (MonoClass));
+
+ mono_metadata_decode_row (tt, tidx-1, cols, CSIZE (cols));
+ class->name = name = mono_metadata_string_heap (image, cols[1]);
+ class->name_space = nspace = mono_metadata_string_heap (image, cols[2]);
+ /*g_print ("Init class %s\n", name);*/
+
+ /* if root of the hierarchy */
+ if (!strcmp (nspace, "System") && !strcmp (name, "Object")) {
+ class->instance_size = sizeof (MonoObject);
+ class->parent = NULL;
+ } else {
+ parent_token = mono_metadata_token_from_dor (cols [3]);
+ class->parent = mono_class_get (image, parent_token);
+ class->instance_size = class->parent->instance_size;
+ class->valuetype = class->parent->valuetype;
+ }
+ if (!strcmp (nspace, "System") && !strcmp (name, "ValueType"))
+ class->valuetype = 1;
+
+ g_assert (class->instance_size);
+ class->image = image;
+ class->type_token = type_token;
+ class->flags = cols [0];
+ class->class_size = sizeof (MonoClass);
+
+ /*
+ * Compute the field and method lists
+ */
+ class->field.first = cols [MONO_TYPEDEF_FIELD_LIST] - 1;
+ class->method.first = cols [MONO_TYPEDEF_METHOD_LIST] - 1;
+
+ if (tt->rows > tidx){
+ guint32 cols_next [MONO_TYPEDEF_SIZE];
+
+ mono_metadata_decode_row (tt, tidx, cols_next, CSIZE (cols_next));
+ class->field.last = cols_next [MONO_TYPEDEF_FIELD_LIST] - 1;
+ class->method.last = cols_next [MONO_TYPEDEF_METHOD_LIST] - 1;
+ } else {
+ class->field.last = image->tables [MONO_TABLE_FIELD].rows;
+ class->method.last = image->tables [MONO_TABLE_METHOD].rows;
+ }
+
+ if (cols [MONO_TYPEDEF_FIELD_LIST] &&
+ cols [MONO_TYPEDEF_FIELD_LIST] <= image->tables [MONO_TABLE_FIELD].rows)
+ class->field.count = class->field.last - class->field.first;
+ else
+ class->field.count = 0;
+
+ if (cols [MONO_TYPEDEF_METHOD_LIST] <= image->tables [MONO_TABLE_METHOD].rows)
+ class->method.count = class->method.last - class->method.first;
+ else
+ class->method.count = 0;
+
+ /*
+ * Computes the size used by the fields, and their locations
+ */
+ if (class->field.count > 0){
+ class->fields = g_new (MonoClassField, class->field.count);
+ class_compute_field_layout (image, class);
+ }
+
+ /* reserve space to store vector pointer in arrays */
+ if (!strcmp (nspace, "System") && !strcmp (name, "Array")) {
+ class->instance_size += 2 * sizeof (gpointer);
+ g_assert (class->field.count == 0);
+ g_assert (class->instance_size == sizeof (MonoArrayObject));
+ }
+
+ class = g_malloc0 (class->class_size);
+ *class = stack_class;
+
+ if (class->method.count > 0) {
+ int i;
+ class->methods = g_new (MonoMethod*, class->method.count);
+ for (i = class->method.first; i < class->method.last; ++i)
+ class->methods [i - class->method.first] = mono_get_method (image,
+ MONO_TOKEN_METHOD_DEF | (i + 1), class);
+ }
+
+ return class;
+}
+
+static guint32
+mono_type_to_tydedef (MonoImage *image, MonoType *type, MonoImage **rimage)
+{
+ MonoImage *corlib, *res;
+ guint32 etype;
+
+ res = corlib = mono_defaults.corlib;
+
+ switch (type->type) {
+ case MONO_TYPE_BOOLEAN:
+ etype = mono_class_token_from_name (corlib, "System", "Boolean");
+ break;
+ case MONO_TYPE_CHAR:
+ etype = mono_class_token_from_name (corlib, "System", "Char");
+ break;
+ case MONO_TYPE_I1:
+ etype = mono_class_token_from_name (corlib, "System", "Byte");
+ break;
+ case MONO_TYPE_I2:
+ etype = mono_class_token_from_name (corlib, "System", "Int16");
+ break;
+ case MONO_TYPE_U2:
+ etype = mono_class_token_from_name (corlib, "System", "UInt16");
+ break;
+ case MONO_TYPE_I4:
+ etype = mono_class_token_from_name (corlib, "System", "Int32");
+ break;
+ case MONO_TYPE_U4:
+ etype = mono_class_token_from_name (corlib, "System", "UInt32");
+ break;
+ case MONO_TYPE_I8:
+ etype = mono_class_token_from_name (corlib, "System", "Int64");
+ break;
+ case MONO_TYPE_U8:
+ etype = mono_class_token_from_name (corlib, "System", "UInt64");
+ break;
+ case MONO_TYPE_R8:
+ etype = mono_class_token_from_name (corlib, "System", "Double");
+ break;
+ case MONO_TYPE_STRING:
+ etype = mono_class_token_from_name (corlib, "System", "String");
+ break;
+ case MONO_TYPE_CLASS:
+ etype = type->data.token;
+ res = image;
+ break;
+ default:
+ g_warning ("implement me %08x\n", type->type);
+ g_assert_not_reached ();
+ }
+
+ *rimage = res;
+ return etype;
+}
+
+/**
+ * @image: context where the image is created
+ * @type_spec: typespec token
+ * @at: an optional pointer to return the array type
+ */
+static MonoClass *
+mono_class_create_from_typespec (MonoImage *image, guint32 type_spec)
+{
+ guint32 idx = mono_metadata_token_index (type_spec);
+ MonoTableInfo *t;
+ guint32 cols [MONO_TYPESPEC_SIZE];
+ const char *ptr;
+ guint32 len, etype;
+ MonoType *type;
+ MonoClass *class;
+ MonoImage *rimage;
+
+ t = &image->tables [MONO_TABLE_TYPESPEC];
+
+ mono_metadata_decode_row (t, idx-1, cols, MONO_TYPESPEC_SIZE);
+ ptr = mono_metadata_blob_heap (image, cols [MONO_TYPESPEC_SIGNATURE]);
+ len = mono_metadata_decode_value (ptr, &ptr);
+ type = mono_metadata_parse_type (image, ptr, &ptr);
+
+ switch (type->type) {
+ case MONO_TYPE_ARRAY:
+ etype = mono_type_to_tydedef (image, type->data.array->type, &rimage);
+ class = mono_array_class_get (rimage, etype, type->data.array->rank);
+ break;
+ case MONO_TYPE_SZARRAY:
+ g_assert (!type->custom_mod);
+ etype = mono_type_to_tydedef (image, type->data.type, &rimage);
+ class = mono_array_class_get (rimage, etype, 1);
+ break;
+ default:
+ g_assert_not_reached ();
+ }
+
+ mono_metadata_free_type (type);
+
+ return class;
+}
+
+/**
+ * mono_array_class_get:
+ * @image: context where the image is created
+ * @etype: element type token
+ * @rank: the dimension of the array class
+ *
+ * Returns: a class object describing the array with element type @etype and
+ * dimension @rank.
+ */
+MonoClass *
+mono_array_class_get (MonoImage *image, guint32 etype, guint32 rank)
+{
+ MonoClass *class, *eclass;
+ static MonoClass *parent = NULL;
+ MonoArrayClass *aclass;
+ guint32 key;
+
+ g_assert (rank <= 255);
+
+ if (!parent) {
+ parent = mono_class_get (mono_defaults.corlib,
+ mono_defaults.array_token);
+ g_assert (parent != NULL);
+ }
+
+ eclass = mono_class_get (image, etype);
+ g_assert (eclass != NULL);
+
+ image = eclass->image;
+
+ g_assert (!eclass->type_token ||
+ mono_metadata_token_table (eclass->type_token) == MONO_TABLE_TYPEDEF);
+
+ key = ((rank & 0xff) << 24) | (eclass->type_token & 0xffffff);
+ if ((class = g_hash_table_lookup (image->array_cache, GUINT_TO_POINTER (key))))
+ return class;
+
+ aclass = g_new0 (MonoArrayClass, 1);
+ class = (MonoClass *)aclass;
+
+ class->image = image;
+ class->name_space = "System";
+ class->name = "Array";
+ class->type_token = 0;
+ class->flags = TYPE_ATTRIBUTE_CLASS;
+ class->parent = parent;
+ class->instance_size = class->parent->instance_size;
+ class->class_size = sizeof (MonoArrayClass);
+
+ aclass->rank = rank;
+ aclass->element_class = eclass;
+
+ g_hash_table_insert (image->array_cache, GUINT_TO_POINTER (key), class);
+ return class;
+}
+
+/*
+ * Auxiliary routine to mono_class_get_field
+ *
+ * Takes a field index instead of a field token.
+ */
+static MonoClassField *
+mono_class_get_field_idx (MonoClass *class, int idx)
+{
+ if (class->field.count){
+ if ((idx >= class->field.first) && (idx < class->field.last)){
+ return &class->fields [idx - class->field.first];
+ }
+ }
+
+ if (!class->parent)
+ return NULL;
+
+ return mono_class_get_field_idx (class->parent, idx);
+}
+
+/**
+ * mono_class_get_field:
+ * @class: the class to lookup the field.
+ * @field_token: the field token
+ *
+ * Returns: A MonoClassField representing the type and offset of
+ * the field, or a NULL value if the field does not belong to this
+ * class.
+ */
+MonoClassField *
+mono_class_get_field (MonoClass *class, guint32 field_token)
+{
+ int idx = mono_metadata_token_index (field_token);
+
+ if (mono_metadata_token_code (field_token) == MONO_TOKEN_MEMBER_REF)
+ g_error ("Unsupported Field Token is a MemberRef, implement me");
+
+ g_assert (mono_metadata_token_code (field_token) == MONO_TOKEN_FIELD_DEF);
+
+ return mono_class_get_field_idx (class, idx - 1);
+}
+
+/**
+ * mono_class_get:
+ * @image: the image where the class resides
+ * @type_token: the token for the class
+ * @at: an optional pointer to return the array element type
+ *
+ * Returns: the MonoClass that represents @type_token in @image
+ */
+MonoClass *
+mono_class_get (MonoImage *image, guint32 type_token)
+{
+ MonoClass *class;
+
+ switch (type_token & 0xff000000){
+ case MONO_TOKEN_TYPE_DEF:
+ if ((class = g_hash_table_lookup (image->class_cache,
+ GUINT_TO_POINTER (type_token))))
+ return class;
+
+ class = mono_class_create_from_typedef (image, type_token);
+ break;
+
+ case MONO_TOKEN_TYPE_REF: {
+ typedef_from_typeref (image, type_token, &image, &type_token);
+ return mono_class_get (image, type_token);
+ }
+ case MONO_TOKEN_TYPE_SPEC:
+ if ((class = g_hash_table_lookup (image->class_cache,
+ GUINT_TO_POINTER (type_token))))
+ return class;
+
+ class = mono_class_create_from_typespec (image, type_token);
+ break;
+ default:
+ g_assert_not_reached ();
+ }
+
+ g_hash_table_insert (image->class_cache, GUINT_TO_POINTER (type_token), class);
+
+ return class;
+}
+
+guint32
+mono_class_token_from_name (MonoImage *image, const char* name_space, const char *name)
+{
+ GHashTable *nspace_table;
+ guint32 token;
+
+ nspace_table = g_hash_table_lookup (image->name_cache, name_space);
+ if (!nspace_table)
+ return 0;
+ token = GPOINTER_TO_UINT (g_hash_table_lookup (nspace_table, name));
+ if (!token)
+ return 0;
+ return MONO_TOKEN_TYPE_DEF | token;
+}
+
+/**
+ * mono_array_element_size:
+ * @ac: pointer to a #MonoArrayClass
+ *
+ * Returns: the size of single array element.
+ */
+gint32
+mono_array_element_size (MonoArrayClass *ac)
+{
+ gint32 esize;
+
+ esize = ac->element_class->instance_size;
+
+ if (ac->element_class->valuetype)
+ esize -= sizeof (MonoObject);
+
+ return esize;
+}
diff --git a/mono/metadata/class.h b/mono/metadata/class.h
new file mode 100644
index 00000000000..1c2fabeadfc
--- /dev/null
+++ b/mono/metadata/class.h
@@ -0,0 +1,76 @@
+#ifndef _MONO_CLI_CLASS_H_
+#define _MONO_CLI_CLASS_H_
+
+#include <mono/metadata/metadata.h>
+#include <mono/metadata/image.h>
+#include <mono/metadata/loader.h>
+
+#define MONO_CLASS_IS_ARRAY(c) (c->type_token == 0)
+
+typedef struct {
+ MonoFieldType *type;
+ int offset;
+ guint32 flags;
+} MonoClassField;
+
+struct _MonoClass {
+ MonoImage *image;
+ guint32 type_token;
+
+ guint inited : 1;
+ guint valuetype : 1; /* derives from System.ValueType */
+
+ MonoClass *parent;
+
+ const char *name;
+ const char *name_space;
+
+ /*
+ * Computed object instance size, total.
+ */
+ int instance_size;
+ int class_size;
+
+ /*
+ * From the TypeDef table
+ */
+ guint32 flags;
+ struct {
+ guint32 first, last;
+ int count;
+ } field, method;
+
+ /*
+ * Field information: Type and location from object base
+ */
+ MonoClassField *fields;
+
+ MonoMethod **methods;
+
+ /*
+ * After the methods, there is room for the static fields...
+ */
+};
+
+typedef struct {
+ MonoClass class;
+ MonoClass *element_class; /* element class */
+ guint32 rank; /* array dimension */
+} MonoArrayClass;
+
+MonoClass *
+mono_class_get (MonoImage *image, guint32 type_token);
+
+guint32
+mono_class_token_from_name (MonoImage *image, const char* name_space, const char *name);
+
+MonoClass *
+mono_array_class_get (MonoImage *image, guint32 etype, guint32 rank);
+
+MonoClassField *
+mono_class_get_field (MonoClass *class, guint32 field_token);
+
+gint32
+mono_array_element_size (MonoArrayClass *ac);
+
+#endif /* _MONO_CLI_CLASS_H_ */
diff --git a/mono/metadata/endian.h b/mono/metadata/endian.h
new file mode 100644
index 00000000000..8da0e4126e0
--- /dev/null
+++ b/mono/metadata/endian.h
@@ -0,0 +1,13 @@
+#ifndef _MONO_METADATA_ENDIAN_H_
+#define _MONO_METADATA_ENDIAN_H_ 1
+
+/* FIXME: implement big endian versions */
+
+#define le64_to_cpu(x) (x)
+#define le32_to_cpu(x) (x)
+#define le16_to_cpu(x) (x)
+#define read32(x) le32_to_cpu (*((guint32 *) (x)))
+#define read16(x) le16_to_cpu (*((guint16 *) (x)))
+#define read64(x) le64_to_cpu (*((guint64 *) (x)))
+
+#endif /* _MONO_METADATA_ENDIAN_H_ */
diff --git a/mono/metadata/icall.c b/mono/metadata/icall.c
new file mode 100644
index 00000000000..fbddc8cb02e
--- /dev/null
+++ b/mono/metadata/icall.c
@@ -0,0 +1,287 @@
+/*
+ * icall.c:
+ *
+ * Authors:
+ * Dietmar Maurer (dietmar@ximian.com)
+ *
+ * (C) 2001 Ximian, Inc.
+ */
+
+#include <config.h>
+#include <glib.h>
+
+#include <mono/metadata/loader.h>
+
+#include "interp.h"
+
+static void
+ves_icall_array_Set (MonoInvocation *frame)
+{
+ stackval *sp = frame->stack_args;
+ MonoObject *o;
+ MonoArrayObject *ao;
+ MonoArrayClass *ac;
+ gint32 i, t, pos, esize;
+ gpointer ea;
+
+ o = frame->obj;
+ ao = (MonoArrayObject *)o;
+ ac = (MonoArrayClass *)o->klass;
+
+ g_assert (ac->rank >= 1);
+
+ pos = sp [0].data.i - ao->bounds [0].lower_bound;
+ for (i = 1; i < ac->rank; i++) {
+ if ((t = sp [i].data.i - ao->bounds [i].lower_bound) >=
+ ao->bounds [i].length) {
+ g_warning ("wrong array index");
+ g_assert_not_reached ();
+ }
+ pos = pos*ao->bounds [i].length + sp [i].data.i -
+ ao->bounds [i].lower_bound;
+ }
+
+ esize = mono_array_element_size (ac);
+ ea = ao->vector + (pos * esize);
+ memcpy (ea, &sp [ac->rank].data.p, esize);
+}
+
+static void
+ves_icall_array_Get (MonoInvocation *frame)
+{
+ stackval *sp = frame->stack_args;
+ MonoObject *o;
+ MonoArrayObject *ao;
+ MonoArrayClass *ac;
+ gint32 i, pos, esize;
+ gpointer ea;
+
+ o = frame->obj;
+ ao = (MonoArrayObject *)o;
+ ac = (MonoArrayClass *)o->klass;
+
+ g_assert (ac->rank >= 1);
+
+ pos = sp [0].data.i - ao->bounds [0].lower_bound;
+ for (i = 1; i < ac->rank; i++)
+ pos = pos*ao->bounds [i].length + sp [i].data.i -
+ ao->bounds [i].lower_bound;
+
+ esize = mono_array_element_size (ac);
+ ea = ao->vector + (pos * esize);
+
+ frame->retval->type = VAL_I32; /* fixme: not really true */
+ memcpy (&frame->retval->data.p, ea, esize);
+}
+
+static void
+ves_icall_System_Array_GetValue (MonoInvocation *frame)
+{
+ stackval *sp = frame->stack_args;
+ MonoArrayObject *ao, *io;
+ MonoArrayClass *ac, *ic;
+ gint32 i, pos, *ind, esize;
+ gpointer *ea;
+
+ g_assert (sp [0].type == VAL_OBJ); /* expect an array of integers */
+
+ io = sp [0].data.p;
+ ic = (MonoArrayClass *)io->obj.klass;
+
+ ao = (MonoArrayObject *)frame->obj;
+ ac = (MonoArrayClass *)ao->obj.klass;
+
+ g_assert (ic->rank == 1);
+ g_assert (io->bounds [0].length == ac->rank);
+
+ ind = (guint32 *)io->vector;
+
+ pos = ind [0] - ao->bounds [0].lower_bound;
+ for (i = 1; i < ac->rank; i++)
+ pos = pos*ao->bounds [i].length + ind [i] -
+ ao->bounds [i].lower_bound;
+
+ esize = mono_array_element_size (ac);
+ ea = ao->vector + (pos * esize);
+
+ frame->retval->type = VAL_OBJ;
+
+ if (ac->element_class->valuetype)
+ frame->retval->data.p = mono_value_box (ac->element_class, ea);
+ else
+ frame->retval->data.p = ea;
+}
+
+static void
+ves_icall_System_Array_SetValue (MonoInvocation *frame)
+{
+ stackval *sp = frame->stack_args;
+ MonoArrayObject *ao, *io, *vo;
+ MonoArrayClass *ac, *ic, *vc;
+ gint32 i, pos, *ind, esize;
+ gpointer *ea;
+
+ g_assert (sp [0].type == VAL_OBJ); /* the value object */
+ g_assert (sp [1].type == VAL_OBJ); /* expect an array of integers */
+
+ vo = sp [0].data.p;
+ vc = (MonoArrayClass *)vo->obj.klass;
+
+ io = sp [1].data.p;
+ ic = (MonoArrayClass *)io->obj.klass;
+
+ ao = (MonoArrayObject *)frame->obj;
+ ac = (MonoArrayClass *)ao->obj.klass;
+
+ g_assert (ic->rank == 1);
+ g_assert (io->bounds [0].length == ac->rank);
+
+ g_assert (ac->element_class == vo->obj.klass);
+
+ ind = (guint32 *)io->vector;
+
+ pos = ind [0] - ao->bounds [0].lower_bound;
+ for (i = 1; i < ac->rank; i++)
+ pos = pos*ao->bounds [i].length + ind [i] -
+ ao->bounds [i].lower_bound;
+
+ esize = mono_array_element_size (ac);
+ ea = ao->vector + (pos * esize);
+
+ if (ac->element_class->valuetype) {
+ g_assert (vc->class.valuetype);
+
+ memcpy (ea, (char *)vo + sizeof (MonoObject), esize);
+ } else
+ ea = (gpointer)vo;
+}
+
+static void
+ves_icall_array_ctor (MonoInvocation *frame)
+{
+ stackval *sp = frame->stack_args;
+ MonoObject *o;
+ MonoArrayObject *ao;
+ MonoArrayClass *ac;
+ gint32 i, len, esize;
+
+ o = frame->obj;
+ ao = (MonoArrayObject *)o;
+ ac = (MonoArrayClass *)o->klass;
+
+ g_assert (ac->rank >= 1);
+
+ len = sp [0].data.i;
+ for (i = 1; i < ac->rank; i++)
+ len *= sp [i].data.i;
+
+ esize = mono_array_element_size (ac);
+ ao->vector = g_malloc0 (len * esize);
+ ao->bounds = g_malloc0 (ac->rank * sizeof (MonoArrayBounds));
+
+ for (i = 0; i < ac->rank; i++)
+ ao->bounds [i].length = sp [i].data.i;
+}
+
+static void
+ves_icall_array_bound_ctor (MonoInvocation *frame)
+{
+ MonoObject *o;
+ MonoArrayClass *ac;
+
+ o = frame->obj;
+ ac = (MonoArrayClass *)o->klass;
+
+ g_warning ("experimental implementation");
+ g_assert_not_reached ();
+}
+
+static void
+ves_icall_System_Array_CreateInstance (MonoInvocation *frame)
+{
+ g_warning ("not implemented");
+ g_assert_not_reached ();
+}
+
+static void
+ves_icall_System_Array_GetRank (MonoInvocation *frame)
+{
+ MonoObject *o;
+
+ o = frame->obj;
+
+ frame->retval->data.i = ((MonoArrayClass *)o->klass)->rank;
+ frame->retval->type = VAL_I32;
+}
+
+static void
+ves_icall_System_Array_GetLength (MonoInvocation *frame)
+{
+ stackval *sp = frame->stack_args;
+ MonoObject *o;
+
+ o = frame->obj;
+
+ frame->retval->data.i = ((MonoArrayObject *)o)->bounds [sp [0].data.i].length;
+ frame->retval->type = VAL_I32;
+}
+
+static void
+ves_icall_System_Array_GetLowerBound (MonoInvocation *frame)
+{
+ stackval *sp = frame->stack_args;
+ MonoArrayObject *ao;
+
+ ao = (MonoArrayObject *)frame->obj;
+
+ frame->retval->data.i = ao->bounds [sp [0].data.i].lower_bound;
+ frame->retval->type = VAL_I32;
+}
+
+static void
+ves_icall_System_Object_MemberwiseClone (MonoInvocation *frame)
+{
+ frame->retval->type = VAL_OBJ;
+ frame->retval->data.p = mono_object_clone (frame->obj);
+}
+
+static gpointer icall_map [] = {
+ /*
+ * System.Array
+ */
+ "__array_Set", ves_icall_array_Set,
+ "__array_Get", ves_icall_array_Get,
+ "__array_ctor", ves_icall_array_ctor,
+ "__array_bound_ctor", ves_icall_array_bound_ctor,
+ "System.Array::GetValue", ves_icall_System_Array_GetValue,
+ "System.Array::SetValue", ves_icall_System_Array_SetValue,
+ "System.Array::GetRank", ves_icall_System_Array_GetRank,
+ "System.Array::GetLength", ves_icall_System_Array_GetLength,
+ "System.Array::GetLowerBound", ves_icall_System_Array_GetLowerBound,
+ "System.Array::CreateInstance", ves_icall_System_Array_CreateInstance,
+
+ /*
+ * System.Object
+ */
+ "System.Object::MemberwiseClone", ves_icall_System_Object_MemberwiseClone,
+
+ /*
+ * add other internal calls here
+ */
+ NULL, NULL
+};
+
+void
+mono_init_icall ()
+{
+ char *n;
+ int i = 0;
+
+ while ((n = icall_map [i])) {
+ mono_add_internal_call (n, icall_map [i+1]);
+ i += 2;
+ }
+
+}
+
+
diff --git a/mono/metadata/image.c b/mono/metadata/image.c
new file mode 100644
index 00000000000..b2412859acc
--- /dev/null
+++ b/mono/metadata/image.c
@@ -0,0 +1,532 @@
+/*
+ * image.c: Routines for manipulating an image stored in an
+ * extended PE/COFF file.
+ *
+ * Author:
+ * Miguel de Icaza (miguel@ximian.com)
+ *
+ * (C) 2001 Ximian, Inc. http://www.ximian.com
+ *
+ * TODO:
+ * Implement big-endian versions of the reading routines.
+ */
+#include <config.h>
+#include <stdio.h>
+#include <glib.h>
+#include <errno.h>
+#include <string.h>
+#include "image.h"
+#include "cil-coff.h"
+#include "rawbuffer.h"
+#include "endian.h"
+#include "private.h"
+
+#define INVALID_ADDRESS 0xffffffff
+
+/*
+ * Keeps track of the various assemblies loaded
+ */
+static GHashTable *loaded_images_hash;
+
+guint32
+mono_cli_rva_image_map (MonoCLIImageInfo *iinfo, guint32 addr)
+{
+ const int top = iinfo->cli_section_count;
+ MonoSectionTable *tables = iinfo->cli_section_tables;
+ int i;
+
+ for (i = 0; i < top; i++){
+ if ((addr >= tables->st_virtual_address) &&
+ (addr < tables->st_virtual_address + tables->st_raw_data_size)){
+ return addr - tables->st_virtual_address + tables->st_raw_data_ptr;
+ }
+ tables++;
+ }
+ return INVALID_ADDRESS;
+}
+
+char *
+mono_cli_rva_map (MonoCLIImageInfo *iinfo, guint32 addr)
+{
+ const int top = iinfo->cli_section_count;
+ MonoSectionTable *tables = iinfo->cli_section_tables;
+ int i;
+
+ for (i = 0; i < top; i++){
+ if ((addr >= tables->st_virtual_address) &&
+ (addr < tables->st_virtual_address + tables->st_raw_data_size)){
+ return iinfo->cli_sections [i] +
+ (addr - tables->st_virtual_address);
+ }
+ tables++;
+ }
+ return NULL;
+}
+
+/**
+ * mono_image_ensure_section_idx:
+ * @image: The image we are operating on
+ * @section: section number that we will load/map into memory
+ *
+ * This routine makes sure that we have an in-memory copy of
+ * an image section (.text, .rsrc, .data).
+ *
+ * Returns: TRUE on success
+ */
+int
+mono_image_ensure_section_idx (MonoImage *image, int section)
+{
+ MonoCLIImageInfo *iinfo = image->image_info;
+ MonoSectionTable *sect;
+ gboolean writable;
+
+ g_return_val_if_fail (section < iinfo->cli_section_count, FALSE);
+
+ if (iinfo->cli_sections [section] != NULL)
+ return TRUE;
+
+ sect = &iinfo->cli_section_tables [section];
+
+ writable = sect->st_flags & SECT_FLAGS_MEM_WRITE;
+
+ iinfo->cli_sections [section] = mono_raw_buffer_load (
+ fileno (image->f), writable,
+ sect->st_raw_data_ptr, sect->st_raw_data_size);
+
+ if (iinfo->cli_sections [section] == NULL)
+ return FALSE;
+
+ return TRUE;
+}
+
+/**
+ * mono_image_ensure_section:
+ * @image: The image we are operating on
+ * @section: section name that we will load/map into memory
+ *
+ * This routine makes sure that we have an in-memory copy of
+ * an image section (.text, .rsrc, .data).
+ *
+ * Returns: TRUE on success
+ */
+int
+mono_image_ensure_section (MonoImage *image, const char *section)
+{
+ MonoCLIImageInfo *ii = image->image_info;
+ int i;
+
+ for (i = 0; i < ii->cli_section_count; i++){
+ if (strncmp (ii->cli_section_tables [i].st_name, section, 8) != 0)
+ continue;
+
+ return mono_image_ensure_section_idx (image, i);
+ }
+ return FALSE;
+}
+
+static int
+load_section_tables (MonoImage *image, MonoCLIImageInfo *iinfo)
+{
+ const int top = iinfo->cli_header.coff.coff_sections;
+ int i;
+
+ iinfo->cli_section_count = top;
+ iinfo->cli_section_tables = g_new0 (MonoSectionTable, top);
+ iinfo->cli_sections = g_new0 (void *, top);
+
+ for (i = 0; i < top; i++){
+ MonoSectionTable *t = &iinfo->cli_section_tables [i];
+
+ if (fread (t, sizeof (MonoSectionTable), 1, image->f) != 1)
+ return FALSE;
+
+ t->st_virtual_size = le32_to_cpu (t->st_virtual_size);
+ t->st_virtual_address = le32_to_cpu (t->st_virtual_address);
+ t->st_raw_data_size = le32_to_cpu (t->st_raw_data_size);
+ t->st_raw_data_ptr = le32_to_cpu (t->st_raw_data_ptr);
+ t->st_reloc_ptr = le32_to_cpu (t->st_reloc_ptr);
+ t->st_lineno_ptr = le32_to_cpu (t->st_lineno_ptr);
+ t->st_reloc_count = le16_to_cpu (t->st_reloc_count);
+ t->st_line_count = le16_to_cpu (t->st_line_count);
+
+ /* consistency checks here */
+ }
+
+ for (i = 0; i < top; i++)
+ if (!mono_image_ensure_section_idx (image, i))
+ return FALSE;
+
+ return TRUE;
+}
+
+static gboolean
+load_cli_header (MonoImage *image, MonoCLIImageInfo *iinfo)
+{
+ guint32 offset;
+ int n;
+
+ offset = mono_cli_rva_image_map (iinfo, iinfo->cli_header.datadir.pe_cli_header.rva);
+ if (offset == INVALID_ADDRESS)
+ return FALSE;
+
+ if (fseek (image->f, offset, 0) != 0)
+ return FALSE;
+
+ if ((n = fread (&iinfo->cli_cli_header, sizeof (MonoCLIHeader), 1, image->f)) != 1)
+ return FALSE;
+
+ /* Catch new uses of the fields that are supposed to be zero */
+
+ if ((iinfo->cli_cli_header.ch_eeinfo_table.rva != 0) ||
+ (iinfo->cli_cli_header.ch_helper_table.rva != 0) ||
+ (iinfo->cli_cli_header.ch_dynamic_info.rva != 0) ||
+ (iinfo->cli_cli_header.ch_delay_load_info.rva != 0) ||
+ (iinfo->cli_cli_header.ch_module_image.rva != 0) ||
+ (iinfo->cli_cli_header.ch_external_fixups.rva != 0) ||
+ (iinfo->cli_cli_header.ch_ridmap.rva != 0) ||
+ (iinfo->cli_cli_header.ch_debug_map.rva != 0) ||
+ (iinfo->cli_cli_header.ch_ip_map.rva != 0)){
+
+ /*
+ * No need to scare people who are testing this, I am just
+ * labelling this as a LAMESPEC
+ */
+ /* g_warning ("Some fields in the CLI header which should have been zero are not zero"); */
+
+ }
+
+ return TRUE;
+}
+
+static gboolean
+load_metadata_ptrs (MonoImage *image, MonoCLIImageInfo *iinfo)
+{
+ guint32 offset, size;
+ guint16 streams;
+ int i;
+ char *ptr;
+
+ offset = mono_cli_rva_image_map (iinfo, iinfo->cli_cli_header.ch_metadata.rva);
+ size = iinfo->cli_cli_header.ch_metadata.size;
+
+ image->raw_metadata = mono_raw_buffer_load (fileno (image->f), FALSE, offset, size);
+ if (image->raw_metadata == NULL)
+ return FALSE;
+
+ ptr = image->raw_metadata;
+
+ if (strncmp (ptr, "BSJB", 4) == 0){
+ guint32 version_string_len;
+
+ ptr += 12;
+ version_string_len = read32 (ptr);
+ ptr += 4;
+ ptr += version_string_len;
+ if (((guint32) ptr) % 4)
+ ptr += 4 - (((guint32) ptr) %4);
+ } else
+ return FALSE;
+
+ /* skip over flags */
+ ptr += 2;
+
+ streams = read16 (ptr);
+ ptr += 2;
+
+ for (i = 0; i < streams; i++){
+ if (strncmp (ptr + 8, "#~", 3) == 0){
+ image->heap_tables.offset = read32 (ptr);
+ image->heap_tables.size = read32 (ptr + 4);
+ ptr += 8 + 3;
+ } else if (strncmp (ptr + 8, "#Strings", 9) == 0){
+ image->heap_strings.offset = read32 (ptr);
+ image->heap_strings.size = read32 (ptr + 4);
+ ptr += 8 + 9;
+ } else if (strncmp (ptr + 8, "#US", 4) == 0){
+ image->heap_us.offset = read32 (ptr);
+ image->heap_us.size = read32 (ptr + 4);
+ ptr += 8 + 4;
+ } else if (strncmp (ptr + 8, "#Blob", 6) == 0){
+ image->heap_blob.offset = read32 (ptr);
+ image->heap_blob.size = read32 (ptr + 4);
+ ptr += 8 + 6;
+ } else if (strncmp (ptr + 8, "#GUID", 6) == 0){
+ image->heap_guid.offset = read32 (ptr);
+ image->heap_guid.size = read32 (ptr + 4);
+ ptr += 8 + 6;
+ } else
+ g_message ("Unknown heap type: %s\n", ptr + 8);
+ if (((guint32)ptr) % 4){
+ ptr += 4 - (((guint32)ptr) % 4);
+ }
+ }
+ return TRUE;
+}
+
+/*
+ * Load representation of logical metadata tables, from the "#~" stream
+ */
+static gboolean
+load_tables (MonoImage *image)
+{
+ char *heap_tables = image->raw_metadata + image->heap_tables.offset;
+ guint32 *rows;
+ guint64 valid_mask;
+ int valid = 0, table;
+ int heap_sizes;
+
+ heap_sizes = heap_tables [6];
+ image->idx_string_wide = ((heap_sizes & 0x01) == 1);
+ image->idx_guid_wide = ((heap_sizes & 0x02) == 2);
+ image->idx_blob_wide = ((heap_sizes & 0x04) == 4);
+
+ valid_mask = read64 (heap_tables + 8);
+ rows = (guint32 *) (heap_tables + 24);
+
+ for (table = 0; table < 64; table++){
+ if ((valid_mask & ((guint64) 1 << table)) == 0){
+ image->tables [table].rows = 0;
+ continue;
+ }
+ if (table > 0x2b) {
+ g_warning("bits in valid must be zero above 0x2b (II - 23.1.6)");
+ }
+ image->tables [table].rows = read32 (rows);
+ rows++;
+ valid++;
+ }
+
+ image->tables_base = (heap_tables + 24) + (4 * valid);
+
+ /* They must be the same */
+ g_assert ((void *) image->tables_base == (void *) rows);
+
+ mono_metadata_compute_table_bases (image);
+ return TRUE;
+}
+
+static gboolean
+load_metadata (MonoImage *image, MonoCLIImageInfo *iinfo)
+{
+ if (!load_metadata_ptrs (image, iinfo))
+ return FALSE;
+
+ return load_tables (image);
+}
+
+static void
+load_class_names (MonoImage *image) {
+ MonoTableInfo *t = &image->tables [MONO_TABLE_TYPEDEF];
+ guint32 cols [MONO_TYPEDEF_SIZE];
+ const char* name;
+ const char *nspace;
+ GHashTable *nspace_table;
+ GHashTable *name_cache = image->name_cache;
+ guint32 i;
+
+ for (i = 1; i <= t->rows; ++i) {
+ mono_metadata_decode_row (t, i - 1, cols, MONO_TYPEDEF_SIZE);
+ name = mono_metadata_string_heap (image, cols [MONO_TYPEDEF_NAME]);
+ nspace = mono_metadata_string_heap (image, cols [MONO_TYPEDEF_NAMESPACE]);
+ if (!(nspace_table = g_hash_table_lookup (name_cache, nspace))) {
+ nspace_table = g_hash_table_new (g_str_hash, g_str_equal);
+ g_hash_table_insert (name_cache, nspace, nspace_table);
+ }
+ g_hash_table_insert (nspace_table, name, GUINT_TO_POINTER (i));
+ }
+}
+
+static MonoImage *
+do_mono_image_open (const char *fname, enum MonoImageOpenStatus *status)
+{
+ MonoCLIImageInfo *iinfo;
+ MonoDotNetHeader *header;
+ MonoMSDOSHeader msdos;
+ MonoImage *image;
+ int n;
+
+ image = g_new0 (MonoImage, 1);
+ image->f = fopen (fname, "r");
+ image->name = g_strdup (fname);
+ iinfo = g_new0 (MonoCLIImageInfo, 1);
+ image->image_info = iinfo;
+
+ image->method_cache = g_hash_table_new (g_direct_hash, g_direct_equal);
+ image->class_cache = g_hash_table_new (g_direct_hash, g_direct_equal);
+ image->name_cache = g_hash_table_new (g_str_hash, g_str_equal);
+ image->array_cache = g_hash_table_new (g_direct_hash, g_direct_equal);
+
+ header = &iinfo->cli_header;
+
+ if (image->f == NULL){
+ if (status)
+ *status = MONO_IMAGE_ERROR_ERRNO;
+ mono_image_close (image);
+ return NULL;
+ }
+
+ if (status)
+ *status = MONO_IMAGE_IMAGE_INVALID;
+
+ if (fread (&msdos, sizeof (msdos), 1, image->f) != 1)
+ goto invalid_image;
+
+ if (!(msdos.msdos_header [0] == 'M' && msdos.msdos_header [1] == 'Z'))
+ goto invalid_image;
+
+ if (msdos.pe_offset != sizeof (msdos))
+ fseek (image->f, msdos.pe_offset, SEEK_SET);
+
+ if ((n = fread (header, sizeof (MonoDotNetHeader), 1, image->f)) != 1)
+ goto invalid_image;
+
+ if (header->coff.coff_machine != 0x14c) /* FIXME: ENOENDIAN */
+ goto invalid_image;
+
+ if (header->coff.coff_opt_header_size != (sizeof (MonoDotNetHeader) - sizeof (MonoCOFFHeader) - 4))
+ goto invalid_image;
+
+ if (header->pe.pe_magic != 0x10B) /* FIXME: ENOENDIAN */
+ goto invalid_image;
+
+ if (header->pe.pe_major != 6 || header->pe.pe_minor != 0)
+ goto invalid_image;
+
+ /*
+ * FIXME: byte swap all addresses here for header.
+ */
+
+ if (!load_section_tables (image, iinfo))
+ goto invalid_image;
+
+ /* Load the CLI header */
+ if (!load_cli_header (image, iinfo))
+ goto invalid_image;
+
+ if (!load_metadata (image, iinfo))
+ goto invalid_image;
+
+ load_class_names (image);
+
+ if (status)
+ *status = MONO_IMAGE_OK;
+
+ return image;
+
+invalid_image:
+ mono_image_close (image);
+ return NULL;
+}
+
+/**
+ * mono_image_open:
+ * @fname: filename that points to the module we want to open
+ * @status: An error condition is returned in this field
+ *
+ * Retuns: An open image of type %MonoImage or NULL on error.
+ * if NULL, then check the value of @status for details on the error
+ */
+MonoImage *
+mono_image_open (const char *fname, enum MonoImageOpenStatus *status)
+{
+ MonoImage *image;
+
+ g_return_val_if_fail (fname != NULL, NULL);
+
+ if (loaded_images_hash){
+ image = g_hash_table_lookup (loaded_images_hash, fname);
+ if (image){
+ image->ref_count++;
+ return image;
+ }
+ }
+
+ image = do_mono_image_open (fname, status);
+ if (image == NULL)
+ return NULL;
+
+ if (!loaded_images_hash)
+ loaded_images_hash = g_hash_table_new (g_str_hash, g_str_equal);
+ g_hash_table_insert (loaded_images_hash, image->name, image);
+
+ return image;
+}
+
+static void
+free_hash_table(gpointer key, gpointer val, gpointer user_data)
+{
+ g_hash_table_destroy ((GHashTable*)val);
+}
+
+/**
+ * mono_image_close:
+ * @image: The image file we wish to close
+ *
+ * Closes an image file, deallocates all memory consumed and
+ * unmaps all possible sections of the file
+ */
+void
+mono_image_close (MonoImage *image)
+{
+ g_return_if_fail (image != NULL);
+
+ if (--image->ref_count)
+ return;
+
+ g_hash_table_remove (loaded_images_hash, image->name);
+
+ if (image->f)
+ fclose (image->f);
+
+ g_free (image->name);
+
+ g_hash_table_destroy (image->method_cache);
+ g_hash_table_destroy (image->class_cache);
+ g_hash_table_destroy (image->array_cache);
+ g_hash_table_foreach (image->name_cache, free_hash_table, NULL);
+ g_hash_table_destroy (image->name_cache);
+
+ if (image->raw_metadata != NULL)
+ mono_raw_buffer_free (image->raw_metadata);
+
+ if (image->image_info){
+ MonoCLIImageInfo *ii = image->image_info;
+ int i;
+
+ for (i = 0; i < ii->cli_section_count; i++){
+ if (!ii->cli_sections [i])
+ continue;
+ mono_raw_buffer_free (ii->cli_sections [i]);
+ }
+ if (ii->cli_section_tables)
+ g_free (ii->cli_section_tables);
+ if (ii->cli_sections)
+ g_free (ii->cli_sections);
+ g_free (image->image_info);
+ }
+
+ g_free (image);
+}
+
+/**
+ * mono_image_strerror:
+ * @status: an code indicating the result from a recent operation
+ *
+ * Returns: a string describing the error
+ */
+const char *
+mono_image_strerror (enum MonoImageOpenStatus status)
+{
+ switch (status){
+ case MONO_IMAGE_OK:
+ return "success";
+ case MONO_IMAGE_ERROR_ERRNO:
+ return strerror (errno);
+ case MONO_IMAGE_IMAGE_INVALID:
+ return "File does not contain a valid CIL image";
+ case MONO_IMAGE_MISSING_ASSEMBLYREF:
+ return "An assembly was referenced, but could not be found";
+ }
+ return "Internal error";
+}
+
diff --git a/mono/metadata/image.h b/mono/metadata/image.h
new file mode 100644
index 00000000000..8b9dbf9a7d3
--- /dev/null
+++ b/mono/metadata/image.h
@@ -0,0 +1,106 @@
+#ifndef _MONONET_METADATA_IMAGE_H_
+#define _MONONET_METADATA_IMAGE_H_
+
+#include <stdio.h>
+#include <glib.h>
+
+typedef struct _MonoImage MonoImage;
+typedef struct _MonoImage MonoMetadata;
+
+typedef struct {
+ MonoImage *image;
+ /* Load files here */
+} MonoAssembly;
+
+typedef struct {
+ guint32 offset;
+ guint32 size;
+} MonoStreamHeader;
+
+typedef struct {
+ guint32 rows, row_size;
+ char *base;
+
+ /*
+ * Tables contain up to 9 rows and the possible sizes of the
+ * fields in the documentation are 1, 2 and 4 bytes. So we
+ * can encode in 2 bits the size.
+ *
+ * A 32 bit value can encode the resulting size
+ *
+ * The top eight bits encode the number of columns in the table.
+ * we only need 4, but 8 is aligned no shift required.
+ */
+ guint32 size_bitfield;
+} MonoTableInfo;
+
+struct _MonoImage {
+ int ref_count;
+ FILE *f;
+ char *name;
+ void *image_info;
+
+ char *raw_metadata;
+
+ gboolean idx_string_wide, idx_guid_wide, idx_blob_wide;
+
+ MonoStreamHeader heap_strings;
+ MonoStreamHeader heap_us;
+ MonoStreamHeader heap_blob;
+ MonoStreamHeader heap_guid;
+ MonoStreamHeader heap_tables;
+
+ char *tables_base;
+
+ MonoTableInfo tables [64];
+
+ /*
+ * references is initialized only by using the mono_assembly_open
+ * function, and not by using the lowlevel mono_image_open.
+ *
+ * It is NULL terminated.
+ */
+ MonoAssembly **references;
+
+ /*
+ * Indexed by method tokens and typedef tokens.
+ */
+ GHashTable *method_cache;
+ GHashTable *class_cache;
+ /*
+ * Indexes namespaces to hash tables that map class name to typedef token.
+ */
+ GHashTable *name_cache;
+
+ /*
+ * Indexed by ((rank << 24) | (typedef & 0xffffff)), which limits us to a
+ * maximal rank of 255
+ */
+ GHashTable *array_cache;
+
+ /*
+ * user_info is a public field and is not touched by the
+ * metadata engine
+ */
+ void *user_info;
+};
+
+enum MonoImageOpenStatus {
+ MONO_IMAGE_OK,
+ MONO_IMAGE_ERROR_ERRNO,
+ MONO_IMAGE_MISSING_ASSEMBLYREF,
+ MONO_IMAGE_IMAGE_INVALID
+};
+
+MonoImage *mono_image_open (const char *fname,
+ enum MonoImageOpenStatus *status);
+void mono_image_close (MonoImage *image);
+const char *mono_image_strerror (enum MonoImageOpenStatus status);
+
+
+int mono_image_ensure_section (MonoImage *image,
+ const char *section);
+int mono_image_ensure_section_idx (MonoImage *image,
+ int section);
+
+#endif
diff --git a/mono/metadata/loader.c b/mono/metadata/loader.c
new file mode 100644
index 00000000000..4b6a6c7dca9
--- /dev/null
+++ b/mono/metadata/loader.c
@@ -0,0 +1,452 @@
+/*
+ * loader.c: Image Loader
+ *
+ * Authors:
+ * Paolo Molaro (lupus@ximian.com)
+ * Miguel de Icaza (miguel@ximian.com)
+ *
+ * (C) 2001 Ximian, Inc.
+ *
+ * This file is used by the interpreter and the JIT engine to locate
+ * assemblies. Used to load AssemblyRef and later to resolve various
+ * kinds of `Refs'.
+ *
+ * TODO:
+ * This should keep track of the assembly versions that we are loading.
+ *
+ */
+#include <config.h>
+#include <glib.h>
+#include <gmodule.h>
+#include <stdio.h>
+#include <string.h>
+#include <mono/metadata/metadata.h>
+#include <mono/metadata/image.h>
+#include <mono/metadata/assembly.h>
+#include <mono/metadata/tokentype.h>
+#include <mono/metadata/cil-coff.h>
+#include <mono/metadata/tabledefs.h>
+#include <mono/metadata/loader.h>
+#include <mono/metadata/class.h>
+
+MonoDefaults mono_defaults;
+
+static char *dll_map[] = {
+ "libc", "libc.so.6",
+ "libm", "libm.so.6",
+ "cygwin1.dll", "libc.so.6",
+ NULL, NULL
+};
+
+static const char *
+mono_map_dll (const char *name)
+{
+ int i = 0;
+
+ while (dll_map [i]) {
+ if (!strcmp (dll_map [i], name))
+ return dll_map [i + 1];
+ i += 2;
+ }
+
+ return name;
+}
+
+void
+mono_init ()
+{
+ static gboolean initialized = FALSE;
+ MonoAssembly *ass;
+ enum MonoImageOpenStatus status = MONO_IMAGE_OK;
+
+ if (initialized)
+ return;
+
+ /* find the corlib */
+ ass = mono_assembly_open (CORLIB_NAME, NULL, &status);
+ g_assert (status == MONO_IMAGE_OK);
+ g_assert (ass != NULL);
+ mono_defaults.corlib = ass->image;
+
+ mono_defaults.array_token = mono_class_token_from_name (
+ mono_defaults.corlib, "System", "Array");
+ g_assert (mono_defaults.array_token != 0);
+
+ mono_defaults.char_token = mono_class_token_from_name (
+ mono_defaults.corlib, "System", "Char");
+ g_assert (mono_defaults.char_token != 0);
+
+ mono_defaults.string_token = mono_class_token_from_name (
+ mono_defaults.corlib, "System", "String");
+
+ g_assert (mono_defaults.string_token != 0);
+
+}
+
+static GHashTable *icall_hash = NULL;
+
+void
+mono_add_internal_call (const char *name, gpointer method)
+{
+ if (!icall_hash)
+ icall_hash = g_hash_table_new (g_str_hash , g_str_equal);
+
+ g_hash_table_insert (icall_hash, g_strdup (name), method);
+}
+
+gpointer
+mono_lookup_internal_call (const char *name)
+{
+ gpointer res;
+
+ if (!icall_hash) {
+ g_warning ("icall_hash not initialized");
+ g_assert_not_reached ();
+ }
+
+ if (!(res = g_hash_table_lookup (icall_hash, name))) {
+ g_warning ("cant resolve internal call to \"%s\"", name);
+ g_assert_not_reached ();
+ }
+
+ return res;
+}
+
+static MonoMethod *
+method_from_memberref (MonoImage *image, guint32 index)
+{
+ MonoImage *mimage;
+ MonoClass *klass;
+ MonoTableInfo *tables = image->tables;
+ guint32 cols[6];
+ guint32 nindex, class, i;
+ const char *mname, *name, *nspace;
+ MonoMethodSignature *sig;
+ const char *ptr;
+
+ mono_metadata_decode_row (&tables [MONO_TABLE_MEMBERREF], index-1, cols, 3);
+ nindex = cols [MONO_MEMBERREF_CLASS] >> MEMBERREF_PARENT_BITS;
+ class = cols [MONO_MEMBERREF_CLASS] & MEMBERREF_PARENT_MASK;
+ /*g_print ("methodref: 0x%x 0x%x %s\n", class, nindex,
+ mono_metadata_string_heap (m, cols [MONO_MEMBERREF_NAME]));*/
+
+ mname = mono_metadata_string_heap (image, cols [MONO_MEMBERREF_NAME]);
+
+ ptr = mono_metadata_blob_heap (image, cols [MONO_MEMBERREF_SIGNATURE]);
+ mono_metadata_decode_blob_size (ptr, &ptr);
+ sig = mono_metadata_parse_method_signature (image, 0, ptr, NULL);
+
+ switch (class) {
+ case MEMBERREF_PARENT_TYPEREF: {
+ guint32 scopeindex, scopetable;
+
+ mono_metadata_decode_row (&tables [MONO_TABLE_TYPEREF], nindex-1, cols, MONO_TYPEREF_SIZE);
+ scopeindex = cols [MONO_TYPEREF_SCOPE] >> RESOLTION_SCOPE_BITS;
+ scopetable = cols [MONO_TYPEREF_SCOPE] & RESOLTION_SCOPE_MASK;
+ /*g_print ("typeref: 0x%x 0x%x %s.%s\n", scopetable, scopeindex,
+ mono_metadata_string_heap (m, cols [MONO_TYPEREF_NAMESPACE]),
+ mono_metadata_string_heap (m, cols [MONO_TYPEREF_NAME]));*/
+ switch (scopetable) {
+ case RESOLTION_SCOPE_ASSEMBLYREF:
+ /*
+ * To find the method we have the following info:
+ * *) name and namespace of the class from the TYPEREF table
+ * *) name and signature of the method from the MEMBERREF table
+ */
+ nspace = mono_metadata_string_heap (image, cols [MONO_TYPEREF_NAMESPACE]);
+ name = mono_metadata_string_heap (image, cols [MONO_TYPEREF_NAME]);
+
+ /* this will triggered by references to mscorlib */
+ g_assert (image->references [scopeindex-1] != NULL);
+
+ mimage = image->references [scopeindex-1]->image;
+
+ i = mono_class_token_from_name (mimage, nspace, name);
+ klass = mono_class_get (mimage, i);
+ /* mostly dumb search for now */
+ for (i = 0; i < klass->method.count; ++i) {
+ MonoMethod *m = klass->methods [i];
+ if (!strcmp (mname, m->name)) {
+ if (mono_metadata_signature_equal (image, sig, mimage, m->signature)) {
+ mono_metadata_free_method_signature (sig);
+ return m;
+ }
+ }
+ }
+ g_warning ("can't find method %s.%s::%s", nspace, name, mname);
+ g_assert_not_reached ();
+ break;
+ default:
+ g_assert_not_reached ();
+ }
+ break;
+ }
+ case MEMBERREF_PARENT_TYPESPEC: {
+ guint32 bcols [MONO_TYPESPEC_SIZE];
+ guint32 len;
+ MonoType *type;
+ MonoMethod *result;
+
+ mono_metadata_decode_row (&tables [MONO_TABLE_TYPESPEC], nindex - 1,
+ bcols, MONO_TYPESPEC_SIZE);
+ ptr = mono_metadata_blob_heap (image, bcols [MONO_TYPESPEC_SIGNATURE]);
+ len = mono_metadata_decode_value (ptr, &ptr);
+ type = mono_metadata_parse_type (image, ptr, &ptr);
+
+ if (type->type != MONO_TYPE_ARRAY)
+ g_assert_not_reached ();
+
+ result = (MonoMethod *)g_new0 (MonoMethod, 1);
+ result->klass = mono_class_get (mono_defaults.corlib, mono_defaults.array_token);
+ result->iflags = METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL;
+ result->signature = sig;
+
+ if (!strcmp (mname, ".ctor")) {
+ g_assert (sig->hasthis);
+ if (type->data.array->rank == sig->param_count) {
+ result->addr = mono_lookup_internal_call ("__array_ctor");
+ return result;
+ } else if ((type->data.array->rank * 2) == sig->param_count) {
+ result->addr = mono_lookup_internal_call ("__array_bound_ctor");
+ return result;
+ } else
+ g_assert_not_reached ();
+ }
+
+ if (!strcmp (mname, "Set")) {
+ g_assert (sig->hasthis);
+ g_assert (type->data.array->rank + 1 == sig->param_count);
+
+ result->addr = mono_lookup_internal_call ("__array_Set");
+ return result;
+ }
+
+ if (!strcmp (mname, "Get")) {
+ g_assert (sig->hasthis);
+ g_assert (type->data.array->rank == sig->param_count);
+
+ result->addr = mono_lookup_internal_call ("__array_Get");
+ return result;
+ }
+
+ g_assert_not_reached ();
+ break;
+ }
+ default:
+ g_assert_not_reached ();
+ }
+
+ return NULL;
+}
+
+static ffi_type *
+ves_map_ffi_type (MonoType *type)
+{
+ ffi_type *rettype;
+
+ switch (type->type) {
+ case MONO_TYPE_I1:
+ rettype = &ffi_type_sint8;
+ break;
+ case MONO_TYPE_BOOLEAN:
+ case MONO_TYPE_U1:
+ rettype = &ffi_type_uint8;
+ break;
+ case MONO_TYPE_I2:
+ rettype = &ffi_type_sint16;
+ break;
+ case MONO_TYPE_U2:
+ case MONO_TYPE_CHAR:
+ rettype = &ffi_type_uint16;
+ break;
+ case MONO_TYPE_I4:
+ rettype = &ffi_type_sint32;
+ break;
+ case MONO_TYPE_U4:
+ rettype = &ffi_type_sint32;
+ break;
+ case MONO_TYPE_R4:
+ rettype = &ffi_type_float;
+ break;
+ case MONO_TYPE_R8:
+ rettype = &ffi_type_double;
+ break;
+ case MONO_TYPE_STRING:
+ rettype = &ffi_type_pointer;
+ break;
+ case MONO_TYPE_VOID:
+ rettype = &ffi_type_void;
+ break;
+ default:
+ g_warning ("not implemented");
+ g_assert_not_reached ();
+ }
+
+ return rettype;
+}
+
+static void
+fill_pinvoke_info (MonoImage *image, MonoMethodPInvoke *piinfo, int index)
+{
+ MonoMethod *mh = &piinfo->method;
+ MonoTableInfo *tables = image->tables;
+ MonoTableInfo *im = &tables [MONO_TABLE_IMPLMAP];
+ MonoTableInfo *mr = &tables [MONO_TABLE_MODULEREF];
+ guint32 im_cols [4];
+ guint32 mr_cols [1];
+ const char *import = NULL;
+ const char *scope = NULL;
+ char *full_name;
+ GModule *gmodule;
+ ffi_type **args, *rettype;
+ int i, acount;
+
+ for (i = 0; i < im->rows; i++) {
+
+ mono_metadata_decode_row (im, i, im_cols, 4);
+
+ if ((im_cols[1] >> 1) == index + 1) {
+
+ import = mono_metadata_string_heap (image, im_cols [2]);
+
+ mono_metadata_decode_row (mr, im_cols [3] - 1, mr_cols,
+ 1);
+
+ scope = mono_metadata_string_heap (image, mr_cols [0]);
+ }
+ }
+
+ g_assert (import && scope);
+
+ scope = mono_map_dll (scope);
+ full_name = g_module_build_path (NULL, scope);
+ gmodule = g_module_open (full_name, G_MODULE_BIND_LAZY);
+ g_free (full_name);
+
+ g_assert (gmodule);
+
+ piinfo->cif = g_new (ffi_cif , 1);
+ piinfo->piflags = im_cols [0];
+
+ g_module_symbol (gmodule, import, &mh->addr);
+
+ g_assert (mh->addr);
+
+ acount = mh->signature->param_count;
+
+ args = g_new (ffi_type *, acount);
+
+ for (i = 0; i < acount; i++)
+ args[i] = ves_map_ffi_type (mh->signature->params [i]->type);
+
+ rettype = ves_map_ffi_type (mh->signature->ret->type);
+
+ if (!ffi_prep_cif (piinfo->cif, FFI_DEFAULT_ABI, acount, rettype,
+ args) == FFI_OK) {
+ g_warning ("prepare pinvoke failed");
+ g_assert_not_reached ();
+ }
+}
+
+MonoMethod *
+mono_get_method (MonoImage *image, guint32 token, MonoClass *klass)
+{
+ MonoMethod *result;
+ int table = mono_metadata_token_table (token);
+ int index = mono_metadata_token_index (token);
+ MonoTableInfo *tables = image->tables;
+ const char *loc, *sig = NULL;
+ char *name;
+ int size;
+ guint32 cols [MONO_TYPEDEF_SIZE];
+
+ if (table == MONO_TABLE_METHOD && (result = g_hash_table_lookup (image->method_cache, GINT_TO_POINTER (token))))
+ return result;
+
+ if (table != MONO_TABLE_METHOD) {
+ g_assert (table == MONO_TABLE_MEMBERREF);
+ return method_from_memberref (image, index);
+ }
+
+ mono_metadata_decode_row (&tables [table], index - 1, cols, 6);
+
+ if (cols [1] & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL) {
+ MonoTableInfo *t = &image->tables [MONO_TABLE_TYPEDEF];
+ MonoAssembly *corlib;
+ guint32 tdef;
+ guint32 tdcols [MONO_TYPEDEF_SIZE];
+
+ tdef = mono_metadata_typedef_from_method (image, index - 1) - 1;
+
+ mono_metadata_decode_row (t, tdef, tdcols, MONO_TYPEDEF_SIZE);
+
+ name = g_strconcat (mono_metadata_string_heap (image, tdcols [MONO_TYPEDEF_NAMESPACE]), ".",
+ mono_metadata_string_heap (image, tdcols [MONO_TYPEDEF_NAME]), "::",
+ mono_metadata_string_heap (image, cols [MONO_METHOD_NAME]), NULL);
+
+ corlib = mono_assembly_open (CORLIB_NAME, NULL, NULL);
+
+ /* all internal calls must be inside corlib */
+ g_assert (corlib->image == image);
+
+ result = (MonoMethod *)g_new0 (MonoMethod, 1);
+
+ result->addr = mono_lookup_internal_call (name);
+
+ g_free (name);
+
+ g_assert (result->addr != NULL);
+
+ } else if (cols [2] & METHOD_ATTRIBUTE_PINVOKE_IMPL) {
+
+ result = (MonoMethod *)g_new0 (MonoMethodPInvoke, 1);
+ } else {
+
+ result = (MonoMethod *)g_new0 (MonoMethodNormal, 1);
+ }
+
+ result->klass = klass;
+ result->flags = cols [2];
+ result->iflags = cols [1];
+ result->name = mono_metadata_string_heap (image, cols [3]);
+
+ if (!sig) /* already taken from the methodref */
+ sig = mono_metadata_blob_heap (image, cols [4]);
+ size = mono_metadata_decode_blob_size (sig, &sig);
+ result->signature = mono_metadata_parse_method_signature (image, 0, sig, NULL);
+
+ if (result->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL) {
+ fill_pinvoke_info (image, (MonoMethodPInvoke *)result,
+ index - 1);
+ } else if (!(result->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL)) {
+ /* if this is a methodref from another module/assembly, this fails */
+ loc = mono_cli_rva_map ((MonoCLIImageInfo *)image->image_info, cols [0]);
+ g_assert (loc);
+ if (!result->klass) {
+ guint32 type = mono_metadata_typedef_from_method (image, token);
+ result->klass = mono_class_get (image, MONO_TOKEN_TYPE_DEF | type);
+ }
+ ((MonoMethodNormal *)result)->header =
+ mono_metadata_parse_mh (image, loc);
+ }
+
+ g_hash_table_insert (image->method_cache, GINT_TO_POINTER (token), result);
+
+ return result;
+}
+
+void
+mono_free_method (MonoMethod *method)
+{
+ mono_metadata_free_method_signature (method->signature);
+ if (method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL) {
+ MonoMethodPInvoke *piinfo = (MonoMethodPInvoke *)method;
+ g_free (piinfo->cif->arg_types);
+ g_free (piinfo->cif);
+ } else if (!(method->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL)) {
+ mono_metadata_free_mh (((MonoMethodNormal *)method)->header);
+ }
+
+ g_free (method);
+}
+
diff --git a/mono/metadata/loader.h b/mono/metadata/loader.h
new file mode 100644
index 00000000000..29ffca190bf
--- /dev/null
+++ b/mono/metadata/loader.h
@@ -0,0 +1,58 @@
+#ifndef _MONO_METADATA_LOADER_H_
+#define _MONO_METADATA_LOADER_H_ 1
+
+#include <ffi.h>
+#include <mono/metadata/metadata.h>
+#include <mono/metadata/image.h>
+
+typedef struct _MonoClass MonoClass;
+
+typedef struct {
+ guint16 flags; /* method flags */
+ guint16 iflags; /* method implementation flags */
+ MonoClass *klass;
+ MonoMethodSignature *signature;
+ gpointer addr;
+ /* name is useful mostly for debugging */
+ const char *name;
+} MonoMethod;
+
+typedef struct {
+ MonoMethod method;
+ MonoMethodHeader *header;
+} MonoMethodNormal;
+
+typedef struct {
+ MonoMethod method;
+ guint16 piflags; /* pinvoke flags */
+ ffi_cif *cif;
+} MonoMethodPInvoke;
+
+typedef struct {
+ MonoImage *corlib;
+ guint32 array_token;
+ guint32 string_token;
+ guint32 char_token;
+} MonoDefaults;
+
+extern MonoDefaults mono_defaults;
+
+void
+mono_init (void);
+
+MonoMethod *
+mono_get_method (MonoImage *image, guint32 token, MonoClass *klass);
+
+void
+mono_free_method (MonoMethod *method);
+
+MonoImage *
+mono_load_image (const char *fname, enum MonoImageOpenStatus *status);
+
+void
+mono_add_internal_call (const char *name, gpointer method);
+
+gpointer
+mono_lookup_internal_call (const char *name);
+
+#endif
diff --git a/mono/metadata/metadata.c b/mono/metadata/metadata.c
index 02db6e5c04b..a92aceb1ab3 100644
--- a/mono/metadata/metadata.c
+++ b/mono/metadata/metadata.c
@@ -8,6 +8,1787 @@
*/
#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
#include <glib.h>
#include "metadata.h"
+#include "tabledefs.h"
+#include "endian.h"
+#include "cil-coff.h"
+#include "tokentype.h"
+#include "private.h"
+
+/*
+ * Encoding of the "description" argument:
+ *
+ * identifier [CODE ARG]
+ *
+ * If CODE is ':', then a lookup on table ARG is performed
+ * If CODE is '=', then a lookup in the aliased-table ARG is performed
+ * If CODE is '#', then this encodes a flag, ARG is the flag name.
+ *
+ * Aliased table for example is `CustomAttributeType' which depending on the
+ * information might refer to different tables.
+ */
+
+static MonoMetaTable AssemblySchema [] = {
+ { MONO_MT_UINT32, "HashId" },
+ { MONO_MT_UINT16, "Major" },
+ { MONO_MT_UINT16, "Minor" },
+ { MONO_MT_UINT16, "BuildNumber" },
+ { MONO_MT_UINT16, "RevisionNumber" },
+ { MONO_MT_UINT32, "Flags" },
+ { MONO_MT_BLOB_IDX, "PublicKey" },
+ { MONO_MT_STRING_IDX, "Name" },
+ { MONO_MT_STRING_IDX, "Culture" },
+ { MONO_MT_END, NULL }
+};
+
+static MonoMetaTable AssemblyOSSchema [] = {
+ { MONO_MT_UINT32, "OSPlatformID" },
+ { MONO_MT_UINT32, "OSMajor" },
+ { MONO_MT_UINT32, "OSMinor" },
+ { MONO_MT_END, NULL }
+};
+
+static MonoMetaTable AssemblyProcessorSchema [] = {
+ { MONO_MT_UINT32, "Processor" },
+ { MONO_MT_END, NULL }
+};
+
+static MonoMetaTable AssemblyRefSchema [] = {
+ { MONO_MT_UINT16, "Major" },
+ { MONO_MT_UINT16, "Minor" },
+ { MONO_MT_UINT16, "Build" },
+ { MONO_MT_UINT16, "Revision" },
+ { MONO_MT_UINT32, "Flags" },
+ { MONO_MT_BLOB_IDX, "PublicKeyOrToken" },
+ { MONO_MT_STRING_IDX, "Name" },
+ { MONO_MT_STRING_IDX, "Culture" },
+ { MONO_MT_BLOB_IDX, "HashValue" },
+ { MONO_MT_END, NULL }
+};
+
+static MonoMetaTable AssemblyRefOSSchema [] = {
+ { MONO_MT_UINT32, "OSPlatformID" },
+ { MONO_MT_UINT32, "OSMajorVersion" },
+ { MONO_MT_UINT32, "OSMinorVersion" },
+ { MONO_MT_TABLE_IDX, "AssemblyRef:AssemblyRef" },
+ { MONO_MT_END, NULL }
+};
+
+static MonoMetaTable AssemblyRefProcessorSchema [] = {
+ { MONO_MT_UINT32, "Processor" },
+ { MONO_MT_TABLE_IDX, "AssemblyRef:AssemblyRef" },
+ { MONO_MT_END, NULL }
+};
+
+static MonoMetaTable ClassLayoutSchema [] = {
+ { MONO_MT_UINT16, "PackingSize" },
+ { MONO_MT_UINT32, "ClassSize" },
+ { MONO_MT_TABLE_IDX, "Parent:TypeDef" },
+ { MONO_MT_END, NULL }
+};
+
+static MonoMetaTable ConstantSchema [] = {
+ { MONO_MT_UINT8, "Type" },
+ { MONO_MT_UINT8, "PaddingZero" },
+ { MONO_MT_CONST_IDX, "Parent" },
+ { MONO_MT_BLOB_IDX, "Value" },
+ { MONO_MT_END, NULL }
+};
+
+static MonoMetaTable CustomAttributeSchema [] = {
+ { MONO_MT_HASCAT_IDX, "Parent" },
+ { MONO_MT_CAT_IDX, "Type" },
+ { MONO_MT_BLOB_IDX, "Value" },
+ { MONO_MT_END, NULL }
+};
+
+static MonoMetaTable DeclSecuritySchema [] = {
+ { MONO_MT_UINT16, "Action" },
+ { MONO_MT_HASDEC_IDX, "Parent" },
+ { MONO_MT_BLOB_IDX, "PermissionSet" },
+ { MONO_MT_END, NULL }
+};
+
+static MonoMetaTable EventMapSchema [] = {
+ { MONO_MT_TABLE_IDX, "Parent:TypeDef" },
+ { MONO_MT_TABLE_IDX, "EventList:Event" },
+ { MONO_MT_END, NULL }
+};
+
+static MonoMetaTable EventSchema [] = {
+ { MONO_MT_UINT16, "EventFlags#EventAttribute" },
+ { MONO_MT_STRING_IDX, "Name" },
+ { MONO_MT_TABLE_IDX, "EventType" }, /* TypeDef or TypeRef */
+ { MONO_MT_END, NULL }
+};
+
+static MonoMetaTable ExportedTypeSchema [] = {
+ { MONO_MT_UINT32, "Flags" },
+ { MONO_MT_TABLE_IDX, "TypeDefId" },
+ { MONO_MT_STRING_IDX, "TypeName" },
+ { MONO_MT_STRING_IDX, "TypeNameSpace" },
+ { MONO_MT_IMPL_IDX, "Implementation" },
+ { MONO_MT_END, NULL }
+};
+
+static MonoMetaTable FieldSchema [] = {
+ { MONO_MT_UINT16, "Flags" },
+ { MONO_MT_STRING_IDX, "Name" },
+ { MONO_MT_BLOB_IDX, "Signature" },
+ { MONO_MT_END, NULL }
+};
+static MonoMetaTable FieldLayoutSchema [] = {
+ { MONO_MT_UINT32, "Offset" },
+ { MONO_MT_TABLE_IDX, "Field:Field" },
+ { MONO_MT_END, NULL }
+};
+
+static MonoMetaTable FieldMarshalSchema [] = {
+ { MONO_MT_HFM_IDX, "Parent" },
+ { MONO_MT_BLOB_IDX, "NativeType" },
+ { MONO_MT_END, NULL }
+};
+static MonoMetaTable FieldRVASchema [] = {
+ { MONO_MT_UINT32, "RVA" },
+ { MONO_MT_TABLE_IDX, "Field:Field" },
+ { MONO_MT_END, NULL }
+};
+
+static MonoMetaTable FileSchema [] = {
+ { MONO_MT_UINT32, "Flags" },
+ { MONO_MT_STRING_IDX, "Name" },
+ { MONO_MT_BLOB_IDX, "Value" },
+ { MONO_MT_END, NULL }
+};
+
+static MonoMetaTable ImplMapSchema [] = {
+ { MONO_MT_UINT16, "MappingFlag" },
+ { MONO_MT_MF_IDX, "MemberForwarded" },
+ { MONO_MT_STRING_IDX, "ImportName" },
+ { MONO_MT_TABLE_IDX, "ImportScope:ModuleRef" },
+ { MONO_MT_END, NULL }
+};
+
+static MonoMetaTable InterfaceImplSchema [] = {
+ { MONO_MT_TABLE_IDX, "Class:TypeDef" },
+ { MONO_MT_TDOR_IDX, "Interface=TypeDefOrRef" },
+ { MONO_MT_END, NULL }
+};
+
+static MonoMetaTable ManifestResourceSchema [] = {
+ { MONO_MT_UINT32, "Offset" },
+ { MONO_MT_UINT32, "Flags" },
+ { MONO_MT_STRING_IDX, "Name" },
+ { MONO_MT_IMPL_IDX, "Implementation" },
+ { MONO_MT_END, NULL }
+};
+
+static MonoMetaTable MemberRefSchema [] = {
+ { MONO_MT_MRP_IDX, "Class" },
+ { MONO_MT_STRING_IDX, "Name" },
+ { MONO_MT_BLOB_IDX, "Signature" },
+ { MONO_MT_END, NULL }
+};
+
+static MonoMetaTable MethodSchema [] = {
+ { MONO_MT_UINT32, "RVA" },
+ { MONO_MT_UINT16, "ImplFlags#MethodImplAttributes" },
+ { MONO_MT_UINT16, "Flags#MethodAttribute" },
+ { MONO_MT_STRING_IDX, "Name" },
+ { MONO_MT_BLOB_IDX, "Signature" },
+ { MONO_MT_TABLE_IDX, "ParamList:Param" },
+ { MONO_MT_END, NULL }
+};
+
+static MonoMetaTable MethodImplSchema [] = {
+ { MONO_MT_TABLE_IDX, "Class:TypeDef" },
+ { MONO_MT_MDOR_IDX, "MethodBody" },
+ { MONO_MT_MDOR_IDX, "MethodDeclaration" },
+ { MONO_MT_END, NULL }
+};
+
+static MonoMetaTable MethodSemanticsSchema [] = {
+ { MONO_MT_UINT16, "MethodSemantic" },
+ { MONO_MT_TABLE_IDX, "Method:Method" },
+ { MONO_MT_HS_IDX, "Association" },
+ { MONO_MT_END, NULL }
+};
+
+static MonoMetaTable ModuleSchema [] = {
+ { MONO_MT_UINT16, "Generation" },
+ { MONO_MT_STRING_IDX, "Name" },
+ { MONO_MT_GUID_IDX, "MVID" },
+ { MONO_MT_GUID_IDX, "EncID" },
+ { MONO_MT_GUID_IDX, "EncBaseID" },
+ { MONO_MT_END, NULL }
+};
+
+static MonoMetaTable ModuleRefSchema [] = {
+ { MONO_MT_STRING_IDX, "Name" },
+ { MONO_MT_END, NULL }
+};
+
+static MonoMetaTable NestedClassSchema [] = {
+ { MONO_MT_TABLE_IDX, "NestedClass:TypeDef" },
+ { MONO_MT_TABLE_IDX, "EnclosingClass:TypeDef" },
+ { MONO_MT_END, NULL }
+};
+
+static MonoMetaTable ParamSchema [] = {
+ { MONO_MT_UINT16, "Flags" },
+ { MONO_MT_UINT16, "Sequence" },
+ { MONO_MT_STRING_IDX, "Name" },
+ { MONO_MT_END, NULL }
+};
+
+static MonoMetaTable PropertySchema [] = {
+ { MONO_MT_UINT16, "Flags" },
+ { MONO_MT_STRING_IDX, "Name" },
+ { MONO_MT_BLOB_IDX, "Type" },
+ { MONO_MT_END, NULL }
+};
+
+static MonoMetaTable PropertyMapSchema [] = {
+ { MONO_MT_TABLE_IDX, "Parent:TypeDef" },
+ { MONO_MT_TABLE_IDX, "PropertyList:Property" },
+ { MONO_MT_END, NULL }
+};
+
+static MonoMetaTable StandaloneSigSchema [] = {
+ { MONO_MT_BLOB_IDX, "Signature" },
+ { MONO_MT_END, NULL }
+};
+
+static MonoMetaTable TypeDefSchema [] = {
+ { MONO_MT_UINT32, "Flags" },
+ { MONO_MT_STRING_IDX, "Name" },
+ { MONO_MT_STRING_IDX, "Namespace" },
+ { MONO_MT_TDOR_IDX, "Extends" },
+ { MONO_MT_TABLE_IDX, "FieldList:Field" },
+ { MONO_MT_TABLE_IDX, "MethodList:Method" },
+ { MONO_MT_END, NULL }
+};
+
+static MonoMetaTable TypeRefSchema [] = {
+ { MONO_MT_RS_IDX, "ResolutionScope=ResolutionScope" },
+ { MONO_MT_STRING_IDX, "Name" },
+ { MONO_MT_STRING_IDX, "Namespace" },
+ { MONO_MT_END, NULL }
+};
+
+static MonoMetaTable TypeSpecSchema [] = {
+ { MONO_MT_BLOB_IDX, "Signature" },
+ { MONO_MT_END, NULL }
+};
+
+static struct {
+ MonoMetaTable *table;
+ const char *name;
+} tables [] = {
+ /* 0 */ { ModuleSchema, "Module" },
+ /* 1 */ { TypeRefSchema, "TypeRef" },
+ /* 2 */ { TypeDefSchema, "TypeDef" },
+ /* 3 */ { NULL, NULL },
+ /* 4 */ { FieldSchema, "Field" },
+ /* 5 */ { NULL, NULL },
+ /* 6 */ { MethodSchema, "Method" },
+ /* 7 */ { NULL, NULL },
+ /* 8 */ { ParamSchema, "Param" },
+ /* 9 */ { InterfaceImplSchema, "InterfaceImpl" },
+ /* A */ { MemberRefSchema, "MemberRef" },
+ /* B */ { ConstantSchema, "Constant" },
+ /* C */ { CustomAttributeSchema, "CustomAttribute" },
+ /* D */ { FieldMarshalSchema, "FieldMarshal" },
+ /* E */ { DeclSecuritySchema, "DeclSecurity" },
+ /* F */ { ClassLayoutSchema, "ClassLayout" },
+ /* 10 */ { FieldLayoutSchema, "FieldLayout" },
+ /* 11 */ { StandaloneSigSchema, "StandaloneSig" },
+ /* 12 */ { EventMapSchema, "EventMap" },
+ /* 13 */ { NULL, NULL },
+ /* 14 */ { EventSchema, "Event" },
+ /* 15 */ { PropertyMapSchema, "PropertyMap" },
+ /* 16 */ { NULL, NULL },
+ /* 17 */ { PropertySchema, "PropertyTable" },
+ /* 18 */ { MethodSemanticsSchema, "MethodSemantics" },
+ /* 19 */ { MethodImplSchema, "MethodImpl" },
+ /* 1A */ { ModuleRefSchema, "ModuleRef" },
+ /* 1B */ { TypeSpecSchema, "TypeSpec" },
+ /* 1C */ { ImplMapSchema, "ImplMap" },
+ /* 1D */ { FieldRVASchema, "FieldRVA" },
+ /* 1E */ { NULL, NULL },
+ /* 1F */ { NULL, NULL },
+ /* 20 */ { AssemblySchema, "Assembly" },
+ /* 21 */ { AssemblyProcessorSchema, "AssemblyProcessor" },
+ /* 22 */ { AssemblyOSSchema, "AssemblyOS" },
+ /* 23 */ { AssemblyRefSchema, "AssemblyRef" },
+ /* 24 */ { AssemblyRefProcessorSchema, "AssemblyRefProcessor" },
+ /* 25 */ { AssemblyRefOSSchema, "AssemblyRefOS" },
+ /* 26 */ { FileSchema, "File" },
+ /* 27 */ { ExportedTypeSchema, "ExportedType" },
+ /* 28 */ { ManifestResourceSchema, "ManifestResource" },
+ /* 29 */ { NestedClassSchema, "NestedClass" },
+ /* 2A */ { NULL, NULL },
+ /* 2B */ { NULL, NULL },
+};
+
+/**
+ * mono_meta_table_name:
+ * @table: table index
+ *
+ * Returns the name for the @table index
+ */
+const char *
+mono_meta_table_name (int table)
+{
+ if ((table < 0) || (table > 0x29))
+ return "";
+
+ return tables [table].name;
+}
+
+/* The guy who wrote the spec for this should not be allowed near a
+ * computer again.
+
+If e is a coded token(see clause 23.1.7) that points into table ti out of n possible tables t0, .. tn-1,
+then it is stored as e << (log n) & tag{ t0, .. tn-1}[ ti] using 2 bytes if the maximum number of
+rows of tables t0, ..tn-1, is less than 2^16 - (log n), and using 4 bytes otherwise. The family of
+finite maps tag{ t0, ..tn-1} is defined below. Note that to decode a physical row, you need the
+inverse of this mapping.
+
+ */
+#define rtsize(s,b) (((s) < (1 << (b)) ? 2 : 4))
+#define idx_size(tableidx) (meta->tables [(tableidx)].rows < 65536 ? 2 : 4)
+
+/* Reference: Partition II - 23.2.6 */
+static int
+compute_size (MonoMetadata *meta, MonoMetaTable *table, int tableindex, guint32 *result_bitfield)
+{
+ guint32 bitfield = 0;
+ int size = 0, field_size;
+ int i, n, code;
+ int shift = 0;
+
+ for (i = 0; (code = table [i].code) != MONO_MT_END; i++){
+ switch (code){
+ case MONO_MT_UINT32:
+ field_size = 4; break;
+
+ case MONO_MT_UINT16:
+ field_size = 2; break;
+
+ case MONO_MT_UINT8:
+ field_size = 1; break;
+
+ case MONO_MT_BLOB_IDX:
+ field_size = meta->idx_blob_wide ? 4 : 2; break;
+
+ case MONO_MT_STRING_IDX:
+ field_size = meta->idx_string_wide ? 4 : 2; break;
+
+ case MONO_MT_GUID_IDX:
+ field_size = meta->idx_guid_wide ? 4 : 2; break;
+
+ case MONO_MT_TABLE_IDX:
+ /* Uhm, a table index can point to other tables besides the current one
+ * so, it's not correct to use the rowcount of the current table to
+ * get the size for this column - lupus
+ */
+ switch (tableindex) {
+ case MONO_TABLE_ASSEMBLYREFOS:
+ g_assert (i == 3);
+ field_size = idx_size (MONO_TABLE_ASSEMBLYREF); break;
+ case MONO_TABLE_ASSEMBLYPROCESSOR:
+ g_assert (i == 1);
+ field_size = idx_size (MONO_TABLE_ASSEMBLYREF); break;
+ case MONO_TABLE_CLASSLAYOUT:
+ g_assert (i == 2);
+ field_size = idx_size (MONO_TABLE_TYPEDEF); break;
+ case MONO_TABLE_EVENTMAP:
+ g_assert (i == 0 || i == 1);
+ field_size = i ? idx_size (MONO_TABLE_EVENT):
+ idx_size(MONO_TABLE_TYPEDEF);
+ break;
+ case MONO_TABLE_EVENT:
+ g_assert (i == 2);
+ field_size = MAX (idx_size (MONO_TABLE_TYPEDEF), idx_size(MONO_TABLE_TYPEREF));
+ field_size = MAX (field_size, idx_size(MONO_TABLE_TYPESPEC));
+ break;
+ case MONO_TABLE_EXPORTEDTYPE:
+ g_assert (i == 1);
+ field_size = idx_size (MONO_TABLE_TYPEDEF); break;
+ case MONO_TABLE_FIELDLAYOUT:
+ g_assert (i == 1);
+ field_size = idx_size (MONO_TABLE_FIELD); break;
+ case MONO_TABLE_FIELDRVA:
+ g_assert (i == 1);
+ field_size = idx_size (MONO_TABLE_FIELD); break;
+ case MONO_TABLE_IMPLMAP:
+ g_assert (i == 3);
+ field_size = idx_size (MONO_TABLE_MODULEREF); break;
+ case MONO_TABLE_INTERFACEIMPL:
+ g_assert (i == 0);
+ field_size = idx_size (MONO_TABLE_TYPEDEF); break;
+ case MONO_TABLE_METHOD:
+ g_assert (i == 5);
+ field_size = idx_size (MONO_TABLE_PARAM); break;
+ case MONO_TABLE_METHODIMPL:
+ g_assert (i == 0);
+ field_size = idx_size (MONO_TABLE_TYPEDEF); break;
+ case MONO_TABLE_METHODSEMANTICS:
+ g_assert (i == 1);
+ field_size = idx_size (MONO_TABLE_METHOD); break;
+ case MONO_TABLE_NESTEDCLASS:
+ g_assert (i == 0 || i == 1);
+ field_size = idx_size (MONO_TABLE_TYPEDEF); break;
+ case MONO_TABLE_PROPERTYMAP:
+ g_assert (i == 0 || i == 1);
+ field_size = i ? idx_size (MONO_TABLE_PROPERTY):
+ idx_size(MONO_TABLE_TYPEDEF);
+ break;
+ case MONO_TABLE_TYPEDEF:
+ g_assert (i == 4 || i == 5);
+ field_size = i == 4 ? idx_size (MONO_TABLE_FIELD):
+ idx_size(MONO_TABLE_METHOD);
+ break;
+ default:
+ g_assert_not_reached ();
+ }
+ if (field_size != idx_size (tableindex))
+ g_warning ("size changed (%d to %d)", idx_size (tableindex), field_size);
+
+ break;
+
+ /*
+ * HasConstant: ParamDef, FieldDef, Property
+ */
+ case MONO_MT_CONST_IDX:
+ n = MAX (meta->tables [MONO_TABLE_PARAM].rows,
+ meta->tables [MONO_TABLE_FIELD].rows);
+ n = MAX (n, meta->tables [MONO_TABLE_PROPERTY].rows);
+
+ /* 2 bits to encode tag */
+ field_size = rtsize (n, 16-2);
+ break;
+
+ /*
+ * HasCustomAttribute: points to any table but
+ * itself.
+ */
+ case MONO_MT_HASCAT_IDX:
+ /*
+ * We believe that since the signature and
+ * permission are indexing the Blob heap,
+ * we should consider the blob size first
+ */
+ /* I'm not a believer - lupus
+ if (meta->idx_blob_wide){
+ field_size = 4;
+ break;
+ }*/
+
+ n = MAX (meta->tables [MONO_TABLE_METHOD].rows,
+ meta->tables [MONO_TABLE_FIELD].rows);
+ n = MAX (n, meta->tables [MONO_TABLE_TYPEREF].rows);
+ n = MAX (n, meta->tables [MONO_TABLE_TYPEDEF].rows);
+ n = MAX (n, meta->tables [MONO_TABLE_PARAM].rows);
+ n = MAX (n, meta->tables [MONO_TABLE_INTERFACEIMPL].rows);
+ n = MAX (n, meta->tables [MONO_TABLE_MEMBERREF].rows);
+ n = MAX (n, meta->tables [MONO_TABLE_MODULE].rows);
+ /* Permission seems to be a blob heap pointer */
+ n = MAX (n, meta->tables [MONO_TABLE_PROPERTY].rows);
+ n = MAX (n, meta->tables [MONO_TABLE_EVENT].rows);
+ /* Signature seems to be a blob heap pointer */
+ n = MAX (n, meta->tables [MONO_TABLE_MODULEREF].rows);
+ n = MAX (n, meta->tables [MONO_TABLE_TYPESPEC].rows);
+ n = MAX (n, meta->tables [MONO_TABLE_ASSEMBLY].rows);
+ n = MAX (n, meta->tables [MONO_TABLE_ASSEMBLYREF].rows);
+ n = MAX (n, meta->tables [MONO_TABLE_FILE].rows);
+ n = MAX (n, meta->tables [MONO_TABLE_EXPORTEDTYPE].rows);
+ n = MAX (n, meta->tables [MONO_TABLE_MANIFESTRESOURCE].rows);
+
+ /* 5 bits to encode */
+ field_size = rtsize (n, 16-5);
+ break;
+
+ /*
+ * CustomAttributeType: TypeDef, TypeRef, MethodDef,
+ * MemberRef and String.
+ */
+ case MONO_MT_CAT_IDX:
+ /* String is a heap, if it is wide, we know the size */
+ /* See above, nope.
+ if (meta->idx_string_wide){
+ field_size = 4;
+ break;
+ }*/
+
+ n = MAX (meta->tables [MONO_TABLE_TYPEREF].rows,
+ meta->tables [MONO_TABLE_TYPEDEF].rows);
+ n = MAX (n, meta->tables [MONO_TABLE_METHOD].rows);
+ n = MAX (n, meta->tables [MONO_TABLE_MEMBERREF].rows);
+
+ /* 3 bits to encode */
+ field_size = rtsize (n, 16-3);
+ break;
+
+ /*
+ * HasDeclSecurity: Typedef, MethodDef, Assembly
+ */
+ case MONO_MT_HASDEC_IDX:
+ n = MAX (meta->tables [MONO_TABLE_TYPEDEF].rows,
+ meta->tables [MONO_TABLE_METHOD].rows);
+ n = MAX (n, meta->tables [MONO_TABLE_ASSEMBLY].rows);
+
+ /* 2 bits to encode */
+ field_size = rtsize (n, 16-2);
+ break;
+
+ /*
+ * Implementation: File, AssemblyRef, ExportedType
+ */
+ case MONO_MT_IMPL_IDX:
+ n = MAX (meta->tables [MONO_TABLE_FILE].rows,
+ meta->tables [MONO_TABLE_ASSEMBLYREF].rows);
+ n = MAX (n, meta->tables [MONO_TABLE_EXPORTEDTYPE].rows);
+
+ /* 2 bits to encode tag */
+ field_size = rtsize (n, 16-2);
+ break;
+
+ /*
+ * HasFieldMarshall: FieldDef, ParamDef
+ */
+ case MONO_MT_HFM_IDX:
+ n = MAX (meta->tables [MONO_TABLE_FIELD].rows,
+ meta->tables [MONO_TABLE_PARAM].rows);
+
+ /* 1 bit used to encode tag */
+ field_size = rtsize (n, 16-1);
+ break;
+
+ /*
+ * MemberForwarded: FieldDef, MethodDef
+ */
+ case MONO_MT_MF_IDX:
+ n = MAX (meta->tables [MONO_TABLE_FIELD].rows,
+ meta->tables [MONO_TABLE_METHOD].rows);
+
+ /* 1 bit used to encode tag */
+ field_size = rtsize (n, 16-1);
+ break;
+
+ /*
+ * TypeDefOrRef: TypeDef, ParamDef, TypeSpec
+ * LAMESPEC
+ * It is TypeDef, _TypeRef_, TypeSpec, instead.
+ */
+ case MONO_MT_TDOR_IDX:
+ n = MAX (meta->tables [MONO_TABLE_TYPEDEF].rows,
+ meta->tables [MONO_TABLE_TYPEREF].rows);
+ n = MAX (n, meta->tables [MONO_TABLE_TYPESPEC].rows);
+
+ /* 2 bits to encode */
+ field_size = rtsize (n, 16-2);
+ break;
+
+ /*
+ * MemberRefParent: TypeDef, TypeRef, MethodDef, ModuleRef, TypeSpec, MemberRef
+ */
+ case MONO_MT_MRP_IDX:
+ n = MAX (meta->tables [MONO_TABLE_TYPEDEF].rows,
+ meta->tables [MONO_TABLE_TYPEREF].rows);
+ n = MAX (n, meta->tables [MONO_TABLE_METHOD].rows);
+ n = MAX (n, meta->tables [MONO_TABLE_MODULEREF].rows);
+ n = MAX (n, meta->tables [MONO_TABLE_TYPESPEC].rows);
+ n = MAX (n, meta->tables [MONO_TABLE_MEMBERREF].rows);
+
+ /* 3 bits to encode */
+ field_size = rtsize (n, 16 - 3);
+ break;
+
+ case MONO_MT_MDOR_IDX:
+
+ /*
+ * MethodDefOrRef: MethodDef, MemberRef
+ */
+ case MONO_MT_HS_IDX:
+ n = MAX (meta->tables [MONO_TABLE_METHOD].rows,
+ meta->tables [MONO_TABLE_MEMBERREF].rows);
+
+ /* 1 bit used to encode tag */
+ field_size = rtsize (n, 16-1);
+ break;
+
+ /*
+ * ResolutionScope: Module, ModuleRef, AssemblyRef, TypeRef
+ */
+ case MONO_MT_RS_IDX:
+ n = MAX (meta->tables [MONO_TABLE_MODULE].rows,
+ meta->tables [MONO_TABLE_MODULEREF].rows);
+ n = MAX (n, meta->tables [MONO_TABLE_ASSEMBLYREF].rows);
+ n = MAX (n, meta->tables [MONO_TABLE_TYPEREF].rows);
+
+ /* 2 bits used to encode tag (ECMA spec claims 3) */
+ field_size = rtsize (n, 16 - 2);
+ break;
+ }
+
+ /*
+ * encode field size as follows (we just need to
+ * distinguish them).
+ *
+ * 4 -> 3
+ * 2 -> 1
+ * 1 -> 0
+ */
+ bitfield |= (field_size-1) << shift;
+ shift += 2;
+ size += field_size;
+ /*g_print ("table %02x field %d size %d\n", tableindex, i, field_size);*/
+ }
+
+ *result_bitfield = (i << 24) | bitfield;
+ return size;
+}
+
+/**
+ * mono_metadata_compute_table_bases:
+ * @meta: metadata context to compute table values
+ *
+ * Computes the table bases for the metadata structure.
+ * This is an internal function used by the image loader code.
+ */
+void
+mono_metadata_compute_table_bases (MonoMetadata *meta)
+{
+ int i;
+ char *base = meta->tables_base;
+
+ for (i = 0; i < 64; i++){
+ if (meta->tables [i].rows == 0)
+ continue;
+
+ meta->tables [i].row_size = compute_size (
+ meta, tables [i].table, i,
+ &meta->tables [i].size_bitfield);
+ meta->tables [i].base = base;
+ base += meta->tables [i].rows * meta->tables [i].row_size;
+ }
+}
+
+/**
+ * mono_metadata_locate:
+ * @meta: metadata context
+ * @table: table code.
+ * @idx: index of element to retrieve from @table.
+ *
+ * Returns a pointer to the @idx element in the metadata table
+ * whose code is @table.
+ */
+char *
+mono_metadata_locate (MonoMetadata *meta, int table, int idx)
+{
+ /* idx == 0 refers always to NULL */
+ g_return_val_if_fail (idx > 0 && idx <= meta->tables [table].rows, "");
+
+ return meta->tables [table].base + (meta->tables [table].row_size * (idx - 1));
+}
+
+char *
+mono_metadata_locate_token (MonoMetadata *meta, guint32 token)
+{
+ return mono_metadata_locate (meta, token >> 24, token & 0xffffff);
+}
+
+/**
+ * mono_metadata_get_table:
+ * @table: table to retrieve
+ *
+ * Returns the MonoMetaTable structure for table @table
+ */
+MonoMetaTable *
+mono_metadata_get_table (MonoMetaTableEnum table)
+{
+ int x = (int) table;
+
+ g_return_val_if_fail ((x > 0) && (x <= MONO_TABLE_LAST), NULL);
+
+ return tables [table].table;
+}
+
+/**
+ * mono_metadata_string_heap:
+ * @meta: metadata context
+ * @index: index into the string heap.
+ *
+ * Returns: an in-memory pointer to the @index in the string heap.
+ */
+const char *
+mono_metadata_string_heap (MonoMetadata *meta, guint32 index)
+{
+ g_return_val_if_fail (index < meta->heap_strings.size, "");
+ return meta->raw_metadata + meta->heap_strings.offset + index;
+}
+
+const char *
+mono_metadata_user_string (MonoMetadata *meta, guint32 index)
+{
+ g_return_val_if_fail (index < meta->heap_us.size, "");
+ return meta->raw_metadata + meta->heap_us.offset + index;
+}
+
+/**
+ * mono_metadata_blob_heap:
+ * @meta: metadata context
+ * @index: index into the blob.
+ *
+ * Returns: an in-memory pointer to the @index in the Blob heap.
+ */
+const char *
+mono_metadata_blob_heap (MonoMetadata *meta, guint32 index)
+{
+ g_return_val_if_fail (index < meta->heap_blob.size, "");
+ return meta->raw_metadata + meta->heap_blob.offset + index;
+}
+
+static const char *
+dword_align (const char *ptr)
+{
+ return (const char *) (((guint32) (ptr + 3)) & ~3);
+}
+
+/**
+ * mono_metadata_decode_row:
+ * @t: table to extract information from.
+ * @idx: index in table.
+ * @res: array of @res_size cols to store the results in
+ *
+ * This decompresses the metadata element @idx in table @t
+ * into the guint32 @res array that has res_size elements
+ */
+void
+mono_metadata_decode_row (MonoTableInfo *t, int idx, guint32 *res, int res_size)
+{
+ guint32 bitfield = t->size_bitfield;
+ int i, count = mono_metadata_table_count (bitfield);
+ char *data = t->base + idx * t->row_size;
+
+ g_assert (res_size == count);
+
+ for (i = 0; i < count; i++){
+ int n = mono_metadata_table_size (bitfield, i);
+
+ switch (n){
+ case 1:
+ res [i] = *data; break;
+ case 2:
+ res [i] = read16 (data); break;
+
+ case 4:
+ res [i] = read32 (data); break;
+
+ default:
+ g_assert_not_reached ();
+ }
+ data += n;
+ }
+}
+
+/**
+ * mono_metadata_decode_row_col:
+ * @t: table to extract information from.
+ * @idx: index for row in table.
+ * @col: column in the row.
+ *
+ * This function returns the value of column @col from the @idx
+ * row in the table @t.
+ */
+guint32
+mono_metadata_decode_row_col (MonoTableInfo *t, int idx, guint col)
+{
+ guint32 bitfield = t->size_bitfield;
+ int i;
+ register char *data = t->base + idx * t->row_size;
+ register int n;
+
+ g_assert (col < mono_metadata_table_count (bitfield));
+
+ n = mono_metadata_table_size (bitfield, 0);
+ for (i = 0; i < col; ++i) {
+ data += n;
+ n = mono_metadata_table_size (bitfield, i + 1);
+ }
+ switch (n){
+ case 1:
+ return *data;
+ case 2:
+ return read16 (data);
+ case 4:
+ return read32 (data);
+ default:
+ g_assert_not_reached ();
+ }
+ return 0;
+}
+/**
+ * mono_metadata_decode_blob_size:
+ * @ptr: pointer to a blob object
+ * @rptr: the new position of the pointer
+ *
+ * This decodes a compressed size as described by 23.1.4 (a blob or user string object)
+ *
+ * Returns: the size of the blob object
+ */
+guint32
+mono_metadata_decode_blob_size (const char *xptr, const char **rptr)
+{
+ const unsigned char *ptr = xptr;
+ guint32 size;
+
+ if ((*ptr & 0x80) == 0){
+ size = ptr [0] & 0x7f;
+ ptr++;
+ } else if ((*ptr & 0x40) == 0){
+ size = ((ptr [0] & 0x3f) << 8) + ptr [1];
+ ptr += 2;
+ } else {
+ size = ((ptr [0] & 0x1f) << 24) +
+ (ptr [1] << 16) +
+ (ptr [2] << 8) +
+ ptr [3];
+ ptr += 4;
+ }
+ if (rptr)
+ *rptr = ptr;
+ return size;
+}
+
+
+/**
+ * mono_metadata_decode_value:
+ * @ptr: pointer to decode from
+ * @rptr: the new position of the pointer
+ *
+ * This routine decompresses 32-bit values as specified in the "Blob and
+ * Signature" section (22.2)
+ *
+ * Returns: the decoded value
+ */
+guint32
+mono_metadata_decode_value (const char *_ptr, const char **rptr)
+{
+ const unsigned char *ptr = (unsigned char *) _ptr;
+ unsigned char b = *ptr;
+ guint32 len;
+
+ if ((b & 0x80) == 0){
+ len = b;
+ ++ptr;
+ } else if ((b & 0x40) == 0){
+ len = ((b & 0x3f) << 8 | ptr [1]);
+ ptr += 2;
+ } else {
+ len = ((b & 0x1f) << 24) |
+ (ptr [1] << 16) |
+ (ptr [2] << 8) |
+ ptr [3];
+ ptr += 4;
+ }
+ if (rptr)
+ *rptr = ptr;
+
+ return len;
+}
+
+guint32
+mono_metadata_parse_typedef_or_ref (MonoMetadata *m, const char *ptr, const char **rptr)
+{
+ guint32 token;
+ guint table;
+ token = mono_metadata_decode_value (ptr, &ptr);
+
+ switch (token & 0x03) {
+ case 0: table = MONO_TABLE_TYPEDEF; break;
+ case 1: table = MONO_TABLE_TYPEREF; break;
+ case 2: table = MONO_TABLE_TYPESPEC; break;
+ default: g_error ("Unhandled encoding for typedef-or-ref coded index");
+ }
+ if (rptr)
+ *rptr = ptr;
+ return (token >> 2) | table << 24;
+}
+
+int
+mono_metadata_parse_custom_mod (MonoMetadata *m, MonoCustomMod *dest, const char *ptr, const char **rptr)
+{
+ MonoCustomMod local;
+ if ((*ptr == MONO_TYPE_CMOD_OPT) ||
+ (*ptr == MONO_TYPE_CMOD_REQD)) {
+ if (!dest)
+ dest = &local;
+ dest->mod = *ptr++;
+ dest->token = mono_metadata_parse_typedef_or_ref (m, ptr, &ptr);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+MonoArray *
+mono_metadata_parse_array (MonoMetadata *m, const char *ptr, const char **rptr)
+{
+ int i;
+ MonoArray *array = g_new0 (MonoArray, 1);
+
+ array->type = mono_metadata_parse_type (m, ptr, &ptr);
+ array->rank = mono_metadata_decode_value (ptr, &ptr);
+
+ array->numsizes = mono_metadata_decode_value (ptr, &ptr);
+ if (array->numsizes)
+ array->sizes = g_new0 (int, array->numsizes);
+ for (i = 0; i < array->numsizes; ++i)
+ array->sizes [i] = mono_metadata_decode_value (ptr, &ptr);
+
+ array->numlobounds = mono_metadata_decode_value (ptr, &ptr);
+ if (array->numlobounds)
+ array->lobounds = g_new0 (int, array->numlobounds);
+ for (i = 0; i < array->numlobounds; ++i)
+ array->lobounds [i] = mono_metadata_decode_value (ptr, &ptr);
+
+ if (rptr)
+ *rptr = ptr;
+ return array;
+}
+
+void
+mono_metadata_free_array (MonoArray *array)
+{
+ mono_metadata_free_type (array->type);
+ g_free (array->sizes);
+ g_free (array->lobounds);
+ g_free (array);
+}
+
+MonoParam *
+mono_metadata_parse_param (MonoMetadata *m, int rettype, const char *ptr, const char **rptr)
+{
+ const char *tmp_ptr = ptr;
+ MonoParam *param;
+ int count = 0;
+ int byref = 0;
+
+ /* count the modifiers */
+ while (mono_metadata_parse_custom_mod (m, NULL, tmp_ptr, &tmp_ptr))
+ count++;
+ param = g_malloc0(sizeof(MonoParam)+(count-MONO_ZERO_LEN_ARRAY)*sizeof(MonoCustomMod));
+ param->num_modifiers = count;
+ /* save them this time */
+ count = 0;
+ while (mono_metadata_parse_custom_mod (m, &(param->modifiers[count]), ptr, &ptr))
+ count++;
+ switch (*ptr) {
+ case MONO_TYPE_TYPEDBYREF:
+ param->typedbyref = 1;
+ ptr++;
+ break;
+ case MONO_TYPE_BYREF:
+ byref = 1;
+ ptr++;
+ /* follow through */
+ default:
+ if (*ptr == MONO_TYPE_VOID && !rettype)
+ g_error ("void not allowed in param");
+ param->type = mono_metadata_parse_type (m, ptr, &ptr);
+ param->type->byref = byref;
+ break;
+ }
+ if (rptr)
+ *rptr = ptr;
+ return param;
+}
+
+void
+mono_metadata_free_param (MonoParam *param)
+{
+ if (param->type)
+ mono_metadata_free_type (param->type);
+ g_free (param);
+}
+
+MonoMethodSignature *
+mono_metadata_parse_method_signature (MonoMetadata *m, int def, const char *ptr, const char **rptr)
+{
+ MonoMethodSignature *method = g_new0(MonoMethodSignature, 1);
+ int i, align, offset = 0;
+
+ if (*ptr & 0x20)
+ method->hasthis = 1;
+ if (*ptr & 0x40)
+ method->explicit_this = 1;
+ method->call_convention = *ptr & 0x0F;
+ ptr++;
+ method->param_count = mono_metadata_decode_value (ptr, &ptr);
+ method->ret = mono_metadata_parse_param (m, 1, ptr, &ptr);
+
+ if (method->hasthis)
+ offset += sizeof(gpointer);
+ if (method->param_count) {
+ int size;
+
+ method->params = g_new0(MonoParam*, method->param_count);
+ method->sentinelpos = -1;
+
+ for (i = 0; i < method->param_count; ++i) {
+ if (*ptr == MONO_TYPE_SENTINEL) {
+ if (method->call_convention != MONO_CALL_VARARG || def)
+ g_error ("found sentinel for methoddef or no vararg method");
+ method->sentinelpos = i;
+ ptr++;
+ }
+ method->params [i] = mono_metadata_parse_param (m, 0, ptr, &ptr);
+ size = mono_type_size (method->params [i]->type, &align);
+ offset += (offset % align);
+ offset += size;
+ }
+ }
+ method->params_size = offset;
+
+ if (rptr)
+ *rptr = ptr;
+ return method;
+}
+
+void
+mono_metadata_free_method_signature (MonoMethodSignature *method)
+{
+ int i;
+ mono_metadata_free_param (method->ret);
+ for (i = 0; i < method->param_count; ++i)
+ mono_metadata_free_param (method->params[i]);
+
+ g_free (method->params);
+ g_free (method);
+}
+
+/*
+ * do_mono_metadata_parse_type:
+ * @type: MonoType to be filled in with the return value
+ * @
+ * Internal routine used to "fill" the contents of @type from an
+ * allocated pointer. This is done this way to avoid doing too
+ * many mini-allocations (particularly for the MonoFieldType which
+ * most of the time is just a MonoType, but sometimes might be augmented).
+ *
+ * This routine is used by mono_metadata_parse_type and
+ * mono_metadata_parse_field_type
+ *
+ * This extracts a Type as specified in Partition II (22.2.12)
+ */
+static void
+do_mono_metadata_parse_type (MonoType *type, MonoMetadata *m, const char *ptr, const char **rptr)
+{
+ type->type = mono_metadata_decode_value (ptr, &ptr);
+
+ switch (type->type){
+ case MONO_TYPE_VOID:
+ case MONO_TYPE_BOOLEAN:
+ case MONO_TYPE_CHAR:
+ case MONO_TYPE_I1:
+ case MONO_TYPE_U1:
+ case MONO_TYPE_I2:
+ case MONO_TYPE_U2:
+ case MONO_TYPE_I4:
+ case MONO_TYPE_U4:
+ case MONO_TYPE_I8:
+ case MONO_TYPE_U8:
+ case MONO_TYPE_R4:
+ case MONO_TYPE_R8:
+ case MONO_TYPE_I:
+ case MONO_TYPE_U:
+ case MONO_TYPE_STRING:
+ case MONO_TYPE_OBJECT:
+ case MONO_TYPE_TYPEDBYREF:
+ break;
+ case MONO_TYPE_VALUETYPE:
+ case MONO_TYPE_CLASS:
+ type->data.token = mono_metadata_parse_typedef_or_ref (m, ptr, &ptr);
+ break;
+ case MONO_TYPE_SZARRAY:
+ case MONO_TYPE_PTR:
+ if (mono_metadata_parse_custom_mod (m, NULL, ptr, NULL)) {
+ const char *tmp_ptr = ptr;
+ MonoModifiedType *mtype;
+ int count = 0;
+
+ type->custom_mod = 1;
+ /* count the modifiers */
+ while (mono_metadata_parse_custom_mod (m, NULL, tmp_ptr, &tmp_ptr))
+ count++;
+ type->data.mtype = mtype = g_malloc0(sizeof(MonoModifiedType)+(count-MONO_ZERO_LEN_ARRAY)*sizeof(MonoCustomMod));
+ mtype->num_modifiers = count;
+ count = 0;
+
+ /* save them this time */
+ while (mono_metadata_parse_custom_mod (m, &(mtype->modifiers[count]), ptr, &ptr))
+ count++;
+ mtype->type = mono_metadata_parse_type (m, ptr, &ptr);
+ } else {
+ type->data.type = mono_metadata_parse_type (m, ptr, &ptr);
+ }
+ break;
+ case MONO_TYPE_FNPTR:
+ type->data.method = mono_metadata_parse_method_signature (m, 0, ptr, &ptr);
+ break;
+ case MONO_TYPE_ARRAY:
+ type->data.array = mono_metadata_parse_array (m, ptr, &ptr);
+ break;
+ default:
+ g_error ("type 0x%02x not handled in mono_metadata_parse_type", type->type);
+ }
+
+ if (rptr)
+ *rptr = ptr;
+}
+
+/**
+ * mono_metadata_parse_type:
+ * @m: metadata context to scan
+ * @ptr: pointer to encoded Type stream.
+ * @rptr: the new position in the stream after parsing the type
+ *
+ * Returns: A MonoType structure that has the parsed information
+ * from the type stored at @ptr in the metadata table @m.
+ */
+MonoType *
+mono_metadata_parse_type (MonoMetadata *m, const char *ptr, const char **rptr)
+{
+ /* should probably be allocated in a memchunk */
+ MonoType *type = g_new0(MonoType, 1);
+
+ do_mono_metadata_parse_type (type, m, ptr, rptr);
+
+ return type;
+}
+
+void
+mono_metadata_free_type (MonoType *type)
+{
+ switch (type->type){
+ case MONO_TYPE_SZARRAY:
+ case MONO_TYPE_PTR:
+ if (!type->custom_mod) {
+ if (type->data.type)
+ mono_metadata_free_type (type->data.type);
+ } else if (type->data.mtype) {
+ mono_metadata_free_type (type->data.mtype->type);
+ g_free (type->data.mtype);
+ }
+ break;
+ case MONO_TYPE_FNPTR:
+ mono_metadata_free_method_signature (type->data.method);
+ break;
+ case MONO_TYPE_ARRAY:
+ mono_metadata_free_array (type->data.array);
+ break;
+ }
+ g_free (type);
+}
+
+static void
+hex_dump (const char *buffer, int base, int count)
+{
+ int show_header = 1;
+ int i;
+
+ if (count < 0){
+ count = -count;
+ show_header = 0;
+ }
+
+ for (i = 0; i < count; i++){
+ if (show_header)
+ if ((i % 16) == 0)
+ printf ("\n0x%08x: ", (unsigned char) base + i);
+
+ printf ("%02x ", (unsigned char) (buffer [i]));
+ }
+ fflush (stdout);
+}
+
+/**
+ * @mh: The Method header
+ * @ptr: Points to the beginning of the Section Data (25.3)
+ */
+static void
+parse_section_data (MonoMethodHeader *mh, const unsigned char *ptr)
+{
+ unsigned char sect_data_flags;
+ const unsigned char *sptr;
+ int is_fat;
+ guint32 sect_data_len;
+
+ while (1) {
+ /* align on 32-bit boundary */
+ /* FIXME: not 64-bit clean code */
+ sptr = ptr = dword_align (ptr);
+ sect_data_flags = *ptr;
+ ptr++;
+
+ is_fat = sect_data_flags & METHOD_HEADER_SECTION_FAT_FORMAT;
+ if (is_fat) {
+ sect_data_len = (ptr [2] << 16) | (ptr [1] << 8) | ptr [0];
+ ptr += 3;
+ } else {
+ sect_data_len = ptr [0];
+ ++ptr;
+ }
+ /*
+ g_print ("flags: %02x, len: %d\n", sect_data_flags, sect_data_len);
+ hex_dump (sptr, 0, sect_data_len+8);
+ g_print ("\nheader: ");
+ hex_dump (sptr-4, 0, 4);
+ g_print ("\n");
+ */
+
+ if (sect_data_flags & METHOD_HEADER_SECTION_EHTABLE) {
+ const unsigned char *p = dword_align (ptr);
+ int i;
+ mh->num_clauses = is_fat ? sect_data_len / 24: sect_data_len / 12;
+ /* we could just store a pointer if we don't need to byteswap */
+ mh->clauses = g_new0 (MonoExceptionClause, mh->num_clauses);
+ for (i = 0; i < mh->num_clauses; ++i) {
+ MonoExceptionClause *ec = &mh->clauses [i];
+ if (is_fat) {
+ /* we could memcpy and byteswap */
+ ec->flags = read32 (p);
+ p += 4;
+ ec->try_offset = read32 (p);
+ p += 4;
+ ec->try_len = read32 (p);
+ p += 4;
+ ec->handler_offset = read32 (p);
+ p += 4;
+ ec->handler_len = read32 (p);
+ p += 4;
+ ec->token_or_filter = read32 (p);
+ p += 4;
+ } else {
+ ec->flags = read16 (p);
+ p += 2;
+ ec->try_offset = read16 (p);
+ p += 2;
+ ec->try_len = *p;
+ ++p;
+ ec->handler_offset = read16 (p);
+ p += 2;
+ ec->handler_len = *p;
+ ++p;
+ ec->token_or_filter = read32 (p);
+ p += 4;
+ }
+ /* g_print ("try %d: %x %04x-%04x %04x\n", i, ec->flags, ec->try_offset, ec->try_offset+ec->try_len, ec->try_len); */
+ }
+ }
+ if (sect_data_flags & METHOD_HEADER_SECTION_MORE_SECTS)
+ ptr += sect_data_len - 4; /* LAMESPEC: it seems the size includes the header */
+ else
+ return;
+ }
+}
+
+MonoMethodHeader *
+mono_metadata_parse_mh (MonoMetadata *m, const char *ptr)
+{
+ MonoMethodHeader *mh;
+ unsigned char flags = *(unsigned char *) ptr;
+ unsigned char format = flags & METHOD_HEADER_FORMAT_MASK;
+ guint16 fat_flags;
+ guint32 local_var_sig_tok;
+ int hsize;
+
+ g_return_val_if_fail (ptr != NULL, NULL);
+
+ mh = g_new0 (MonoMethodHeader, 1);
+ switch (format){
+ case METHOD_HEADER_TINY_FORMAT:
+ ptr++;
+ mh->max_stack = 8;
+ local_var_sig_tok = 0;
+ mh->code_size = flags >> 2;
+ mh->code = ptr;
+ break;
+
+ case METHOD_HEADER_TINY_FORMAT1:
+ ptr++;
+ mh->max_stack = 8;
+ local_var_sig_tok = 0;
+
+ //
+ // The spec claims 3 bits, but the Beta2 is
+ // incorrect
+ //
+ mh->code_size = flags >> 2;
+ mh->code = ptr;
+ break;
+
+ case METHOD_HEADER_FAT_FORMAT:
+ fat_flags = read16 (ptr);
+ ptr += 2;
+ hsize = (fat_flags >> 12) & 0xf;
+ mh->max_stack = *(guint16 *) ptr;
+ ptr += 2;
+ mh->code_size = *(guint32 *) ptr;
+ ptr += 4;
+ local_var_sig_tok = *(guint32 *) ptr;
+ ptr += 4;
+
+ if (fat_flags & METHOD_HEADER_INIT_LOCALS)
+ mh->init_locals = 1;
+ else
+ mh->init_locals = 0;
+
+ mh->code = ptr;
+
+ if (!(fat_flags & METHOD_HEADER_MORE_SECTS))
+ break;
+
+ /*
+ * There are more sections
+ */
+ ptr = mh->code + mh->code_size;
+
+ parse_section_data (mh, (const unsigned char*)ptr);
+ break;
+
+ default:
+ g_free (mh);
+ return NULL;
+ }
+
+ if (local_var_sig_tok) {
+ MonoTableInfo *t = &m->tables [MONO_TABLE_STANDALONESIG];
+ const char *ptr;
+ guint32 cols [MONO_STAND_ALONG_SIGNATURE_SIZE];
+ int len=0, i, bsize;
+ guint offset = 0;
+
+ mono_metadata_decode_row (t, (local_var_sig_tok & 0xffffff)-1, cols, 1);
+ ptr = mono_metadata_blob_heap (m, cols [MONO_STAND_ALONG_SIGNATURE]);
+ bsize = mono_metadata_decode_blob_size (ptr, &ptr);
+ if (*ptr != 0x07)
+ g_warning ("wrong signature for locals blob");
+ ptr++;
+ len = mono_metadata_decode_value (ptr, &ptr);
+ mh->num_locals = len;
+ if (!mh->num_locals)
+ return mh;
+ mh->locals = g_new (MonoType*, len);
+ for (i = 0; i < len; ++i) {
+ gboolean pinned = FALSE;
+ int val;
+ int align;
+ const char *p = ptr;
+ val = mono_metadata_decode_blob_size (ptr, &ptr);
+ if (val == MONO_TYPE_PINNED) {
+ p = ptr;
+ pinned = TRUE;
+ val = mono_metadata_decode_blob_size (ptr, &ptr);
+ }
+ if (val == MONO_TYPE_BYREF) {
+ p = ptr;
+ }
+ mh->locals [i] = mono_metadata_parse_type (m, p, &ptr);
+
+ if (pinned)
+ mh->locals [i]->constraint = MONO_TYPE_PINNED;
+ if (val == MONO_TYPE_BYREF)
+ mh->locals [i]->byref = 1;
+
+ val = mono_type_size (mh->locals [i], &align);
+ offset += (offset % align);
+ offset += val;
+ }
+ mh->locals_size = offset;
+ }
+ return mh;
+}
+
+void
+mono_metadata_free_mh (MonoMethodHeader *mh)
+{
+ int i;
+ for (i = 0; i < mh->num_locals; ++i)
+ mono_metadata_free_type (mh->locals[i]);
+ g_free (mh->locals);
+ g_free (mh->clauses);
+ g_free (mh);
+}
+
+/**
+ * mono_metadata_parse_field_type:
+ * @m: metadata context to extract information from
+ * @ptr: pointer to the field signature
+ *
+ * Parses the field signature, and returns the type information for it.
+ *
+ * Returns: The MonoFieldType that was extracted from @ptr.
+ */
+MonoFieldType *
+mono_metadata_parse_field_type (MonoMetadata *m, const char *ptr, const char **rptr)
+{
+ return mono_metadata_parse_param (m, 0, ptr, rptr);
+}
+
+/*
+ * mono_metadata_token_from_dor:
+ * @dor_token: A TypeDefOrRef coded index
+ *
+ * dor_token is a TypeDefOrRef coded index: it contains either
+ * a TypeDef, TypeRef or TypeSpec in the lower bits, and the upper
+ * bits contain an index into the table.
+ *
+ * Returns: an expanded token
+ */
+guint32
+mono_metadata_token_from_dor (guint32 dor_index)
+{
+ int table, idx;
+
+ table = dor_index & 0x03;
+ idx = dor_index >> 2;
+
+ switch (table){
+ case 0: /* TypeDef */
+ return MONO_TOKEN_TYPE_DEF | idx;
+
+ case 1: /* TypeRef */
+ return MONO_TOKEN_TYPE_REF | idx;
+
+ case 2: /* TypeSpec */
+ return MONO_TOKEN_TYPE_SPEC | idx;
+
+ default:
+ g_assert_not_reached ();
+ }
+
+ return 0;
+}
+
+/*
+ * We use this to pass context information to the row locator
+ */
+typedef struct {
+ int idx; /* The index that we are trying to locate */
+ int col_idx; /* The index in the row where idx may be stored */
+ MonoTableInfo *t; /* pointer to the table */
+ guint32 result;
+} locator_t;
+
+#define CSIZE(x) (sizeof (x) / 4)
+
+/*
+ * How the row locator works.
+ *
+ * Table A
+ * ___|___
+ * ___|___ Table B
+ * ___|___------> _______
+ * ___|___ _______
+ *
+ * A column in the rows of table A references an index in table B.
+ * For example A may be the TYPEDEF table and B the METHODDEF table.
+ *
+ * Given an index in table B we want to get the row in table A
+ * where the column n references our index in B.
+ *
+ * In the locator_t structure:
+ * t is table A
+ * col_idx is the column number
+ * index is the index in table B
+ * result will be the index in table A
+ *
+ * Examples:
+ * Table A Table B column (in table A)
+ * TYPEDEF METHODDEF MONO_TYPEDEF_METHOD_LIST
+ * TYPEDEF FIELD MONO_TYPEDEF_FIELD_LIST
+ * PROPERTYMAP PROPERTY MONO_PROPERTY_MAP_PROPERTY_LIST
+ * METHODSEM PROPERTY ASSOCIATION (encoded index)
+ *
+ * Note that we still don't support encoded indexes.
+ *
+ */
+static int
+typedef_locator (const void *a, const void *b)
+{
+ locator_t *loc = (locator_t *) a;
+ char *bb = (char *) b;
+ int typedef_index = (bb - loc->t->base) / loc->t->row_size;
+ guint32 col, col_next;
+
+ col = mono_metadata_decode_row_col (loc->t, typedef_index, loc->col_idx);
+
+ if (loc->idx < col)
+ return -1;
+
+ /*
+ * Need to check that the next row is valid.
+ */
+ if (typedef_index + 1 < loc->t->rows) {
+ col_next = mono_metadata_decode_row_col (loc->t, typedef_index + 1, loc->col_idx);
+ if (loc->idx >= col_next)
+ return 1;
+
+ if (col == col_next)
+ return 1;
+ }
+
+ loc->result = typedef_index;
+
+ return 0;
+}
+
+guint32
+mono_metadata_typedef_from_field (MonoMetadata *meta, guint32 index)
+{
+ MonoTableInfo *tdef = &meta->tables [MONO_TABLE_TYPEDEF];
+ locator_t loc;
+
+ loc.idx = mono_metadata_token_index (index);
+ loc.col_idx = MONO_TYPEDEF_FIELD_LIST;
+ loc.t = tdef;
+
+ if (!bsearch (&loc, tdef->base, tdef->rows, tdef->row_size, typedef_locator))
+ g_assert_not_reached ();
+
+ /* loc_result is 0..1, needs to be mapped to table index (that is +1) */
+ return loc.result + 1;
+}
+
+guint32
+mono_metadata_typedef_from_method (MonoMetadata *meta, guint32 index)
+{
+ MonoTableInfo *tdef = &meta->tables [MONO_TABLE_TYPEDEF];
+ locator_t loc;
+
+ loc.idx = mono_metadata_token_index (index);
+ loc.col_idx = MONO_TYPEDEF_METHOD_LIST;
+ loc.t = tdef;
+
+ if (!bsearch (&loc, tdef->base, tdef->rows, tdef->row_size, typedef_locator))
+ g_assert_not_reached ();
+
+ /* loc_result is 0..1, needs to be mapped to table index (that is +1) */
+ return loc.result + 1;
+}
+
+#ifndef __GNUC__
+#define __alignof__(a) sizeof(a)
+#endif
+
+/*
+ * mono_type_size:
+ * @t: the type to return the size of
+ *
+ * Returns: the number of bytes required to hold an instance of this
+ * type in memory
+ */
+int
+mono_type_size (MonoType *t, gint *align)
+{
+ if (!t) {
+ *align = 1;
+ return 0;
+ }
+ if (t->byref) {
+ *align = __alignof__(gpointer);
+ return sizeof (gpointer);
+ }
+
+ switch (t->type){
+ case MONO_TYPE_VOID:
+ *align = 1;
+ return 0;
+ case MONO_TYPE_BOOLEAN:
+ *align = __alignof__(char);
+ return sizeof (char);
+
+ case MONO_TYPE_CHAR:
+ *align = __alignof__(short);
+ return sizeof (short);
+
+ case MONO_TYPE_I1:
+ case MONO_TYPE_U1:
+ *align = __alignof__(char);
+ return 1;
+
+ case MONO_TYPE_I2:
+ case MONO_TYPE_U2:
+ *align = __alignof__(gint16);
+ return 2;
+
+ case MONO_TYPE_I4:
+ case MONO_TYPE_U4:
+ *align = __alignof__(gint32);
+ return 4;
+ case MONO_TYPE_R4:
+ *align = __alignof__(float);
+ return 4;
+
+ case MONO_TYPE_I8:
+ case MONO_TYPE_U8:
+ *align = __alignof__(gint64);
+ case MONO_TYPE_R8:
+ *align = __alignof__(double);
+ return 8;
+
+ case MONO_TYPE_I:
+ case MONO_TYPE_U:
+ *align = __alignof__(gpointer);
+ return sizeof (gpointer);
+
+ case MONO_TYPE_STRING:
+ *align = __alignof__(gpointer);
+ return sizeof (gpointer);
+
+ case MONO_TYPE_OBJECT:
+ *align = __alignof__(gpointer);
+ return sizeof (gpointer);
+
+ case MONO_TYPE_VALUETYPE:
+ *align = __alignof__(gpointer);
+ /*
+ * FIXME: very bogus value
+ */
+ g_warning ("fixme: wrong size for value type");
+ return 4;
+ case MONO_TYPE_CLASS:
+ case MONO_TYPE_SZARRAY:
+ case MONO_TYPE_PTR:
+ case MONO_TYPE_FNPTR:
+ case MONO_TYPE_ARRAY:
+ case MONO_TYPE_TYPEDBYREF: /* we may want to use a struct {MonoType* type, void *data } instead ...*/
+ *align = __alignof__(gpointer);
+ return sizeof (gpointer);
+ default:
+ g_error ("type 0x%02x unknown", t->type);
+ }
+ return 0;
+}
+
+static gboolean
+mono_metadata_type_token_equal (MonoMetadata *m1, guint32 token1,
+ MonoMetadata *m2, guint32 token2)
+{
+ int table1 = mono_metadata_token_table (token1);
+ int index1 = mono_metadata_token_index (token1);
+ int table2 = mono_metadata_token_table (token2);
+ int index2 = mono_metadata_token_index (token2);
+ guint32 cols[MAX (MONO_TYPEDEF_SIZE, MONO_TYPEREF_SIZE)];
+ const char *name1, *nspace1;
+ const char *name2, *nspace2;
+
+ switch (table1) {
+ case MONO_TABLE_TYPEDEF:
+ mono_metadata_decode_row (&m1->tables [table1], index1 - 1, cols, MONO_TYPEDEF_SIZE);
+ name1 = mono_metadata_string_heap (m1, cols [MONO_TYPEDEF_NAME]);
+ nspace1 = mono_metadata_string_heap (m1, cols [MONO_TYPEDEF_NAMESPACE]);
+ break;
+ case MONO_TABLE_TYPEREF:
+ mono_metadata_decode_row (&m1->tables [table1], index1 - 1, cols, MONO_TYPEREF_SIZE);
+ name1 = mono_metadata_string_heap (m1, cols [MONO_TYPEREF_NAME]);
+ nspace1 = mono_metadata_string_heap (m1, cols [MONO_TYPEREF_NAMESPACE]);
+ break;
+ default:
+ g_assert_not_reached ();
+ }
+
+
+ switch (table2) {
+ case MONO_TABLE_TYPEDEF:
+ mono_metadata_decode_row (&m2->tables [table2], index2 - 1, cols, MONO_TYPEDEF_SIZE);
+ name2 = mono_metadata_string_heap (m2, cols [MONO_TYPEDEF_NAME]);
+ nspace2 = mono_metadata_string_heap (m2, cols [MONO_TYPEDEF_NAMESPACE]);
+ break;
+ case MONO_TABLE_TYPEREF:
+ mono_metadata_decode_row (&m2->tables [table2], index2 -1, cols, MONO_TYPEREF_SIZE);
+ name2 = mono_metadata_string_heap (m2, cols [MONO_TYPEREF_NAME]);
+ nspace2 = mono_metadata_string_heap (m2, cols [MONO_TYPEREF_NAMESPACE]);
+ break;
+ default:
+ g_assert_not_reached ();
+ }
+
+
+ if (strcmp (nspace1, nspace2))
+ return FALSE;
+
+ if (strcmp (name1, name2))
+ return FALSE;
+
+ return TRUE;
+}
+
+static gboolean
+mono_metadata_type_equal (MonoMetadata *m1, MonoType *t1, MonoMetadata *m2, MonoType *t2)
+{
+ if (t1->type != t2->type ||
+ t1->byref != t2->byref)
+ return FALSE;
+
+ switch (t1->type) {
+ case MONO_TYPE_VOID:
+ case MONO_TYPE_BOOLEAN:
+ case MONO_TYPE_CHAR:
+ case MONO_TYPE_I1:
+ case MONO_TYPE_U1:
+ case MONO_TYPE_I2:
+ case MONO_TYPE_U2:
+ case MONO_TYPE_I4:
+ case MONO_TYPE_U4:
+ case MONO_TYPE_I8:
+ case MONO_TYPE_U8:
+ case MONO_TYPE_R4:
+ case MONO_TYPE_R8:
+ case MONO_TYPE_STRING:
+ case MONO_TYPE_I:
+ case MONO_TYPE_U:
+ case MONO_TYPE_OBJECT:
+ break;
+ case MONO_TYPE_VALUETYPE:
+ case MONO_TYPE_CLASS:
+ return mono_metadata_type_token_equal (m1, t1->data.token, m2, t2->data.token);
+ default:
+ g_error ("implement type compare for %0x!", t1->type);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+gboolean
+mono_metadata_signature_equal (MonoMetadata *m1, MonoMethodSignature *sig1,
+ MonoMetadata *m2, MonoMethodSignature *sig2)
+{
+ int i;
+
+ if (sig1->hasthis != sig2->hasthis ||
+ sig1->param_count != sig2->param_count)
+ return FALSE;
+
+ for (i = 0; i < sig1->param_count; i++) {
+ MonoParam *p1 = sig1->params[i];
+ MonoParam *p2 = sig2->params[i];
+
+ if (p1->param_attrs != p2->param_attrs ||
+ p1->typedbyref != p2->typedbyref)
+ return FALSE;
+
+ if (!mono_metadata_type_equal (m1, p1->type, m2, p2->type))
+ return FALSE;
+ }
+
+ return TRUE;
+}
diff --git a/mono/metadata/metadata.h b/mono/metadata/metadata.h
index 6e34877013f..4c88a2b8e20 100644
--- a/mono/metadata/metadata.h
+++ b/mono/metadata/metadata.h
@@ -1,18 +1,263 @@
+#ifndef __MONO_METADATA_H__
+#define __MONO_METADATA_H__
+
+#include <glib.h>
+
+#include <mono/metadata/blob.h>
+#include <mono/metadata/row-indexes.h>
+#include <mono/metadata/image.h>
+
+#ifdef __GNUC__
+#define MONO_ZERO_LEN_ARRAY 0
+#else
+#define MONO_ZERO_LEN_ARRAY 1
+#endif
+
+typedef enum {
+ MONO_TABLE_MODULE,
+ MONO_TABLE_TYPEREF,
+ MONO_TABLE_TYPEDEF,
+ MONO_TABLE_UNUSED1,
+ MONO_TABLE_FIELD,
+ MONO_TABLE_UNUSED2,
+ MONO_TABLE_METHOD,
+ MONO_TABLE_UNUSED3,
+ MONO_TABLE_PARAM,
+ MONO_TABLE_INTERFACEIMPL,
+ MONO_TABLE_MEMBERREF,
+ MONO_TABLE_CONSTANT,
+ MONO_TABLE_CUSTOMATTRIBUTE,
+ MONO_TABLE_FIELDMARSHAL,
+ MONO_TABLE_DECLSECURITY,
+ MONO_TABLE_CLASSLAYOUT,
+ MONO_TABLE_FIELDLAYOUT,
+ MONO_TABLE_STANDALONESIG,
+ MONO_TABLE_EVENTMAP,
+ MONO_TABLE_UNUSED4,
+ MONO_TABLE_EVENT,
+ MONO_TABLE_PROPERTYMAP,
+ MONO_TABLE_UNUSED5,
+ MONO_TABLE_PROPERTY,
+ MONO_TABLE_METHODSEMANTICS,
+ MONO_TABLE_METHODIMPL,
+ MONO_TABLE_MODULEREF,
+ MONO_TABLE_TYPESPEC,
+ MONO_TABLE_IMPLMAP,
+ MONO_TABLE_FIELDRVA,
+ MONO_TABLE_UNUSED6,
+ MONO_TABLE_UNUSED7,
+ MONO_TABLE_ASSEMBLY,
+ MONO_TABLE_ASSEMBLYPROCESSOR,
+ MONO_TABLE_ASSEMBLYOS,
+ MONO_TABLE_ASSEMBLYREF,
+ MONO_TABLE_ASSEMBLYREFPROCESSOR,
+ MONO_TABLE_ASSEMBLYREFOS,
+ MONO_TABLE_FILE,
+ MONO_TABLE_EXPORTEDTYPE,
+ MONO_TABLE_MANIFESTRESOURCE,
+ MONO_TABLE_NESTEDCLASS,
+
+#define MONO_TABLE_LAST MONO_TABLE_NESTEDCLASS
+} MonoMetaTableEnum;
+
+typedef enum {
+ MONO_EXCEPTION_CLAUSE_NONE,
+ MONO_EXCEPTION_CLAUSE_FILTER,
+ MONO_EXCEPTION_CLAUSE_FINALLY,
+ MONO_EXCEPTION_CLAUSE_FAULT = 4
+} MonoExceptionEnum;
+
+typedef enum {
+ MONO_CALL_DEFAULT,
+ MONO_CALL_C,
+ MONO_CALL_STDCALL,
+ MONO_CALL_THISCALL,
+ MONO_CALL_FASTCALL,
+ MONO_CALL_VARARG
+} MonoCallConvention;
+
+void mono_metadata_decode_row (MonoTableInfo *t,
+ int idx,
+ guint32 *res,
+ int res_size);
+
+guint32 mono_metadata_decode_row_col (MonoTableInfo *t,
+ int idx,
+ guint col);
+
+/*
+ * This macro is used to extract the size of the table encoded in
+ * the size_bitfield of MonoTableInfo.
+ */
+#define mono_metadata_table_size(bitfield,table) ((((bitfield) >> ((table)*2)) & 0x3) + 1)
+#define mono_metadata_table_count(bitfield) ((bitfield) >> 24)
+
+/*
+ *
+ */
+char *mono_metadata_locate (MonoMetadata *meta, int table, int idx);
+char *mono_metadata_locate_token (MonoMetadata *meta, guint32 token);
+
+const char *mono_metadata_string_heap (MonoMetadata *meta, guint32 index);
+const char *mono_metadata_blob_heap (MonoMetadata *meta, guint32 index);
+const char *mono_metadata_user_string (MonoMetadata *meta, guint32 index);
+
+guint32 mono_metadata_typedef_from_field (MonoMetadata *meta, guint32 index);
+guint32 mono_metadata_typedef_from_method (MonoMetadata *meta, guint32 index);
+
+/*
+ * Functions to extract information from the Blobs
+ */
+guint32 mono_metadata_decode_value (const char *ptr,
+ const char **rptr);
+guint32 mono_metadata_decode_blob_size (const char *ptr,
+ const char **rptr);
+
+typedef struct {
+ guint32 flags;
+ guint32 try_offset;
+ guint32 try_len;
+ guint32 handler_offset;
+ guint32 handler_len;
+ guint32 token_or_filter;
+} MonoExceptionClause;
+
+typedef struct _MonoType MonoType;
+typedef struct _MonoArray MonoArray;
+typedef struct _MonoMethodSignature MonoMethodSignature;
+
typedef struct {
- guint32 sh_offset;
- guint32 sh_size;
-} stream_header_t;
+ guchar mod;
+ guint32 token;
+} MonoCustomMod;
typedef struct {
- char *raw_metadata;
+ MonoType *type;
+ int num_modifiers;
+ MonoCustomMod modifiers [MONO_ZERO_LEN_ARRAY]; /* this may grow */
+} MonoModifiedType;
+
+struct _MonoArray {
+ MonoType *type;
+ int rank;
+ int numsizes;
+ int numlobounds;
+ int *sizes;
+ int *lobounds;
+};
+
+struct _MonoType {
+ guchar type; /* ElementTypeEnum */
+ guchar custom_mod; /* for PTR and SZARRAY: use data.mtype instead of data.type */
+ guchar byref; /* when included in a MonoRetType */
+ guchar constraint; /* valid when included in a local var signature */
+ union {
+ guint32 token; /* for VALUETYPE and CLASS */
+ MonoType *type;
+ MonoModifiedType *mtype;
+ MonoArray *array; /* for ARRAY */
+ MonoMethodSignature *method;
+ } data;
+};
+
+typedef struct {
+ /* maybe use a union here: saves 4 bytes */
+ MonoType *type; /* NULL for VOID */
+ short param_attrs; /* 22.1.11 */
+ char typedbyref;
+ char num_modifiers;
+ MonoCustomMod modifiers [MONO_ZERO_LEN_ARRAY]; /* this may grow */
+} MonoRetType;
+
+/* MonoRetType is used also for params and fields */
+typedef MonoRetType MonoParam;
+typedef MonoRetType MonoFieldType;
+
+struct _MonoMethodSignature {
+ char hasthis;
+ char explicit_this;
+ char call_convention;
+ guint16 param_count;
+ guint16 sentinelpos;
+ MonoRetType *ret;
+ MonoParam **params;
+ guint32 params_size;
+};
+
+typedef struct {
+ guint32 code_size;
+ const unsigned char *code;
+ guint16 max_stack;
+ unsigned int num_clauses : 15;
+ /* if num_locals != 0, then the following apply: */
+ unsigned int init_locals : 1;
+ guint16 num_locals;
+ MonoType **locals;
+ guint32 locals_size;
+ MonoExceptionClause *clauses;
+} MonoMethodHeader;
+
+guint32 mono_metadata_parse_typedef_or_ref (MonoMetadata *m,
+ const char *ptr,
+ const char **rptr);
+int mono_metadata_parse_custom_mod (MonoMetadata *m,
+ MonoCustomMod *dest,
+ const char *ptr,
+ const char **rptr);
+MonoArray *mono_metadata_parse_array (MonoMetadata *m,
+ const char *ptr,
+ const char **rptr);
+void mono_metadata_free_array (MonoArray *array);
+MonoParam *mono_metadata_parse_param (MonoMetadata *m,
+ int rettype,
+ const char *ptr,
+ const char **rptr);
+void mono_metadata_free_param (MonoParam *param);
+MonoType *mono_metadata_parse_type (MonoMetadata *m,
+ const char *ptr,
+ const char **rptr);
+void mono_metadata_free_type (MonoType *type);
+int mono_type_size (MonoType *type,
+ int *alignment);
+
+MonoFieldType *mono_metadata_parse_field_type (MonoMetadata *m,
+ const char *ptr,
+ const char **rptr);
+
+
+MonoMethodSignature *mono_metadata_parse_method_signature (MonoMetadata *m,
+ int def,
+ const char *ptr,
+ const char **rptr);
+void mono_metadata_free_method_signature (MonoMethodSignature *method);
+
+gboolean mono_metadata_signature_equal (MonoMetadata *m1,
+ MonoMethodSignature *sig1,
+ MonoMetadata *m2,
+ MonoMethodSignature *sig2);
+
+MonoMethodHeader *mono_metadata_parse_mh (MonoMetadata *m, const char *ptr);
+void mono_metadata_free_mh (MonoMethodHeader *mh);
+
+/*
+ * Makes a token based on a table and an index
+ */
+#define mono_metadata_make_token(table,idx) (((table) << 24)| idx)
+
+/*
+ * Returns the table index that this token encodes.
+ */
+#define mono_metadata_token_table(token) ((token) >> 24)
+
+ /*
+ * Returns the index that a token refers to
+ */
+#define mono_metadata_token_index(token) ((token & 0xffffff))
+
- stream_header_t heap_strings;
- stream_header_t heap_us;
- stream_header_t heap_blob;
- stream_header_t heap_guid;
- stream_header_t heap_tables;
+#define mono_metadata_token_code(token) ((token & 0xff000000))
- guint32 rows [64];
-} metadata_t;
+guint32 mono_metadata_token_from_dor (guint32 dor_index);
+#endif /* __MONO_METADATA_H__ */
diff --git a/mono/metadata/metaparse.h b/mono/metadata/metaparse.h
new file mode 100644
index 00000000000..2db1b82c906
--- /dev/null
+++ b/mono/metadata/metaparse.h
@@ -0,0 +1,16 @@
+#ifndef _MONO_METADATA_METAPARSE_H_
+#define _MONO_METADATA_METAPARSE_H__
+
+typedef struct {
+ guint32 cols [6];
+ struct {
+ guint32 first, last;
+ } field;
+ struct {
+ guint32 first, last;
+ } method;
+} MonoTypedef;
+
+void mono_typedef_get (MonoImage *image, guint32 tidx, MonoTypedef *ret);
+
+#endif
diff --git a/mono/metadata/mono-endian.h b/mono/metadata/mono-endian.h
new file mode 100644
index 00000000000..8da0e4126e0
--- /dev/null
+++ b/mono/metadata/mono-endian.h
@@ -0,0 +1,13 @@
+#ifndef _MONO_METADATA_ENDIAN_H_
+#define _MONO_METADATA_ENDIAN_H_ 1
+
+/* FIXME: implement big endian versions */
+
+#define le64_to_cpu(x) (x)
+#define le32_to_cpu(x) (x)
+#define le16_to_cpu(x) (x)
+#define read32(x) le32_to_cpu (*((guint32 *) (x)))
+#define read16(x) le16_to_cpu (*((guint16 *) (x)))
+#define read64(x) le64_to_cpu (*((guint64 *) (x)))
+
+#endif /* _MONO_METADATA_ENDIAN_H_ */
diff --git a/mono/metadata/object.c b/mono/metadata/object.c
new file mode 100644
index 00000000000..7f34e6e3eca
--- /dev/null
+++ b/mono/metadata/object.c
@@ -0,0 +1,222 @@
+/*
+ * object.c: Object creation for the Mono runtime
+ *
+ * Author:
+ * Miguel de Icaza (miguel@ximian.com)
+ *
+ * (C) 2001 Ximian, Inc.
+ */
+#include <config.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <mono/metadata/loader.h>
+#include <mono/metadata/object.h>
+
+/**
+ * mono_object_allocate:
+ * @size: number of bytes to allocate
+ *
+ * This is a very simplistic routine until we have our GC-aware
+ * memory allocator.
+ *
+ * Returns: an allocated object of size @size, or NULL on failure.
+ */
+static void *
+mono_object_allocate (size_t size)
+{
+ void *o = calloc (1, size);
+
+ return o;
+}
+
+/**
+ * mono_object_free:
+ *
+ * Frees the memory used by the object. Debugging purposes
+ * only, as we will have our GC system.
+ */
+void
+mono_object_free (MonoObject *o)
+{
+ MonoClass *c = o->klass;
+
+ memset (o, 0, c->instance_size);
+ free (o);
+}
+
+/**
+ * mono_object_new:
+ * @image: Context where the type_token is hosted
+ * @type_token: a token of the type that we want to create
+ *
+ * Returns: A newly created object whose definition is
+ * looked up using @type_token in the @image image
+ */
+MonoObject *
+mono_object_new (MonoImage *image, guint32 type_token)
+{
+ MonoClass *c;
+ MonoObject *o;
+
+ c = mono_class_get (image, type_token);
+ o = mono_object_allocate (c->instance_size);
+ o->klass = c;
+
+ return o;
+}
+
+/**
+ * mono_object_clone:
+ * @obj: the object to clone
+ *
+ * Returns: A newly created object who is a shallow copy of @obj
+ */
+MonoObject *
+mono_object_clone (MonoObject *obj)
+{
+ MonoObject *o;
+ int size;
+
+ size = obj->klass->instance_size;
+ o = mono_object_allocate (size);
+
+ memcpy (o, obj, size);
+
+ return o;
+}
+
+/*
+ * mono_new_szarray:
+ * @image: image where the object is being referenced
+ * @etype: element type token
+ * @n: number of array elements
+ *
+ * This routine creates a new szarray with @n elements of type @token
+ */
+MonoObject *
+mono_new_szarray (MonoImage *image, guint32 etype, guint32 n)
+{
+ MonoClass *c;
+ MonoObject *o;
+ MonoArrayObject *ao;
+ MonoArrayClass *ac;
+
+ c = mono_array_class_get (image, etype, 1);
+ g_assert (c != NULL);
+
+ o = mono_object_allocate (c->instance_size);
+ o->klass = c;
+
+ ao = (MonoArrayObject *)o;
+ ac = (MonoArrayClass *)c;
+
+ ao->bounds = g_malloc0 (sizeof (MonoArrayBounds));
+ ao->bounds [0].length = n;
+ ao->bounds [0].lower_bound = 0;
+
+
+ ao->vector = g_malloc0 (n * mono_array_element_size (ac));
+
+ return o;
+}
+
+/**
+ * mono_new_utf16_string:
+ * @text: a pointer to an utf16 string
+ * @len: the length of the string
+ *
+ * Returns: A newly created string object which contains @text.
+ */
+MonoObject *
+mono_new_utf16_string (const char *text, gint32 len)
+{
+ MonoObject *s;
+ MonoArrayObject *ca;
+
+ s = mono_object_new (mono_defaults.corlib, mono_defaults.string_token);
+ g_assert (s != NULL);
+
+ ca = (MonoArrayObject *)mono_new_szarray (mono_defaults.corlib, mono_defaults.string_token, len);
+ g_assert (ca != NULL);
+
+ ((MonoStringObject *)s)->c_str = ca;
+ ((MonoStringObject *)s)->length = len;
+
+ memcpy (ca->vector, text, len * 2);
+
+ return s;
+}
+
+/**
+ * mono_new_string:
+ * @text: a pointer to an utf8 string
+ *
+ * Returns: A newly created string object which contains @text.
+ */
+MonoObject *
+mono_new_string (const char *text)
+{
+ MonoObject *o;
+ guint16 *ut;
+ int i, l;
+
+ /* fixme: use some kind of unicode library here */
+
+ l = strlen (text);
+ ut = g_malloc (l*2);
+
+ for (i = 0; i < l; i++)
+ ut [i] = text[i];
+
+ o = mono_new_utf16_string ((char *)ut, l);
+
+ g_free (ut);
+
+ return o;
+}
+
+/**
+ * mono_value_box:
+ * @class: the class of the value
+ * @value: a pointer to the unboxed data
+ *
+ * Returns: A newly created object which contains @value.
+ */
+MonoObject *
+mono_value_box (MonoClass *class, gpointer value)
+{
+ MonoObject *res;
+ int size;
+
+ g_assert (class->valuetype);
+
+ res = mono_object_allocate (class->instance_size);
+ res->klass = class;
+
+ size = res->klass->instance_size - sizeof (MonoObject);
+
+ memcpy ((char *)res + sizeof (MonoObject), value, size);
+
+ return res;
+}
+
+/**
+ * mono_object_isinst:
+ * @obj: an object
+ * @klass: a pointer to a class
+ *
+ * Returns: #TRUE if @obj is derived from @klass
+ */
+gboolean
+mono_object_isinst (MonoObject *obj, MonoClass *klass)
+{
+ MonoClass *oklass = obj->klass;
+
+ while (oklass) {
+ if (oklass == klass)
+ return TRUE;
+ oklass = oklass->parent;
+ }
+ return FALSE;
+}
+
diff --git a/mono/metadata/object.h b/mono/metadata/object.h
new file mode 100644
index 00000000000..cf9447a9154
--- /dev/null
+++ b/mono/metadata/object.h
@@ -0,0 +1,52 @@
+#ifndef _MONO_CLI_OBJECT_H_
+#define _MONO_CLI_OBJECT_H_
+
+#include <mono/metadata/class.h>
+
+typedef struct {
+ MonoClass *klass;
+} MonoObject;
+
+typedef struct {
+ guint32 length;
+ guint32 lower_bound;
+} MonoArrayBounds;
+
+typedef struct {
+ MonoObject obj;
+ gpointer vector;
+ MonoArrayBounds *bounds;
+} MonoArrayObject;
+
+typedef struct {
+ MonoObject obj;
+ MonoArrayObject *c_str;
+ gint32 length;
+} MonoStringObject;
+
+MonoObject *
+mono_object_new (MonoImage *image, guint32 type_token);
+
+MonoObject *
+mono_new_szarray (MonoImage *image, guint32 etype, guint32 n);
+
+MonoObject *
+mono_new_utf16_string (const char *text, gint32 len);
+
+MonoObject *
+mono_new_string (const char *text);
+
+void
+mono_object_free (MonoObject *o);
+
+MonoObject *
+mono_value_box (MonoClass *class, gpointer val);
+
+MonoObject *
+mono_object_clone (MonoObject *obj);
+
+gboolean
+mono_object_isinst (MonoObject *obj, MonoClass *klass);
+
+#endif
+
diff --git a/mono/metadata/pedump.c b/mono/metadata/pedump.c
index 7a716cf3ea7..a0019a263ef 100644
--- a/mono/metadata/pedump.c
+++ b/mono/metadata/pedump.c
@@ -8,9 +8,14 @@
*/
#include <config.h>
#include <stdio.h>
-#include "assembly.h"
+#include <string.h>
+#include "image.h"
#include <glib.h>
#include "cil-coff.h"
+#include "private.h"
+
+gboolean dump_data = TRUE;
+gboolean dump_tables = FALSE;
static void
hex_dump (char *buffer, int base, int count)
@@ -44,7 +49,7 @@ hex32 (char *label, guint32 x)
}
static void
-dump_coff_header (coff_header_t *coff)
+dump_coff_header (MonoCOFFHeader *coff)
{
printf ("\nCOFF Header:\n");
hex16 (" Machine", coff->coff_machine);
@@ -58,7 +63,7 @@ dump_coff_header (coff_header_t *coff)
}
static void
-dump_pe_header (pe_header_t *pe)
+dump_pe_header (MonoPEHeader *pe)
{
printf ("\nPE Header:\n");
hex16 (" Magic (0x010b)", pe->pe_magic);
@@ -74,7 +79,7 @@ dump_pe_header (pe_header_t *pe)
}
static void
-dump_nt_header (pe_header_nt_t *nt)
+dump_nt_header (MonoPEHeaderNT *nt)
{
printf ("\nNT Header:\n");
@@ -102,13 +107,13 @@ dump_nt_header (pe_header_nt_t *nt)
}
static void
-dent (const char *label, pe_dir_entry_t de)
+dent (const char *label, MonoPEDirEntry de)
{
printf ("\t%s: 0x%08x [0x%08x]\n", label, de.rva, de.size);
}
static void
-dump_datadir (pe_datadir_t *dd)
+dump_datadir (MonoPEDatadir *dd)
{
printf ("\nData directories:\n");
dent (" Export Table", dd->pe_export_table);
@@ -129,7 +134,7 @@ dump_datadir (pe_datadir_t *dd)
}
static void
-dump_dotnet_header (dotnet_header_t *header)
+dump_dotnet_header (MonoDotNetHeader *header)
{
dump_coff_header (&header->coff);
dump_pe_header (&header->pe);
@@ -138,7 +143,7 @@ dump_dotnet_header (dotnet_header_t *header)
}
static void
-dump_section_table (section_table_t *st)
+dump_section_table (MonoSectionTable *st)
{
guint32 flags = st->st_flags;
@@ -166,17 +171,17 @@ dump_section_table (section_table_t *st)
}
static void
-dump_sections (dotnet_image_info_t *iinfo)
+dump_sections (MonoCLIImageInfo *iinfo)
{
- const int top = iinfo->dn_header.coff.coff_sections;
+ const int top = iinfo->cli_header.coff.coff_sections;
int i;
for (i = 0; i < top; i++)
- dump_section_table (&iinfo->dn_section_tables [i]);
+ dump_section_table (&iinfo->cli_section_tables [i]);
}
static void
-dump_cli_header (cli_header_t *ch)
+dump_cli_header (MonoCLIHeader *ch)
{
printf ("\n");
printf (" CLI header size: %d\n", ch->ch_size);
@@ -195,92 +200,87 @@ dump_cli_header (cli_header_t *ch)
}
static void
-dsh (char *label, dotnet_image_info_t *iinfo, stream_header_t *sh)
+dsh (char *label, MonoStreamHeader *sh)
{
printf ("%s: 0x%08x - 0x%08x [%d == 0x%08x]\n",
label,
- sh->sh_offset, sh->sh_offset + sh->sh_size,
- sh->sh_size, sh->sh_size);
+ sh->offset, sh->offset + sh->size,
+ sh->size, sh->size);
}
static void
-dump_metadata_ptrs (dotnet_image_info_t *iinfo)
+dump_metadata_ptrs (MonoMetadata *meta)
{
- metadata_t *meta = &iinfo->dn_metadata;
-
printf ("\nMetadata pointers:\n");
- dsh ("\tTables (#~)", iinfo, &meta->heap_tables);
- dsh ("\t Strings", iinfo, &meta->heap_strings);
- dsh ("\t Blob", iinfo, &meta->heap_blob);
- dsh ("\tUser string", iinfo, &meta->heap_us);
- dsh ("\t GUID", iinfo, &meta->heap_guid);
+ dsh ("\tTables (#~)", &meta->heap_tables);
+ dsh ("\t Strings", &meta->heap_strings);
+ dsh ("\t Blob", &meta->heap_blob);
+ dsh ("\tUser string", &meta->heap_us);
+ dsh ("\t GUID", &meta->heap_guid);
}
-static const char *
-table_to_string (int table)
+static void
+dump_table (MonoMetadata *meta, int table)
{
- char *map_table_to_string [] = {
- /* 0 */ "Module", "TypeRef", "TypeDef", "FieldPtr",
- /* 4 */ "FieldDef", "MethodPtr", "MethodDef", "ParamPtr",
- /* 8 */ "ParamDef", "InterfaceImpl", "MemberRef", "FieldInit",
- /* 12 */ "CustomAttr", "MarshalDef", "Permission", "LayoutDef",
- /* 16 */ "FieldOffset", "Signature", "EventAssoc", "EventPtr",
- /* 20 */ "Event", "PropertyAssoc", "PropertyPtr", "Property",
- /* 24 */ "MethodAssoc", "MethodImpl", "ModuleRef", "TypeSpec",
- /* 28 */ "PInvoke", "Data", "EncLog", "EncAssoc",
- /* 32 */ "Assembly", "ProcessorDef", "OSDef", "AssemblyRef",
- /* 36 */ "ProcessorRef", "OSRef", "File", "ComType",
- /* 40 */ "ManifestResource", "ExeLocation", "42", "43",
- /* 44 */ "44", "45", "NestedClass", "47"
- /* 48 */ "48", "49", "50", "51",
- /* 52 */ "52", "53", "54", "55"
- /* 56 */ "56", "57", "58", "59"
- /* 60 */ "60", "61", "62", "63"
- };
-
- if (table < 0 || table > 63)
- return "Unknown table name";
- return map_table_to_string [table];
}
static void
-dump_metadata (dotnet_image_info_t *iinfo)
+dump_metadata (MonoMetadata *meta)
{
- metadata_t *meta = &iinfo->dn_metadata;
int table;
- dump_metadata_ptrs (iinfo);
+ dump_metadata_ptrs (meta);
printf ("Rows:\n");
for (table = 0; table < 64; table++){
- if (meta->rows [table] == 0)
+ if (meta->tables [table].rows == 0)
continue;
- printf ("Table %s (%d): %d rows\n", table_to_string (table), table, meta->rows [table]);
+ printf ("Table %s: %d records (%d bytes, at %p)\n",
+ mono_meta_table_name (table),
+ meta->tables [table].rows,
+ meta->tables [table].row_size,
+ meta->tables [table].base
+ );
+ if (dump_tables)
+ dump_table (meta, table);
}
}
static void
-dump_dotnet_iinfo (dotnet_image_info_t *iinfo)
+dump_methoddef (MonoMetadata *metadata, guint32 token)
{
- dump_dotnet_header (&iinfo->dn_header);
+ char *loc;
+
+ loc = mono_metadata_locate_token (metadata, token);
+
+ printf ("RVA for Entry Point: 0x%08x\n", (*(guint32 *)loc));
+}
+
+static void
+dump_dotnet_iinfo (MonoImage *image)
+{
+ MonoCLIImageInfo *iinfo = image->image_info;
+
+ dump_dotnet_header (&iinfo->cli_header);
dump_sections (iinfo);
- dump_cli_header (&iinfo->dn_cli_header);
- dump_metadata (iinfo);
+ dump_cli_header (&iinfo->cli_cli_header);
+ dump_metadata (image);
+
+ dump_methoddef (image, iinfo->cli_cli_header.ch_entry_point);
}
static void
usage (void)
{
- printf ("Usage is: pedump [-m] file.exe\n");
+ printf ("Usage is: pedump [--tables] file.exe\n");
exit (1);
}
int
main (int argc, char *argv [])
{
- dotnet_image_info_t *iinfo;
- MonoAssembly *assembly;
+ MonoImage *image;
char *file = NULL;
int i;
@@ -290,19 +290,25 @@ main (int argc, char *argv [])
continue;
}
- if (argv [i][1] == 'h')
+ if (strcmp (argv [i], "--help") == 0)
usage ();
+ if (strcmp (argv [i], "--tables") == 0)
+ dump_tables = 1;
}
if (!file)
usage ();
- assembly = mono_assembly_open (file, NULL);
- iinfo = assembly->image_info;
-
- dump_dotnet_iinfo (iinfo);
+ image = mono_image_open (file, NULL);
+ if (!image){
+ fprintf (stderr, "Can not open image %s\n", file);
+ exit (1);
+ }
- mono_assembly_close (assembly);
+ if (dump_data)
+ dump_dotnet_iinfo (image);
+
+ mono_image_close (image);
return 0;
}
diff --git a/mono/metadata/private.h b/mono/metadata/private.h
new file mode 100644
index 00000000000..b30d77863fd
--- /dev/null
+++ b/mono/metadata/private.h
@@ -0,0 +1,78 @@
+#ifndef __MONO_METADATA_PRIVATE_H__
+#define __MONO_METADATA_PRIVATE_H__
+
+/*
+ * This enumeration is used to describe the data types in the metadata
+ * tables
+ */
+enum {
+ MONO_MT_END,
+
+ /* Sized elements */
+ MONO_MT_UINT32,
+ MONO_MT_UINT16,
+ MONO_MT_UINT8,
+
+ /* Index into Blob heap */
+ MONO_MT_BLOB_IDX,
+
+ /* Index into String heap */
+ MONO_MT_STRING_IDX,
+
+ /* GUID index */
+ MONO_MT_GUID_IDX,
+
+ /* Pointer into a table */
+ MONO_MT_TABLE_IDX,
+
+ /* HasConstant:Parent pointer (Param, Field or Property) */
+ MONO_MT_CONST_IDX,
+
+ /* HasCustomAttribute index. Indexes any table except CustomAttribute */
+ MONO_MT_HASCAT_IDX,
+
+ /* CustomAttributeType encoded index */
+ MONO_MT_CAT_IDX,
+
+ /* HasDeclSecurity index: TypeDef Method or Assembly */
+ MONO_MT_HASDEC_IDX,
+
+ /* Implementation coded index: File, Export AssemblyRef */
+ MONO_MT_IMPL_IDX,
+
+ /* HasFieldMarshal coded index: Field or Param table */
+ MONO_MT_HFM_IDX,
+
+ /* MemberForwardedIndex: Field or Method */
+ MONO_MT_MF_IDX,
+
+ /* TypeDefOrRef coded index: typedef, typeref, typespec */
+ MONO_MT_TDOR_IDX,
+
+ /* MemberRefParent coded index: typeref, moduleref, method, memberref, typesepc, typedef */
+ MONO_MT_MRP_IDX,
+
+ /* MethodDefOrRef coded index: Method or Member Ref table */
+ MONO_MT_MDOR_IDX,
+
+ /* HasSemantic coded index: Event or Property */
+ MONO_MT_HS_IDX,
+
+ /* ResolutionScope coded index: Module, ModuleRef, AssemblytRef, TypeRef */
+ MONO_MT_RS_IDX
+};
+
+typedef struct {
+ int code;
+ char *def;
+} MonoMetaTable;
+
+const char *mono_meta_table_name (int table);
+
+/* Internal functions */
+void mono_metadata_compute_table_bases (MonoMetadata *meta);
+
+MonoMetaTable *mono_metadata_get_table (MonoMetaTableEnum table);
+
+#endif /* __MONO_METADATA_PRIVATE_H__ */
+
diff --git a/mono/metadata/rawbuffer.c b/mono/metadata/rawbuffer.c
index a72705af35e..d7d66a6073e 100644
--- a/mono/metadata/rawbuffer.c
+++ b/mono/metadata/rawbuffer.c
@@ -18,7 +18,7 @@
GHashTable *malloc_map;
void *
-raw_buffer_load (int fd, int is_writable, guint32 base, size_t size)
+mono_raw_buffer_load (int fd, int is_writable, guint32 base, size_t size)
{
size_t start, end;
int prot = PROT_READ;
@@ -52,7 +52,7 @@ raw_buffer_load (int fd, int is_writable, guint32 base, size_t size)
}
void
-raw_buffer_free (void *buffer)
+mono_raw_buffer_free (void *buffer)
{
int size, diff;
char *base;
diff --git a/mono/metadata/rawbuffer.h b/mono/metadata/rawbuffer.h
index 4091fc434c2..12f1a05a336 100644
--- a/mono/metadata/rawbuffer.h
+++ b/mono/metadata/rawbuffer.h
@@ -1,3 +1,3 @@
-void *raw_buffer_load (int fd, int writable, guint32 base, size_t size);
-void raw_buffer_free (void *buffer);
+void *mono_raw_buffer_load (int fd, int writable, guint32 base, size_t size);
+void mono_raw_buffer_free (void *buffer);
diff --git a/mono/metadata/row-indexes.h b/mono/metadata/row-indexes.h
new file mode 100644
index 00000000000..ee7d352e3af
--- /dev/null
+++ b/mono/metadata/row-indexes.h
@@ -0,0 +1,385 @@
+
+#ifndef __MONO_METADATA_ROW_INDEXES_H__
+#define __MONO_METADATA_ROW_INDEXES_H__
+
+/*
+ * The last entry in the enum is used to give the number
+ * of columns in the row.
+ */
+
+enum {
+ MONO_ASSEMBLY_HASH_ALG,
+ MONO_ASSEMBLY_MAJOR_VERSION,
+ MONO_ASSEMBLY_MINOR_VERSION,
+ MONO_ASSEMBLY_BUILD_NUMBER,
+ MONO_ASSEMBLY_REV_NUMBER,
+ MONO_ASSEMBLY_FLAGS,
+ MONO_ASSEMBLY_PUBLIC_KEY,
+ MONO_ASSEMBLY_NAME,
+ MONO_ASSEMBLY_CULTURE,
+ MONO_ASSEMBLY_SIZE
+};
+
+enum {
+ MONO_ASSEMBLYOS_PLATFORM,
+ MONO_ASSEMBLYOS_MAJOR_VERSION,
+ MONO_ASSEMBLYOS_MINOR_VERSION,
+ MONO_ASSEMBLYOS_SIZE
+};
+
+enum {
+ MONO_ASSEMBLY_PROCESSOR,
+ MONO_ASSEMBLY_PROCESSOR_SIZE
+};
+
+enum {
+ MONO_ASSEMBLYREF_MAJOR_VERSION,
+ MONO_ASSEMBLYREF_MINOR_VERSION,
+ MONO_ASSEMBLYREF_BUILD_NUMBER,
+ MONO_ASSEMBLYREF_REV_NUMBER,
+ MONO_ASSEMBLYREF_FLAGS,
+ MONO_ASSEMBLYREF_PUBLIC_KEY,
+ MONO_ASSEMBLYREF_NAME,
+ MONO_ASSEMBLYREF_CULTURE,
+ MONO_ASSEMBLYREF_HASH_VALUE,
+ MONO_ASSEMBLYREF_SIZE
+};
+
+enum {
+ MONO_ASSEMBLYREFOS_PLATFORM,
+ MONO_ASSEMBLYREFOS_MAJOR_VERSION,
+ MONO_ASSEMBLYREFOS_MINOR_VERSION,
+ MONO_ASSEMBLYREFOS_ASSEMBLYREF,
+ MONO_ASSEMBLYREFOS_SIZE
+};
+
+enum {
+ MONO_ASSEMBLYREFPROC_PROCESSOR,
+ MONO_ASSEMBLYREFPROC_ASSEMBLYREF,
+ MONO_ASSEMBLYREFPROC_SIZE
+};
+
+enum {
+ MONO_CLASS_LAYOUT_PACKING_SIZE,
+ MONO_CLASS_LAYOUT_CLASS_SIZE,
+ MONO_CLASS_LAYOUT_PARENT,
+ MONO_CLASS_LAYOUT_SIZE
+};
+
+enum {
+ MONO_CONSTANT_TYPE,
+ MONO_CONSTANT_PADDING,
+ MONO_CONSTANT_PARENT,
+ MONO_CONSTANT_VALUE,
+ MONO_CONSTANT_SIZE
+};
+
+enum {
+ MONO_CUSTOM_ATTR_PARENT,
+ MONO_CUSTOM_ATTR_TYPE,
+ MONO_CUSTOM_ATTR_VALUE,
+ MONO_CUSTOM_ATTR_SIZE
+};
+
+enum {
+ MONO_DECL_SECURITY_ACTION,
+ MONO_DECL_SECURITY_PARENT,
+ MONO_DECL_SECURITY_PERMISSIONSET,
+ MONO_DECL_SECURITY_SIZE
+};
+
+enum {
+ MONO_EVENT_MAP_PARENT,
+ MONO_EVENT_MAP_EVENTLIST,
+ MONO_EVENT_MAP_SIZE
+};
+
+enum {
+ MONO_EVENT_FLAGS,
+ MONO_EVENT_NAME,
+ MONO_EVENT_TYPE,
+ MONO_EVENT_SIZE
+};
+
+enum {
+ MONO_EXP_TYPE_FLAGS,
+ MONO_EXP_TYPE_TYPEDEF,
+ MONO_EXP_TYPE_NAME,
+ MONO_EXP_TYPE_NAMESPACE,
+ MONO_EXP_TYPE_IMPLEMENTATION,
+ MONO_EXP_TYPE_SIZE
+};
+
+enum {
+ MONO_FIELD_FLAGS,
+ MONO_FIELD_NAME,
+ MONO_FIELD_SIGNATURE,
+ MONO_FIELD_SIZE
+};
+
+enum {
+ MONO_FIELD_LAYOUT_OFFSET,
+ MONO_FIELD_LAYOUT_FIELD,
+ MONO_FIELD_LAYOUT_SIZE
+};
+
+enum {
+ MONO_FIELD_MARSHAL_PARENT,
+ MONO_FIELD_MARSHAL_NATIVE_TYPE,
+ MONO_FIELD_MARSHAL_SIZE
+};
+
+enum {
+ MONO_FIELD_RVA_RVA,
+ MONO_FIELD_RVA_FIELD,
+ MONO_FIELD_RVA_SIZE
+};
+
+enum {
+ MONO_FILE_FLAGS,
+ MONO_FILE_NAME,
+ MONO_FILE_HASH_VALUE,
+ MONO_FILE_SIZE
+};
+
+enum {
+ MONO_IMPLMAP_FLAGS,
+ MONO_IMPLMAP_MEMBER,
+ MONO_IMPLMAP_NAME,
+ MONO_IMPLMAP_SCOPE,
+ MONO_IMPLMAP_SIZE
+};
+
+enum {
+ MONO_INTERFACEIMPL_CLASS,
+ MONO_INTERFACEIMPL_INTERFACE,
+ MONO_INTERFACEIMPL_SIZE
+};
+
+enum {
+ MONO_MANIFEST_OFFSET,
+ MONO_MANIFEST_FLAGS,
+ MONO_MANIFEST_NAME,
+ MONO_MANIFEST_IMPLEMENTATION,
+ MONO_MANIFEST_SIZE
+};
+
+enum {
+ MONO_MEMBERREF_CLASS,
+ MONO_MEMBERREF_NAME,
+ MONO_MEMBERREF_SIGNATURE,
+ MONO_MEMBERREF_SIZE
+};
+
+enum {
+ MONO_METHOD_RVA,
+ MONO_METHOD_IMPLFALGS,
+ MONO_METHOD_FLAGS,
+ MONO_METHOD_NAME,
+ MONO_METHOD_SIGNATURE,
+ MONO_METHOD_PARAMLIST,
+ MONO_METHOD_SIZE
+};
+
+enum {
+ MONO_MTHODIMPL_CLASS,
+ MONO_MTHODIMPL_BODY,
+ MONO_MTHODIMPL_DECLARATION,
+ MONO_MTHODIMPL_SIZE
+};
+
+enum {
+ MONO_METHOD_SEMA_SEMANTICS,
+ MONO_METHOD_SEMA_METHOD,
+ MONO_METHOD_SEMA_ASSOCIATION,
+ MONO_METHOD_SEMA_SIZE
+};
+
+enum {
+ MONO_MODULE_GENERATION,
+ MONO_MODULE_NAME,
+ MONO_MODULE_MVID,
+ MONO_MODULE_ENC,
+ MONO_MODULE_ENCBASE,
+ MONO_MODULE_SIZE
+};
+
+enum {
+ MONO_MODULEREF_NAME,
+ MONO_MODULEREF_SIZE
+};
+
+enum {
+ MONO_NESTED_CLASS_NESTED,
+ MONO_NESTED_CLASS_ENCLOSING,
+ MONO_NESTED_CLASS_SIZE
+};
+
+enum {
+ MONO_PARAM_FLAGS,
+ MONO_PARAM_SEQUENCE,
+ MONO_PARAM_NAME,
+ MONO_PARAM_SIZE
+};
+
+enum {
+ MONO_PROPERTY_FLAGS,
+ MONO_PROPERTY_NAME,
+ MONO_PROPERTY_TYPE,
+ MONO_PROPERTY_SIZE
+};
+
+enum {
+ MONO_PROPERTY_MAP_PARENT,
+ MONO_PROPERTY_MAP_PROPERTY_LIST,
+ MONO_PROPERTY_MAP_SIZE
+};
+
+enum {
+ MONO_STAND_ALONG_SIGNATURE,
+ MONO_STAND_ALONG_SIGNATURE_SIZE
+};
+
+enum {
+ MONO_TYPEDEF_FLAGS,
+ MONO_TYPEDEF_NAME,
+ MONO_TYPEDEF_NAMESPACE,
+ MONO_TYPEDEF_EXTENDS,
+ MONO_TYPEDEF_FIELD_LIST,
+ MONO_TYPEDEF_METHOD_LIST,
+ MONO_TYPEDEF_SIZE
+};
+
+enum {
+ MONO_TYPEREF_SCOPE,
+ MONO_TYPEREF_NAME,
+ MONO_TYPEREF_NAMESPACE,
+ MONO_TYPEREF_SIZE
+};
+
+enum {
+ MONO_TYPESPEC_SIGNATURE,
+ MONO_TYPESPEC_SIZE
+};
+
+/*
+ * Coded Tokens
+ * The _BITS entry is for the bits used in the token.
+ * The _MASK entry is for mask the index out.
+ */
+
+enum {
+ TYPEDEFORREF_TYPEDEF,
+ TYPEDEFORREF_PARAMDEF,
+ TYPEDEFORREF_TYPESPEC,
+ TYPEDEFORREF_BITS = 2,
+ TYPEDEFORREF_MASK = 3
+};
+
+enum {
+ HASCOSTANT_FIEDDEF,
+ HASCOSTANT_FIEDREF, /* typo in spec? LAMESPEC */
+ HASCOSTANT_PROPERTY,
+ HASCOSTANT_BITS = 2,
+ HASCOSTANT_MASK = 3
+};
+
+enum {
+ CUSTOM_ATTR_METHODDEF,
+ CUSTOM_ATTR_FIELDDEF,
+ CUSTOM_ATTR_TYPEREF,
+ CUSTOM_ATTR_TYPEDEF,
+ CUSTOM_ATTR_PARAMDEF,
+ CUSTOM_ATTR_INTERFACE,
+ CUSTOM_ATTR_MEMBERREF,
+ CUSTOM_ATTR_MODULE,
+ CUSTOM_ATTR_PERMISSION,
+ CUSTOM_ATTR_PROPERTY,
+ CUSTOM_ATTR_EVENT,
+ CUSTOM_ATTR_SIGNATURE,
+ CUSTOM_ATTR_MODULEREF,
+ CUSTOM_ATTR_TYPESPEC,
+ CUSTOM_ATTR_ASSEMBLY,
+ CUSTOM_ATTR_ASSEMBLYREF,
+ CUSTOM_ATTR_FILE,
+ CUSTOM_ATTR_EXP_TYPE,
+ CUSTOM_ATTR_MANIFEST,
+ CUSTOM_ATTR_BITS = 5,
+ CUSTOM_ATTR_MASK = 0x1F
+};
+
+enum {
+ HAS_FIELD_MARSHAL_FIELDSREF,
+ HAS_FIELD_MARSHAL_PARAMDEF,
+ HAS_FIELD_MARSHAL_BITS = 1,
+ HAS_FIELD_MARSHAL_MASK = 1
+};
+
+enum {
+ HAS_DECL_SECURITY_TYPEDEF,
+ HAS_DECL_SECURITY_METHODDEF,
+ HAS_DECL_SECURITY_ASSEMBLY,
+ HAS_DECL_SECURITY_BITS = 1,
+ HAS_DECL_SECURITY_MASK = 1
+};
+
+enum {
+ MEMBERREF_PARENT_TYPEDEF,
+ MEMBERREF_PARENT_TYPEREF,
+ MEMBERREF_PARENT_MODULEREF,
+ MEMBERREF_PARENT_METHODDEF,
+ MEMBERREF_PARENT_TYPESPEC,
+ MEMBERREF_PARENT_BITS = 3,
+ MEMBERREF_PARENT_MASK = 7
+};
+
+enum {
+ HAS_SEMANTICS_EVENT,
+ HAS_SEMANTICS_PROPERTY,
+ HAS_SEMANTICS_BITS = 1,
+ HAS_SEMANTICS_MASK = 1
+};
+
+enum {
+ METHODDEFORREF_METHODDEF,
+ METHODDEFORREF_METHODREF,
+ METHODDEFORREF_BITS = 1,
+ METHODDEFORREF_MASK = 1
+};
+
+enum {
+ MEMBERFORWD_FIELDDEF,
+ MEMBERFORWD_METHODDEF,
+ MEMBERFORWD_BITS = 1,
+ MEMBERFORWD_MASK = 1
+};
+
+enum {
+ IMPLEMENTATION_FILE,
+ IMPLEMENTATION_ASSEMBLYREF,
+ IMPLEMENTATION_EXP_TYPE,
+ IMPLEMENTATION_BITS = 2,
+ IMPLEMENTATION_MASK = 3
+};
+
+enum {
+ CUSTOM_ATTR_TYPE_TYPEREF,
+ CUSTOM_ATTR_TYPE_TYPEDEF,
+ CUSTOM_ATTR_TYPE_METHODDEF,
+ CUSTOM_ATTR_TYPE_MEMBERREF,
+ CUSTOM_ATTR_TYPE_STRING,
+ CUSTOM_ATTR_TYPE_BITS = 3,
+ CUSTOM_ATTR_TYPE_MASK = 7
+};
+
+enum {
+ RESOLTION_SCOPE_MODULE,
+ RESOLTION_SCOPE_MODULEREF,
+ RESOLTION_SCOPE_ASSEMBLYREF, /* LAMESPEC claims 3 */
+ RESOLTION_SCOPE_TYPEREF, /* LAMESPEC claims 4 */
+ RESOLTION_SCOPE_BITS = 2, /* LAMESPEC claims 3 */
+ RESOLTION_SCOPE_MASK = 3 /* LAMESPEC claims 7 */
+};
+
+#endif /* __MONO_METADATA_ROW_INDEXES_H__ */
+
diff --git a/mono/metadata/tabledefs.h b/mono/metadata/tabledefs.h
new file mode 100644
index 00000000000..6cc6ce6b93c
--- /dev/null
+++ b/mono/metadata/tabledefs.h
@@ -0,0 +1,186 @@
+/*
+ * tabledefs.h: This file contains the various definitions for constants
+ * found on the metadata tables
+ *
+ * Author:
+ * Miguel de Icaza (miguel@ximian.com)
+ *
+ * (C) 2001 Ximian, Inc.
+ *
+ * From the ECMA documentation
+ */
+
+#ifndef _MONO_METADATA_TABLEDEFS_H_
+#define _MONO_METADATA_TABLEDEFS_H_
+
+
+/*
+ * Field Attributes (21.1.5).
+ */
+
+#define FIELD_ATTRIBUTE_FIELD_ACCESS_MASK 0x0007
+#define FIELD_ATTRIBUTE_COMPILER_CONTROLLED 0x0000
+#define FIELD_ATTRIBUTE_PRIVATE 0x0001
+#define FIELD_ATTRIBUTE_FAM_AND_ASSEM 0x0002
+#define FIELD_ATTRIBUTE_ASSEMBLY 0x0003
+#define FIELD_ATTRIBUTE_FAMILY 0x0004
+#define FIELD_ATTRIBUTE_FAM_OR_ASSEM 0x0005
+#define FIELD_ATTRIBUTE_PUBLIC 0x0006
+
+#define FIELD_ATTRIBUTE_STATIC 0x0010
+#define FIELD_ATTRIBUTE_INIT_ONLY 0x0020
+#define FIELD_ATTRIBUTE_LITERAL 0x0040
+#define FIELD_ATTRIBUTE_NOT_SERIALIZED 0x0080
+#define FIELD_ATTRIBUTE_SPECIAL_NAME 0x0200
+#define FIELD_ATTRIBUTE_PINVOKE_IMPL 0x2000
+
+/* For runtime use only */
+#define FIELD_ATTRIBUTE_RESERVED_MASK 0x9500
+#define FIELD_ATTRIBUTE_RT_SPECIAL_NAME 0x0400
+#define FIELD_ATTRIBUTE_HAS_FIELD_MARSHAL 0x1000
+#define FIELD_ATTRIBUTE_HAS_DEFAULT 0x8000
+#define FIELD_ATTRIBUTE_HAS_FIELD_RVA 0x0100
+
+/*
+ * Type Attributes (21.1.13).
+ */
+#define TYPE_ATTRIBUTE_VISIBILITY_MASK 0x00000007
+#define TYPE_ATTRIBUTE_NOT_PUBLIC 0x00000000
+#define TYPE_ATTRIBUTE_PUBLIC 0x00000001
+#define TYPE_ATTRIBUTE_NESTED_PUBLIC 0x00000002
+#define TYPE_ATTRIBUTE_NESTED_PRIVATE 0x00000003
+#define TYPE_ATTRIBUTE_NESTED_FAMILY 0x00000004
+#define TYPE_ATTRIBUTE_NESTED_ASSEMBLY 0x00000005
+#define TYPE_ATTRIBUTE_NESTED_FAM_AND_ASSEM 0x00000006
+#define TYPE_ATTRIBUTE_NESTED_FAM_OR_ASSEM 0x00000007
+
+#define TYPE_ATTRIBUTE_LAYOUT_MASK 0x00000018
+#define TYPE_ATTRIBUTE_AUTO_LAYOUT 0x00000000
+#define TYPE_ATTRIBUTE_SEQUENTIAL_LAYOUT 0x00000008
+#define TYPE_ATTRIBUTE_EXPLICIT_LAYOUT 0x00000010
+
+#define TYPE_ATTRIBUTE_CLASS_SEMANTIC_MASK 0x00000020
+#define TYPE_ATTRIBUTE_CLASS 0x00000000
+#define TYPE_ATTRIBUTE_INTERFACE 0x00000020
+
+#define TYPE_ATTRIBUTE_ABSTRACT 0x00000080
+#define TYPE_ATTRIBUTE_SEALED 0x00000100
+#define TYPE_ATTRIBUTE_SPECIAL_NAME 0x00000400
+
+#define TYPE_ATTRIBUTE_IMPORT 0x00001000
+#define TYPE_ATTRIBUTE_SERIALIZABLE 0x00002000
+
+#define TYPE_ATTRIBUTE_STRING_FORMAT_MASK 0x00030000
+#define TYPE_ATTRIBUTE_ANSI_CLASS 0x00000000
+#define TYPE_ATTRIBUTE_UNICODE_CLASS 0x00010000
+#define TYPE_ATTRIBUTE_AUTO_CLASS 0x00020000
+
+#define TYPE_ATTRIBUTE_BEFORE_FIELD_INIT 0x00100000
+
+#define TYPE_ATTRIBUTE_RESERVED_MASK 0x00040800
+#define TYPE_ATTRIBUTE_RT_SPECIAL_NAME 0x00000800
+#define TYPE_ATTRIBUTE_HAS_SECURITY 0x00040000
+
+/*
+ * Method Attributes (22.1.9)
+ */
+
+#define METHOD_IMPL_ATTRIBUTE_CODE_TYPE_MASK 0x0003
+#define METHOD_IMPL_ATTRIBUTE_IL 0x0000
+#define METHOD_IMPL_ATTRIBUTE_NATIVE 0x0001
+#define METHOD_IMPL_ATTRIBUTE_OPTIL 0x0002
+#define METHOD_IMPL_ATTRIBUTE_RUNTIME 0x0003
+
+#define METHOD_IMPL_ATTRIBUTE_MANAGED_MASK 0x0004
+#define METHOD_IMPL_ATTRIBUTE_UNMANAGED 0x0004
+#define METHOD_IMPL_ATTRIBUTE_MANAGED 0x0000
+
+#define METHOD_IMPL_ATTRIBUTE_FORWARD_REF 0x0010
+#define METHOD_IMPL_ATTRIBUTE_PRESERVE_SIG 0x0080
+#define METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL 0x1000
+#define METHOD_IMPL_ATTRIBUTE_SYNCHRONIZED 0x0020
+#define METHOD_IMPL_ATTRIBUTE_NOINLINING 0x0008
+#define METHOD_IMPL_ATTRIBUTE_MAX_METHOD_IMPL_VAL 0xffff
+
+#define METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK 0x0007
+#define METHOD_ATTRIBUTE_COMPILER_CONTROLLED 0x0000
+#define METHOD_ATTRIBUTE_PRIVATE 0x0001
+#define METHOD_ATTRIBUTE_FAM_AND_ASSEM 0x0002
+#define METHOD_ATTRIBUTE_ASSEM 0x0003
+#define METHOD_ATTRIBUTE_FAMILY 0x0004
+#define METHOD_ATTRIBUTE_FAM_OR_ASSEM 0x0005
+#define METHOD_ATTRIBUTE_PUBLIC 0x0006
+
+#define METHOD_ATTRIBUTE_STATIC 0x0010
+#define METHOD_ATTRIBUTE_FINAL 0x0020
+#define METHOD_ATTRIBUTE_VIRTUAL 0x0040
+#define METHOD_ATTRIBUTE_HIDE_BY_SIG 0x0080
+
+#define METHOD_ATTRIBUTE_VTABLE_LAYOUT_MASK 0x0100
+#define METHOD_ATTRIBUTE_REUSE_SLOT 0x0000
+#define METHOD_ATTRIBUTE_NEW_SLOT 0x0100
+
+#define METHOD_ATTRIBUTE_ABSTRACT 0x0400
+#define METHOD_ATTRIBUTE_SPECIAL_NAME 0x0800
+
+#define METHOD_ATTRIBUTE_PINVOKE_IMPL 0x2000
+#define METHOD_ATTRIBUTE_UNMANAGED_EXPORT 0x0008
+
+/*
+ * For runtime use only
+ */
+#define METHOD_ATTRIBUTE_RESERVED_MASK 0xd000
+#define METHOD_ATTRIBUTE_RT_SPECIAL_NAME 0x1000
+#define METHOD_ATTRIBUTE_HAS_SECURITY 0x4000
+#define METHOD_ATTRIBUTE_REQUIRE_SEC_OBJECT 0x8000
+
+
+/*
+ * Method Semantics ([MethodSemanticAttributes]) 22.1.10
+ */
+
+#define METHOD_SEMANTIC_SETTER 0x0001
+#define METHOD_SEMANTIC_GETTER 0x0002
+#define METHOD_SEMANTIC_OTHER 0x0004
+#define METHOD_SEMANTIC_ADD_ON 0x0008
+#define METHOD_SEMANTIC_REMOVE_ON 0x0010
+#define METHOD_SEMANTIC_FIRE 0x0020
+
+/*
+ * Flags for Params (22.1.11)
+ */
+#define PARAM_ATTRIBUTE_IN 0x0001
+#define PARAM_ATTRIBUTE_OUT 0x0002
+#define PARAM_ATTRIBUTE_OPTIONAL 0x0004
+#define PARAM_ATTRIBUTE_RESERVED_MASK 0xf000
+#define PARAM_ATTRIBUTE_HAS_DEFAULT 0x1000
+#define PARAM_ATTRIBUTE_HAS_FIELD_MARSHAL 0x2000
+#define PARAM_ATTRIBUTE_UNUSED 0xcfe0
+
+/*
+ * 22.1.12 PropertyAttributes
+ */
+#define PROPERTY_ATTRIBUTE_SPECIAL_NAME 0x0200
+#define PROPERTY_ATTRIBUTE_RESERVED_MASK 0xf400
+#define PROPERTY_ATTRIBUTE_RT_SPECIAL_NAME 0x0400
+#define PROPERTY_ATTRIBUTE_HAS_DEFAULT 0x1000
+#define PROPERTY_ATTRIBUTE_UNUSED 0xe9ff
+
+/*
+ * 22.1.7 Flags for ImplMap [PInvokeAttributes]
+ */
+#define PINVOKE_ATTRIBUTE_NO_MANGLE 0x0001
+#define PINVOKE_ATTRIBUTE_CHAR_SET_MASK 0x0006
+#define PINVOKE_ATTRIBUTE_CHAR_SET_NOT_SPEC 0x0000
+#define PINVOKE_ATTRIBUTE_CHAR_SET_ANSI 0x0002
+#define PINVOKE_ATTRIBUTE_CHAR_SET_UNICODE 0x0004
+#define PINVOKE_ATTRIBUTE_CHAR_SET_AUTO 0x0006
+#define PINVOKE_ATTRIBUTE_SUPPORTS_LAST_ERROR 0x0040
+#define PINVOKE_ATTRIBUTE_CALL_CONV_MASK 0x0700
+#define PINVOKE_ATTRIBUTE_CALL_CONV_WINAPI 0x0100
+#define PINVOKE_ATTRIBUTE_CALL_CONV_CDECL 0x0200
+#define PINVOKE_ATTRIBUTE_CALL_CONV_STDCALL 0x0300
+#define PINVOKE_ATTRIBUTE_CALL_CONV_THISCALL 0x0400
+#define PINVOKE_ATTRIBUTE_CALL_CONV_FASTCALL 0x0500
+
+#endif
diff --git a/mono/metadata/tokentype.h b/mono/metadata/tokentype.h
new file mode 100644
index 00000000000..b99b173923a
--- /dev/null
+++ b/mono/metadata/tokentype.h
@@ -0,0 +1,39 @@
+#ifndef _MONO_METADATA_TOKENTYPE_H_
+#define _MONO_METADATA_TOKENTYPE_H_
+
+/*
+ * These tokens match the table ID except for the last
+ * three (string, name and base type which are special)
+ */
+
+typedef enum {
+ MONO_TOKEN_MODULE = 0x00000000,
+ MONO_TOKEN_TYPE_REF = 0x01000000,
+ MONO_TOKEN_TYPE_DEF = 0x02000000,
+ MONO_TOKEN_FIELD_DEF = 0x04000000,
+ MONO_TOKEN_METHOD_DEF = 0x06000000,
+ MONO_TOKEN_PARAM_DEF = 0x08000000,
+ MONO_TOKEN_INTERFACE_IMPL = 0x09000000,
+ MONO_TOKEN_MEMBER_REF = 0x0a000000,
+ MONO_TOKEN_CUSTOM_ATTRIBUTE = 0x0c000000,
+ MONO_TOKEN_PERMISSION = 0x0e000000,
+ MONO_TOKEN_SIGNATURE = 0x11000000,
+ MONO_TOKEN_EVENT = 0x14000000,
+ MONO_TOKEN_PROPERTY = 0x17000000,
+ MONO_TOKEN_MODULE_REF = 0x1a000000,
+ MONO_TOKEN_TYPE_SPEC = 0x1b000000,
+ MONO_TOKEN_ASSEMBLY = 0x20000000,
+ MONO_TOKEN_ASSEMBLY_REF = 0x23000000,
+ MONO_TOKEN_FILE = 0x26000000,
+ MONO_TOKEN_EXPORTED_TYPE = 0x27000000,
+ MONO_TOKEN_MANIFEST_RESOURCE = 0x28000000,
+
+ /*
+ * These do not match metadata tables directly
+ */
+ MONO_TOKEN_STRING = 0x70000000,
+ MONO_TOKEN_NAME = 0x71000000,
+ MONO_TOKEN_BASE_TYPE = 0x72000000
+} MonoTokenType;
+
+#endif /* _MONO_METADATA_TOKENTYPE_H_ */
diff --git a/mono/metadata/typedef.c b/mono/metadata/typedef.c
new file mode 100644
index 00000000000..f488ec25745
--- /dev/null
+++ b/mono/metadata/typedef.c
@@ -0,0 +1,54 @@
+/*
+ * typedef.c: Handling of TypeDefs.
+ *
+ * Author:
+ * Miguel de Icaza (miguel@ximian.com)
+ *
+ * (C) 2001 Ximian, Inc.
+ */
+#include <config.h>
+#include <mono/metadata/typedef.h>
+
+/**
+ * mono_typedef_decode:
+ * @image: image to decode from
+ * @tidx: typedef number
+ *
+ * Decodes the TypeDef whose index is @tidx in @image
+ */
+void
+mono_typedef_decode (MonoImage *image, guint32 tidx, MonoTypedef *ret)
+{
+ MonoMetadata *m = &image->metadata;
+ MonoTableInfo *tt = m->tables [MONO_TABLE_TYPEDEF];
+ int next_is_valid;
+ guint32 cols_next [MONO_TYPEDEF_SIZE];
+ guint last;
+
+ g_assert (typedef_token < tt->rows);
+
+ mono_metadata_decode_row (tt, typedef_idx, &ret->cols, CSIZE (ret->cols));
+
+ /*
+ * Get the field and method range
+ */
+ ret->field.first = ret->cols [MONO_TYPEREF_FIELD_LIST] - 1;
+ ret->method.first = ret->cols [MONO_TYPEDEF_METHOD_LIST] - 1;
+
+ if (tt->rows > typedef_idx + 1){
+ mono_metadata_decode_row (tt, typedef_idx + 1, cols_next, CSIZE (cols_next));
+ ret->field.last = cols_next [MONO_TYPEREF_FIELD_LIST] - 1;
+ ret->method.last = cols_next [MONO_TYPEREF_FIELD_LIST] - 1;
+ } else {
+ ret->field.last = m->tables [MONO_TABLE_FIELD].rows;
+ ret->field.method = m->tables [MONO_TABLE_METHOD].rows;
+ }
+
+ /*
+ * Get the method range
+ */
+ ref
+
+}
+
+
diff --git a/mono/metadata/types.h b/mono/metadata/types.h
new file mode 100644
index 00000000000..e5ddd7c4f66
--- /dev/null
+++ b/mono/metadata/types.h
@@ -0,0 +1,17 @@
+#ifndef _MONO_METADATA_TYPES_H_
+#define _MONO_METADATA_TYPES_H_
+
+typedef struct _MonoImage MonoImage;
+
+enum MonoImageOpenStatus {
+ MONO_IMAGE_OK,
+ MONO_IMAGE_ERROR_ERRNO,
+ MONO_IMAGE_MISSING_ASSEMBLYREF,
+ MONO_IMAGE_IMAGE_INVALID
+};
+
+typedef struct _MonoAssembly MonoAssembly;
+
+typedef char * (*MonoAssemblyResolverFn)(const char *name);
+
+#endif
diff --git a/mono/tests/.cvsignore b/mono/tests/.cvsignore
new file mode 100644
index 00000000000..eb0b3ef1308
--- /dev/null
+++ b/mono/tests/.cvsignore
@@ -0,0 +1,3 @@
+Makefile.in
+Makefile
+*.stdout \ No newline at end of file
diff --git a/mono/tests/Makefile.am b/mono/tests/Makefile.am
new file mode 100644
index 00000000000..7f8a2dce285
--- /dev/null
+++ b/mono/tests/Makefile.am
@@ -0,0 +1,46 @@
+
+TEST_PROG=../interpreter/mint
+CSC=csc
+
+TESTSRC= \
+ test-ops.cs \
+ fib.cs \
+ obj.cs \
+ random.cs \
+ switch.cs \
+ outparm.cs \
+ nested-loops.cs \
+ exception.cs \
+ exception2.cs \
+ exception3.cs \
+ struct.cs \
+ pinvoke.cs \
+ array.cs \
+ stream.cs
+
+TESTS= \
+ test-ops.exe \
+ fib.exe \
+ obj.exe \
+ random.exe \
+ switch.exe \
+ outparm.exe \
+ nested-loops.exe \
+ exception.exe \
+ exception2.exe \
+ exception3.exe \
+ struct.exe \
+ pinvoke.exe \
+ array.exe \
+ stream.exe
+
+EXTRA_DIST=test-driver $(TESTSRC)
+
+%.exe: %.cs
+ $(CSC) $<
+
+test: $(TEST_PROG) $(TESTS)
+ for i in $(TESTS); do \
+ ./test-driver $(TEST_PROG) $$i; \
+ done
+
diff --git a/mono/tests/array.cs b/mono/tests/array.cs
new file mode 100755
index 00000000000..9f587eea3b8
--- /dev/null
+++ b/mono/tests/array.cs
@@ -0,0 +1,134 @@
+using System;
+using System.Runtime.InteropServices;
+
+public class Test {
+
+ [DllImport("cygwin1.dll", EntryPoint="puts", CharSet=CharSet.Ansi)]
+ public static extern int puts (string name);
+
+ public static int jagged ()
+ {
+ int[][] j2 = new int [3][];
+
+ // does not work
+ // j2 [0] = new int[] {1, 2, 3};
+ // j2 [1] = new int[] {1, 2, 3, 4, 5, 6};
+ // j2 [2] = new int[] {1, 2, 3, 4, 5, 6, 7, 8, 9};
+
+ j2 [0] = new int[3];
+ j2 [1] = new int[6];
+ j2 [2] = new int[9];
+
+ for (int i = 0; i < j2.Length; i++)
+ for (int j = 0; j < (i+1)*3; j++)
+ j2 [i][j] = j;
+
+ for (int i = 0; i < j2.Length; i++)
+ for (int j = 0; j < (i+1)*3; j++)
+ if (j2 [i][j] != j)
+ return 1;
+ return 0;
+ }
+
+ public static int stest ()
+ {
+ string[] sa = new string[32];
+
+ sa [0] = "This";
+ sa [2] = "is";
+ sa [10] = "a";
+ sa [20] = "stupid";
+ sa [21] = "Test";
+
+ for (int i = 0; i < sa.Length; i++)
+ if (sa [i] != null)
+ puts (sa [i]);
+
+ return 0;
+ }
+
+ public static int atest2 ()
+ {
+ int[,] ia = new int[32,32];
+
+ for (int i = 0; i <ia.GetLength (0); i++)
+ ia [i,i] = i*i;
+
+ for (int i = 0; i <ia.GetLength (0); i++)
+ if (ia [i,i] != i*i)
+ return 1;
+
+ for (int i = 0; i <ia.GetLength (0); i++)
+ ia.SetValue (i*i*i, i, i);
+
+ for (int i = 0; i <ia.GetLength (0); i++)
+ if ((int)ia.GetValue (i, i) != i*i*i)
+ return 1;
+
+ return 0;
+ }
+
+ public static int atest ()
+ {
+ int[] ia = new int[32];
+
+ for (int i = 0; i <ia.Length; i++)
+ ia [i] = i*i;
+
+ for (int i = 0; i <ia.Length; i++)
+ if (ia [i] != i*i)
+ return 1;
+
+ if (ia.Rank != 1)
+ return 1;
+
+ if (ia.GetValue (2) == null)
+ return 1;
+
+ for (int i = 0; i <ia.Length; i++)
+ ia.SetValue (i*i*i, i);
+
+ for (int i = 0; i <ia.Length; i++)
+ if ((int)ia.GetValue (i) != i*i*i)
+ return 1;
+
+ return 0;
+ }
+
+ public static int boxtest ()
+ {
+ int i = 123;
+ object o = i;
+ int j = (int) o;
+
+ if (i != j)
+ return 1;
+
+ return 0;
+ }
+
+ public static int Main () {
+
+ if (boxtest () != 0)
+ return 1;
+
+ if (atest () != 0)
+ return 1;
+
+ if (atest2 () != 0)
+ return 1;
+ if (atest2 () != 0)
+ return 1;
+
+ if (stest () != 0)
+ return 1;
+
+ if (jagged () != 0)
+ return 1;
+
+
+ return 0;
+ }
+}
+
+
diff --git a/mono/tests/exception.cs b/mono/tests/exception.cs
new file mode 100755
index 00000000000..b5667fb5057
--- /dev/null
+++ b/mono/tests/exception.cs
@@ -0,0 +1,34 @@
+using System;
+
+public class Ex {
+
+ public static int test (int a) {
+ int res;
+ int fin = 0;
+ try {
+ res = 10/a;
+ } catch (DivideByZeroException ex) {
+ if (fin != 1)
+ res = 34;
+ else
+ res = 33;
+ } catch {
+ if (fin != 1)
+ res = 24;
+ else
+ res = 22;
+ } finally {
+ fin = 1;
+ }
+ return res;
+ }
+ public static int Main () {
+ if (test(1) != 10)
+ return 1;
+ if (test(0) != 33)
+ return 2;
+ return 0;
+ }
+}
+
+
diff --git a/mono/tests/exception2.cs b/mono/tests/exception2.cs
new file mode 100755
index 00000000000..f298b8fda7c
--- /dev/null
+++ b/mono/tests/exception2.cs
@@ -0,0 +1,22 @@
+using System;
+
+public class Ex2 {
+
+ public static int test (int a) {
+ int res;
+ res = 10/a;
+ return res;
+ }
+ public static int Main () {
+ int res = 1;
+ try {
+ test(1);
+ test(0);
+ } catch {
+ res = 0;
+ }
+ return res;
+ }
+}
+
+
diff --git a/mono/tests/exception3.cs b/mono/tests/exception3.cs
new file mode 100755
index 00000000000..ebda13ac424
--- /dev/null
+++ b/mono/tests/exception3.cs
@@ -0,0 +1,40 @@
+using System;
+
+public class MyEx : Exception {
+ public MyEx () {}
+}
+
+public class Ex {
+
+ public static int test (int a) {
+ int res;
+ int fin = 0;
+ try {
+ res = 10/a;
+ throw new MyEx ();
+ } catch (DivideByZeroException ex) {
+ if (fin != 1)
+ res = 34;
+ else
+ res = 33;
+ } finally {
+ fin = 1;
+ }
+ return res;
+ }
+ public static int Main () {
+ int catched = 0;
+ try {
+ test (1);
+ } catch (MyEx ex) {
+ catched = 1;
+ }
+ if (catched != 1)
+ return 2;
+ if (test(0) != 33)
+ return 3;
+ return 0;
+ }
+}
+
+
diff --git a/mono/tests/fib.cs b/mono/tests/fib.cs
new file mode 100755
index 00000000000..3a3dff99744
--- /dev/null
+++ b/mono/tests/fib.cs
@@ -0,0 +1,15 @@
+public class Fib {
+
+ public static int fib (int n) {
+ if (n < 2)
+ return 1;
+ return fib(n-2)+fib(n-1);
+ }
+ public static int Main () {
+ if (fib (32) != 3524578)
+ return 1;
+ return 0;
+ }
+}
+
+
diff --git a/mono/tests/nested-loops.cs b/mono/tests/nested-loops.cs
new file mode 100755
index 00000000000..4475ab7d715
--- /dev/null
+++ b/mono/tests/nested-loops.cs
@@ -0,0 +1,31 @@
+
+public class NestedLoop {
+ static public int Main() {
+ int n = 16;
+ int x = 0;
+ int a = n;
+ while (a-- != 0) {
+ int b = n;
+ while (b-- != 0) {
+ int c = n;
+ while (c-- != 0) {
+ int d = n;
+ while (d-- != 0) {
+ int e = n;
+ while (e-- != 0) {
+ int f = n;
+ while (f-- != 0) {
+ x++;
+ }
+ }
+ }
+ }
+ }
+ }
+ if (x != 16777216)
+ return 1;
+ return 0;
+ }
+}
+
+
diff --git a/mono/tests/obj.cs b/mono/tests/obj.cs
new file mode 100755
index 00000000000..84bba6ea4b0
--- /dev/null
+++ b/mono/tests/obj.cs
@@ -0,0 +1,30 @@
+using System;
+
+public class TestObj {
+ static public int sbah = 5;
+ public int bah = 1;
+ public int boh;
+
+ public TestObj () {
+ boh = 2;
+ }
+ public int amethod () {
+ return boh;
+ }
+ public static int Main () {
+ TestObj obj = new TestObj ();
+ TestObj clone;
+
+ if (sbah + obj.bah + obj.amethod () != 8)
+ return 1;
+
+ clone = (TestObj)obj.MemberwiseClone ();
+
+ if (clone.boh != 2)
+ return 1;
+
+ return 0;
+ }
+}
+
+
diff --git a/mono/tests/outparm.cs b/mono/tests/outparm.cs
new file mode 100755
index 00000000000..b7f9d3db150
--- /dev/null
+++ b/mono/tests/outparm.cs
@@ -0,0 +1,21 @@
+public class OutParm {
+
+ public static void out_param (out int n) {
+ n = 1;
+ }
+ public static void ref_param (ref int n) {
+ n += 2;
+ }
+ public static int Main () {
+ int n = 0;
+ out_param (out n);
+ if (n != 1)
+ return 1;
+ ref_param (ref n);
+ if (n != 3)
+ return 2;
+ return 0;
+ }
+}
+
+
diff --git a/mono/tests/pinvoke.cs b/mono/tests/pinvoke.cs
new file mode 100755
index 00000000000..dd526727318
--- /dev/null
+++ b/mono/tests/pinvoke.cs
@@ -0,0 +1,21 @@
+using System;
+using System.Runtime.InteropServices;
+
+public class Test {
+
+ [DllImport("cygwin1.dll", EntryPoint="puts", CharSet=CharSet.Ansi)]
+ public static extern int puts (string name);
+
+ public static int Main () {
+ puts ("A simple Test for PInvoke");
+
+ if (Math.Cos (Math.PI) != -1)
+ return 1;
+ if (Math.Acos (1) != 0)
+ return 1;
+
+ return 0;
+ }
+}
+
+
diff --git a/mono/tests/random.cs b/mono/tests/random.cs
new file mode 100755
index 00000000000..004046c9765
--- /dev/null
+++ b/mono/tests/random.cs
@@ -0,0 +1,21 @@
+
+public class GenRandom {
+ static int last = 42;
+
+ public static double gen_random(double max) {
+
+ last = (last * 3877 + 29573) % 139968;
+ return( max * last / 139968 );
+ }
+
+ public static int Main() {
+ int N = 900000;
+ double result = 0;
+
+ while (N-- != 0) {
+ result = gen_random(100.0);
+ }
+ //printf("%.9f\n", result);
+ return(0);
+ }
+}
diff --git a/mono/tests/stream.cs b/mono/tests/stream.cs
new file mode 100755
index 00000000000..0636c8dc0d2
--- /dev/null
+++ b/mono/tests/stream.cs
@@ -0,0 +1,15 @@
+using System;
+using System.IO;
+
+public class Test {
+
+ public static int Main () {
+ FileStream s = new FileStream ("/tmp/stest.dat", FileMode.Create);
+
+
+
+ return 0;
+ }
+}
+
+
diff --git a/mono/tests/struct.cs b/mono/tests/struct.cs
new file mode 100755
index 00000000000..d95f39ecaf3
--- /dev/null
+++ b/mono/tests/struct.cs
@@ -0,0 +1,21 @@
+struct Point
+{
+ public int x, y, z;
+ public Point(int x, int y) {
+ this.x = x;
+ this.y = y;
+ this.z = 5;
+ }
+}
+
+public class test {
+ public static int Main () {
+ Point p = new Point (10, 20);
+ Point c = p;
+ if (c.x != 10)
+ return 1;
+ if (c.y != 20)
+ return 2;
+ return 0;
+ }
+}
diff --git a/mono/tests/switch.cs b/mono/tests/switch.cs
new file mode 100755
index 00000000000..5fa65893c8d
--- /dev/null
+++ b/mono/tests/switch.cs
@@ -0,0 +1,25 @@
+public class Switch {
+
+ public static int test (int n) {
+ switch (n) {
+ case 0: return 1;
+ case 1: return 0;
+ case -1: return 2;
+ default:
+ return 0xff;
+ }
+ }
+ public static int Main () {
+ if (test(0) != 1)
+ return 1;
+ if (test(1) != 0)
+ return 2;
+ if (test(-1) != 2)
+ return 3;
+ if (test(3) != 0xff)
+ return 4;
+ return 0;
+ }
+}
+
+
diff --git a/mono/tests/test-driver b/mono/tests/test-driver
new file mode 100755
index 00000000000..e3396c20e1f
--- /dev/null
+++ b/mono/tests/test-driver
@@ -0,0 +1,33 @@
+#!/usr/bin/perl -w
+
+my $interpreter = shift;
+my $test = shift;
+my $output = $test;
+my $stdout = $test.'.stdout';
+my $stderr = $test.'.stderr';
+
+$output =~ s/\.exe$/.output/;
+
+$| = 0;
+print "Testing $test... ";
+
+my $res = system("$interpreter $test 2>/dev/null 1>$stdout");
+
+if ($res) {
+ printf ("failed $? (%d) signal (%d).\n", $? >> 8, $? & 127);
+} elsif (-f $output) {
+ print "failed output.\n" if (read_file ($output) ne read_file ($stdout));
+} else {
+ print "pass.\n";
+ #unlink ($result);
+}
+exit (0);
+
+sub read_file {
+ local ($/);
+ my $out = shift;
+ open (F, "<$out") || die $!;
+ $out = <F>;
+ close(F);
+ return $out;
+}
diff --git a/mono/tests/test-ops.cs b/mono/tests/test-ops.cs
new file mode 100755
index 00000000000..6606db508ba
--- /dev/null
+++ b/mono/tests/test-ops.cs
@@ -0,0 +1,32 @@
+
+public class TestIntOps {
+
+ public static int simple_add (int a, int b) {
+ return a+b;
+ }
+
+ public static int simple_sub (int a, int b) {
+ return a-b;
+ }
+
+ public static int simple_mul (int a, int b) {
+ return a*b;
+ }
+
+ public static int Main() {
+ int num = 1;
+
+ if (simple_add (1, 1) != 2) return num;
+ num++;
+ if (simple_add (31, -1) != 30) return num;
+ num++;
+ if (simple_sub (31, -1) != 32) return num;
+ num++;
+ if (simple_mul (12, 12) != 144) return num;
+ num++;
+
+ // add more meaningful tests
+
+ return 0;
+ }
+}
diff --git a/mono/wrapper/.cvsignore b/mono/wrapper/.cvsignore
new file mode 100644
index 00000000000..f0889f36f79
--- /dev/null
+++ b/mono/wrapper/.cvsignore
@@ -0,0 +1,8 @@
+Makefile
+Makefile.in
+.deps
+.libs
+wrapper.h
+*.lo
+*.la
+Wrapper.cs \ No newline at end of file
diff --git a/mono/wrapper/Makefile.am b/mono/wrapper/Makefile.am
new file mode 100644
index 00000000000..e9af1c43eb2
--- /dev/null
+++ b/mono/wrapper/Makefile.am
@@ -0,0 +1,22 @@
+lib_LTLIBRARIES = libmonowrapper.la
+
+INCLUDES = $(GLIB_CFLAGS) -I$(top_srcdir)
+
+libmonowrapper_la_SOURCES = \
+ wrapper.c
+
+libmonowrapperincludedir = $(includir)/mono/wrapper
+
+libmonowrapperinclude_HEADERS =
+ wrapper.h
+
+noinst_HEADERS =
+
+
+wrapper.h: genwrapper.pl
+ $(srcdir)/genwrapper.pl >wrapper.h
+
+BUILT_SOURCES = wrapper.h
+CLEANFILES += $(BUILT_SOURCES)
+
+EXTRA_DIST = genwrapper.pl \ No newline at end of file
diff --git a/mono/wrapper/genwrapper.pl b/mono/wrapper/genwrapper.pl
new file mode 100755
index 00000000000..7443cfd994d
--- /dev/null
+++ b/mono/wrapper/genwrapper.pl
@@ -0,0 +1,458 @@
+#!/usr/bin/perl
+
+# Author:
+# Dietmar Maurer (dietmar@ximian.com)
+#
+# (C) 2001 Ximian, Inc.
+
+use Getopt::Long;
+init();
+
+@includes = ("sys/types.h", "sys/stat.h", "unistd.h", "fcntl.h", "glib.h",
+ "errno.h");
+$cflags = `gnome-config --cflags glib`;
+$cflags =~ s/\n//;
+
+$lib = "monowrapper";
+
+create_struct ("MonoWrapperStat", "stat",
+ "uint", "st_dev",
+ "uint", "st_mode",
+ "uint", "st_nlink",
+ "uint", "st_uid",
+ "uint", "st_gid",
+ "long", "st_size",
+ "uint", "st_atime",
+ "uint", "st_mtime",
+ "uint", "st_ctime",
+ );
+
+create_func ($lib, "", "seek", "long",
+ "IntPtr", "fd",
+ "long", "offset",
+ "int", "whence");
+
+create_func ($lib, "", "read", "int",
+ "IntPtr", "fd",
+ "void *", "buf",
+ "int", "count");
+
+create_func ($lib, "", "write", "int",
+ "IntPtr", "fd",
+ "void *", "buf",
+ "int", "count");
+
+create_func ($lib, "", "fstat", "int",
+ "IntPtr", "fd",
+ "stat *", "buf");
+
+create_func ($lib, "", "ftruncate", "int",
+ "IntPtr", "fd",
+ "long", "length");
+
+create_func ($lib, "", "open", "IntPtr",
+ "string", "path",
+ "int", "flags",
+ "int", "mode");
+
+create_func ($lib, "", "close", "int",
+ "IntPtr", "fd");
+
+map_const ("int", "%d", "SEEK_SET",
+ "int", "%d", "SEEK_CUR",
+ "int", "%d", "SEEK_END",
+
+ "int", "0x%08x", "O_RDONLY",
+ "int", "0x%08x", "O_WRONLY",
+ "int", "0x%08x", "O_RDWR",
+ "int", "0x%08x", "O_CREAT",
+ "int", "0x%08x", "O_EXCL",
+ "int", "0x%08x", "O_NOCTTY",
+ "int", "0x%08x", "O_TRUNC",
+ "int", "0x%08x", "O_SYNC",
+ "int", "0x%08x", "O_APPEND",
+
+ "int", "0x%08x", "STDIN_FILENO",
+ "int", "0x%08x", "STDOUT_FILENO",
+ "int", "0x%08x", "STDERR_FILENO",
+
+ "int", "0x%08x", "S_IFMT",
+ "int", "0x%08x", "S_IFSOCK",
+ "int", "0x%08x", "S_IFLNK",
+ "int", "0x%08x", "S_IFREG",
+ "int", "0x%08x", "S_IFBLK",
+ "int", "0x%08x", "S_IFDIR",
+ "int", "0x%08x", "S_IFCHR",
+ "int", "0x%08x", "S_IFIFO",
+ "int", "0x%08x", "S_ISUID",
+ "int", "0x%08x", "S_ISGID",
+ "int", "0x%08x", "S_ISVTX",
+ "int", "0x%08x", "S_IRWXU",
+ "int", "0x%08x", "S_IRUSR",
+ "int", "0x%08x", "S_IWUSR",
+ "int", "0x%08x", "S_IXUSR",
+ "int", "0x%08x", "S_IRWXG",
+ "int", "0x%08x", "S_IRGRP",
+ "int", "0x%08x", "S_IWGRP",
+ "int", "0x%08x", "S_IXGRP",
+ "int", "0x%08x", "S_IRWXO",
+ "int", "0x%08x", "S_IROTH",
+ "int", "0x%08x", "S_IWOTH",
+ "int", "0x%08x", "S_IXOTH",
+
+ "int", "%d", "EPERM",
+ "int", "%d", "ENOENT",
+ "int", "%d", "ESRCH",
+ "int", "%d", "EINTR",
+ "int", "%d", "EIO",
+ "int", "%d", "ENXIO",
+ "int", "%d", "E2BIG",
+ "int", "%d", "ENOEXEC",
+ "int", "%d", "EBADF",
+ "int", "%d", "ECHILD",
+ "int", "%d", "EAGAIN",
+ "int", "%d", "ENOMEM",
+ "int", "%d", "EACCES",
+ "int", "%d", "EFAULT",
+ "int", "%d", "ENOTBLK",
+ "int", "%d", "EBUSY",
+ "int", "%d", "EEXIST",
+ "int", "%d", "EXDEV",
+ "int", "%d", "ENODEV",
+ "int", "%d", "EISDIR",
+ "int", "%d", "EINVAL",
+ "int", "%d", "ENFILE",
+ "int", "%d", "EMFILE",
+ "int", "%d", "ENOTTY",
+ "int", "%d", "ETXTBSY",
+ "int", "%d", "EFBIG",
+ "int", "%d", "ENOSPC",
+ "int", "%d", "ESPIPE",
+ "int", "%d", "EROFS",
+ "int", "%d", "EMLINK",
+ "int", "%d", "EPIPE",
+ "int", "%d", "EDOM",
+ "int", "%d", "ERANGE",
+ "int", "%d", "EDEADLK",
+ "int", "%d", "ENAMETOOLONG",
+ "int", "%d", "ENOLCK",
+ "int", "%d", "ENOSYS",
+ "int", "%d", "ENOTEMPTY",
+ "int", "%d", "ELOOP",
+ "int", "%d", "EWOULDBLOCK",
+ "int", "%d", "ENOMSG",
+ "int", "%d", "EIDRM",
+ "int", "%d", "ECHRNG",
+ "int", "%d", "EL2NSYNC",
+ "int", "%d", "EL3HLT",
+ "int", "%d", "EL3RST",
+ "int", "%d", "ELNRNG",
+ "int", "%d", "EUNATCH",
+ "int", "%d", "ENOCSI",
+ "int", "%d", "EL2HLT",
+ "int", "%d", "EBADE",
+ "int", "%d", "EBADR",
+ "int", "%d", "EXFULL",
+ "int", "%d", "ENOANO",
+ "int", "%d", "EBADRQC",
+ "int", "%d", "EBADSLT",
+ "int", "%d", "EDEADLOCK",
+ "int", "%d", "EBFONT",
+ "int", "%d", "ENOSTR",
+ "int", "%d", "ENODATA",
+ "int", "%d", "ETIME",
+ "int", "%d", "ENOSR",
+ "int", "%d", "ENONET",
+ "int", "%d", "ENOPKG",
+ "int", "%d", "EREMOTE",
+ "int", "%d", "ENOLINK",
+ "int", "%d", "EADV",
+ "int", "%d", "ESRMNT",
+ "int", "%d", "ECOMM",
+ "int", "%d", "EPROTO",
+ "int", "%d", "EMULTIHOP",
+ "int", "%d", "EDOTDOT",
+ "int", "%d", "EBADMSG",
+ "int", "%d", "EOVERFLOW",
+ "int", "%d", "ENOTUNIQ",
+ "int", "%d", "EBADFD",
+ "int", "%d", "EREMCHG",
+ "int", "%d", "ELIBACC",
+ "int", "%d", "ELIBBAD",
+ "int", "%d", "ELIBSCN",
+ "int", "%d", "ELIBMAX",
+ "int", "%d", "ELIBEXEC",
+ "int", "%d", "EILSEQ",
+ "int", "%d", "ERESTART",
+ "int", "%d", "ESTRPIPE",
+ "int", "%d", "EUSERS",
+ "int", "%d", "ENOTSOCK",
+ "int", "%d", "EDESTADDRREQ",
+ "int", "%d", "EMSGSIZE",
+ "int", "%d", "EPROTOTYPE",
+ "int", "%d", "ENOPROTOOPT",
+ "int", "%d", "EPROTONOSUPPORT",
+ "int", "%d", "ESOCKTNOSUPPORT",
+ "int", "%d", "EOPNOTSUPP",
+ "int", "%d", "EPFNOSUPPORT",
+ "int", "%d", "EAFNOSUPPORT",
+ "int", "%d", "EADDRINUSE",
+ "int", "%d", "EADDRNOTAVAIL",
+ "int", "%d", "ENETDOWN",
+ "int", "%d", "ENETUNREACH",
+ "int", "%d", "ENETRESET",
+ "int", "%d", "ECONNABORTED",
+ "int", "%d", "ECONNRESET",
+ "int", "%d", "ENOBUFS",
+ "int", "%d", "EISCONN",
+ "int", "%d", "ENOTCONN",
+ "int", "%d", "ESHUTDOWN",
+ "int", "%d", "ETOOMANYREFS",
+ "int", "%d", "ETIMEDOUT",
+ "int", "%d", "ECONNREFUSED",
+ "int", "%d", "EHOSTDOWN",
+ "int", "%d", "EHOSTUNREACH",
+ "int", "%d", "EALREADY",
+ "int", "%d", "EINPROGRESS",
+ "int", "%d", "ESTALE",
+ "int", "%d", "EUCLEAN",
+ "int", "%d", "ENOTNAM",
+ "int", "%d", "ENAVAIL",
+ "int", "%d", "EISNAM",
+ "int", "%d", "EREMOTEIO",
+ "int", "%d", "EDQUOT",
+ "int", "%d", "ENOMEDIUM",
+ "int", "%d", "EMEDIUMTYPE",
+ );
+
+sub init {
+
+ $csmode = 0;
+
+ GetOptions ("csharp" => \$csmode) or die "cant parse options";
+
+ $CC = $env{"CC"};
+
+ if (!$CC) {
+ $CC = "gcc";
+ }
+
+
+ %tmap = ("void" => "void",
+ "IntPtr" => "int",
+ "sbyte" => "gint8",
+ "byte" => "guint8",
+ "short" => "gint16",
+ "ushort" => "guint16",
+ "int" => "gint32",
+ "uint" => "guint32",
+ "long" => "gint64",
+ "ulong" => "guint64",
+ "string" => "const char *",
+ );
+}
+
+sub t {
+ my ($name) = @_;
+ my ($rname) = $name;
+
+ if ($name =~ m/(.*)\*\s*$/) {
+ $rname = $1;
+ $rname =~ s/\s+$//; # remove trailing spaces
+ $rval = $tmap{$rname} || die "unable to map type \"$name\"";
+ return "$rval*";
+ }
+
+ $rval = $tmap{$name} || die "unable to map type \"$name\"";
+
+}
+
+sub create_func {
+ my (@func) = @_;
+ my ($i) = 0;
+ my ($res) = "";
+
+ if ($func[1] eq "") {
+ $func[1] = "mono_wrapper_$func[2]";
+ }
+
+ if ($csmode) {
+
+ $res = "\t[DllImport(\"$func[0]\", EntryPoint=\"$func[1]\", CharSet=CharSet.Ansi)]\n";
+ $res .= "\tpublic unsafe static extern $func[3] $func[2] (";
+ $i +=4;
+ while ($i <= $#func) {
+ if ($i>4) {
+ $res .= ", ";
+ }
+ $res .= "$func[$i] $func[$i+1]";
+
+ $i+=2;
+ }
+ $res .= ");\n\n";
+
+ $res_func .= $res;
+
+ } else {
+
+ $res = t($func[3]) . "\n$func[1] (";
+
+ $i +=4;
+ while ($i <= $#func) {
+ if ($i>4) {
+ $res .= ", ";
+ }
+ $res .= t($func[$i]) . " $func[$i+1]";
+
+ $i+=2;
+ }
+ $res .= ");\n\n";
+
+ $res_func .= $res;
+ }
+}
+
+sub create_struct {
+ my (@str) = @_;
+ my ($i) = 0;
+ my ($res) = "";
+
+ if ($csmode) {
+ $res = "public struct $str[1] {\n";
+ $i +=2;
+ while ($i <= $#str) {
+ $res .= "\tpublic $str[$i] $str[$i+1];\n";
+ $i+=2;
+ }
+ $res .= "};\n\n";
+ } else {
+ $res = "typedef struct {\n";
+ $i += 2;
+ while ($i <= $#str) {
+ $res .= "\t" . t($str[$i]) . " $str[$i+1];\n";
+ $i+=2;
+ }
+ $res .= "} $str[0];\n\n";
+ }
+
+ $tmap{"$str[1]"} = "$str[0]";
+
+ $res_struct .= $res;
+}
+
+sub map_const {
+ my (@co) = @_;
+ my ($res) = "";
+ my ($l);
+ my ($space);
+
+ if (!$csmode) {
+ return;
+ }
+
+ my ($tfn) = "/tmp/etypes$$.c";
+
+ open (TFN, ">$tfn") || die (0);
+
+ for ($i = 0; $i <= $#includes; $i++) {
+ print TFN "#include \"$includes[$i]\"\n";
+ }
+
+ print TFN "\nint main () {\n";
+ for ($i = 0; $i <= $#co; $i+=3) {
+
+ $l = 20 - length($co[$i+2]);
+
+ $space = "";
+ for (my ($j) = 0; $j < $l; $j++) {
+ $space = $space . " ";
+ }
+
+ print TFN "printf (\"\\tpublic const %s %s $space= $co[$i+1];\\n\",".
+ " \"$co[$i]\", \"$co[$i+2]\", $co[$i+2]);\n";
+
+ }
+ print TFN "exit (-1);\n";
+ print TFN "}\n";
+
+ close (TFN);
+
+ system ("$CC $cflags $tfn") == 0
+ or die "calling c compiler failed";
+
+ system ("rm $tfn");
+
+ $res = `./a.out`;
+
+ if (!$res) {
+ die "calling a.out failde";
+ }
+
+ $res_const = $res_const . $res;
+
+ system ("rm ./a.out");
+}
+
+sub etypes_end {
+
+ @ae = split (/\./, $__class);
+
+ print $res_struct;
+
+ print "public class $ae[$#ae] {\n\n";
+
+ if ($res_const) {
+ print "$res_const\n\n";
+ }
+
+ print "$res_func";
+
+ printf "} // class $ae[$#ae]\n\n";
+
+ for ($i = $#ae - 1; $i >= 0; $i--) {
+ print "} // namescape $ae[$i]\n";
+ }
+
+}
+
+print "/*\n * Generated automatically: do not edit this file.\n */\n\n";
+
+
+if ($csmode) {
+
+ print "using System;\n";
+ print "using System.Runtime.InteropServices;\n\n";
+
+ print "namespace Unix {\n\n";
+
+ print $res_struct;
+
+ print "public class Wrapper {\n\n";
+
+ if ($res_const) {
+ print "$res_const\n\n";
+ }
+
+ print "$res_func";
+
+ print "}\n";
+
+ print "}\n";
+
+
+} else {
+
+ print "#ifndef _MONO_WRAPPER_H_\n#define _MONO_WRAPPER_H_ 1\n\n";
+
+ for ($i = 0; $i <= $#includes; $i++) {
+ print "#include <$includes[$i]>\n";
+ }
+
+ print "\n";
+
+ print $res_struct;
+
+ print $res_func;
+
+ print "#endif\n";
+}
diff --git a/mono/wrapper/wrapper.c b/mono/wrapper/wrapper.c
new file mode 100644
index 00000000000..56364ac651a
--- /dev/null
+++ b/mono/wrapper/wrapper.c
@@ -0,0 +1,68 @@
+#include <config.h>
+#include <limits.h>
+
+#include "wrapper.h"
+
+gint64
+mono_wrapper_seek (int fd, gint64 offset, gint32 whence)
+{
+ if (offset > INT_MAX || offset < INT_MIN)
+ return -1;
+
+ return lseek (fd, offset, whence);
+}
+
+gint32
+mono_wrapper_read (int fd, void* buf, gint32 count)
+{
+ return read (fd, buf, count);
+}
+
+gint32
+mono_wrapper_write (int fd, void* buf, gint32 count)
+{
+ return write (fd, buf, count);
+}
+
+gint32
+mono_wrapper_fstat (int fd, MonoWrapperStat* buf)
+{
+ struct stat fs;
+
+ if (fstat (fd, &fs) != 0)
+ return -1;
+
+ buf->st_dev = fs.st_dev;
+ buf->st_mode = fs.st_mode;
+ buf->st_nlink = fs.st_nlink;
+ buf->st_uid = fs.st_uid;
+ buf->st_gid = fs.st_gid;
+ buf->st_size = fs.st_size;
+ buf->st_atime = fs.st_atime;
+ buf->st_mtime = fs.st_ctime;
+ buf->st_ctime = fs.st_ctime;
+
+ return 0;
+}
+
+gint32
+mono_wrapper_ftruncate (int fd, gint64 length)
+{
+ if (length > INT_MAX || length < INT_MIN)
+ return -1;
+
+ return ftruncate (fd, length);
+}
+
+int
+mono_wrapper_open (const char * path, gint32 flags, gint32 mode)
+{
+ return open (path, flags, mode);
+}
+
+gint32
+mono_wrapper_close (int fd)
+{
+ return close (fd);
+}
+
diff --git a/notes/cil b/notes/cil
new file mode 100644
index 00000000000..458aca543ba
--- /dev/null
+++ b/notes/cil
@@ -0,0 +1,13 @@
+Random collection of notes
+
+ * What is the point of having the InlineVar argument to
+ opcodes be a signed integer instead of unsigned?
+
+
+Storage
+
+ The CIL metadata is a very compressed file format, even the
+ sizes of blobs and strings are recorded in a compressed form.
+ Still, all strings are encoded using 16-bit chars, instead of the
+ more efficient UTF-8.
+
diff --git a/runtime/.cvsignore b/runtime/.cvsignore
new file mode 100644
index 00000000000..f914cb46763
--- /dev/null
+++ b/runtime/.cvsignore
@@ -0,0 +1,3 @@
+Makefile
+Makefile.in
+*.dll
diff --git a/runtime/Makefile.am b/runtime/Makefile.am
new file mode 100644
index 00000000000..7f438031a0a
--- /dev/null
+++ b/runtime/Makefile.am
@@ -0,0 +1,18 @@
+#
+# This is just used to copy and install the DLL files that are currently
+# being compiled on windows.
+#
+
+#
+# Keep in sync with mono/mono/metadata/Makefile.am
+#
+assembliesdir = $(libdir)
+
+install-data-hook:
+ -cp $(srcdir)/*.dll $(assembliesdir)
+
+dist-hook:
+ -cp $(srcdir)/*.dll $(distdir)
+
+copy_dlls:
+ cp /nt/mono/mcs/class/*/*.dll . \ No newline at end of file
diff --git a/status/.cvsignore b/status/.cvsignore
new file mode 100755
index 00000000000..2fa0dc1b707
--- /dev/null
+++ b/status/.cvsignore
@@ -0,0 +1,6 @@
+compare.exe
+compare.pdb
+corlib.xml
+bn
+bm
+web
diff --git a/status/ByMaintainer.cs b/status/ByMaintainer.cs
new file mode 100755
index 00000000000..c6643834af1
--- /dev/null
+++ b/status/ByMaintainer.cs
@@ -0,0 +1,52 @@
+//
+// ByMaintainer.cs
+//
+// Author:
+// Sean MacIsaac (sean@ximian.com)
+//
+// (C) Ximian, Inc. http://www.ximian.com
+//
+
+using System;
+using System.IO;
+using System.Xml;
+using System.Xml.Xsl;
+using System.Xml.XPath;
+
+namespace Mono.StatusReporter {
+ public class ByMaintainer {
+ static int Main (string[] args) {
+ XslTransform xslt = new XslTransform ();
+ xslt.Load ("ByMaintainer.xsl");
+ //StreamWriter sw = new StreamWriter ("bm/index");
+
+ XPathDocument doc = new XPathDocument ("class.xml");
+
+ XmlDocument maintainers = new XmlDocument();
+
+ maintainers.Load ("maintainers.xml");
+
+ XmlNodeList people = maintainers.GetElementsByTagName("person");
+ foreach (XmlNode node in people) {
+ string email = node.Attributes.GetNamedItem("email").Value;
+ string name = node.Attributes.GetNamedItem("name").Value;
+
+ //sw.WriteLine ("<li><a href=\"" + email + ".html\">" + email + "</a>");
+
+ XmlWriter writer = new XmlTextWriter ("bm/" + email, null);
+
+ XsltArgumentList xslArg = new XsltArgumentList ();
+ xslArg.AddParam ("email", "", email);
+ xslArg.AddParam ("name", "", name);
+
+ xslt.Transform (doc, xslArg, writer);
+
+ writer.Close ();
+ }
+
+ //sw.Close ();
+
+ return 0;
+ }
+ }
+}
diff --git a/status/ByMaintainer.xsl b/status/ByMaintainer.xsl
new file mode 100755
index 00000000000..bf0b04e765e
--- /dev/null
+++ b/status/ByMaintainer.xsl
@@ -0,0 +1,34 @@
+<?xml version="1.0"?>
+
+<xsl:stylesheet version='1.0' xmlns:xsl='http://www.w3.org/1999/XSL/Transform'>
+
+<xsl:param name="email"/>
+<xsl:param name="name"/>
+
+<xsl:template match="/">
+ <h2>Maintained by <xsl:value-of select="$name"/> (<xsl:value-of select="$email"/>)</h2>
+ <table border="1">
+ <tr>
+ <td>Class Name</td>
+ <td>Last Activity</td>
+ <td>Implementation</td>
+ <td>Test Suite</td>
+ <td>Completion</td>
+ </tr>
+ <xsl:apply-templates/>
+ </table>
+</xsl:template>
+
+<xsl:template match="class">
+ <xsl:if test="contains(maintainers/*, $email)">
+ <tr>
+ <td><xsl:value-of select="@name"/></td>
+ <td><xsl:value-of select="last-activity"/></td>
+ <td><xsl:value-of select="implementation"/></td>
+ <td><xsl:value-of select="test-suite"/></td>
+ <td><xsl:value-of select="completion"/></td>
+ </tr>
+ </xsl:if>
+</xsl:template>
+
+</xsl:stylesheet>
diff --git a/status/ByNamespace.cs b/status/ByNamespace.cs
new file mode 100755
index 00000000000..7d16ef434ef
--- /dev/null
+++ b/status/ByNamespace.cs
@@ -0,0 +1,55 @@
+//
+// ByNamespace.cs
+//
+// Author:
+// Sean MacIsaac (sean@ximian.com)
+//
+// (C) Ximian, Inc. http://www.ximian.com
+//
+
+using System;
+using System.Collections;
+using System.IO;
+using System.Xml;
+using System.Xml.Xsl;
+using System.Xml.XPath;
+
+namespace Mono.StatusReporter {
+ public class ByMaintainer {
+ static int Main (string[] args) {
+ XslTransform xslt = new XslTransform ();
+ xslt.Load ("ByNamespace.xsl");
+ //StreamWriter sw = new StreamWriter ("bn/index");
+
+ XPathDocument doc = new XPathDocument ("class.xml");
+
+ XmlDocument classxml = new XmlDocument ();
+ classxml.Load ("class.xml");
+ ArrayList nsList = new ArrayList ();
+
+ XmlNodeList classes = classxml.GetElementsByTagName ("class");
+ foreach (XmlNode node in classes) {
+ string name = node.Attributes.GetNamedItem ("name").Value;
+ string ns = name.Substring(0, name.LastIndexOf ("."));
+ if (!nsList.Contains (ns)) nsList.Add (ns);
+ }
+
+ foreach (string str in nsList) {
+ //sw.WriteLine ("<li><a href=\"" + str + ".html\">" + str + "</a>");
+
+ XmlWriter writer = new XmlTextWriter ("bn/" + str, null);
+
+ XsltArgumentList xslArg = new XsltArgumentList ();
+ xslArg.AddParam ("ns", "", str);
+
+ xslt.Transform (doc, xslArg, writer);
+
+ writer.Close ();
+ }
+
+ //sw.Close ();
+
+ return 0;
+ }
+ }
+}
diff --git a/status/ByNamespace.xsl b/status/ByNamespace.xsl
new file mode 100755
index 00000000000..d75ce75fbde
--- /dev/null
+++ b/status/ByNamespace.xsl
@@ -0,0 +1,38 @@
+<?xml version="1.0"?>
+
+<xsl:stylesheet version='1.0' xmlns:xsl='http://www.w3.org/1999/XSL/Transform'>
+
+<xsl:output method="html" indent="yes"/>
+
+<xsl:param name="ns"/>
+
+<xsl:template match="/">
+ <h2>Classes in <xsl:value-of select="$ns"/></h2>
+ <table border="1">
+ <tr>
+ <td>Class Name</td>
+ <td>Head Maintainer</td>
+ <td>Last Activity</td>
+ <td>Implementation</td>
+ <td>Test Suite</td>
+ <td>Completion</td>
+ </tr>
+
+ <xsl:apply-templates/>
+ </table>
+</xsl:template>
+
+<xsl:template match="class">
+ <xsl:if test="starts-with(@name, $ns) and not(contains(substring-after(@name, concat($ns, '.')), '.'))">
+ <tr>
+ <td><xsl:value-of select="@name"/></td>
+ <td><xsl:value-of select="maintainers/maintainer[1]"/></td>
+ <td><xsl:value-of select="last-activity"/></td>
+ <td><xsl:value-of select="implementation"/></td>
+ <td><xsl:value-of select="test-suite"/></td>
+ <td><xsl:value-of select="completion"/></td>
+ </tr>
+ </xsl:if>
+</xsl:template>
+
+</xsl:stylesheet>
diff --git a/status/ChangeLog b/status/ChangeLog
new file mode 100755
index 00000000000..2caae9224b2
--- /dev/null
+++ b/status/ChangeLog
@@ -0,0 +1,21 @@
+2001-07-17 Sean MacIsaac <macisaac@ximian.com>
+
+ * ByNamespace.xsl: removed bug for improper handling of namespace.
+ eg System.Collections.Blah was showing up in System list.
+
+2001-07-16 Sean MacIsaac <macisaac@ximian.com>
+
+ * ByNamespace.xsl: Needed by ByNamespace.cs.
+
+ * ByNamespace.cs: Generates html by namespace..
+
+ * ByMaintainer.xsl: Needed by ByMaintainer.cs.
+
+ * ByMaintainer.cs: Generates html by maintainer.
+
+ * class.xml: Class maintainers go here.
+
+ * maintainers.xml: Only maintaining email/name pairs here.
+
+ * compare-assembly.cs: Started refactoring to give what Migee
+ wants.
diff --git a/status/class.xml b/status/class.xml
new file mode 100755
index 00000000000..7bcbd9ee3ff
--- /dev/null
+++ b/status/class.xml
@@ -0,0 +1,2224 @@
+<classes>
+ <class name="System.Object">
+ <last-activity>Jul-15-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>75</completion>
+ <maintainers>
+ <maintainer>miguel@ximian.com</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.ApplicationException">
+ <last-activity>Jul-15-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>100</completion>
+ <maintainers>
+ <maintainer>joe@ximian.com</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.ArgumentException">
+ <last-activity>Jul-15-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>100</completion>
+ <maintainers>
+ <maintainer>joe@ximian.com</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.ArgumentNullException">
+ <last-activity>Jul-15-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>100</completion>
+ <maintainers>
+ <maintainer>joe@ximian.com</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.ArgumentOutOfRangeException">
+ <last-activity>Jul-15-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>100</completion>
+ <maintainers>
+ <maintainer>joe@ximian.com</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.ArithmeticException">
+ <last-activity>Jul-15-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>100</completion>
+ <maintainers>
+ <maintainer>joe@ximian.com</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.Array">
+ <last-activity>Jul-15-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>90</completion>
+ <maintainers>
+ <maintainer>joe@ximian.com</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.ArrayTypeMismatchException">
+ <last-activity>Jul-15-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>100</completion>
+ <maintainers>
+ <maintainer>joe@ximian.com</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.Attribute">
+ <last-activity>Aug-16-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>95</completion>
+ <maintainers>
+ <maintainer>ndrochak@gol.com</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.FlagsAttribute">
+ <last-activity>Aug-19-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>95</completion>
+ <maintainers>
+ <maintainer>miguel@ximian.com</maintainer>
+ </maintainers>
+ </class>
+ <class name="System.CLSCompliantAttribute">
+ <last-activity>Aug-19-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>95</completion>
+ <maintainers>
+ <maintainer>miguel@ximian.com</maintainer>
+ </maintainers>
+ </class>
+ <class name="System.ContextStaticAttribute">
+ <last-activity>Aug-19-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>95</completion>
+ <maintainers>
+ <maintainer>miguel@ximian.com</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.DivideByZeroException">
+ <last-activity>Jul-15-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>100</completion>
+ <maintainers>
+ <maintainer>joe@ximian.com</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.DuplicateWaitObjectException">
+ <last-activity>Jul-15-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>100</completion>
+ <maintainers>
+ <maintainer>joe@ximian.com</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.Exception">
+ <last-activity>Jul-15-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>50</completion>
+ <maintainers>
+ <maintainer>miguel@ximian.com</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.ExecutionEngineException">
+ <last-activity>Jul-15-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>100</completion>
+ <maintainers>
+ <maintainer>joe@ximian.com</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.FormatException">
+ <last-activity>Jul-15-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>100</completion>
+ <maintainers>
+ <maintainer>joe@ximian.com</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.ICloneable">
+ <last-activity>Jul-15-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>100</completion>
+ <maintainers>
+ <maintainer>miguel@ximian.com</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.IComparible">
+ <last-activity>Jul-15-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>100</completion>
+ <maintainers>
+ <maintainer>miguel@ximian.com</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.IConvertible">
+ <last-activity>Jul-15-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>100</completion>
+ <maintainers>
+ <maintainer>miguel@ximian.com</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.ICustomFormatter">
+ <last-activity>Jul-15-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>100</completion>
+ <maintainers>
+ <maintainer>miguel@ximian.com</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.IDisposable">
+ <last-activity>Jul-15-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>100</completion>
+ <maintainers>
+ <maintainer>miguel@ximian.com</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.IFormatProvider">
+ <last-activity>Jul-15-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>100</completion>
+ <maintainers>
+ <maintainer>miguel@ximian.com</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.IFormattable">
+ <last-activity>Jul-15-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>100</completion>
+ <maintainers>
+ <maintainer>miguel@ximian.com</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.IndexOutOfRangeException">
+ <last-activity>Jul-15-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>100</completion>
+ <maintainers>
+ <maintainer>joe@ximian.com</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.Int16">
+ <last-activity>Jul-15-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>10</completion>
+ <maintainers>
+ <maintainer>miguel@ximian.com</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.Int32">
+ <last-activity>Jul-15-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>10</completion>
+ <maintainers>
+ <maintainer>miguel@ximian.com</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.Int64">
+ <last-activity>Jul-15-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>10</completion>
+ <maintainers>
+ <maintainer>miguel@ximian.com</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.IndividualCastException">
+ <last-activity>Jul-15-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>100</completion>
+ <maintainers>
+ <maintainer>joe@ximian.com</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.InvalidOperationException">
+ <last-activity>Jul-15-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>100</completion>
+ <maintainers>
+ <maintainer>joe@ximian.com</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.InvalidProgramException">
+ <last-activity>Jul-15-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>100</completion>
+ <maintainers>
+ <maintainer>joe@ximian.com</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.MulticastNotSupportedException">
+ <last-activity>Jul-15-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>100</completion>
+ <maintainers>
+ <maintainer>joe@ximian.com</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.NotFiniteNumberException">
+ <last-activity>Jul-15-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>100</completion>
+ <maintainers>
+ <maintainer>joe@ximian.com</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.NotSupportedException">
+ <last-activity>Jul-15-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>100</completion>
+ <maintainers>
+ <maintainer>joe@ximian.com</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.NullReferenceException">
+ <last-activity>Jul-15-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>100</completion>
+ <maintainers>
+ <maintainer>joe@ximian.com</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.OutOfMemoryException">
+ <last-activity>Jul-15-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>100</completion>
+ <maintainers>
+ <maintainer>joe@ximian.com</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.OverflowExceptionException">
+ <last-activity>Jul-15-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>100</completion>
+ <maintainers>
+ <maintainer>joe@ximian.com</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.RankException">
+ <last-activity>Jul-15-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>100</completion>
+ <maintainers>
+ <maintainer>joe@ximian.com</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.StackOverflowException">
+ <last-activity>Jul-15-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>100</completion>
+ <maintainers>
+ <maintainer>joe@ximian.com</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.String">
+ <last-activity>Jul-15-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>50</completion>
+ <maintainers>
+ <maintainer>fejj@ximian.com</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.SystemException">
+ <last-activity>Jul-15-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>100</completion>
+ <maintainers>
+ <maintainer>joe@ximian.com</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.TypeCode">
+ <last-activity>Jul-15-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>100</completion>
+ <maintainers>
+ <maintainer>miguel@ximian.com</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.TypeInitializationException">
+ <last-activity>Jul-15-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>100</completion>
+ <maintainers>
+ <maintainer>joe@ximian.com</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.UInt16">
+ <last-activity>Jul-15-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>10</completion>
+ <maintainers>
+ <maintainer>miguel@ximian.com</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.UInt32">
+ <last-activity>Jul-15-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>10</completion>
+ <maintainers>
+ <maintainer>miguel@ximian.com</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.UInt64">
+ <last-activity>Jul-15-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>10</completion>
+ <maintainers>
+ <maintainer>miguel@ximian.com</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.ValueType">
+ <last-activity>Jul-15-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>100</completion>
+ <maintainers>
+ <maintainer>miguel@ximian.com</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.Version">
+ <last-activity>Jul-15-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>100</completion>
+ <maintainers>
+ <maintainer>miguel@ximian.com</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.Void">
+ <last-activity>Jul-15-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>100</completion>
+ <maintainers>
+ <maintainer>miguel@ximian.com</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.Collections.ArrayList">
+ <last-activity>Jul-15-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>100</completion>
+ <maintainers>
+ <maintainer>vladimir@pobox.com</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.Collections.ICollection">
+ <last-activity>Jul-15-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>100</completion>
+ <maintainers>
+ <maintainer>vladimir@pobox.com</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.Runtime.Serialization.StreamingContext">
+ <last-activity>Aug-6-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>100</completion>
+ <maintainers>
+ <maintainer>miguel@ximian.com</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.Runtime.Serialization.StreamingContextStates">
+ <last-activity>Aug-6-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>100</completion>
+ <maintainers>
+ <maintainer>miguel@ximian.com</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.Runtime.Serialization.IObjectReference">
+ <last-activity>Aug-6-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>100</completion>
+ <maintainers>
+ <maintainer>miguel@ximian.com</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.Runtime.Remoting.ObjRef">
+ <last-activity>Aug-6-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>20</completion>
+ <maintainers>
+ <maintainer>miguel@ximian.com</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.MarshalByRefObject">
+ <last-activity>Aug-6-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>20</completion>
+ <maintainers>
+ <maintainer>miguel@ximian.com</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.Collections.IComparer">
+ <last-activity>Jul-15-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>100</completion>
+ <maintainers>
+ <maintainer>vladimir@pobox.com</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.Collections.IDictionary">
+ <last-activity>Jul-15-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>100</completion>
+ <maintainers>
+ <maintainer>vladimir@pobox.com</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.Collections.IDictionaryEnumerator">
+ <last-activity>Jul-15-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>100</completion>
+ <maintainers>
+ <maintainer>vladimir@pobox.com</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.Collections.IEnumerable">
+ <last-activity>Jul-15-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>100</completion>
+ <maintainers>
+ <maintainer>vladimir@pobox.com</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.Collections.IEnumerator">
+ <last-activity>Jul-15-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>100</completion>
+ <maintainers>
+ <maintainer>vladimir@pobox.com</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.Collections.HashCodeProvider">
+ <last-activity>Jul-15-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>100</completion>
+ <maintainers>
+ <maintainer>vladimir@pobox.com</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.Collections.IList">
+ <last-activity>Jul-15-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>100</completion>
+ <maintainers>
+ <maintainer>vladimir@pobox.com</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.Collections.Hashtable">
+ <last-activity>Jul-15-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>yes</test-suite>
+ <completion>75</completion>
+ <maintainers>
+ <maintainer>jbarn@httcb.net</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.Collections.Queue">
+ <last-activity>Jul-30-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>yes</test-suite>
+ <completion>?</completion>
+ <maintainers>
+ <maintainer>ric@users.sourceforge.net</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.Globalization.UnicodeCateogy">
+ <last-activity>Jul-15-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>100</completion>
+ <maintainers>
+ <maintainer>joe@ximian.com</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.Net.AuthenticationManager">
+ <last-activity>Jul-15-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>75</completion>
+ <maintainers>
+ <maintainer>miguel@ximian.com</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.Net.Authorization">
+ <last-activity>Jul-15-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>75</completion>
+ <maintainers>
+ <maintainer>miguel@ximian.com</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.Net.EndPoint">
+ <last-activity>Jul-15-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>75</completion>
+ <maintainers>
+ <maintainer>miguel@ximian.com</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.Net.IAuthenticationModule">
+ <last-activity>Jul-15-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>75</completion>
+ <maintainers>
+ <maintainer>miguel@ximian.com</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.Net.ICredentialLookup">
+ <last-activity>Jul-15-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>75</completion>
+ <maintainers>
+ <maintainer>miguel@ximian.com</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.Net.IPAdress">
+ <last-activity>Jul-15-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>75</completion>
+ <maintainers>
+ <maintainer>miguel@ximian.com</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.Net.IPEndPoint">
+ <last-activity>Jul-15-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>75</completion>
+ <maintainers>
+ <maintainer>miguel@ximian.com</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.Net.SocketAddress">
+ <last-activity>Jul-15-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>75</completion>
+ <maintainers>
+ <maintainer>miguel@ximian.com</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.Text.ASCIIEncoding">
+ <last-activity>Jul-15-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>10</completion>
+ <maintainers>
+ <maintainer>macisaac@ximian.com</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.Text.Encoding">
+ <last-activity>Jul-15-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>10</completion>
+ <maintainers>
+ <maintainer>macisaac@ximian.com</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.StringBuilder">
+ <last-activity>Jul-15-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>yes</test-suite>
+ <completion>100</completion>
+ <maintainers>
+ <maintainer>marcins@zipworld.com.au</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.Environment">
+ <last-activity>Aug-12-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>?</completion>
+ <maintainers>
+ <maintainer>develop@wtfo-guru.com</maintainer>
+ </maintainers>
+ </class>
+ <class name="System.IO.Path">
+ <last-activity>Jul-20-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>yes</test-suite>
+ <completion>50</completion>
+ <maintainers>
+ <maintainer>develop@wtfo-guru.com</maintainer>
+ </maintainers>
+ </class>
+ <class name="System.OperatingSystem">
+ <last-activity>Aug-13-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>yes</test-suite>
+ <completion>50</completion>
+ <maintainers>
+ <maintainer>develop@wtfo-guru.com</maintainer>
+ </maintainers>
+ </class>
+ <class name="System.IO.Directory">
+ <last-activity>Aug-13-2001</last-activity>
+ <implementation>no</implementation>
+ <test-suite>no</test-suite>
+ <completion>?</completion>
+ <maintainers>
+ <maintainer>develop@wtfo-guru.com</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.Text.UnicodeEncoding">
+ <last-activity>Jul-15-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>10</completion>
+ <maintainers>
+ <maintainer>macisaac@ximian.com</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.Text.UTF7Encoding">
+ <last-activity>Jul-15-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>10</completion>
+ <maintainers>
+ <maintainer>macisaac@ximian.com</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.Text.UTF8Encoding">
+ <last-activity>Jul-15-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>10</completion>
+ <maintainers>
+ <maintainer>macisaac@ximian.com</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.Math">
+ <last-activity>Jul-19-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>95</completion>
+ <maintainers>
+ <maintainer>bob@thestuff.net</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.IO.TextReader">
+ <last-activity>Jul-15-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>?</completion>
+ <maintainers>
+ <maintainer>marcins@zipworld.com.au</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.Console">
+ <last-activity>Jul-0-2001</last-activity>
+ <implementation>no</implementation>
+ <test-suite>no</test-suite>
+ <completion>?</completion>
+ <maintainers>
+ <maintainer>marcel@narings.nl</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.IO.StringReader">
+ <last-activity>Jul-15-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>yes</test-suite>
+ <completion>?</completion>
+ <maintainers>
+ <maintainer>marcins@zipworld.com.au</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.IO.TextWriter">
+ <last-activity>Jul-15-2001</last-activity>
+ <implementation>no</implementation>
+ <test-suite>no</test-suite>
+ <completion>yes</completion>
+ <maintainers>
+ <maintainer>marcins@zipworld.com.au</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.IO.StringWriter">
+ <last-activity>Jul-15-2001</last-activity>
+ <implementation>no</implementation>
+ <test-suite>yes</test-suite>
+ <completion>yes</completion>
+ <maintainers>
+ <maintainer>marcins@zipworld.com.au</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.EventArgs">
+ <last-activity>Jul-16-2001</last-activity>
+ <implementation>no</implementation>
+ <test-suite>no</test-suite>
+ <completion>?</completion>
+ <maintainers>
+ <maintainer>michaellambert@bellsouth.net</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.IAsyncResult">
+ <last-activity>Jul-21-2001</last-activity>
+ <implementation>no</implementation>
+ <test-suite>no</test-suite>
+ <completion>?</completion>
+ <maintainers>
+ <maintainer>michaellambert@bellsouth.net</maintainer>
+ </maintainers>
+ </class>
+ <class name="System.Threading.WaitHandle">
+ <last-activity>Jul-21-2001</last-activity>
+ <implementation>no</implementation>
+ <test-suite>no</test-suite>
+ <completion>?</completion>
+ <maintainers>
+ <maintainer>michaellambert@bellsouth.net</maintainer>
+ </maintainers>
+ </class>
+ <class name="System.IntPtr">
+ <last-activity>Jul-21-2001</last-activity>
+ <implementation>no</implementation>
+ <test-suite>no</test-suite>
+ <completion>?</completion>
+ <maintainers>
+ <maintainer>michaellambert@bellsouth.net</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.IO.MemoryStream">
+ <last-activity>Jul-19-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>yes</test-suite>
+ <completion>?</completion>
+ <maintainers>
+ <maintainer>marcins@zipworld.com.au</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.Collections.Stack">
+ <last-activity>Jul-15-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>yes</test-suite>
+ <completion>100</completion>
+ <maintainers>
+ <maintainer>rooneg@electricjellyfish.net</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.Diagnostics.Switch">
+ <last-activity>Jul-15-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>?</completion>
+ <maintainers>
+ <maintainer>angryjohn69@nc.rr.com</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.Diagnostics.BooleanSwitch">
+ <last-activity>Jul-15-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>?</completion>
+ <maintainers>
+ <maintainer>angryjohn69@nc.rr.com</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.Diagnostics.TraceSwitch">
+ <last-activity>Jul-15-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>?</completion>
+ <maintainers>
+ <maintainer>angryjohn69@nc.rr.com</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.Diagnostics.ConditionalAttribute">
+ <last-activity>Aug-21-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>99</completion>
+ <maintainers>
+ <maintainer>ndrochak@gol.com</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.Diagnostics.Debug">
+ <last-activity>Jul-15-2001</last-activity>
+ <implementation>no</implementation>
+ <test-suite>no</test-suite>
+ <completion>?</completion>
+ <maintainers>
+ <maintainer>angryjohn69@nc.rr.com</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.Diagnostics.DebuggableAttribute">
+ <last-activity>Aug-21-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>99</completion>
+ <maintainers>
+ <maintainer>ndrochak@gol.com</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.Diagnostics.DiagnosticsConfigurationHandler">
+ <last-activity>Jul-15-2001</last-activity>
+ <implementation>no</implementation>
+ <test-suite>no</test-suite>
+ <completion>?</completion>
+ <maintainers>
+ <maintainer>angryjohn69@nc.rr.com</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.Diagnostics.StackFrame">
+ <last-activity>Jul-15-2001</last-activity>
+ <implementation>no</implementation>
+ <test-suite>no</test-suite>
+ <completion>?</completion>
+ <maintainers>
+ <maintainer>angryjohn69@nc.rr.com</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.Diagnostics.StackTrace">
+ <last-activity>Jul-15-2001</last-activity>
+ <implementation>no</implementation>
+ <test-suite>no</test-suite>
+ <completion>?</completion>
+ <maintainers>
+ <maintainer>angryjohn69@nc.rr.com</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.Diagnostics.Trace">
+ <last-activity>Jul-15-2001</last-activity>
+ <implementation>no</implementation>
+ <test-suite>no</test-suite>
+ <completion>?</completion>
+ <maintainers>
+ <maintainer>angryjohn69@nc.rr.com</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.Diagnostics.TraceLevel">
+ <last-activity>Jul-15-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>?</completion>
+ <maintainers>
+ <maintainer>angryjohn69@nc.rr.com</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.Diagnostics.TraceListener">
+ <last-activity>Jul-15-2001</last-activity>
+ <implementation>no</implementation>
+ <test-suite>no</test-suite>
+ <completion>?</completion>
+ <maintainers>
+ <maintainer>angryjohn69@nc.rr.com</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.IO.BinaryReader">
+ <last-activity>Jul-15-2001</last-activity>
+ <implementation>no</implementation>
+ <test-suite>no</test-suite>
+ <completion>?</completion>
+ <maintainers>
+ <maintainer>czw@home.se</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.IO.BinaryWriter">
+ <last-activity>Jul-15-2001</last-activity>
+ <implementation>no</implementation>
+ <test-suite>no</test-suite>
+ <completion>?</completion>
+ <maintainers>
+ <maintainer>czw@home.se</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.IO.FileStream">
+ <last-activity>Jul-15-2001</last-activity>
+ <implementation>no</implementation>
+ <test-suite>no</test-suite>
+ <completion>?</completion>
+ <maintainers>
+ <maintainer>czw@home.se</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.IO.Stream">
+ <last-activity>Jul-15-2001</last-activity>
+ <implementation>no</implementation>
+ <test-suite>no</test-suite>
+ <completion>?</completion>
+ <maintainers>
+ <maintainer>czw@home.se</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.Xml.XmlReader">
+ <last-activity>Jul-15-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>yes</test-suite>
+ <completion>?</completion>
+ <maintainers>
+ <maintainer>jason@injektilo.org</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.Xml.XmlTextReader">
+ <last-activity>Jul-15-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>yes</test-suite>
+ <completion>?</completion>
+ <maintainers>
+ <maintainer>jason@injektilo.org</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.Xml.XmlNodeType">
+ <last-activity>Jul-19-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>yes</test-suite>
+ <completion>?</completion>
+ <maintainers>
+ <maintainer>jason@injektilo.org</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.Xml.XmlSpace">
+ <last-activity>Jul-19-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>yes</test-suite>
+ <completion>?</completion>
+ <maintainers>
+ <maintainer>jason@injektilo.org</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.Xml.XmlNameTable">
+ <last-activity>Jul-19-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>yes</test-suite>
+ <completion>?</completion>
+ <maintainers>
+ <maintainer>jason@injektilo.org</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.Xml.XmlNamespaceManager">
+ <last-activity>Jul-19-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>yes</test-suite>
+ <completion>?</completion>
+ <maintainers>
+ <maintainer>jason@injektilo.org</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.Xml.XmlParserContext">
+ <last-activity>Jul-19-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>yes</test-suite>
+ <completion>?</completion>
+ <maintainers>
+ <maintainer>jason@injektilo.org</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.Xml.XmlResolver">
+ <last-activity>Jul-19-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>yes</test-suite>
+ <completion>?</completion>
+ <maintainers>
+ <maintainer>jason@injektilo.org</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.Xml.XmlDocument">
+ <last-activity>Jul-29-2001</last-activity>
+ <implementation>no</implementation>
+ <test-suite>no</test-suite>
+ <completion>?</completion>
+ <maintainers>
+ <maintainer>hildjj@cursive.net</maintainer>
+ </maintainers>
+ </class>
+ <class name="System.Xml.XmlAttribute">
+ <last-activity>Jul-29-2001</last-activity>
+ <implementation>no</implementation>
+ <test-suite>no</test-suite>
+ <completion>?</completion>
+ <maintainers>
+ <maintainer>hildjj@cursive.net</maintainer>
+ </maintainers>
+ </class>
+ <class name="System.Xml.XmlAttributeCollection">
+ <last-activity>Jul-29-2001</last-activity>
+ <implementation>no</implementation>
+ <test-suite>no</test-suite>
+ <completion>?</completion>
+ <maintainers>
+ <maintainer>hildjj@cursive.net</maintainer>
+ </maintainers>
+ </class>
+ <class name="System.Xml.XmlNode">
+ <last-activity>Jul-29-2001</last-activity>
+ <implementation>no</implementation>
+ <test-suite>no</test-suite>
+ <completion>?</completion>
+ <maintainers>
+ <maintainer>hildjj@cursive.net</maintainer>
+ </maintainers>
+ </class>
+ <class name="System.Xml.XmlElement">
+ <last-activity>Jul-29-2001</last-activity>
+ <implementation>no</implementation>
+ <test-suite>no</test-suite>
+ <completion>?</completion>
+ <maintainers>
+ <maintainer>hildjj@cursive.net</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.Collections.SortedList">
+ <last-activity>Jul-16-2001</last-activity>
+ <implementation>no</implementation>
+ <test-suite>no</test-suite>
+ <completion>?</completion>
+ <maintainers>
+ <maintainer>serge@wildwestsoftware.com</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.Collections.Specialized.CollectionsUtil">
+ <last-activity>Jul-16-2001</last-activity>
+ <implementation>no</implementation>
+ <test-suite>no</test-suite>
+ <completion>?</completion>
+ <maintainers>
+ <maintainer>jbarn@httcb.net</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.Collections.Specialized.HybridDictionary">
+ <last-activity>Jul-16-2001</last-activity>
+ <implementation>no</implementation>
+ <test-suite>no</test-suite>
+ <completion>?</completion>
+ <maintainers>
+ <maintainer>jbarn@httcb.net</maintainer>
+ <maintainer>josh@narf.com</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.Collections.Specialized.ListDictionary">
+ <last-activity>Aug-21-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>100</completion>
+ <maintainers>
+ <maintainer>jbarn@httcb.net</maintainer>
+ <maintainer>josh@narf.com</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.Collections.Specialized.StringCollection">
+ <last-activity>Jul-16-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>yes</test-suite>
+ <completion>?</completion>
+ <maintainers>
+ <maintainer>jbarn@httcb.net</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.Collections.Specialized.StringDictionary">
+ <last-activity>Jul-16-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>100</completion>
+ <maintainers>
+ <maintainer>jbarn@httcb.net</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.Collections.Specialized.StringEnumerator">
+ <last-activity>Jul-16-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>100</completion>
+ <maintainers>
+ <maintainer>jbarn@httcb.net</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.Collections.Specialized.NameObjectCollectionBase">
+ <last-activity>Jul-20-2001</last-activity>
+ <implementation>no</implementation>
+ <test-suite>no</test-suite>
+ <completion>?</completion>
+ <maintainers>
+ <maintainer>gleb@eurosoft.od.ua</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.Collections.Specialized.KeysCollection">
+ <last-activity>Jul-20-2001</last-activity>
+ <implementation>no</implementation>
+ <test-suite>no</test-suite>
+ <completion>?</completion>
+ <maintainers>
+ <maintainer>gleb@eurosoft.od.ua</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.Collections.Specialized.NameValueCollection">
+ <last-activity>Jul-20-2001</last-activity>
+ <implementation>no</implementation>
+ <test-suite>no</test-suite>
+ <completion>?</completion>
+ <maintainers>
+ <maintainer>gleb@eurosoft.od.ua</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.Uri">
+ <last-activity>Jul-17-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>40</completion>
+ <maintainers>
+ <maintainer>rooneg@electricjellyfish.net</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.UriBuilder">
+ <last-activity>Jul-16-2001</last-activity>
+ <implementation>no</implementation>
+ <test-suite>no</test-suite>
+ <completion>?</completion>
+ <maintainers>
+ <maintainer>scott@stonecobra.com</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.UriFormatException">
+ <last-activity>Jul-16-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>85</completion>
+ <maintainers>
+ <maintainer>scott@stonecobra.com</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.Boolean">
+ <last-activity>Jul-16-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>?</completion>
+ <maintainers>
+ <maintainer>dsh2120@draper.com</maintainer>
+ </maintainers>
+ </class>
+ <class name="System.Convert">
+ <last-activity>Jul-16-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>?</completion>
+ <maintainers>
+ <maintainer>dsh2120@draper.com</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.Collections.BitArray">
+ <last-activity>Jul-16-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>yes</test-suite>
+ <completion>?</completion>
+ <maintainers>
+ <maintainer>dmenest@yahoo.com</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.TimeSpan">
+ <last-activity>Jul-17-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>?</completion>
+ <maintainers>
+ <maintainer>duco@lorentz.xs4all.nl</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.Web.Cache">
+ <last-activity>Jul-20-2001</last-activity>
+ <implementation>no</implementation>
+ <test-suite>no</test-suite>
+ <completion>?</completion>
+ <maintainers>
+ <maintainer>Patrik.Torstensson@framfablabs.com</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.Configuration.Assemblies.AssemblyHash">
+ <last-activity>Jul-17-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>?</completion>
+ <maintainers>
+ <maintainer>tomasr@mvps.org</maintainer>
+ </maintainers>
+ </class>
+ <class name="System.Configuration.Assemblies.AssemblyVersionCompatibility">
+ <last-activity>Jul-17-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>?</completion>
+ <maintainers>
+ <maintainer>tomasr@mvps.org</maintainer>
+ </maintainers>
+ </class>
+ <class name="System.Configuration.Assemblies.AssemblyHashAlgorithm">
+ <last-activity>Jul-17-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>?</completion>
+ <maintainers>
+ <maintainer>tomasr@mvps.org</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.Security">
+ <last-activity>Jul-17-2001</last-activity>
+ <implementation>no</implementation>
+ <test-suite>no</test-suite>
+ <completion>?</completion>
+ <maintainers>
+ <maintainer>tomasr@mvps.org</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.Security.Policy">
+ <last-activity>Jul-17-2001</last-activity>
+ <implementation>no</implementation>
+ <test-suite>no</test-suite>
+ <completion>?</completion>
+ <maintainers>
+ <maintainer>tomasr@mvps.org</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.Collections.CaseInsensitiveComparer">
+ <last-activity>Jul-19-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>yes</test-suite>
+ <completion>?</completion>
+ <maintainers>
+ <maintainer>serge@wildwestsoftware.com</maintainer>
+ </maintainers>
+ </class>
+ <class name="System.Collections.CaseInsensitiveHashCodeProvider">
+ <last-activity>Jul-19-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>yes</test-suite>
+ <completion>?</completion>
+ <maintainers>
+ <maintainer>serge@wildwestsoftware.com</maintainer>
+ </maintainers>
+ </class>
+ <class name="System.Collections.Comparer">
+ <last-activity>Jul-19-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>yes</test-suite>
+ <completion>?</completion>
+ <maintainers>
+ <maintainer>serge@wildwestsoftware.com</maintainer>
+ </maintainers>
+ </class>
+ <class name="System.Collections.ReadOnlyCollectionBase">
+ <last-activity>Aug-03-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>yes</test-suite>
+ <completion>100</completion>
+ <maintainers>
+ <maintainer>ndrochak@gol.com</maintainer>
+ </maintainers>
+ </class>
+ <class name="System.Collections.CollectionBase">
+ <last-activity>Aug-03-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>yes</test-suite>
+ <completion>100</completion>
+ <maintainers>
+ <maintainer>ndrochak@gol.com</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.Byte">
+ <last-activity>Jul-19-2001</last-activity>
+ <implementation>no</implementation>
+ <test-suite>yes</test-suite>
+ <completion>?</completion>
+ <maintainers>
+ <maintainer>dholden@draper.com</maintainer>
+ </maintainers>
+ </class>
+ <class name="System.SByte">
+ <last-activity>Jul-19-2001</last-activity>
+ <implementation>no</implementation>
+ <test-suite>yes</test-suite>
+ <completion>?</completion>
+ <maintainers>
+ <maintainer>dholden@draper.com</maintainer>
+ </maintainers>
+ </class>
+ <class name="System.Single">
+ <last-activity>Jul-19-2001</last-activity>
+ <implementation>no</implementation>
+ <test-suite>yes</test-suite>
+ <completion>?</completion>
+ <maintainers>
+ <maintainer>dholden@draper.com</maintainer>
+ </maintainers>
+ </class>
+ <class name="System.Globalization.NumberFormatInfo">
+ <last-activity>Jul-27-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>yes</test-suite>
+ <completion>?</completion>
+ <maintainers>
+ <maintainer>dholden@draper.com</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.Security.Cryptography.HashAlgorithm">
+ <last-activity>Jul-20-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>yes</test-suite>
+ <completion>?</completion>
+ <maintainers>
+ <maintainer>Matthew.S.Ford@rose-hulman.edu</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.Security.Cryptography.CipherMode">
+ <last-activity>Jul-20-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>yes</test-suite>
+ <completion>?</completion>
+ <maintainers>
+ <maintainer>Matthew.S.Ford@rose-hulman.edu</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.Security.Cryptography.CryptoStreamMode">
+ <last-activity>Jul-20-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>yes</test-suite>
+ <completion>?</completion>
+ <maintainers>
+ <maintainer>Matthew.S.Ford@rose-hulman.edu</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.Security.Cryptography.KeySizes">
+ <last-activity>Jul-20-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>yes</test-suite>
+ <completion>?</completion>
+ <maintainers>
+ <maintainer>Matthew.S.Ford@rose-hulman.edu</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.Security.Cryptography.PaddingMode">
+ <last-activity>Jul-20-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>yes</test-suite>
+ <completion>?</completion>
+ <maintainers>
+ <maintainer>Matthew.S.Ford@rose-hulman.edu</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.Security.Cryptography.MD5">
+ <last-activity>Jul-20-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>yes</test-suite>
+ <completion>?</completion>
+ <maintainers>
+ <maintainer>Matthew.S.Ford@rose-hulman.edu</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.Security.Cryptography.MD5CryptoServiceProvider">
+ <last-activity>Jul-20-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>yes</test-suite>
+ <completion>?</completion>
+ <maintainers>
+ <maintainer>Matthew.S.Ford@rose-hulman.edu</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.Security.Cryptography.SHA1">
+ <last-activity>Jul-20-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>yes</test-suite>
+ <completion>?</completion>
+ <maintainers>
+ <maintainer>Matthew.S.Ford@rose-hulman.edu</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.Security.Cryptography.SHA1CryptoServiceProvider">
+ <last-activity>Jul-20-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>yes</test-suite>
+ <completion>?</completion>
+ <maintainers>
+ <maintainer>Matthew.S.Ford@rose-hulman.edu</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.Security.Cryptography.SHA256">
+ <last-activity>Jul-20-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>yes</test-suite>
+ <completion>?</completion>
+ <maintainers>
+ <maintainer>Matthew.S.Ford@rose-hulman.edu</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.Security.Cryptography.SHA384">
+ <last-activity>Jul-20-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>yes</test-suite>
+ <completion>?</completion>
+ <maintainers>
+ <maintainer>Matthew.S.Ford@rose-hulman.edu</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.Security.Cryptography.SHA512">
+ <last-activity>Jul-20-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>yes</test-suite>
+ <completion>?</completion>
+ <maintainers>
+ <maintainer>Matthew.S.Ford@rose-hulman.edu</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.Security.Cryptography.DeriveBytes">
+ <last-activity>Aug-1-2001</last-activity>
+ <implementation>no</implementation>
+ <test-suite>no</test-suite>
+ <completion>?</completion>
+ <maintainers>
+ <maintainer>Matthew.S.Ford@rose-hulman.edu</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.Security.Cryptography.PasswordDeriveBytes">
+ <last-activity>Aug-1-2001</last-activity>
+ <implementation>no</implementation>
+ <test-suite>no</test-suite>
+ <completion>?</completion>
+ <maintainers>
+ <maintainer>Matthew.S.Ford@rose-hulman.edu</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.Security.Cryptography.Rijndael">
+ <last-activity>Aug-1-2001</last-activity>
+ <implementation>no</implementation>
+ <test-suite>no</test-suite>
+ <completion>?</completion>
+ <maintainers>
+ <maintainer>Matthew.S.Ford@rose-hulman.edu</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.Security.Cryptography.RijndaelManaged">
+ <last-activity>Aug-1-2001</last-activity>
+ <implementation>no</implementation>
+ <test-suite>no</test-suite>
+ <completion>?</completion>
+ <maintainers>
+ <maintainer>Matthew.S.Ford@rose-hulman.edu</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.Security.Cryptography.SymmetricalAlgoritm">
+ <last-activity>Aug-1-2001</last-activity>
+ <implementation>no</implementation>
+ <test-suite>no</test-suite>
+ <completion>?</completion>
+ <maintainers>
+ <maintainer>Matthew.S.Ford@rose-hulman.edu</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.Security.Cryptography.ToBase64Transform">
+ <last-activity>Aug-1-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>?</completion>
+ <maintainers>
+ <maintainer>serge@wildwestsoftware.com</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.Security.Cryptography.FromBase64Transform">
+ <last-activity>Aug-1-2001</last-activity>
+ <implementation>no</implementation>
+ <test-suite>no</test-suite>
+ <completion>?</completion>
+ <maintainers>
+ <maintainer>serge@wildwestsoftware.com</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.Security.Cryptography.DES">
+ <last-activity>Aug-1-2001</last-activity>
+ <implementation>no/soft</implementation>
+ <test-suite>no</test-suite>
+ <completion>?</completion>
+ <maintainers>
+ <maintainer>serge@wildwestsoftware.com</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.Security.Cryptography.DESCrytpoServiceProvider">
+ <last-activity>Aug-1-2001</last-activity>
+ <implementation>no/soft</implementation>
+ <test-suite>no</test-suite>
+ <completion>?</completion>
+ <maintainers>
+ <maintainer>serge@wildwestsoftware.com</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.Random">
+ <last-activity>Aug-6-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>yes</test-suite>
+ <completion>85</completion>
+ <maintainers>
+ <maintainer>bob@thestuff.net</maintainer>
+ </maintainers>
+ </class>
+
+ <class name="System.DateTime">
+ <last-activity>Jul-23-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>10</completion>
+ <maintainers>
+ <maintainer>marcel@narings.nl</maintainer>
+ </maintainers>
+ </class>
+ <class name="System.Globalization.Calendar">
+ <last-activity>Jul-24-2001</last-activity>
+ <implementation>no</implementation>
+ <test-suite>no</test-suite>
+ <completion>?</completion>
+ <maintainers>
+ <maintainer>marcel@narings.nl</maintainer>
+ </maintainers>
+ </class>
+ <class name="System.Globalization.GregorianCalendar">
+ <last-activity>Jul-24-2001</last-activity>
+ <implementation>no</implementation>
+ <test-suite>no</test-suite>
+ <completion>?</completion>
+ <maintainers>
+ <maintainer>marcel@narings.nl</maintainer>
+ </maintainers>
+ </class>
+ <class name="System.Globalization.HebrewCalendar">
+ <last-activity>Jul-24-2001</last-activity>
+ <implementation>no</implementation>
+ <test-suite>no</test-suite>
+ <completion>?</completion>
+ <maintainers>
+ <maintainer>marcel@narings.nl</maintainer>
+ </maintainers>
+ </class>
+ <class name="System.Globalization.HijriCalendar">
+ <last-activity>Jul-24-2001</last-activity>
+ <implementation>no</implementation>
+ <test-suite>no</test-suite>
+ <completion>?</completion>
+ <maintainers>
+ <maintainer>marcel@narings.nl</maintainer>
+ </maintainers>
+ </class>
+ <class name="System.Globalization.JapaneseCalendar">
+ <last-activity>Jul-24-2001</last-activity>
+ <implementation>no</implementation>
+ <test-suite>no</test-suite>
+ <completion>?</completion>
+ <maintainers>
+ <maintainer>marcel@narings.nl</maintainer>
+ </maintainers>
+ </class>
+ <class name="System.Globalization.JulianCalendar">
+ <last-activity>Jul-24-2001</last-activity>
+ <implementation>no</implementation>
+ <test-suite>no</test-suite>
+ <completion>?</completion>
+ <maintainers>
+ <maintainer>marcel@narings.nl</maintainer>
+ </maintainers>
+ </class>
+ <class name="System.Globalization.KoreanCalendar">
+ <last-activity>Jul-24-2001</last-activity>
+ <implementation>no</implementation>
+ <test-suite>no</test-suite>
+ <completion>?</completion>
+ <maintainers>
+ <maintainer>marcel@narings.nl</maintainer>
+ </maintainers>
+ </class>
+ <class name="System.Globalization.TaiwanCalendar">
+ <last-activity>Jul-24-2001</last-activity>
+ <implementation>no</implementation>
+ <test-suite>no</test-suite>
+ <completion>?</completion>
+ <maintainers>
+ <maintainer>marcel@narings.nl</maintainer>
+ </maintainers>
+ </class>
+ <class name="System.Globalization.ThaiBuddhistCalendar">
+ <last-activity>Jul-24-2001</last-activity>
+ <implementation>no</implementation>
+ <test-suite>no</test-suite>
+ <completion>?</completion>
+ <maintainers>
+ <maintainer>marcel@narings.nl</maintainer>
+ </maintainers>
+ </class>
+ <class name="System.ComponentModel.Container">
+ <last-activity>Aug-2-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>100</completion>
+ <maintainers>
+ <maintainer>miguel@ximian.com</maintainer>
+ </maintainers>
+ </class>
+ <class name="System.ComponentModel.IContainer">
+ <last-activity>Aug-2-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>100</completion>
+ <maintainers>
+ <maintainer>miguel@ximian.com</maintainer>
+ </maintainers>
+ </class>
+ <class name="System.ComponentModel.Component">
+ <last-activity>Aug-2-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>100</completion>
+ <maintainers>
+ <maintainer>miguel@ximian.com</maintainer>
+ </maintainers>
+ </class>
+ <class name="System.ComponentModel.ComponentCollection">
+ <last-activity>Aug-2-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>10</completion>
+ <maintainers>
+ <maintainer>miguel@ximian.com</maintainer>
+ </maintainers>
+ </class>
+ <class name="System.ComponentModel.IComponent">
+ <last-activity>Aug-2-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>100</completion>
+ <maintainers>
+ <maintainer>miguel@ximian.com</maintainer>
+ </maintainers>
+ </class>
+ <class name="System.ComponentModel.ISite">
+ <last-activity>Aug-2-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>100</completion>
+ <maintainers>
+ <maintainer>miguel@ximian.com</maintainer>
+ </maintainers>
+ </class>
+ <class name="System.IServiceProvider">
+ <last-activity>Aug-2-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>100</completion>
+ <maintainers>
+ <maintainer>miguel@ximian.com</maintainer>
+ </maintainers>
+ </class>
+ <class name="System.EventHandler">
+ <last-activity>Aug-2-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>100</completion>
+ <maintainers>
+ <maintainer>miguel@ximian.com</maintainer>
+ </maintainers>
+ </class>
+ <class name="System.Web.HttpCacheability">
+ <last-activity>Aug-9-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>100</completion>
+ <maintainers>
+ <maintainer>bob@thestuff.net</maintainer>
+ </maintainers>
+ </class>
+ <class name="System.Web.HttpCacheRevalidation">
+ <last-activity>Aug-9-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>100</completion>
+ <maintainers>
+ <maintainer>bob@thestuff.net</maintainer>
+ </maintainers>
+ </class>
+ <class name="System.Web.HttpValidationStatus">
+ <last-activity>Aug-9-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>100</completion>
+ <maintainers>
+ <maintainer>bob@thestuff.net</maintainer>
+ </maintainers>
+ </class>
+ <class name="System.Web.ProcessShutdownReason">
+ <last-activity>Aug-9-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>100</completion>
+ <maintainers>
+ <maintainer>bob@thestuff.net</maintainer>
+ </maintainers>
+ </class>
+ <class name="System.Web.ProcessStatus">
+ <last-activity>Aug-9-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>100</completion>
+ <maintainers>
+ <maintainer>bob@thestuff.net</maintainer>
+ </maintainers>
+ </class>
+ <class name="System.Web.TraceMode">
+ <last-activity>Aug-9-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>100</completion>
+ <maintainers>
+ <maintainer>bob@thestuff.net</maintainer>
+ </maintainers>
+ </class>
+ <class name="System.Web.IHttpAsyncHandler">
+ <last-activity>Aug-9-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>100</completion>
+ <maintainers>
+ <maintainer>bob@thestuff.net</maintainer>
+ </maintainers>
+ </class>
+ <class name="System.Web.IHttpHandler">
+ <last-activity>Aug-9-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>100</completion>
+ <maintainers>
+ <maintainer>bob@thestuff.net</maintainer>
+ </maintainers>
+ </class>
+ <class name="System.Web.IHttpHandlerFactory">
+ <last-activity>Aug-9-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>100</completion>
+ <maintainers>
+ <maintainer>bob@thestuff.net</maintainer>
+ </maintainers>
+ </class>
+ <class name="System.Web.IHttpModule">
+ <last-activity>Aug-9-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>100</completion>
+ <maintainers>
+ <maintainer>bob@thestuff.net</maintainer>
+ </maintainers>
+ </class>
+ <class name="System.Web.BeginEventHandler">
+ <last-activity>Aug-9-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>100</completion>
+ <maintainers>
+ <maintainer>bob@thestuff.net</maintainer>
+ </maintainers>
+ </class>
+ <class name="System.Web.EndEventHandler">
+ <last-activity>Aug-9-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>100</completion>
+ <maintainers>
+ <maintainer>bob@thestuff.net</maintainer>
+ </maintainers>
+ </class>
+ <class name="System.Web.HttpCacheValidateHandler">
+ <last-activity>Aug-9-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>100</completion>
+ <maintainers>
+ <maintainer>bob@thestuff.net</maintainer>
+ </maintainers>
+ </class>
+ <class name="System.Web.HttpWorkerRequest.EndOfSendNotification">
+ <last-activity>Aug-9-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>100</completion>
+ <maintainers>
+ <maintainer>bob@thestuff.net</maintainer>
+ </maintainers>
+ </class>
+ <class name="System.Web.HttpCookie">
+ <last-activity>Aug-9-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>?</completion>
+ <maintainers>
+ <maintainer>bob@thestuff.net</maintainer>
+ </maintainers>
+ </class>
+ <class name="System.Web.HttpCookieCollection">
+ <last-activity>Aug-9-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>?</completion>
+ <maintainers>
+ <maintainer>bob@thestuff.net</maintainer>
+ </maintainers>
+ </class>
+ <class name="System.Drawing.Color">
+ <last-activity>Aug-10-2001</last-activity>
+ <implementation>no</implementation>
+ <test-suite>no</test-suite>
+ <completion>?</completion>
+ <maintainers>
+ <maintainer>mkestner@speakeasy.net</maintainer>
+ </maintainers>
+ </class>
+ <class name="System.Drawing.Point">
+ <last-activity>Aug-17-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>?</completion>
+ <maintainers>
+ <maintainer>mkestner@speakeasy.net</maintainer>
+ </maintainers>
+ </class>
+ <class name="System.Drawing.PointF">
+ <last-activity>Aug-17-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>?</completion>
+ <maintainers>
+ <maintainer>mkestner@speakeasy.net</maintainer>
+ </maintainers>
+ </class>
+ <class name="System.Drawing.Rectangle">
+ <last-activity>Aug-10-2001</last-activity>
+ <implementation>no</implementation>
+ <test-suite>no</test-suite>
+ <completion>?</completion>
+ <maintainers>
+ <maintainer>mkestner@speakeasy.net</maintainer>
+ </maintainers>
+ </class>
+ <class name="System.Drawing.RectangleF">
+ <last-activity>Aug-10-2001</last-activity>
+ <implementation>no</implementation>
+ <test-suite>no</test-suite>
+ <completion>?</completion>
+ <maintainers>
+ <maintainer>mkestner@speakeasy.net</maintainer>
+ </maintainers>
+ </class>
+ <class name="System.Drawing.Size">
+ <last-activity>Aug-17-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>?</completion>
+ <maintainers>
+ <maintainer>mkestner@speakeasy.net</maintainer>
+ </maintainers>
+ </class>
+ <class name="System.Drawing.SizeF">
+ <last-activity>Aug-17-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>?</completion>
+ <maintainers>
+ <maintainer>mkestner@speakeasy.net</maintainer>
+ </maintainers>
+ </class>
+ <class name="System.Web.UI.Control">
+ <last-activity>Aug-22-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>?</completion>
+ <maintainers>
+ <maintainer>bob@thestuff.net</maintainer>
+ </maintainers>
+ </class>
+ <class name="System.Configuration.ConfigurationException">
+ <last-activity>Aug-21-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>?</completion>
+ <maintainers>
+ <maintainer>cpodurgiel@msn.com</maintainer>
+ </maintainers>
+ </class>
+ <class name="System.Configuration.IgnoreSectionHandler">
+ <last-activity>Aug-21-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>?</completion>
+ <maintainers>
+ <maintainer>cpodurgiel@msn.com</maintainer>
+ </maintainers>
+ </class>
+ <class name="System.Configuration.IConfigurationSectionHandler">
+ <last-activity>Aug-21-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>?</completion>
+ <maintainers>
+ <maintainer>cpodurgiel@msn.com</maintainer>
+ </maintainers>
+ </class>
+ <class name="System.Configuration.ConfigurationSettings">
+ <last-activity>Aug-21-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>?</completion>
+ <maintainers>
+ <maintainer>cpodurgiel@msn.com</maintainer>
+ </maintainers>
+ </class>
+ <class name="System.Configuration.NameValueSectionHandler">
+ <last-activity>Aug-21-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>?</completion>
+ <maintainers>
+ <maintainer>cpodurgiel@msn.com</maintainer>
+ </maintainers>
+ </class>
+ <class name="System.Web.UI.HtmlControlls.HtmlControl">
+ <last-activity>Aug-22-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>?</completion>
+ <maintainers>
+ <maintainer>bob@thestuff.net</maintainer>
+ </maintainers>
+ </class>
+ <class name="System.Web.UI.HtmlControlls.HtmlContainerControl">
+ <last-activity>Aug-22-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>?</completion>
+ <maintainers>
+ <maintainer>bob@thestuff.net</maintainer>
+ </maintainers>
+ </class>
+ <class name="System.Web.UI.HtmlControlls.HtmlGenericControl">
+ <last-activity>Aug-22-2001</last-activity>
+ <implementation>yes</implementation>
+ <test-suite>no</test-suite>
+ <completion>?</completion>
+ <maintainers>
+ <maintainer>bob@thestuff.net</maintainer>
+ </maintainers>
+ </class>
+</classes>
+
diff --git a/status/commands b/status/commands
new file mode 100755
index 00000000000..fb92219a18b
--- /dev/null
+++ b/status/commands
@@ -0,0 +1,56 @@
+0,Class Libraries,index.html,index.src
+0,Namespace,namespace.html,namespace.src
+1,System,System.html,bn/System
+1,System.Collections,System.Collections.html,bn/System.Collections
+1,System.Collections.Specialized,System.Collections.Specialized.html,bn/System.Collections.Specialized
+1,System.ComponentModel,System.ComponentModel.html,bn/System.ComponentModel
+1,System.Configuration,System.Configuration.html,bn/System.Configuration
+1,System.Configuration.Assemblies,System.Configuration.Assemblies.html,bn/System.Configuration.Assemblies
+1,System.Diagnostics,System.Diagnostics.html,bn/System.Diagnostics
+1,System.Drawing,System.Drawing.html,bn/System.Drawing
+1,System.Globalization,System.Globalization.html,bn/System.Globalization
+1,System.IO,System.IO.html,bn/System.IO
+1,System.Net,System.Net.html,bn/System.Net
+1,System.Runtime.Remoting,System.Runtime.Remoting.html,bn/System.Runtime.Remoting
+1,System.Runtime.Serialization,System.Runtime.Serialization.html,bn/System.Runtime.Serialization
+1,System.Security,System.Security.html,bn/System.Security
+1,System.Security.Cryptography,System.Security.Cryptography.html,bn/System.Security.Cryptography
+1,System.Text,System.Text.html,bn/System.Text
+1,System.Threading,System.Threading.html,bn/System.Threading
+1,System.Web,System.Web.html,bn/System.Web
+1,System.Web.HttpWorkerRequest,System.Web.HttpWorkerRequest.html,bn/System.Web.HttpWorkerRequest
+1,System.Web.UI,System.Web.UI.html,bn/System.Web.UI
+1,System.Xml,System.Xml.html,bn/System.Xml
+0,Maintainer,maintainer.html,maintainer.src
+1,Matthew.S.Ford@rose-hulman.edu,Matthew.S.Ford@rose-hulman.edu.html,bm/Matthew.S.Ford@rose-hulman.edu
+1,Patrik.Torstensson@framfablabs.com,Patrik.Torstensson@framfablabs.com.html,bm/Patrik.Torstensson@framfablabs.com
+1,angryjohn69@nc.rr.com,angryjohn69@nc.rr.com.html,bm/angryjohn69@nc.rr.com
+1,bob@thestuff.net,bob@thestuff.net.html,bm/bob@thestuff.net
+1,cpodurgiel@msn.com,cpodurgiel@msn.com.html,bm/cpodurgiel@msn.com
+1,czw@home.se,czw@home.se.html,bm/czw@home.se
+1,develop@wtfo-guru.com,develop@wtfo-guru.com.html,bm/develop@wtfo-guru.com
+1,dholden@draper.com,dholden@draper.com.html,bm/dholden@draper.com
+1,dmenest@yahoo.com,dmenest@yahoo.com.html,bm/dmenest@yahoo.com
+1,dsh2120@draper.com,dsh2120@draper.com.html,bm/dsh2120@draper.com
+1,duco@lorentz.xs4all.nl,duco@lorentz.xs4all.nl.html,bm/duco@lorentz.xs4all.nl
+1,fejj@ximian.com,fejj@ximian.com.html,bm/fejj@ximian.com
+1,gleb@eurosoft.od.ua,gleb@eurosoft.od.ua.html,bm/gleb@eurosoft.od.ua
+1,hildjj@cursive.net,hildjj@cursive.net.html,bm/hildjj@cursive.net
+1,iain@ximian.com,iain@ximian.com.html,bm/iain@ximian.com
+1,jason@injektilo.org,jason@injektilo.org.html,bm/jason@injektilo.org
+1,jbarn@httcb.net,jbarn@httcb.net.html,bm/jbarn@httcb.net
+1,joe@ximian.com,joe@ximian.com.html,bm/joe@ximian.com
+1,macisaac@ximian.com,macisaac@ximian.com.html,bm/macisaac@ximian.com
+1,marcel@narings.nl,marcel@narings.nl.html,bm/marcel@narings.nl
+1,marcins@zipworld.com.au,marcins@zipworld.com.au.html,bm/marcins@zipworld.com.au
+1,michaellambert@bellsouth.net,michaellambert@bellsouth.net.html,bm/michaellambert@bellsouth.net
+1,miguel@ximian.com,miguel@ximian.com.html,bm/miguel@ximian.com
+1,mkestner@speakeasy.net,mkestner@speakeasy.net.html,bm/mkestner@speakeasy.net
+1,ndrochak@gol.com,ndrochak@gol.com.html,bm/ndrochak@gol.com
+1,nick@jobdragon.com,nick@jobdragon.com.html,bm/nick@jobdragon.com
+1,rooneg@electricjellyfish.net,rooneg@electricjellyfish.net.html,bm/rooneg@electricjellyfish.net
+1,scott@stonecobra.com,scott@stonecobra.com.html,bm/scott@stonecobra.com
+1,serge@wildwestsoftware.com,serge@wildwestsoftware.com.html,bm/serge@wildwestsoftware.com
+1,toelen@hotmail.com,toelen@hotmail.com.html,bm/toelen@hotmail.com
+1,tomasr@mvps.org,tomasr@mvps.org.html,bm/tomasr@mvps.org
+1,vladimir@pobox.com,vladimir@pobox.com.html,bm/vladimir@pobox.com
diff --git a/status/compare-assembly.cs b/status/compare-assembly.cs
new file mode 100755
index 00000000000..87028889922
--- /dev/null
+++ b/status/compare-assembly.cs
@@ -0,0 +1,164 @@
+/*
+Tool #1:
+
+ compare file1.dll file2.dll annotations.xml
+
+ file1.dll: This is an assembly created by Microsoft.
+
+ file2.dll: This is a Mono assembly (currently we have none
+ that build).
+
+ annotations.xml: contains comments about a class:
+
+ <class name="System.Object">
+ <maintainer>
+ <email>miguel@ximian.com</email>
+ <name>Miguel de Icaza</name>
+ </maintainer>
+ <status test-suite="no" percent="XX">
+ </class>
+
+ That would generate an XML file with all the classes that are
+ implemented in the second library. If there is nothing for a
+ given class, it should generate an emtpy group:
+
+ <class name="System.Object">
+ </class>
+
+Tool #2:
+
+ Using a Perl script that can grok XML, generate HTML pages
+ that we can put on the web site:
+
+ Per assembly status.
+ Per maintainer status.
+ Per Percent status.
+
+*/
+
+using System;
+using System.Collections;
+using System.Reflection;
+using System.Xml;
+
+namespace Mapper
+{
+ public class Mapper
+ {
+ Assembly ms, mono;
+ XmlDocument annotations, output;
+
+ public Mapper(string ms_lib, string mono_lib, string annotation)
+ {
+ Assembly ms = Assembly.LoadFrom (ms_lib);
+ Assembly mono = Assembly.LoadFrom (mono_lib);
+ annotations = new XmlDocument ();
+ annotations.Load (annotation);
+ output = new XmlDocument ();
+ }
+
+ void DumpMember (MemberInfo mi)
+ {
+ string kind;
+ string more="";
+
+ switch (mi.MemberType)
+ {
+ case MemberTypes.Field:
+ kind = "field";
+ break;
+ case MemberTypes.Method:
+ if (((MethodInfo)mi).IsSpecialName) {
+ return;
+ }
+ kind = "method";
+ more = " signature='" + mi.ToString() +"'";
+ break;
+ case MemberTypes.Event:
+ kind = "event";
+ break;
+ case MemberTypes.Property:
+ kind = "property";
+ break;
+ default:
+ kind = "***UNKOWN***";
+ break;
+ }
+ }
+
+ void DumpType (Type t)
+ {
+ string kind, name, attrs = "";
+
+ name = t.Name;
+
+ if (t.IsClass) {
+ kind = "class";
+ } else if (t.IsInterface) {
+ kind = "interface";
+ } else if (t.IsValueType) {
+ kind = "valueType";
+ } else if (t.IsEnum) {
+ kind = "enum";
+ } else return;
+
+ if (t.IsAbstract) {
+ attrs += "abstract='true'";
+ } else if (t.IsSealed) {
+ attrs += "sealed='true'";
+ } else if (t.IsCOMObject) {
+ attrs += "comobject='true'";
+ }
+
+ foreach (Type type in t.GetNestedTypes ()) {
+ DumpType (type);
+ }
+
+ foreach (FieldInfo field in t.GetFields ()) {
+ DumpMember (field);
+ }
+
+ foreach (MethodInfo method in t.GetMethods ()) {
+ DumpMember (method);
+ }
+
+ }
+
+ void LoadTypeList (Type [] types)
+ {
+ foreach (Type t in types) {
+ }
+ }
+
+ public void Map ()
+ {
+ Type [] types;
+ Module [] modules;
+ string name;
+
+ name = ms.GetName ().Name;
+ types = ms.GetExportedTypes ();
+ modules = ms.GetModules ();
+
+ DumpTypeList (types);
+ }
+
+ public static int Main(string[] args)
+ {
+ Mapper m;
+ string basedir = "c:\\WINDOWS\\Microsoft.NET\\Framework\\v1.0.2914\\";
+
+ if (args.Length != 3) {
+ Console.WriteLine ("usage: compare ms_lib.dll mono_lib.dll annotations.xml");
+ }
+ try {
+ m = new Mapper (args[0], args[1], args[2]);
+ m.Map ();
+ } catch (Exception e) {
+ Console.WriteLine("Error: " + e.ToString ());
+ }
+ return 0;
+ }
+ }
+}
+
diff --git a/status/index.src b/status/index.src
new file mode 100755
index 00000000000..60f91f17ac6
--- /dev/null
+++ b/status/index.src
@@ -0,0 +1,17 @@
+You can browse the status of the class library and see who has
+registered to work on what parts of the system. You can view either
+by maintainer or by namespace.
+
+The tables represent things that contributors are working on. We
+register the date when they started working on a particular class, and
+whether a contributor has sent code in (the "implementation" column).
+
+If you want to contribute to Mono, you want to pick a class which is
+not listed here. Alternatively, you can contact the maintainer of a
+class if you want for example to help him improve his code, make it
+faster, better, provide documentation or make comments.
+
+Sometimes contributors will get too busy with other tasks, so they
+will abandon their work on a class. That is why we keep track of the
+time when they "reserve" a class to work on. If the contributor gets
+too busy, we will know if someone else can work on it
diff --git a/status/maintainer.src b/status/maintainer.src
new file mode 100755
index 00000000000..8f514e6c0f3
--- /dev/null
+++ b/status/maintainer.src
@@ -0,0 +1 @@
+These lists are by maintainer.
diff --git a/status/maintainers.xml b/status/maintainers.xml
new file mode 100755
index 00000000000..679225f1229
--- /dev/null
+++ b/status/maintainers.xml
@@ -0,0 +1,35 @@
+<maintainers>
+ <person email="miguel@ximian.com" name="Miguel de Icaza"/>
+ <person email="fejj@ximian.com" name="Jeffrey Stedfast"/>
+ <person email="jbarn@httcb.net" name="John Barnette"/>
+ <person email="iain@ximian.com" name="Iain"/>
+ <person email="bob@thestuff.net" name="Bob Smith"/>
+ <person email="joe@ximian.com" name="Joe Shaw"/>
+ <person email="marcins@zipworld.com.au" name="Marcin Szczepanski"/>
+ <person email="rooneg@electricjellyfish.net" name="Garrett Rooney"/>
+ <person email="angryjohn69@nc.rr.com" name="John R. Hicks"/>
+ <person email="czw@home.se" name="Jens Backman"/>
+ <person email="jason@injektilo.org" name="Jason Diamon"/>
+ <person email="macisaac@ximian.com" name="Sean MacIsaac"/>
+ <person email="vladimir@pobox.com" name="Vladimir Vukicevic"/>
+ <person name="Michael Lambert" email="michaellambert@bellsouth.net"/>
+ <person email="serge@wildwestsoftware.com" name="Sergey Chaban"/>
+ <person email="scott@stonecobra.com" name="Scott Sanders"/>
+ <person name="Garrett Rooney" email="rooneg@electricjellyfish.net"/>
+ <person name="David Menestrina" email="dmenest@yahoo.com"/>
+ <person name="Duco Fijma" email="duco@lorentz.xs4all.nl"/>
+ <person name="Patrik Torstensson" email="Patrik.Torstensson@framfablabs.com"/>
+ <person name="Tomas Restrepo" email="tomasr@mvps.org"/>
+ <person name="Derek Holden" email="dholden@draper.com"/>
+ <person name="Derek Holden" email="dsh2120@draper.com"/>
+ <person name="Gleb Novodran" email="gleb@eurosoft.od.ua"/>
+ <person name="Matthew S. Ford" email="Matthew.S.Ford@rose-hulman.edu"/>
+ <person name="Marcel Narings" email="marcel@narings.nl"/>
+ <person name="Joe Hildebrand" email="hildjj@cursive.net"/>
+ <person name="Nick Drochak" email="ndrochak@gol.com"/>
+ <person name="Mike Kestner" email="mkestner@speakeasy.net"/>
+ <person name="Jim Richardson" email="develop@wtfo-guru.com"/>
+ <person name="Leen Toelen" email="toelen@hotmail.com"/>
+ <person name="Chris Podurgiel" email="cpodurgiel@msn.com"/>
+</maintainers>
+
diff --git a/status/make_web.pl b/status/make_web.pl
new file mode 100755
index 00000000000..39796753ab0
--- /dev/null
+++ b/status/make_web.pl
@@ -0,0 +1,21 @@
+#!/usr/bin/perl -w
+
+open COMMANDS, ">commands";
+
+print COMMANDS "0,Class Libraries,index.html,index.src\n";
+
+print COMMANDS "0,Namespace,namespace.html,namespace.src\n";
+$files_list = `ls bn`;
+@files = split(/\s+/, $files_list);
+foreach $file (@files) {
+ print COMMANDS "1,$file,$file.html,bn/$file\n";
+}
+
+print COMMANDS "0,Maintainer,maintainer.html,maintainer.src\n";
+$files_list = `ls bm`;
+@files = split(/\s+/, $files_list);
+foreach $file (@files) {
+ print COMMANDS "1,$file,$file.html,bm/$file\n";
+}
+
+close COMMANDS
diff --git a/status/makefile b/status/makefile
new file mode 100644
index 00000000000..dd073172a75
--- /dev/null
+++ b/status/makefile
@@ -0,0 +1,35 @@
+NETDIR=c:\\winnt\\microsoft.net\\framework\\v1.0.2914
+MCSCLASSDIR=..\\..\\mcs\\class
+CSC=//c/winnt/microsoft.net/framework/v1.0.2914/csc.exe /nologo
+
+all: ByMaintainer ByNamespace webfiles
+
+exec:
+ $(CSC) /debug+ /debug:full /target:exe /out:compare.exe compare-assembly.cs
+
+xml:
+ ./compare.exe $(NETDIR)\\mscorlib.dll $(MCSCLASSDIR)\\corlib\\corlib.dll > corlib.xml
+
+push:
+ scp *.xml web/*html www@www.ximian.com:/web/cvsmodules/mono/class-status
+
+clean:
+ -rm -f compare.exe compare.pdb corlib.xml ByMaintainer.exe ByNamespace.exe commands *~ .*~
+ -rm -rf bn
+ -rm -rf bm
+ -rm -rf web
+
+ByNamespace: ByNamespace.xsl class.xml
+ $(CSC) ByNamespace.cs
+ -mkdir bn
+ ./ByNamespace
+
+ByMaintainer: ByMaintainer.xsl class.xml
+ $(CSC) ByMaintainer.cs
+ -mkdir bm
+ ./ByMaintainer
+
+webfiles:
+ -mkdir web
+ ./make_web.pl
+ ../doc/web/process.pl commands ../doc/web/template.html.in web
diff --git a/status/mono-stats b/status/mono-stats
new file mode 100755
index 00000000000..64a2947df09
--- /dev/null
+++ b/status/mono-stats
@@ -0,0 +1,289 @@
+#!/usr/bin/perl -w
+
+use strict;
+use XML::Parser;
+#use Data::Dumper;
+
+# command line arguments: shell globs for the files containing the info
+# for the ms assemblyes and mono's
+my $msglob = shift || 'ms*.xml';
+my $monoglob = shift || 'mono*.xml';
+# maintainers file
+my $mfile = 'maintainers.xml';
+my $curfile;
+
+# positions in array refs
+use constant MNAME => 0;
+use constant MASSEMBLY => 1;
+use constant MCLASS => 2;
+
+use constant MAINTAINER => 0;
+use constant PERCENT => 1;
+use constant HASH => 2;
+# we store all the data in some global hash tables
+# $email => [$name, \%assembly, \%class]
+my %maintainer;
+
+# $name => [$maintainer, $percent, \%classes];
+my %assembly;
+
+# $name => [$maintainer, $percent, \%methods]
+my %class;
+
+# my parsing state machine
+my @status;
+# current maintainer, class and assembly pointers
+my ($curm, $curc, $cura);
+my $mono = 0;
+my $namespace = '';
+my %status_action = (
+ MAINTAINERS => sub {
+ my ($elem, %attrs) = @_;
+ malformed ($mfile, $elem, 'maintainers', \@status);
+ push @status, 'DUDE';
+ },
+ DUDE => sub {
+ my ($elem, %attrs) = @_;
+ malformed ($mfile, $elem, 'person', \@status);
+ foreach(qw(email name)) {die "$_ not included in person\n" unless defined $attrs{$_}}
+ $curm = $maintainer{$attrs{email}} = [$attrs{name}, {}, {}];
+ push @status, 'DUDE_CONTENT';
+ },
+ DUDE_CONTENT => sub {
+ my ($elem, %attrs) = @_;
+ malformed ($mfile, $elem, 'class|assembly', \@status);
+ if ($elem eq 'class') {
+ $curm->[MCLASS]->{$attrs{name}} = '';
+ } elsif ($elem eq 'assembly') {
+ $curm->[MASSEMBLY]->{$attrs{name}} = '';
+ }
+ push @status, 'DUDE_CONTENT';
+ },
+ ASSEMBLY => sub {
+ my ($elem, %attrs) = @_;
+ malformed ($curfile, $elem, 'assembly', \@status);
+ $namespace = '';
+ $cura = $assembly{$attrs{name}} = ['', 0, {}];
+ push @status, 'NAMESPACE';
+ },
+ NAMESPACE => sub {
+ my ($elem, %attrs) = @_;
+ malformed ($curfile, $elem, 'namespace', \@status);
+ $namespace = $attrs{name};
+ push @status, 'CLASS';
+ },
+ CLASS => sub {
+ my ($elem, %attrs) = @_;
+ malformed ($curfile, $elem, 'class|valueType|interface', \@status);
+ if ($elem eq 'class') {
+ my $name = $namespace ? $namespace.".".$attrs{name} : $attrs{name};
+ if ($mono) {
+ warn "mono implements non exisistent class $name\n"
+ if (!exists $class{$name});
+ $curc = $class{$name};
+ } else {
+ $curc = $class{$name} = ['', 0, {}];
+ }
+ $cura->[HASH]->{$name} = $mono;
+ push @status, 'METHOD';
+ } else {
+ push @status, 'METHOD';
+ }
+ },
+ METHOD => sub {
+ my ($elem, %attrs) = @_;
+ malformed ($curfile, $elem, 'method|field|valueType', \@status);
+ if ($elem eq 'method') {
+ my $name = $attrs{signature};
+ if ($mono) {
+ warn "mono implements non exisistent method $name\n"
+ if (!exists $curc->[HASH]->{$name});
+ }
+ $curc->[HASH]->{$name} = $mono;
+ push @status, 'METHOD';
+ } else {
+ push @status, 'METHOD';
+ }
+ },
+);
+
+
+my $parser = new XML::Parser (Handlers => {Start => \&handle_tag, End => \&end_tag});
+
+# parse the maintainers info
+if ($mfile) {
+ @status = 'MAINTAINERS';
+ $parser->parsefile($mfile);
+ #print Dumper(\%maintainer);
+}
+
+foreach (glob($msglob)) {
+ $curfile = $_;
+ @status = 'ASSEMBLY';
+ $mono = 0;
+ $parser->parsefile($_);
+}
+
+foreach (glob($monoglob)) {
+ $curfile = $_;
+ @status = 'ASSEMBLY';
+ $mono = 1;
+ $parser->parsefile($_);
+}
+
+create_stats();
+create_html();
+#print Dumper(\%assembly);
+#print Dumper(\%class);
+exit(0);
+
+sub malformed {
+ my ($file, $elem, $match, $data) = @_;
+ unless ($elem =~ /^$match$/) {
+ $data = Dumper($data) if defined $data;
+ die "file $file malformed ($elem instead of $match) $data\n"
+ }
+}
+
+sub handle_tag {
+ my $parser = shift @_;
+ my $status = $status[-1];
+ die "status $status unknown" unless exists $status_action{$status};
+ $status_action{$status}->(@_);
+}
+
+sub end_tag {
+ my $last = pop @status;
+ # print STDERR "done with $last\n";
+}
+
+sub assign_maintainer {
+ my ($m, $from, $to, $type) = @_;
+ foreach (keys %$from) {
+ if (!exists $to->{$_}) {
+ warn "$m maintains unknown $type $_\n";
+ # fixup to avoid warnings
+ $to->{$_}->[MAINTAINER] = $m;
+ $to->{$_}->[PERCENT] = 0;
+ $to->{$_}->[HASH] = {};
+ } else {
+ warn "$to->{$_}->[MAINTAINER] already maintains $_ (now $m)\n" if $to->{$_}->[MAINTAINER];
+ $to->{$_}->[MAINTAINER] = $m;
+ }
+ }
+}
+
+sub completeness {
+ my $hash = shift @_;
+ my $total = keys %$hash;
+ my $done = 0;
+ map {$done += $_} values %$hash;
+ return 0 unless $total;
+ return int($done*100/$total);
+}
+
+sub create_stats {
+ # set maintainer field in assembly and class hashes
+ foreach my $m (sort keys %maintainer) {
+ assign_maintainer ($m, $maintainer{$m}->[MASSEMBLY], \%assembly, 'assembly');
+ assign_maintainer ($m, $maintainer{$m}->[MCLASS], \%class, 'class');
+ }
+ # assign completeness percent
+ foreach my $ass (values %assembly) {
+ $ass->[PERCENT] = completeness ($ass->[HASH]);
+ }
+ foreach my $class (values %class) {
+ $class->[PERCENT] = completeness ($class->[HASH]);
+ }
+}
+
+sub html_header {
+ my ($title) = @_;
+return <<"EOF";
+<html><head><title>$title</title></head><body bgcolor="#ffffff">
+<h1 ALIGN=center>$title</H1>
+EOF
+
+}
+
+sub unimplemented ($) {
+ my ($c) = @_;
+ my $id = $c;
+ $id =~ tr/./-/;
+ return "<A HREF='per-unimplemented.html#$id'>$c</A>";
+}
+
+sub create_html {
+
+ open(F, ">per-assembly.html") || die "Cannot open file: $!";
+ print F html_header("Mono - per-assembly stats");
+ print F "<TABLE BORDER=1><TR><TH>Assembly<TH>Maintainer<TH>Completion\n";
+ foreach my $ass (sort keys %assembly) {
+ print F "\t<TR><TD>", join('<TD>', $ass, $assembly{$ass}->[MAINTAINER], $assembly{$ass}->[PERCENT]), "\n";
+ }
+ print F "</TABLE>\n";
+ print F "</body></html>\n";
+ close(F);
+
+ # per maintainer info
+ open(F, ">per-maintainer.html") || die "Cannot open file: $!";
+ print F html_header("Mono - per-maintainer stats");
+ print F "<TABLE BORDER=1><TR><TH>Maintainer<TH>Class<TH>Completion\n";
+ foreach my $m (sort keys %maintainer) {
+ my @classes = sort keys %{$maintainer{$m}->[MCLASS]};
+ my $count = @classes;
+ foreach my $c (@classes) {
+ my $start = $count?"\t<TR><TD ROWSPAN=$count>$m<TD>":"\t<TR><TD>";
+ $count = 0;
+ print F $start, join('<TD>', $c, $class{$c}->[PERCENT]), "\n";
+ }
+ }
+ my @unmantained = sort grep {!$class{$_}->[MAINTAINER]} keys %class;
+ my $count = @unmantained;
+ foreach my $c (@unmantained) {
+ my $start = $count?"\t<TR><TD ROWSPAN=$count>Unmantained<TD>":"\t<TR><TD>";
+ $count = 0;
+ print F $start, join('<TD>', $c, $class{$c}->[PERCENT]), "\n";
+ }
+ print F "</TABLE>\n";
+ print F "</body></html>\n";
+ close(F);
+
+ # per-completion info
+ open(F, ">per-completion.html") || die "Cannot open file: $!";
+ print F html_header("Mono - per-completion stats");
+ print F "<TABLE BORDER=1><TR><TH>Completion<TH>Class<TH>Maintainer\n";
+ foreach my $c (sort {$class{$b}->[PERCENT] <=> $class{$a}->[PERCENT]} keys %class) {
+ print F "\t<TR><TD>", join('<TD>', $class{$c}->[PERCENT], unimplemented($c), $class{$c}->[MAINTAINER]), "\n";
+ }
+ print F "</TABLE>\n";
+ print F "</body></html>\n";
+ close(F);
+
+ # unimplemented methods
+ # FIXME: this can create a very big file, split on assembly name
+ # and fix also the unimplemented() sub
+ open(F, ">per-unimplemented.html") || die "Cannot open file: $!";
+ print F html_header("Mono - unimplemented methods stats");
+ print F "<TABLE BORDER=1><TR><TH>Class<TH>Method\n";
+ foreach my $c (sort grep {$class{$_}->[PERCENT] != 100} keys %class) {
+ my @methods = sort grep {!$class{$c}->[HASH]->{$_}} keys %{$class{$c}->[HASH]};
+ my $count = @methods;
+ my $aname = '';
+ if ($count) {
+ my $id = $c;
+ $id =~ tr/./-/;
+ $aname = "<A NAME='$id'></A>";
+ }
+ foreach my $m (@methods) {
+ my $start = $count?"\t<TR><TD ROWSPAN=$count>$aname$c<TD>":"\t<TR><TD>";
+ $count = 0;
+ print F $start, join('<TD>', $m), "\n";
+ }
+ }
+ print F "</TABLE>\n";
+ print F "</body></html>\n";
+ close(F);
+
+}
+
diff --git a/status/namespace.src b/status/namespace.src
new file mode 100755
index 00000000000..0d20d369b35
--- /dev/null
+++ b/status/namespace.src
@@ -0,0 +1 @@
+These lists are by Namespace.
diff --git a/web/.cvsignore b/web/.cvsignore
new file mode 100644
index 00000000000..79a25824094
--- /dev/null
+++ b/web/.cvsignore
@@ -0,0 +1,3 @@
+Makefile.in
+Makefile
+all-docs
diff --git a/web/Makefile.am b/web/Makefile.am
new file mode 100644
index 00000000000..dd2e2d85e2c
--- /dev/null
+++ b/web/Makefile.am
@@ -0,0 +1,19 @@
+WEB_FILES= \
+ c-sharp class-library contact contributing documentation download \
+ faq gcc-frontend ideas index passport rationale resources \
+ roadmap runtime status team testing thanks tools
+
+OTHERS= pending resources-pending todo
+
+EXTRA_DIST = $(WEB_FILES) README $(OTHERS)
+
+all-docs: $(WEB_FILES)
+ cat rationale roadmap c-sharp tools class-library \
+ runtime documentation download faq contributing \
+ resources status > all-docs
+
+webit:
+ (cd web; make && make push)
+
+push-notes:
+ scp release-notes/mono* www@www:/web/cvsmodules/mono/archive
diff --git a/web/README b/web/README
new file mode 100644
index 00000000000..333d133943f
--- /dev/null
+++ b/web/README
@@ -0,0 +1,17 @@
+To edit the website appearance:
+
+cd doc/web
+edit template.html.in
+make
+
+To edit website content:
+
+cd doc (this directory)
+edit files carefully
+cd web
+make
+
+To publish changes:
+
+cd web
+make push
diff --git a/web/c-sharp b/web/c-sharp
new file mode 100644
index 00000000000..0c5be542f02
--- /dev/null
+++ b/web/c-sharp
@@ -0,0 +1,188 @@
+* MCS: The Ximian C# compiler
+
+ MCS began as an experiment to learn the features of C# by
+ writing a large C# program. MCS is currently able to parse C#
+ programs and create an internal tree representation of the
+ program. MCS can parse itself.
+
+ MCS now does type checking at the class, interface and struct
+ levels and can resolve the class hierarchy and as of last week
+ can generate interface code.
+
+ Work is progressing quickly on various fronts in the C#
+ compiler. Recently I started using the System.Reflection API
+ to load system type definitions and avoid self-population of
+ types in the compiler and dropped my internal Type
+ representation in favor of using the CLI's System.Type.
+
+** Phases of the compiler
+
+ The compiler has a number of phases:
+
+ <ul>
+ * Lexical analyzer: hand-coded lexical analyzer that
+ provides tokens to the parser.
+
+ * The Parser: the parser is implemented using Jay (A
+ Berkeley Yacc port to Java, that I ported to C#).
+ The parser does minimal work and syntax checking,
+ and only constructs a parsed tree.
+
+ Each language element gets its own class. The code
+ convention is to use an uppercase name for the
+ language element. So a C# class and its associated
+ information is kept in a "Class" class, a "struct"
+ in a "Struct" class and so on. Statements derive
+ from the "Statement" class, and Expressions from the
+ Expr class.
+
+ * Parent class resolution: before the actual code
+ generation, we need to resolve the parents and
+ interfaces for interface, classe and struct
+ definitions.
+
+ * Semantic analysis: since C# can not resolve in a
+ top-down pass what identifiers actually mean, we
+ have to postpone this decision until the above steps
+ are finished.
+
+ * Code generation: The compiler recently started generating IL
+ executables that contain interfaces. Work is
+ progressing in other areas.
+
+ The code generation is done through the System.Reflection.Emit API.
+ </ul>
+
+<a name="tasks">
+** Current pending tasks
+
+ Simple tasks:
+
+ <ul>
+ * Array declarations are currently being ignored,
+
+ * PInvoke declarations are not supported.
+
+ * Pre-processing is not supported.
+
+ * Attribute declarations and passing currently ignored.
+
+ * Compiler does not pass around line/col information from tokenizer for error reporting.
+
+ * Jay does not work correctly with `error'
+ productions, making parser errors hard to point. It
+ would be best to port the Bison-To-Java compiler to
+ become Bison-to-C# compiler (bjepson@oreilly.com
+ might have more information)
+ </ul>
+
+ Interesting and Fun hacks to the compiler:
+
+ <ul>
+ * Finishing the JB port from Java to C#. If you are
+ interested in working on this, please contact Brian
+ Jepson (bjepson at oreilly d-o-t com).
+
+ More on JB at: <a href="http://www.cs.colorado.edu/~dennis/software/jb.html">
+ http://www.cs.colorado.edu/~dennis/software/jb.html</a>
+
+ JB will allow us to move from the Berkeley Yacc
+ based Jay to a Bison-based compiler (better error
+ reporting and recovery).
+
+ * Semantic Analysis: Return path coverage and
+ initialization before use coverage are two great
+ features of C# that help reduce the number of bugs
+ in applications. It is one interesting hack.
+
+ * Enum resolutions: it is another fun hack, as enums can be defined
+ in terms of themselves (<tt>enum X { a = b + 1, b = 5 }</tt>).
+
+ </ul>
+
+** Questions and Answers
+
+Q: Why not write a C# front-end for GCC?
+
+A: I wanted to learn about C#, and this was an exercise in this
+ task. The resulting compiler is highly object-oriented, which has
+ lead to a very nice, easy to follow and simple implementation of
+ the compiler.
+
+ I found that the design of this compiler is very similar to
+ Guavac's implementation.
+
+ Targeting the CIL/MSIL byte codes would require to re-architecting
+ GCC, as GCC is mostly designed to be used for register machines.
+
+ The GCC Java engine that generates Java byte codes cheats: it does
+ not use the GCC backend; it has a special backend just for Java, so
+ you can not really generate Java bytecodes from the other languages
+ supported by GCC.
+
+Q: If your C# compiler is written in C#, how do you plan on getting
+ this working on a non-Microsoft environment.
+
+ We will do this through an implementation of the CLI Virtual
+ Execution System for Unix (our JIT engine).
+
+Q: Do you use Bison?
+
+A: No, currently I am using Jay which is a port of Berkeley Yacc to
+ Java that I later ported to C#. This means that error recovery is
+ not as nice as I would like to, and for some reason error
+ productions are not being caught.
+
+ In the future I want to port one of the Bison/Java ports to C# for
+ the parser.
+
+Q: Should someone work on a GCC front-end to C#?
+
+A: I would love if someone does, and we would love to help anyone that
+ takes on that task, but we do not have the time or expertise to
+ build a C# compiler with the GCC engine. I find it a lot more fun
+ personally to work on C# on a C# compiler, which has an intrinsic
+ beauty.
+
+ We can provide help and assistance to anyone who would like to work
+ on this task.
+
+Q: Should someone make a GCC backend that will generate CIL images?
+
+A: I would love to see a backend to GCC that generates CIL images. It
+ would provide a ton of free compilers that would generate CIL
+ code. This is something that people would want to look into
+ anyways for Windows interoperation in the future.
+
+ Again, we would love to provide help and assistance to anyone
+ interested in working in such a project.
+
+Q: What about making a front-end to GCC that takes CIL images and
+ generates native code?
+
+A: I would love to see this, specially since GCC supports this same
+ feature for Java Byte Codes. You could use the metadata library
+ from Mono to read the byte codes (ie, this would be your
+ "front-end") and generate the trees that get passed to the
+ optimizer.
+
+ Ideally our implementation of the CLI will be available as a shared
+ library that could be linked with your application as its runtime
+ support.
+
+ Again, we would love to provide help and assistance to anyone
+ interested in working in such a project.
+
+Q: But would this work around the GPL in the GCC compiler and allow
+ people to work on non-free front-ends?
+
+A: People can already do this by targeting the JVM byte codes (there
+ are about 130 compilers for various languages that target the JVM).
+
+Q: Why are you writing a JIT engine instead of a front-end to GCC?
+
+A: The JIT engine and runtime engine will be able to execute CIL
+ executables generated on Windows.
+
+You might also want to look at the <a href="faq.html#gcc">GCC</a>
+section on the main FAQ
diff --git a/web/ccvs b/web/ccvs
new file mode 100644
index 00000000000..b67e8dc0c5b
--- /dev/null
+++ b/web/ccvs
@@ -0,0 +1,112 @@
+* CVS Access
+
+ If you are an active Mono developer, you can get a CVS account
+ that hosts the Mono source code.
+
+ Send an e-mail to miguel with your public SSH key for this
+ purpose. Please specify if the key was generated with SSH1 or SSH2.
+
+ If you are using SSH2, please generate your key using:
+
+<pre>
+ ssh-keygen -t rsa
+</pre>
+
+ And mail me the id_rsa.pub file.
+
+ If you are using SSH1, run:
+<pre>
+ ssh-keygen
+</pre>
+
+ And mail me your identity.pub file.
+
+ You will need CVS and SSH. Windows users can get both by
+ installing Cygwin (<a
+ href="http://www.cygwin.com">http://www.cygwin.com</a>)
+
+ Unix users will probably have those tools installed already.
+
+** Checking out the sources
+
+ To check out the sources for the first time from the
+ repository, use this command:
+
+<pre>
+ export CVS_RSH=ssh
+ export CVSROOT=username@mono-cvs.ximian.com:/cvs/public
+ cvs -z3 co mcs mono
+</pre>
+
+** Updating your sources
+
+ Every day people will be making changes, to get your latest
+ updated sources, use:
+
+<pre>
+ cvs -z3 update -Pd mcs mono
+</pre>
+
+ Note: The '-z3' enables compression for the whole cvs action.
+ The '-Pd' makes the update operation (P)rune directories that
+ have been deleted and get new (d)irectories added to the
+ repository.
+
+** Making patches
+
+ Usually you will want to make a patch to contribute, and let
+ other people review it before commiting it. To obtain such a
+ "patch", you type:
+
+<pre>
+ cd directory-you-want-to-diff
+ cvs -z3 diff -u > file.diff
+ mail mono-list@ximian.com < file.diff
+</pre>
+
+** Commiting your work
+
+ Once you get approval to commit to the CVS, or if you are
+ commiting code that you are the maintainer of, you will want
+ to commit your code to CVS.
+
+ To do this, you have to "add" any new files that you created:
+
+<pre>
+ cvs add new-file.cs
+</pre>
+
+ And then commit your changes to the repository:
+
+<pre>
+ cvs commit file-1.cs file-2.cs
+</pre>
+
+** The Mailing List
+
+ To keep track of the various development and changes to the
+ CVS tree, you can subscribe to the mono-cvs-list@ximian.com.
+ To subscribe, send an email message to
+ mono-cvs-list-request@ximian.com and in the body of the
+ message put `subscribe'.
+
+ This will send you an email message every time a change is
+ made to the CVS repository, together with the information that
+ the author of the changes submitted.
+
+** Recommendations
+
+ Please do not commit code that would break the compile to the
+ CVS, because that normally wastes everybody's time.
+
+ Make sure that you add all the files before you do a commit.
+
+ Use ChangeLog entries so we can keep textual descriptions of
+ your work, and use the contents of your ChangeLog file as the
+ CVS commit message (ie, paste the contents of this into the
+ editor buffer).
+
+ If you are making changes to someone else's code, please make
+ sure you get in touch with the maintainer of that code before
+ applying patches. You want to avoid commiting conflicting
+ work to someone else's code.
diff --git a/web/class-library b/web/class-library
new file mode 100644
index 00000000000..2819ff8ba43
--- /dev/null
+++ b/web/class-library
@@ -0,0 +1,183 @@
+* The Class Library
+
+ The Class Library should be compatible with Microsoft's .NET
+ implementation.
+
+ Please see the <a href="class-status.html">Class Status</a>
+ page for a status of who is working on which classes.
+
+ We will write as much code as possible in C#. We may need to
+ interface with code written in C to gain access to the
+ functionality of libraries like libart, Gtk+, and libc.
+
+** Contributing
+
+ We welcome contributions to the the Class Library. To get
+ started, check the status page for information about which
+ APIs are being worked on, and how to get in touch with
+ individual maintainers.
+
+ If you want to work on a class, first check the <a
+ href="download.html">Classes Distribution</a> to see if it is
+ not implemented yet, if not, check the <a
+ href="class-status.html">Class Status</a> to see if someone is
+ already working on it, and maybe contact them.
+
+ If nobody is working on it, mail <a
+ href="mailto:mono-list@ximian.com">mono-list@ximian.com</a>
+ with the class you want to implement and CC <a
+ href="mailto:miguel@ximian.com">miguel@ximian.com</a>.
+
+ You can also track live the activities of the Mono CVS module
+ by subscribing to the <a
+ href="http://mail.ximian.com/mailman/listinfo/mono-cvs-list">mono-cvs-list</a>
+
+
+
+** Layout
+
+ The Class Library resides in the `mcs' module in the directoy
+ `class'.
+
+ Each directory in the directory represents the assembly where
+ the code belongs to, and inside each directory we divide the
+ code based on the namespace they implement.
+
+ There are two cases when we should consider portability: when
+ we are dealing with a couple of classes only that differ from
+ system to system (Consider System.Net and System.IO for Win32
+ and Unix). In those cases we will just place the files for
+ example on <t>corlib/System/System.IO/Unix-Console.cs</t> and
+ <t>corlib/System/System.IO/Win32-Console.cs</t>.
+
+ For classes that might differ more (for example, the
+ implementation of Windows.Forms), we might have different
+ directories altogether: <t>System.Windows.Forms/Win32</t>,
+ <t>System.Windows.Forms/Gtk+</t> and
+ <t>System.Windows.Forms/Cocoa</t>.
+
+** Using existing components from GNOME.
+
+ Our current plan is to implement the GUI tools on top of
+ Gtk+. The only obstacle here is that applications from Windows
+ might expect to be able to pull the HWND property from the
+ widgets and use PInvoke to call Windows functions.
+
+** Class Library and Win32 dependencies.
+
+ There are a few spots where the Win32 foundation is exposed to
+ the class library (for example, the HDC and HWND properties in
+ the GDI+). Casual inspection suggests that these can be
+ safely mapped to Gdk's GC and GdkWindow pointers without
+ breaking anything.
+
+ The only drawback is that support for PInvoke of Win32 code
+ won't be available. An alternate solution would be to use
+ portions of Wine, or even to use Wine as our toolkit.
+
+*** Initial GDI+ and WinForms implementation
+
+ The initial implementation will use Gtk+ as the underlying
+ toolkit. Since GTK+ has already been ported to many windowing
+ systems other than X (including frame buffer, Win32, and BeOS)
+ its use should cover most applications for most users.
+
+*** Database access
+
+ We will implement ADO.NET functionality by reusing <a
+ href="http://www.gnome-db.org">GNOME-DB</a>. This is an ideal
+ choice, since GNOME-DB was implemented precisely to provide an
+ ADO-like system for GNOME.
+
+*** Component Integration
+
+ We will provide a new namespace to use GNOME specific features
+ as well as a namespace to host Bonobo interfaces and classes
+ in Mono.
+
+** Licensing
+
+ The class library will be licensed under the terms of the GNU
+ LGPL. Some people have pointed out that the plain LGPL is
+ troublesome for embedded use of the Mono class libraries. So
+ we are considering to use the GPL with a special exception
+ (like the <a
+ href="http://www.gnu.org/software/classpath/classpath.html">GNU
+ Classpath</a> project did.
+
+ The exception to the GPL would be:
+
+ <i>The library is distributed under the terms of the GNU General
+ Public License with the following exception:
+
+ If you link this library against your own program, then you do not
+ need to release the source code for that program. However, any
+ changes that you make to the library itself, or to any native
+ methods upon which the library relies, must be re-distributed in
+ accordance with the terms of the GPL.</i>
+
+ If you are going to contribute, please keep in mind that we
+ might require you to agree that Ximian might adjust the
+ license to enable the use of the class libraries on embedded
+ systems or to develop proprietary applications using Mono.
+
+ We suggest that you assign the copyright of your work to the
+ GNOME Foundation or the Free Software Foundation to simplify
+ defending the code in case it is used inappropiately.
+
+** Class Library testing
+
+ We need to write regression tests that will verify
+ the correctness of the class library, compiler, and JIT
+ engine.
+
+ Please write your regression tests using <a
+ href="http://nunit.sourceforge.net">NUnit</a>
+
+** Coding conventions
+
+ Please follow the conventions on the ECMA specification (On
+ the Annex Partition) for your coding your libraries.
+
+ Use 8 space tabs for writing your code (hopefully we can keep
+ this consistent). If you are modifying someone else's code, try
+ to keep the coding style similar.
+
+ For a rationale on 8 space tabs, read Linus Torvald's Coding
+ Style guidelines in the Linux kernel source for a rationale.
+
+*** Missing implementation bits
+
+ If you implement a class and you are missing implementation bits,
+ please put in the code the word "TODO" and a description of what
+ is missing to be implemented.
+
+*** Tagging buggy code
+
+ If there is a bug in your implementation tag the problem by using
+ the word "FIXME" in the code, together with a description of the
+ problem.
+
+ Do not use XXX or obscure descriptions, because otherwise people
+ will not be able to understand what you mean.
+
+*** Tagging Lame specs
+
+ Sometimes the specification will be lame (consider Version.ToString (fieldCount)
+ where there is no way of knowing how many fields are available, making the API
+ not only stupid, but leading to unreliable code).
+
+ In those cases, use the keyword "LAMESPEC".
+
+** FAQ
+
+Frequently asked questions about the class library:
+
+Q: I am writing a new class that overrides one of the system classes,
+ and I am getting a 1595 warning from the compiler. Should we use a
+ different namespace?
+
+A: There is a quick solution to the problem, you can pass the command
+ line argument /nowarn:1595 and this will effectively let you use
+ your implementation of the code, while overriding the ones from the
+ system assemblies. \ No newline at end of file
diff --git a/web/class-status b/web/class-status
new file mode 100644
index 00000000000..db8d360dbff
--- /dev/null
+++ b/web/class-status
@@ -0,0 +1,16 @@
+* Status of the various pieces of the class library
+
+ You can browse the status of the class library and see who has
+ registered to work on what parts of the system. These list
+ work-in-progress components currently.
+
+ Browse the current <a href="class-status/index.html">status</a>.
+
+ You can also download the XML <a
+ href="class-status/maintainers.xml">maintainers</a> file that
+ contains the actual maintainers list.
+
+ You can also download the master <a
+ href="class-status/class.xml">Class Status XML</a> file.
+
+
diff --git a/web/contact b/web/contact
new file mode 100644
index 00000000000..a268f704731
--- /dev/null
+++ b/web/contact
@@ -0,0 +1,16 @@
+* Contacting the Mono team.
+
+ You can contact the Mono Team by sending e-mail to `<a
+ href="mailto:mono-hackers@ximian.com">mono-hackers@ximian.com</a>'.
+
+ You can contact the general forum of discussion by sending
+ e-mail to <a href="mailto:mono-list@ximian.com">mono-list@ximian.com</a>
+
+ You can contact me (Miguel de Icaza) by sending e-mail to <a
+ href="mailto:miguel@ximian.com">miguel@ximian.com</a>. My web
+ page is <a
+ href="http://primates.ximian.com/~miguel">http://primates.ximian.com/~miguel"</a>
+
+ You can also <a
+ href="http://www.ximian.com/about/contact.php3">reach Ximian.</a>
+
diff --git a/web/contributing b/web/contributing
new file mode 100644
index 00000000000..d0e5925d8fa
--- /dev/null
+++ b/web/contributing
@@ -0,0 +1,105 @@
+* Contributing to the Mono project
+
+ There are many ways in which you can help in the Mono project:
+
+ <ul>
+ * <b>Programmers:</b> You can work on a free
+ implementation of the <a
+ href="class-library.html">class libraries</a>, the
+ <a href="runtime.html">runtime engine</a>, <a
+ href="tools.html">the tools</a>, the <a
+ href="testing.html">testing framework</a>
+
+ * <b>Writers:</b> You can help us bywriting <a
+ href="documentation.html">documentation</a>.
+ </ul>
+
+ Those are just broad things that need to be worked on, but
+ something that would help tremendously would be to help with
+ small duties in the project that need to be addressed.
+
+** To start contributing
+
+ To start developing classes or to contribute to the compiler,
+ you only need Windows and the .NET Beta 2 SDK. Please notice
+ that you do not need Visual Studio (although you can use it if
+ you want).
+
+ You can get it <a href="http://msdn.microsoft.com/downloads/default.asp?url=/downloads/sample.asp?url=/msdn-files/027/000/976/msdncompositedoc.xml&frame=true">here</a>
+
+ Alternatively you can use the <a
+ href="#compile-service">compilation service</a> that was setup by
+ Derek.
+
+** Bug reporting
+
+ If you find bugs in Mono, please make sure you enter a bug
+ report so we can keep track of problems in Mono.
+
+ To enter bug reports go to <a href="http://bugzilla.ximian.com">
+ http://bugzilla.ximian.com</a> and enter bug reports against
+ your favorite component (Mono, Runtime, C# compiler).
+
+** Small tasks
+
+ A few smaller tasks are here, dropped in no particular order:
+ <ul>
+ * <b>MCS compilation process:</b> Currently MCS does
+ not build with a single `make' command. This should
+ be fixed (this being part of the `Joel Test' that
+ software has to pass).
+
+ * <b>Mono/doc and web site:</b> They need to be
+ packaged up in the official `distribution'
+ </ul>
+
+<a name="compile-service">
+* C# Compilation Service
+
+ If you are working on a class for the Mono project, but do not
+ have a C# compiler available or a Windows machine to run the
+ .NET SDK, you can use the compilation service that Derek
+ Holden setup in the following URL: <a
+ href="http://toilet.2y.net:8080/">http://toilet.2y.net:8080/</a>
+
+ The service will let you compile a source file and get back a
+ list of errors in the class file. You will not be able to run
+ the code, but at least you can get some code written that will
+ help us further down the line.
+
+ You can contact (and thank) Derek for this service by sending
+ him nice email at <a
+ href="mailto:derek@Draper.Com">derek@draper.com</a>
+
+* Books on C# and DotNet.
+
+ <ul>
+ * Dotnet Books (<a href="http://www.dotnetbooks.com">http://www.dotnetbooks.com</a>)
+
+ * Dotnet Resources (<a href="http://www.dotnetexperts.com/resources/">
+ http://www.dotnetexperts.com/resources</a>)
+
+ * O'Really C# Essentials (<a href="http://www.oreilly.com/catalog/csharpess/">
+ http://www.oreally.com/catalog/csharpess</a>)
+
+ * O'Really .NET Essentials (<a href="http://www.oreilly.com/catalog/dotnetfrmess/">
+ http://www.oreally.com/catalog/dotnetfrmess</a>)
+
+* Special note
+
+ If you have looked at Microsoft's implementation of .NET or
+ their shared source code, you may not be able to contribute
+ to Mono. Details will follow when we know more about this.
+
+ In general be careful when you are implementing free software
+ and you have access to proprietary code. We need to make sure
+ that we are not using someone else's copyrighted code
+ accidentally.
+
+ Please do not use the <b>ildasm</b> program to disassemble
+ proprietary code when you are planning to reimplement a class
+ for Mono. If you have done this, we might not be able to use
+ your code.
+
+ Please stick to published documentation for implementing any
+ classes.
diff --git a/web/devel-faq b/web/devel-faq
new file mode 100644
index 00000000000..9ca89285219
--- /dev/null
+++ b/web/devel-faq
@@ -0,0 +1,190 @@
+* Developer FAQ
+
+** New classes
+
+Q: Should we write classes which are not part of the .NET or ECMA specs?
+
+A: Yes. The ECMA and .NET specifications are far from complete, and
+ to produce a complete platform we will need a number of other
+ classes and components.
+
+ Any new classes that are not part of .NET or ECMA should be
+ designed to be reusable on anyone's CLI implementation. So that
+ Windows developers can also use any new classes that we come up
+ with.
+
+ We have a few existing <a href="ideas.html">Ideas on missing
+ classes</a>
+
+** Language Compatibility
+
+Q: What is the magic that allow multiple languages to co-exist?
+
+A: From Fergus Henderson:
+
+<i><blockquote>
+There are different levels of interoperability.
+The ECMA spec defines different categories of
+CLS (Common Language Specification) conformance.
+There are also some useful categories that don't
+correspond to any of the levels defined in the ECMA spec.
+In increasing degree of difficulty, your language implementation
+can
+
+ <ul>
+ * (a) just generate IL
+
+ * (b) be a CLS "consumer", which means that it can read in
+ meta-data describing component interfaces,
+ and that it provides a way to declare variables of
+ CLS-complaint types and to call CLS-complaint methods.
+
+ * (c) be a CLS "extender", which means that it can in addition
+ derive from CLS-compliant classes
+ and implement CLS-compliant interfaces
+
+ * (d) be able to produce components with *any* CLS-compliant
+ component interface.
+ </ul>
+
+Supporting some of these may require extending your language. However,
+you can get quite a lot of interoperability by just putting appropriate
+functionality in your compiler, without extending your language.
+
+For some things, e.g. ASP.NET, your language implementation also needs to be
+able to
+
+ <ul>
+ * (e) consume CodeDom trees. CodeDom trees are an abstract
+ representation of programs in a form similar to a C# parse
+ tree, with embedded code snippets (unparsed strings).
+ Given a CodeDom tree, with the snippets in your language,
+ your language implementation needs to generate a (i) .NET
+ assembly and possibly also (ii) a source file in your language.
+
+ * (f) produce CodeDom trees. For some applications,
+ your language implementation also needs to be able to
+ round-trip from CodeDom -> your language -> CodeDom.
+ </ul>
+
+and for some things it needs to
+
+ <ul>
+ * (g) generate *verifiable* IL
+ </ul>
+
+So when you hear all the hype about how language XYZ is a
+".NET language", make sure you ask which of these different
+things are supported.
+
+[For the record, Mercury currently supports (a). We're working on
+(b) and (g), and on parts of (c) and (e). We're never going to do (f), I very
+strongly doubt we'll ever do (d), and for (c) we might only ever support
+implementing interfaces, not deriving from classes.]
+
+</blockquote></i>
+
+** PInvoke
+
+Q: What are the two major initiatives to implement PInvoke?
+
+A: Fergus Henderson answers:
+
+<i><blockquote>
+Many of the .NET APIs will need to be implemented using code that calls C/Unix
+APIs, such as stat(). The standard way of interfacing with native code from
+.NET code is to use "PInvoke". However, there is a difficulty: many of
+these APIs are defined in terms of types such as C's `long' or `size_t'
+or the Posix `struct stat' whose representation varies depending on the
+platform (architecture/OS/C compiler). There's no *portable* way of
+accessing those from .NET managed code.
+
+So, there are a couple of different approaches.
+One possibility is to access such routines by writing a wrapper, e.g. in C,
+that provides the same functionality without using types with a system-dependent
+representation. The wrapper can then be directly accessed from portable
+.NET code. The .NET code remains both source- and binary-portable;
+the wrapper code is source-portable, but needs to be compiled
+seperately for each target platform. The drawback of this approach is
+that you have to write a lot of cumbersome wrapper code.
+
+Another possibility is to extend the .NET VM with support for an
+additional custom attribute, e.g. "[PosixType]". The VM would then
+represent types tagged with this attribute in the same way that the
+underlying system represents those types. With this approach, no
+wrapper code would be needed. A drawback of this approach is that it
+pushes quite a bit of complexity into the VM; the VM would have to know
+the native representation of all types annotated with this attribute.
+Another drawback is that code using this extension might not work on
+different VMs.
+
+There have also been some other suggestions, but those are the two that
+I think are the best.
+</blockquote></i>
+
+Q: What is the problem implementing PInvoke?
+
+A: Again, from Fergus Henderson:
+
+<i><blockquote>
+There's no problem implementing PInvoke as specified in the ECMA
+specs and/or MS documentation. It's just that PInvoke by itself
+doesn't solve all of the problems; in particular it doesn't solve
+the problem of C types whose representation is different on different
+systems.
+</blockquote></i>
+
+** CVS use
+
+Q: Why do we keep ChangeLogs and make the CVS commit messages be the
+ same? One could be generated from the other
+
+A: There are a number of reasons for keeping ChangeLog files as well as
+ CVS commit files:
+
+ <ul>
+ * Offline programming: when people are traveling, CVS logs are
+ not available.
+
+ * Slow CVS access: Many people work over modem lines (very
+ typical for contributors in Europe, Asia, Latin America)
+ using CVS is slow and might not be available to you (cvs
+ server down, no anoncvs server available).
+
+ * ChangeLogs travel in a released tarball package, so it is
+ possible to study the rationale of changes even after a
+ project is long "released", or you only have the sources for
+ the code.
+
+ * ChangeLog are not metadata for each file, they are live
+ files that you can browse in the package that is being
+ distributed.
+ </ul>
+
+Making the CVS commit message be the same as the ChangeLog has other
+benefits:
+
+ <ul>
+ * You can track down with `cvs log' what things were changed,
+ and match those to meaningful reports on the intentions of
+ the commit.
+
+ * When reading the commits-list, you can get a glimpse of the
+ changes without having to diff out or cvs update your tree.
+
+ * You can read off-line the changes that are being made
+ (asyncrouns operation).
+ </ul>
+
+This mechanism works very well for GNOME and other projects.
+
+Q: Should I use any of the special RCS keywords like $Id: devel-faq,v 1.1 2001/07/31 21:13:05 miguel Exp $, $Author: miguel $,
+ $Date: 2001/07/31 21:13:05 $, or $Revision: 1.1 $?
+
+A: Please avoid using those in the source code in the CVS. They
+ are not really useful, and they cause a lot of conflicts when
+ people have separate CVS trees.
+
+ It was a nightmare with the Linux kernel when two people had their
+ private CVS trees and were submitting patches to the core.
+
diff --git a/web/documentation b/web/documentation
new file mode 100644
index 00000000000..166e0e8ccfe
--- /dev/null
+++ b/web/documentation
@@ -0,0 +1,50 @@
+* Documentation
+
+ Although most of the concepts from Microsoft.NET can
+ be applied to the completed Mono platform, we do need to
+ have a complete set of free documentation written specifically
+ for Mono.
+
+ The documentation license we have chosen is the GNU Free
+ Documentation License (FDL), the standard for most documents
+ in the free software world.
+
+ We need documentation on a number of topics:
+
+ <ul>
+
+ * The development tools (compilers, assembler tools,
+ language reference, design time features).
+
+ * Frequently Asked Question compilations.
+
+ * HOWTO documents.
+
+ * The Class Libraries
+
+ * Tutorials on Mono and the specifics of running it.
+
+ * A guide to Mono as compared to the Microsoft.NET
+ Framework SDK
+
+ </ul>
+
+** Class Library documentation
+
+ When contributing to the Class Library effort, please use the
+ inline XML documentation tags to document your classes so we
+ can automatically generate the documentation from the class
+ libraries.
+
+ If you provide examples, please do not embed them into the
+ source code, as that will make the source code harder to read
+ and maintain. Instead, put examples for your code into a
+ subdirectory of the class libraries. Make your sample
+ code a full standalone application that people can compile.
+ Ideally the Mono documentation browser will let you edit, modify
+ and run the sample programs.
+
+
+
+
+
diff --git a/web/download b/web/download
new file mode 100644
index 00000000000..64daa7761fb
--- /dev/null
+++ b/web/download
@@ -0,0 +1,177 @@
+* Software Availability
+
+ The Virtual Execution System is available in package `mono'.
+ Currently this contains a metadata library and the
+ disassembler. Please reffer to our <a
+ href="runtime.html">Runtime</a> description for more details
+ on this part of the project.
+
+ The code for the C# compiler as well as the language error
+ test suite and the class library are in the `mcs' package, we
+ will move this later into `mono' itself.
+
+ In order to make mcs and the class libraries you will need the
+ GNU make tools. These may be obtained for the Windows
+ environment from <a href="http://www.cygwin.com">cygwin.com</a>.
+
+ You will also need to get GLIB, from: <a
+href="ftp://ftp.gtk.org/pub/gtk/v1.2/glib-1.2.10.tar.gz">ftp://ftp.gtk.org/pub/gtk/v1.2/glib-1.2.10.tar.gz</a>
+
+<a name="sources">
+** Sources
+
+ We provide both <a href="packaged">packaged and tested</a>
+ tarballs (those are known to compile and pass `make
+ distcheck') as well as <a href="snapshots">daily snapshots</a> done
+ at 10pm Boston Time
+
+<a name="snapshots">
+*** Snapshots
+
+ The daily snapshots are available <a
+ href="http://www.go-mono.com/snapshots">here</a>. These
+ snapshots are done every day at 10pm EST (Boston Time).
+
+ They are not guaranteed to build, but most of the time they
+ should. They should give you a window to see what we are up to.
+
+ You might also want to track our development using the <a
+ href="http://mail.ximian.com/mailman/listinfo/mono-cvs-list">mono-cvs-list</a>
+ mailing list.
+
+<a name="packaged">
+*** Released and tested packages
+
+ <ul>
+ <a name="july-29">
+ <b>July 29, 2001</b>
+ <ul>
+ * <a href="archive/mono-0.5.tar.gz">mono-0.5.tar.gz</a>: Mono Runtime 0.5 release
+ * <a href="archive/mono-0.5">Release Notes</a>
+ </ul>
+
+ <a name="july-22">
+ <b>July 22, 2001</b>
+ <ul>
+ * <a href="archive/mcs-22-Jul-2001.tar.gz">mcs-22-Jul-2001.tar.gz</a>: CVS snapshot.
+ * <a href="archive/mcs-Jul-22-Jul-19-2001.tar.gz">Differences since 19</a>: CVS snapshot.
+ * <a href="archive/mcs-22">Release Notes</a>
+ </ul>
+
+ <a name="july-19">
+ <b>July 19th, 2001</b>
+ <ul>
+ * <a href="archive/mcs-19-Jul-2001.tar.gz">mcs-19-Jul-2001.tar.gz</a>: CVS snapshot.
+ * <a href="archive/mcs-Jul-17-Jul-19-2001.tar.gz">Differences since 17</a>: CVS snapshot.
+ * <a href="archive/mcs-19">Release Notes</a>
+ </ul>
+
+ <a name="july-17">
+ <b>July 17th, 2001</b>
+ <ul>
+ * <a href="archive/mcs-17-Jul-2001.tar.gz">mcs-17-Jul-2001.tar.gz</a>: CVS snapshot.
+ * <a href="archive/mcs-Jul-15-Jul-17-2001.tar.gz">Differences since 15</a>: CVS snapshot.
+ * <a href="archive/mcs-17">Release Notes</a>
+ </ul>
+
+ <a name="july-15">
+ <b>July 15th, 2001</b>
+ <ul>
+ * <a href="archive/mcs-15-Jul-2001.tar.gz">mcs-15-Jul-2001.tar.gz</a>: CVS snapshot.
+ * <a href="archive/mono-0.4.tar.gz">mono-0.4.tar.gz</a>: Packaged Source Code.
+ * <a href="archive/mono-0.4">Release Notes</a>
+ </ul>
+
+ <a name="july-14">
+ <b>July 14th, 2001</b>
+ <ul>
+ * <a href="archive/mcs-12-Jul-2001.tar.gz">mcs-12-Jul-2001.tar.gz</a>: CVS snapshot.
+ * <a href="archive/mono-0.3.tar.gz">mono-0.3.tar.gz</a>: Packaged Source Code.
+ </ul>
+
+ <a name="july-8">
+ <b>July 8th, 2001</b>
+
+ <ul>
+ * <a href="archive/mcs-08-Jul-2001.tar.gz">mcs-08-Jul-2001.tar.gz</a>: CVS Snapshot
+ * <a href="archive/mono-08-Jul-2001.tar.gz">mono-08-Jul-2001.tar.gz</a>: CVS Snapshot
+ </ul>
+ </ul>
+
+<a name="install">
+** Installing the software
+
+ To install and work on the compiler and the class libraries,
+ follow these instructions:
+
+ <ul>
+ * Install <a href="http://www.cygwin.com">CygWin</a> first.
+
+ * Untar the MCS distribution (see below for information).
+
+ * Go into the MCS directory and type `make windows'
+ </ul>
+
+ To compile the mono runtime on windows:
+
+ <ul>
+ * Install <a href="http://www.cygwin.com">CygWin</a> first.
+
+ * Once installed, in a terminal window or a cygwin
+ window (a shortcut should be on your desktop), untar the glib
+ distribution:
+
+<pre>
+tar xzvf glib-1.2.10.tar.gz
+</pre>
+
+ * Configure, compile and install glib, like this:
+
+<pre>
+./configure --prefix=/usr
+make
+make install
+</pre>
+
+ * Unpack the mono distribution:
+
+<pre>
+tar xzvf mono-XXX.tar.gz
+</pre>
+
+ * Configure, compile and install:
+
+<pre>
+./configure --prefix=//c/mono
+make
+make install
+</pre>
+ </ul>
+
+ To compile the mono runtime on Unix:
+
+ <ul>
+
+ * Download the mono distribution
+
+ * Unpack the mono distribution:
+
+<pre>
+tar xzvf mono-XXX.tar.gz
+</pre>
+
+ * Configure, compile and install:
+<pre>
+./configure
+make
+make install
+</pre>
+ </ul>
+
+** CVS
+
+ We are trying to figure out where to put our CVS repository.
+ We are debating between the GNOME CVS or SourceForge. Watch
+ this spot.
+
+
diff --git a/web/faq b/web/faq
new file mode 100644
index 00000000000..3bb7d839e14
--- /dev/null
+++ b/web/faq
@@ -0,0 +1,722 @@
+** Basics
+
+Q: Is Mono the same as Microsoft's .NET initiative?
+
+A: It is not.
+
+ .NET is a company-wide initiative at Microsoft that
+ encompasses many different areas. The .NET development framework,
+ Passport, Biztalk, new server products, and anything that is
+ remotely connected to .NET gets the ".NET-stamping" treatment.
+ Some components of Microsoft's .NET initiative have been announced
+ and some others are in the works.
+
+ Mono is a project to implement several technologies developed by
+ Microsoft that have now been submitted to the ECMA Standards Body.
+
+Q: What technologies are included in Mono?
+
+A: Mono contains a number of components useful for building new
+ software:
+
+ <ul>
+ * A Common Language Infrastructure (CLI) virtual
+ machine that contains a class loader, Just-in-time
+ compiler, and a garbage collecting runtime.
+
+ * A class library that can work with any language
+ which works on the CLR.
+
+ * A compiler for the C# language. In the future we
+ might work on other compilers that target the Common
+ Language Runtime.
+
+ Windows has compilers that target the
+ virtual machine from
+ <a href="http://msdn.microsoft.com/net/thirdparty/default.asp#lang">a
+ number of languages:</a> Managed C++, Java Script,
+ Eiffel, Component Pascal, APL, Cobol, Oberon, Perl,
+ Python, Scheme, Smalltalk, Standard ML, Haskell,
+ Mercury and Oberon.
+ </ul>
+
+ The CLR and the Common Type System (CTS) enables applications and
+ libraries to be written in a number of languages. Classes and
+ methods created in one language can be used from a different
+ language.
+
+ This means for example that if you define a class to do algebraic
+ manipulation in C#, that class can be reused from any other
+ language that supports the CLI. You could create a class in C#,
+ subclass it in C++ and instantiate it in an Eiffel program.
+
+ A single object system, threading system, class libraries, and
+ garbage collection system can be shared across all these languages.
+
+Q: Where can I find the specification for these technologies?
+
+A: You can find the work-in-progress documentation from the T3G ECMA
+ group here:
+
+ <a href="http://www.dotnetexperts.com">http://www.dotnetexperts.com</a>
+
+Q: Will you implement the .NET Framework SDK class libraries?
+
+A: Yes, we will be implementing the APIs of the .NET Framework SDK
+ class libraries.
+
+Q: What does Mono stand for?
+
+A: Mono is the word for `Monkey' in Spanish. We like monkeys.
+
+ It only means a number of other things: monochromatic (hence the
+ gray theme used in the Web site).
+
+Q: When will you ship it?
+
+A: We do not know when the code will be shipped. The more
+ contributions we get to the project, the sooner it will ship.
+
+ A rough estimate is that we might be able to run our C# compiler on
+ Linux by the end of the year. That means running the Windows
+ Executable generated by a Microsoft .NET compiler on the Linux
+ platform.
+
+ We expect that doing GUI applications will require more work on the
+ class libraries. That could take another six months.
+
+Q: How can I contribute?
+
+A: Check the <a href="contributing.html">contributing</a> section.
+
+Q: You guys should innovate instead of copying.
+
+A: In this particular case, we see a clear advantage in the platform
+ and we are interested in using the features of the CLI on open source systems.
+
+ We have decided that we should spend our limited resources towards
+ implementing an existing specification instead of designing and
+ implementing our own.
+
+ Designing and implementing our own would be possible, but it doesn't make
+ sense to do that just because the specification comes from a
+ proprietary vendor.
+
+** Ximian
+
+Q: Why is Ximian working on .NET?
+
+A: We are interested in providing the best tools for programmers to
+ develop applications for Free Operating Systems.
+
+ For more information, read the project <a
+ href="rationale.html">rationale</a> page.
+
+Q: Will Ximian be able to take on a project of this size?
+
+A: Ximian will not be able to taken on the whole project on its own.
+ Mono will be a free software/open source community project, that is
+ the only way we can hope to implement something of this size. You
+ can <a href="contributing.html">contribute</a> to this effort.
+
+Q: What pieces will Ximian be working on?
+
+A: We will focus on building a development and execution
+ environment.
+
+ The idea is to get Mono to a state of that would allow
+ third parties to actually be able to use it real-world development.
+
+Q: Why does Ximian even care?
+
+A: We like the features that the CLI and its related technologies
+ bring to the table. An exciting addition to the developer toolkit.
+ The goal of Mono is to bring this technology to non-Windows
+ platforms (although we hope Mono will also run on Windows, for
+ debugging and comparative purposes).
+
+
+** Licensing
+
+Q: Will I be able to write proprietary applications that run with
+ Mono?
+
+A: Yes. The licensing scheme is planned to allow proprietary
+ developers to write applications with Mono.
+
+Q: What license is Mono on?
+
+A: The C# Compiler is released under the terms of the GPL. The class
+ libraries will be under the LGPL or the GPL with a special
+ exception. The runtime libraries are under the LGPL.
+
+ Since the LGPL is not suitable for embedded systems development, we
+ are also licensing the libraries under the GPL with the following exception:
+
+ If you link this library against your own program, then you do not
+ need to release the source code for that program. However, any
+ changes that you make to the library itself, or to any native
+ methods upon which the library relies, must be re-distributed in
+ accordance with the terms of the GPL.
+
+ This is similar in spirit to <a
+ href="http://www.gnu.org/software/classpath/classpath.html">GNU
+ Classpath.</a>
+
+Q: But in Object Oriented Programming I need to subclass your library
+ functions, does that mean that I am making modifications to your
+ library and hence I would have to distribute my sources under the
+ LGPL?
+
+A: No. Object Oriented Programming in the class library is a well
+ understood interface barrier, so you can actually develop
+ proprietary applications with the Mono libraries.
+
+Q: Will you accept code under the XXX License?
+
+A: If the XXX License is compatible with the license we use in that
+ specific piece of code, then yes. If you want to use the BSD license, make
+ sure you use the BSD license without the advertisement clause (The
+ `Ousterhout License').
+
+** Mono and .NET
+
+Q: If applications use Mono, does that mean that I have to pay a service fee?
+
+A: No. Mono is not related to Microsoft's initiative of
+ software-as-a-service.
+
+Q: If you implement .NET, will I depend on Microsoft Passport to run my software?
+
+A: No. The .NET Framework is a runtime infrastructure and collection
+ of class libraries. Passport may be required to access certain web
+ services written for that framework, but only if the programmer
+ chooses Passport as the authentication mechanism.
+
+Q: Is .NET just a bunch of marketing slogans?
+
+A: Although the `.NET initiative' is still quite nebulous, The .NET Framework
+ has been available for some time. Mono is not an implementation of the .NET
+ initiative, just the development framework.
+
+Q: What is a 100% .NET application?
+
+A: A `100% .NET application' is one that only uses the APIs defined
+ under the System namespace and does not use PInvoke. These
+ applications would in theory run unmodified on Windows, Linux,
+ HP-UX, Solaris, MacOS X and others.
+
+Q: But Microsoft will release a port of the real thing under the
+ `Shared Source' license, why bother with anything else?
+
+A: The Shared Source implementation will not be usable for commercial
+ purposes. We are working towards an implementation that will grant
+ a number of rights to recipients: use for any purpose,
+ redistribution, modification, and redistribution of modifications.
+
+ This is what we call <a
+ href="http://www.gnu.org/philosophy/free-sw.html">Free Software</a>
+
+** Passport
+
+Q: Is this a free implementation of Passport?
+
+A: No. Passport is part of Microsoft's Hailstorm initiative. Mono
+ is just a runtime, a compiler and a set of class libraries.
+
+Q: Will the System.Web.Security.PassportIdentity class, mean
+ that my software will depend on Passport?
+
+A: No. That just means that applications might use that API to
+ contact a Passport site.
+
+ As long as your application does not use Passport, you will not
+ need Passport.
+
+ It might even be possible to implement that class with
+ a set of dummy functions, or use an alternate Passport implementation.
+
+ We do not know at this time whether the Passport protocol is
+ documented and whether we will be able to talk to
+ passport.com
+
+Q: But that must mean that you are tied to Passport!
+
+A: All the contrary. The implementation could keep the interface (for
+ the sake of simplicity, lets say it implements the method `Login'
+ and `GetUserName').
+
+ We could implement `Login' and `GetUserName' by talking to XNS or
+ any other decentralized systems. Or any other system that the
+ industry standarizes on.
+
+Q: What is your opinion?
+
+A: You can read my personal <a href="passport.html">opinion on
+ passport</a>.
+
+Q: Will Mono running on Linux make Passport available for Linux?
+
+A: The Passport toolkit for Linux-based web servers is available from
+ Microsoft.
+
+ Again, Mono has nothing to do with Passport.
+
+** Mono and Windows
+
+Q: Will Mono allow me to run Microsoft Office on Linux?
+
+A: No, it will not. Microsoft Office is a Windows application. To
+ run Windows applications on Intel Unix systems refer to <a
+ href="http://www.winehq.com">the Wine Project</a>
+
+** GNOME
+
+Q: How is this related to GNOME?
+
+A: In a number of ways:
+
+ * Mono will use existing
+ components that have been developed for GNOME when it makes
+ sense. For example on X systems, we will use Gtk+ and
+ Libart to implement Winforms and the Drawing2D API.
+
+ For database access, we will use LibGDA (not really
+ depending on GNOME, but related to).
+
+ * This project was born out of the need of providing improved
+ tools for the GNOME community.
+
+ * We would like to add support to our CLR implementation to
+ deal with GObjects (in GNOME 1.x, they are called
+ GtkObjects), and allow Mono developers to provide GObjects
+ or use and extend existing GObjects.
+
+Q: Has the GNOME Foundation or the GNOME team adopted Mono?
+
+A: Mono is too new to be adopted by those groups. We hope that the
+ tools that we will provide will be adopted by free software
+ programmers including the GNOME Foundation members and the GNOME
+ project generally.
+
+Q: Should GNOME programmers switch over to Mono?
+
+A: Mono will not be ready even within the next six months, and a
+ complete implementation is probably one year away.
+
+ We encourage GNOME developers to continue using the existing tools,
+ libraries and components. Improvements made to GNOME will have an
+ impact on Mono, as they will provide the "backend" for various
+ classes.
+
+Q: Will Mono include compatibility with Bonobo components?
+
+A: Yes, we will provide a set of classes for implementing and using
+ Bonobo components from within Mono.
+
+Q: Does Mono replace Bonobo?
+
+A: Bonobo is very focused on cross-application component reuse. Mono
+ will provide a Bonobo framework to allow you to develop Bonobo
+ components and use Bonobo components on Unix.
+
+ Mono should allow you to write Bonobo components more easily, just
+ like .NET on Windows allows you to export .NET components to COM.
+
+** Mono and the Web
+
+Q: Is Mono a way of running Java applets?
+
+A: No.
+
+** Web Services
+
+Q: Is Mono just a new way of writing Web Services?
+
+A: No.
+
+Q: If this implements the SDK classes, will I be able to write and
+ execute .NET Web Services with this?
+
+A: Yes, you will.
+
+ When the project is finished, you will be able to use the same
+ technologies that are available through the .NET Framework SDK on
+ Windows to write Web Services.
+
+Q: What about Soup?
+
+A: Soup is a library for GNOME applications to create SOAP server and
+ SOAP clients. You can browse the source code for soup using <a
+ href="http://cvs.gnome.org/bonsai">GNOME's Bonsai</a>
+
+Q: Can I use CORBA?
+
+A: Yes. The CLI contains enough information about a class that
+ exposing it to other RPC systems (like CORBA) is really simple, and
+ does not even require support from an object.
+
+ We will be implementing CORBA interoperation as an extension to the
+ Mono classes so that we can integrate with Bonobo, just like
+ Microsoft provides COM interoperation classes and support
+ mechanisms.
+
+Q: Can I serialize my objects to other things other than XML?
+
+A: Yes, although the serializing tools have not yet been planned, and
+you would probably have to implement them yourself.
+
+** Development Tools
+
+Q: Will it be possible to use the CLI features without using bytecodes
+ or the JIT?
+
+A: Yes. The CLI engine will be made available as a shared library.
+ The garbage collection engine, the threading abstraction, the
+ object system, the dynamic type code system and the JIT will be
+ available for C developers to integreate with their applications if
+ they wish to do so.
+
+Q: Will you have new development tools?
+
+A: Hopefully Free Software enthusiasts will contribute tools to
+ improve the developer environment. These tools could be developed
+ initially using Microsoft implementation of the CLI and then
+ executed later with Mono.
+
+** Mono and Java
+
+Q: What about using Java? After all there are many languages that
+ target the Java VM.
+
+A: You can get very good tools for doing Java development on free
+ systems right now. <a href="http://www.redhat.com">Red Hat</a> has
+ contributed a <a href="http://gcc.gnu.org">GCC</a> <a
+ href="http://gcc.gnu.org/java">frontend for Java</a> that can take
+ Java sources or Java byte codes and generate native executables; <a
+ href="http://www.transvirtual.com">Transvirtual</a> has implemented
+ <a href="http://www.kaffe.org">Kaffe</a> a JIT engine for Java;
+ Intel also has a Java VM called <a
+ href="http://www.intel.com/research/mrl/orp">ORP</a>.
+
+ The JVM is not designed to be a general purpose virtual machine.
+ The Common Intermediate Language (CIL), on the other hand, is
+ designed to be a target for a
+ wide variety of programming languages, and has a set of rules
+ designed to be optimal for JITers.
+
+
+Q: What kind of rules make the Common Intermediate Language useful for
+ JITers?
+
+A: The main rule is that the stack in the CLI is not a general purpose
+ stack. You are not allowed to use it for other purposes than
+ computing values and passing arguments to functions or return
+ values.
+
+ At any given call or return instruction, the types on the stack
+ have to be the same independently of the flow of execution of your
+ code.
+
+Q: I heard that the CIL is ideal for JITing and not efficient for
+ interpreters, is this the case?
+
+A: The CIL is better suited to be JITed than JVM byte codes, but you
+ can interpret them as trivially as you can interpret JVM byte
+ codes.
+
+Q: Could Java target the CLI?
+
+A: Yes, Java could target the CLI. We have details on a <a
+ href="ideas.html#guavac">project</a> that someone could take on to
+ make this happen.
+
+** Extending Mono
+
+Q: Would you allow other classes other than those in the
+ specification?
+
+A: Yes. The Microsoft class collection is very big, but it is by no
+ means complete. It would be nice to have a port of `Camel' (the
+ Mail API used by Evolution inspired by Java Mail) for Mono
+ applications.
+
+ You might also want to look into implementing CORBA for Mono. Not
+ only because it would be useful, but because it sounds like a fun
+ thing to do, given the fact that the CLI is such a type rich
+ system.
+
+ For more information on extending Mono, see our <a
+ href="ideas.html">ideas</a> page.
+
+** Mono and portability
+
+Q: Will Mono only work on Linux?
+
+A: Currently, we are doing our work on Linux-based systems and
+ Windows. We do not expect many Linux-isms in the code, so it
+ should be easy to port Mono to other UNIX variants.
+
+Q: What about Mono on non X-based systems?
+
+A: Our main intention at Ximian is to be able to develop GNOME
+ applications with Mono, but if you are interested in providing a
+ port of the Winform classes to other platforms (frame buffer or
+ MacOS X for example), we would gladly integrate them, as long
+ they are under a Free Software License.
+
+** Reusing existing Code
+
+Q: What projects will you reuse or build upon?
+
+A: We want to get Mono in the hands of programmers soon. We are
+ interested in reusing existing open source software.
+
+Q: What about Intel's research JIT framework, ORP?
+
+A: At this time, we are investigating whether we can use elements of
+ ORP for Mono. ORP is a research JIT engine that has a clear
+ defined API that splits the JIT from the GC system and the actual
+ byte code implementation. It is a research product.
+
+Q: What about using GNU Lightning?
+
+A: We are also researching <a
+ href="http://www.gnu.org/software/lightning/lightning.html">GNU
+ Lightning</a>.
+
+<a name="ximian-and-microsoft">
+** Ximian and Microsoft
+
+Q: I read that Microsoft is helping out Ximian, is this true?
+
+A: Initial contact between David Stutz and Miguel de Icaza happened.
+ It was a friendly conversation. Microsoft is interested in other
+ implementing .NET and are willing to help make the ECMA spec more
+ accurate for this purpose.
+
+ We were initially contacted by Sam Ruby at the ECMA TG3 committee
+ to discuss the same issue. And we are glad to have good contacts
+ to ask questions about the specs.
+
+Q: Is Microsoft paying Ximian to do this?
+
+A: No, we are doing this for purely selfish reasons. We are upgrading
+ our development platform to build better applications on Unix and other
+ systems.
+
+Q: Do you fear that Microsoft will change the spec and render Mono useless?
+
+A: No. Microsoft proved with the CLI and the C# language that it was
+ possible to create a powerful foundation for many languages to
+ interoperate. We will always have that.
+
+ Even if changes happened in the platform which were undocumented
+ (which is very unlikely), the existing platform has a value on its
+ own.
+
+ Miguel once explained its motivation for working on Mono to Dave
+ Winer, and his mail got posted <a
+ href="http://scriptingnews.userland.com/stories/storyReader$1275">here</a>
+
+Q: Didn't Miguel de Icaza say that `Unix Sucks'?
+
+A: Yes, he did, as a catch phrase in his opening remark on the Ottawa
+ Linux Symposium. His talk focused on various ways to improve Unix.
+
+ There is a paper describing some ways to improve Unix at:
+
+ <a href="http://primates.ximian.com/~miguel/bongo-bong.html">
+ http://primates.ximian.com/~miguel/bongo-bong.html</a>
+
+Q: Didn't Ximian's Miguel work for Microsoft?
+
+A: Actually, Nat Friedman (Ximian's co-founder) did work as an
+ intern for Microsoft for one summer but Miguel did not.
+
+Q: Did Nat and Miguel meet at Microsoft?
+
+A: They met online on the Linux IRC network; They met in person for
+ the first time in 1997.
+
+** Mono and Microsoft
+
+Q: How can you expect Mono to compete with Microsoft, wont this
+ require an effort too large?
+
+A: You are right. Mono will never become a reality without the help
+ of other contributors. Ximian is a small company that can not
+ finish Mono alone. We will be working with members of the
+ community to deliver the product.
+
+Q: Is Microsoft and Corel involved in the Mono implementation?
+
+A: No, they are not.
+
+Q: Are you writing Mono from the ECMA specs?
+
+A: yes, we are writing them from the ECMA specs and the published
+ materials in print about .NET
+
+Q: What happens if Microsoft `Embraces and Extends' the CLI standard
+ and keeps Mono out of the play?
+
+A: There are various explanations to this question. The first one is
+ that the benefits that you can get from the CLI are going to be
+ there with or without `embracing and extending'. We might not be
+ able to run every .NET Windows application on Mono. But remember:
+ it was already easy for someone to just use PInvoke to tie their
+ application to Windows.
+
+ The bottom line is that the advantages of having a CLI runtime will
+ be with us, no matter if Microsoft forks their version to be
+ incompatible.
+
+Q: What if Microsoft changes the interface, and all of a sudden
+ applications break?
+
+A: If they change their released API, every application that was
+ developed against it will break.
+
+ That being said, Microsoft have a pretty good record of keeping
+ backwards binary compatibility.
+
+** Acronyms
+
+Q: What is the difference between CLR (Common Language Runtime) and
+ CLI (Common Language Infrastructure)?
+
+A: CLI is the specification of an execution system. The Microsoft
+ implementation of this specification is named CLR.
+
+ Unless we come up with our own acronym, we could just call ours
+ also CLR, just because it would do exactly the same thing the
+ Microsoft implementation does.
+
+<a name="gcc">
+** Mono and GCC
+
+Q: Should someone work on a GCC front-end to C#?
+
+A: I would love if someone does, and we would love to help anyone that
+ takes on that task, but we do not have the time or expertise to
+ build a C# compiler with the GCC engine. I find it a lot more fun
+ personally to work on C# on a C# compiler, which has an intrinsic
+ beauty.
+
+ We can provide help and assistance to anyone who would like to work
+ on this task.
+
+Q: Should someone make a GCC backend that will generate CIL images?
+
+A: I would love to see a backend to GCC that generates CIL images. It
+ would provide a ton of free compilers that would generate CIL
+ code. This is something that people would want to look into
+ anyways for Windows interoperation in the future.
+
+ Again, we would love to provide help and assistance to anyone
+ interested in working in such a project.
+
+Q: What about making a front-end to GCC that takes CIL images and
+ generates native code?
+
+A: I would love to see this, specially since GCC supports this same
+ feature for Java Byte Codes. You could use the metadata library
+ from Mono to read the byte codes (ie, this would be your
+ "front-end") and generate the trees that get passed to the
+ optimizer.
+
+ Ideally our implementation of the CLI will be available as a shared
+ library that could be linked with your application as its runtime
+ support.
+
+ Again, we would love to provide help and assistance to anyone
+ interested in working in such a project.
+
+Q: But would this work around the GPL in the GCC compiler and allow
+ people to work on non-free front-ends?
+
+A: People can already do this by targeting the JVM byte codes (there
+ are about 130 compilers for various languages that target the JVM).
+
+Q: Why are you writing a JIT engine instead of a front-end to GCC?
+
+A: The JIT engine and runtime engine will be able to execute CIL
+ executables generated on Windows.
+
+** Mono and Portability
+
+Q: Will Mono work on other variants of Unix?
+
+A: Yes. We do not expect to add any gratuitous incompatibilities.
+
+Q: Will Mono run on Windows?
+
+A: Hopefully yes. Currently some parts of Mono only run on Windows
+ (the C# compiler is a .NET executable) and other parts have only
+ been compiled on Linux, but work on Windows with Cygwin.
+
+Q: Will Mono depend on GNOME?
+
+A: It will depend only if you are using a particular assembly (for
+ example, for doing GUI applications). If you are just interested
+ in Mono for implementing a `Hello World Enterprise P2P Web
+ Service', you will not need any GNOME component.
+
+** Performance
+
+Q: How fast will be Mono?
+
+A: We can not predict the future, but a conservative estimate is that
+ it would be at least `as fast as other JIT engines'.
+
+ Now, wishfully thinking I hope that we will ship various JITs with
+ Mono just like Microsoft has done. A fast JITer when maximum
+ performance is not needed, but fast load times are important; And
+ an optimizing JITer that would be slower at generating code but
+ produce more optimal output.
+
+ The CIL has some advantages over the Java byte code: it is really
+ an intermediate representation and there are a number of
+ restrictions on how you can emit CIL code that simplify creating
+ better JIT engines.
+
+ For example, on the CIL the stack is not really an abstraction
+ available for the code generator to use at will: it is just a way
+ of creating a postfix representation of the parsed tree. At any
+ given call point or return point, the contents of the stack are
+ expected to contain the same object types independently of how the
+ instructions was reached.
+
+
+** Mono and Portable.NET
+
+Q: What are the differences between Mono and Portable.NET?
+
+A: Most of Mono is being written using C#, the only pieces written in
+ C are those who have to absolutely be built using C (The JIT
+ engine, the runtime, the interfaces to the garbage collection
+ system).
+
+ The C# compiler and the tools will become reusable C# components.
+
+ Portable.NET is building its components out of C pieces.
+
+** Assorted questions
+
+Q: You say that the CLI allows multiple languages to execute on the
+ same environment. Isn't this the purpose of CORBA?
+
+A: The key difference between CORBA (and COM) and the CLI is that the
+ CLI allows "data-level interoperability" because every
+ language/component uses the same data layout and memory management.
+
+ This means you can operate directly upon the datatypes that someone
+ else provides, without having to go via their interfaces. It also
+ means you don't have to "marshall" (convert) parameters (data
+ layouts are the same, so you can just pass components directly) and
+ you don't have to worry about memory managment, because all
+ languages/components share the same garbage collector and address
+ space. This means much less copying and no need for reference
+ counting.
+
diff --git a/web/gcc-frontend b/web/gcc-frontend
new file mode 100644
index 00000000000..2b15346db69
--- /dev/null
+++ b/web/gcc-frontend
@@ -0,0 +1,9 @@
+* The GCC front-end
+
+ The GCC front-end will accept input in a binary file with
+ codes in the Common Intermediate Language (CIL), and generate
+ native code.
+
+ This will allow pre-compilation and full optimization to take
+ place before a program is executed.
+
diff --git a/web/ideas b/web/ideas
new file mode 100644
index 00000000000..fb2a89aa205
--- /dev/null
+++ b/web/ideas
@@ -0,0 +1,119 @@
+* Ideas
+
+ Here are a few ideas of tools, classes and projects that you
+ could start. More are forthcoming.
+
+<a name="runtime">
+** Runtime
+
+ We need a verifier that can be run on an executable (assembly)
+ and tells whether the metadata for the executable is correct
+ or not. It should report any anomalies.
+
+ For a list of anomalies in assemblies, check the various assertions
+ that are described on the ECMA documentation.
+
+ This will help test our generated executables and can be also
+ used as an external verifier.
+
+<a name="classes">
+** Classes
+
+ <ul>
+TODO=jxta,The JXTA Peer to Peer foundation
+ * Implement a JXTA protocol implementation:
+ <a href="http://www.jxta.org">http://www.jxta.org</a>
+
+TODO=camel,Mail API
+ * Implement a Mail API, similar to Camel or JavaMail (Camel has
+ significant architecture features that are required on a real
+ mailer).
+
+ You can check the current C
+ <a href="http://cvs.gnome.org/bonsai/rview.cgi?dir=evolution%2Fcamel">
+ Camel implementation</a>.
+
+ Such an implementation could be used both with
+ Microsoft .NET and Mono.
+
+TODO=multimedia
+ * Interfacing to Multimedia systems. You might want
+ to look into the Quicktime API. I know <a
+ href="mailto:vladimir@ximian.com">Vladimir</a> has
+ researched the problem before
+
+TODO=gtk,Gtk+ wrappers for Mono and .NET
+ * Wrap the Gtk+ API. This is simple and can be done
+ on Windows as Gtk+ 2.0 works on Windows.
+
+ This work can also be used on Windows and will
+ enable developers on Windows to use some of Gtk+'s
+ advanced features.
+
+ The idea is to wrap the Gtk+ API and allow us to
+ build GUI applications using Gtk+ and in the future
+ other Gtk+-based libraries from Mono (Gal, GtkHTML).
+
+ There is extensive knowledge on wrapping Gtk+ in
+ other languages (this has been done this for Perl,
+ Python, Java, Scheme, Haskel and other languages in
+ the past).
+ </ul>
+
+<a name="projects">
+** Projects
+
+ <ul>
+TODO=xmlStorage,
+ * Implement an xmlStorageSystem for the CLI:
+ <a href="http://www.soapware.org/xmlStorageSystem">
+ http://www.soapware.org/xmlStorageSystem</a>
+
+TODO=guavac,Java compiler for .NET
+ * You could take one of the existing Java compilers
+ (Guavac comes to mind as it is so nice) and modify
+ it to generate .NET code rather than JVM byte
+ codes.
+
+ This should be a pretty straightforward task.
+ Guavac has the advantage of being written in C++ and
+ it could be compiled with the Microsoft Managed C++
+ compiler and produce a .NET executable with it.
+
+TODO=CORBA,CORBA implementation
+ * Build a CORBA interoperability engine for the CLR.
+ You do not need to do all of the work, just talking
+ the protocol will get us a long way (<a
+ href="http://www.omg.org">The OMG site</a> has the
+ CORBA specs).
+
+ Get in touch with David Taylor (dtaylo11 at bigpond
+ dot net dot au) as he has been working on this
+ project.
+
+TODO=Bonobo,Bonobo for Mono
+ * Once CORBA is done, implement the Bonobo interfaces
+ to allow people to use Bonobo components in Mono and
+ Mono components with Bonobo. The best of both worlds!
+
+TODO=moniker,Object Naming System with Monikers
+ * A naming space for Mono. An object naming space is
+ a very powerful tool. Bonobo implements a moniker
+ system that is more powerful than the original
+ moniker concept that was pioneered by COM/OLE in the
+ Microsoft world.
+
+ Our implementation builds on a concept, and we have
+ made it simpler, more powerful, more extensible and
+ a much better mechanism than the equivalent monikers
+ on Windows.
+
+ Implementing Mono monikers would benefit both
+ Windows users using .NET and Mono users on Unix and
+ Windows.
+
+ Here is <a
+ href="http://primates.ximian.com/~miguel/monikers.html">an
+ overview of the moniker system</a> in Bonobo.
+
+ </ul>
diff --git a/web/index b/web/index
new file mode 100644
index 00000000000..d43c81135ed
--- /dev/null
+++ b/web/index
@@ -0,0 +1,103 @@
+ <a href="http://www.ximian.com">Ximian</a> announced the
+ launch of the Mono project, an effort to create an Open Source
+ implementation of the .NET Development Framework.
+
+ Mono includes: <a href="c-sharp.html">a compiler</a> for the
+ C# language, a <a href="runtime.html">runtime</a> for the
+ Common Language Infrastructure and a set of <a
+ href="class-librayr.html">class libraries</a>
+
+ You can read our <a href="rationale.html">rationale</a> for
+ this project. If you have questions about the project, please
+ read our list of <a href="faq.html">Frequently Asked
+ Questions</a> or <a href="mailto:mono-list@ximian.com">contact us.</a>
+
+ You might also want to <a href="download.html">Download the
+ source</a> for our work so far. Or you can grab a <a
+ href="snapshots">snapshot</a> of our current work.
+
+ You might want to <a
+ href="resources.html#mailing">subscribe</a> to our mono-list
+ and mono-announce-list
+
+ You can contact the team at: <a
+ href="mailto:mono-list@ximian.com">mono-list@ximian.com</a>
+
+** Aug 20, 2001
+
+ A new <a href="contributing.html#compile-service">Compilation
+ service</a> has been made available by Derek to allow people
+ without access to the <a
+ href="http://msdn.microsoft.com/downloads/default.asp?url=/downloads/sample.asp?url=/msdn-files/027/000/976/msdncompositedoc.xml&frame=true">.NET SDK</a>
+
+** Aug 3, 2001
+
+ Daily snapshots of mcs and mono are now available, they will
+ run every night at 10pm Boston time.
+
+** Jul 29, 2001
+
+ Mono Runtime 0.5 has been <a
+ href="download.html#july-29">released.</a> Check the <a
+ href="archive/mono-0.5">release notes</a>
+
+** Jul 25, 2001
+
+ The slides for <A href="Presentations/O-Reilly">my
+ presentation</a> at <a href="http://www.oreilly.com">O'Reilly
+ Open Source Software Convention</a>
+
+** Jul 22, 2001
+
+ Another release of the class libraries is out, check the <a
+ href="archive/mcs-22">MCS 22-July Release Notes</a>. You can
+ get the new class libraries from <a
+ href="download.html#july-22">here</a>
+
+** Jul 19, 2001
+
+ Another release of the class libraries is out, check the <a
+ href="archive/mcs-19">MCS 19-July Release Notes</a>. You can
+ get the new class libraries from <a
+ href="download.html#july-19">here</a>
+
+** Jul 17, 2001
+
+ Another release of the class libraries is out, check the <a
+ href="archive/mcs-17">MCS 17-July Release Notes</a>. You can
+ get the new class libraries from <a
+ href="download.html#july-17">here</a>
+
+ Do not forget to check out the updated <a href="faq.html">FAQ</a>.
+
+ Got Sean's new <a href="class-status/index.html">Class
+ Status</a> web pages up. These are a lot better than mine, and
+ we are now keeping better track of contributors.
+
+** Jul 15, 2001
+
+ Another release of Mono is out, check the <a
+ href="archive/mono-0.4">Mono 0.4 Release Notes</a>. Get it <a
+ href="download.html#july-15">here</a>.
+
+** Jul 14, 2001
+
+ A <a
+ href="http://mail.ximian.com/archives/public/mono-list/2001-July/000399.html">new
+ release</a> of the
+ runtime, compiler and classes has been made. Get it <a href="download.html#july-14">here</a>
+
+** Jul 12, 2001
+
+ I keep getting questions about my opinion on Passport, even when
+ Mono has <b>nothing</b> to do with it. I finally <a
+ href="passport.html">wrote something.</a>
+
+** Jul 9, 2001
+
+ Project launched.
+
+** O'Reilly
+
+ Brian posted a story on <a
+ href="http://www.oreillynet.com/dotnet">O'Reilly Network .NET</a>
diff --git a/web/passport b/web/passport
new file mode 100644
index 00000000000..05346d8aa20
--- /dev/null
+++ b/web/passport
@@ -0,0 +1,276 @@
+* Updates
+
+ I have received many comments from people, and I have updated
+ the page accordingly. From removing incorrect statements, to
+ fixing typos, to include mentions to other software pieces.
+
+ I also corrected my statement about IIS and a trojan horse, I
+ should read a more educated press in the future. My apologies
+ to Microsoft and its employees on this particular topic. IIS
+ did not have a trojan horse built in.
+
+* Microsoft Hailstorm and Passport
+
+ Microsoft Passport is a centralized database hosted by
+ Microsoft that enhances the consumer experience with the Web
+ by providing a single logon system that they can use across a
+ number of participant web sites.
+
+ As you might know by now from our extensive <a
+ href="faq.html">FAQ</a>, the Mono project has nothing to do
+ with Microsoft Hailstorm or <a
+ href="http://www.passport.com">Microsoft Passport.</a>
+
+ Still a lot of people have asked us our opinion on them.
+
+** Passport
+
+ Passport is important not because of it being a breakthrough
+ technologically speaking, but because the company is in a
+ position to drive most people toward being suscribers of it.
+
+ At the time of this writing passport is required to use the
+ free mail service <a href="http://www.hotmail.com">Hotmail</a>
+ to get customized support for the <a
+ href="http://www.msn.com">MSN portal</a>, <a
+ href="http://msdn.microsoft.com">Microsoft Developers
+ Network</a> and according to the original announcement from
+ Microsoft <a href="http://www.americanexpress.com">American
+ Express</a> and <a href="http://www.ebay.com">EBay</a> will be
+ adopting it.
+
+ There is already a <a
+ href="http://www.passport.com/Directory/Default.asp?PPDir=C&lc=1033">Large
+ list</a> of participating sites.
+
+ There are many current users of it and Microsoft will be
+ driving more users towards Passport as it <a
+ href="http://news.cnet.com/news/0-1003-200-6343275.html">integrates
+ it</a> in their upcoming release of Windows.
+
+ Microsoft has also <a
+ href="http://www.passport.com/Business/JoinPassportNetwork.asp?lc=1033">developed
+ a toolkit</a> to enable current web merchants to integrate
+ their services with passport.
+
+ To the end user, there is a clear benefit: they only have to
+ log into a single network and not remember multiple passwords
+ across sites on the internet. Companies that adopt passport
+ will have a competition advantage over those that dont.
+ Microsoft lists a list of <a
+ href="http://www.passport.com/Business/Default.asp?lc=1033">benefits</a>
+ to companies.
+
+
+** The problems of Passport
+
+ There are a number of concerns that different groups have over
+ Passport. Sometimes I have some, sometimes I do not. But
+ overall, consumers and businesses can have better solutions.
+
+ <ul>
+ * <b>Single Point of Failure:</b> As more services and
+ components depend on remote servers, functionality can
+ grind to a halt if there is a failure on the
+ centralized Passport system.
+
+ Such a failure was predicted, and we recently <a
+ href="http://news.cnet.com/news/0-1005-200-6473003.html">witnessed</a>
+ got a lot of people worried.
+
+ The outgage lasted for seven days. Think what this
+ could do to your business.
+
+ * <b>Trust:</b> Not everyone trusts Microsoft to keep
+ their information confidential. Concerns are not only
+ at the corporate level policy, but also the fact that
+ the source code for Microsoft products is not
+ available, means that trojans or worms could be built
+ into the products by malicious engineers.
+
+ * <b>Security:</b> With a centralized system like
+ Passport, imagine the repercussions of a malicious
+ hacker gaining access to the Passport database.
+ Personal information and credit card information about
+ almost everyone using a computer could be stored there.
+
+ Hackers have already <a
+ href="http://slashdot.org/articles/00/10/27/1147248.shtml">broken
+ into Microsoft</a> in the past. And the company was
+ unable to figure out for how long their systems had
+ been hacked.
+
+ Security holes have been found in <a
+ href="http://slashdot.org/articles/00/04/14/0619206.shtml">IIS
+ in the past.</a> If all the world's data is stored on
+ a central location, when a single security hole is
+ detected, it would allow an intruder to install a
+ backdoor within seconds into the corporate network
+ without people ever noticing.
+
+ Microsoft itself has been recently hit by worms,
+ imagine if all your business depended on a single
+ provider for providing all or your authentication
+ needs
+ </ul>
+
+ Microsoft might or might not realize this. The idea behind
+ Passport is indeed a good one (I can start to get rid of my
+ file that keeps track of the 30 logins and passwords or so
+ that I use across the various services on the net myself).
+
+** Alternatives to Microsoft Passport
+
+ An alternative to Microsoft Passport needs to take the above
+ problems into consideration. Any solution of the form `We
+ will just have a competing offering' will not work.
+
+ The system thus has to be:
+
+ <ul>
+ * <b>Distributed:</b> The entire authentication
+ system should not create an internet `blackout' in the
+ case of failure.
+
+ A distributed system using different software
+ platforms and different vendors would be more
+ resistent to an attack, as holes in a particular
+ implementation of the server software would not affect
+ every person at the same time.
+
+ A security hole attack might not even be relevant to
+ other software vendors software.
+
+ * <b>Allow for multiple registrars:</b> Users should
+ be able to choose a registrar (their banks, local
+ phone company, service provider, Swiss bank, or any
+ other entity they trust.
+
+ * <b>Mandate good security measures:</b> As a
+ principle, only Open Source software should be used
+ for servers in the registrar, and they should conform
+ to a standard set of tools and software that can be
+ examined by third parties.
+ </ul>
+
+ An implementation of this protocol could use the DNS or a
+ DNS-like setup to distribute the information of users with the
+ possibility of replicating and caching public information
+ about the user.
+
+ For instant messaging (another piece of the Hailstorm bit),
+ you want to use a non-centralized system like Sun's <a
+ href="http://www.jxta.org">JXTA</a>. Some people mailed me to
+ mention Jabber as a messaging platform and other people
+ pointed out to the <a
+ href="http://java.sun.com/products/jms/">Java Message
+ Service</a>. The JMS does support a number of very
+ interesting features that are worth researching.
+
+ It could also just use the user e-mail address as the `key' to
+ choose the registrar (msn.com, hotmail.com -> passport.com;
+ aol.com -> aol.passport.com; you get the idea).
+
+ The <a
+ href="http://www.soapware.org/xmlStorageSystem">xmlStorage</a>
+ idea from <a href="http://www.scripting.com">Dave Winer</a>
+ could be used to store the information.
+
+ A toolkit for various popular web servers could be provided,
+ authenticated and should be open sourced (for those of you who
+ think that a binary program would give more security and would
+ prevent people from tampering: you are wrong. You can always
+ use a proxy system that "behaves" like the binary, and passes
+ information back and forth from the real program, and snoops
+ in-transit information).
+
+ Good cryptographers need to be involved in this problem to
+ figure out the details and the possible insecure pieces of a
+ proposal like this.
+
+** Implementation: In short
+
+ To keep it short: <b>DNS, JXTA, xmlStorage.</b>
+
+
+** Deploying it
+
+ The implementation of such a system should be a pretty
+ straightforward task once security cryptographers have
+ designed such a beast.
+
+ The major problems are:
+
+ <ul>
+ * <b>People might just not care:</b> In a poll to US
+ citizens a couple of decades ago, it was found that
+ most people did not care about the rights they were
+ given by the Bill of Rights, which lead to a number of
+ laws to be passed in the US that eliminated most of
+ the rights people had.
+
+ * <b>The industry will move way too slow:</b>
+ Microsoft's implementation is out in the open now: it
+ is being deployed, and soon it will be insinuated to
+ many, many users. The industry needs to get together
+ soon if they care about this issue.
+
+ By the time the industry reacts, it might be too
+ late.
+ </ul>
+
+** Passport and Mono
+
+ The .NET class libraries include a Passport class that
+ applications might use to authenticate with Passport. Since
+ we do not have information at this point on the exact protocol
+ of Passport, it is not even feasible to implement it.
+
+ If at some point the information is disclosed, it could be
+ implemented.
+
+ If a competing system to Passport existed, we could probably
+ hide all the authentication information to use a number of
+ different passport-like systems.
+
+ If a user does not want to use Passport at all, he could
+ always turn it off (or completely remove the class from the
+ library). After all, this is free software.
+
+ Currently, we are too far from the point where this is a real
+ issue.
+
+** Passport and endangering Open Source.
+
+ A few people have said: `Mono will allow Passport to be
+ available for Linux and that is bad'. This is plain
+ missinformation.
+
+ Currently, you can obtain Passport for Linux from Microsoft
+ itself and deploy it today on your Web server. Mono does not
+ even enter the picture here. Go to passport.com and download
+ the toolkit and you will see with your own eyes that passport
+ is <B>already</b> available for Linux.
+
+** Disclaimer
+
+ This is just a group of personal thoughts of mine that I have
+ placed here because I get asked this question a lot lately.
+ The views of this page are not a statement from my employer
+ (Ximian, Inc).
+
+ This is not part of Mono. We are not trying to deal with this
+ problem.
+
+ Nat Friedman (Ximian's co-founder) has his own ideas on how a
+ competing system to Passport could be designed, but I will let
+ <a href="http://www.nat.org/">him</a> post his own story.
+
+** Other Alternatives
+
+ Some people have pointed out <a
+ href="http://www.xns.org">XNS</a>
+
+Send comments to me: Miguel de Icaza (<a
+ href="mailto:miguel@ximian.com">miguel@ximian.com</a>)
+
diff --git a/web/pending b/web/pending
new file mode 100644
index 00000000000..e243a10dedf
--- /dev/null
+++ b/web/pending
@@ -0,0 +1,14 @@
+** Microsoft and GNU and Linux.
+
+Q: Does this mean that Microsoft is better than Linux?
+
+A: Many of us are working on <a
+ href="http://www.gnu.org/philosophy/free-sw.html">free software<a>
+ and want to have an <a href="http://www.opensource.org">open
+ source</a> environment that we can change, modify, improve, learn
+ from, and share with others. Some of us also think that this will
+ lead on the long run to better software: more efficient, faster,
+ more robust and more.
+
+ We are willing to take good ideas from any source they come from.
+
diff --git a/web/rationale b/web/rationale
new file mode 100644
index 00000000000..1027d292286
--- /dev/null
+++ b/web/rationale
@@ -0,0 +1,173 @@
+
+* The Mono Project
+
+** Background.
+
+ The GNOME project goal was to bring missing technologies to
+ Unix and make it competitive in the current market place for
+ desktop applications. We also realized early on that language
+ independence was important, and that is why GNOME APIs were
+ coded using a standard that allowed the APIs to be easily
+ wrapped for other languages. Our APIs are available to most
+ programming languages on Unix (Perl, Python, Scheme, C++,
+ Objective-C, Ada).
+
+ Later on we decided to use better methods for encapsulating
+ our APIs, and we started to use CORBA to define interfaces to
+ components. We complemented it with policy and a set of
+ standard GNOME interfaces for easily creating reusable,
+ language independent components, controls and compound
+ documents. This technology is known as <a
+ href="http://www.ximian.com/tech/bonobo.php3">Bonobo</a>.
+ Interfaces to Bonobo exist for C, Perl, Python, and
+ Java.
+
+ CORBA is good when you define coarse interfaces, and most
+ Bonobo interfaces are coarse. The only problem is that
+ Bonobo/CORBA interfaces are not good for small interfaces.
+ For example, an XML parsing Bonobo/CORBA component would be
+ inefficient compared to a C API.
+
+** Another explanation
+
+ I recently explained our motivations to Dave Winer, and he posted
+ it <a
+ href="http://scriptingnews.userland.com/stories/storyReader$1275">here</a>
+
+** Microsoft's .NET
+
+ The Microsoft .NET initiative is confusing because it is a
+ company wide effort that ranges from development tools to end
+ user applications. .NET is a branding formative that
+ has been applied to:
+
+ <ul>
+ * The .NET development platform, a new platform for
+ writing software.
+
+ * Web services.
+
+ * Microsoft Server Applications.
+
+ * New tools that use the new development platform.
+
+ * Hailstorm, the Passport centralized single-signon
+ system that is being integrated into Windows XP.
+
+ </ul>
+
+ Mono is an implementation of the .NET development platform.
+
+** The Common Language Infrastructure platform.
+
+ Microsoft has created a new development platform. The
+ highlights of this new development platform are:
+
+ <ul>
+ * A runtime environment that provides garbage
+ collection, threading and a virtual machine
+ specification (The Virtual Execution System, VES)
+
+ * A comprehensive class library.
+
+ * A new language, C#. Very similar to Java, C#
+ allows programmers to use all the features available
+ on the .NET runtime.
+
+ * A language specification that compilers can
+ follow if they want to generate classes and code
+ that can interoperate with other programming
+ languages (The Common Language Specification: CLS)
+ </ul>
+
+ The Common Language Infrastructure platform is similar to the
+ goals we had in GNOME of giving language independence to
+ programmers. It is more mature, documented, larger in scope,
+ and has a consistent design.
+
+ Any API that is written using a CLS provider language can be
+ used by any language that is a CLS consumer. Compilers
+ generate code in a format called Common Intermediate Language
+ (CIL) which is an intermediate representation of a compiled
+ program and is easy to compile to native code or compiled
+ using Just-in-Time (JIT) engines. The restrictions placed by
+ the runtime on the CIL byte codes ensures that it is possible
+ to do a good job at optimizing the code in a JIT compiler.
+
+ There is not really a lot of innovation in this platform: we
+ have seen all of these concepts before, and we are all
+ familiar with how these things work.
+
+ What makes the Common Language Infrastructure development
+ platform interesting is that it is a good mix of technologies
+ that have been nicely integrated.
+
+ The .NET development platform is essentially a new foundation
+ for program development that gives Microsoft a room to grow
+ for the coming years.
+
+** ECMA standards.
+
+ Microsoft has submitted the
+ specifications of C#, the runtime, the metadata and the
+ other various bits of the .NET development platform to the
+ <a href="http://www.ecma.ch">ECMA</a> for standarization.
+
+ You can get a copy of the specifications submitted to ECMA
+ from: <a href="http://www.dotnetexperts.com/ecma">http://www.dotnetexperts.com/ecma</a>
+
+** Mono: an Open Source Common Language Infrastructure implementation.
+
+ Ximian has begun work on Mono, a project that aims to bring
+ the Common Language Infrastructure platform to free systems.
+
+ When the GNU project was launched, they picked the best
+ operating system that was available out there, and they
+ began to clone it: Unix.
+
+ The .NET development platform is a very rich, powerful, and
+ well designed platform that would help improve the free
+ software development platform. Just like the GNU project
+ began to clone Unix sixteen years ago, we will be cloning the
+ .NET development platform because it is a great platform to
+ build on.
+
+** What makes up Mono?
+
+ There are various pieces that will make up Mono:
+
+ <ul>
+ * A C# compiler.
+
+ * The Virtual Execution System: that will have the
+ Just-in-Time compiler, garbage collector, loader,
+ threading engine.
+
+ A byte code interpreter will be provided for quickly
+ porting Mono to new systems and debugging the JIT
+ purposes, but it is not intended to be the ideal
+ execution environment.
+
+ * An implemenation of the .NET class library.
+
+ * Visual development tools.
+
+ * A CIL GCC frontend.
+ </ul>
+
+** Why use GNOME components?
+
+ GNOME is an umbrella project that consists of infrastructural
+ components (GUI toolkit, XML libraries, CORBA implementation,
+ printing architecture, imaging system), a desktop environment,
+ and productivity applications.
+
+ The GNOME infrastructural components can be used to quickly
+ implement various pieces of the class libraries without reinventing
+ the wheel, and since all those components are licensed under
+ the terms of the GNU LGPL it is a perfect fit.
+
+ Libart will be used to implement the Drawing.2D API; Gtk+ and
+ the GNOME libraries will be used to implement the WinForms
+ API and of course Glib and libxml will be used in various
+ places. \ No newline at end of file
diff --git a/web/release-notes/mono-0.3 b/web/release-notes/mono-0.3
new file mode 100644
index 00000000000..4976037b957
--- /dev/null
+++ b/web/release-notes/mono-0.3
@@ -0,0 +1,46 @@
+To: mono-list@ximian.com, mono-announce-list@ximian.com
+Subject: July 12 snapshots.
+FCC: ~/Mail/outbox.txt
+X-Windows: Sometimes you fill a vacuum and it still sucks.
+--text follows this line--
+
+Hey!
+
+ July 12 snapshots of class libraries, the compiler and the mono
+runtime are available.
+
+New on this release:
+
+ * Runtime (module: mono)
+
+ The beginning of a simple interpreter that Paolo started
+ workign on (can run really simple .NET programs).
+
+ Disassembler copes with more elements of the binary format and
+ more tokens are decoded. Paolo is working now on moving some
+ of these to the metadata library.
+
+ More tables are dumped.
+
+ * Class libraries (module: mcs/class)
+
+ Many new more classes are in from Joe, Vladimir, Jeff, Sean
+ and yours truly.
+
+ Sean fixed the build process, and it is now possible to
+ compile with a single command the assemblies. We will be
+ revisiting this mechanism in the future to compile per-OS
+ assemblies (ie, Unix, Windows, MacOS, etc).
+
+ * Compiler (module mcs/mcs)
+
+ Not much done this week, just a few fixes here and there, and
+ more work to make it easy to compiler.
+
+ * Documentation (module: mono/doc)
+
+ All the changes to the web site are there for your browsing
+ pleasure. We still need to integrate the status system in
+ there.
+
+Miguel.
diff --git a/web/release-notes/mono-0.4 b/web/release-notes/mono-0.4
new file mode 100644
index 00000000000..1d7e1cea5f1
--- /dev/null
+++ b/web/release-notes/mono-0.4
@@ -0,0 +1,43 @@
+To: mono-list@ximian.com
+Subject: Sunday snapshot available.
+Gcc: mail.2001-07
+--text follows this line--
+
+Hey guys,
+
+ I promise I will not be doing these so often once we have the CVS
+server up. In the meantime:
+
+ * MCS
+
+ Sean got the classes to compile in a single go. You
+ will need CygWin (www.cygwin.org) to compile though
+ (GNU make and stuff is required).
+
+ System.Xml.XmlReader contribution from Jason
+ (WOOHHOO!!). It also contains a nice test-suite for
+ his functions, and in his new code bit, his
+ implementation is faster than Microsoft's
+
+ We now ship `jay' as part of the distribution to allow
+ you to compile the compiler with the same `make'
+ command. Small fixes to the parser as well were
+ introduced.
+
+ * Mono 0.4
+
+ Paolo's interpreter supports call instructions and has
+ the test suite program that he posted about.
+
+
+ All documentation ships now in the mono-0.4.tar.gz
+
+Notes:
+
+ As usual, MCS is targeted to be compiled on a Windows machine
+ (you will need Cygwin).
+
+ Mono is targeted to be compiled on a Unix machine or a Windows
+ machine running Cygwin.
+
+Miguel. \ No newline at end of file
diff --git a/web/resources b/web/resources
new file mode 100644
index 00000000000..1e0a361b23e
--- /dev/null
+++ b/web/resources
@@ -0,0 +1,121 @@
+
+* Resources
+
+ There are a number of resources available for those of you who
+ want to contribute to the Mono project. Here are a few links.
+
+ If you want to send suggestions for links, address them to <a
+ mailto="web-mono@ximian.com">web-mono@ximian.com</a>.
+
+** ECMA Documentation.
+
+ You can get the documentation for the ECMA specs from a number of sites:
+ <ul>
+ * <a href="http://msdn.microsoft.com/net/ecma">At MSDN</a>
+ * <a href="http://www.dotnetexperts.com">Dot Net Experts</a>
+ * <a href="http://developer.intel.com/software/idap/ecma">Intel</a>
+ * <a href="http://lightning.csse.monash.edu.au/.net/CLI">Monash University</a>
+ </ul>
+
+ These contain specifications for the assembler, the metadata,
+ byte codes supported by the CLI virtual machine, the C#
+ language and the core class libraries.
+
+ For details on the .NET class libraries, you can
+ visit the Microsoft's Developer Network:
+
+ <ul>
+ * <a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/cpref_start.asp">.NET Framework Class Library</a>
+ </ul>
+
+ You can also get this information if you install the Beta2
+ release of the .NET Framework.
+
+<a name="mailing">
+** Mailing Lists
+
+ There are a number of mailing lists for Mono
+
+ <ul>
+
+ * <b><a
+ href="http://mail.ximian.com/mailman/listinfo/mono-list">mono-list:</a></b>
+ The general Mono discussion list.
+ * <b><a
+ href="http://mail.ximian.com/mailman/listinfo/mono-announce-list">mono-announce-list:</a></b>
+ Announcements of Mono developments.
+ * <b><a
+ href="http://mail.ximian.com/mailman/listinfo/mono-gc-list">mono-gc-list:</a></b>
+ Discussion on the GC system of Mono.
+ * <b><a
+ href="http://mail.ximian.com/mailman/listinfo/mono-cvs-list">mono-cvs-list:</a></b>
+ Track the CVS activity of Mono on this mailing list. You can get <a href="http://www.go-mono.com/snapshots">daily snapshots</a> as well.
+ * <b><a
+ href="http://mail.ximian.com/mailman/listinfo/mono-docs-list">mono-docs-list:</a></b>
+ Discussion on the documentation of Mono.
+ * <b><a
+ href="http://discuss.develop.com/dotnet.html">Dotnet mailing
+ list at Develop.com:</a></b> The guys at Develop Mentor run
+ this general purpose mailing list.
+ </ul>
+
+** Discussion Groups.
+
+ <ul>
+
+ * <a href="http://www.oreillynet.com">O'Reilly
+ Network</a> has a <a
+ href="http://www.oreillynet.com/dotnet">section devoted to
+ .NET</a>
+ * <a
+ href="http://msdn.microsoft.com/newsgroups">MSDN</a> also
+ lists various newsgroups related to .NET</ul>
+ </ul>
+
+** Other .NET related projects
+
+ There are a number of related projects to Mono:
+
+ <ul>
+ * <a
+ href="http://www.icsharpcode.net/OpenSource/SD/default.asp">Sharp
+ Develop:</a> an IDE for the C# language written in C#.
+
+ * <a
+ href="http://janet-js.sourceforge.net/">Janet:</a>
+ an implemention of ECMAScript (the standarized
+ version of JavaScript) in C#
+
+ * <a
+ href="http://www.southern-storm.com.au/portable_net.html">Portable.NET:</a>
+ Another implementation of the CLI and C# compiler.
+
+ * <a href="http://nunit.sourceforge.net">NUnit:</a> A
+ testing framework for .NET classes.
+
+ * <a href="http://www.kaffe.org">Kaffe:</a> A popular
+ Free Software JIT engine for Java.
+
+ * <a href="http://www.intel.com/research/mrl/orp">ORP:</a> A research
+ JIT/VM/GC system from Intel.
+ </ul>
+
+** GNOME Documentation
+
+ Documnetation on GNOME, and the GNOME APIs is available from
+ the <a href="http://developer.gnome.org">developer</a> site at
+ GNOME:
+
+ <ul>
+ * <a href="http://developer.gnome.org/doc/API/">GNOME
+ API documentation</a>
+
+ * <a href="http://developer.gnome.org/doc/books">GNOME
+ Online books</a>
+
+ * <A
+ href="http://developer.gnome.org/arch/">Architecture Overview</a>
+ </ul>
+
+
+ \ No newline at end of file
diff --git a/web/resources-pending b/web/resources-pending
new file mode 100644
index 00000000000..fd9b9073d64
--- /dev/null
+++ b/web/resources-pending
@@ -0,0 +1,30 @@
+** MacOS Documentation
+
+** Assembly Language Manuals online
+ Intel
+ MIPS
+ SPARC
+
+** Microsoft
+ msdn.microsoft.com/net
+ Research.microsoft.com
+
+** Related Technologies
+
+ <ul>
+
+ * The CLI allows people to create Web Services using the SOAP
+ protocol. SOAP is based on XML, XML schemas an the HTTP
+ protocol.
+ <ul>
+ * XML specification.
+ * XML Namespaces.
+ * XML Schemas.
+ * SOAP Specification.
+ </ul>
+ </ul>
+
+** Compiler Information
+ GCC
+ GCC Sample front-end tutorial
+
diff --git a/web/roadmap b/web/roadmap
new file mode 100644
index 00000000000..6cdfa1366a8
--- /dev/null
+++ b/web/roadmap
@@ -0,0 +1,12 @@
+* Roadmap
+
+ We are working on the following three projects at Ximian:
+
+ The C# Compiler (mcs/mcs)
+
+ A .NET compatible Class Library (mcs/class)
+
+ The JIT/interpreter (mono)
+
+
+ \ No newline at end of file
diff --git a/web/runtime b/web/runtime
new file mode 100644
index 00000000000..7217abfa83f
--- /dev/null
+++ b/web/runtime
@@ -0,0 +1,144 @@
+* The Mono runtime
+
+ The Mono runtime will implement the JIT engine (and a byte
+ code interpreter for quickly porting to new systems), the
+ class loader, the garbage collector, threading system and
+ metadata access libraries.
+
+ Currently the runtime has an image loader and metadata access
+ entry points. The runtime comes with a simple interpreter
+ that can execute very simple programs.
+
+** Executing MSIL/CIL images
+
+ The code will load an executable and map the references to
+ external assemblies to our own version of the assemblies on
+ GNU/Linux.
+
+ Our roadmap looks like this, this has been updated as of
+ <b>Jul 15, 2001</b>:
+
+ <ul>
+
+ * Milestone 1: <b> Done</b> Fully read and parse all CIL byte-codes
+ and metadata tokens (ie, a disassembler).
+
+ * Milestone 2: Complete an interpreter for CIL byte
+ codes. This interpreter can be used temporarly to
+ run CIL byte code on a system where no JIT is
+ available.
+
+ * Milestone 3: Define an <i>lburg</i>-like instruction
+ selector for the JITer for Intel. Although slower
+ at JITing than a streaming JITer, it generates
+ better code. The same grammar can later be used for
+ the stream jitter.
+
+ * Milestone 4: Implement JITer.
+
+ * Milestone 5: Port of the JITer to non IA32 systems.
+ </ul>
+
+ A setup similar to the Kaffe JIT engine can be used to
+ layout the code to support non-IA32 architectures. Our work
+ will be focused on getting a IA32 version running first.
+
+ The JIT engine should work on Linux and Win32, although you
+ will need to install the CygWin32 development tools to get a
+ Unix-like compilation environment.
+
+** JIT Engine (<b>updated, Jul 14th, 2001</b>)
+
+ We will be using a code-generator generator approach for our
+ JITer. Given the properties of CIL byte codes, we can take
+ full advantage of a real instruction selector for our code
+ generator.
+
+ There are a couple of books that deal with this technique: "A
+ Retargetable C Compiler" and "Advanced Compiler Design and
+ Implementation" are good references. You can also get a
+ technical description of <a
+ href="http://research.microsoft.com/copyright/accept.asp?path=http://www.research.microsoft.com/~drh/pubs/iburg.pdf&pub=ACM">lbrug</a>
+
+ Previously we had looked at a number of JIT engines and tools,
+ but they would not take full advantage of the CIL properties:
+
+ <ul>
+ * <a
+ href="http://www.intel.com/research/mrl/orp/">ORP</a>
+
+ * <a
+ href="http://www.gnu.org/software/lightning/">GNU
+ Lightning</a>
+
+ * <a href="http://www.eecs.harvard.edu/~nr/toolkit/">NJ Machine
+ Toolkit</a>.).
+
+ * VCODE.
+ </ul>
+
+** Garbage Collection
+
+ We have decided to implement a generational tracing garbage
+ collector, which is very similar to the one being used by
+ .NET. For an introduction to the garbage collection system
+ used by Microsoft's CLR implementation, you can read this book
+ on <a
+ href="http://www.amazon.com/exec/obidos/ASIN/0471941484/o/qid=992556433/sr=2-1/ref=aps_sr_b_1_1/103-5866388-0492603">Garbage
+ Collection.</a>
+
+ Another consideration is to use the same interface that ORP
+ uses to its Garbage Collection system and reuse that GC system
+ instead of rolling our own, as the ORP system is pretty advanced
+ and is independent of the rest of ORP.
+
+ Although using a conservative garbage collector like Bohem's
+ would work, all the type information is available at runtime,
+ so we can actually implement a better collector than a
+ conservative collector.
+
+ <ul>
+ * Garbage collection list and FAQ:<br>
+ <a href="http://www.iecc.com/gclist/">http://www.iecc.com/gclist/</a>
+
+ * "GC points in a Threaded Environment":<br>
+ <a href="http://research.sun.com/techrep/1998/abstract-70.html">
+ http://research.sun.com/techrep/1998/abstract-70.html</a>
+
+ * "A Generational Mostly-concurrent Garbage Collector":
+ <a href="http://research.sun.com/techrep/2000/abstract-88.html">
+ http://research.sun.com/techrep/2000/abstract-88.html</a>
+
+ * Details on The Microsoft .NET Garbage Collection Implementation:<br>
+ <a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnmag00/html/GCI.asp">http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnmag00/html/GCI.asp</a>
+ <a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnmag00/html/GCI2.asp">http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnmag00/html/GCI2.asp</a>
+ </ul>
+
+** Useful links
+
+ Paolo Molaro found a few interesting links:
+
+ <ul>
+ * On compilation of stack-based languages:<br>
+ <a href="http://www.complang.tuwien.ac.at/projects/rafts.html">
+ http://www.complang.tuwien.ac.at/projects/rafts.html</a>
+
+ * A paper on fast JIT compilation of a stack-based language:<br>
+ <a href="http://www.research.microsoft.com/~cwfraser/pldi99codegen.pdf">
+ http://www.research.microsoft.com/~cwfraser/pldi99codegen.pdf</a>
+
+ * Vmgen generates much of the code for efficient virtual machine (VM)
+ interpreters from simple descriptions of the VM instructions:<br>
+ <a href="http://www.complang.tuwien.ac.at/anton/vmgen/">
+ http://www.complang.tuwien.ac.at/anton/vmgen</a>
+ </ul>
+
+** PInvoke
+
+ PInvoke is the mechanism we are using to wrap Unix API calls
+ as well as talking to system libraries.
+
+ We hvae implemented PInvoke through libffi, but we are likely
+ going to roll our own system as the runtime matures, specially
+ as the interpreter is approaching completion, and we move into
+ the JITer.
diff --git a/web/status b/web/status
new file mode 100644
index 00000000000..d2e09c7e837
--- /dev/null
+++ b/web/status
@@ -0,0 +1,38 @@
+* Project Status
+
+
+ Pieces of Mono that have been implemented:
+
+ <ul>
+ * C# compiler: The C# parser can now generate parse
+ trees. Next up: semantic analysis, compiler lever optimizations
+ and code generation.
+
+ * Metadata library: Can currently parse and load
+ information from .NET modules (executables and DLL
+ files).
+
+ Parsing of Exception tables is missing.
+
+ * Disassembler: Can disassemble .NET modules. Still
+ lacking exception handling as well as useful debugging
+ tools (hex dumping, token dumping).
+
+ * Class Libraries: You can check the current status in the
+ <a href="class-status.html">Class Status page</a>
+ </ul>
+
+ Tasks on the critical path:
+
+ <ul>
+ * Bytecode interpreter: (Paolo is working on this).
+
+ * Simple JIT: Not implemented yet (Miguel is
+ researching the code-generator generator)
+
+ * Garbage collection engine (Dick is working on this, his contact is <a
+ href="mailto:dick@ximian.com">dick@ximian.com</a>
+ </ul>
+
+ If you want to work on any task here, please mail <a
+ href="mailto:mono-list@ximian.com">mono-list@ximian.com</a>
diff --git a/web/team b/web/team
new file mode 100644
index 00000000000..eff7bc9d3d5
--- /dev/null
+++ b/web/team
@@ -0,0 +1,2 @@
+* The MonoNet Team
+
diff --git a/web/testing b/web/testing
new file mode 100644
index 00000000000..febabf6550e
--- /dev/null
+++ b/web/testing
@@ -0,0 +1,21 @@
+* Testing
+
+ All classes in Mono libraries should have comprehensive unit test
+ suites to go with them. Unit testing is a software engineering
+ methodology that makes it easier to build correct code. Every
+ method in every class should have a set of tests to verify
+ that they work correctly. Mono also needs a testing framework
+ to make it easy to write and run lots of tests.
+
+ Try <a href="http://nunit.sourceforge.net">NUnit</a>
+
+ Why do unit testing? It becomes simple to run automated tests
+ for the whole library. Unit tests are a safety net - you can
+ change part of the code and verify that you haven't broken
+ anything. Ideally, tests are written before the actual library
+ code itself. And every time a bug is discovered, a test should
+ be written to demonstrate the bug and its fix. Then, if
+ you ever reintroduce the bug, you will know immediately. For
+ more info, read <a
+ href="http://nunit.sourceforge.net/doc/testinfected/testing.html">
+ JUnit Test Infected: Programmers Love Writing Tests</a>.
diff --git a/web/thanks b/web/thanks
new file mode 100644
index 00000000000..5f2df36f9cd
--- /dev/null
+++ b/web/thanks
@@ -0,0 +1,6 @@
+* Thanks
+
+ We would like to thank Tim O'Reilly, Brian Jepson and Nathan
+ Torkington for their help.
+
+ Dave Winer for provided interesting comments and a to read.
diff --git a/web/todo b/web/todo
new file mode 100644
index 00000000000..abae8cdfb40
--- /dev/null
+++ b/web/todo
@@ -0,0 +1 @@
+Discuss with write new JIT \ No newline at end of file
diff --git a/web/tools b/web/tools
new file mode 100644
index 00000000000..eabef48bb88
--- /dev/null
+++ b/web/tools
@@ -0,0 +1,67 @@
+* Tools
+
+ We need a number of tools to make people productive using a
+ Mono-based solution. Some of these tools can be developed on
+ Windows before Mono is fully finished.
+
+ All of these tools should be written using C#.
+
+ For the tools that are typically command line tools: Try to
+ write these as components that could load their input from
+ streams or collections of streams, and implement the command
+ line tools as wrappers around those classes.
+
+ For example, we will be making the C# compiler a component
+ that could be reused by applications that might have a use for
+ the various bits of the compiler (either to embed the
+ compiler, or reuse the code generator part of it).
+
+ This is important so that these components (compiler,
+ assembler, linker, etc) can be integrated later into the
+ visual development environment (hopefully with the help of the
+ SharpDevelop hackers).
+
+TODO=ilasm,IL Assembler
+** IL Assembler.
+
+ This assembler should basically take as input a file
+ containing IL bytecodes as specified in the `Partition II' of
+ the ECMA spec, and produce a binary file.
+
+TODO=al,Assembly Linker
+** Assembly Linker.
+
+ This tool is used to construct assemblies, which are basically
+ deployment units for CLI executables.
+
+TODO=debugger,Debugger
+** Debugger
+
+ We will need a debugging API to debug CLI applications and
+ then a debugger component that can be used in an IDE
+ environment.
+
+TODO=ide,Integrated Development Environment
+** Integrated Development Environment
+
+ There is already a project to create a C# development
+ environment: <a
+ href="http://www.icsharpcode.net/OpenSource/SD/default.asp">SharpDevelop</a>.
+ People should work with the SharpDevelop hackers to produce a
+ unified development environment.
+
+ Please work with the SharpDevelop hackers to build a good IDE.
+ We will work on creating an embedable compiler component and
+ an embeddable debugger component that can be used withing
+ SharpDevelop
+
+TODO=hbrowser,Help Browser
+** Help Browser
+
+ We need a good help browser that can be used to browse
+ documentation. Ideally this help browser can accept as input
+ XML Docbook input and an assorted set of file formats
+ (Microsoft Help, Unix manual pages, Unix Info pages)
+
+ Look at the GNOME DevHelp for a good set of ideas on how to
+ implement this. \ No newline at end of file
diff --git a/web/web/.cvsignore b/web/web/.cvsignore
new file mode 100644
index 00000000000..a023a6f9c7c
--- /dev/null
+++ b/web/web/.cvsignore
@@ -0,0 +1,2 @@
+*.src
+*.html
diff --git a/web/web/commands b/web/web/commands
new file mode 100644
index 00000000000..4184a72fecb
--- /dev/null
+++ b/web/web/commands
@@ -0,0 +1,17 @@
+0,Home,index.html,index.src
+1,FAQ,faq.html,faq.src
+0,Mono,rationale.html,rationale.src
+1,Runtime,runtime.html,runtime.src
+1,Classes,class-library.html,class-library.src
+2,Class Status,class-status.html,class-status.src
+1,C# Compiler,c-sharp.html,c-sharp.src
+1,Status,status.html,status.src
+0,Contributing,contributing.html,contributing.src
+1,Documentation,documentation.html,documentation.src
+1,Test Suite,testing.html,testing.src
+1,Tools,tools.html,tools.src
+0,Download,download.html,download.src
+0,Resources,resources.html,resources.src
+1,Ideas,ideas.html,ideas.src
+1,Passport,passport.html,passport.src
+0,Contact,contact.html,contact.src
diff --git a/web/web/htmlify b/web/web/htmlify
new file mode 100644
index 00000000000..a2b2706f16e
--- /dev/null
+++ b/web/web/htmlify
@@ -0,0 +1,26 @@
+#!/usr/bin/perl
+$q = 1;
+
+while (<>){
+ chop;
+ if (/^\* (.*)$/){
+ print "<h1>$1</h1>\n";
+ } elsif (/^\*\* (.*)$/) {
+ print "<h2>$1</h2>\n";
+ } elsif (/^\*\*\* (.*)$/) {
+ print "<h3>$1</h3>\n";
+ } elsif (/^$/) {
+ print "<p>\n";
+ } elsif (/^\t\t\* (.*)$/) {
+ print "<li>$1\n";
+ } elsif (/^Q: (.*)$/){
+ print "<p><a name=\"q$q\"></a><b>Question $q:</b> $1\n";
+ $q++;
+ } elsif (/^A: (.*)$/){
+ print "$1\n";
+ } elsif (/^TODO=(.*),$/){
+ print "<a name=\"$1\">\n";
+ } else {
+ print "$_\n";
+ }
+}
diff --git a/web/web/images/bgsquares.gif b/web/web/images/bgsquares.gif
new file mode 100644
index 00000000000..864bcd44038
--- /dev/null
+++ b/web/web/images/bgsquares.gif
Binary files differ
diff --git a/web/web/images/bgsquares.png b/web/web/images/bgsquares.png
new file mode 100644
index 00000000000..54de2ad1e6d
--- /dev/null
+++ b/web/web/images/bgsquares.png
Binary files differ
diff --git a/web/web/images/bgsquares.xcf.gz b/web/web/images/bgsquares.xcf.gz
new file mode 100644
index 00000000000..200b5805615
--- /dev/null
+++ b/web/web/images/bgsquares.xcf.gz
Binary files differ
diff --git a/web/web/images/mono.gif b/web/web/images/mono.gif
new file mode 100644
index 00000000000..298976a07b7
--- /dev/null
+++ b/web/web/images/mono.gif
Binary files differ
diff --git a/web/web/images/mono.png b/web/web/images/mono.png
new file mode 100644
index 00000000000..a19e38acedd
--- /dev/null
+++ b/web/web/images/mono.png
Binary files differ
diff --git a/web/web/images/pixel.gif b/web/web/images/pixel.gif
new file mode 100644
index 00000000000..a4f37d7e02e
--- /dev/null
+++ b/web/web/images/pixel.gif
Binary files differ
diff --git a/web/web/images/pixel.png b/web/web/images/pixel.png
new file mode 100644
index 00000000000..d8f33a2a3e4
--- /dev/null
+++ b/web/web/images/pixel.png
Binary files differ
diff --git a/web/web/makefile b/web/web/makefile
new file mode 100644
index 00000000000..1e549a40c3a
--- /dev/null
+++ b/web/web/makefile
@@ -0,0 +1,39 @@
+SOURCES= \
+ ../contributing \
+ ../class-library \
+ ../class-status \
+ ../contact \
+ ../c-sharp \
+ ../documentation \
+ ../download \
+ ../faq \
+ ../gcc-frontend \
+ ../index \
+ ../ideas \
+ ../passport \
+ ../rationale \
+ ../resources \
+ ../roadmap \
+ ../runtime \
+ ../status \
+ ../testing \
+ ../tools
+
+all:
+ -mkdir site
+ for i in $(SOURCES); do \
+ perl htmlify $$i > `basename $$i`.src; \
+ done;
+
+ perl process.pl commands template.html.in .
+
+clean:
+ for i in $(SOURCES); do \
+ rm -f `basename $$i`.src `basename $$i`.html; \
+ done;
+
+push:
+ scp *.html www@www.ximian.com:/web/cvsmodules/mono
+
+push2:
+ scp *.html primates:public_html/xxx
diff --git a/web/web/process.pl b/web/web/process.pl
new file mode 100755
index 00000000000..157ae9bb08f
--- /dev/null
+++ b/web/web/process.pl
@@ -0,0 +1,73 @@
+#!/usr/bin/perl
+#
+# Author:
+# Sean MacIsaac
+#
+
+use strict;
+
+my $full_expand = 1;
+my @template;
+my $n;
+
+if ($#ARGV != 2) {
+ print "process.pl command_file template_file directory_prefix\n";
+ exit ();
+}
+
+my $menu = "";
+
+open COMMANDS, $ARGV[0] || die "Can not open $ARGV[0]";
+while (<COMMANDS>) {
+ chop;
+ my @command = split /,/;
+ if ($command[0] != -1) {
+ $menu .= "\t\t";
+ if ($command[0] == 0){
+ $menu .= "<tr><td valign=\"top\" class=\"navi\"><a class=\"navi\"";
+ } else {
+ $menu .= "<tr><td valign=\"top\" class=\"subnavi\">&nbsp;&nbsp;&nbsp<a class=\"subnavi\"";
+ }
+ $menu .= "HREF=\"$command[2]\">$command[1]</A></td></tr>\n\n";
+ }
+}
+close COMMANDS;
+
+open TEMPLATE, $ARGV[1] || die "Can not open $ARGV[1]";
+while (<TEMPLATE>) {
+ push @template, $_;
+}
+close TEMPLATE;
+
+open COMMANDS, $ARGV[0] || die "Can not open $ARGV[0]";
+while (<COMMANDS>) {
+ chop;
+ my @command = split /,/;
+
+ $n = $ARGV[2] . "/" . $command[2];
+ open OUTPUT, ">" . $n || die "Can not create $n";
+
+ my $content = "";
+ open INPUT, $command[3] || die "Can not open $command[3]";
+ while (<INPUT>) {
+ $content .= $_;
+ }
+ close INPUT;
+
+ my $line;
+ my $temp;
+ my $tit;
+ my $title;
+
+ $tit = $command[1];
+ foreach $line (@template) {
+ $temp = $line;
+ $title = "$tit / Mono";
+ $temp =~ s/#TITLE#/$title/;
+ $temp =~ s/#CONTENT#/$content/;
+ $temp =~ s/#MENU#/$menu/;
+ print OUTPUT $temp;
+ }
+
+ close OUTPUT;
+}
diff --git a/web/web/template.html.in b/web/web/template.html.in
new file mode 100644
index 00000000000..7afdfca4a1b
--- /dev/null
+++ b/web/web/template.html.in
@@ -0,0 +1,78 @@
+<html>
+<head>
+<title>#TITLE#</title>
+<style type="text/css">
+<!--
+ body { font-family: "trebuchet ms", lucida, verdana, helvetica;
+ background-image: url("images/bgsquares.gif");
+ background-attachment: fixed; }
+ body, td, table { font-family: "trebuchet ms", lucida, verdana, helvetica;
+ font-size: 12px; }
+
+ .navi { font-size: 14px; background: #444444; }
+ .subnavi { font-size: 12px; }
+ .footnote { font-size: 10px; color: #aaaaaa; }
+
+ a.navi { color: #ffffff; text-decoration: none; font-weight: bold; }
+ a.navi:visited { color: #cccccc; }
+ a.navi:hover { color: #ee9900; text-decoration: underline; }
+
+ a.subnavi { color: #ffffff; text-decoration: none; font-weight: bold; }
+ a.subnavi:visited { color: #cccccc; }
+ a.subnavi:hover { color: #ee9900; text-decoration: underline; }
+
+// -->
+</style>
+</head>
+<body bgcolor="#555555" text="#000000">
+
+<table cellpadding="0" cellspacing="0" border="0" width="100%">
+ <tr>
+ <td><img src="images/pixel.gif"></td><!-- left border -->
+ <td colspan="4">
+ <a href="/"><img src="images/mono.gif" border="0"></a></td>
+ <td><img src="images/pixel.gif"></td><!-- right border -->
+ </tr>
+ <tr>
+ <td><img src="images/pixel.gif" width="1" height="1"></td>
+ <td colspan="3" bgcolor="black"><img src="images/pixel.gif" height="2"></td>
+ <td bgcolor="black"><img src="images/pixel.gif" width="1"></td>
+ <td><img src="images/pixel.gif"></td>
+ </tr>
+ <tr>
+ <td width="100"><img src="images/pixel.gif"></td>
+ <td valign="top">
+ <table cellpadding="2" valign="top" cellspacing="0" border="0">
+ #MENU#
+ </table>
+ </td>
+ <td bgcolor="black" width="1"><img src="images/pixel.gif" width="1"></td>
+ <td bgcolor="white" align="left" width="80%" valign="top">
+ <table cellpadding="16">
+ <tr><td>
+ #CONTENT#
+ </td></tr>
+ </table>
+ </td>
+ <td bgcolor="black"><img src="images/pixel.gif" width="1"></td>
+ <td width="100"><img src="images/pixel.gif"></td>
+ </tr>
+ <tr>
+ <td colspan="2">
+ <img src="images/pixel.gif"></td>
+ <td colspan="2" bgcolor="black"><img src="images/pixel.gif" height="1"></td>
+ <td bgcolor="black"><img src="images/pixel.gif" width="1"></td>
+ <td><img src="images/pixel.gif"></td>
+ </tr>
+
+ <td colspan="2"></td>
+ <td colspan="2" align="center">
+ <a class="footnote" href="mailto: webmaster@go-mono.com">webmaster@go-mono.com</a>
+ </td>
+ <td colspan="2"></td>
+ </tr>
+</tr>
+</table>
+
+</body>
+</html>