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