Create this branch to work on loading of different Kernel-Debugger DLL providers...
[reactos.git] / reactos / ntoskrnl / kdbg / kdb_expr.c
diff --git a/reactos/ntoskrnl/kdbg/kdb_expr.c b/reactos/ntoskrnl/kdbg/kdb_expr.c
deleted file mode 100644 (file)
index 6bc249d..0000000
+++ /dev/null
@@ -1,1201 +0,0 @@
-/*
- *  ReactOS kernel
- *  Copyright (C) 2005 ReactOS Team
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License along
- *  with this program; if not, write to the Free Software Foundation, Inc.,
- *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-/*
- * PROJECT:         ReactOS kernel
- * FILE:            ntoskrnl/dbg/kdb_expr.c
- * PURPOSE:         Kernel debugger expression evaluation
- * PROGRAMMER:      Gregor Anich (blight@blight.eu.org)
- * UPDATE HISTORY:
- *                  Created 15/01/2005
- */
-
-/* Note:
- *
- * The given expression is parsed and stored in reverse polish notation,
- * then it is evaluated and the result is returned.
- */
-
-/* INCLUDES ******************************************************************/
-
-#include <ntoskrnl.h>
-#define NDEBUG
-#include <debug.h>
-
-/* TYPES *********************************************************************/
-typedef enum _RPN_OP_TYPE
-{
-    RpnOpNop,
-    RpnOpBinaryOperator,
-    RpnOpUnaryOperator,
-    RpnOpImmediate,
-    RpnOpRegister,
-    RpnOpDereference
-} RPN_OP_TYPE;
-
-typedef ULONGLONG (*RPN_BINARY_OPERATOR)(ULONGLONG a, ULONGLONG b);
-
-typedef struct _RPN_OP
-{
-    RPN_OP_TYPE  Type;
-    ULONG        CharacterOffset;
-    union
-    {
-        /* RpnOpBinaryOperator */
-        RPN_BINARY_OPERATOR  BinaryOperator;
-        /* RpnOpImmediate */
-        ULONGLONG            Immediate;
-        /* RpnOpRegister */
-        UCHAR                Register;
-        /* RpnOpDereference */
-        UCHAR                DerefMemorySize;
-    }
-    Data;
-}
-RPN_OP, *PRPN_OP;
-
-typedef struct _RPN_STACK
-{
-    ULONG   Size;     /* Number of RPN_OPs on Ops */
-    ULONG   Sp;       /* Stack pointer */
-    RPN_OP  Ops[1];   /* Array of RPN_OPs */
-}
-RPN_STACK, *PRPN_STACK;
-
-/* DEFINES *******************************************************************/
-#define stricmp _stricmp
-
-#ifndef RTL_FIELD_SIZE
-# define RTL_FIELD_SIZE(type, field) (sizeof(((type *)0)->field))
-#endif
-
-#define CONST_STRCPY(dst, src) \
-    do { if ((dst)) { memcpy(dst, src, sizeof(src)); } } while (0);
-
-#define RPN_OP_STACK_SIZE     256
-#define RPN_VALUE_STACK_SIZE  256
-
-/* GLOBALS *******************************************************************/
-static struct
-{
-    ULONG Size;
-    ULONG Sp;
-    RPN_OP Ops[RPN_OP_STACK_SIZE];
-}
-RpnStack =
-{
-    RPN_OP_STACK_SIZE,
-    0
-};
-
-static const struct
-{
-    PCHAR Name;
-    UCHAR Offset;
-    UCHAR Size;
-}
-RegisterToTrapFrame[] =
-{
-    {"eip",     FIELD_OFFSET(KDB_KTRAP_FRAME, Tf.Eip),     RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Tf.Eip)},
-    {"eflags",  FIELD_OFFSET(KDB_KTRAP_FRAME, Tf.EFlags),  RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Tf.EFlags)},
-    {"eax",     FIELD_OFFSET(KDB_KTRAP_FRAME, Tf.Eax),     RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Tf.Eax)},
-    {"ebx",     FIELD_OFFSET(KDB_KTRAP_FRAME, Tf.Ebx),     RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Tf.Ebx)},
-    {"ecx",     FIELD_OFFSET(KDB_KTRAP_FRAME, Tf.Ecx),     RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Tf.Ecx)},
-    {"edx",     FIELD_OFFSET(KDB_KTRAP_FRAME, Tf.Edx),     RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Tf.Edx)},
-    {"esi",     FIELD_OFFSET(KDB_KTRAP_FRAME, Tf.Esi),     RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Tf.Esi)},
-    {"edi",     FIELD_OFFSET(KDB_KTRAP_FRAME, Tf.Edi),     RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Tf.Edi)},
-    {"esp",     FIELD_OFFSET(KDB_KTRAP_FRAME, Tf.HardwareEsp),     RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Tf.HardwareEsp)},
-    {"ebp",     FIELD_OFFSET(KDB_KTRAP_FRAME, Tf.Ebp),     RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Tf.Ebp)},
-    {"cs",      FIELD_OFFSET(KDB_KTRAP_FRAME, Tf.SegCs),      2 }, /* Use only the lower 2 bytes */
-    {"ds",      FIELD_OFFSET(KDB_KTRAP_FRAME, Tf.SegDs),      RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Tf.SegDs)},
-    {"es",      FIELD_OFFSET(KDB_KTRAP_FRAME, Tf.SegEs),      RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Tf.SegEs)},
-    {"fs",      FIELD_OFFSET(KDB_KTRAP_FRAME, Tf.SegFs),      RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Tf.SegFs)},
-    {"gs",      FIELD_OFFSET(KDB_KTRAP_FRAME, Tf.SegGs),      RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Tf.SegGs)},
-    {"ss",      FIELD_OFFSET(KDB_KTRAP_FRAME, Tf.HardwareSegSs),      RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Tf.HardwareSegSs)},
-    {"dr0",     FIELD_OFFSET(KDB_KTRAP_FRAME, Tf.Dr0),     RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Tf.Dr0)},
-    {"dr1",     FIELD_OFFSET(KDB_KTRAP_FRAME, Tf.Dr1),     RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Tf.Dr1)},
-    {"dr2",     FIELD_OFFSET(KDB_KTRAP_FRAME, Tf.Dr2),     RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Tf.Dr2)},
-    {"dr3",     FIELD_OFFSET(KDB_KTRAP_FRAME, Tf.Dr3),     RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Tf.Dr3)},
-    {"dr6",     FIELD_OFFSET(KDB_KTRAP_FRAME, Tf.Dr6),     RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Tf.Dr6)},
-    {"dr7",     FIELD_OFFSET(KDB_KTRAP_FRAME, Tf.Dr7),     RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Tf.Dr7)},
-    {"cr0",     FIELD_OFFSET(KDB_KTRAP_FRAME, Cr0),        RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Cr0)},
-    {"cr2",     FIELD_OFFSET(KDB_KTRAP_FRAME, Cr2),        RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Cr2)},
-    {"cr3",     FIELD_OFFSET(KDB_KTRAP_FRAME, Cr3),        RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Cr3)},
-    {"cr4",     FIELD_OFFSET(KDB_KTRAP_FRAME, Cr4),        RTL_FIELD_SIZE(KDB_KTRAP_FRAME, Cr4)}
-};
-static const INT RegisterToTrapFrameCount = sizeof (RegisterToTrapFrame) / sizeof (RegisterToTrapFrame[0]);
-
-/* FUNCTIONS *****************************************************************/
-
-ULONGLONG
-RpnBinaryOperatorAdd(
-    ULONGLONG a,
-    ULONGLONG b)
-{
-    return a + b;
-}
-
-ULONGLONG
-RpnBinaryOperatorSub(
-    ULONGLONG a,
-    ULONGLONG b)
-{
-    return a - b;
-}
-
-ULONGLONG
-RpnBinaryOperatorMul(
-    ULONGLONG a,
-    ULONGLONG b)
-{
-    return a * b;
-}
-
-ULONGLONG
-RpnBinaryOperatorDiv(
-    ULONGLONG a,
-    ULONGLONG b)
-{
-    return a / b;
-}
-
-ULONGLONG
-RpnBinaryOperatorMod(
-    ULONGLONG a,
-    ULONGLONG b)
-{
-    return a % b;
-}
-
-ULONGLONG
-RpnBinaryOperatorEquals(
-    ULONGLONG a,
-    ULONGLONG b)
-{
-    return (a == b);
-}
-
-ULONGLONG
-RpnBinaryOperatorNotEquals(
-    ULONGLONG a,
-    ULONGLONG b)
-{
-    return (a != b);
-}
-
-ULONGLONG
-RpnBinaryOperatorLessThan(
-    ULONGLONG a,
-    ULONGLONG b)
-{
-    return (a < b);
-}
-
-ULONGLONG
-RpnBinaryOperatorLessThanOrEquals(
-    ULONGLONG a,
-    ULONGLONG b)
-{
-    return (a <= b);
-}
-
-ULONGLONG
-RpnBinaryOperatorGreaterThan(
-    ULONGLONG a,
-    ULONGLONG b)
-{
-    return (a > b);
-}
-
-ULONGLONG
-RpnBinaryOperatorGreaterThanOrEquals(
-    ULONGLONG a,
-    ULONGLONG b)
-{
-    return (a >= b);
-}
-
-/*!\brief Dumps the given RPN stack content
- *
- * \param Stack  Pointer to a RPN_STACK structure.
- */
-VOID
-RpnpDumpStack(
-    IN PRPN_STACK Stack)
-{
-    ULONG ul;
-
-    ASSERT(Stack);
-    DbgPrint("\nStack size: %ld\n", Stack->Sp);
-
-    for (ul = 0; ul < Stack->Sp; ul++)
-    {
-        PRPN_OP Op = Stack->Ops + ul;
-        switch (Op->Type)
-        {
-            case RpnOpNop:
-                DbgPrint("NOP,");
-                break;
-
-            case RpnOpImmediate:
-                DbgPrint("0x%I64x,", Op->Data.Immediate);
-                break;
-
-            case RpnOpBinaryOperator:
-                if (Op->Data.BinaryOperator == RpnBinaryOperatorAdd)
-                    DbgPrint("+,");
-                else if (Op->Data.BinaryOperator == RpnBinaryOperatorSub)
-                    DbgPrint("-,");
-                else if (Op->Data.BinaryOperator == RpnBinaryOperatorMul)
-                    DbgPrint("*,");
-                else if (Op->Data.BinaryOperator == RpnBinaryOperatorDiv)
-                    DbgPrint("/,");
-                else if (Op->Data.BinaryOperator == RpnBinaryOperatorMod)
-                    DbgPrint("%%,");
-                else if (Op->Data.BinaryOperator == RpnBinaryOperatorEquals)
-                    DbgPrint("==,");
-                else if (Op->Data.BinaryOperator == RpnBinaryOperatorNotEquals)
-                    DbgPrint("!=,");
-                else if (Op->Data.BinaryOperator == RpnBinaryOperatorLessThan)
-                    DbgPrint("<,");
-                else if (Op->Data.BinaryOperator == RpnBinaryOperatorLessThanOrEquals)
-                    DbgPrint("<=,");
-                else if (Op->Data.BinaryOperator == RpnBinaryOperatorGreaterThan)
-                    DbgPrint(">,");
-                else if (Op->Data.BinaryOperator == RpnBinaryOperatorGreaterThanOrEquals)
-                    DbgPrint(">=,");
-                else
-                    DbgPrint("UNKNOWN OP,");
-
-                break;
-
-            case RpnOpRegister:
-                DbgPrint("%s,", RegisterToTrapFrame[Op->Data.Register].Name);
-                break;
-
-            case RpnOpDereference:
-                DbgPrint("[%s],",
-                    (Op->Data.DerefMemorySize == 1) ? ("byte") :
-                    ((Op->Data.DerefMemorySize == 2) ? ("word") :
-                    ((Op->Data.DerefMemorySize == 4) ? ("dword") : ("qword"))));
-                break;
-
-            default:
-                DbgPrint("\nUnsupported Type: %d\n", Op->Type);
-                ul = Stack->Sp;
-                break;
-        }
-    }
-
-    DbgPrint("\n");
-}
-
-/*!\brief Clears the given RPN stack.
- *
- * \param Stack  Pointer to a RPN_STACK structure.
- */
-static VOID
-RpnpClearStack(
-    OUT PRPN_STACK Stack)
-{
-    ASSERT(Stack);
-    Stack->Sp = 0;
-}
-
-/*!\brief Pushes an RPN_OP onto the stack.
- *
- * \param Stack  Pointer to a RPN_STACK structure.
- * \param Op     RPN_OP to be copied onto the stack.
- */
-static BOOLEAN
-RpnpPushStack(
-    IN OUT PRPN_STACK Stack,
-    IN     PRPN_OP Op)
-{
-    ASSERT(Stack);
-    ASSERT(Op);
-
-    if (Stack->Sp >= Stack->Size)
-        return FALSE;
-
-    memcpy(Stack->Ops + Stack->Sp, Op, sizeof (RPN_OP));
-    Stack->Sp++;
-
-    return TRUE;
-}
-
-/*!\brief Pops the top op from the stack.
- *
- * \param Stack  Pointer to a RPN_STACK structure.
- * \param Op     Pointer to an RPN_OP to store the popped op into (can be NULL).
- *
- * \retval TRUE   Success.
- * \retval FALSE  Failure (stack empty)
- */
-static BOOLEAN
-RpnpPopStack(
-    IN OUT PRPN_STACK Stack,
-    OUT    PRPN_OP Op  OPTIONAL)
-{
-    ASSERT(Stack);
-
-    if (Stack->Sp == 0)
-        return FALSE;
-
-    Stack->Sp--;
-    if (Op)
-        memcpy(Op, Stack->Ops + Stack->Sp, sizeof (RPN_OP));
-
-    return TRUE;
-}
-
-/*!\brief Gets the top op from the stack (not popping it)
- *
- * \param Stack  Pointer to a RPN_STACK structure.
- * \param Op     Pointer to an RPN_OP to copy the top op into.
- *
- * \retval TRUE   Success.
- * \retval FALSE  Failure (stack empty)
- */
-static BOOLEAN
-RpnpTopStack(
-    IN  PRPN_STACK Stack,
-    OUT PRPN_OP Op)
-{
-    ASSERT(Stack);
-    ASSERT(Op);
-
-    if (Stack->Sp == 0)
-        return FALSE;
-
-    memcpy(Op, Stack->Ops + Stack->Sp - 1, sizeof (RPN_OP));
-
-    return TRUE;
-}
-
-/*!\brief Parses an expression.
- *
- * This functions parses the given expression until the end of string or a closing
- * brace is found. As the function parses the string it pushes RPN_OPs onto the
- * stack.
- *
- * Examples: 1+2*3 ; eax+10 ; (eax+16) * (ebx+4) ; dword[eax]
- *
- * \param Stack            Pointer to a RPN_STACK structure.
- * \param Expression       String to parse.
- * \param CharacterOffset  Character offset of the subexpression from the beginning of the expression.
- * \param End              On success End is set to the character at which parsing stopped.
- * \param ErrOffset        On failure this is set to the character offset at which the error occoured.
- * \param ErrMsg           On failure a message describing the problem is copied into this buffer (128 bytes)
- *
- * \retval TRUE   Success.
- * \retval FALSE  Failure.
- */
-static BOOLEAN
-RpnpParseExpression(
-    IN  PRPN_STACK Stack,
-    IN  PCHAR Expression,
-    OUT PCHAR *End  OPTIONAL,
-    IN  ULONG CharacterOffset,
-    OUT PLONG ErrOffset  OPTIONAL,
-    OUT PCHAR ErrMsg  OPTIONAL)
-{
-    PCHAR p = Expression;
-    PCHAR pend;
-    PCHAR Operator = NULL;
-    LONG OperatorOffset = -1;
-    RPN_OP RpnOp;
-    RPN_OP PoppedOperator;
-    BOOLEAN HavePoppedOperator = FALSE;
-    RPN_OP ComparativeOp;
-    BOOLEAN ComparativeOpFilled = FALSE;
-    BOOLEAN IsComparativeOp;
-    INT i, i2;
-    ULONG ul;
-    UCHAR MemorySize;
-    CHAR Buffer[16];
-    BOOLEAN First;
-
-    ASSERT(Stack);
-    ASSERT(Expression);
-
-    First = TRUE;
-    for (;;)
-    {
-        /* Skip whitespace */
-        while (isspace(*p))
-        {
-            p++;
-            CharacterOffset++;
-        }
-
-        /* Check for end of expression */
-        if (p[0] == '\0' || p[0] == ')' || p[0] == ']')
-            break;
-
-        if (!First)
-        {
-            /* Remember operator */
-            Operator = p++;
-            OperatorOffset = CharacterOffset++;
-
-            /* Pop operator (to get the right operator precedence) */
-            HavePoppedOperator = FALSE;
-            if (*Operator == '*' || *Operator == '/' || *Operator == '%')
-            {
-                if (RpnpTopStack(Stack, &PoppedOperator) &&
-                    PoppedOperator.Type == RpnOpBinaryOperator &&
-                    (PoppedOperator.Data.BinaryOperator == RpnBinaryOperatorAdd ||
-                    PoppedOperator.Data.BinaryOperator == RpnBinaryOperatorSub))
-                {
-                    RpnpPopStack(Stack, NULL);
-                    HavePoppedOperator = TRUE;
-                }
-                else if (PoppedOperator.Type == RpnOpNop)
-                {
-                    RpnpPopStack(Stack, NULL);
-                    /* Discard the NOP - it was only pushed to indicate there was a
-                     * closing brace, so the previous operator shouldn't be popped.
-                     */
-                }
-            }
-            else if ((Operator[0] == '=' && Operator[1] == '=') ||
-                     (Operator[0] == '!' && Operator[1] == '=') ||
-                     Operator[0] == '<' || Operator[0] == '>')
-            {
-                if (Operator[0] == '=' || Operator[0] == '!' ||
-                    (Operator[0] == '<' && Operator[1] == '=') ||
-                    (Operator[0] == '>' && Operator[1] == '='))
-                {
-                    p++;
-                    CharacterOffset++;
-                }
-#if 0
-                /* Parse rest of expression */
-                if (!RpnpParseExpression(Stack, p + 1, &pend, CharacterOffset + 1,
-                                         ErrOffset, ErrMsg))
-                {
-                    return FALSE;
-                }
-                else if (pend == p + 1)
-                {
-                    CONST_STRCPY(ErrMsg, "Expression expected");
-
-                    if (ErrOffset)
-                        *ErrOffset = CharacterOffset + 1;
-
-                    return FALSE;
-                }
-
-                goto end_of_expression; /* return */
-#endif
-            }
-            else if (Operator[0] != '+' && Operator[0] != '-')
-            {
-                CONST_STRCPY(ErrMsg, "Operator expected");
-
-                if (ErrOffset)
-                    *ErrOffset = OperatorOffset;
-
-                return FALSE;
-            }
-
-            /* Skip whitespace */
-            while (isspace(*p))
-            {
-                p++;
-                CharacterOffset++;
-            }
-        }
-
-        /* Get operand */
-        MemorySize = sizeof(ULONG_PTR); /* default to pointer size */
-
-get_operand:
-        i = strcspn(p, "+-*/%()[]<>!=");
-        if (i > 0)
-        {
-            i2 = i;
-
-            /* Copy register name/memory size */
-            while (isspace(p[--i2]));
-
-            i2 = min(i2 + 1, (INT)sizeof (Buffer) - 1);
-            strncpy(Buffer, p, i2);
-            Buffer[i2] = '\0';
-
-            /* Memory size prefix */
-            if (p[i] == '[')
-            {
-                if (stricmp(Buffer, "byte") == 0)
-                    MemorySize = 1;
-                else if (stricmp(Buffer, "word") == 0)
-                    MemorySize = 2;
-                else if (stricmp(Buffer, "dword") == 0)
-                    MemorySize = 4;
-                else if (stricmp(Buffer, "qword") == 0)
-                    MemorySize = 8;
-                else
-                {
-                    CONST_STRCPY(ErrMsg, "Invalid memory size prefix");
-
-                    if (ErrOffset)
-                        *ErrOffset = CharacterOffset;
-
-                    return FALSE;
-                }
-
-                p += i;
-                CharacterOffset += i;
-                goto get_operand;
-            }
-
-            /* Try to find register */
-            for (i = 0; i < RegisterToTrapFrameCount; i++)
-            {
-                if (stricmp(RegisterToTrapFrame[i].Name, Buffer) == 0)
-                    break;
-            }
-
-            if (i < RegisterToTrapFrameCount)
-            {
-                RpnOp.Type = RpnOpRegister;
-                RpnOp.CharacterOffset = CharacterOffset;
-                RpnOp.Data.Register = i;
-                i = strlen(RegisterToTrapFrame[i].Name);
-                CharacterOffset += i;
-                p += i;
-            }
-            else
-            {
-                /* Immediate value */
-                /* FIXME: Need string to ULONGLONG function */
-                ul = strtoul(p, &pend, 0);
-                if (p != pend)
-                {
-                    RpnOp.Type = RpnOpImmediate;
-                    RpnOp.CharacterOffset = CharacterOffset;
-                    RpnOp.Data.Immediate = (ULONGLONG)ul;
-                    CharacterOffset += pend - p;
-                    p = pend;
-                }
-                else
-                {
-                    CONST_STRCPY(ErrMsg, "Operand expected");
-
-                    if (ErrOffset)
-                        *ErrOffset = CharacterOffset;
-
-                    return FALSE;
-                }
-            }
-
-            /* Push operand */
-            if (!RpnpPushStack(Stack, &RpnOp))
-            {
-                CONST_STRCPY(ErrMsg, "RPN op stack overflow");
-
-                if (ErrOffset)
-                    *ErrOffset = -1;
-
-                return FALSE;
-            }
-        }
-        else if (i == 0)
-        {
-            if (p[0] == '(' || p[0] == '[') /* subexpression */
-            {
-                if (!RpnpParseExpression(Stack, p + 1, &pend, CharacterOffset + 1,
-                                         ErrOffset, ErrMsg))
-                {
-                    return FALSE;
-                }
-                else if (pend == p + 1)
-                {
-                    CONST_STRCPY(ErrMsg, "Expression expected");
-
-                    if (ErrOffset)
-                        *ErrOffset = CharacterOffset + 1;
-
-                    return FALSE;
-                }
-
-                if (p[0] == '[') /* dereference */
-                {
-                    ASSERT(MemorySize == 1 || MemorySize == 2 ||
-                           MemorySize == 4 || MemorySize == 8);
-
-                    if (pend[0] != ']')
-                    {
-                        CONST_STRCPY(ErrMsg, "']' expected");
-
-                        if (ErrOffset)
-                            *ErrOffset = CharacterOffset + (pend - p);
-
-                        return FALSE;
-                    }
-
-                    RpnOp.Type = RpnOpDereference;
-                    RpnOp.CharacterOffset = CharacterOffset;
-                    RpnOp.Data.DerefMemorySize = MemorySize;
-
-                    if (!RpnpPushStack(Stack, &RpnOp))
-                    {
-                        CONST_STRCPY(ErrMsg, "RPN op stack overflow");
-
-                        if (ErrOffset)
-                            *ErrOffset = -1;
-
-                        return FALSE;
-                    }
-                }
-                else /* p[0] == '(' */
-                {
-                    if (pend[0] != ')')
-                    {
-                        CONST_STRCPY(ErrMsg, "')' expected");
-
-                        if (ErrOffset)
-                            *ErrOffset = CharacterOffset + (pend - p);
-
-                        return FALSE;
-                    }
-                }
-
-                /* Push a "nop" to prevent popping of the + operator (which would
-                 * result in (10+10)/2 beeing evaluated as 15)
-                 */
-                RpnOp.Type = RpnOpNop;
-                if (!RpnpPushStack(Stack, &RpnOp))
-                {
-                    CONST_STRCPY(ErrMsg, "RPN op stack overflow");
-
-                    if (ErrOffset)
-                        *ErrOffset = -1;
-
-                    return FALSE;
-                }
-
-                /* Skip closing brace/bracket */
-                pend++;
-
-                CharacterOffset += pend - p;
-                p = pend;
-            }
-            else if (First && p[0] == '-') /* Allow expressions like "- eax" */
-            {
-                RpnOp.Type = RpnOpImmediate;
-                RpnOp.CharacterOffset = CharacterOffset;
-                RpnOp.Data.Immediate = 0;
-
-                if (!RpnpPushStack(Stack, &RpnOp))
-                {
-                    CONST_STRCPY(ErrMsg, "RPN op stack overflow");
-
-                    if (ErrOffset)
-                        *ErrOffset = -1;
-
-                    return FALSE;
-                }
-            }
-            else
-            {
-                CONST_STRCPY(ErrMsg, "Operand expected");
-
-                if (ErrOffset)
-                    *ErrOffset = CharacterOffset;
-
-                return FALSE;
-            }
-        }
-        else
-        {
-            CONST_STRCPY(ErrMsg, "strcspn() failed");
-
-            if (ErrOffset)
-                *ErrOffset = -1;
-
-            return FALSE;
-        }
-
-        if (!First)
-        {
-            /* Push operator */
-            RpnOp.CharacterOffset = OperatorOffset;
-            RpnOp.Type = RpnOpBinaryOperator;
-            IsComparativeOp = FALSE;
-
-            switch (*Operator)
-            {
-                case '+':
-                    RpnOp.Data.BinaryOperator = RpnBinaryOperatorAdd;
-                    break;
-
-                case '-':
-                    RpnOp.Data.BinaryOperator = RpnBinaryOperatorSub;
-                    break;
-
-                case '*':
-                    RpnOp.Data.BinaryOperator = RpnBinaryOperatorMul;
-                    break;
-
-                case '/':
-                    RpnOp.Data.BinaryOperator = RpnBinaryOperatorDiv;
-                    break;
-
-                case '%':
-                    RpnOp.Data.BinaryOperator = RpnBinaryOperatorMod;
-                    break;
-
-                case '=':
-                    ASSERT(Operator[1] == '=');
-                    IsComparativeOp = TRUE;
-                    RpnOp.Data.BinaryOperator = RpnBinaryOperatorEquals;
-                    break;
-
-                case '!':
-                    ASSERT(Operator[1] == '=');
-                    IsComparativeOp = TRUE;
-                    RpnOp.Data.BinaryOperator = RpnBinaryOperatorNotEquals;
-                    break;
-
-                case '<':
-                    IsComparativeOp = TRUE;
-
-                    if (Operator[1] == '=')
-                        RpnOp.Data.BinaryOperator = RpnBinaryOperatorLessThanOrEquals;
-                    else
-                        RpnOp.Data.BinaryOperator = RpnBinaryOperatorLessThan;
-
-                    break;
-
-                case '>':
-                    IsComparativeOp = TRUE;
-
-                    if (Operator[1] == '=')
-                        RpnOp.Data.BinaryOperator = RpnBinaryOperatorGreaterThanOrEquals;
-                    else
-                        RpnOp.Data.BinaryOperator = RpnBinaryOperatorGreaterThan;
-
-                    break;
-
-                default:
-                    ASSERT(0);
-                    break;
-            }
-
-            if (IsComparativeOp)
-            {
-                if (ComparativeOpFilled && !RpnpPushStack(Stack, &ComparativeOp))
-                {
-                    CONST_STRCPY(ErrMsg, "RPN op stack overflow");
-
-                    if (ErrOffset)
-                        *ErrOffset = -1;
-
-                    return FALSE;
-                }
-
-                memcpy(&ComparativeOp, &RpnOp, sizeof(RPN_OP));
-                ComparativeOpFilled = TRUE;
-            }
-            else if (!RpnpPushStack(Stack, &RpnOp))
-            {
-                CONST_STRCPY(ErrMsg, "RPN op stack overflow");
-
-                if (ErrOffset)
-                    *ErrOffset = -1;
-
-                return FALSE;
-            }
-
-            /* Push popped operator */
-            if (HavePoppedOperator)
-            {
-                if (!RpnpPushStack(Stack, &PoppedOperator))
-                {
-                    CONST_STRCPY(ErrMsg, "RPN op stack overflow");
-
-                    if (ErrOffset)
-                        *ErrOffset = -1;
-
-                    return FALSE;
-                }
-            }
-        }
-
-        First = FALSE;
-    }
-
-//end_of_expression:
-
-    if (ComparativeOpFilled && !RpnpPushStack(Stack, &ComparativeOp))
-    {
-        CONST_STRCPY(ErrMsg, "RPN op stack overflow");
-
-        if (ErrOffset)
-            *ErrOffset = -1;
-
-        return FALSE;
-    }
-
-    /* Skip whitespace */
-    while (isspace(*p))
-    {
-        p++;
-        CharacterOffset++;
-    }
-
-    if (End)
-        *End = p;
-
-    return TRUE;
-}
-
-/*!\brief Evaluates the RPN op stack and returns the result.
- *
- * \param Stack      Pointer to a RPN_STACK structure.
- * \param TrapFrame  Register values.
- * \param Result     Pointer to an ULONG to store the result into.
- * \param ErrOffset  On failure this is set to the character offset at which the error occoured.
- * \param ErrMsg     Buffer which receives an error message on failure (128 bytes)
- *
- * \retval TRUE   Success.
- * \retval FALSE  Failure.
- */
-static BOOLEAN
-RpnpEvaluateStack(
-    IN  PRPN_STACK Stack,
-    IN  PKDB_KTRAP_FRAME TrapFrame,
-    OUT PULONGLONG Result,
-    OUT PLONG ErrOffset  OPTIONAL,
-    OUT PCHAR ErrMsg  OPTIONAL)
-{
-    ULONGLONG ValueStack[RPN_VALUE_STACK_SIZE];
-    ULONG ValueStackPointer = 0;
-    ULONG index;
-    ULONGLONG ull;
-    ULONG ul;
-    USHORT us;
-    UCHAR uc;
-    PVOID p;
-    BOOLEAN Ok;
-#ifdef DEBUG_RPN
-    ULONG ValueStackPointerMax = 0;
-#endif
-
-    ASSERT(Stack);
-    ASSERT(TrapFrame);
-    ASSERT(Result);
-
-    for (index = 0; index < Stack->Sp; index++)
-    {
-        PRPN_OP Op = Stack->Ops + index;
-
-#ifdef DEBUG_RPN
-        ValueStackPointerMax = max(ValueStackPointerMax, ValueStackPointer);
-#endif
-
-        switch (Op->Type)
-        {
-            case RpnOpNop:
-                /* No operation */
-                break;
-
-            case RpnOpImmediate:
-                if (ValueStackPointer == RPN_VALUE_STACK_SIZE)
-                {
-                    CONST_STRCPY(ErrMsg, "Value stack overflow");
-
-                    if (ErrOffset)
-                        *ErrOffset = -1;
-
-                    return FALSE;
-                }
-
-                ValueStack[ValueStackPointer++] = Op->Data.Immediate;
-                break;
-
-            case RpnOpRegister:
-                if (ValueStackPointer == RPN_VALUE_STACK_SIZE)
-                {
-                    CONST_STRCPY(ErrMsg, "Value stack overflow");
-
-                    if (ErrOffset)
-                        *ErrOffset = -1;
-
-                    return FALSE;
-                }
-
-                ul = Op->Data.Register;
-                p = (PVOID)((ULONG_PTR)TrapFrame + RegisterToTrapFrame[ul].Offset);
-
-                switch (RegisterToTrapFrame[ul].Size)
-                {
-                    case 1: ull = (ULONGLONG)(*(PUCHAR)p); break;
-                    case 2: ull = (ULONGLONG)(*(PUSHORT)p); break;
-                    case 4: ull = (ULONGLONG)(*(PULONG)p); break;
-                    case 8: ull = (ULONGLONG)(*(PULONGLONG)p); break;
-                    default: ASSERT(0); return FALSE; break;
-                }
-
-                ValueStack[ValueStackPointer++] = ull;
-                break;
-
-            case RpnOpDereference:
-                if (ValueStackPointer < 1)
-                {
-                    CONST_STRCPY(ErrMsg, "Value stack underflow");
-
-                    if (ErrOffset)
-                        *ErrOffset = -1;
-
-                    return FALSE;
-                }
-
-                /* FIXME: Print a warning when address is out of range */
-                p = (PVOID)(ULONG_PTR)ValueStack[ValueStackPointer - 1];
-                Ok = FALSE;
-
-                switch (Op->Data.DerefMemorySize)
-                {
-                    case 1:
-                        if (NT_SUCCESS(KdbpSafeReadMemory(&uc, p, sizeof (uc))))
-                        {
-                            Ok = TRUE;
-                            ull = (ULONGLONG)uc;
-                        }
-                        break;
-
-                    case 2:
-                        if (NT_SUCCESS(KdbpSafeReadMemory(&us, p, sizeof (us))))
-                        {
-                            Ok = TRUE;
-                            ull = (ULONGLONG)us;
-                        }
-                        break;
-
-                    case 4:
-                        if (NT_SUCCESS(KdbpSafeReadMemory(&ul, p, sizeof (ul))))
-                        {
-                            Ok = TRUE;
-                            ull = (ULONGLONG)ul;
-                        }
-                        break;
-
-                    case 8:
-                        if (NT_SUCCESS(KdbpSafeReadMemory(&ull, p, sizeof (ull))))
-                        {
-                            Ok = TRUE;
-                        }
-                        break;
-
-                    default:
-                        ASSERT(0);
-                        return FALSE;
-                        break;
-                }
-
-                if (!Ok)
-                {
-                    _snprintf(ErrMsg, 128, "Couldn't access memory at 0x%lx", (ULONG)p);
-
-                    if (ErrOffset)
-                        *ErrOffset = Op->CharacterOffset;
-
-                    return FALSE;
-                }
-
-                ValueStack[ValueStackPointer - 1] = ull;
-                break;
-
-            case RpnOpBinaryOperator:
-                if (ValueStackPointer < 2)
-                {
-                    CONST_STRCPY(ErrMsg, "Value stack underflow");
-
-                    if (ErrOffset)
-                        *ErrOffset = -1;
-
-                    return FALSE;
-                }
-
-                ValueStackPointer--;
-                ull = ValueStack[ValueStackPointer];
-
-                if (ull == 0 && Op->Data.BinaryOperator == RpnBinaryOperatorDiv)
-                {
-                    CONST_STRCPY(ErrMsg, "Division by zero");
-
-                    if (ErrOffset)
-                        *ErrOffset = Op->CharacterOffset;
-
-                    return FALSE;
-                }
-
-                ull = Op->Data.BinaryOperator(ValueStack[ValueStackPointer - 1], ull);
-                ValueStack[ValueStackPointer - 1] = ull;
-                break;
-
-            default:
-                ASSERT(0);
-                return FALSE;
-        }
-    }
-
-#ifdef DEBUG_RPN
-    DPRINT1("Max value stack pointer: %d\n", ValueStackPointerMax);
-#endif
-
-    if (ValueStackPointer != 1)
-    {
-        CONST_STRCPY(ErrMsg, "Stack not empty after evaluation");
-
-        if (ErrOffset)
-            *ErrOffset = -1;
-
-        return FALSE;
-    }
-
-    *Result = ValueStack[0];
-    return TRUE;
-}
-
-/*!\brief Evaluates the given expression
- *
- * \param Expression  Expression to evaluate.
- * \param TrapFrame   Register values.
- * \param Result      Variable which receives the result on success.
- * \param ErrOffset   Variable which receives character offset on parse error (-1 on other errors)
- * \param ErrMsg      Buffer which receives an error message on failure (128 bytes)
- *
- * \retval TRUE   Success.
- * \retval FALSE  Failure.
- */
-BOOLEAN
-KdbpRpnEvaluateExpression(
-    IN  PCHAR Expression,
-    IN  PKDB_KTRAP_FRAME TrapFrame,
-    OUT PULONGLONG Result,
-    OUT PLONG ErrOffset  OPTIONAL,
-    OUT PCHAR ErrMsg  OPTIONAL)
-{
-    PRPN_STACK Stack = (PRPN_STACK)&RpnStack;
-
-    ASSERT(Expression);
-    ASSERT(TrapFrame);
-    ASSERT(Result);
-
-    /* Clear the stack and parse the expression */
-    RpnpClearStack(Stack);
-    if (!RpnpParseExpression(Stack, Expression, NULL, 0, ErrOffset, ErrMsg))
-        return FALSE;
-
-#ifdef DEBUG_RPN
-    RpnpDumpStack(Stack);
-#endif
-
-    /* Evaluate the stack */
-    if (!RpnpEvaluateStack(Stack, TrapFrame, Result, ErrOffset, ErrMsg))
-        return FALSE;
-
-    return TRUE;
-}
-
-/*!\brief Parses the given expression and returns a "handle" to it.
- *
- * \param Expression  Expression to evaluate.
- * \param ErrOffset   Variable which receives character offset on parse error (-1 on other errors)
- * \param ErrMsg      Buffer which receives an error message on failure (128 bytes)
- *
- * \returns "Handle" for the expression, NULL on failure.
- *
- * \sa KdbpRpnEvaluateExpression
- */
-PVOID
-KdbpRpnParseExpression(
-    IN  PCHAR Expression,
-    OUT PLONG ErrOffset  OPTIONAL,
-    OUT PCHAR ErrMsg  OPTIONAL)
-{
-    LONG Size;
-    PRPN_STACK Stack = (PRPN_STACK)&RpnStack;
-    PRPN_STACK NewStack;
-
-    ASSERT(Expression);
-
-    /* Clear the stack and parse the expression */
-    RpnpClearStack(Stack);
-    if (!RpnpParseExpression(Stack, Expression, NULL, 0, ErrOffset, ErrMsg))
-        return FALSE;
-
-#ifdef DEBUG_RPN
-    RpnpDumpStack(Stack);
-#endif
-
-    /* Duplicate the stack and return a pointer/handle to it */
-    ASSERT(Stack->Sp >= 1);
-    Size = sizeof (RPN_STACK) + (RTL_FIELD_SIZE(RPN_STACK, Ops[0]) * (Stack->Sp - 1));
-    NewStack = ExAllocatePoolWithTag(NonPagedPool, Size, TAG_KDBG);
-
-    if (!NewStack)
-    {
-        CONST_STRCPY(ErrMsg, "Out of memory");
-
-        if (ErrOffset)
-            *ErrOffset = -1;
-
-        return NULL;
-    }
-
-    memcpy(NewStack, Stack, Size);
-    NewStack->Size = NewStack->Sp;
-
-    return NewStack;
-}
-
-/*!\brief Evaluates the given expression and returns the result.
- *
- * \param Expression  Expression "handle" returned by KdbpRpnParseExpression.
- * \param TrapFrame   Register values.
- * \param Result      Variable which receives the result on success.
- * \param ErrOffset   Variable which receives character offset on parse error (-1 on other errors)
- * \param ErrMsg      Buffer which receives an error message on failure (128 bytes)
- *
- * \returns "Handle" for the expression, NULL on failure.
- *
- * \sa KdbpRpnParseExpression
- */
-BOOLEAN
-KdbpRpnEvaluateParsedExpression(
-    IN  PVOID Expression,
-    IN  PKDB_KTRAP_FRAME TrapFrame,
-    OUT PULONGLONG Result,
-    OUT PLONG ErrOffset  OPTIONAL,
-    OUT PCHAR ErrMsg  OPTIONAL)
-{
-    PRPN_STACK Stack = (PRPN_STACK)Expression;
-
-    ASSERT(Expression);
-    ASSERT(TrapFrame);
-    ASSERT(Result);
-
-    /* Evaluate the stack */
-    return RpnpEvaluateStack(Stack, TrapFrame, Result, ErrOffset, ErrMsg);
-}
-