more class status updates:
[mono.git] / mcs / tools / corcompare / CompletionInfo.cs
1 // Mono.Util.CorCompare.CompletionInfo
2 //
3 // Author(s):
4 //   Piers Haken (piersh@friskit.com)
5 //
6 // (C) 2001-2002 Piers Haken
7
8 using System;
9 using System.Reflection;
10 using System.Xml;
11 using System.Collections;
12
13 namespace Mono.Util.CorCompare 
14 {
15         #region
16         public struct CompletionType
17         {
18                 private enum CompletionTypes
19                 {
20                         Present,
21                         Missing,
22                         Extra
23                 }
24                 private const int MASK_TYPE = 0x0f;
25                 private const int MASK_TODO = 0x10;
26                 //private const int MASK_ERROR = 0x20;
27                 private int m_type;
28
29                 private CompletionType (CompletionTypes type, bool fTodo)
30                 {
31                         m_type = (int) type;
32
33                         if (fTodo)
34                                 m_type |= MASK_TODO;
35                 }
36
37                 public bool IsPresent
38                 {
39                         get { return Type == CompletionTypes.Present; }
40                 }
41                 public bool IsMissing
42                 {
43                         get { return Type == CompletionTypes.Missing; }
44                 }
45                 public bool IsExtra
46                 {
47                         get { return Type == CompletionTypes.Extra; }
48                 }
49                 public bool IsTodo
50                 {
51                         get { return (m_type & MASK_TODO) != 0; }
52                 }
53                 private CompletionTypes Type
54                 {
55                         get { return (CompletionTypes) (m_type & MASK_TYPE); }
56                 }
57
58                 public override string ToString ()
59                 {
60                         switch (Type)
61                         {
62                                 case CompletionTypes.Missing:
63                                         return "missing";
64                                 case CompletionTypes.Extra:
65                                         return "extra";
66                                 case CompletionTypes.Present:
67                                         return "present";
68                                 default:
69                                         throw new Exception ("Invalid CompletionType: "+Type);
70                         }
71                 }
72
73                 public static CompletionType Present
74                 {
75                         get { return new CompletionType (CompletionTypes.Present, false); }
76                 }
77                 public static CompletionType Missing
78                 {
79                         get { return new CompletionType (CompletionTypes.Missing, false); }
80                 }
81                 public static CompletionType Extra
82                 {
83                         get { return new CompletionType (CompletionTypes.Extra, false); }
84                 }
85                 public static CompletionType Compare (Object oMono, Object oMS)
86                 {
87                         if (oMono == null)
88                                 return Missing;
89                         else if (oMS == null)
90                                 return Extra;
91                         else
92                                 return Present;
93                 }
94         }
95
96         /// <summary>
97         ///     Represents the amount of work done on a node
98         /// </summary>
99         /// <remarks>
100         ///     created by - Piersh
101         ///     created on - 3/2/2002 1:12:00 AM
102         /// </remarks>
103
104         public struct CompletionInfo
105         {
106                 public int cPresent;
107                 public int cExtra;
108                 public int cMissing;
109                 public int cTodo;
110
111                 /// <summary>
112                 /// converts a CompletionTypes into a CompletionInfo
113                 /// sets the corresponding field to '1'
114                 /// </summary>
115                 /// <param name="ct">the CompletionTypes to convert</param>
116                 public CompletionInfo (CompletionType ct)
117                 {
118                         cPresent = cTodo = cMissing = cExtra = 0;
119                         if (ct.IsPresent)
120                                 cPresent = 1;
121                         else if (ct.IsMissing)
122                                 cMissing = 1;
123                         else if (ct.IsExtra)
124                                 cExtra = 1;
125
126                         if (ct.IsTodo)
127                                 cTodo = 1;
128                 }
129
130                 /// <summary>
131                 /// counts the total number of elements represented by this info
132                 /// </summary>
133                 public int cTotal
134                 {
135                         get
136                         {
137                                 return cPresent + cTodo + cMissing;
138                         }
139                 }
140
141                 /// <summary>
142                 /// adds two CompletionInfos together
143                 /// </summary>
144                 /// <param name="m_nodeStatus"></param>
145                 public void Add (CompletionInfo m_nodeStatus)
146                 {
147                         cPresent += m_nodeStatus.cPresent;
148                         cTodo += m_nodeStatus.cTodo;
149                         cMissing += m_nodeStatus.cMissing;
150                         cExtra += m_nodeStatus.cExtra;
151                 }
152
153                 /// <summary>
154                 /// subtracts two CompletionInfos
155                 /// </summary>
156                 /// <param name="m_nodeStatus"></param>
157                 public void Sub (CompletionInfo m_nodeStatus)
158                 {
159                         cPresent -= m_nodeStatus.cPresent;
160                         cTodo -= m_nodeStatus.cTodo;
161                         cMissing -= m_nodeStatus.cMissing;
162                         cExtra -= m_nodeStatus.cExtra;
163                         if (cPresent < 0 || cTodo < 0 || cMissing < 0 || cExtra < 0)
164                                 throw new Exception ("Completion underflow on subtract");
165                 }
166
167                 /// <summary>
168                 /// increments the corresponding field
169                 /// </summary>
170                 /// <param name="ct"></param>
171                 public void Add (CompletionType ct)
172                 {
173                         Add (new CompletionInfo (ct));
174                 }
175                 /// <summary>
176                 /// decrements the corresponding field
177                 /// </summary>
178                 /// <param name="ct"></param>
179                 public void Sub (CompletionType ct)
180                 {
181                         Sub (new CompletionInfo (ct));
182                 }
183
184                 /// <summary>
185                 /// adds appropriate 'missing', 'todo' & 'complete' attributes to an XmlElement
186                 /// </summary>
187                 /// <param name="elt"></param>
188                 public void SetAttributes (XmlElement elt)
189                 {
190                         elt.SetAttribute ("present", cPresent.ToString ());
191                         elt.SetAttribute ("missing", cMissing.ToString ());
192                         elt.SetAttribute ("extra", cExtra.ToString ());
193                         elt.SetAttribute ("todo", cTodo.ToString ());
194
195                         //int percentComplete = (cTotal == 0) ? 100 : (100 - 100 * (cMissing + cExtra) / cTotal);
196                         //elt.SetAttribute ("complete", percentComplete.ToString ());
197                 }
198         }
199
200         #endregion
201
202         public enum PresenceTypes
203         {
204 //              UNINITIALIZED = 0,
205                 Missing = 0,
206                 Present,
207                 Extra
208         }
209
210         public enum ErrorTypes
211         {
212                 // TODO: order is important here... (see Status.SetError ())
213 //              UNINITIALIZED = 0,
214                 OK = 0,
215                 Todo,
216                 Warning,
217                 Error
218         }
219
220         public struct PresenceCounts
221         {
222                 public int cMissing;
223                 public int cPresent;
224                 public int cExtra;
225
226                 public PresenceCounts (PresenceTypes type)
227                 {
228                         cMissing = cPresent = cExtra = 0;
229                         if (type == PresenceTypes.Missing)
230                                 cMissing = 1;
231                         else if (type == PresenceTypes.Present)
232                                 cPresent = 1;
233                         else if (type == PresenceTypes.Extra)
234                                 cExtra = 1;
235                         else throw new Exception ("Invalid PresenceType");
236                 }
237                 public int Total
238                 {
239                         get { return cMissing + cPresent + cExtra; }
240                 }
241                 public void Add (PresenceCounts counts)
242                 {
243                         cMissing += counts.cMissing;
244                         cPresent += counts.cPresent;
245                         cExtra += counts.cExtra;
246                 }
247                 public void Sub (PresenceCounts counts)
248                 {
249                         cMissing -= counts.cMissing;
250                         cPresent -= counts.cPresent;
251                         cExtra -= counts.cExtra;
252
253                         if (cMissing < 0 || cPresent < 0 || cExtra < 0)
254                                 throw new Exception ("Underflow");
255                 }
256                 public void Add (PresenceTypes type)
257                 {
258                         Add (new PresenceCounts (type));
259                 }
260                 public void Sub (PresenceTypes type)
261                 {
262                         Sub (new PresenceCounts (type));
263                 }
264                 public void SetAttributes (XmlElement elt, string strSuffix)
265                 {
266                         if (cMissing != 0)
267                                 elt.SetAttribute ("missing"+strSuffix, cMissing.ToString ());
268                         if (cPresent != 0)
269                                 elt.SetAttribute ("present"+strSuffix, cPresent.ToString ());
270                         if (cExtra != 0)
271                                 elt.SetAttribute ("extra"+strSuffix, cExtra.ToString ());
272                 }
273         }
274
275         public struct ErrorCounts
276         {
277                 public int cOK;
278                 public int cTodo;
279                 public int cWarning;
280                 public int cError;
281
282                 public ErrorCounts (ErrorTypes type)
283                 {
284                         cOK = cTodo = cWarning = cError = 0;
285                         if (type == ErrorTypes.OK)
286                                 cOK = 1;
287                         else if (type == ErrorTypes.Todo)
288                                 cTodo = 1;
289                         else if (type == ErrorTypes.Warning)
290                                 cWarning = 1;
291                         else if (type == ErrorTypes.Error)
292                                 cError = 1;
293                         else throw new Exception ("Invalid ErrorType");
294                 }
295                 public int Total
296                 {
297                         get { return cOK + cTodo + cWarning + cError; }
298                 }
299                 public void Add (ErrorCounts counts)
300                 {
301                         cOK += counts.cOK;
302                         cTodo += counts.cTodo;
303                         cWarning += counts.cWarning;
304                         cError += counts.cError;
305                 }
306                 public void Sub (ErrorCounts counts)
307                 {
308                         cOK -= counts.cOK;
309                         cTodo -= counts.cTodo;
310                         cWarning -= counts.cWarning;
311                         cError -= counts.cError;
312                         if (cOK < 0 || cTodo < 0 || cWarning < 0 || cError < 0)
313                                 throw new Exception ("Underflow");
314                 }
315                 public void Add (ErrorTypes type)
316                 {
317                         Add (new ErrorCounts (type));
318                 }
319                 public void Sub (ErrorTypes type)
320                 {
321                         Sub (new ErrorCounts (type));
322                 }
323                 public void SetAttributes (XmlElement elt, string strSuffix)
324                 {
325                         if (cOK != 0)
326                                 elt.SetAttribute ("ok"+strSuffix, cOK.ToString ());
327                         if (cTodo != 0)
328                                 elt.SetAttribute ("todo"+strSuffix, cTodo.ToString ());
329                         if (cWarning != 0)
330                                 elt.SetAttribute ("warning"+strSuffix, cWarning.ToString ());
331                         if (cError != 0)
332                                 elt.SetAttribute ("error"+strSuffix, cError.ToString ());
333                 }
334         }
335
336         public struct Status
337         {
338                 public PresenceTypes presence;
339                 public ErrorTypes error;
340
341                 public string PresenceName
342                 {
343                         get
344                         {
345                                 if (presence == PresenceTypes.Missing)
346                                         return "missing";
347                                 else if (presence == PresenceTypes.Present)
348                                         return "present";
349                                 else if (presence == PresenceTypes.Extra)
350                                         return "extra";
351                                 else throw new Exception ("Invalid PresenceType");
352                         }
353                 }
354                 public string ErrorName
355                 {
356                         get
357                         {
358                                 if (error == ErrorTypes.OK)
359                                         return "OK";
360                                 else if (error == ErrorTypes.Todo)
361                                         return "todo";
362                                 else if (error == ErrorTypes.Warning)
363                                         return "warning";
364                                 else if (error == ErrorTypes.Error)
365                                         return "error";
366                                 else throw new Exception ("Invalid ErrorType");
367                         }
368                 }
369                 public void SetAttributes (XmlElement elt)
370                 {
371                         if (presence != PresenceTypes.Present)
372                                 elt.SetAttribute ("presence", PresenceName);
373                         if (error != ErrorTypes.OK)
374                                 elt.SetAttribute ("error", ErrorName);
375                 }
376         }
377
378         public struct StatusCounts
379         {
380                 public PresenceCounts presenceCounts;
381                 public ErrorCounts errorCounts;
382
383                 public void Add (StatusCounts statusCounts)
384                 {
385                         presenceCounts.Add (statusCounts.presenceCounts);
386                         errorCounts.Add (statusCounts.errorCounts);
387                         if (presenceCounts.Total != errorCounts.Total)
388                                 throw new Exception ("invalid status counts");
389                 }
390                 public void Sub (StatusCounts statusCounts)
391                 {
392                         presenceCounts.Sub (statusCounts.presenceCounts);
393                         errorCounts.Sub (statusCounts.errorCounts);
394                         if (presenceCounts.Total != errorCounts.Total)
395                                 throw new Exception ("invalid status counts");
396                 }
397                 public void Add (Status status)
398                 {
399                         presenceCounts.Add (status.presence);
400                         errorCounts.Add (status.error);
401                         if (presenceCounts.Total != errorCounts.Total)
402                                 throw new Exception ("invalid status counts");
403                 }
404                 public void Sub (Status status)
405                 {
406                         presenceCounts.Sub (status.presence);
407                         errorCounts.Sub (status.error);
408                         if (presenceCounts.Total != errorCounts.Total)
409                                 throw new Exception ("invalid status counts");
410                 }
411                 public void SetAttributes (XmlElement elt, string strSuffix)
412                 {
413                         presenceCounts.SetAttributes (elt, strSuffix);
414                         errorCounts.SetAttributes (elt, strSuffix);
415
416                         int cTotal = presenceCounts.cMissing + presenceCounts.cPresent;
417                         int cIncomplete =
418                                 presenceCounts.cMissing +
419                                 errorCounts.cTodo +
420                                 errorCounts.cWarning +
421                                 errorCounts.cError;
422
423                         if (presenceCounts.Total != errorCounts.Total)
424                                 throw new Exception ("invalid status counts");
425
426                         if (cTotal != 0)
427                         {
428                                 int percentComplete = 100 * (cTotal - cIncomplete) / cTotal;
429                                 elt.SetAttribute ("complete" + strSuffix, percentComplete.ToString ());
430                         }
431                 }
432         }
433
434         public class NodeMessage
435         {
436                 protected string msg;
437
438                 public NodeMessage (string _msg)
439                 {
440                         msg = _msg;
441                 }
442
443                 public string Message
444                 {
445                         get { return msg; }
446                 }
447         }
448
449         public class NodeStatus
450         {
451                 public Status status;
452                 protected StatusCounts statusCountsChildren;
453                 protected StatusCounts statusCountsTotal;
454                 protected IList lstWarnings;
455
456                 public NodeStatus ()
457                 {
458                         status.error = ErrorTypes.OK;
459                 }
460
461                 /// <summary>
462                 /// Constructs a NodeStatus by comparing the presence of two objects
463                 /// it only sets the status.presence field
464                 /// </summary>
465                 /// <param name="objMono"></param>
466                 /// <param name="objMS"></param>
467                 public NodeStatus (Object objMono, Object objMS)
468                 {
469                         status.error = ErrorTypes.OK;
470                         statusCountsChildren = statusCountsTotal = new StatusCounts ();
471                         if (objMono == null)
472                                 status.presence = PresenceTypes.Missing;
473                         else if (objMS == null)
474                                 status.presence = PresenceTypes.Extra;
475                         else
476                                 status.presence = PresenceTypes.Present;
477                 }
478                 public void Add (NodeStatus statusChild)
479                 {
480                         if ((int) statusChild.status.error > (int) status.error)
481                                 status.error = statusChild.status.error;
482                         statusCountsTotal.Add (statusChild.statusCountsTotal);
483                         statusCountsChildren.Add (statusChild.statusCountsChildren);
484                 }
485                 public void AddChildren (NodeStatus statusChild)
486                 {
487                         statusCountsTotal.Add (statusChild.statusCountsTotal);
488                         statusCountsTotal.Add (statusChild.status);
489                         statusCountsChildren.Add (statusChild.status);
490                 }
491
492                 public void SubChildren (NodeStatus statusChild)
493                 {
494                         statusCountsTotal.Sub (statusChild.statusCountsTotal);
495                         statusCountsTotal.Sub (statusChild.status);
496                         statusCountsChildren.Sub (statusChild.status);
497                 }
498
499                 public void Add (StatusCounts statusCounts)
500                 {
501                         statusCountsChildren.Add (statusCounts);
502                         statusCountsTotal.Add (statusCounts);
503                 }
504
505                 public void Sub (StatusCounts statusCounts)
506                 {
507                         statusCountsChildren.Sub (statusCounts);
508                         statusCountsTotal.Sub (statusCounts);
509                 }
510
511                 public void Add (Status status)
512                 {
513                         statusCountsChildren.Add (status);
514                         statusCountsTotal.Add (status);
515                 }
516
517                 public void Sub (Status status)
518                 {
519                         statusCountsChildren.Sub (status);
520                         statusCountsTotal.Sub (status);
521                 }
522
523
524                 public bool IsMissing
525                 {
526                         get { return status.presence == PresenceTypes.Missing; }
527                 }
528                 public bool IsPresent
529                 {
530                         get { return status.presence == PresenceTypes.Present; }
531                 }
532                 public bool IsExtra
533                 {
534                         get { return status.presence == PresenceTypes.Extra; }
535                 }
536
537                 public void SetAttributes (XmlElement elt)
538                 {
539                         status.SetAttributes (elt);
540                         statusCountsChildren.SetAttributes (elt, "");
541                         statusCountsTotal.SetAttributes (elt, "_total");
542
543                         // add any warning messages
544                         if (lstWarnings != null)
545                         {
546                                 XmlElement eltWarnings = elt.OwnerDocument.CreateElement ("warnings");
547                                 elt.AppendChild (eltWarnings);
548                                 foreach (NodeMessage msg in lstWarnings)
549                                 {
550                                         XmlElement eltWarning = elt.OwnerDocument.CreateElement ("warning");
551                                         eltWarnings.AppendChild (eltWarning);
552                                         eltWarning.SetAttribute ("text", msg.Message);
553                                 }
554                         }
555
556                         //int percentComplete = (cTotal == 0) ? 100 : (100 - 100 * (cMissing + cExtra) / cTotal);
557                         //elt.SetAttribute ("complete", percentComplete.ToString ());
558                 }
559                 public void SetError (ErrorTypes errorNew)
560                 {
561                         // TODO: assumes order of error values
562                         if ((int) errorNew > (int) status.error)
563                                 status.error = errorNew;
564                 }
565                 public void AddWarning (string strWarning)
566                 {
567                         if (lstWarnings == null)
568                                 lstWarnings = new ArrayList ();
569                         lstWarnings.Add (new NodeMessage (strWarning));
570                         SetError (ErrorTypes.Warning);
571                 }
572         }
573 }