Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

488 lines
13 KiB

  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <string.h>
  4. #include <windows.h>
  5. #include <commdlg.h>
  6. #include "prfl.h"
  7. #include "skeltest.h"
  8. #include "hugetest.h"
  9. #include "primtest.h"
  10. #include "teapot.h"
  11. #include "resource.h"
  12. #include "macros.h"
  13. // DEFINES
  14. #define WM_EOT (WM_USER+0)
  15. #define WM_READTEST (WM_USER+1)
  16. #define WM_DONEREADING (WM_USER+2)
  17. #define WM_STARTTEST (WM_USER+3)
  18. #define WM_ABORTTEST (WM_USER+4)
  19. #define WM_TESTDONE (WM_USER+5)
  20. // GLOBAL VARIABLES
  21. static LPCTSTR lpszAppName = "Scripter";
  22. HINSTANCE hInstance;
  23. HWND hWndMain;
  24. FILE *infile = stdin;
  25. FILE *outfile = stdout;
  26. // FUNCTION HEADERS
  27. LRESULT CALLBACK mainWndProc(HWND, UINT, WPARAM, LPARAM);
  28. // INLINE FUNCTIONS
  29. inline void SetText(char *szText) {
  30. SetDlgItemText(hWndMain, S_IDC_MESSAGE, szText);
  31. #ifdef DEBUG
  32. fprintf(stderr, "main window text: %s\n", szText);
  33. #endif
  34. }
  35. inline void ShowButtonOK(BOOL bShow)
  36. { ShowWindow(GetDlgItem(hWndMain,IDOK), bShow ? SW_SHOWNORMAL : SW_HIDE); }
  37. inline void ShowButtonCancel(BOOL bShow)
  38. { ShowWindow(GetDlgItem(hWndMain,IDCANCEL), bShow ? SW_SHOWNORMAL : SW_HIDE); }
  39. inline void ShowButtons(BOOL bShow)
  40. { ShowButtonOK(bShow); ShowButtonCancel(bShow); }
  41. inline void ErrorMessage(const char *szMsg) {
  42. fprintf(stderr, "%s\n", szMsg);
  43. MessageBox(NULL, szMsg, "ERROR!", MB_OK | MB_ICONERROR | MB_TASKMODAL);
  44. }
  45. inline void WarningMessage(const char *szMsg) {
  46. fprintf(stderr, "%s\n", szMsg);
  47. MessageBox(NULL, szMsg, "WARNING!", MB_OK | MB_ICONWARNING | MB_TASKMODAL);
  48. }
  49. /*
  50. * reads one line in from our infile, handles comment character '#' and
  51. * line-continue character '\\'. If our buffer would overflow, we return '+'
  52. * in the first character of our string, else we return '-'
  53. */
  54. char *ReadOneLine()
  55. {
  56. static char acLine[1024];
  57. char *pc;
  58. int iSize = sizeof(acLine) - 1;
  59. int iEnd;
  60. BOOL bEOL = FALSE;
  61. acLine[0] = '-';
  62. pc = acLine + 1;
  63. while (!bEOL && iSize > 0) {
  64. pc = fgets(pc, iSize, infile);
  65. if (!pc) { // EOF
  66. return NULL;
  67. }
  68. pc = index(pc, '#'); // comments
  69. if (pc) *pc = '\0';
  70. iEnd = strlen(acLine);
  71. if (acLine[iEnd-1] == '\n') { // don't return new line
  72. acLine[iEnd-1] = '\0';
  73. iEnd--;
  74. }
  75. if (acLine[iEnd-1] != '\\') { // use \ as a line-continue indicator
  76. bEOL = TRUE;
  77. } else {
  78. bEOL = FALSE;
  79. iSize = sizeof(acLine) - iEnd;
  80. pc = acLine + iEnd - 1;
  81. }
  82. }
  83. if (!bEOL) acLine[0] = '+'; // have we run out of room?
  84. return acLine;
  85. }
  86. char *ReadOneNonBlankLine()
  87. {
  88. char *pc, *rol;
  89. BOOL bEND = FALSE;
  90. while (!bEND) {
  91. rol = pc = ReadOneLine();
  92. if (!pc) return pc;
  93. pc++;
  94. while (*pc && isspace(*pc)) pc++;
  95. bEND = (BOOL) *pc;
  96. }
  97. pc--;
  98. *pc = *rol;
  99. return pc;
  100. }
  101. int ReadScriptHeader()
  102. {
  103. char *pc;
  104. pc = ReadOneNonBlankLine();
  105. if (!pc || *pc == '+') {
  106. ErrorMessage("Fatal error reading number of tests in script file!");
  107. exit(-1);
  108. }
  109. return atoi(pc+1);
  110. }
  111. SkeletonTest **AllocateTestArray(int i)
  112. {
  113. SkeletonTest **past;
  114. past = (SkeletonTest **) malloc(i*sizeof(SkeletonTest*));
  115. bzero(past, i*sizeof(SkeletonTest*));
  116. return past;
  117. }
  118. SkeletonTest *ReadAndCreateTest()
  119. {
  120. SkeletonTest *pst = NULL;
  121. char acFileName[_MAX_PATH], acData[1024];
  122. char *szLine, *pc;
  123. int i, iFile = 0, iData = 0;
  124. void *pTmp;
  125. szLine = ReadOneNonBlankLine();
  126. if (!szLine) {
  127. ErrorMessage("Unexpected end of file.");
  128. return NULL;
  129. }
  130. if (*szLine == '+') {
  131. ErrorMessage("Line too long.");
  132. exit(-1);
  133. }
  134. szLine++;
  135. i = sscanf(szLine, "%s %n", acFileName, &iData);
  136. if (i == 0) {
  137. *acFileName = '\0';
  138. WarningMessage("Warning: no data file for this test.");
  139. }
  140. if (*acFileName == '"') {
  141. pc = index(szLine+iFile+1, '"');
  142. if (!pc) {
  143. fprintf(stderr, "Unmatched \".");
  144. exit(-1);
  145. }
  146. bzero(acFileName, sizeof(acFileName));
  147. strncpy(acFileName, szLine+iFile+1, (pc-szLine) - iFile - 1);
  148. sscanf(pc, "\" %n", &iData);
  149. strncpy(acData, pc+iData, sizeof(acData));
  150. } else {
  151. strncpy(acData, szLine+iData, sizeof(acData));
  152. }
  153. if (iData == 0)
  154. *acData = '\0';
  155. #ifdef DEBUG
  156. fprintf(stderr,
  157. "line: \'%s\'\ni: %d\nFile: %s\nData: (%d) \'%s\'\n\n",
  158. szLine, i, acFileName, iData, acData);
  159. #endif
  160. pst = NULL;
  161. pTmp = prfl_AutoLoad(acFileName, &iData);
  162. if (iData) {
  163. ErrorMessage((char*)pTmp);
  164. return NULL;
  165. }
  166. pst = (SkeletonTest*) pTmp;
  167. if (*acData) {
  168. pst->ReadExtraData(acData);
  169. }
  170. return pst;
  171. }
  172. void SetFilesFromCmdLine(const char *szCmdLine)
  173. {
  174. char acBuffer[512], acErrBuf[512];
  175. char *szIn, *szOut, *szEnd;
  176. strncpy(acBuffer, szCmdLine, sizeof(acBuffer));
  177. szIn = acBuffer;
  178. while (*szIn && isspace(*szIn)) szIn++;
  179. szEnd = szIn;
  180. if (*szEnd == '"') {
  181. szEnd = index(szIn+1, '"');
  182. if (!szEnd) {
  183. fprintf(stderr, "Unmatched \".");
  184. exit(-1);
  185. }
  186. }
  187. while (*szEnd && !isspace(*szEnd)) szEnd++;
  188. *szEnd = '\0';
  189. szOut = szEnd+1;
  190. while (*szOut && isspace(*szOut)) szOut++;
  191. szEnd = szOut;
  192. if (*szEnd == '"') {
  193. szEnd = index(szOut+1, '"');
  194. if (!szEnd) {
  195. fprintf(stderr, "Unmatched \".");
  196. exit(-1);
  197. }
  198. }
  199. while (*szEnd && !isspace(*szEnd)) szEnd++;
  200. *szEnd = '\0';
  201. infile = stdin; outfile = stdout;
  202. if (szIn && (*szIn != '\0')&&(*szIn != '-')) infile = fopen(szIn, "r");
  203. if (szOut && (*szOut != '\0')&&(*szOut != '-')) outfile = fopen(szOut,"a");
  204. if (infile && outfile)
  205. return;
  206. if (infile && !outfile)
  207. sprintf(acErrBuf, "Error opening output file: %s", szOut);
  208. if (!infile && outfile)
  209. sprintf(acErrBuf, "Error opening input file: %s", szIn);
  210. if (!infile && !outfile)
  211. sprintf(acErrBuf, "Error opening input file: %s\n"
  212. "Error opening output file: %s", szIn, szOut);
  213. ErrorMessage(acErrBuf);
  214. exit(-1);
  215. }
  216. int APIENTRY WinMain(HINSTANCE hInst, HINSTANCE hPrevInstance,
  217. LPSTR lpCmdLine, int iCmdShow)
  218. {
  219. MSG msg;
  220. WNDCLASSEX wc;
  221. HACCEL hAccel;
  222. SkeletonTest **past;
  223. int i;
  224. hInstance = hInst;
  225. // Register Window style
  226. wc.cbSize = sizeof(wc);
  227. wc.style = CS_HREDRAW | CS_VREDRAW;
  228. wc.lpfnWndProc = (WNDPROC) mainWndProc;
  229. wc.cbClsExtra = 0;
  230. wc.cbWndExtra = DLGWINDOWEXTRA;
  231. wc.hInstance = hInstance;
  232. wc.hIcon = NULL;
  233. wc.hCursor = LoadCursor(NULL, IDC_ARROW);
  234. wc.hbrBackground = (HBRUSH) COLOR_BTNSHADOW;
  235. wc.lpszMenuName = NULL;
  236. wc.lpszClassName = lpszAppName;
  237. wc.hIconSm = NULL;
  238. // Register the window class
  239. if(RegisterClassEx(&wc) == 0)
  240. exit(-1);
  241. if (prfl_RegisterClass(hInstance) == FALSE)
  242. exit(-1);
  243. SetFilesFromCmdLine(lpCmdLine);
  244. fprintf(stdout, "Reading script.\n");
  245. fflush(stdout);
  246. i = ReadScriptHeader();
  247. past = AllocateTestArray(i);
  248. hWndMain = CreateDialog(hInstance, lpszAppName, 0, NULL);
  249. SendMessage(hWndMain, WM_INITDIALOG, (WPARAM) i, (LPARAM) past);
  250. hAccel = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDR_ACCELERATOR2));
  251. while(GetMessage(&msg, NULL, 0, 0)) {
  252. if (!TranslateAccelerator(hWndMain, hAccel, &msg)) {
  253. TranslateMessage(&msg);
  254. DispatchMessage(&msg);
  255. }
  256. }
  257. return msg.wParam;
  258. }
  259. void EOT_callback()
  260. {
  261. PostMessage(hWndMain, WM_EOT, 0, 0);
  262. }
  263. // Window procedure, handles all messages for this window
  264. LRESULT CALLBACK mainWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
  265. {
  266. typedef enum { NONE, LOADING, WAITING, RUNNING, DONE } ModeType;
  267. static ModeType mMode = NONE;
  268. static char szFileName[_MAX_PATH];
  269. static char szTitleName[_MAX_FNAME + _MAX_EXT];
  270. static char acBuffer[120];
  271. static SkeletonTest **past = NULL;
  272. static int iNumTests = 0;
  273. static int iCurrent = -1;
  274. static SkeletonTest *pTest = NULL;
  275. static BOOL bOnce = FALSE;
  276. int iControl;
  277. iControl = LOWORD(wParam);
  278. #ifdef DEBUG
  279. if ((msg >= WM_USER) || (msg == WM_INITDIALOG)) {
  280. fprintf(stderr, "message: %d (WM_USER+%d) %u (%d) %u\n",
  281. msg, msg-WM_USER, wParam, iControl, lParam);
  282. }
  283. #endif
  284. switch (msg)
  285. {
  286. case WM_CREATE:
  287. break; // WM_CREATE
  288. case WM_INITDIALOG:
  289. if (!bOnce) {
  290. mMode = LOADING;
  291. past = (SkeletonTest **) lParam;
  292. iNumTests = iControl;
  293. PostMessage(hwnd, WM_READTEST, 0, 0);
  294. ShowButtonOK(FALSE);
  295. ShowButtonCancel(TRUE);
  296. SetText("This is some text.");
  297. bOnce = TRUE;
  298. } else {
  299. fprintf(stderr, "%cERROR -- Multiple inits!!!\n",7);
  300. }
  301. break; // WM_INITDIALOG
  302. case WM_READTEST:
  303. sprintf(acBuffer,"Reading test %d of %d.", iControl+1, iNumTests);
  304. SetText(acBuffer);
  305. past[iControl] = ReadAndCreateTest();
  306. if (iControl+1 < iNumTests)
  307. PostMessage(hwnd, WM_READTEST, iControl+1, 0);
  308. else
  309. PostMessage(hwnd, WM_DONEREADING, 0, 0);
  310. break; // WM_READTEST
  311. case WM_DONEREADING:
  312. mMode = WAITING;
  313. sprintf(acBuffer, "Script loaded, ready to run.");
  314. SetText(acBuffer);
  315. ShowButtons(TRUE);
  316. break; // WM_DONEREADING
  317. case WM_STARTTEST:
  318. iCurrent = iControl;
  319. if (iCurrent >= iNumTests) {
  320. iCurrent = -1;
  321. pTest = NULL;
  322. return 0;
  323. }
  324. pTest = past[iCurrent];
  325. if (!pTest) {
  326. sprintf(acBuffer, "Can't run test %d (doesn't exist).",iControl+1);
  327. SetText(acBuffer);
  328. return 0;
  329. }
  330. sprintf(acBuffer,"Running test %d: %s",iControl+1,pTest->QueryName());
  331. #ifdef DEBUG
  332. fprintf(stderr,"%s\n",acBuffer);
  333. #endif
  334. SetText(acBuffer);
  335. mMode = RUNNING;
  336. if (!prfl_StartTest(pTest, pTest->QueryName(), EOT_callback)) {
  337. sprintf(acBuffer, "Error starting test %d: %s",
  338. iCurrent, pTest->QueryName());
  339. SetText(acBuffer);
  340. MessageBeep(0);
  341. ErrorMessage(acBuffer);
  342. mMode = WAITING;
  343. return 0;
  344. }
  345. ShowButtonOK(FALSE);
  346. break; // WM_STARTTEST
  347. case WM_ABORTTEST:
  348. prfl_StopTest();
  349. mMode = WAITING;
  350. sprintf(acBuffer, "Script aborted. Ready to re-run.");
  351. SetText(acBuffer);
  352. ShowButtons(TRUE);
  353. break; // WM_ABORTTEST
  354. case WM_COMMAND:
  355. {
  356. switch (iControl)
  357. {
  358. case IDOK:
  359. switch (mMode)
  360. {
  361. case NONE:
  362. case LOADING:
  363. case RUNNING:
  364. break;
  365. case WAITING:
  366. PostMessage(hwnd, WM_STARTTEST, 0, 0);
  367. break;
  368. case DONE:
  369. DestroyWindow(hwnd);
  370. break;
  371. }
  372. break; // IDOK
  373. case IDCANCEL:
  374. switch (mMode)
  375. {
  376. case NONE:
  377. case LOADING:
  378. case WAITING:
  379. case DONE:
  380. DestroyWindow(hwnd);
  381. break;
  382. case RUNNING:
  383. SendMessage(hwnd, WM_ABORTTEST, 0, 0);
  384. break;
  385. }
  386. break; // IDCANCEL
  387. default: // This is an error!
  388. MessageBeep(0);
  389. return DefWindowProc(hwnd,msg,wParam,lParam);
  390. }
  391. }
  392. return 0; // WM_COMMAND
  393. case WM_EOT:
  394. if (prfl_TestRunning()) {
  395. PostMessage(hwnd, WM_EOT, 0, 0);
  396. } else {
  397. double dNumCalls, dDuration, dResult;
  398. dNumCalls = prfl_GetCount();
  399. dDuration = prfl_GetDuration();
  400. dResult = prfl_GetResult();
  401. sprintf(acBuffer, "%d %g %g %g %g %g %s",
  402. iCurrent, dDuration, dNumCalls, dNumCalls*1000/dDuration,
  403. dResult, dResult*1000/dDuration, pTest->QueryName());
  404. fprintf(outfile, "%s\n", acBuffer);
  405. fflush(outfile);
  406. if (iCurrent < iNumTests-1) {
  407. PostMessage(hwnd, WM_STARTTEST, iCurrent+1, 0);
  408. } else {
  409. PostMessage(hwnd, WM_TESTDONE, 0, 0);
  410. }
  411. }
  412. break; // WM_EOT
  413. case WM_TESTDONE:
  414. mMode = DONE;
  415. sprintf(acBuffer, "Script completed.");
  416. SetText(acBuffer);
  417. ShowButtonOK(TRUE);
  418. ShowButtonCancel(FALSE);
  419. break;
  420. case WM_DESTROY:
  421. PostQuitMessage(0);
  422. return 0; // WM_DESTROY
  423. }
  424. return DefWindowProc(hwnd,msg,wParam,lParam);
  425. }