Project

General

Profile

root / branches / compiler / cSharp / ooasCompiler / src / libs / c5 / C5 / Formatting.cs @ 3

1
/*
2
 Copyright (c) 2003-2006 Niels Kokholm and Peter Sestoft
3
 Permission is hereby granted, free of charge, to any person obtaining a copy
4
 of this software and associated documentation files (the "Software"), to deal
5
 in the Software without restriction, including without limitation the rights
6
 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
 copies of the Software, and to permit persons to whom the Software is
8
 furnished to do so, subject to the following conditions:
9
 
10
 The above copyright notice and this permission notice shall be included in
11
 all copies or substantial portions of the Software.
12
 
13
 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19
 SOFTWARE.
20
*/
21

    
22
using C5;
23
using System;
24
using System.Reflection;
25
using System.Reflection.Emit;
26
using System.Diagnostics;
27
using System.Text;
28

    
29
namespace C5
30
{
31
  /// <summary>
32
  /// <i>(Describe usage of "L:300" format string.)</i>
33
  /// </summary>
34
  public interface IShowable : IFormattable
35
  {
36
    //TODO: wonder if we should use TextWriters instead of StringBuilders?
37
    /// <summary>
38
    /// Format <code>this</code> using at most approximately <code>rest</code> chars and 
39
    /// append the result, possibly truncated, to stringbuilder.
40
    /// Subtract the actual number of used chars from <code>rest</code>.
41
    /// </summary>
42
    /// <param name="stringbuilder"></param>
43
    /// <param name="rest"></param>
44
    /// <param name="formatProvider"></param>
45
    /// <returns>True if the appended formatted string was complete (not truncated).</returns>
46
    bool Show(StringBuilder stringbuilder, ref int rest, IFormatProvider formatProvider);
47
  }
48
  // ------------------------------------------------------------
49

    
50
  // Static helper methods for Showing collections 
51

    
52
  /// <summary>
53
  /// 
54
  /// </summary>
55
  public static class Showing
56
  {
57
    /// <summary>
58
    /// Show  <code>Object obj</code> by appending it to <code>stringbuilder</code>
59
    /// </summary>
60
    /// <param name="obj"></param>
61
    /// <param name="stringbuilder"></param>
62
    /// <param name="rest"></param>
63
    /// <param name="formatProvider"></param>
64
    /// <returns>True if <code>obj</code> was shown completely.</returns>
65
    public static bool Show(Object obj, StringBuilder stringbuilder, ref int rest, IFormatProvider formatProvider)
66
    {
67
      IShowable showable;
68
      if (rest <= 0)
69
        return false;
70
      else if ((showable = obj as IShowable) != null)
71
        return showable.Show(stringbuilder, ref rest, formatProvider);
72
      int oldLength = stringbuilder.Length;
73
      stringbuilder.AppendFormat(formatProvider, "{0}", obj);
74
      rest -= (stringbuilder.Length - oldLength);
75
      return true;
76
    }
77

    
78
    /// <summary>
79
    /// 
80
    /// </summary>
81
    /// <param name="showable"></param>
82
    /// <param name="format"></param>
83
    /// <param name="formatProvider"></param>
84
    /// <returns></returns>
85
    public static String ShowString(IShowable showable, String format, IFormatProvider formatProvider)
86
    {
87
      int rest = maxLength(format);
88
      StringBuilder sb = new StringBuilder();
89
      showable.Show(sb, ref rest, formatProvider);
90
      return sb.ToString();
91
    }
92

    
93
    /// <summary>
94
    /// 
95
    /// </summary>
96
    /// <param name="format"></param>
97
    /// <returns></returns>
98
    static int maxLength(String format)
99
    {
100
      //TODO: validate format string
101
      if (format == null)
102
        return 80;
103
      if (format.Length > 1 && format.StartsWith("L"))
104
      {
105
        return int.Parse(format.Substring(1));
106
      }
107
      else
108
        return int.MaxValue;
109
    }
110

    
111
    /// <summary>
112
    /// 
113
    /// </summary>
114
    /// <typeparam name="T"></typeparam>
115
    /// <param name="items"></param>
116
    /// <param name="stringbuilder"></param>
117
    /// <param name="rest"></param>
118
    /// <param name="formatProvider"></param>
119
    /// <returns>True if collection was shown completely</returns>
120
    public static bool ShowCollectionValue<T>(ICollectionValue<T> items, StringBuilder stringbuilder, ref int rest, IFormatProvider formatProvider)
121
    {
122
      string startdelim = "{ ", enddelim = " }";
123
      bool showIndexes = false;
124
      bool showMultiplicities = false;
125
      //TODO: do not test here at run time, but select code at compile time
126
      //      perhaps by delivering the print type to this metod
127
      IList<T> list;
128
      ICollection<T> coll = items as ICollection<T>;
129
      if ((list = items as IList<T>) != null)
130
      {
131
        startdelim = "[ ";
132
        enddelim = " ]";
133
        //TODO: should have been (items as IIndexed<T>).IndexingSpeed
134
        showIndexes = list.IndexingSpeed == Speed.Constant;
135
      }
136
      else if (coll != null)
137
      {
138
        if (coll.AllowsDuplicates)
139
        {
140
          startdelim = "{{ ";
141
          enddelim = " }}";
142
          if (coll.DuplicatesByCounting)
143
            showMultiplicities = true;
144
        }
145
      }
146

    
147
      stringbuilder.Append(startdelim);
148
      rest -= 2 * startdelim.Length;
149
      bool first = true;
150
      bool complete = true;
151
      int index = 0;
152

    
153
      if (showMultiplicities)
154
      {
155
        foreach (KeyValuePair<T, int> p in coll.ItemMultiplicities())
156
        {
157
          complete = false;
158
          if (rest <= 0)
159
            break;
160
          if (first)
161
            first = false;
162
          else
163
          {
164
            stringbuilder.Append(", ");
165
            rest -= 2;
166
          }
167
          if (complete = Showing.Show(p.Key, stringbuilder, ref rest, formatProvider))
168
          {
169
            string multiplicityString = string.Format("(*{0})", p.Value);
170
            stringbuilder.Append(multiplicityString);
171
            rest -= multiplicityString.Length;
172
          }
173
        }
174
      }
175
      else
176
      {
177
        foreach (T x in items)
178
        {
179
          complete = false;
180
          if (rest <= 0)
181
            break;
182
          if (first)
183
            first = false;
184
          else
185
          {
186
            stringbuilder.Append(", ");
187
            rest -= 2;
188
          }
189
          if (showIndexes)
190
          {
191
            string indexString = string.Format("{0}:", index++);
192
            stringbuilder.Append(indexString);
193
            rest -= indexString.Length;
194
          }
195
          complete = Showing.Show(x, stringbuilder, ref rest, formatProvider);
196
        }
197
      }
198
      if (!complete)
199
      {
200
        stringbuilder.Append("...");
201
        rest -= 3;
202
      }
203
      stringbuilder.Append(enddelim);
204
      return complete;
205
    }
206

    
207
    /// <summary>
208
    /// 
209
    /// </summary>
210
    /// <typeparam name="K"></typeparam>
211
    /// <typeparam name="V"></typeparam>
212
    /// 
213
    /// <param name="dictionary"></param>
214
    /// <param name="stringbuilder"></param>
215
    /// <param name="formatProvider"></param>
216
    /// <param name="rest"></param>
217
    /// <returns></returns>
218
    public static bool ShowDictionary<K, V>(IDictionary<K, V> dictionary, StringBuilder stringbuilder, ref int rest, IFormatProvider formatProvider)
219
    {
220
      bool sorted = dictionary is ISortedDictionary<K, V>;
221
      stringbuilder.Append(sorted ? "[ " : "{ ");
222
      rest -= 4;				   // Account for "( " and " )"
223
      bool first = true;
224
      bool complete = true;
225

    
226
      foreach (KeyValuePair<K, V> p in dictionary)
227
      {
228
        complete = false;
229
        if (rest <= 0)
230
          break;
231
        if (first)
232
          first = false;
233
        else
234
        {
235
          stringbuilder.Append(", ");
236
          rest -= 2;
237
        }
238
        complete = Showing.Show(p, stringbuilder, ref rest, formatProvider);
239
      }
240
      if (!complete)
241
      {
242
        stringbuilder.Append("...");
243
        rest -= 3;
244
      }
245
      stringbuilder.Append(sorted ? " ]" : " }");
246
      return complete;
247
    }
248
  }
249
}