1// regress.cpp -- Regression test program, main code
2// $Id: regress.cpp 1230 2007-03-09 15:58:53Z jcw $
3// This is part of Metakit, the homepage is http://www.equi4.com/metakit.html
4
5#include "regress.h"
6
7#if defined (macintosh)
8#include <SIOUX.h>
9#ifdef DEBUG_NEW
10#include <DebugNew.cp>
11//#include "ZoneRanger.c"
12#if DEBUG_NEW >= 2 && !defined (q4_MAC_LEAK_CHECK)
13#define q4_MAC_LEAK_CHECK 1
14#endif
15#endif
16#endif
17
18#if __profile__
19#define q4_MWCW_PROFILER 1
20#include <profiler.h>
21#endif
22
23#if q4_NOTHROW
24const char *msg;
25#endif
26
27#if _WIN32_WCE
28
29#define WIN32_LEAN_AND_MEAN
30#include <windows.h>
31
32int remove(const char *fn_) {
33  c4_Bytes buffer;
34  int n = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, fn_,  - 1, NULL, 0);
35  wchar_t *w = (wchar_t*)buffer.SetBufferClear((n + 1) *sizeof(wchar_t));
36  MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, fn_,  - 1, w, n);
37  return DeleteFile((wchar_t*)buffer.Contents()) ? 0 :  - 1;
38}
39
40#endif
41
42int
43#if _WIN32_WCE
44_cdecl
45#endif
46main() {
47  //  afxMemDF |= allocMemDF | checkAlwaysMemDF;
48
49  // The M4STRING package sometimes keeps a spare empty string around.
50  // By allocating it here, we avoid a few bogus memory leak reports.
51  c4_String empty;
52
53#if q4_MAC_LEAK_CHECK
54  DebugNewForgetLeaks();
55#endif
56
57#if q4_MWCW_PROFILER
58  if (!ProfilerInit(collectDetailed, bestTimeBase, 20, 5)) {
59#endif
60    TestBasics1();
61    TestBasics2();
62    TestNotify();
63    TestCustom1();
64    TestCustom2();
65    TestResize();
66    TestStores1();
67    TestStores2();
68    TestStores3();
69    TestStores4();
70    TestStores5();
71    TestDiffer();
72    TestExtend();
73    TestFormat();
74    TestMapped();
75    TestLimits();
76
77#if q4_MWCW_PROFILER
78    ProfilerDump("\pRegress.prof");
79    ProfilerTerm();
80  }
81#endif
82
83#if defined (_DEBUG)
84  fputs("\nPress return... ", stderr);
85  getchar();
86#endif
87#if q4_MAC_LEAK_CHECK
88  if (DebugNewReportLeaks())
89    fputs("    *** Memory leaks found ***\n", stderr);
90#endif
91#if defined (macintosh)
92  SIOUXSettings.asktosaveonclose = false;
93#endif
94
95  fputs("Done.\n", stderr);
96  return 0;
97}
98
99// Recursively display the entire view contents. The results shown do not
100// depend on file layout (free space, file positions, flat vs. on-demand).
101
102static void ViewDisplay(const c4_View &v_, FILE *fp, int l_ = 0) {
103  c4_String types;
104  bool hasData = false, hasSubs = false;
105
106  // display header info and collect all data types
107  fprintf(fp, "%*s VIEW %5d rows =", l_, "", v_.GetSize());
108  for (int n = 0; n < v_.NumProperties(); ++n) {
109    c4_Property prop = v_.NthProperty(n);
110    char t = prop.Type();
111
112    fprintf(fp, " %s:%c", (const char*)prop.Name(), t);
113
114    types += t;
115
116    if (t == 'V')
117      hasSubs = true;
118    else
119      hasData = true;
120  }
121  fprintf(fp, "\n");
122
123  for (int j = 0; j < v_.GetSize(); ++j) {
124    if (hasData)
125     { // data properties are all shown on the same line
126      fprintf(fp, "%*s %4d:", l_, "", j);
127      c4_RowRef r = v_[j];
128
129      for (int k = 0; k < types.GetLength(); ++k) {
130        c4_Property p = v_.NthProperty(k);
131
132        switch (types[k]) {
133          case 'I':
134            fprintf(fp, " %ld", (long)((c4_IntProp &)p)(r));
135            break;
136
137#if !q4_TINY
138          case 'F':
139            fprintf(fp, " %g", (double)((c4_FloatProp &)p)(r));
140            break;
141
142          case 'D':
143            fprintf(fp, " %.12g", (double)((c4_DoubleProp &)p)(r));
144            break;
145#endif
146
147          case 'S':
148            fprintf(fp, " '%s'", (const char*)((c4_StringProp &)p)(r));
149            break;
150
151          case 'M':
152            // backward compatibility
153          case 'B':
154            fprintf(fp, " (%db)", (p(r)).GetSize());
155            break;
156
157          default:
158            if (types[k] != 'V')
159              fprintf(fp, " (%c?)", types[k]);
160        }
161      }
162
163      fprintf(fp, "\n");
164    }
165
166    if (hasSubs)
167     { // subviews are then shown, each as a separate block
168      for (int k = 0; k < types.GetLength(); ++k) {
169        if (types[k] == 'V') {
170          c4_Property prop = v_.NthProperty(k);
171
172          fprintf(fp, "%*s %4d: subview '%s'\n", l_, "", j, (const char*)
173            prop.Name());
174
175          c4_ViewProp &vp = (c4_ViewProp &)prop;
176
177          ViewDisplay(vp(v_[j]), fp, l_ + 2);
178        }
179      }
180    }
181  }
182}
183
184void DumpFile(const char *in_, const char *out_) {
185  FILE *fp = fopen(out_, TEXTOUT);
186  A(fp);
187
188  c4_Storage store(in_, 0);
189
190  ViewDisplay(store, fp);
191
192  fclose(fp);
193}
194
195void Fail(const char *msg) {
196#if q4_NOTHROW
197  fprintf(stderr, "\t%s\n", msg);
198  printf("*** %s ***\n", msg);
199#else
200  throw msg;
201#endif
202}
203
204void FailExpr(const char *expr) {
205  char buffer[100];
206  sprintf(buffer, "Failed: A(%s)", expr);
207  Fail(buffer);
208}
209
210int StartTest(int mask_, const char *name_, const char *desc_) {
211  if (mask_) {
212#if q4_MFC && defined(_DEBUG)
213    TRACE("%s - %-40s *** DISABLED ***\n", name_, desc_);
214#endif
215#if !q4_MWCW_PROFILER
216    fprintf(stderr, "%s - %-40s   *** DISABLED ***\n", name_, desc_);
217#endif
218    return false;
219  }
220
221#if q4_MFC && defined(_DEBUG)
222  TRACE("%s - %s\n", name_, desc_);
223#endif
224#if !q4_MWCW_PROFILER
225  fprintf(stderr, "%s - %s\n", name_, desc_);
226#endif
227
228  char buffer[50];
229  sprintf(buffer, "%s%s.txt", TESTDIR, name_);
230#if _WIN32_WCE
231  fclose(stdout);
232  fopen(buffer, TEXTOUT);
233#else
234  freopen(buffer, TEXTOUT, stdout);
235#endif
236  printf(">>> %s\n", desc_);
237
238  return true;
239}
240
241void CatchMsg(const char *msg) {
242#if !q4_MWCW_PROFILER
243  fprintf(stderr, "\t%s\n", msg);
244#endif
245  printf("*** %s ***\n", msg);
246}
247
248void CatchOther() {
249#if !q4_MWCW_PROFILER
250  fputs("\tException!\n", stderr);
251#endif
252  printf("*** Exception ***\n");
253}
254