VirtualBox

source: vbox/trunk/src/VBox/Debugger/testcase/tstDBGCParser.cpp@ 41553

Last change on this file since 41553 was 41553, checked in by vboxsync, 13 years ago

Debugger hacking: Moving status codes to VBox/err.h. Changing the mod operator from '%s' to 'mod' to avoid confusing it an the flat-address operator. Working on more parsers testcases.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Revision
File size: 24.2 KB
Line 
1/* $Id: tstDBGCParser.cpp 41553 2012-06-02 20:11:07Z vboxsync $ */
2/** @file
3 * DBGC Testcase - Command Parser.
4 */
5
6/*
7 * Copyright (C) 2006-2011 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18/*******************************************************************************
19* Header Files *
20*******************************************************************************/
21#include <VBox/dbg.h>
22#include "../DBGCInternal.h"
23
24#include <iprt/string.h>
25#include <iprt/test.h>
26#include <VBox/err.h>
27
28
29/*******************************************************************************
30* Internal Functions *
31*******************************************************************************/
32static DECLCALLBACK(bool) tstDBGCBackInput(PDBGCBACK pBack, uint32_t cMillies);
33static DECLCALLBACK(int) tstDBGCBackRead(PDBGCBACK pBack, void *pvBuf, size_t cbBuf, size_t *pcbRead);
34static DECLCALLBACK(int) tstDBGCBackWrite(PDBGCBACK pBack, const void *pvBuf, size_t cbBuf, size_t *pcbWritten);
35static DECLCALLBACK(void) tstDBGCBackSetReady(PDBGCBACK pBack, bool fReady);
36
37
38/*******************************************************************************
39* Global Variables *
40*******************************************************************************/
41/** The test handle. */
42static RTTEST g_hTest = NIL_RTTEST;
43
44/** The DBGC backend structure for use in this testcase. */
45static DBGCBACK g_tstBack =
46{
47 tstDBGCBackInput,
48 tstDBGCBackRead,
49 tstDBGCBackWrite,
50 tstDBGCBackSetReady
51};
52/** For keeping track of output prefixing. */
53static bool g_fPendingPrefix = true;
54/** Pointer to the current input position. */
55const char *g_pszInput = NULL;
56/** The output of the last command. */
57static char g_szOutput[1024];
58/** The current offset into g_szOutput. */
59static size_t g_offOutput = 0;
60
61
62/**
63 * Checks if there is input.
64 *
65 * @returns true if there is input ready.
66 * @returns false if there not input ready.
67 * @param pBack Pointer to the backend structure supplied by
68 * the backend. The backend can use this to find
69 * it's instance data.
70 * @param cMillies Number of milliseconds to wait on input data.
71 */
72static DECLCALLBACK(bool) tstDBGCBackInput(PDBGCBACK pBack, uint32_t cMillies)
73{
74 return g_pszInput != NULL
75 && *g_pszInput != '\0';
76}
77
78
79/**
80 * Read input.
81 *
82 * @returns VBox status code.
83 * @param pBack Pointer to the backend structure supplied by
84 * the backend. The backend can use this to find
85 * it's instance data.
86 * @param pvBuf Where to put the bytes we read.
87 * @param cbBuf Maximum nymber of bytes to read.
88 * @param pcbRead Where to store the number of bytes actually read.
89 * If NULL the entire buffer must be filled for a
90 * successful return.
91 */
92static DECLCALLBACK(int) tstDBGCBackRead(PDBGCBACK pBack, void *pvBuf, size_t cbBuf, size_t *pcbRead)
93{
94 if (g_pszInput && *g_pszInput)
95 {
96 size_t cb = strlen(g_pszInput);
97 if (cb > cbBuf)
98 cb = cbBuf;
99 *pcbRead = cb;
100 memcpy(pvBuf, g_pszInput, cb);
101 g_pszInput += cb;
102 }
103 else
104 *pcbRead = 0;
105 return VINF_SUCCESS;
106}
107
108
109/**
110 * Write (output).
111 *
112 * @returns VBox status code.
113 * @param pBack Pointer to the backend structure supplied by
114 * the backend. The backend can use this to find
115 * it's instance data.
116 * @param pvBuf What to write.
117 * @param cbBuf Number of bytes to write.
118 * @param pcbWritten Where to store the number of bytes actually written.
119 * If NULL the entire buffer must be successfully written.
120 */
121static DECLCALLBACK(int) tstDBGCBackWrite(PDBGCBACK pBack, const void *pvBuf, size_t cbBuf, size_t *pcbWritten)
122{
123 const char *pch = (const char *)pvBuf;
124 if (pcbWritten)
125 *pcbWritten = cbBuf;
126 while (cbBuf-- > 0)
127 {
128 /* screen/log output */
129 if (g_fPendingPrefix)
130 {
131 RTTestPrintfNl(g_hTest, RTTESTLVL_ALWAYS, "OUTPUT: ");
132 g_fPendingPrefix = false;
133 }
134 if (*pch == '\n')
135 g_fPendingPrefix = true;
136 RTTestPrintf(g_hTest, RTTESTLVL_ALWAYS, "%c", *pch);
137
138 /* buffer output */
139 if (g_offOutput < sizeof(g_szOutput) - 1)
140 {
141 g_szOutput[g_offOutput++] = *pch;
142 g_szOutput[g_offOutput] = '\0';
143 }
144
145 /* advance */
146 pch++;
147 }
148 return VINF_SUCCESS;
149}
150
151
152/**
153 * Ready / busy notification.
154 *
155 * @param pBack Pointer to the backend structure supplied by
156 * the backend. The backend can use this to find
157 * it's instance data.
158 * @param fReady Whether it's ready (true) or busy (false).
159 */
160static DECLCALLBACK(void) tstDBGCBackSetReady(PDBGCBACK pBack, bool fReady)
161{
162}
163
164
165/**
166 * Completes the output, making sure that we're in
167 * the 1 position of a new line.
168 */
169static void tstCompleteOutput(void)
170{
171 if (!g_fPendingPrefix)
172 RTTestPrintf(g_hTest, RTTESTLVL_ALWAYS, "\n");
173 g_fPendingPrefix = true;
174}
175
176
177/**
178 * Checks if two DBGC variables are identical
179 *
180 * @returns
181 * @param pVar1 .
182 * @param pVar2 .
183 */
184bool DBGCVarAreIdentical(PCDBGCVAR pVar1, PCDBGCVAR pVar2)
185{
186 if (!pVar1)
187 return false;
188 if (pVar1 == pVar2)
189 return true;
190
191 if (pVar1->enmType != pVar2->enmType)
192 return false;
193 switch (pVar1->enmType)
194 {
195 case DBGCVAR_TYPE_GC_FLAT:
196 if (pVar1->u.GCFlat != pVar2->u.GCFlat)
197 return false;
198 break;
199 case DBGCVAR_TYPE_GC_FAR:
200 if (pVar1->u.GCFar.off != pVar2->u.GCFar.off)
201 return false;
202 if (pVar1->u.GCFar.sel != pVar2->u.GCFar.sel)
203 return false;
204 break;
205 case DBGCVAR_TYPE_GC_PHYS:
206 if (pVar1->u.GCPhys != pVar2->u.GCPhys)
207 return false;
208 break;
209 case DBGCVAR_TYPE_HC_FLAT:
210 if (pVar1->u.pvHCFlat != pVar2->u.pvHCFlat)
211 return false;
212 break;
213 case DBGCVAR_TYPE_HC_PHYS:
214 if (pVar1->u.HCPhys != pVar2->u.HCPhys)
215 return false;
216 break;
217 case DBGCVAR_TYPE_NUMBER:
218 if (pVar1->u.u64Number != pVar2->u.u64Number)
219 return false;
220 break;
221 case DBGCVAR_TYPE_STRING:
222 case DBGCVAR_TYPE_SYMBOL:
223 if (RTStrCmp(pVar1->u.pszString, pVar2->u.pszString) != 0)
224 return false;
225 break;
226 default:
227 AssertFailedReturn(false);
228 }
229
230 if (pVar1->enmRangeType != pVar2->enmRangeType)
231 return false;
232 switch (pVar1->enmRangeType)
233 {
234 case DBGCVAR_RANGE_NONE:
235 break;
236
237 case DBGCVAR_RANGE_ELEMENTS:
238 case DBGCVAR_RANGE_BYTES:
239 if (pVar1->u64Range != pVar2->u64Range)
240 return false;
241 break;
242 default:
243 AssertFailedReturn(false);
244 }
245
246 return true;
247}
248
249/**
250 * Tries one command string.
251 * @param pDbgc Pointer to the debugger instance.
252 * @param pszCmds The command to test.
253 * @param rcCmd The expected result.
254 * @param fNoExecute When set, the command is not executed.
255 * @param pszExpected Expected output. This does not need to include all
256 * of the output, just the start of it. Thus the
257 * prompt can be omitted.
258 * @param cArgs The number of expected arguments. -1 if we don't
259 * want to check the parsed arguments.
260 * @param va Info about expected parsed arguments. For each
261 * argument a DBGCVARTYPE, value (depends on type),
262 * DBGCVARRANGETYPE and optionally range value.
263 */
264static void tstTryExV(PDBGC pDbgc, const char *pszCmds, int rcCmd, bool fNoExecute, const char *pszExpected,
265 int32_t cArgs, va_list va)
266{
267 RT_ZERO(g_szOutput);
268 g_offOutput = 0;
269 g_pszInput = pszCmds;
270 if (strchr(pszCmds, '\0')[-1] == '\n')
271 RTTestPrintfNl(g_hTest, RTTESTLVL_ALWAYS, "RUNNING: %s", pszCmds);
272 else
273 RTTestPrintfNl(g_hTest, RTTESTLVL_ALWAYS, "RUNNING: %s\n", pszCmds);
274
275 pDbgc->rcCmd = VERR_INTERNAL_ERROR;
276 dbgcProcessInput(pDbgc, fNoExecute);
277 tstCompleteOutput();
278
279 if (pDbgc->rcCmd != rcCmd)
280 RTTestFailed(g_hTest, "rcCmd=%Rrc expected =%Rrc\n", pDbgc->rcCmd, rcCmd);
281 else if ( !fNoExecute
282 && pszExpected
283 && strncmp(pszExpected, g_szOutput, strlen(pszExpected)))
284 RTTestFailed(g_hTest, "Wrong output - expected \"%s\"", pszExpected);
285
286 if (cArgs >= 0)
287 {
288 PCDBGCVAR paArgs = pDbgc->aArgs;
289 for (int32_t iArg = 0; iArg < cArgs; iArg++)
290 {
291 DBGCVAR ExpectedArg;
292 ExpectedArg.enmType = (DBGCVARTYPE)va_arg(va, int/*DBGCVARTYPE*/);
293 switch (ExpectedArg.enmType)
294 {
295 case DBGCVAR_TYPE_GC_FLAT: ExpectedArg.u.GCFlat = va_arg(va, RTGCPTR); break;
296 case DBGCVAR_TYPE_GC_FAR: ExpectedArg.u.GCFar.sel = va_arg(va, int /*RTSEL*/);
297 ExpectedArg.u.GCFar.off = va_arg(va, uint32_t); break;
298 case DBGCVAR_TYPE_GC_PHYS: ExpectedArg.u.GCPhys = va_arg(va, RTGCPHYS); break;
299 case DBGCVAR_TYPE_HC_FLAT: ExpectedArg.u.pvHCFlat = va_arg(va, void *); break;
300 case DBGCVAR_TYPE_HC_PHYS: ExpectedArg.u.HCPhys = va_arg(va, RTHCPHYS); break;
301 case DBGCVAR_TYPE_NUMBER: ExpectedArg.u.u64Number = va_arg(va, uint64_t); break;
302 case DBGCVAR_TYPE_STRING: ExpectedArg.u.pszString = va_arg(va, const char *); break;
303 case DBGCVAR_TYPE_SYMBOL: ExpectedArg.u.pszString = va_arg(va, const char *); break;
304 default:
305 RTTestFailed(g_hTest, "enmType=%u iArg=%u\n", ExpectedArg.enmType, iArg);
306 ExpectedArg.u.u64Number = 0;
307 break;
308 }
309 ExpectedArg.enmRangeType = (DBGCVARRANGETYPE)va_arg(va, int /*DBGCVARRANGETYPE*/);
310 switch (ExpectedArg.enmRangeType)
311 {
312 case DBGCVAR_RANGE_NONE: ExpectedArg.u64Range = 0; break;
313 case DBGCVAR_RANGE_ELEMENTS: ExpectedArg.u64Range = va_arg(va, uint64_t); break;
314 case DBGCVAR_RANGE_BYTES: ExpectedArg.u64Range = va_arg(va, uint64_t); break;
315 default:
316 RTTestFailed(g_hTest, "enmRangeType=%u iArg=%u\n", ExpectedArg.enmRangeType, iArg);
317 ExpectedArg.u64Range = 0;
318 break;
319 }
320
321 if (!DBGCVarAreIdentical(&ExpectedArg, &paArgs[iArg]))
322 RTTestFailed(g_hTest,
323 "Arg #%u\n"
324 "actual: enmType=%u u64=%#RX64 enmRangeType=%u u64Range=%#RX64\n"
325 "expected: enmType=%u u64=%#RX64 enmRangeType=%u u64Range=%#RX64\n",
326 iArg,
327 paArgs[iArg].enmType, paArgs[iArg].u.u64Number, paArgs[iArg].enmRangeType, paArgs[iArg].u64Range,
328 ExpectedArg.enmType, ExpectedArg.u.u64Number, ExpectedArg.enmRangeType, ExpectedArg.u64Range);
329 }
330 }
331}
332
333/**
334 * Tries one command string.
335 *
336 * @param pDbgc Pointer to the debugger instance.
337 * @param pszCmds The command to test.
338 * @param rcCmd The expected result.
339 * @param fNoExecute When set, the command is not executed.
340 * @param pszExpected Expected output. This does not need to include all
341 * of the output, just the start of it. Thus the
342 * prompt can be omitted.
343 * @param cArgs The number of expected arguments. -1 if we don't
344 * want to check the parsed arguments.
345 * @param ... Info about expected parsed arguments. For each
346 * argument a DBGCVARTYPE, value (depends on type),
347 * DBGCVARRANGETYPE and optionally range value.
348 */
349static void tstTryEx(PDBGC pDbgc, const char *pszCmds, int rcCmd, bool fNoExecute, const char *pszExpected, int32_t cArgs, ...)
350{
351 va_list va;
352 va_start(va, cArgs);
353 tstTryExV(pDbgc, pszCmds, rcCmd, fNoExecute, pszExpected, cArgs, va);
354 va_end(va);
355}
356
357
358/**
359 * Tries one command string without executing it.
360 *
361 * @param pDbgc Pointer to the debugger instance.
362 * @param pszCmds The command to test.
363 * @param rcCmd The expected result.
364 */
365static void tstTry(PDBGC pDbgc, const char *pszCmds, int rcCmd)
366{
367 return tstTryEx(pDbgc, pszCmds, rcCmd, true /*fNoExecute*/, NULL, -1);
368}
369
370
371#ifdef SOME_UNUSED_FUNCTION
372/**
373 * Tries to execute one command string.
374 * @param pDbgc Pointer to the debugger instance.
375 * @param pszCmds The command to test.
376 * @param rcCmd The expected result.
377 * @param pszExpected Expected output. This does not need to include all
378 * of the output, just the start of it. Thus the
379 * prompt can be omitted.
380 */
381static void tstTryExec(PDBGC pDbgc, const char *pszCmds, int rcCmd, const char *pszExpected)
382{
383 return tstTryEx(pDbgc, pszCmds, rcCmd, false /*fNoExecute*/, pszExpected, -1);
384}
385#endif
386
387
388/**
389 * Test an operator on an expression resulting a plain number.
390 *
391 * @param pDbgc Pointer to the debugger instance.
392 * @param pszExpr The express to test.
393 * @param u64Expect The expected result.
394 */
395static void tstNumOp(PDBGC pDbgc, const char *pszExpr, uint64_t u64Expect)
396{
397 char szCmd[80];
398 RTStrPrintf(szCmd, sizeof(szCmd), "format %s\n", pszExpr);
399
400 char szExpected[80];
401 RTStrPrintf(szExpected, sizeof(szExpected),
402 "Number: hex %llx dec 0i%lld oct 0t%llo", u64Expect, u64Expect, u64Expect);
403
404 return tstTryEx(pDbgc, szCmd, VINF_SUCCESS, false /*fNoExecute*/, szExpected, -1);
405}
406
407
408
409static void testCodeView_ba(PDBGC pDbgc)
410{
411 RTTestISub("codeview - ba");
412 tstTry(pDbgc, "ba x 1 0f000:0000\n", VINF_SUCCESS);
413 tstTry(pDbgc, "ba x 1 0f000:0000 0\n", VINF_SUCCESS);
414 tstTry(pDbgc, "ba x 1 0f000:0000 0 ~0\n", VINF_SUCCESS);
415 tstTry(pDbgc, "ba x 1 0f000:0000 0 ~0 \"command\"\n", VINF_SUCCESS);
416 tstTry(pDbgc, "ba x 1 0f000:0000 0 ~0 \"command\" too_many\n", VERR_DBGC_PARSE_TOO_MANY_ARGUMENTS);
417 tstTry(pDbgc, "ba x 1\n", VERR_DBGC_PARSE_TOO_FEW_ARGUMENTS);
418
419 tstTryEx(pDbgc, "ba x 1 0f000:1234 5 1000 \"command\"\n", VINF_SUCCESS,
420 true /*fNoExecute*/, NULL /*pszExpected*/, 6 /*cArgs*/,
421 DBGCVAR_TYPE_STRING, "x", DBGCVAR_RANGE_BYTES, UINT64_C(1),
422 DBGCVAR_TYPE_NUMBER, UINT64_C(1), DBGCVAR_RANGE_NONE,
423 DBGCVAR_TYPE_GC_FAR, 0xf000, UINT32_C(0x1234), DBGCVAR_RANGE_NONE,
424 DBGCVAR_TYPE_NUMBER, UINT64_C(0x5), DBGCVAR_RANGE_NONE,
425 DBGCVAR_TYPE_NUMBER, UINT64_C(0x1000), DBGCVAR_RANGE_NONE,
426 DBGCVAR_TYPE_STRING, "command", DBGCVAR_RANGE_BYTES, UINT64_C(7));
427
428 tstTryEx(pDbgc, "ba x 1 %0f000:1234 5 1000 \"command\"\n", VINF_SUCCESS,
429 true /*fNoExecute*/, NULL /*pszExpected*/, 6 /*cArgs*/,
430 DBGCVAR_TYPE_STRING, "x", DBGCVAR_RANGE_BYTES, UINT64_C(1),
431 DBGCVAR_TYPE_NUMBER, UINT64_C(1), DBGCVAR_RANGE_NONE,
432 DBGCVAR_TYPE_GC_FLAT, UINT64_C(0xf1234), DBGCVAR_RANGE_NONE,
433 DBGCVAR_TYPE_NUMBER, UINT64_C(0x5), DBGCVAR_RANGE_NONE,
434 DBGCVAR_TYPE_NUMBER, UINT64_C(0x1000), DBGCVAR_RANGE_NONE,
435 DBGCVAR_TYPE_STRING, "command", DBGCVAR_RANGE_BYTES, UINT64_C(7));
436
437 tstTry(pDbgc, "ba x 1 bad:bad 5 1000 \"command\"\n", VINF_SUCCESS);
438 tstTry(pDbgc, "ba x 1 %bad:bad 5 1000 \"command\"\n", VERR_DBGC_PARSE_CONVERSION_FAILED);
439
440 tstTryEx(pDbgc, "ba f 1 0f000:1234 5 1000 \"command\"\n", VINF_SUCCESS,
441 true /*fNoExecute*/, NULL /*pszExpected*/, 6 /*cArgs*/,
442 DBGCVAR_TYPE_STRING, "f", DBGCVAR_RANGE_BYTES, UINT64_C(1),
443 DBGCVAR_TYPE_NUMBER, UINT64_C(1), DBGCVAR_RANGE_NONE,
444 DBGCVAR_TYPE_GC_FAR, 0xf000, UINT32_C(0x1234), DBGCVAR_RANGE_NONE,
445 DBGCVAR_TYPE_NUMBER, UINT64_C(0x5), DBGCVAR_RANGE_NONE,
446 DBGCVAR_TYPE_NUMBER, UINT64_C(0x1000), DBGCVAR_RANGE_NONE,
447 DBGCVAR_TYPE_STRING, "command", DBGCVAR_RANGE_BYTES, UINT64_C(7));
448
449 tstTry(pDbgc, "ba x 1 0f000:1234 qnx 1000 \"command\"\n", VERR_DBGC_PARSE_ARGUMENT_TYPE_MISMATCH);
450 tstTry(pDbgc, "ba x 1 0f000:1234 5 qnx \"command\"\n", VERR_DBGC_PARSE_ARGUMENT_TYPE_MISMATCH);
451 tstTry(pDbgc, "ba x qnx 0f000:1234 5 1000 \"command\"\n", VERR_DBGC_PARSE_ARGUMENT_TYPE_MISMATCH);
452 tstTry(pDbgc, "ba x 1 qnx 5 1000 \"command\"\n", VERR_DBGC_PARSE_ARGUMENT_TYPE_MISMATCH);
453}
454
455
456int main()
457{
458 /*
459 * Init.
460 */
461 int rc = RTTestInitAndCreate("tstDBGCParser", &g_hTest);
462 if (rc)
463 return rc;
464 RTTestBanner(g_hTest);
465
466 /*
467 * Create a DBGC instance.
468 */
469 RTTestSub(g_hTest, "dbgcCreate");
470 PDBGC pDbgc;
471 rc = dbgcCreate(&pDbgc, &g_tstBack, 0);
472 if (RT_SUCCESS(rc))
473 {
474 pDbgc->pVM = (PVM)pDbgc;
475 rc = dbgcProcessInput(pDbgc, true /* fNoExecute */);
476 tstCompleteOutput();
477 if (RT_SUCCESS(rc))
478 {
479 RTTestSub(g_hTest, "basic parsing");
480 tstTry(pDbgc, "stop\n", VINF_SUCCESS);
481 tstTry(pDbgc, "format 1\n", VINF_SUCCESS);
482 tstTry(pDbgc, "format \n", VERR_DBGC_PARSE_TOO_FEW_ARGUMENTS);
483 tstTry(pDbgc, "format 0 1 23 4\n", VERR_DBGC_PARSE_TOO_MANY_ARGUMENTS);
484 tstTry(pDbgc, "sa 3 23 4 'q' \"21123123\" 'b' \n", VINF_SUCCESS);
485
486 if (RTTestErrorCount(g_hTest) == 0)
487 {
488 RTTestSub(g_hTest, "Operators");
489 tstNumOp(pDbgc, "1", 1);
490 tstNumOp(pDbgc, "1", 1);
491 tstNumOp(pDbgc, "1", 1);
492
493 tstNumOp(pDbgc, "+1", 1);
494 tstNumOp(pDbgc, "++++++1", 1);
495
496 tstNumOp(pDbgc, "-1", UINT64_MAX);
497 tstNumOp(pDbgc, "--1", 1);
498 tstNumOp(pDbgc, "---1", UINT64_MAX);
499 tstNumOp(pDbgc, "----1", 1);
500
501 tstNumOp(pDbgc, "~0", UINT64_MAX);
502 tstNumOp(pDbgc, "~1", UINT64_MAX-1);
503 tstNumOp(pDbgc, "~~0", 0);
504 tstNumOp(pDbgc, "~~1", 1);
505
506 tstNumOp(pDbgc, "!1", 0);
507 tstNumOp(pDbgc, "!0", 1);
508 tstNumOp(pDbgc, "!42", 0);
509 tstNumOp(pDbgc, "!!42", 1);
510 tstNumOp(pDbgc, "!!!42", 0);
511 tstNumOp(pDbgc, "!!!!42", 1);
512
513 tstNumOp(pDbgc, "1 +1", 2);
514 tstNumOp(pDbgc, "1 + 1", 2);
515 tstNumOp(pDbgc, "1+1", 2);
516 tstNumOp(pDbgc, "1+ 1", 2);
517
518 tstNumOp(pDbgc, "1 - 1", 0);
519 tstNumOp(pDbgc, "99 - 90", 9);
520
521 tstNumOp(pDbgc, "2 * 2", 4);
522
523 tstNumOp(pDbgc, "2 / 2", 1);
524 tstNumOp(pDbgc, "2 / 0", UINT64_MAX);
525 tstNumOp(pDbgc, "0i1024 / 0i4", 256);
526
527 tstNumOp(pDbgc, "8 mod 7", 1);
528
529 tstNumOp(pDbgc, "1<<1", 2);
530 tstNumOp(pDbgc, "1<<0i32", UINT64_C(0x0000000100000000));
531 tstNumOp(pDbgc, "1<<0i48", UINT64_C(0x0001000000000000));
532 tstNumOp(pDbgc, "1<<0i63", UINT64_C(0x8000000000000000));
533
534 tstNumOp(pDbgc, "fedcba0987654321>>0i04", UINT64_C(0x0fedcba098765432));
535 tstNumOp(pDbgc, "fedcba0987654321>>0i32", UINT64_C(0xfedcba09));
536 tstNumOp(pDbgc, "fedcba0987654321>>0i48", UINT64_C(0x0000fedc));
537
538 tstNumOp(pDbgc, "0ef & 4", 4);
539 tstNumOp(pDbgc, "01234567891 & fff", UINT64_C(0x00000000891));
540 tstNumOp(pDbgc, "01234567891 & ~fff", UINT64_C(0x01234567000));
541
542 tstNumOp(pDbgc, "1 | 1", 1);
543 tstNumOp(pDbgc, "0 | 4", 4);
544 tstNumOp(pDbgc, "4 | 0", 4);
545 tstNumOp(pDbgc, "4 | 4", 4);
546 tstNumOp(pDbgc, "1 | 4 | 2", 7);
547
548 tstNumOp(pDbgc, "1 ^ 1", 0);
549 tstNumOp(pDbgc, "1 ^ 0", 1);
550 tstNumOp(pDbgc, "0 ^ 1", 1);
551 tstNumOp(pDbgc, "3 ^ 1", 2);
552 tstNumOp(pDbgc, "7 ^ 3", 4);
553
554 tstNumOp(pDbgc, "7 || 3", 1);
555 tstNumOp(pDbgc, "1 || 0", 1);
556 tstNumOp(pDbgc, "0 || 1", 1);
557 tstNumOp(pDbgc, "0 || 0", 0);
558
559 tstNumOp(pDbgc, "0 && 0", 0);
560 tstNumOp(pDbgc, "1 && 0", 0);
561 tstNumOp(pDbgc, "0 && 1", 0);
562 tstNumOp(pDbgc, "1 && 1", 1);
563 tstNumOp(pDbgc, "4 && 1", 1);
564 }
565
566 if (RTTestErrorCount(g_hTest) == 0)
567 {
568 RTTestSub(g_hTest, "Odd cases");
569 tstTry(pDbgc, "r @rax\n", VINF_SUCCESS);
570 tstTry(pDbgc, "r @eax\n", VINF_SUCCESS);
571 tstTry(pDbgc, "r @ah\n", VINF_SUCCESS);
572 tstTry(pDbgc, "r @notavalidregister\n", VERR_DBGF_REGISTER_NOT_FOUND);
573 }
574
575 /*
576 * Test codeview commands.
577 */
578#ifdef DEBUG_bird /* This will fail for a while */
579 if (RTTestErrorCount(g_hTest) == 0)
580 {
581 testCodeView_ba(pDbgc);
582
583 }
584#endif
585 }
586
587 dbgcDestroy(pDbgc);
588 }
589
590 /*
591 * Summary
592 */
593 return RTTestSummaryAndDestroy(g_hTest);
594}
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette