csdoc-patches Mailing List for C Sharp Document Generator (XML/HTML) (Page 3)
Status: Planning
Brought to you by:
mastergaurav
You can subscribe to this list here.
2003 |
Jan
|
Feb
(46) |
Mar
(17) |
Apr
(11) |
May
|
Jun
|
Jul
|
Aug
|
Sep
(1) |
Oct
|
Nov
|
Dec
|
---|---|---|---|---|---|---|---|---|---|---|---|---|
2004 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
(65) |
Nov
(17) |
Dec
|
From: <mas...@us...> - 2004-10-07 00:18:23
|
Update of /cvsroot/csdoc/csdoc/src/mcs/build/profiles In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv24956/profiles Log Message: Directory /cvsroot/csdoc/csdoc/src/mcs/build/profiles added to the repository |
From: <mas...@us...> - 2004-10-06 19:58:57
|
Update of /cvsroot/csdoc/csdoc/src/mcs In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv26927 Added Files: makefile Log Message: makefile: Updated |
From: <mas...@us...> - 2004-10-06 19:57:41
|
Update of /cvsroot/csdoc/csdoc/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv26612 Modified Files: makefile Log Message: makefile: Updated Index: makefile =================================================================== RCS file: /cvsroot/csdoc/csdoc/src/makefile,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** makefile 19 Feb 2003 05:48:39 -0000 1.2 --- makefile 6 Oct 2004 19:57:32 -0000 1.3 *************** *** 1,15 **** ! DIRS=jay nant mcs csdoc INSTALL= /usr/bin/install ! all: linux ! ! # if test x$(OS) = xWindows_NT; then make linux; else make -f makefile.gnu; fi ! ! install: ! if test x$(OS) = xWindows_NT; then make windowsinstall; else make -f makefile.gnu install; fi ! linux: for i in $(DIRS); do \ ! (cd $$i; make linux) || exit 1; \ done --- 1,10 ---- ! DIRS=mcs nant csdoc INSTALL= /usr/bin/install ! all: default ! default: for i in $(DIRS); do \ ! (cd $$i; make) || exit 1; \ done |
From: <mas...@us...> - 2004-10-06 19:42:22
|
Update of /cvsroot/csdoc/csdoc/src/mcsdoc In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv23270/mcsdoc Log Message: Directory /cvsroot/csdoc/csdoc/src/mcsdoc added to the repository |
From: <mas...@us...> - 2004-10-06 19:32:19
|
Update of /cvsroot/csdoc/csdoc/src/mcs/class/Mono.CSharp.Debugger In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv20667/Mono.CSharp.Debugger Added Files: MonoSymbolFile.cs MonoSymbolTable.cs MonoSymbolWriter.cs Log Message: no message --- NEW FILE: MonoSymbolFile.cs --- // // Mono.CSharp.Debugger/MonoSymbolFile.cs // // Author: // Martin Baulig (ma...@xi...) // // (C) 2003 Ximian, Inc. http://www.ximian.com // // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using System.Reflection; using System.Collections; using System.Text; using System.Threading; using System.IO; namespace Mono.CompilerServices.SymbolWriter { public class MonoSymbolFileException : Exception { public MonoSymbolFileException () : base () { } public MonoSymbolFileException (string message, params object[] args) : base (String.Format (message, args)) { } } internal class MyMemoryStream : Stream { int length; int real_length; int position; int chunk_size = 4096; ArrayList chunks = new ArrayList (); private struct Chunk { public readonly int Offset; public readonly int Length; public byte[] Buffer; public Chunk (int offset, int length) { this.Offset = offset; this.Length = length; this.Buffer = new Byte [length]; } } public override long Position { get { return position; } set { if (value > length) throw new ArgumentOutOfRangeException (); position = (int) value; } } public override long Length { get { return length; } } public override bool CanRead { get { return true; } } public override bool CanWrite { get { return true; } } public override bool CanSeek { get { return true; } } public override void SetLength (long new_length) { if (new_length < length) throw new ArgumentException (); while (new_length >= real_length) { Chunk new_chunk = new Chunk (real_length, chunk_size); chunks.Add (new_chunk); real_length += chunk_size; } length = (int) new_length; } public override void Flush () { } public override long Seek (long offset, SeekOrigin origin) { int ref_point; switch (origin) { case SeekOrigin.Begin: ref_point = 0; break; case SeekOrigin.Current: ref_point = position; break; case SeekOrigin.End: ref_point = length; break; default: throw new ArgumentException ("Invalid SeekOrigin"); } if ((ref_point + offset < 0) || (offset > real_length)) throw new ArgumentOutOfRangeException (); position = ref_point + (int) offset; return position; } Chunk FindChunk (int offset) { return (Chunk) chunks [offset / chunk_size]; } public override int Read (byte[] buffer, int offset, int count) { int old_count = count; while (count > 0) { Chunk chunk = FindChunk (position); int coffset = position - chunk.Offset; int rest = chunk.Length - coffset; int size = System.Math.Min (count, rest); Array.Copy (chunk.Buffer, coffset, buffer, offset, size); position += size; offset += size; count -= size; } return old_count; } public override void Write (byte[] buffer, int offset, int count) { if (position + count > length) SetLength (position + count); while (count > 0) { Chunk chunk = FindChunk (position); int coffset = position - chunk.Offset; int rest = chunk.Length - coffset; int size = System.Math.Min (count, rest); Array.Copy (buffer, offset, chunk.Buffer, coffset, size); position += size; offset += size; count -= size; } } public byte[] GetContents () { byte[] retval = new byte [length]; position = 0; Read (retval, 0, length); return retval; } } internal class MyBinaryWriter : BinaryWriter { public MyBinaryWriter (Stream stream) : base (stream) { } public void WriteLeb128 (int value) { base.Write7BitEncodedInt (value); } } internal class MyBinaryReader : BinaryReader { public MyBinaryReader (Stream stream) : base (stream) { } public int ReadLeb128 () { return base.Read7BitEncodedInt (); } } public class MonoDebuggerSupport { static GetTypeFunc get_type; static GetMethodTokenFunc get_method_token; static GetMethodFunc get_method; static GetLocalTypeFromSignatureFunc local_type_from_sig; static GetGuidFunc get_guid; static CheckRuntimeVersionFunc check_runtime_version; delegate Type GetTypeFunc (Assembly assembly, int token); delegate int GetMethodTokenFunc (Assembly assembly, MethodBase method); delegate MethodBase GetMethodFunc (Assembly assembly, int token); delegate Type GetLocalTypeFromSignatureFunc (Assembly assembly, byte[] sig); delegate Guid GetGuidFunc (Module module); delegate string CheckRuntimeVersionFunc (string filename); static Delegate create_delegate (Type type, Type delegate_type, string name) { MethodInfo mi = type.GetMethod (name, BindingFlags.Static | BindingFlags.NonPublic); if (mi == null) throw new Exception ("Can't find " + name); return Delegate.CreateDelegate (delegate_type, mi); } static MonoDebuggerSupport () { get_type = (GetTypeFunc) create_delegate ( typeof (Assembly), typeof (GetTypeFunc), "MonoDebugger_GetType"); get_method_token = (GetMethodTokenFunc) create_delegate ( typeof (Assembly), typeof (GetMethodTokenFunc), "MonoDebugger_GetMethodToken"); get_method = (GetMethodFunc) create_delegate ( typeof (Assembly), typeof (GetMethodFunc), "MonoDebugger_GetMethod"); local_type_from_sig = (GetLocalTypeFromSignatureFunc) create_delegate ( typeof (Assembly), typeof (GetLocalTypeFromSignatureFunc), "MonoDebugger_GetLocalTypeFromSignature"); get_guid = (GetGuidFunc) create_delegate ( typeof (Module), typeof (GetGuidFunc), "Mono_GetGuid"); check_runtime_version = (CheckRuntimeVersionFunc) create_delegate ( typeof (Assembly), typeof (CheckRuntimeVersionFunc), "MonoDebugger_CheckRuntimeVersion"); } public static Type GetType (Assembly assembly, int token) { return get_type (assembly, token); } public static int GetMethodToken (MethodBase method) { return get_method_token (method.ReflectedType.Assembly, method); } public static MethodBase GetMethod (Assembly assembly, int token) { return get_method (assembly, token); } public static Type GetLocalTypeFromSignature (Assembly assembly, byte[] sig) { return local_type_from_sig (assembly, sig); } public static string CheckRuntimeVersion (string filename) { return check_runtime_version (filename); } public static Guid GetGuid (Module module) { return get_guid (module); } } public class MonoSymbolFile : IDisposable { ArrayList methods = new ArrayList (); ArrayList sources = new ArrayList (); Hashtable method_source_hash = new Hashtable (); Hashtable type_hash = new Hashtable (); OffsetTable ot; int last_type_index; int last_method_index; int last_source_index; int last_namespace_index; public int NumLineNumbers; public MonoSymbolFile () { } internal int AddSource (SourceFileEntry source) { sources.Add (source); return ++last_source_index; } internal int DefineType (Type type) { if (type_hash.Contains (type)) return (int) type_hash [type]; int index = ++last_type_index; type_hash.Add (type, index); return index; } internal void AddMethod (MethodEntry entry) { methods.Add (entry); } internal int GetNextTypeIndex () { return ++last_type_index; } internal int GetNextMethodIndex () { return ++last_method_index; } internal int GetNextNamespaceIndex () { return ++last_namespace_index; } byte [] stringBuffer; int maxCharsPerRound; static Encoding enc = Encoding.UTF8; internal string ReadString (int offset) { int old_pos = (int) reader.BaseStream.Position; reader.BaseStream.Position = offset; string text = reader.ReadString (); reader.BaseStream.Position = old_pos; return text; } void Write (MyBinaryWriter bw, Guid guid) { // Magic number and file version. bw.Write (OffsetTable.Magic); bw.Write (OffsetTable.Version); bw.Write (guid.ToByteArray ()); // // Offsets of file sections; we must write this after we're done // writing the whole file, so we just reserve the space for it here. // long offset_table_offset = bw.BaseStream.Position; ot.Write (bw); // // Write data sections. // ot.DataSectionOffset = (int) bw.BaseStream.Position; foreach (SourceFileEntry source in sources) source.WriteData (bw); ot.DataSectionSize = (int) bw.BaseStream.Position - ot.DataSectionOffset; // // Write out the method index // ot.MethodTableOffset = (int) bw.BaseStream.Position; for (int i = 0; i < methods.Count; i++) { MethodEntry entry = (MethodEntry) methods [i]; entry.WriteIndex (bw); } ot.MethodTableSize = (int) bw.BaseStream.Position - ot.MethodTableOffset; // // Write source table. // ot.SourceTableOffset = (int) bw.BaseStream.Position; for (int i = 0; i < sources.Count; i++) { SourceFileEntry source = (SourceFileEntry) sources [i]; source.Write (bw); } ot.SourceTableSize = (int) bw.BaseStream.Position - ot.SourceTableOffset; // // Fixup offset table. // ot.TypeCount = last_type_index; ot.MethodCount = methods.Count; ot.SourceCount = sources.Count; // // Write offset table. // ot.TotalFileSize = (int) bw.BaseStream.Position; bw.Seek ((int) offset_table_offset, SeekOrigin.Begin); ot.Write (bw); bw.Seek (0, SeekOrigin.End); } public byte[] CreateSymbolFile (Guid guid) { if (reader != null) throw new InvalidOperationException (); using (MyMemoryStream stream = new MyMemoryStream ()) { Write (new MyBinaryWriter (stream), guid); return stream.GetContents (); } } Assembly assembly; MyBinaryReader reader; Hashtable method_hash; Hashtable source_file_hash; Hashtable method_token_hash; Hashtable source_name_hash; protected MonoSymbolFile (string filename, Assembly assembly) { this.assembly = assembly; FileStream stream = new FileStream (filename, FileMode.Open, FileAccess.Read); reader = new MyBinaryReader (stream); Guid guid; try { long magic = reader.ReadInt64 (); long version = reader.ReadInt32 (); if (magic != OffsetTable.Magic) throw new MonoSymbolFileException ( "Symbol file `{0}' is not a valid " + "Mono symbol file", filename); if (version != OffsetTable.Version) throw new MonoSymbolFileException ( "Symbol file `{0}' has version {1}, " + "but expected {2}", filename, version, OffsetTable.Version); guid = new Guid (reader.ReadBytes (16)); ot = new OffsetTable (reader); } catch { throw new MonoSymbolFileException ( "Cannot read symbol file `{0}'", filename); } Module[] modules = assembly.GetModules (); Guid assembly_guid = MonoDebuggerSupport.GetGuid (modules [0]); if (guid != assembly_guid) throw new MonoSymbolFileException ( "Symbol file `{0}' does not match assembly `{1}'", filename, assembly.Location); method_hash = new Hashtable (); source_file_hash = new Hashtable (); } public static MonoSymbolFile ReadSymbolFile (Assembly assembly) { string filename = assembly.Location; string name = filename + ".mdb"; return new MonoSymbolFile (name, assembly); } public Assembly Assembly { get { return assembly; } } public int SourceCount { get { return ot.SourceCount; } } public int MethodCount { get { return ot.MethodCount; } } public int TypeCount { get { return ot.TypeCount; } } public int NamespaceCount { get { return last_namespace_index; } } internal int LineNumberCount = 0; internal int LocalCount = 0; internal int StringSize = 0; public SourceFileEntry GetSourceFile (int index) { if ((index < 1) || (index > ot.SourceCount)) throw new ArgumentException (); if (reader == null) throw new InvalidOperationException (); SourceFileEntry source = (SourceFileEntry) source_file_hash [index]; if (source != null) return source; reader.BaseStream.Position = ot.SourceTableOffset + SourceFileEntry.Size * (index - 1); source = new SourceFileEntry (this, reader); source_file_hash.Add (index, source); return source; } public SourceFileEntry[] Sources { get { if (reader == null) throw new InvalidOperationException (); SourceFileEntry[] retval = new SourceFileEntry [SourceCount]; for (int i = 0; i < SourceCount; i++) retval [i] = GetSourceFile (i + 1); return retval; } } public MethodIndexEntry GetMethodIndexEntry (int index) { int old_pos = (int) reader.BaseStream.Position; reader.BaseStream.Position = ot.MethodTableOffset + MethodIndexEntry.Size * (index - 1); MethodIndexEntry ie = new MethodIndexEntry (reader); reader.BaseStream.Position = old_pos; return ie; } public MethodEntry GetMethodByToken (int token) { if (reader == null) throw new InvalidOperationException (); if (method_token_hash == null) { method_token_hash = new Hashtable (); for (int i = 0; i < MethodCount; i++) { MethodIndexEntry ie = GetMethodIndexEntry (i + 1); method_token_hash.Add (ie.Token, i + 1); } } object value = method_token_hash [token]; if (value == null) return null; return GetMethod ((int) value); } public MethodEntry GetMethod (MethodBase method) { if (reader == null) throw new InvalidOperationException (); int token = MonoDebuggerSupport.GetMethodToken (method); return GetMethodByToken (token); } public MethodEntry GetMethod (int index) { if ((index < 1) || (index > ot.MethodCount)) throw new ArgumentException (); if (reader == null) throw new InvalidOperationException (); MethodEntry entry = (MethodEntry) method_hash [index]; if (entry != null) return entry; MethodIndexEntry ie = GetMethodIndexEntry (index); reader.BaseStream.Position = ie.FileOffset; entry = new MethodEntry (this, reader, index); method_hash.Add (index, entry); return entry; } public MethodEntry[] Methods { get { if (reader == null) throw new InvalidOperationException (); MethodEntry[] retval = new MethodEntry [MethodCount]; for (int i = 0; i < MethodCount; i++) retval [i] = GetMethod (i + 1); return retval; } } public MethodSourceEntry GetMethodSource (int index) { if ((index < 1) || (index > ot.MethodCount)) throw new ArgumentException (); if (reader == null) throw new InvalidOperationException (); object entry = method_source_hash [index]; if (entry != null) return (MethodSourceEntry) entry; MethodEntry method = GetMethod (index); foreach (MethodSourceEntry source in method.SourceFile.Methods) { if (source.Index == index) { method_source_hash.Add (index, source); return source; } } throw new MonoSymbolFileException ("Internal error."); } public int FindSource (string file_name) { if (reader == null) throw new InvalidOperationException (); if (source_name_hash == null) { source_name_hash = new Hashtable (); for (int i = 0; i < ot.SourceCount; i++) { SourceFileEntry source = GetSourceFile (i + 1); source_name_hash.Add (source.FileName, i); } } object value = source_name_hash [file_name]; if (value == null) return -1; return (int) value; } internal MyBinaryReader BinaryReader { get { if (reader == null) throw new InvalidOperationException (); return reader; } } void IDisposable.Dispose () { Dispose (true); } protected virtual void Dispose (bool disposing) { if (disposing) { if (reader != null) { reader.Close (); reader = null; } } } } } --- NEW FILE: MonoSymbolTable.cs --- // // Mono.CSharp.Debugger/MonoSymbolTable.cs // // Author: // Martin Baulig (ma...@xi...) // // (C) 2002 Ximian, Inc. http://www.ximian.com // // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using System.Collections; using System.Text; using System.IO; // // Parts which are actually written into the symbol file are marked with // // #region This is actually written to the symbol file // #endregion // // Please do not modify these regions without previously talking to me. // // All changes to the file format must be synchronized in several places: // // a) The fields in these regions (and their order) must match the actual // contents of the symbol file. // // This helps people to understand the symbol file format without reading // too much source code, ie. you look at the appropriate region and then // you know what's actually in the file. // // It is also required to help me enforce b). // // b) The regions must be kept in sync with the unmanaged code in // mono/metadata/debug-mono-symfile.h // // When making changes to the file format, you must also increase two version // numbers: // // i) OffsetTable.Version in this file. // ii) MONO_SYMBOL_FILE_VERSION in mono/metadata/debug-mono-symfile.h // // After doing so, recompile everything, including the debugger. Symbol files // with different versions are incompatible to each other and the debugger and // the runtime enfore this, so you need to recompile all your assemblies after // changing the file format. // namespace Mono.CompilerServices.SymbolWriter { public struct OffsetTable { public const int Version = 38; public const long Magic = 0x45e82623fd7fa614; #region This is actually written to the symbol file public int TotalFileSize; public int DataSectionOffset; public int DataSectionSize; public int SourceCount; public int SourceTableOffset; public int SourceTableSize; public int MethodCount; public int MethodTableOffset; public int MethodTableSize; public int TypeCount; #endregion internal OffsetTable (BinaryReader reader) { TotalFileSize = reader.ReadInt32 (); DataSectionOffset = reader.ReadInt32 (); DataSectionSize = reader.ReadInt32 (); SourceCount = reader.ReadInt32 (); SourceTableOffset = reader.ReadInt32 (); SourceTableSize = reader.ReadInt32 (); MethodCount = reader.ReadInt32 (); MethodTableOffset = reader.ReadInt32 (); MethodTableSize = reader.ReadInt32 (); TypeCount = reader.ReadInt32 (); } internal void Write (BinaryWriter bw) { bw.Write (TotalFileSize); bw.Write (DataSectionOffset); bw.Write (DataSectionSize); bw.Write (SourceCount); bw.Write (SourceTableOffset); bw.Write (SourceTableSize); bw.Write (MethodCount); bw.Write (MethodTableOffset); bw.Write (MethodTableSize); bw.Write (TypeCount); } public override string ToString () { return String.Format ( "OffsetTable [{0} - {1}:{2} - {3}:{4}:{5} - {6}:{7}:{8} - {9}]", TotalFileSize, DataSectionOffset, DataSectionSize, SourceCount, SourceTableOffset, SourceTableSize, MethodCount, MethodTableOffset, MethodTableSize, TypeCount); } } public struct LineNumberEntry { #region This is actually written to the symbol file public readonly int Row; public readonly int Offset; #endregion public LineNumberEntry (int row, int offset) { this.Row = row; this.Offset = offset; } public static LineNumberEntry Null = new LineNumberEntry (0, 0); internal LineNumberEntry (BinaryReader reader) { Row = reader.ReadInt32 (); Offset = reader.ReadInt32 (); } internal void Write (BinaryWriter bw) { bw.Write (Row); bw.Write (Offset); } private class OffsetComparerClass : IComparer { public int Compare (object a, object b) { LineNumberEntry l1 = (LineNumberEntry) a; LineNumberEntry l2 = (LineNumberEntry) b; if (l1.Offset < l2.Offset) return -1; else if (l1.Offset > l2.Offset) return 1; else return 0; } } private class RowComparerClass : IComparer { public int Compare (object a, object b) { LineNumberEntry l1 = (LineNumberEntry) a; LineNumberEntry l2 = (LineNumberEntry) b; if (l1.Row < l2.Row) return -1; else if (l1.Row > l2.Row) return 1; else return 0; } } public static readonly IComparer OffsetComparer = new OffsetComparerClass (); public static readonly IComparer RowComparer = new RowComparerClass (); public override string ToString () { return String.Format ("[Line {0}:{1}]", Row, Offset); } } public class LexicalBlockEntry { public int Index; #region This is actually written to the symbol file public int StartOffset; public int EndOffset; #endregion public LexicalBlockEntry (int index, int start_offset) { this.Index = index; this.StartOffset = start_offset; } internal LexicalBlockEntry (int index, MyBinaryReader reader) { this.Index = index; this.StartOffset = reader.ReadInt32 (); this.EndOffset = reader.ReadInt32 (); } public void Close (int end_offset) { this.EndOffset = end_offset; } internal void Write (MyBinaryWriter bw) { bw.Write (StartOffset); bw.Write (EndOffset); } public override string ToString () { return String.Format ("[LexicalBlock {0}:{1}]", StartOffset, EndOffset); } } public struct LocalVariableEntry { #region This is actually written to the symbol file public readonly string Name; public readonly byte[] Signature; public readonly int BlockIndex; #endregion public LocalVariableEntry (string Name, byte[] Signature, int BlockIndex) { this.Name = Name; this.Signature = Signature; this.BlockIndex = BlockIndex; } internal LocalVariableEntry (MyBinaryReader reader) { Name = reader.ReadString (); int sig_length = reader.ReadLeb128 (); Signature = reader.ReadBytes (sig_length); BlockIndex = reader.ReadLeb128 (); } internal void Write (MonoSymbolFile file, MyBinaryWriter bw) { bw.Write (Name); bw.WriteLeb128 ((int) Signature.Length); bw.Write (Signature); bw.WriteLeb128 (BlockIndex); } public override string ToString () { return String.Format ("[LocalVariable {0}]", Name); } } public class SourceFileEntry { #region This is actually written to the symbol file public readonly int Index; int Count; int NamespaceCount; int NameOffset; int MethodOffset; int NamespaceTableOffset; #endregion MonoSymbolFile file; string file_name; ArrayList methods; ArrayList namespaces; bool creating; public static int Size { get { return 24; } } public SourceFileEntry (MonoSymbolFile file, string file_name) { this.file = file; this.file_name = file_name; this.Index = file.AddSource (this); creating = true; methods = new ArrayList (); namespaces = new ArrayList (); } public void DefineMethod (string name, int token, LocalVariableEntry[] locals, LineNumberEntry[] lines, LexicalBlockEntry[] blocks, int start, int end, int namespace_id) { if (!creating) throw new InvalidOperationException (); MethodEntry entry = new MethodEntry ( file, this, name, (int) token, locals, lines, blocks, start, end, namespace_id); methods.Add (entry); file.AddMethod (entry); } public int DefineNamespace (string name, string[] using_clauses, int parent) { if (!creating) throw new InvalidOperationException (); int index = file.GetNextNamespaceIndex (); NamespaceEntry ns = new NamespaceEntry (name, index, using_clauses, parent); namespaces.Add (ns); return index; } internal void WriteData (MyBinaryWriter bw) { NameOffset = (int) bw.BaseStream.Position; bw.Write (file_name); ArrayList list = new ArrayList (); foreach (MethodEntry entry in methods) list.Add (entry.Write (file, bw)); list.Sort (); Count = list.Count; MethodOffset = (int) bw.BaseStream.Position; foreach (MethodSourceEntry method in list) method.Write (bw); NamespaceCount = namespaces.Count; NamespaceTableOffset = (int) bw.BaseStream.Position; foreach (NamespaceEntry ns in namespaces) ns.Write (file, bw); } internal void Write (BinaryWriter bw) { bw.Write (Index); bw.Write (Count); bw.Write (NamespaceCount); bw.Write (NameOffset); bw.Write (MethodOffset); bw.Write (NamespaceTableOffset); } internal SourceFileEntry (MonoSymbolFile file, BinaryReader reader) { this.file = file; Index = reader.ReadInt32 (); Count = reader.ReadInt32 (); NamespaceCount = reader.ReadInt32 (); NameOffset = reader.ReadInt32 (); MethodOffset = reader.ReadInt32 (); NamespaceTableOffset = reader.ReadInt32 (); file_name = file.ReadString (NameOffset); } public string FileName { get { return file_name; } } public MethodSourceEntry[] Methods { get { if (creating) throw new InvalidOperationException (); BinaryReader reader = file.BinaryReader; int old_pos = (int) reader.BaseStream.Position; reader.BaseStream.Position = MethodOffset; ArrayList list = new ArrayList (); for (int i = 0; i < Count; i ++) list.Add (new MethodSourceEntry (reader)); reader.BaseStream.Position = old_pos; MethodSourceEntry[] retval = new MethodSourceEntry [Count]; list.CopyTo (retval, 0); return retval; } } public NamespaceEntry[] Namespaces { get { if (creating) throw new InvalidOperationException (); MyBinaryReader reader = file.BinaryReader; int old_pos = (int) reader.BaseStream.Position; reader.BaseStream.Position = NamespaceTableOffset; ArrayList list = new ArrayList (); for (int i = 0; i < NamespaceCount; i ++) list.Add (new NamespaceEntry (file, reader)); reader.BaseStream.Position = old_pos; NamespaceEntry[] retval = new NamespaceEntry [list.Count]; list.CopyTo (retval, 0); return retval; } } public override string ToString () { return String.Format ("SourceFileEntry ({0}:{1}:{2})", Index, file_name, Count); } } public struct MethodSourceEntry : IComparable { #region This is actually written to the symbol file public readonly int Index; public readonly int FileOffset; public readonly int StartRow; public readonly int EndRow; #endregion public MethodSourceEntry (int index, int file_offset, int start, int end) { this.Index = index; this.FileOffset = file_offset; this.StartRow = start; this.EndRow = end; } internal MethodSourceEntry (BinaryReader reader) { Index = reader.ReadInt32 (); FileOffset = reader.ReadInt32 (); StartRow = reader.ReadInt32 (); EndRow = reader.ReadInt32 (); } public static int Size { get { return 16; } } internal void Write (BinaryWriter bw) { bw.Write (Index); bw.Write (FileOffset); bw.Write (StartRow); bw.Write (EndRow); } public int CompareTo (object obj) { MethodSourceEntry method = (MethodSourceEntry) obj; if (method.StartRow < StartRow) return -1; else if (method.StartRow > StartRow) return 1; else return 0; } public override string ToString () { return String.Format ("MethodSourceEntry ({0}:{1}:{2}:{3})", Index, FileOffset, StartRow, EndRow); } } public struct MethodIndexEntry { #region This is actually written to the symbol file public readonly int FileOffset; public readonly int Token; #endregion public static int Size { get { return 8; } } public MethodIndexEntry (int offset, int token) { this.FileOffset = offset; this.Token = token; } internal MethodIndexEntry (BinaryReader reader) { FileOffset = reader.ReadInt32 (); Token = reader.ReadInt32 (); } internal void Write (BinaryWriter bw) { bw.Write (FileOffset); bw.Write (Token); } public override string ToString () { return String.Format ("MethodIndexEntry ({0}:{1:x})", FileOffset, Token); } } public class MethodEntry : IComparable { #region This is actually written to the symbol file public readonly int SourceFileIndex; public readonly int Token; public readonly int StartRow; public readonly int EndRow; public readonly int NumLocals; public readonly int NumLineNumbers; public readonly int NamespaceID; public readonly bool LocalNamesAmbiguous; int NameOffset; int TypeIndexTableOffset; int LocalVariableTableOffset; int LineNumberTableOffset; int NumLexicalBlocks; int LexicalBlockTableOffset; #endregion int file_offset; public readonly int Index; public readonly SourceFileEntry SourceFile; public readonly LineNumberEntry[] LineNumbers; public readonly int[] LocalTypeIndices; public readonly LocalVariableEntry[] Locals; public readonly LexicalBlockEntry[] LexicalBlocks; public readonly MonoSymbolFile SymbolFile; public static int Size { get { return 52; } } internal MethodEntry (MonoSymbolFile file, MyBinaryReader reader, int index) { this.SymbolFile = file; this.Index = index; SourceFileIndex = reader.ReadInt32 (); Token = reader.ReadInt32 (); StartRow = reader.ReadInt32 (); EndRow = reader.ReadInt32 (); NumLocals = reader.ReadInt32 (); NumLineNumbers = reader.ReadInt32 (); NameOffset = reader.ReadInt32 (); TypeIndexTableOffset = reader.ReadInt32 (); LocalVariableTableOffset = reader.ReadInt32 (); LineNumberTableOffset = reader.ReadInt32 (); NumLexicalBlocks = reader.ReadInt32 (); LexicalBlockTableOffset = reader.ReadInt32 (); NamespaceID = reader.ReadInt32 (); LocalNamesAmbiguous = reader.ReadInt32 () != 0; SourceFile = file.GetSourceFile (SourceFileIndex); if (LineNumberTableOffset != 0) { long old_pos = reader.BaseStream.Position; reader.BaseStream.Position = LineNumberTableOffset; LineNumbers = new LineNumberEntry [NumLineNumbers]; for (int i = 0; i < NumLineNumbers; i++) LineNumbers [i] = new LineNumberEntry (reader); reader.BaseStream.Position = old_pos; } if (LocalVariableTableOffset != 0) { long old_pos = reader.BaseStream.Position; reader.BaseStream.Position = LocalVariableTableOffset; Locals = new LocalVariableEntry [NumLocals]; for (int i = 0; i < NumLocals; i++) Locals [i] = new LocalVariableEntry (reader); reader.BaseStream.Position = old_pos; } if (TypeIndexTableOffset != 0) { long old_pos = reader.BaseStream.Position; reader.BaseStream.Position = TypeIndexTableOffset; LocalTypeIndices = new int [NumLocals]; for (int i = 0; i < NumLocals; i++) LocalTypeIndices [i] = reader.ReadInt32 (); reader.BaseStream.Position = old_pos; } if (LexicalBlockTableOffset != 0) { long old_pos = reader.BaseStream.Position; reader.BaseStream.Position = LexicalBlockTableOffset; LexicalBlocks = new LexicalBlockEntry [NumLexicalBlocks]; for (int i = 0; i < NumLexicalBlocks; i++) LexicalBlocks [i] = new LexicalBlockEntry (i, reader); reader.BaseStream.Position = old_pos; } } internal MethodEntry (MonoSymbolFile file, SourceFileEntry source, string name, int token, LocalVariableEntry[] locals, LineNumberEntry[] lines, LexicalBlockEntry[] blocks, int start_row, int end_row, int namespace_id) { this.SymbolFile = file; Index = file.GetNextMethodIndex (); Token = token; SourceFileIndex = source.Index; SourceFile = source; StartRow = start_row; EndRow = end_row; NamespaceID = namespace_id; LexicalBlocks = blocks; NumLexicalBlocks = LexicalBlocks != null ? LexicalBlocks.Length : 0; LineNumbers = BuildLineNumberTable (lines); NumLineNumbers = LineNumbers.Length; file.NumLineNumbers += NumLineNumbers; NumLocals = locals != null ? locals.Length : 0; Locals = locals; if (NumLocals <= 32) { // Most of the time, the O(n^2) factor is actually // less than the cost of allocating the hash table, // 32 is a rough number obtained through some testing. for (int i = 0; i < NumLocals; i ++) { string nm = locals [i].Name; for (int j = i + 1; j < NumLocals; j ++) { if (locals [j].Name == nm) { LocalNamesAmbiguous = true; goto locals_check_done; } } } locals_check_done : ; } else { Hashtable local_names = new Hashtable (); foreach (LocalVariableEntry local in locals) { if (local_names.Contains (local.Name)) { LocalNamesAmbiguous = true; break; } local_names.Add (local.Name, local); } } LocalTypeIndices = new int [NumLocals]; for (int i = 0; i < NumLocals; i++) LocalTypeIndices [i] = file.GetNextTypeIndex (); } static LineNumberEntry [] tmp_buff = new LineNumberEntry [20]; // BuildLineNumberTable() eliminates duplicate line numbers and ensures // we aren't going "backwards" since this would counfuse the runtime's // debugging code (and the debugger). // // In the line number table, the "offset" field most be strictly // monotonic increasing; that is, the next entry must not have an offset // which is equal to or less than the current one. // // The most common case is that our input (ie. the line number table as // we get it from mcs) contains several entries with the same offset // (and different line numbers) - but it may also happen that the offset // is decreasing (this can be considered as an exception, such lines will // simply be discarded). LineNumberEntry[] BuildLineNumberTable (LineNumberEntry[] line_numbers) { int pos = 0; int last_offset = -1; int last_row = -1; if (line_numbers == null) return new LineNumberEntry [0]; if (tmp_buff.Length < (line_numbers.Length + 1)) tmp_buff = new LineNumberEntry [(line_numbers.Length + 1) * 2]; for (int i = 0; i < line_numbers.Length; i++) { LineNumberEntry line = line_numbers [i]; if (line.Offset > last_offset) { if (last_row >= 0) tmp_buff [pos ++] = new LineNumberEntry (last_row, last_offset); last_row = line.Row; last_offset = line.Offset; } else if (line.Row > last_row) { last_row = line.Row; } } if (last_row >= 0) tmp_buff [pos ++] = new LineNumberEntry (last_row, last_offset); LineNumberEntry [] retval = new LineNumberEntry [pos]; Array.Copy (tmp_buff, retval, pos); return retval; } internal MethodSourceEntry Write (MonoSymbolFile file, MyBinaryWriter bw) { NameOffset = (int) bw.BaseStream.Position; TypeIndexTableOffset = (int) bw.BaseStream.Position; for (int i = 0; i < NumLocals; i++) bw.Write (LocalTypeIndices [i]); LocalVariableTableOffset = (int) bw.BaseStream.Position; for (int i = 0; i < NumLocals; i++) Locals [i].Write (file, bw); file.LocalCount += NumLocals; LineNumberTableOffset = (int) bw.BaseStream.Position; for (int i = 0; i < NumLineNumbers; i++) LineNumbers [i].Write (bw); file.LineNumberCount += NumLineNumbers; LexicalBlockTableOffset = (int) bw.BaseStream.Position; for (int i = 0; i < NumLexicalBlocks; i++) LexicalBlocks [i].Write (bw); file_offset = (int) bw.BaseStream.Position; bw.Write (SourceFileIndex); bw.Write (Token); bw.Write (StartRow); bw.Write (EndRow); bw.Write (NumLocals); bw.Write (NumLineNumbers); bw.Write (NameOffset); bw.Write (TypeIndexTableOffset); bw.Write (LocalVariableTableOffset); bw.Write (LineNumberTableOffset); bw.Write (NumLexicalBlocks); bw.Write (LexicalBlockTableOffset); bw.Write (NamespaceID); bw.Write (LocalNamesAmbiguous ? 1 : 0); return new MethodSourceEntry (Index, file_offset, StartRow, EndRow); } internal void WriteIndex (BinaryWriter bw) { new MethodIndexEntry (file_offset, Token).Write (bw); } public int CompareTo (object obj) { MethodEntry method = (MethodEntry) obj; if (method.Token < Token) return 1; else if (method.Token > Token) return -1; else return 0; } public override string ToString () { return String.Format ("[Method {0}:{1}:{2}:{3}:{4} - {6}:{7} - {5}]", Index, Token, SourceFileIndex, StartRow, EndRow, SourceFile, NumLocals, NumLineNumbers); } } public struct NamespaceEntry { #region This is actually written to the symbol file public readonly string Name; public readonly int Index; public readonly int Parent; public readonly string[] UsingClauses; #endregion public NamespaceEntry (string name, int index, string[] using_clauses, int parent) { this.Name = name; this.Index = index; this.Parent = parent; this.UsingClauses = using_clauses != null ? using_clauses : new string [0]; } internal NamespaceEntry (MonoSymbolFile file, MyBinaryReader reader) { Name = reader.ReadString (); Index = reader.ReadLeb128 (); Parent = reader.ReadLeb128 (); int count = reader.ReadLeb128 (); UsingClauses = new string [count]; for (int i = 0; i < count; i++) UsingClauses [i] = reader.ReadString (); } internal void Write (MonoSymbolFile file, MyBinaryWriter bw) { bw.Write (Name); bw.WriteLeb128 (Index); bw.WriteLeb128 (Parent); bw.WriteLeb128 (UsingClauses.Length); foreach (string uc in UsingClauses) bw.Write (uc); } public override string ToString () { return String.Format ("[Namespace {0}:{1}:{2}]", Name, Index, Parent); } } } --- NEW FILE: MonoSymbolWriter.cs --- // // Mono.CSharp.Debugger/MonoSymbolWriter.cs // // Author: // Martin Baulig (ma...@xi...) // // This is the default implementation of the System.Diagnostics.SymbolStore.ISymbolWriter // interface. // // (C) 2002 Ximian, Inc. http://www.ximian.com // // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using System.Runtime.CompilerServices; using System.Collections; using System.IO; namespace Mono.CompilerServices.SymbolWriter { public interface ISourceFile { SourceFileEntry Entry { get; } } public interface ISourceMethod { string Name { get; } int NamespaceID { get; } int Token { get; } } public class MonoSymbolWriter { protected ArrayList locals = null; protected ArrayList methods = null; protected ArrayList sources = null; protected readonly MonoSymbolFile file; private string filename = null; LineNumberEntry [] current_method_lines; int current_method_lines_pos = 0; internal ISourceFile[] Sources { get { ISourceFile[] retval = new ISourceFile [sources.Count]; sources.CopyTo (retval, 0); return retval; } } private SourceMethod current_method = null; // // Interface IMonoSymbolWriter // public MonoSymbolWriter (string filename) { this.methods = new ArrayList (); this.sources = new ArrayList (); this.locals = new ArrayList (); this.file = new MonoSymbolFile (); this.filename = filename + ".mdb"; this.current_method_lines = new LineNumberEntry [50]; } public void CloseNamespace () { } public void DefineLocalVariable (string name, byte[] signature) { if (current_method == null) return; current_method.AddLocal (name, signature); } public void MarkSequencePoint (int offset, int line, int column) { if (current_method == null) return; if (current_method_lines_pos == current_method_lines.Length) { LineNumberEntry [] tmp = current_method_lines; current_method_lines = new LineNumberEntry [current_method_lines.Length * 2]; Array.Copy (tmp, current_method_lines, current_method_lines_pos); } current_method_lines [current_method_lines_pos++] = new LineNumberEntry (line, offset); } public void OpenMethod (ISourceFile file, ISourceMethod method, int startRow, int startColumn, int endRow, int endColumn) { SourceMethod source = new SourceMethod ( file, method, startRow, startColumn, endRow, endColumn); current_method = source; methods.Add (current_method); } public void CloseMethod () { current_method.SetLineNumbers ( current_method_lines, current_method_lines_pos); current_method_lines_pos = 0; current_method = null; } public SourceFileEntry DefineDocument (string url) { SourceFileEntry entry = new SourceFileEntry (file, url); sources.Add (entry); return entry; } public int DefineNamespace (string name, SourceFileEntry source, string[] using_clauses, int parent) { if ((source == null) || (using_clauses == null)) throw new NullReferenceException (); return source.DefineNamespace (name, using_clauses, parent); } public int OpenScope (int startOffset) { if (current_method == null) return 0; current_method.StartBlock (startOffset); return 0; } public void CloseScope (int endOffset) { if (current_method == null) return; current_method.EndBlock (endOffset); } protected byte[] CreateOutput (Guid guid) { foreach (SourceMethod method in methods) { method.SourceFile.Entry.DefineMethod ( method.Method.Name, method.Method.Token, method.Locals, method.Lines, method.Blocks, method.Start.Row, method.End.Row, method.Method.NamespaceID); } return file.CreateSymbolFile (guid); } public void WriteSymbolFile (Guid guid) { using (FileStream stream = new FileStream ( filename, FileMode.Create, FileAccess.Write)) { byte[] data = CreateOutput (guid); stream.Write (data, 0, data.Length); } } protected class SourceMethod { LineNumberEntry [] lines; private ArrayList _locals; private ArrayList _blocks; private Stack _block_stack; private int next_block_id = 0; private ISourceMethod _method; private ISourceFile _file; private LineNumberEntry _start, _end; private LexicalBlockEntry _implicit_block; public SourceMethod (ISourceFile file, ISourceMethod method, int startLine, int startColumn, int endLine, int endColumn) { this._file = file; this._method = method; this._start = new LineNumberEntry (startLine, 0); this._end = new LineNumberEntry (endLine, 0); this._implicit_block = new LexicalBlockEntry (0, 0); } public void StartBlock (int startOffset) { LexicalBlockEntry block = new LexicalBlockEntry ( ++next_block_id, startOffset); if (_block_stack == null) _block_stack = new Stack (); _block_stack.Push (block); if (_blocks == null) _blocks = new ArrayList (); _blocks.Add (block); } public void EndBlock (int endOffset) { LexicalBlockEntry block = (LexicalBlockEntry) _block_stack.Pop (); block.Close (endOffset); } public LexicalBlockEntry[] Blocks { get { if (_blocks == null) return new LexicalBlockEntry [0]; else { LexicalBlockEntry[] retval = new LexicalBlockEntry [_blocks.Count]; _blocks.CopyTo (retval, 0); return retval; } } } public LexicalBlockEntry CurrentBlock { get { if ((_block_stack != null) && (_block_stack.Count > 0)) return (LexicalBlockEntry) _block_stack.Peek (); else return _implicit_block; } } public LineNumberEntry[] Lines { get { return lines; } } public LocalVariableEntry[] Locals { get { if (_locals == null) return new LocalVariableEntry [0]; else { LocalVariableEntry[] retval = new LocalVariableEntry [_locals.Count]; _locals.CopyTo (retval, 0); return retval; } } } public void AddLocal (string name, byte[] signature) { if (_locals == null) _locals = new ArrayList (); _locals.Add (new LocalVariableEntry ( name, signature, CurrentBlock.Index)); } public ISourceFile SourceFile { get { return _file; } } public ISourceMethod Method { get { return _method; } } public LineNumberEntry Start { get { return _start; } } public LineNumberEntry End { get { return _end; } } // // Passes on the lines from the MonoSymbolWriter. This method is // free to mutate the lns array, and it does. // internal void SetLineNumbers (LineNumberEntry [] lns, int count) { int pos = 0; int last_offset = -1; int last_row = -1; for (int i = 0; i < count; i++) { LineNumberEntry line = lns [i]; if (line.Offset > last_offset) { if (last_row >= 0) lns [pos++] = new LineNumberEntry ( last_row, last_offset); last_row = line.Row; last_offset = line.Offset; } else if (line.Row > last_row) { last_row = line.Row; } } lines = new LineNumberEntry [count + ((last_row >= 0) ? 1 : 0)]; Array.Copy (lns, lines, pos); if (last_row >= 0) lines [pos] = new LineNumberEntry ( last_row, last_offset); } } } } |
From: <mas...@us...> - 2004-10-06 19:32:18
|
Update of /cvsroot/csdoc/csdoc/src/mcs/class/corlib/Mono.Security.Cryptography In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv20667/corlib/Mono.Security.Cryptography Added Files: CryptoConvert.cs Log Message: no message --- NEW FILE: CryptoConvert.cs --- // // CryptoConvert.cs - Crypto Convertion Routines // // Author: // Sebastien Pouliot <seb...@xi...> // // (C) 2003 Motus Technologies Inc. (http://www.motus.com) // (C) 2004 Novell (http://www.novell.com) // // // Copyright (C) 2004 Novell, Inc (http://www.novell.com) // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using System.Globalization; using System.Security.Cryptography; using System.Text; namespace Mono.Security.Cryptography { #if INSIDE_CORLIB internal #else public #endif sealed class CryptoConvert { private CryptoConvert () { } static private int ToInt32LE (byte [] bytes, int offset) { return (bytes [offset+3] << 24) | (bytes [offset+2] << 16) | (bytes [offset+1] << 8) | bytes [offset]; } static private uint ToUInt32LE (byte [] bytes, int offset) { return (uint)((bytes [offset+3] << 24) | (bytes [offset+2] << 16) | (bytes [offset+1] << 8) | bytes [offset]); } static private byte [] GetBytesLE (int val) { return new byte [] { (byte) (val & 0xff), (byte) ((val >> 8) & 0xff), (byte) ((val >> 16) & 0xff), (byte) ((val >> 24) & 0xff) }; } static private byte[] Trim (byte[] array) { for (int i=0; i < array.Length; i++) { if (array [i] != 0x00) { byte[] result = new byte [array.Length - i]; Buffer.BlockCopy (array, i, result, 0, result.Length); return result; } } return null; } // convert the key from PRIVATEKEYBLOB to RSA // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/security/Security/private_key_blobs.asp // e.g. SNK files, PVK files static public RSA FromCapiPrivateKeyBlob (byte[] blob) { return FromCapiPrivateKeyBlob (blob, 0); } static public RSA FromCapiPrivateKeyBlob (byte[] blob, int offset) { if (blob == null) throw new ArgumentNullException ("blob"); if (offset >= blob.Length) throw new ArgumentException ("blob is too small."); try { if ((blob [offset] != 0x07) || // PRIVATEKEYBLOB (0x07) (blob [offset+1] != 0x02) || // Version (0x02) (blob [offset+2] != 0x00) || // Reserved (word) (blob [offset+3] != 0x00) || (ToUInt32LE (blob, offset+8) != 0x32415352)) // DWORD magic = RSA2 throw new CryptographicException ("Invalid blob header"); // ALGID (CALG_RSA_SIGN, CALG_RSA_KEYX, ...) // int algId = ToInt32LE (blob, offset+4); // DWORD bitlen int bitLen = ToInt32LE (blob, offset+12); // DWORD public exponent RSAParameters rsap = new RSAParameters (); byte[] exp = new byte [4]; Buffer.BlockCopy (blob, offset+16, exp, 0, 4); Array.Reverse (exp); rsap.Exponent = Trim (exp); int pos = offset+20; // BYTE modulus[rsapubkey.bitlen/8]; int byteLen = (bitLen >> 3); rsap.Modulus = new byte [byteLen]; Buffer.BlockCopy (blob, pos, rsap.Modulus, 0, byteLen); Array.Reverse (rsap.Modulus); pos += byteLen; // BYTE prime1[rsapubkey.bitlen/16]; int byteHalfLen = (byteLen >> 1); rsap.P = new byte [byteHalfLen]; Buffer.BlockCopy (blob, pos, rsap.P, 0, byteHalfLen); Array.Reverse (rsap.P); pos += byteHalfLen; // BYTE prime2[rsapubkey.bitlen/16]; rsap.Q = new byte [byteHalfLen]; Buffer.BlockCopy (blob, pos, rsap.Q, 0, byteHalfLen); Array.Reverse (rsap.Q); pos += byteHalfLen; // BYTE exponent1[rsapubkey.bitlen/16]; rsap.DP = new byte [byteHalfLen]; Buffer.BlockCopy (blob, pos, rsap.DP, 0, byteHalfLen); Array.Reverse (rsap.DP); pos += byteHalfLen; // BYTE exponent2[rsapubkey.bitlen/16]; rsap.DQ = new byte [byteHalfLen]; Buffer.BlockCopy (blob, pos, rsap.DQ, 0, byteHalfLen); Array.Reverse (rsap.DQ); pos += byteHalfLen; // BYTE coefficient[rsapubkey.bitlen/16]; rsap.InverseQ = new byte [byteHalfLen]; Buffer.BlockCopy (blob, pos, rsap.InverseQ, 0, byteHalfLen); Array.Reverse (rsap.InverseQ); pos += byteHalfLen; // ok, this is hackish but CryptoAPI support it so... // note: only works because CRT is used by default // http://bugzilla.ximian.com/show_bug.cgi?id=57941 rsap.D = new byte [byteLen]; // must be allocated if (pos + byteLen + offset <= blob.Length) { // BYTE privateExponent[rsapubkey.bitlen/8]; Buffer.BlockCopy (blob, pos, rsap.D, 0, byteLen); Array.Reverse (rsap.D); } RSA rsa = (RSA)RSA.Create (); rsa.ImportParameters (rsap); return rsa; } catch (Exception e) { throw new CryptographicException ("Invalid blob.", e); } } static public byte[] ToCapiPrivateKeyBlob (RSA rsa) { RSAParameters p = rsa.ExportParameters (true); int keyLength = p.Modulus.Length; // in bytes byte[] blob = new byte [20 + (keyLength << 2) + (keyLength >> 1)]; blob [0] = 0x07; // Type - PRIVATEKEYBLOB (0x07) blob [1] = 0x02; // Version - Always CUR_BLOB_VERSION (0x02) // [2], [3] // RESERVED - Always 0 blob [5] = 0x24; // ALGID - Always 00 24 00 00 (for CALG_RSA_SIGN) blob [8] = 0x52; // Magic - RSA2 (ASCII in hex) blob [9] = 0x53; blob [10] = 0x41; blob [11] = 0x32; byte[] bitlen = GetBytesLE (keyLength << 3); blob [12] = bitlen [0]; // bitlen blob [13] = bitlen [1]; blob [14] = bitlen [2]; blob [15] = bitlen [3]; // public exponent (DWORD) int pos = 16; int n = p.Exponent.Length; while (n > 0) blob [pos++] = p.Exponent [--n]; // modulus pos = 20; byte[] part = p.Modulus; int len = part.Length; Array.Reverse (part, 0, len); Buffer.BlockCopy (part, 0, blob, pos, len); pos += len; // private key part = p.P; len = part.Length; Array.Reverse (part, 0, len); Buffer.BlockCopy (part, 0, blob, pos, len); pos += len; part = p.Q; len = part.Length; Array.Reverse (part, 0, len); Buffer.BlockCopy (part, 0, blob, pos, len); pos += len; part = p.DP; len = part.Length; Array.Reverse (part, 0, len); Buffer.BlockCopy (part, 0, blob, pos, len); pos += len; part = p.DQ; len = part.Length; Array.Reverse (part, 0, len); Buffer.BlockCopy (part, 0, blob, pos, len); pos += len; part = p.InverseQ; len = part.Length; Array.Reverse (part, 0, len); Buffer.BlockCopy (part, 0, blob, pos, len); pos += len; part = p.D; len = part.Length; Array.Reverse (part, 0, len); Buffer.BlockCopy (part, 0, blob, pos, len); return blob; } static public RSA FromCapiPublicKeyBlob (byte[] blob) { return FromCapiPublicKeyBlob (blob, 0); } static public RSA FromCapiPublicKeyBlob (byte[] blob, int offset) { if (blob == null) throw new ArgumentNullException ("blob"); if (offset >= blob.Length) throw new ArgumentException ("blob is too small."); try { if ((blob [offset] != 0x06) || // PUBLICKEYBLOB (0x06) (blob [offset+1] != 0x02) || // Version (0x02) (blob [offset+2] != 0x00) || // Reserved (word) (blob [offset+3] != 0x00) || (ToUInt32LE (blob, offset+8) != 0x31415352)) // DWORD magic = RSA1 throw new CryptographicException ("Invalid blob header"); // ALGID (CALG_RSA_SIGN, CALG_RSA_KEYX, ...) // int algId = ToInt32LE (blob, offset+4); // DWORD bitlen int bitLen = ToInt32LE (blob, offset+12); // DWORD public exponent RSAParameters rsap = new RSAParameters (); rsap.Exponent = new byte [3]; rsap.Exponent [0] = blob [offset+18]; rsap.Exponent [1] = blob [offset+17]; rsap.Exponent [2] = blob [offset+16]; int pos = offset+20; // BYTE modulus[rsapubkey.bitlen/8]; int byteLen = (bitLen >> 3); rsap.Modulus = new byte [byteLen]; Buffer.BlockCopy (blob, pos, rsap.Modulus, 0, byteLen); Array.Reverse (rsap.Modulus); RSA rsa = (RSA)RSA.Create (); rsa.ImportParameters (rsap); return rsa; } catch (Exception e) { throw new CryptographicException ("Invalid blob.", e); } } static public byte[] ToCapiPublicKeyBlob (RSA rsa) { RSAParameters p = rsa.ExportParameters (false); int keyLength = p.Modulus.Length; // in bytes byte[] blob = new byte [20 + keyLength]; blob [0] = 0x06; // Type - PUBLICKEYBLOB (0x06) blob [1] = 0x02; // Version - Always CUR_BLOB_VERSION (0x02) // [2], [3] // RESERVED - Always 0 blob [5] = 0x24; // ALGID - Always 00 24 00 00 (for CALG_RSA_SIGN) blob [8] = 0x52; // Magic - RSA1 (ASCII in hex) blob [9] = 0x53; blob [10] = 0x41; blob [11] = 0x31; byte[] bitlen = GetBytesLE (keyLength << 3); blob [12] = bitlen [0]; // bitlen blob [13] = bitlen [1]; blob [14] = bitlen [2]; blob [15] = bitlen [3]; // public exponent (DWORD) int pos = 16; int n = p.Exponent.Length; while (n > 0) blob [pos++] = p.Exponent [--n]; // modulus pos = 20; byte[] part = p.Modulus; int len = part.Length; Array.Reverse (part, 0, len); Buffer.BlockCopy (part, 0, blob, pos, len); pos += len; return blob; } // PRIVATEKEYBLOB // PUBLICKEYBLOB static public RSA FromCapiKeyBlob (byte[] blob) { return FromCapiKeyBlob (blob, 0); } static public RSA FromCapiKeyBlob (byte[] blob, int offset) { if (blob == null) throw new ArgumentNullException ("blob"); if (offset >= blob.Length) throw new ArgumentException ("blob is too small."); switch (blob [offset]) { case 0x00: // this could be a public key inside an header // like "sn -e" would produce if (blob [offset + 12] == 0x06) { return FromCapiPublicKeyBlob (blob, offset + 12); } break; case 0x06: return FromCapiPublicKeyBlob (blob, offset); case 0x07: return FromCapiPrivateKeyBlob (blob, offset); } throw new CryptographicException ("Unknown blob format."); } static public byte[] ToCapiKeyBlob (AsymmetricAlgorithm keypair, bool includePrivateKey) { if (keypair == null) throw new ArgumentNullException ("keypair"); // check between RSA and DSA (and potentially others like DH) if (keypair is RSA) return ToCapiKeyBlob ((RSA)keypair, includePrivateKey); else return null; // TODO } static public byte[] ToCapiKeyBlob (RSA rsa, bool includePrivateKey) { if (rsa == null) throw new ArgumentNullException ("rsa"); if (includePrivateKey) return ToCapiPrivateKeyBlob (rsa); else return ToCapiPublicKeyBlob (rsa); } static public string ToHex (byte[] input) { if (input == null) return null; StringBuilder sb = new StringBuilder (input.Length * 2); foreach (byte b in input) { sb.Append (b.ToString ("X2", CultureInfo.InvariantCulture)); } return sb.ToString (); } static private byte FromHexChar (char c) { if ((c >= 'a') && (c <= 'f')) return (byte) (c - 'a' + 10); if ((c >= 'A') && (c <= 'F')) return (byte) (c - 'A' + 10); if ((c >= '0') && (c <= '9')) return (byte) (c - '0'); throw new ArgumentException ("invalid hex char"); } static public byte[] FromHex (string hex) { if (hex == null) return null; if ((hex.Length & 0x1) == 0x1) throw new ArgumentException ("Length must be a multiple of 2"); byte[] result = new byte [hex.Length >> 1]; int n = 0; int i = 0; while (n < result.Length) { result [n] = (byte) (FromHexChar (hex [i++]) << 4); result [n++] += FromHexChar (hex [i++]); } return result; } } } |
Update of /cvsroot/csdoc/csdoc/src/mcs/build/profiles In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv20482/profiles Added Files: atomic.make bootstrap.make default.make net_1_0.make net_2_0.make net_2_0_bootstrap.make Log Message: no message --- NEW FILE: atomic.make --- # -*- Makefile -*- # # The 'atomic' profile. # In this profile we compile everything relative to the already-installed # runtime, so we use the bootstrap (external) compiler for everything and # don't set MONO_PATH. # # (So the libraries are compiled and installed atomically, not incrementally.) MCS = $(BOOTSTRAP_MCS) # Causes some build errors #PROFILE_MCS_FLAGS = /d:NET_1_1 /lib:$(prefix)/lib # Get our installed libraries (an issue on windows) PROFILE_MCS_FLAGS = /lib:$(prefix)/lib # Check that installed libraries even exist. profile-check: @if test '!' -f $(prefix)/lib/I18N.dll ; then \ echo ; \ echo "$(prefix)/lib/I18N.dll does not exist." ; \ echo ; \ echo "This probably means that you are building from a miniature" ; \ echo "distribution of MCS or don't yet have an installed MCS at all." ; \ echo "The current build profile needs a complete installation of" ; \ echo "MCS to build against; you need to build using the default" ; \ echo "profile. Use this command:" ; \ echo ; \ echo " $(MAKE) PROFILE=default" ; \ echo ; \ exit 1 ; \ fi # Exciting, no? --- NEW FILE: bootstrap.make --- # -*- makefile -*- # # The default 'bootstrap' profile -- builds so that we link against # the libraries as we build them. # # We use the platform's native C# runtime and compiler if possible. # Note that we have sort of confusing terminology here; BOOTSTRAP_MCS # is what allows us to bootstrap ourselves, but when we are bootstrapping, # we use INTERNAL_MCS. # When bootstrapping, compile against our new assemblies. # (MONO_PATH doesn't just affect what assemblies are loaded to # run the compiler; /r: flags are by default loaded from whatever's # in the MONO_PATH too). MCS = MONO_PATH="$(topdir)/class/lib/$(PROFILE):$$MONO_PATH" $(RUNTIME) --debug $(topdir)/mcs/mcs.exe BOOTSTRAP_MCS = $(MCS) # nuttzing! profile-check: # Causes some build errors PROFILE_MCS_FLAGS = -d:NET_1_1 -d:ONLY_1_1 --- NEW FILE: default.make --- # -*- makefile -*- # # The default 'bootstrap' profile -- builds so that we link against # the libraries as we build them. # # We use the platform's native C# runtime and compiler if possible. # Note that we have sort of confusing terminology here; BOOTSTRAP_MCS # is what allows us to bootstrap ourselves, but when we are bootstrapping, # we use INTERNAL_MCS. # When bootstrapping, compile against our new assemblies. # (MONO_PATH doesn't just affect what assemblies are loaded to # run the compiler; /r: flags are by default loaded from whatever's # in the MONO_PATH too). ifdef PLATFORM_MONO_NATIVE MCS = MONO_PATH="$(topdir)/class/lib/$(PROFILE):$$MONO_PATH" $(INTERNAL_MCS) MBAS = MONO_PATH="$(topdir)/class/lib/$(PROFILE):$$MONO_PATH" $(INTERNAL_MBAS) else MCS = $(PLATFORM_RUNTIME) $(BOOTSTRAP_MCS) /lib:$(topdir)/class/lib/$(PROFILE) MBAS = $(PLATFORM_RUNTIME) $(BOOTSTRAP_MBAS) /lib:$(topdir)/class/lib/$(PROFILE) endif # nuttzing! profile-check: PROFILE_MCS_FLAGS = -d:NET_1_1 -d:ONLY_1_1 PROFILE_MBAS_FLAGS = -d:NET_1_1 -d:ONLY_1_1 FRAMEWORK_VERSION = 1.0 --- NEW FILE: net_1_0.make --- # -*- Makefile -*- # # Only build .NET 1.0 classes. # # If we want to combine this with, say, the atomic profile, # we should create 'atomic-net_1_0.make' which includes both. # # Ideally you could say 'make PROFILE="bootstrap net_1_0"' but # that would be pretty hard to code. include $(topdir)/build/profiles/default.make PROFILE_MCS_FLAGS = /d:NET_1_0 /d:ONLY_1_0 FRAMEWORK_VERSION = 1.0 # done --- NEW FILE: net_2_0.make --- # -*- makefile -*- # # The default 'bootstrap' profile -- builds so that we link against # the libraries as we build them. # # We use the platform's native C# runtime and compiler if possible. # Note that we have sort of confusing terminology here; BOOTSTRAP_MCS # is what allows us to bootstrap ourselves, but when we are bootstrapping, # we use INTERNAL_MCS. # When bootstrapping, compile against our new assemblies. # (MONO_PATH doesn't just affect what assemblies are loaded to # run the compiler; /r: flags are by default loaded from whatever's # in the MONO_PATH too). MCS = MONO_PATH="$(topdir)/class/lib/$(PROFILE)$(PLATFORM_PATH_SEPARATOR)$$MONO_PATH" $(INTERNAL_GMCS) # nuttzing! profile-check: PROFILE_MCS_FLAGS = -d:NET_1_1 -d:NET_2_0 -2 FRAMEWORK_VERSION = 2.0 --- NEW FILE: net_2_0_bootstrap.make --- # -*- makefile -*- # # Note that we're using the .NET 1.1 MCS but MONO_PATH points to the net_2_0_bootstrap directory. # We do it this way to get assembly version references right. # MCS = MONO_PATH="$(topdir)/class/lib/$(PROFILE)$(PLATFORM_PATH_SEPARATOR)$$MONO_PATH" $(INTERNAL_MCS) # Make sure that we're not invoked at the top-level. profile-check: echo "The 'net_2_0_bootstrap' profile is for internal use only" exit 1 PROFILE_MCS_FLAGS = -d:NET_1_1 -d:BOOTSTRAP_NET_2_0 -langversion:default FRAMEWORK_VERSION = 2.0 NO_SIGN_ASSEMBLY = yes |
From: <mas...@us...> - 2004-10-06 19:31:42
|
Update of /cvsroot/csdoc/csdoc/src/mcs/build/platforms In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv20482/platforms Added Files: linux.make win32.make Log Message: no message --- NEW FILE: linux.make --- # -*- makefile -*- # # Platform-specific makefile rules. This one's for linux. # PLATFORM_DEBUG_FLAGS = -g PLATFORM_MCS_FLAGS = PLATFORM_RUNTIME = $(RUNTIME) PLATFORM_CORLIB = mscorlib.dll BOOTSTRAP_MCS = mcs RESGEN = MONO_PATH="$(topdir)/class/lib/$(PROFILE)$(PLATFORM_PATH_SEPARATOR)$$MONO_PATH" $(INTERNAL_RESGEN) PLATFORM_PATH_SEPARATOR = : # Define this if this ever will work on Linux # PLATFORM_MAKE_CORLIB_CMP = yes # This is for changing / to \ on windows PLATFORM_CHANGE_SEPARATOR_CMD = cat hidden_prefix = . hidden_suffix = platform-check: @set fnord $(BOOTSTRAP_MCS) ; if type $$2 >/dev/null 2>&1 ; then :; else \ echo "*** You need a C# compiler installed to build MCS. (make sure mcs works from the command line)" ; \ echo "*** Read INSTALL.txt for information on how to bootstrap" ; \ echo "*** a Mono installation." ; \ exit 1 ; \ fi # I tried this but apparently Make's version strings aren't that # ... consistent between releases. Whatever. # # @if ! $(MAKE) --version |grep '^GNU Make version 3' 1>/dev/null 2>&1 ; then \ # echo "*** You need to build MCS with GNU make. Try \`gmake'" ; \ # exit 1 ; \ # fi --- NEW FILE: win32.make --- # -*- makefile -*- # # Win32 platform-specific makefile rules. # PLATFORM_DEBUG_FLAGS = /debug+ /debug:full PLATFORM_MCS_FLAGS = /nologo /optimize PLATFORM_RUNTIME = PLATFORM_CORLIB = mscorlib.dll BOOTSTRAP_MCS = csc.exe MCS = $(BOOTSTRAP_MCS) RESGEN = resgen.exe PLATFORM_MAKE_CORLIB_CMP = yes PLATFORM_CHANGE_SEPARATOR_CMD=tr '/' '\\\\' PLATFORM_PATH_SEPARATOR = ; hidden_prefix = hidden_suffix = .tmp platform-check: |
From: <mas...@us...> - 2004-10-06 19:31:41
|
Update of /cvsroot/csdoc/csdoc/src/mcs/build/deps In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv20482/deps Added Files: .cvsignore Log Message: no message --- NEW FILE: .cvsignore --- *.makefrag *.response *.stamp *.was_signed |
From: <mas...@us...> - 2004-10-06 19:31:41
|
Update of /cvsroot/csdoc/csdoc/src/mcs/build In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv20482 Added Files: config-default.make executable.make library.make rules.make Log Message: no message --- NEW FILE: config-default.make --- # -*- makefile -*- # # This makefile fragment has (default) configuration # settings for building MCS. # DO NOT EDIT THIS FILE! Create config.make and override settings # there. RUNTIME_FLAGS = TEST_HARNESS = $(topdir)/class/lib/$(PROFILE)/nunit-console.exe MCS_FLAGS = $(PLATFORM_DEBUG_FLAGS) MBAS_FLAGS = $(PLATFORM_DEBUG_FLAGS) LIBRARY_FLAGS = /noconfig CFLAGS = -g -O2 INSTALL = /usr/bin/install prefix = /usr/local RUNTIME = mono $(RUNTIME_FLAGS) TEST_RUNTIME = MONO_PATH="$(topdir)/class/lib/$(PROFILE)$(PLATFORM_PATH_SEPARATOR)$$MONO_PATH" $(RUNTIME) --debug # In case you want to add MCS_FLAGS, this lets you not have to # keep track of the default value DEFAULT_MCS_FLAGS := $(MCS_FLAGS) DEFAULT_MBAS_FLAGS := $(MBAS_FLAGS) # You shouldn't need to set these but might on a # weird platform. # CC = cc # SHELL = /bin/sh # MAKE = gmake --- NEW FILE: executable.make --- # -*- makefile -*- # # The rules for building a program. # I'd rather not create a response file here, # but since on Win32 we need to munge the paths # anyway, we might as well. base_prog = $(shell basename $(PROGRAM)) sourcefile = $(base_prog).sources PROGRAM_config := $(wildcard $(PROGRAM).config) ifeq (cat,$(PLATFORM_CHANGE_SEPARATOR_CMD)) response = $(sourcefile) else response = $(depsdir)/$(base_prog).response executable_CLEAN_FILES += $(response) endif makefrag = $(depsdir)/$(base_prog).makefrag pdb = $(patsubst %.exe,%.pdb,$(PROGRAM)) mdb = $(patsubst %.exe,%.mdb,$(PROGRAM)) executable_CLEAN_FILES += $(makefrag) $(pdb) $(mdb) ifndef PROGRAM_INSTALL_DIR PROGRAM_INSTALL_DIR = $(prefix)/bin endif all-local: $(PROGRAM) install-local: $(PROGRAM) $(PROGRAM_config) $(MKINSTALLDIRS) $(DESTDIR)$(PROGRAM_INSTALL_DIR) $(INSTALL_BIN) $(PROGRAM) $(DESTDIR)$(PROGRAM_INSTALL_DIR) -$(INSTALL_BIN) $(PROGRAM).mdb $(DESTDIR)$(PROGRAM_INSTALL_DIR) ifdef PROGRAM_config $(INSTALL_DATA) $(PROGRAM_config) $(DESTDIR)$(PROGRAM_INSTALL_DIR) endif uninstall-local: -rm -f $(DESTDIR)$(PROGRAM_INSTALL_DIR)/$(base_prog) $(DESTDIR)$(PROGRAM_INSTALL_DIR)/$(base_prog).mdb clean-local: -rm -f *.exe $(BUILT_SOURCES) $(executable_CLEAN_FILES) $(CLEAN_FILES) test-local: $(PROGRAM) @: run-test-local: @: run-test-ondotnet-local: @: DISTFILES = $(sourcefile) $(EXTRA_DISTFILES) dist-local: dist-default for f in `cat $(sourcefile)` ; do \ dest=`dirname $(distdir)/$$f` ; \ $(MKINSTALLDIRS) $$dest && cp $$f $$dest || exit 1 ; \ done ifndef PROGRAM_COMPILE echo CSCOMPILE = $(CSCOMPILE) PROGRAM_COMPILE = $(CSCOMPILE) endif $(PROGRAM): $(BUILT_SOURCES) $(EXTRA_SOURCES) $(response) $(PROGRAM_COMPILE) /target:exe /out:$@ $(BUILT_SOURCES) $(EXTRA_SOURCES) @$(response) $(makefrag): $(sourcefile) @echo Creating $@ ... @sed 's,^,$(PROGRAM): ,' $< > $@ ifneq ($(response),$(sourcefile)) $(response): $(sourcefile) @echo Creating $@ ... @( $(PLATFORM_CHANGE_SEPARATOR_CMD) ) <$< >$@ endif -include $(makefrag) all-local: $(makefrag) $(makefrag): $(topdir)/build/executable.make --- NEW FILE: library.make --- # -*- makefile -*- # # The rules for building our class libraries. # # The NO_TEST stuff is not too pleasant but whatcha # gonna do. # All the dep files now land in the same directory so we # munge in the library name to keep the files from clashing. sourcefile = $(LIBRARY).sources PLATFORM_excludes := $(wildcard $(LIBRARY).$(PLATFORM)-excludes) ifndef PLATFORM_excludes ifeq (cat,$(PLATFORM_CHANGE_SEPARATOR_CMD)) response = $(sourcefile) endif endif ifndef response response = $(depsdir)/$(PROFILE)_$(LIBRARY).response library_CLEAN_FILES += $(response) $(LIBRARY).mdb endif ifndef LIBRARY_NAME LIBRARY_NAME = $(LIBRARY) endif makefrag = $(depsdir)/$(PROFILE)_$(LIBRARY).makefrag the_lib = $(topdir)/class/lib/$(PROFILE)/$(LIBRARY_NAME) the_lib_signature_stamp = $(makefrag:.makefrag=.was_signed) the_pdb = $(the_lib:.dll=.pdb) the_mdb = $(the_lib).mdb library_CLEAN_FILES += $(makefrag) $(the_lib) $(the_pdb) \ $(the_mdb) $(the_lib_signature_stamp) ifndef NO_TEST test_nunit_lib = nunit.framework.dll nunit.core.dll nunit.util.dll test_nunit_dep = $(test_nunit_lib:%=$(topdir)/class/lib/$(PROFILE)/%) test_nunit_ref = $(test_nunit_dep:%=-r:%) library_CLEAN_FILES += TestResult*.xml ifndef test_against test_against = $(the_lib) test_dep = $(the_lib) endif ifndef test_lib test_lib = $(LIBRARY:.dll=_test_$(PROFILE).dll) test_sourcefile = $(LIBRARY:.dll=_test.dll.sources) else test_sourcefile = $(test_lib).sources endif test_pdb = $(test_lib:.dll=.pdb) test_response = $(depsdir)/$(test_lib).response test_makefrag = $(depsdir)/$(test_lib).makefrag test_flags = /r:$(test_against) $(test_nunit_ref) $(TEST_MCS_FLAGS) library_CLEAN_FILES += $(LIBRARY:.dll=_test*.dll) $(LIBRARY:.dll=_test*.pdb) $(test_response) $(test_makefrag) ifndef btest_lib btest_lib = $(LIBRARY:.dll=_btest_$(PROFILE).dll) btest_sourcefile = $(LIBRARY:.dll=_btest.dll.sources) else btest_sourcefile = $(btest_lib).sources endif btest_pdb = $(btest_lib:.dll=.pdb) btest_response = $(depsdir)/$(btest_lib).response btest_makefrag = $(depsdir)/$(btest_lib).makefrag btest_flags = /r:$(test_against) $(test_nunit_ref) $(TEST_MBAS_FLAGS) library_CLEAN_FILES += $(LIBRARY:.dll=_btest*.dll) $(LIBRARY:.dll=_btest*.pdb) $(btest_response) $(btest_makefrag) ifndef HAVE_CS_TESTS HAVE_CS_TESTS := $(wildcard $(test_sourcefile)) endif ifndef HAVE_VB_TESTS HAVE_VB_TESTS := $(wildcard $(btest_sourcefile)) endif endif gacutil = $(topdir)/tools/gacutil/gacutil.exe sn = $(topdir)/tools/security/sn.exe PACKAGE = 1.0 ifeq ($(PROFILE), net_2_0) PACKAGE = 2.0 endif ifeq ($(PLATFORM), win32) GACDIR = `cygpath -w $(DESTDIR)$(prefix)/lib` else GACDIR = $(DESTDIR)$(prefix)/lib endif all-local install-local test-local: $(the_lib) ifdef LIBRARY_INSTALL_DIR install-local: $(MKINSTALLDIRS) $(DESTDIR)$(LIBRARY_INSTALL_DIR) $(INSTALL_LIB) $(the_lib) $(DESTDIR)$(LIBRARY_INSTALL_DIR)/$(LIBRARY_NAME) -$(INSTALL_LIB) $(the_lib).mdb $(DESTDIR)$(LIBRARY_INSTALL_DIR)/$(LIBRARY_NAME).mdb uninstall-local: -rm -f $(DESTDIR)$(LIBRARY_INSTALL_DIR)/$(LIBRARY_NAME) $(DESTDIR)$(LIBRARY_INSTALL_DIR)/$(LIBRARY_NAME).mdb else install-local: $(gacutil) MONO_PATH="$(topdir)/class/lib/$(PROFILE):$$MONO_PATH" $(RUNTIME) $(gacutil) /i $(the_lib) /f /root $(GACDIR) /package $(PACKAGE) uninstall-local: $(gacutil) MONO_PATH="$(topdir)/class/lib/$(PROFILE):$$MONO_PATH" $(RUNTIME) $(gacutil) /u $(LIBRARY_NAME:.dll=) endif ifndef NO_SIGN_ASSEMBLY all-local install-local: $(the_lib_signature_stamp) ifndef LIBRARY_SNK LIBRARY_SNK = $(topdir)/class/mono.snk endif $(the_lib_signature_stamp): $(the_lib) $(sn) MONO_PATH="$(topdir)/class/lib/$(PROFILE):$$MONO_PATH" $(RUNTIME) $(sn) -q -R $(the_lib) $(LIBRARY_SNK) echo stamp > $@ endif clean-local: -rm -f $(library_CLEAN_FILES) $(CLEAN_FILES) test-local run-test-local run-test-ondotnet-local: @: ifndef NO_TEST $(test_nunit_dep): $(topdir)/build/deps/nunit-$(PROFILE).stamp @if test -f $@; then :; else rm -f $<; $(MAKE) $<; fi $(topdir)/build/deps/nunit-$(PROFILE).stamp: cd ${topdir}/nunit20 && $(MAKE) echo "stamp" >$@ endif test_assemblies := ifdef HAVE_CS_TESTS test_assemblies += $(test_lib) endif ifdef HAVE_VB_TESTS test_assemblies += $(btest_lib) endif ifdef test_assemblies test-local: $(test_assemblies) run-test-local: run-test-lib run-test-ondotnet-local: run-test-ondotnet-lib run-test-lib: test-local $(TEST_RUNTIME) $(TEST_HARNESS) /xml:TestResult-$(PROFILE).xml $(test_assemblies) run-test-ondotnet-lib: test-local $(TEST_HARNESS) /xml:TestResult-ondotnet-$(PROFILE).xml $(test_assemblies) endif DISTFILES = $(sourcefile) $(test_sourcefile) $(EXTRA_DISTFILES) TEST_FILES = ifdef HAVE_CS_TESTS TEST_FILES += `sed 's,^,Test/,' $(test_sourcefile)` endif ifdef HAVE_VB_TESTS TEST_FILES += `sed 's,^,Test/,' $(btest_sourcefile)` endif dist-local: dist-default for f in `cat $(sourcefile)` $(TEST_FILES) ; do \ case $$f in \ ../*) : ;; \ *) dest=`dirname $(distdir)/$$f` ; $(MKINSTALLDIRS) $$dest && cp $$f $$dest || exit 1 ;; \ esac ; done ifndef LIBRARY_COMPILE LIBRARY_COMPILE = $(CSCOMPILE) endif ifndef TEST_COMPILE TEST_COMPILE = $(CSCOMPILE) endif ifndef BTEST_COMPILE BTEST_COMPILE = $(BASCOMPILE) endif $(gacutil) $(sn): cd $(@D) && $(MAKE) $(@F) # The library $(the_lib): $(response) ifdef LIBRARY_USE_INTERMEDIATE_FILE $(LIBRARY_COMPILE) $(LIBRARY_FLAGS) $(LIB_MCS_FLAGS) /target:library /out:$(@F) @$(response) mv $(@F) $@ -mv $(@F).mdb $@.mdb else $(LIBRARY_COMPILE) $(LIBRARY_FLAGS) $(LIB_MCS_FLAGS) /target:library /out:$@ @$(response) endif $(makefrag): $(sourcefile) @echo Creating $@ ... @sed 's,^,$(the_lib): ,' $< >$@ ifneq ($(response),$(sourcefile)) $(response): $(sourcefile) $(PLATFORM_excludes) @echo Creating $@ ... @sort $(sourcefile) $(PLATFORM_excludes) | uniq -u | $(PLATFORM_CHANGE_SEPARATOR_CMD) >$@ endif -include $(makefrag) # for now, don't give any /lib flags or set MONO_PATH, since we # give a full path to the assembly. ifdef HAVE_CS_TESTS $(test_lib): $(test_dep) $(test_response) $(test_nunit_dep) $(TEST_COMPILE) /target:library /out:$@ $(test_flags) @$(test_response) $(test_response): $(test_sourcefile) @echo Creating $@ ... @sed 's,^,Test/,' $(test_sourcefile) | $(PLATFORM_CHANGE_SEPARATOR_CMD) >$@ $(test_makefrag): $(test_response) @echo Creating $@ ... @sed 's,^,$(test_lib): ,' $< >$@ -include $(test_makefrag) endif ifdef HAVE_VB_TESTS $(btest_lib): $(test_dep) $(btest_response) $(test_nunit_dep) $(BTEST_COMPILE) /target:library /out:$@ $(btest_flags) @$(btest_response) $(btest_response): $(btest_sourcefile) @echo Creating $@ ... @sed 's,^,Test/,' $(btest_sourcefile) | $(PLATFORM_CHANGE_SEPARATOR_CMD) >$@ $(btest_makefrag): $(btest_response) @echo Creating $@ ... @sed 's,^,$(btest_lib): ,' $< >$@ -include $(btest_makefrag) endif all-local: $(makefrag) $(test_makefrag) $(btest_makefrag) $(makefrag) $(test_makefrag) $(btest_makefrag): $(topdir)/build/library.make --- NEW FILE: rules.make --- # -*- makefile -*- # # This is the makefile fragment with default rules # for building things in MCS # # To customize the build, you should edit config.make. # If you need to edit this file, that's a bug; email # pe...@ne... about it. # Some more variables. The leading period in the sed expression prevents # thisdir = . from being changed into '..' for the toplevel directory. dots := $(shell echo $(thisdir) |sed -e 's,[^./][^/]*,..,g') topdir := $(dots) VERSION = 0.93 USE_MCS_FLAGS = $(LOCAL_MCS_FLAGS) $(PLATFORM_MCS_FLAGS) $(PROFILE_MCS_FLAGS) $(MCS_FLAGS) USE_MBAS_FLAGS = $(LOCAL_MBAS_FLAGS) $(PLATFORM_MBAS_FLAGS) $(PROFILE_MBAS_FLAGS) $(MBAS_FLAGS) USE_CFLAGS = $(LOCAL_CFLAGS) $(CFLAGS) CSCOMPILE = $(MCS) $(USE_MCS_FLAGS) BASCOMPILE = $(MBAS) $(USE_MBAS_FLAGS) CCOMPILE = $(CC) $(USE_CFLAGS) BOOT_COMPILE = $(BOOTSTRAP_MCS) $(USE_MCS_FLAGS) INSTALL_DATA = $(INSTALL) -m 644 INSTALL_BIN = $(INSTALL) -m 755 INSTALL_LIB = $(INSTALL_BIN) MKINSTALLDIRS = $(SHELL) $(topdir)/mkinstalldirs INTERNAL_MCS = $(RUNTIME) $(topdir)/mcs/mcs.exe INTERNAL_MBAS = $(RUNTIME) $(topdir)/mbas/mbas.exe INTERNAL_GMCS = $(RUNTIME) $(topdir)/gmcs/gmcs.exe INTERNAL_ILASM = $(RUNTIME) $(topdir)/ilasm/ilasm.exe INTERNAL_RESGEN = $(RUNTIME) $(topdir)/monoresgen/monoresgen.exe corlib = mscorlib.dll depsdir = $(topdir)/build/deps distdir = $(dots)/$(package)/$(thisdir) # Make sure these propagate if set manually export PLATFORM export PROFILE export MCS export MCS_FLAGS export CC export CFLAGS export INSTALL export MKINSTALLDIRS export TEST_HARNESS export BOOTSTRAP_MCS export DESTDIR export RESGEN # Get this so the platform.make platform-check rule doesn't become the # default target .DEFAULT: all default: all # Get initial configuration. pre-config is so that the builder can # override PLATFORM or PROFILE include $(topdir)/build/config-default.make -include $(topdir)/build/pre-config.make # Default PLATFORM and PROFILE if they're not already defined. ifndef PLATFORM ifeq ($(OS),Windows_NT) PLATFORM = win32 else PLATFORM = linux endif endif # Platform config include $(topdir)/build/platforms/$(PLATFORM).make ifdef PLATFORM_CORLIB corlib = $(PLATFORM_CORLIB) endif # Useful ifeq ($(PLATFORM_RUNTIME),$(RUNTIME)) PLATFORM_MONO_NATIVE = yes endif # Rest of the configuration ifndef PROFILE PROFILE = default endif include $(topdir)/build/profiles/$(PROFILE).make -include $(topdir)/build/config.make ifdef OVERRIDE_TARGET_ALL all: all.override else all: all.real endif all.real: all-recursive $(MAKE) all-local STD_TARGETS = test run-test run-test-ondotnet clean install uninstall $(STD_TARGETS): %: %-recursive $(MAKE) $@-local %-recursive: @set . $$MAKEFLAGS; \ case $$2 in --unix) shift ;; esac; \ case $$2 in *=*) dk="exit 1" ;; *k*) dk=: ;; *) dk="exit 1" ;; esac; \ list='$(SUBDIRS)'; for d in $$list ; do \ (cd $$d && $(MAKE) $*) || $$dk ; \ done # note: dist-local dep, extra subdirs, we invoke dist-recursive in the subdir too dist-recursive: dist-local @list='$(SUBDIRS) $(DIST_ONLY_SUBDIRS)'; for d in $$list ; do \ (cd $$d && $(MAKE) $@) || exit 1 ; \ done # Can only do this from the top dir # ## dist: dist-recursive dist-local # We invert the test here to not end in an error # if ChangeLog doesn't exist. # # Note that we error out if we try to dist a nonexistant # file. Seems reasonable to me. # # Pick up Makefile, makefile, or GNUmakefile dist-default: -mkdir -p $(distdir) test '!' -f ChangeLog || cp ChangeLog $(distdir) if test -f Makefile; then m=M; fi; \ if test -f makefile; then m=m; fi; \ if test -f GNUmakefile; then m=GNUm; fi; \ for f in $${m}akefile $(DISTFILES) ; do \ dest=`dirname $(distdir)/$$f` ; \ $(MKINSTALLDIRS) $$dest && cp $$f $$dest || exit 1 ; \ done # Useful withmcs: $(MAKE) MCS='$(INTERNAL_MCS)' BOOTSTRAP_MCS='$(INTERNAL_MCS)' all |
From: <mas...@us...> - 2004-10-06 19:31:31
|
Update of /cvsroot/csdoc/csdoc/src/mcs/mcs In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv20361 Modified Files: .cvsignore Added Files: compiler.csproj Log Message: no message --- NEW FILE: compiler.csproj --- <VisualStudioProject> <CSHARP ProjectType = "Local" ProductVersion = "7.10.3077" SchemaVersion = "2.0" ProjectGuid = "{896D1461-B76B-41C0-ABE6-ACA2BB4F7B5A}" > <Build> <Settings ApplicationIcon = "" AssemblyKeyContainerName = "" AssemblyName = "mcs" AssemblyOriginatorKeyFile = "" DefaultClientScript = "JScript" DefaultHTMLPageLayout = "Grid" DefaultTargetSchema = "IE50" DelaySign = "false" OutputType = "Exe" PreBuildEvent = "" PostBuildEvent = "" RootNamespace = "CIR" RunPostBuildEvent = "OnBuildSuccess" StartupObject = "" > <Config Name = "Debug" AllowUnsafeBlocks = "false" BaseAddress = "285212672" CheckForOverflowUnderflow = "false" ConfigurationOverrideFile = "" DefineConstants = "DEBUG;TRACE" DocumentationFile = "" DebugSymbols = "true" FileAlignment = "4096" IncrementalBuild = "false" NoStdLib = "false" NoWarn = "" Optimize = "false" OutputPath = ".\" 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" NoStdLib = "false" NoWarn = "" Optimize = "true" OutputPath = "bin\Release\" RegisterForComInterop = "false" RemoveIntegerChecks = "false" TreatWarningsAsErrors = "false" WarningLevel = "4" /> </Settings> <References> <Reference Name = "System" AssemblyName = "System" /> </References> </Build> <Files> <Include> <File RelPath = "anonymous.cs" SubType = "Code" BuildAction = "Compile" /> <File RelPath = "AssemblyInfo.cs" SubType = "Code" BuildAction = "Compile" /> <File RelPath = "assign.cs" SubType = "Code" BuildAction = "Compile" /> <File RelPath = "attribute.cs" SubType = "Code" BuildAction = "Compile" /> <File RelPath = "cfold.cs" SubType = "Code" BuildAction = "Compile" /> <File RelPath = "class.cs" SubType = "Code" BuildAction = "Compile" /> <File RelPath = "codegen.cs" SubType = "Code" BuildAction = "Compile" /> <File RelPath = "const.cs" SubType = "Code" BuildAction = "Compile" /> <File RelPath = "constant.cs" SubType = "Code" BuildAction = "Compile" /> <File RelPath = "convert.cs" SubType = "Code" BuildAction = "Compile" /> <File RelPath = "CryptoConvert.cs" Link = "..\class\corlib\Mono.Security.Cryptography\CryptoConvert.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 = "delegate.cs" SubType = "Code" BuildAction = "Compile" /> <File RelPath = "driver.cs" SubType = "Code" BuildAction = "Compile" /> <File RelPath = "ecore.cs" SubType = "Code" BuildAction = "Compile" /> <File RelPath = "enum.cs" SubType = "Code" BuildAction = "Compile" /> <File RelPath = "expression.cs" SubType = "Code" BuildAction = "Compile" /> <File RelPath = "flowanalysis.cs" SubType = "Code" BuildAction = "Compile" /> <File RelPath = "iterators.cs" SubType = "Code" BuildAction = "Compile" /> <File RelPath = "literal.cs" SubType = "Code" BuildAction = "Compile" /> <File RelPath = "location.cs" SubType = "Code" BuildAction = "Compile" /> <File RelPath = "modifiers.cs" SubType = "Code" BuildAction = "Compile" /> <File RelPath = "MonoSymbolFile.cs" Link = "..\class\Mono.CSharp.Debugger\MonoSymbolFile.cs" SubType = "Code" BuildAction = "Compile" /> <File RelPath = "MonoSymbolTable.cs" Link = "..\class\Mono.CSharp.Debugger\MonoSymbolTable.cs" SubType = "Code" BuildAction = "Compile" /> <File RelPath = "MonoSymbolWriter.cs" Link = "..\class\Mono.CSharp.Debugger\MonoSymbolWriter.cs" SubType = "Code" BuildAction = "Compile" /> <File RelPath = "namespace.cs" SubType = "Code" BuildAction = "Compile" /> <File RelPath = "parameter.cs" SubType = "Code" BuildAction = "Compile" /> <File RelPath = "pending.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 = "support.cs" SubType = "Code" BuildAction = "Compile" /> <File RelPath = "symbolwriter.cs" SubType = "Code" BuildAction = "Compile" /> <File RelPath = "tree.cs" SubType = "Code" BuildAction = "Compile" /> <File RelPath = "typemanager.cs" SubType = "Code" BuildAction = "Compile" /> <Folder RelPath = "Web References\" WebReferences = "TRUE" /> </Include> </Files> </CSHARP> </VisualStudioProject> Index: .cvsignore =================================================================== RCS file: /cvsroot/csdoc/csdoc/src/mcs/mcs/.cvsignore,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** .cvsignore 6 Oct 2004 19:28:29 -0000 1.1 --- .cvsignore 6 Oct 2004 19:30:51 -0000 1.2 *************** *** 5,9 **** Web References bin - compiler.csproj compiler.csproj.user compiler.exe --- 5,8 ---- |
Update of /cvsroot/csdoc/csdoc/src/mcs/mcs In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv19706 Added Files: .cvsignore anonymous.cs AssemblyInfo.cs assign.cs attribute.cs cfold.cs ChangeLog class.cs codegen.cs compiler.doc compiler.sln const.cs constant.cs convert.cs cs-parser.jay cs-tokenizer.cs decl.cs delegate.cs driver.cs ecore.cs enum.cs errors.cs expression.cs flowanalysis.cs gen-il.cs gen-treedump.cs generic.cs genericparser.cs interface.cs iterators.cs literal.cs location.cs makefile makefile.gnu makefile.old mcs.exe.config mcs.exe.sources modifiers.cs namespace.cs NOTES old-code.cs OTODO parameter.cs parameterCollection.cs parser.cs pending.cs README report.cs rootcontext.cs statement.cs statementCollection.cs support.cs symbolwriter.cs TODO tree.cs typemanager.cs Log Message: Cleanup. All files have been moved to mcs --- NEW FILE: .cvsignore --- *.mdb *.pdb Web References Web References Web References bin compiler.csproj compiler.csproj.user compiler.exe compiler.pdb compiler.suo cs-parser.cs mcs obj semantic.cache y.output --- NEW FILE: anonymous.cs --- // // anonymous.cs: Support for anonymous methods // // Author: // Miguel de Icaza (mi...@xi...) // // (C) 2003 Ximian, Inc. // using System; using System.Collections; using System.Reflection; using System.Reflection.Emit; namespace Mono.CSharp { public class AnonymousMethod : Expression { // An array list of AnonymousMethodParameter or null Parameters parameters; Block block; public AnonymousMethod (Parameters parameters, Block block, Location l) { this.parameters = parameters; this.block = block; loc = l; } public override Expression DoResolve (EmitContext ec) { // // Set class type, set type // eclass = ExprClass.Value; // // This hack means `The type is not accessible // anywhere', we depend on special conversion // rules. // type = typeof (AnonymousMethod); return this; } public override void Emit (EmitContext ec) { // nothing, as we only exist to not do anything. } } } --- NEW FILE: AssemblyInfo.cs --- using System.Reflection; using System.Runtime.CompilerServices; [assembly: AssemblyVersion("1.1.1")] [assembly: AssemblyTitle ("Mono C# Compiler")] [assembly: AssemblyDescription ("Mono C# Compiler")] [assembly: AssemblyCopyright ("2001, 2002, 2003 Ximian, Inc.")] [assembly: AssemblyCompany ("Ximian, Inc.")] --- NEW FILE: assign.cs --- // // assign.cs: Assignments. // // Author: // Miguel de Icaza (mi...@xi...) // Martin Baulig (ma...@gn...) // // (C) 2001, 2002, 2003 Ximian, Inc. // using System; using System.Reflection; using System.Reflection.Emit; namespace Mono.CSharp { /// <summary> /// This interface is implemented by expressions that can be assigned to. /// </summary> /// <remarks> /// This interface is implemented by Expressions whose values can not /// store the result on the top of the stack. /// /// Expressions implementing this (Properties, Indexers and Arrays) would /// perform an assignment of the Expression "source" into its final /// location. /// /// No values on the top of the stack are expected to be left by /// invoking this method. /// </remarks> public interface IAssignMethod { // // This is an extra version of Emit. If leave_copy is `true' // A copy of the expression will be left on the stack at the // end of the code generated for EmitAssign // void Emit (EmitContext ec, bool leave_copy); // // This method does the assignment // `source' will be stored into the location specified by `this' // if `leave_copy' is true, a copy of `source' will be left on the stack // if `prepare_for_load' is true, when `source' is emitted, there will // be data on the stack that it can use to compuatate its value. This is // for expressions like a [f ()] ++, where you can't call `f ()' twice. // void EmitAssign (EmitContext ec, Expression source, bool leave_copy, bool prepare_for_load); /* For simple assignments, this interface is very simple, EmitAssign is called with source as the source expression and leave_copy and prepare_for_load false. For compound assignments it gets complicated. EmitAssign will be called as before, however, prepare_for_load will be true. The @source expression will contain an expression which calls Emit. So, the calls look like: this.EmitAssign (ec, source, false, true) -> source.Emit (ec); -> [...] -> this.Emit (ec, false); -> end this.Emit (ec, false); -> end [...] end source.Emit (ec); end this.EmitAssign (ec, source, false, true) When prepare_for_load is true, EmitAssign emits a `token' on the stack that Emit will use for its state. Let's take FieldExpr as an example. assume we are emitting f ().y += 1; Here is the call tree again. This time, each call is annotated with the IL it produces: this.EmitAssign (ec, source, false, true) call f dup Binary.Emit () this.Emit (ec, false); ldfld y end this.Emit (ec, false); IntConstant.Emit () ldc.i4.1 end IntConstant.Emit add end Binary.Emit () stfld end this.EmitAssign (ec, source, false, true) Observe two things: 1) EmitAssign left a token on the stack. It was the result of f (). 2) This token was used by Emit leave_copy (in both EmitAssign and Emit) tells the compiler to leave a copy of the expression at that point in evaluation. This is used for pre/post inc/dec and for a = x += y. Let's do the above example with leave_copy true in EmitAssign this.EmitAssign (ec, source, true, true) call f dup Binary.Emit () this.Emit (ec, false); ldfld y end this.Emit (ec, false); IntConstant.Emit () ldc.i4.1 end IntConstant.Emit add end Binary.Emit () dup stloc temp stfld ldloc temp end this.EmitAssign (ec, source, true, true) And with it true in Emit this.EmitAssign (ec, source, false, true) call f dup Binary.Emit () this.Emit (ec, true); ldfld y dup stloc temp end this.Emit (ec, true); IntConstant.Emit () ldc.i4.1 end IntConstant.Emit add end Binary.Emit () stfld ldloc temp end this.EmitAssign (ec, source, false, true) Note that these two examples are what happens for ++x and x++, respectively. */ } /// <summary> /// An Expression to hold a temporary value. /// </summary> /// <remarks> /// The LocalTemporary class is used to hold temporary values of a given /// type to "simulate" the expression semantics on property and indexer /// access whose return values are void. /// /// The local temporary is used to alter the normal flow of code generation /// basically it creates a local variable, and its emit instruction generates /// code to access this value, return its address or save its value. /// /// If `is_address' is true, then the value that we store is the address to the /// real value, and not the value itself. /// /// This is needed for a value type, because otherwise you just end up making a /// copy of the value on the stack and modifying it. You really need a pointer /// to the origional value so that you can modify it in that location. This /// Does not happen with a class because a class is a pointer -- so you always /// get the indirection. /// /// The `is_address' stuff is really just a hack. We need to come up with a better /// way to handle it. /// </remarks> public class LocalTemporary : Expression, IMemoryLocation { LocalBuilder builder; bool is_address; public LocalTemporary (EmitContext ec, Type t) : this (ec, t, false) {} public LocalTemporary (EmitContext ec, Type t, bool is_address) { type = t; eclass = ExprClass.Value; loc = Location.Null; builder = ec.GetTemporaryLocal (is_address ? TypeManager.GetReferenceType (t): t); this.is_address = is_address; } public LocalTemporary (LocalBuilder b, Type t) { type = t; eclass = ExprClass.Value; loc = Location.Null; builder = b; } public void Release (EmitContext ec) { ec.FreeTemporaryLocal (builder, type); builder = null; } public override Expression DoResolve (EmitContext ec) { return this; } public override void Emit (EmitContext ec) { ILGenerator ig = ec.ig; ig.Emit (OpCodes.Ldloc, builder); // we need to copy from the pointer if (is_address) LoadFromPtr (ig, type); } // NB: if you have `is_address' on the stack there must // be a managed pointer. Otherwise, it is the type from // the ctor. public void Store (EmitContext ec) { ILGenerator ig = ec.ig; ig.Emit (OpCodes.Stloc, builder); } public void AddressOf (EmitContext ec, AddressOp mode) { // if is_address, than this is just the address anyways, // so we just return this. ILGenerator ig = ec.ig; if (is_address) ig.Emit (OpCodes.Ldloc, builder); else ig.Emit (OpCodes.Ldloca, builder); } public bool PointsToAddress { get { return is_address; } } } /// <summary> /// The Assign node takes care of assigning the value of source into /// the expression represented by target. /// </summary> public class Assign : ExpressionStatement { protected Expression target, source, real_source; protected LocalTemporary temp = null, real_temp = null; protected Assign embedded = null; protected bool is_embedded = false; protected bool must_free_temp = false; public Assign (Expression target, Expression source, Location l) { this.target = target; this.source = this.real_source = source; this.loc = l; } protected Assign (Assign embedded, Location l) : this (embedded.target, embedded.source, l) { this.is_embedded = true; } protected virtual Assign GetEmbeddedAssign (Location loc) { return new Assign (this, loc); } public Expression Target { get { return target; } set { target = value; } } public Expression Source { get { return source; } set { source = value; } } public static void error70 (EventInfo ei, Location l) { Report.Error (70, l, "The event '" + ei.Name + "' can only appear on the left-side of a += or -= (except when" + " used from within the type '" + ei.DeclaringType + "')"); } // // Will return either `this' or an instance of `New'. // public override Expression DoResolve (EmitContext ec) { // Create an embedded assignment if our source is an assignment. if (source is Assign) source = embedded = ((Assign) source).GetEmbeddedAssign (loc); real_source = source = source.Resolve (ec); if (source == null) return null; // // This is used in an embedded assignment. // As an example, consider the statement "A = X = Y = Z". // if (is_embedded && !(source is Constant)) { // If this is the innermost assignment (the "Y = Z" in our example), // create a new temporary local, otherwise inherit that variable // from our child (the "X = (Y = Z)" inherits the local from the // "Y = Z" assignment). if (embedded == null) { if (this is CompoundAssign) real_temp = temp = new LocalTemporary (ec, target.Type); else real_temp = temp = new LocalTemporary (ec, source.Type); } else temp = embedded.temp; // Set the source to the new temporary variable. // This means that the following target.ResolveLValue () will tell // the target to read it's source value from that variable. source = temp; } // If we have an embedded assignment, use the embedded assignment's temporary // local variable as source. if (embedded != null) source = (embedded.temp != null) ? embedded.temp : embedded.source; target = target.ResolveLValue (ec, source); if (target == null) return null; Type target_type = target.Type; Type source_type = real_source.Type; // If we're an embedded assignment, our parent will reuse our source as its // source, it won't read from our target. if (is_embedded) type = source_type; else type = target_type; eclass = ExprClass.Value; if (target is EventExpr) { EventInfo ei = ((EventExpr) target).EventInfo; Expression ml = MemberLookup ( ec, ec.ContainerType, ei.Name, MemberTypes.Event, AllBindingFlags | BindingFlags.DeclaredOnly, loc); if (ml == null) { // // If this is the case, then the Event does not belong // to this Type and so, according to the spec // is allowed to only appear on the left hand of // the += and -= operators // // Note that target will not appear as an EventExpr // in the case it is being referenced within the same type container; // it will appear as a FieldExpr in that case. // if (!(source is BinaryDelegate)) { error70 (ei, loc); return null; } } } if (source is New && target_type.IsValueType && (target.eclass != ExprClass.IndexerAccess) && (target.eclass != ExprClass.PropertyAccess)){ New n = (New) source; if (n.SetValueTypeVariable (target)) return n; else return null; } if (!(target is IAssignMethod) && (target.eclass != ExprClass.EventAccess)) { Report.Error (131, loc, "Left hand of an assignment must be a variable, " + "a property or an indexer"); return null; } if ((source.eclass == ExprClass.Type) && (source is TypeExpr)) { source.Error_UnexpectedKind ("variable or value", loc); return null; } else if ((RootContext.Version == LanguageVersion.ISO_1) && (source is MethodGroupExpr)){ ((MethodGroupExpr) source).ReportUsageError (); return null; } if (target_type == source_type) return this; // // If this assignemnt/operator was part of a compound binary // operator, then we allow an explicit conversion, as detailed // in the spec. // if (this is CompoundAssign){ CompoundAssign a = (CompoundAssign) this; Binary b = source as Binary; if (b != null){ // // 1. if the source is explicitly convertible to the // target_type // source = Convert.ExplicitConversion (ec, source, target_type, loc); if (source == null){ Convert.Error_CannotImplicitConversion (loc, source_type, target_type); return null; } // // 2. and the original right side is implicitly convertible to // the type of target // if (Convert.ImplicitStandardConversionExists (a.original_source, target_type)) return this; // // In the spec 2.4 they added: or if type of the target is int // and the operator is a shift operator... // if (source_type == TypeManager.int32_type && (b.Oper == Binary.Operator.LeftShift || b.Oper == Binary.Operator.RightShift)) return this; Convert.Error_CannotImplicitConversion (loc, a.original_source.Type, target_type); return null; } } source = Convert.ImplicitConversionRequired (ec, source, target_type, loc); if (source == null) return null; // If we're an embedded assignment, we need to create a new temporary variable // for the converted value. Our parent will use this new variable as its source. // The same applies when we have an embedded assignment - in this case, we need // to convert our embedded assignment's temporary local variable to the correct // type and store it in a new temporary local. if (is_embedded || embedded != null) { type = target_type; temp = new LocalTemporary (ec, type); must_free_temp = true; } return this; } Expression EmitEmbedded (EmitContext ec) { // Emit an embedded assignment. if (real_temp != null) { // If we're the innermost assignment, `real_source' is the right-hand // expression which gets assigned to all the variables left of it. // Emit this expression and store its result in real_temp. real_source.Emit (ec); real_temp.Store (ec); } if (embedded != null) embedded.EmitEmbedded (ec); // This happens when we've done a type conversion, in this case source will be // the expression which does the type conversion from real_temp. // So emit it and store the result in temp; this is the var which will be read // by our parent. if (temp != real_temp) { source.Emit (ec); temp.Store (ec); } Expression temp_source = (temp != null) ? temp : source; ((IAssignMethod) target).EmitAssign (ec, temp_source, false, false); return temp_source; } void ReleaseEmbedded (EmitContext ec) { if (embedded != null) embedded.ReleaseEmbedded (ec); if (real_temp != null) real_temp.Release (ec); if (must_free_temp) temp.Release (ec); } void Emit (EmitContext ec, bool is_statement) { if (target is EventExpr) { ((EventExpr) target).EmitAddOrRemove (ec, source); return; } IAssignMethod am = (IAssignMethod) target; Expression temp_source; if (embedded != null) { temp_source = embedded.EmitEmbedded (ec); if (temp != null) { source.Emit (ec); temp.Store (ec); temp_source = temp; } } else temp_source = source; am.EmitAssign (ec, temp_source, !is_statement, this is CompoundAssign); if (embedded != null) { if (temp != null) temp.Release (ec); embedded.ReleaseEmbedded (ec); } } public override void Emit (EmitContext ec) { Emit (ec, false); } public override void EmitStatement (EmitContext ec) { Emit (ec, true); } } // // This class is used for compound assignments. // class CompoundAssign : Assign { Binary.Operator op; public Expression original_source; public CompoundAssign (Binary.Operator op, Expression target, Expression source, Location l) : base (target, source, l) { original_source = source; this.op = op; } protected CompoundAssign (CompoundAssign embedded, Location l) : this (embedded.op, embedded.target, embedded.source, l) { this.is_embedded = true; } protected override Assign GetEmbeddedAssign (Location loc) { return new CompoundAssign (this, loc); } public Expression ResolveSource (EmitContext ec) { return original_source.Resolve (ec); } public override Expression DoResolve (EmitContext ec) { original_source = original_source.Resolve (ec); if (original_source == null) return null; target = target.Resolve (ec); if (target == null) return null; // // Only now we can decouple the original source/target // into a tree, to guarantee that we do not have side // effects. // source = new Binary (op, target, original_source, loc); return base.DoResolve (ec); } } } --- NEW FILE: attribute.cs --- // // attribute.cs: Attribute Handler // // Author: Ravi Pratap (ra...@xi...) // Marek Safar (mar...@se...) // // Licensed under the terms of the GNU GPL // // (C) 2001 Ximian, Inc (http://www.ximian.com) // // using System; using System.Diagnostics; using System.Collections; using System.Collections.Specialized; using System.Reflection; using System.Reflection.Emit; using System.Runtime.InteropServices; [...1409 lines suppressed...] if (excluded != null) return excluded == TRUE ? true : false; ConditionalAttribute[] attrs = mb.GetCustomAttributes (TypeManager.conditional_attribute_type, true) as ConditionalAttribute[]; if (attrs.Length == 0) { analyzed_method_excluded.Add (mb, FALSE); return false; } foreach (ConditionalAttribute a in attrs) { if (RootContext.AllDefines.Contains (a.ConditionString)) { analyzed_method_excluded.Add (mb, FALSE); return false; } } analyzed_method_excluded.Add (mb, TRUE); return true; } } } --- NEW FILE: cfold.cs --- // // cfold.cs: Constant Folding // // Author: // Miguel de Icaza (mi...@xi...) // // (C) 2002, 2003 Ximian, Inc. // using System; namespace Mono.CSharp { public class ConstantFold { // // Performs the numeric promotions on the left and right expresions // and desposits the results on `lc' and `rc'. // [...1155 lines suppressed...] ((ULongConstant) right).Value; else if (left is LongConstant) bool_res = ((LongConstant) left).Value <= ((LongConstant) right).Value; else if (left is UIntConstant) bool_res = ((UIntConstant) left).Value <= ((UIntConstant) right).Value; else if (left is IntConstant) bool_res = ((IntConstant) left).Value <= ((IntConstant) right).Value; else return null; return new BoolConstant (bool_res); } return null; } } } --- NEW FILE: ChangeLog --- 2004-10-04 Miguel de Icaza <mi...@xi...> * ecore.cs (Expression.Constantity): Add support for turning null into a constant. * const.cs (Const.Define): Allow constants to be reference types as long as the value is Null. 2004-10-04 Juraj Skripsky <js...@ho...> * namespace.cs (NamespaceEntry.Using): No matter which warning level is set, check if this namespace name has already been added. 2004-10-03 Ben Maurer <bm...@xi...> * expression.cs: reftype [!=]= null should always use br[true,false]. # 67410 2004-10-03 Marek Safar <mar...@se...> [...16743 lines suppressed...] 2001-04-27 Miguel de Icaza <mi...@xi...> * System.CodeDOM/CodeBinaryOperatorExpression.cs: Rearrange enum to match the values in System.CodeDOM. Divid renamed to Divide. * System.CodeDOM/CodeForLoopStatement.cs: Always have valid statements. (Statements.set): remove. * System.CodeDOM/CodeCatchClause.cs: always have a valid statements. * System.CodeDOM/CodeIfStatement.cs: trueStatements and falseStatements always have valid values. * cs-parser.jay: Use System.CodeDOM now. --- NEW FILE: class.cs --- // // class.cs: Class and Struct handlers // // Authors: Miguel de Icaza (mi...@gn...) // Martin Baulig (ma...@gn...) // Marek Safar (mar...@se...) // // Licensed under the terms of the GNU GPL // // (C) 2001, 2002, 2003 Ximian, Inc (http://www.ximian.com) // // // 2002-10-11 Miguel de Icaza <mi...@xi...> // // * class.cs: Following the comment from 2002-09-26 to AddMethod, I // have fixed a remaining problem: not every AddXXXX was adding a // fully qualified name. // // Now everyone registers a fully qualified name in the DeclSpace as [...7071 lines suppressed...] Type [] args; if (mi != null) args = TypeManager.GetArgumentTypes (mi); else args = TypeManager.GetArgumentTypes (pi); Type [] sigp = sig.Parameters; if (args.Length != sigp.Length) return false; for (int i = args.Length; i > 0; ){ i--; if (args [i] != sigp [i]) return false; } return true; } } } --- NEW FILE: codegen.cs --- // // codegen.cs: The code generator // // Author: // Miguel de Icaza (mi...@xi...) // // (C) 2001 Ximian, Inc. // using System; using System.IO; using System.Collections; using System.Reflection; using System.Reflection.Emit; using System.Runtime.InteropServices; using System.Security.Cryptography; using Mono.Security.Cryptography; [...1055 lines suppressed...] ApplyAttributeBuilder (null, new CustomAttributeBuilder (TypeManager.unverifiable_code_ctor, new object [0])); } public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder customBuilder) { if (a != null && a.Type == TypeManager.cls_compliant_attribute_type) { Report.Warning (3012, a.Location, "You must specify the CLSCompliant attribute on the assembly, not the module, to enable CLS compliance checking"); return; } Builder.SetCustomAttribute (customBuilder); } public override string[] ValidAttributeTargets { get { return attribute_targets; } } } } --- NEW FILE: compiler.doc --- Compiler operation The compiler has a number of phases: * Parsing. Initially the compiler parses all the source files and keeps a parsed representation in memory. Very syntax error checking is performed at this point. The compiler stores the information in classes whose names represent the language construct, for example, the "if" construct is stored in an `If' class. A class is stored in a `Class'. * The TypeManager The TypeManager loads all the assemblies that were referenced by the programmer. The CLR type system is used as our repository for types defined as well. So the same interface that is used to query the types, properties and flags about system types is the same interface that we use for our types. As we work our way through the code generation and semantic analysis, new types are entered into the Type system through the use of System.Reflection.Emit. The TypeManager will lookup types on both the user defined types and on the system defined ones. So special care has to be used. The order in which we proceeed from here is important. * Base class resolution and type definition. Once the parsing has happened, the compiler resolves the inheritance tree for interfaces. This is done recursively and we catch recursive interface definitions here. After this is done, we continue on with classes. Classes have can have an optional "parent" inherit from or the implicit System.Object class (for normal builds, builds with /nostdlib will allow you to compile class System.Object with no parent). At this point we do some error checking and verify that the inherits/implements section of a class is correct (since we have previously built the interface inheritance). By the time we are done, all classes, structs and interfaces have been created using System.Reflection.Emit and registered with the Type Manager. This allows us to define fields and resolve argument names for methods, properties, indexers and events. * Field generation Fields are generated next, we go through all the type containers (classes and structs) and enter the fields into their types. * Method, Properties, Indexers and events definitions Now all the methods, constructors, properties, indexers and events are entered. They are only `defined' using System.Reflection.Emit. No code generation will happen until everything has been entered into System.Reflection.Emit. This is important because to actually generate code we need to know everything about the environment in which the code is being generated. * Code Generation At this point all the definitions have been entered into the type manager through System.Reflection.Emit. We can now use System.Reflection to query all the information about the types. Your normal semantic analysis and code generation phase lives here. * Statements Most of the statements are handled in the codegen.cs file. * Expressions * Error reporting We should try to use the `Report.Error' and `Report.Warning' classes which are part of the RootContext (there is even a property to access it). Error reporting should try to use the same codes that the Microsoft compiler uses (if only so we can track which errors we handle and which ones we dont). If there is an error which is specific to MSC, use negative numbers, and register the number in mcs/errors/errors.txt Try to write a test case for any error that you run into the code of the compiler if there is none already. Put your test case in a file called csNNNN.cs in the mcs/errors directory, and have the first two lines be: // csNNNN.cs: This is the description. // Line: XXX Where `XXX' is the line where the error ocurrs. We will later use this as a regression test suite for catching errors in the compiler. --- NEW FILE: compiler.sln --- Microsoft Visual Studio Solution File, Format Version 8.00 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "compiler", "compiler.csproj", "{896D1461-B76B-41C0-ABE6-ACA2BB4F7B5A}" ProjectSection(ProjectDependencies) = postProject EndProjectSection EndProject Global GlobalSection(SolutionConfiguration) = preSolution Debug = Debug Release = Release 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 --- NEW FILE: const.cs --- // // const.cs: Constant declarations. // // Author: // Miguel de Icaza (mi...@xi...) // // (C) 2001 Ximian, Inc. // // // // This is needed because the following situation arises: // // The FieldBuilder is declared with the real type for an enumeration // // When we attempt to set the value for the constant, the FieldBuilder.SetConstant // function aborts because it requires its argument to be of the same type // namespace Mono.CSharp { using System; using System.Reflection; using System.Reflection.Emit; using System.Collections; public class Const : FieldMember { public Expression Expr; EmitContext const_ec; bool resolved = false; object ConstantValue = null; bool in_transit = false; public const int AllowedModifiers = Modifiers.NEW | Modifiers.PUBLIC | Modifiers.PROTECTED | Modifiers.INTERNAL | Modifiers.PRIVATE; public Const (TypeContainer parent, Expression constant_type, string name, Expression expr, int mod_flags, Attributes attrs, Location loc) : base (parent, constant_type, mod_flags, AllowedModifiers, new MemberName (name), null, attrs, loc) { Expr = expr; ModFlags |= Modifiers.STATIC; } public FieldAttributes FieldAttr { get { return FieldAttributes.Literal | FieldAttributes.Static | Modifiers.FieldAttr (ModFlags) ; } } #if DEBUG void dump_tree (Type t) { Console.WriteLine ("Dumping hierarchy"); while (t != null){ Console.WriteLine (" " + t.FullName + " " + (t.GetType ().IsEnum ? "yes" : "no")); t = t.BaseType; } } #endif /// <summary> /// Defines the constant in the @parent /// </summary> public override bool Define () { if (!base.Define ()) return false; const_ec = new EmitContext (Parent, Location, null, MemberType, ModFlags); Type ttype = MemberType; while (ttype.IsArray) ttype = TypeManager.GetElementType (ttype); if (!TypeManager.IsBuiltinType (ttype) && (!ttype.IsSubclassOf (TypeManager.enum_type)) && !(Expr is NullLiteral)) { Report.Error ( -3, Location, "Constant type is not valid (only system types are allowed)"); return false; } FieldBuilder = Parent.TypeBuilder.DefineField (Name, MemberType, FieldAttr); TypeManager.RegisterConstant (FieldBuilder, this); return true; } // // Changes the type of the constant expression `expr' to the Type `type' // Returns null on failure. // public static Constant ChangeType (Location loc, Constant expr, Type type) { if (type == TypeManager.object_type) return expr; bool fail; // from the null type to any reference-type. if (expr is NullLiteral && !type.IsValueType && !TypeManager.IsEnumType (type)) return NullLiteral.Null; if (!Convert.ImplicitStandardConversionExists (expr, type)){ Convert.Error_CannotImplicitConversion (loc, expr.Type, type); return null; } object constant_value = TypeManager.ChangeType (expr.GetValue (), type, out fail); if (fail){ Convert.Error_CannotImplicitConversion (loc, expr.Type, type); // // We should always catch the error before this is ever // reached, by calling Convert.ImplicitStandardConversionExists // throw new Exception ( String.Format ("LookupConstantValue: This should never be reached {0} {1}", expr.Type, type)); } Constant retval; if (type == TypeManager.int32_type) retval = new IntConstant ((int) constant_value); else if (type == TypeManager.uint32_type) retval = new UIntConstant ((uint) constant_value); else if (type == TypeManager.int64_type) retval = new LongConstant ((long) constant_value); else if (type == TypeManager.uint64_type) retval = new ULongConstant ((ulong) constant_value); else if (type == TypeManager.float_type) retval = new FloatConstant ((float) constant_value); else if (type == TypeManager.double_type) retval = new DoubleConstant ((double) constant_value); else if (type == TypeManager.string_type) retval = new StringConstant ((string) constant_value); else if (type == TypeManager.short_type) retval = new ShortConstant ((short) constant_value); else if (type == TypeManager.ushort_type) retval = new UShortConstant ((ushort) constant_value); else if (type == TypeManager.sbyte_type) retval = new SByteConstant ((sbyte) constant_value); else if (type == TypeManager.byte_type) retval = new ByteConstant ((byte) constant_value); else if (type == TypeManager.char_type) retval = new CharConstant ((char) constant_value); else if (type == TypeManager.bool_type) retval = new BoolConstant ((bool) constant_value); else throw new Exception ("LookupConstantValue: Unhandled constant type: " + type); return retval; } /// <summary> /// Looks up the value of a constant field. Defines it if it hasn't /// already been. Similar to LookupEnumValue in spirit. /// </summary> public bool LookupConstantValue (out object value) { if (resolved) { value = ConstantValue; return true; } if (in_transit) { Report.Error (110, Location, "The evaluation of the constant value for `" + Name + "' involves a circular definition."); value = null; return false; } in_transit = true; int errors = Report.Errors; // // We might have cleared Expr ourselves in a recursive definition // if (Expr == null){ value = null; return false; } Expr = Expr.Resolve (const_ec); in_transit = false; if (Expr == null) { if (errors == Report.Errors) Report.Error (150, Location, "A constant value is expected"); value = null; return false; } Expression real_expr = Expr; Constant ce = Expr as Constant; if (ce == null){ UnCheckedExpr un_expr = Expr as UnCheckedExpr; CheckedExpr ch_expr = Expr as CheckedExpr; EmptyCast ec_expr = Expr as EmptyCast; if ((un_expr != null) && (un_expr.Expr is Constant)) Expr = un_expr.Expr; else if ((ch_expr != null) && (ch_expr.Expr is Constant)) Expr = ch_expr.Expr; else if ((ec_expr != null) && (ec_expr.Child is Constant)) Expr = ec_expr.Child; else if (Expr is ArrayCreation){ Report.Error (133, Location, "Arrays can not be constant"); } else { if (errors == Report.Errors) Report.Error (150, Location, "A constant value is expected"); value = null; return false; } ce = Expr as Constant; } if (MemberType != real_expr.Type) { ce = ChangeType (Location, ce, MemberType); if (ce == null){ value = null; return false; } Expr = ce; } ConstantValue = ce.GetValue (); if (MemberType.IsEnum){ // // This sadly does not work for our user-defined enumerations types ;-( // try { ConstantValue = System.Enum.ToObject ( MemberType, ConstantValue); } catch (ArgumentException){ Report.Error ( -16, Location, ".NET SDK 1.0 does not permit to create the constant "+ " field from a user-defined enumeration"); } } FieldBuilder.SetConstant (ConstantValue); if (!TypeManager.RegisterFieldValue (FieldBuilder, ConstantValue)) throw new Exception ("Cannot register const value"); value = ConstantValue; resolved = true; return true; } /// <summary> /// Emits the field value by evaluating the expression /// </summary> public override void Emit () { object value; LookupConstantValue (out value); if (OptAttributes != null) { OptAttributes.Emit (const_ec, this); } base.Emit (); } } } --- NEW FILE: constant.cs --- // // constant.cs: Constants. // // Author: // Miguel de Icaza (mi...@xi...) // // (C) 2001 Ximian, Inc. // // namespace Mono.CSharp { using System; using System.Reflection.Emit; /// <summary> /// Base class for constants and literals. /// </summary> public abstract class Constant : Expression { [...1074 lines suppressed...] } public override void Emit (EmitContext ec) { if (Value == null) ec.ig.Emit (OpCodes.Ldnull); else ec.ig.Emit (OpCodes.Ldstr, Value); } public override bool IsNegative { get { return false; } } } } --- NEW FILE: convert.cs --- // // conversion.cs: various routines for implementing conversions. // // Authors: // Miguel de Icaza (mi...@xi...) // Ravi Pratap (ra...@xi...) // // (C) 2001, 2002, 2003 Ximian, Inc. // namespace Mono.CSharp { using System; using System.Collections; using System.Diagnostics; using System.Reflection; using System.Reflection.Emit; // // A container class for all the conversion operations [...1735 lines suppressed...] Type target_type, Location l) { Expression ne = ImplicitConversionStandard (ec, expr, target_type, l); if (ne != null) return ne; ne = ExplicitNumericConversion (ec, expr, target_type, l); if (ne != null) return ne; ne = ExplicitReferenceConversion (expr, target_type); if (ne != null) return ne; Error_CannotConvertType (l, expr.Type, target_type); return null; } } } --- NEW FILE: cs-parser.jay --- %{ // // cs-parser.jay: The Parser for the C# compiler // // Authors: Miguel de Icaza (mi...@gn...) // Ravi Pratap (ra...@xi...) // // Licensed under the terms of the GNU GPL // // (C) 2001 Ximian, Inc (http://www.ximian.com) // // TODO: // (1) 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 { }" // // Possible optimization: // Run memory profiler with parsing only, and consider dropping // arraylists where not needed. Some pieces can use linked lists. [...4397 lines suppressed...] Console.WriteLine (e); } } void CheckToken (int error, int yyToken, string msg) { if (yyToken >= Token.FIRST_KEYWORD && yyToken <= Token.LAST_KEYWORD){ Report.Error (error, lexer.Location, String.Format ("{0}: `{1}' is a keyword", msg, yyNames [yyToken].ToLower ())); return; } Report.Error (error, lexer.Location, msg); } void CheckIdentifierToken (int yyToken) { CheckToken (1041, yyToken, "Identifier expected"); } /* end end end */ } --- NEW FILE: cs-tokenizer.cs --- // // cs-tokenizer.cs: The Tokenizer for the C# compiler // This also implements the preprocessor // // Author: Miguel de Icaza (mi...@gn...) // // Licensed under the terms of the GNU GPL // // (C) 2001, 2002 Ximian, Inc (http://www.ximian.com) // /* * TODO: * Make sure we accept the proper Unicode ranges, per the spec. * Report error 1032 */ using System; using System.Text; [...2013 lines suppressed...] return Token.ERROR; } return Token.EOF; } public void cleanup () { if (ifstack != null && ifstack.Count >= 1) { int state = (int) ifstack.Pop (); if ((state & REGION) != 0) Report.Error (1038, "#endregion directive expected"); else Report.Error (1027, "#endif directive expected"); } } } } --- NEW FILE: decl.cs --- // // decl.cs: Declaration base class for structs, classes, enums and interfaces. // // Author: Miguel de Icaza (mi...@gn...) // Marek Safar (mar...@se...) // // Licensed under the terms of the GNU GPL // // (C) 2001 Ximian, Inc (http://www.ximian.com) // // TODO: Move the method verification stuff from the class.cs and interface.cs here // using System; using System.Collections; using System.Globalization; using System.Reflection.Emit; using System.Reflection; [...1943 lines suppressed...] if ((entry.EntryType & tested_type) != tested_type) continue; MethodBase method_to_compare = (MethodBase)entry.Member; if (AttributeTester.AreOverloadedMethodParamsClsCompliant (method.ParameterTypes, TypeManager.GetArgumentTypes (method_to_compare))) continue; IMethodData md = TypeManager.GetMethod (method_to_compare); // TODO: now we are ignoring CLSCompliance(false) on method from other assembly which is buggy. // However it is exactly what csc does. if (md != null && !md.IsClsCompliaceRequired (method.Parent)) continue; Report.SymbolRelatedToPreviousError (entry.Member); Report.Error (3006, method.Location, "Overloaded method '{0}' differing only in ref or out, or in array rank, is not CLS-compliant", method.GetSignatureForError ()); } } } } --- NEW FILE: delegate.cs --- // // delegate.cs: Delegate Handler // // Authors: // Ravi Pratap (ra...@xi...) // Miguel de Icaza (mi...@xi...) // // 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.Text; namespace Mono.CSharp { /// <summary> /// Holds Delegates /// </summary> public class Delegate : DeclSpace { public Expression ReturnType; public Parameters Parameters; public ConstructorBuilder ConstructorBuilder; public MethodBuilder InvokeBuilder; public MethodBuilder BeginInvokeBuilder; public MethodBuilder EndInvokeBuilder; Type [] param_types; Type ret_type; static string[] attribute_targets = new string [] { "type", "return" }; Expression instance_expr; MethodBase delegate_method; ReturnParameter return_attributes; const int AllowedModifiers = Modifiers.NEW | Modifiers.PUBLIC | Modifiers.PROTECTED | Modifiers.INTERNAL | Modifiers.UNSAFE | Modifiers.PRIVATE; public Delegate (NamespaceEntry ns, TypeContainer parent, Expression type, int mod_flags, MemberName name, Parameters param_list, Attributes attrs, Location l) : base (ns, parent, name, attrs, l) { this.ReturnType = type; ModFlags = Modifiers.Check (AllowedModifiers, mod_flags, IsTopLevel ? Modifiers.INTERNAL : Modifiers.PRIVATE, l); Parameters = param_list; } public override void ApplyAttributeBuilder(Attribute a, CustomAttributeBuilder cb) { if (a.Target == AttributeTargets.ReturnValue) { if (return_attributes == null) return_attributes = new ReturnParameter (InvokeBuilder, Location); return_attributes.ApplyAttributeBuilder (a, cb); return; } base.ApplyAttributeBuilder (a, cb); } public override TypeBuilder DefineType () { if (TypeBuilder != null) return TypeBuilder; TypeAttributes attr = Modifiers.TypeAttr (ModFlags, IsTopLevel) | TypeAttributes.Class | TypeAttributes.Sealed; if (IsTopLevel) { if (TypeManager.NamespaceClash (Name, Location)) return null; ModuleBuilder builder = CodeGen.Module.Builder; TypeBuilder = builder.DefineType ( Name, attr, TypeManager.multicast_delegate_type); } else { TypeBuilder builder = Parent.TypeBuilder; string name = Name.Substring (1 + Name.LastIndexOf ('.')); TypeBuilder = builder.DefineNestedType ( name, attr, TypeManager.multicast_delegate_type); } TypeManager.AddDelegateType (Name, TypeBuilder, this); return TypeBuilder; } public override bool DefineMembers (TypeContainer container) { return true; } public override bool Define () { MethodAttributes mattr; int i; EmitContext ec = new EmitContext (this, this, Location, null, null, ModFlags, false); // FIXME: POSSIBLY make this static, as it is always constant // Type [] const_arg_types = new Type [2]; const_arg_types [0] = TypeManager.object_type; const_arg_types [1] = TypeManager.intptr_type; mattr = MethodAttributes.RTSpecialName | MethodAttributes.SpecialName | MethodAttributes.HideBySig | MethodAttributes.Public; ConstructorBuilder = TypeBuilder.DefineConstructor (mattr, CallingConventions.Standard, const_arg_types); ConstructorBuilder.DefineParameter (1, ParameterAttributes.None, "object"); ConstructorBuilder.DefineParameter (2, ParameterAttributes.None, "method"); // // HACK because System.Reflection.Emit is lame // // // FIXME: POSSIBLY make these static, as they are always the same Parameter [] fixed_pars = new Parameter [2]; fixed_pars [0] = new Parameter (null, null, Parameter.Modifier.NONE, null); fixed_pars [1] = new Parameter (null, null, Parameter.Modifier.NONE, null); Parameters const_parameters = new Parameters (fixed_pars, null, Location); TypeManager.RegisterMethod ( ConstructorBuilder, new InternalParameters (const_arg_types, const_parameters), const_arg_types); ConstructorBuilder.SetImplementationFlags (MethodImplAttributes.Runtime); // // Here the various methods like Invoke, BeginInvoke etc are defined // // First, call the `out of band' special method for // defining recursively any types we need: if (!Parameters.ComputeAndDefineParameterTypes (this)) return false; param_types = Parameters.GetParameterInfo (this); if (param_types == null) return false; // // Invoke method // // Check accessibility foreach (Type partype in param_types){ if (!Parent.AsAccessible (partype, ModFlags)) { Report.Error (59, Location, "Inconsistent accessibility: parameter type `" + TypeManager.CSharpName (partype) + "` is less " + "accessible than delegate `" + Name + "'"); return false; } if (partype.IsPointer && !UnsafeOK (Parent)) return false; } ReturnType = ResolveTypeExpr (ReturnType, false, Location); if (ReturnType == null) return false; ret_type = ReturnType.Type; if (ret_type == null) return false; if (!Parent.AsAccessible (ret_type, ModFlags)) { Report.Error (58, Location, "Inconsistent accessibility: return type `" + TypeManager.CSharpName (ret_type) + "` is less " + "accessible than delegate `" + Name + "'"); return false; } if (ret_type.IsPointer && !UnsafeOK (Parent)) return false; // // We don't have to check any others because they are all // guaranteed to be accessible - they are standard types. // CallingConventions cc = Parameters.GetCallingConvention (); mattr = MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.Virtual; InvokeBuilder = TypeBuilder.DefineMethod ("Invoke", mattr, cc, ret_type, param_types); // // Define parameters, and count out/ref parameters // int out_params = 0; i = 0; if (Parameters.FixedParameters != null){ int top = Parameters.FixedParameters.Length; Parameter p; for (; i < top; i++) { p = Parameters.FixedParameters [i]; p.DefineParameter (ec, InvokeBuilder, null, i + 1, Location); if ((p.ModFlags & Parameter.Modifier.ISBYREF) != 0) out_params++; } } if (Parameters.ArrayParameter != null){ Parameter p = Parameters.ArrayParameter; p.DefineParameter (ec, InvokeBuilder, null, i + 1, Location); } InvokeBuilder.SetImplementationFlags (MethodImplAttributes.Runtime); TypeManager.RegisterMethod (InvokeBuilder, new InternalParameters (Parent, Parameters), param_types); // // BeginInvoke // int params_num = param_types.Length; Type [] async_param_types = new Type [params_num + 2]; param_types.CopyTo (async_param_types, 0); async_param_types [params_num] = TypeManager.asynccallback_type; async_param_types [params_num + 1] = TypeManager.object_type; mattr = MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.Virtual | MethodAttributes.NewSlot; BeginInvokeBuilder = TypeBuilder.DefineMethod ("BeginInvoke", mattr, cc, TypeManager.iasyncresult_type, async_param_types); i = 0; if (Parameters.FixedParameters != null){ int top = Parameters.FixedParameters.Length; Parameter p; for (i = 0 ; i < top; i++) { p = Parameters.FixedParameters [i]; p.DefineParameter (ec, BeginInvokeBuilder, null, i + 1, Location); } } if (Parameters.ArrayParameter != null){ Parameter p = Parameters.ArrayParameter; p.DefineParameter (ec, BeginInvokeBuilder, null, i + 1, Location); i++; } BeginInvokeBuilder.DefineParameter (i + 1, ParameterAttributes.None, "callback"); BeginInvokeBuilder.DefineParameter (i + 2, ParameterAttributes.None, "object"); BeginInvokeBuilder.SetImplementationFlags (MethodImplAttributes.Runtime); Parameter [] async_params = new Parameter [params_num + 2]; int n = 0; if (Parameters.FixedParameters != null){ Parameters.FixedParameters.CopyTo (async_params, 0); n = Parameters.FixedParameters.Length; } if (Parameters.ArrayParameter != null) async_params [n] = Parameters.ArrayParameter; async_params [params_num] = new Parameter ( TypeManager.system_asynccallback_expr, "callback", Parameter.Modifier.NONE, null); async_params [params_num + 1] = new Parameter ( TypeManager.system_object_expr, "object", Parameter.Modifier.NONE, null); Parameters async_parameters = new Parameters (async_params, null, Location); async_parameters.ComputeAndDefineParameterTypes (this); async_parameters.ComputeAndDefineParameterTypes (this); TypeManager.RegisterMethod (BeginInvokeBuilder, new InternalParameters (Parent, async_parameters), async_param_types); // // EndInvoke is a bit more interesting, all the parameters labeled as // out or ref have to be duplicated here. // Type [] end_param_types = new Type [out_params + 1]; Parameter [] end_params = new Parameter [out_params + 1]; int param = 0; if (out_params > 0){ int top = Parameters.FixedParameters.Length; for (i = 0; i < top; i++){ Parameter p = Parameters.FixedParameters [i]; if ((p.ModFlags & Parameter.Modifier.ISBYREF) == 0) continue; end_param_types [param] = param_types [i]; end_params [param] = p; param++; } } end_param_types [out_params] = TypeManager.iasyncresult_type; end_params [out_params] = new Parameter (TypeManager.system_iasyncresult_expr, "result", Parameter.Modifier.NONE, null); // // Create method, define parameters, register parameters with type system // EndInvokeBuilder = TypeBuilder.DefineMethod ("EndInvoke", mattr, cc, ret_type, end_param_types); EndInvokeBuilder.SetImplementationFlags (MethodImplAttributes.Runtime); // // EndInvoke: Label the parameters // EndInvokeBuilder.DefineParameter (out_params + 1, ParameterAttributes.None, "result"); for (i = 0; i < end_params.Length-1; i++){ EndInvokeBuilder.DefineParameter (i + 1, end_params [i].Attributes, end_params [i].Name); } Parameters end_parameters = new Parameters (end_params, null, Location); end_parameters.ComputeAndDefineParameterTypes (this); TypeManager.RegisterMethod ( EndInvokeBuilder, new InternalParameters (Parent, end_parameters), end_param_types); return true; } public override void Emit () { if (OptAttributes != null) { EmitContext ec = new EmitContext ( Parent, this, Location, null, null, ModFlags, false); Parameters.LabelParameters (ec, InvokeBuilder, Location); OptAttributes.Emit (ec, this); } base.Emit (); } public override string[] ValidAttributeTargets { get { return attribute_targets; } } //TODO: duplicate protected override bool VerifyClsCompliance (DeclSpace ds) { if (!base.VerifyClsCompliance (ds)) { return false; } AttributeTester.AreParametersCompliant (Parameters.FixedParameters, Location); if (!AttributeTester.IsClsCompliant (ReturnType.Type)) { Report.Error (3002, Location, "Return type of '{0}' is not CLS-compliant", GetSignatureForError ()); } return true; } /// <summary> /// Verifies whether the method in question is compatible with the delegate /// Returns the method itself if okay and null if not. /// </summary> public static MethodBase VerifyMethod (EmitContext ec, Type delegate_type, MethodBase mb, Location loc) { ParameterData pd = Invocation.GetParameterData (mb); int pd_count = pd.Count; Expression ml = Expression.MemberLookup ( ec, delegate_type, "Invoke", loc); if (!(ml is MethodGroupExpr)) { Report.Error (-100, loc, "Internal error: could not find Invoke method!"); return null; } MethodBase invoke_mb = ((MethodGroupExpr) ml).Methods [0]; ParameterData invoke_pd = Invocation.GetParameterData (invoke_mb); if (invoke_pd.Count != pd_count) return null; for (int i = pd_count; i > 0; ) { i--; if (invoke_pd.ParameterType (i) == pd.ParameterType (i) && invoke_pd.ParameterModifier (i) == pd.ParameterModifier (i)) continue; else { return null; } } if (((MethodInfo) invoke_mb).ReturnType == ((MethodInfo) mb).ReturnType) return mb; else return null; } // <summary> // Verifies whether the invocation arguments are compatible with the // delegate's target method // </summary> public static bool VerifyApplicability (EmitContext ec, Type delegate_type, ArrayList args, Location loc) { int arg_count; if (args == null) arg_count = 0; else arg_count = args.Count; Expression ml = Expression.MemberLookup ( ec, delegate_type, "Invoke", loc); if (!(ml is MethodGroupExpr)) { Report.Error (-100, loc, "Internal error: could not find Invoke method!" + delegate_type); return false; } MethodBase mb = ((MethodGroupExpr) ml).Methods [0]; ParameterData pd = Invocation.GetParameterData (mb); int pd_count = pd.Count; bool params_method = (pd_count != 0) && (pd.ParameterModifier (pd_count - 1) == Parameter.Modifier.PARAMS); if (!params_method && pd_count != arg_count) { Report.Error (1593, loc, "Delegate '" + delegate_type.ToString () + "' does not take '" + arg_count + "' arguments"); return false; } // // Consider the case: // delegate void FOO(param object[] args); // FOO f = new FOO(...); // f(new object[] {1, 2, 3}); // // This should be treated like f(1,2,3). This is done by ignoring the // 'param' modifier for that invocation. If that fails, then the // 'param' modifier is considered. // // One issue is that 'VerifyArgumentsCompat' modifies the elements of // the 'args' array. However, the modifications appear idempotent. // Normal 'Invocation's also have the same behaviour, implicitly. // bool ans = false; if (arg_count == pd_count) ans = Invocation.VerifyArgumentsCompat ( ec, args, arg_count, mb, false, delegate_type, false, loc); if (!ans && params_method) ans = Invocation.VerifyArgumentsCompat ( ec, args, arg_count, mb, true, delegate_type, false, loc); return ans; } /// <summary> /// Verifies whether the delegate in question is compatible with this one in /// order to determine if instantiation from the same is possible. /// </summary> public static bool VerifyDelegate (EmitContext ec, Type delegate_type, Type probe_type, Location loc) { Expression ml = Expression.MemberLookup ( ec, delegate_type, "Invoke", loc); if (!(ml is MethodGroupExpr)) { Report.Error (-100, loc, "Internal error: could not find Invoke method!"); return false; } MethodBase mb = ((MethodGroupExpr) ml).Methods [0]; ParameterData pd = Invocation.GetParameterData (mb); Expression probe_ml = Expression.MemberLookup ( ec, delegate_type, "Invoke", loc); if (!(probe_ml is MethodGroupExpr)) { Report.Error (-100, loc, "Internal error: could not find Invoke method!"); return false; } MethodBase probe_mb = ((MethodGroupExpr) probe_ml).Methods [0]; ParameterData probe_pd = Invocation.GetParameterData (probe_mb); if (((MethodInfo) mb).ReturnType != ((MethodInfo) probe_mb).ReturnType) return false; if (pd.Count != probe_pd.Count) return false; for (int i = pd.Count; i > 0; ) { i--; if (pd.ParameterType (i) != probe_pd.ParameterType (i) || pd.ParameterModifier (i) != probe_pd.ParameterModifier (i)) return false; } return true; } public static string FullDelegateDesc (Type del_type, MethodBase mb, ParameterData pd) { StringBuilder sb = new StringBuilder (TypeManager.CSharpName (((MethodInfo) mb).ReturnType)); sb.Append (" " + del_type.ToString ()); sb.Append (" ("); int length = pd.Count; for (int i = length; i > 0; ) { i--; sb.Append (pd.ParameterDesc (length - i - 1)); if (i != 0) sb.Append (", "); } sb.Append (")"); return sb.ToString (); } // Hack around System.Reflection as found everywhere else public override MemberList FindMembers (MemberTypes mt, BindingFlags bf, MemberFilter filter, object criteria) { ArrayList members = new ArrayList (); if ((mt & MemberTypes.Method) != 0) { if (ConstructorBuilder != null) if (filter (ConstructorBuilder, criteria)) members.Add (ConstructorBuilder); if (InvokeBuilder != null) if (filter (InvokeBuilder, criteria)) members.Add (InvokeBuilder); if (BeginInvokeBuilder != null) if (filter (BeginInvokeBuilder, criteria)) members.Add (BeginInvokeBuilder); if (EndInvokeBuilder != null) if (filter (EndInvokeBuilder, criteria)) members.Add (EndInvokeBuilder); } return new MemberList (members); } public override MemberCache MemberCache { get { return null; } } public Expression InstanceExpression { get { return instance_expr; } set { instance_expr = value; } } public MethodBase TargetMethod { get { return delegate_method; } set { delegate_method = value; } } public Type TargetReturnType { get { return ret_type; } } public Type [] ParameterTypes { get { return param_types; } } public override AttributeTargets AttributeTargets { get { return AttributeTargets.Delegate; } } protected override void VerifyObsoleteAttribute() { CheckUsageOfObsoleteAttribute (ret_type); foreach (Type type in param_types) { CheckUsageOfObsoleteAttribute (type); } } } // // Base class for `NewDelegate' and `ImplicitDelegateCreation' // public abstract class DelegateCreation : Expression { protected MethodBase constructor_method; protected MethodBase delegate_method; protected MethodGroupExpr method_group; protected Expression delegate_instance_expression; public DelegateCreation () {} public static void Error_NoMatchingMethodForDelegate (EmitContext ec, MethodGroupExpr mg, Type type, Location loc) { string method_desc; if (mg.Methods.Length > 1) method_desc = mg.Methods [0].Name; else method_desc = Invocation.FullMethodDesc (mg.Methods [0]); Expression invoke_method = Expression.MemberLookup ( ec, type, "Invoke", MemberTypes.Method, Expression.AllBindingFlags, loc); MethodBase method = ((MethodGroupExpr) invoke_method).Methods [0]; ParameterData param = Invocation.GetParameterData (method); string delegate_desc = Delegate.FullDelegateDesc (type, method, param); Report.Error (1... [truncated message content] |
Update of /cvsroot/csdoc/csdoc/src/mcs/jay In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv9981 Added Files: .cvsignore ACKNOWLEDGEMENTS ChangeLog closure.c defs.h depend error.c jay.1 lalr.c lr0.c main.c makefile makefile.gnu mkpar.c NEW_FEATURES NOTES output.c reader.c README README.jay skeleton skeleton.cs symtab.c verbose.c warshall.c Log Message: Cleanup. All files have been moved to jay --- NEW FILE: .cvsignore --- jay jay.exe --- NEW FILE: ACKNOWLEDGEMENTS --- 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 --- NEW FILE: ChangeLog --- 2004-06-10 Rafael Teixeira <raf...@ho...> * skeleton.cs: oops some uses of changed classes/interfaces also need to become internal. 2004-06-10 Atsushi Enomoto <at...@xi...> * skelton.cs: make classes/interfaces internal. 2004-06-03 Atsushi Enomoto <at...@xi...> * Makefile : ignore make run-test-ondotnet. Mon May 3 08:34:32 CEST 2004 Paolo Molaro <lu...@xi...> * main.c, defs.h: use the proper header files instead of broken prototypes (thanks to Marcus for reporting). 2004-03-13 Miguel de Icaza <mi...@xi...> * main.c (create_file_names): Try a few temp directories, since Windows uses a different directory naming scheme apparently: #47696 2004-03-05 Zoltan Varga <va...@fr...> * main.c: Applied patch from Albert Strasheim (136...@su...). Fix compilation under mingw. 2004-02-07 Miguel de Icaza <mi...@xi...> * skeleton.cs: Report the token that we errored on; Helps find parser errors. 2003-12-16 Atsushi Enomoto <at...@xi...> * skelton.cs : Added ErrorOutput text writer. 2003-10-08 Atsushi Enomoto <gi...@ki...> * output.c, skelton, skelton.cs : Renamed yyName[] to yyNames[] to make output CLS-compliant. 2003-05-16 Peter Williams <pe...@xi...> * main.c (print_skel_dir): New function called when jay is passed '-p'; prints the directory where the default skeleton files are installed ($(prefix)/share/jay). * makefile (CFLAGS): Add a -DSKEL_DIRECTORY to support print_skel_dir. * jay.1: Document the -p parameter. 2003-05-16 Peter Williams <pe...@xi...> * makefile (install): Call the install in makefile.gnu * makefile.gnu (install): Actually install jay and its skeleton files. 2003-02-09 Martin Baulig <ma...@xi...> * output.c: Use `#line default' instead of source file "-". 2003-01-13 Jackson Harper <ja...@la...> * skeleton.cs: Remove cleanup stuff, it has been moved to a better spot. 2003-01-13 Duncan Mak <du...@xi...> * skeleton.cs (cleanpup): Rename to cleanup to make it look more consistent. 2003-01-13 Jackson Harper <ja...@la...> * skeleton.cs: Call lexer.Cleanup when the lexer reaches the EOF. 2002-08-20 Miguel de Icaza <mi...@xi...> * skeleton.cs: Fix the code that expanded the arrays dynamically, it was broken, and instead was copying 0 elements. 2002-07-10 Alp Toker <al...@at...> * main.c: mktemp() is deprecated with gcc 3.1.1, use mkstemp() instead 2001-07-15 Sean MacIsaac <mac...@xi...> * makefile: added windows and unix targets. 2001-07-14 Sean MacIsaac <mac...@xi...> * main.c: fixed error in command line flag -c if it was not first option. --- NEW FILE: closure.c --- /* * 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 --- NEW FILE: defs.h --- /* * 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> #include <stdlib.h> #include <string.h> #include <errno.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 char *default_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(); --- NEW FILE: depend --- 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 --- NEW FILE: error.c --- /* * 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); } --- NEW FILE: jay.1 --- .\" 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 ] [ -p ] [ -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. .TP .B -p The .B -p option causes .I jay to print the directory in which its sample skeleton files are installed. If a project wants to use the default skeleton file included with \fIjay\fR, it can use this option in a makefile to find the path to the .I skeleton or .I skeleton.cs file included with the jay distribution. .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. --- NEW FILE: lalr.c --- /* * 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++; } } } --- NEW FILE: lr0.c --- /* * 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(); } --- NEW FILE: main.c --- /* * 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; int 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; #if defined(_WIN32) && !defined(__CYGWIN32__) && !defined(__CYGWIN__) extern char* mktemp(); #define mkstemp mktemp #endif 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 [-tvcp] [-b file_prefix] filename\n", myname); exit(1); } void print_skel_dir(void) { printf ("%s\n", SKEL_DIRECTORY); exit (0); } 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 'p': print_skel_dir (); break; case 'c': csharp = 1; line_format = "#line %d \"%s\"\n"; default_line_format = "#line default\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 'p': print_skel_dir (); 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; #if defined(_WIN32) && !defined(__CYGWIN32__) && !defined(__CYGWIN__) tmpdir = "."; #else tmpdir = getenv("TMPDIR"); if (tmpdir == 0) tmpdir = getenv ("TMP"); if (tmpdir == 0) tmpdir = getenv ("TEMP"); if (tmpdir == 0) tmpdir = "/tmp"; #endif 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'; mkstemp(action_file_name); mkstemp(prolog_file_name); mkstemp(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) { inp... [truncated message content] |
From: <mas...@us...> - 2004-10-06 17:42:04
|
Update of /cvsroot/csdoc/csdoc/src/mcs/build/deps In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv24827/deps Log Message: Directory /cvsroot/csdoc/csdoc/src/mcs/build/deps added to the repository |
From: <mas...@us...> - 2004-10-06 17:40:03
|
Update of /cvsroot/csdoc/csdoc/src/mcs/class/corlib/Mono.Security.Cryptography In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv24151/Mono.Security.Cryptography Log Message: Directory /cvsroot/csdoc/csdoc/src/mcs/class/corlib/Mono.Security.Cryptography added to the repository |
From: <mas...@us...> - 2004-10-06 17:39:53
|
Update of /cvsroot/csdoc/csdoc/src/mcs/class/Mono.CSharp.Debugger In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv23946/Mono.CSharp.Debugger Log Message: Directory /cvsroot/csdoc/csdoc/src/mcs/class/Mono.CSharp.Debugger added to the repository |
From: <mas...@us...> - 2004-10-06 17:39:38
|
Update of /cvsroot/csdoc/csdoc/src/mcs/class/corlib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv23636/corlib Log Message: Directory /cvsroot/csdoc/csdoc/src/mcs/class/corlib added to the repository |
From: <mas...@us...> - 2004-10-06 17:39:19
|
Update of /cvsroot/csdoc/csdoc/src/mcs/mcs In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv23276/mcs Log Message: Directory /cvsroot/csdoc/csdoc/src/mcs/mcs added to the repository |
From: <mas...@us...> - 2004-10-06 17:39:11
|
Update of /cvsroot/csdoc/csdoc/src/mcs/class In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv23198/class Log Message: Directory /cvsroot/csdoc/csdoc/src/mcs/class added to the repository |
From: <mas...@us...> - 2004-10-06 16:47:10
|
Update of /cvsroot/csdoc/csdoc/src/mcs/build In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv6891/build Log Message: Directory /cvsroot/csdoc/csdoc/src/mcs/build added to the repository |
Update of /cvsroot/csdoc/csdoc/src/mcs In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv5804 Removed Files: .cvsignore anonymous.cs AssemblyInfo.cs assign.cs attribute.cs cfold.cs ChangeLog class.cs codegen.cs compiler.csproj compiler.doc compiler.sln const.cs constant.cs convert.cs cs-parser.jay cs-tokenizer.cs decl.cs delegate.cs driver.cs ecore.cs enum.cs errors.cs expression.cs flowanalysis.cs gen-il.cs gen-treedump.cs generic.cs genericparser.cs interface.cs iterators.cs literal.cs location.cs makefile makefile.gnu mcs.exe.config mcs.exe.sources modifiers.cs namespace.cs NOTES old-code.cs OTODO parameter.cs parameterCollection.cs parser.cs pending.cs README report.cs rootcontext.cs statement.cs statementCollection.cs support.cs symbolwriter.cs TODO tree.cs typemanager.cs Log Message: Cleanup. All files have been moved to mcs directory --- .cvsignore DELETED --- --- anonymous.cs DELETED --- --- AssemblyInfo.cs DELETED --- --- assign.cs DELETED --- --- attribute.cs DELETED --- --- cfold.cs DELETED --- --- ChangeLog DELETED --- --- class.cs DELETED --- --- codegen.cs DELETED --- --- compiler.csproj DELETED --- --- compiler.doc DELETED --- --- compiler.sln DELETED --- --- const.cs DELETED --- --- constant.cs DELETED --- --- convert.cs DELETED --- --- cs-parser.jay DELETED --- --- cs-tokenizer.cs DELETED --- --- decl.cs DELETED --- --- delegate.cs DELETED --- --- driver.cs DELETED --- --- ecore.cs DELETED --- --- enum.cs DELETED --- --- errors.cs DELETED --- --- expression.cs DELETED --- --- flowanalysis.cs DELETED --- --- gen-il.cs DELETED --- --- gen-treedump.cs DELETED --- --- generic.cs DELETED --- --- genericparser.cs DELETED --- --- interface.cs DELETED --- --- iterators.cs DELETED --- --- literal.cs DELETED --- --- location.cs DELETED --- --- makefile DELETED --- --- makefile.gnu DELETED --- --- mcs.exe.config DELETED --- --- mcs.exe.sources DELETED --- --- modifiers.cs DELETED --- --- namespace.cs DELETED --- --- NOTES DELETED --- --- old-code.cs DELETED --- --- OTODO DELETED --- --- parameter.cs DELETED --- --- parameterCollection.cs DELETED --- --- parser.cs DELETED --- --- pending.cs DELETED --- --- README DELETED --- --- report.cs DELETED --- --- rootcontext.cs DELETED --- --- statement.cs DELETED --- --- statementCollection.cs DELETED --- --- support.cs DELETED --- --- symbolwriter.cs DELETED --- --- TODO DELETED --- --- tree.cs DELETED --- --- typemanager.cs DELETED --- |
Update of /cvsroot/csdoc/csdoc/src/jay In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv5500 Removed Files: .cvsignore ACKNOWLEDGEMENTS ChangeLog closure.c defs.h depend error.c jay.1 lalr.c lr0.c main.c makefile makefile.gnu mkpar.c NEW_FEATURES NOTES output.c reader.c README README.jay skeleton skeleton.cs symtab.c verbose.c warshall.c Log Message: Cleanup. All files have been moved to mcs/jay directory --- .cvsignore DELETED --- --- ACKNOWLEDGEMENTS DELETED --- --- ChangeLog DELETED --- --- closure.c DELETED --- --- defs.h DELETED --- --- depend DELETED --- --- error.c DELETED --- --- jay.1 DELETED --- --- lalr.c DELETED --- --- lr0.c DELETED --- --- main.c DELETED --- --- makefile DELETED --- --- makefile.gnu DELETED --- --- mkpar.c DELETED --- --- NEW_FEATURES DELETED --- --- NOTES DELETED --- --- output.c DELETED --- --- reader.c DELETED --- --- README DELETED --- --- README.jay DELETED --- --- skeleton DELETED --- --- skeleton.cs DELETED --- --- symtab.c DELETED --- --- verbose.c DELETED --- --- warshall.c DELETED --- |
From: <mas...@us...> - 2004-10-06 16:30:24
|
Update of /cvsroot/csdoc/csdoc/src/mcs/jay In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv2247/jay Log Message: Directory /cvsroot/csdoc/csdoc/src/mcs/jay added to the repository |
From: <mas...@us...> - 2004-10-06 15:52:17
|
Update of /cvsroot/csdoc/csdoc/src/build/platforms In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv25134/platforms Log Message: Directory /cvsroot/csdoc/csdoc/src/build/platforms added to the repository |
From: <mas...@us...> - 2004-10-06 15:35:02
|
Update of /cvsroot/csdoc/csdoc/src/build/profiles In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv25134/profiles Log Message: Directory /cvsroot/csdoc/csdoc/src/build/profiles added to the repository |