- Timestamp:
- Jun 3, 2012 10:46:46 PM (13 years ago)
- Location:
- trunk
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/VBox/dbg.h
r39154 r41558 388 388 * @param pCmdHlp Pointer to the command callback structure. 389 389 * @param pcb Where to store the number of bytes written. 390 * @param pszFormat The format string. 391 * This is using the log formatter, so it's format extensions can be used.390 * @param pszFormat The format string. This may use all IPRT extensions as 391 * well as the debugger ones. 392 392 * @param ... Arguments specified in the format string. 393 393 */ … … 400 400 * @param pCmdHlp Pointer to the command callback structure. 401 401 * @param pcb Where to store the number of bytes written. 402 * @param pszFormat The format string. 403 * This is using the log formatter, so it's format extensions can be used.402 * @param pszFormat The format string. This may use all IPRT extensions as 403 * well as the debugger ones. 404 404 * @param args Arguments specified in the format string. 405 405 */ 406 406 DECLCALLBACKMEMBER(int, pfnPrintfV)(PDBGCCMDHLP pCmdHlp, size_t *pcbWritten, const char *pszFormat, va_list args); 407 408 /** 409 * Command helper for formatting a string with debugger format specifiers. 410 * 411 * @returns The number of bytes written. 412 * @param pCmdHlp Pointer to the command callback structure. 413 * @param pszBuf The output buffer. 414 * @param cbBuf The size of the output buffer. 415 * @param pszFormat The format string. This may use all IPRT extensions as 416 * well as the debugger ones. 417 * @param ... Arguments specified in the format string. 418 */ 419 DECLCALLBACKMEMBER(size_t, pfnStrPrintf)(PDBGCCMDHLP pCmdHlp, char *pszBuf, size_t cbBuf, const char *pszFormat, ...); 420 421 /** 422 * Command helper for formatting a string with debugger format specifiers. 423 * 424 * @returns The number of bytes written. 425 * @param pCmdHlp Pointer to the command callback structure. 426 * @param pszBuf The output buffer. 427 * @param cbBuf The size of the output buffer. 428 * @param pszFormat The format string. This may use all IPRT extensions as 429 * well as the debugger ones. 430 * @param va Arguments specified in the format string. 431 */ 432 DECLCALLBACKMEMBER(size_t, pfnStrPrintfV)(PDBGCCMDHLP pCmdHlp, char *pszBuf, size_t cbBuf, 433 const char *pszFormat, va_list va); 407 434 408 435 /** … … 613 640 614 641 /** 615 * Command helper for writing formatted text to the debug console. 616 * 617 * @returns VBox status. 618 * @param pCmdHlp Pointer to the command callback structure. 619 * @param pszFormat The format string. 620 * This is using the log formatter, so it's format extensions can be used. 621 * @param ... Arguments specified in the format string. 642 * @copydoc DBGCCMDHLP::pfnPrintf 622 643 */ 623 644 DECLINLINE(int) DBGCCmdHlpPrintf(PDBGCCMDHLP pCmdHlp, const char *pszFormat, ...) … … 631 652 632 653 return rc; 654 } 655 656 657 /** 658 * @copydoc DBGCCMDHLP::pfnStrPrintf 659 */ 660 DECLINLINE(size_t) DBGCCmdHlpStrPrintf(PDBGCCMDHLP pCmdHlp, char *pszBuf, size_t cbBuf, const char *pszFormat, ...) 661 { 662 va_list va; 663 size_t cch; 664 665 va_start(va, pszFormat); 666 cch = pCmdHlp->pfnStrPrintfV(pCmdHlp, pszBuf, cbBuf, pszFormat, va); 667 va_end(va); 668 669 return cch; 633 670 } 634 671 -
trunk/include/VBox/err.h
r41553 r41558 2122 2122 /** Syntax error - too many arguments for static storage. */ 2123 2123 #define VERR_DBGC_PARSE_ARGUMENT_OVERFLOW (VERR_DBGC_PARSE_LOWEST + 2) 2124 /** Syntax error - argument didn't match description. */ 2125 #define VERR_DBGC_PARSE_NO_ARGUMENT_MATCH (VERR_DBGC_PARSE_LOWEST + 3) 2124 2126 2125 /** Syntax error - the argument does not allow a range to be specified. */ 2127 2126 #define VERR_DBGC_PARSE_NO_RANGE_ALLOWED (VERR_DBGC_PARSE_LOWEST + 5) … … 2144 2143 /** Syntax error - the specified function is not a function. */ 2145 2144 #define VERR_DBGC_PARSE_NOT_A_FUNCTION (VERR_DBGC_PARSE_LOWEST + 14) 2145 /** Syntax error - out of scratch memory. */ 2146 #define VERR_DBGC_PARSE_NO_SCRATCH (VERR_DBGC_PARSE_LOWEST + 15) 2146 2147 /** Syntax error - out of regular heap memory. */ 2147 #define VERR_DBGC_PARSE_NO_MEMORY (VERR_DBGC_PARSE_LOWEST + 1 5)2148 #define VERR_DBGC_PARSE_NO_MEMORY (VERR_DBGC_PARSE_LOWEST + 16) 2148 2149 /** Syntax error - incorrect argument type. */ 2149 #define VERR_DBGC_PARSE_INCORRECT_ARG_TYPE (VERR_DBGC_PARSE_LOWEST + 1 6)2150 #define VERR_DBGC_PARSE_INCORRECT_ARG_TYPE (VERR_DBGC_PARSE_LOWEST + 17) 2150 2151 /** Syntax error - an undefined variable was referenced. */ 2151 #define VERR_DBGC_PARSE_VARIABLE_NOT_FOUND (VERR_DBGC_PARSE_LOWEST + 1 7)2152 #define VERR_DBGC_PARSE_VARIABLE_NOT_FOUND (VERR_DBGC_PARSE_LOWEST + 18) 2152 2153 /** Syntax error - a type conversion failed. */ 2153 #define VERR_DBGC_PARSE_CONVERSION_FAILED (VERR_DBGC_PARSE_LOWEST + 1 8)2154 #define VERR_DBGC_PARSE_CONVERSION_FAILED (VERR_DBGC_PARSE_LOWEST + 19) 2154 2155 /** Syntax error - you hit a debugger feature which isn't implemented yet. 2155 2156 * (Feel free to help implement it.) */ 2156 #define VERR_DBGC_PARSE_NOT_IMPLEMENTED (VERR_DBGC_PARSE_LOWEST + 19)2157 #define VERR_DBGC_PARSE_NOT_IMPLEMENTED (VERR_DBGC_PARSE_LOWEST + 20) 2157 2158 /** Syntax error - Couldn't staisfy a request for a sepcific result type. */ 2158 #define VERR_DBGC_PARSE_BAD_RESULT_TYPE (VERR_DBGC_PARSE_LOWEST + 2 0)2159 #define VERR_DBGC_PARSE_BAD_RESULT_TYPE (VERR_DBGC_PARSE_LOWEST + 21) 2159 2160 /** Syntax error - Cannot read symbol value, it is a set-only symbol. */ 2160 #define VERR_DBGC_PARSE_WRITEONLY_SYMBOL (VERR_DBGC_PARSE_LOWEST + 2 1)2161 #define VERR_DBGC_PARSE_WRITEONLY_SYMBOL (VERR_DBGC_PARSE_LOWEST + 22) 2161 2162 /** Syntax error - Invalid command name. */ 2162 #define VERR_DBGC_PARSE_INVALD_COMMAND_NAME (VERR_DBGC_PARSE_LOWEST + 2 2)2163 #define VERR_DBGC_PARSE_INVALD_COMMAND_NAME (VERR_DBGC_PARSE_LOWEST + 23) 2163 2164 /** Syntax error - Command not found. */ 2164 #define VERR_DBGC_PARSE_COMMAND_NOT_FOUND (VERR_DBGC_PARSE_LOWEST + 23) 2165 2166 /** Syntax error - Obsolete. */ 2167 #define VERR_DBGC_PARSE_ARGUMENT_TYPE_MISMATCH (VERR_DBGC_PARSE_LOWEST + 4) 2165 #define VERR_DBGC_PARSE_COMMAND_NOT_FOUND (VERR_DBGC_PARSE_LOWEST + 24) 2168 2166 2169 2167 -
trunk/src/VBox/Debugger/DBGCCmdHlp.cpp
r41553 r41558 51 51 return rc; 52 52 } 53 53 54 54 55 /** … … 211 212 212 213 return pDbgc->rcOutput; 214 } 215 216 217 /** 218 * @interface_method_impl{DBGCCMDHLP,pfnStrPrintf} 219 */ 220 static DECLCALLBACK(size_t) dbgcHlpStrPrintfV(PDBGCCMDHLP pCmdHlp, char *pszBuf, size_t cbBuf, 221 const char *pszFormat, va_list va) 222 { 223 PDBGC pDbgc = DBGC_CMDHLP2DBGC(pCmdHlp); 224 return RTStrPrintfExV(dbgcStringFormatter, pDbgc, pszBuf, cbBuf, pszFormat, va); 225 } 226 227 228 /** 229 * @interface_method_impl{DBGCCMDHLP,pfnStrPrintf} 230 */ 231 static DECLCALLBACK(size_t) dbgcHlpStrPrintf(PDBGCCMDHLP pCmdHlp, char *pszBuf, size_t cbBuf, const char *pszFormat, ...) 232 { 233 PDBGC pDbgc = DBGC_CMDHLP2DBGC(pCmdHlp); 234 va_list va; 235 va_start(va, pszFormat); 236 size_t cch = RTStrPrintfExV(dbgcStringFormatter, pDbgc, pszBuf, cbBuf, pszFormat, va); 237 va_end(va); 238 return cch; 213 239 } 214 240 … … 1255 1281 pDbgc->CmdHlp.pfnPrintfV = dbgcHlpPrintfV; 1256 1282 pDbgc->CmdHlp.pfnPrintf = dbgcHlpPrintf; 1283 pDbgc->CmdHlp.pfnStrPrintf = dbgcHlpStrPrintf; 1284 pDbgc->CmdHlp.pfnStrPrintfV = dbgcHlpStrPrintfV; 1257 1285 pDbgc->CmdHlp.pfnVBoxErrorV = dbgcHlpVBoxErrorV; 1258 1286 pDbgc->CmdHlp.pfnVBoxError = dbgcHlpVBoxError; -
trunk/src/VBox/Debugger/DBGCEval.cpp
r41553 r41558 5 5 6 6 /* 7 * Copyright (C) 2006-201 1Oracle Corporation7 * Copyright (C) 2006-2012 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 31 31 32 32 #include "DBGCInternal.h" 33 34 /** Rewrite in progress. */ 35 #define BETTER_ARGUMENT_MATCHING 33 36 34 37 … … 64 67 65 68 69 66 70 static int dbgcEvalSubString(PDBGC pDbgc, char *pszExpr, size_t cchExpr, PDBGCVAR pArg) 67 71 { … … 72 76 */ 73 77 char ch = *pszExpr; 74 if (ch == '"' || ch == '\'' || ch == '`')78 if (ch == '"' || ch == '\'') 75 79 { 76 80 if (pszExpr[--cchExpr] != ch) … … 142 146 143 147 /** 144 * Match variable and variable descriptor, promoting the variable if necessary. 145 * 146 * @returns VBox status code. 147 * @param pDbgc Debug console instanace. 148 * @param pVar Variable. 149 * @param pVarDesc Variable descriptor. 148 * dbgcEvalSubUnary worker that handles simple numeric or pointer expressions. 149 * 150 * @returns VBox status code. pResult contains the result on success. 151 * @param pDbgc Debugger console instance data. 152 * @param pszExpr The expression string. 153 * @param cchExpr The length of the expression. 154 * @param enmCategory The desired type category (for range / no range). 155 * @param pResult Where to store the result of the expression evaluation. 150 156 */ 151 static int dbgcEvalSubMatchVar(PDBGC pDbgc, PDBGCVAR pVar, PCDBGCVARDESC pVarDesc) 157 static int dbgcEvalSubNumericOrPointer(PDBGC pDbgc, char *pszExpr, size_t cchExpr, DBGCVARCAT enmCategory, 158 PDBGCVAR pResult) 152 159 { 153 /* 154 * (If match or promoted to match, return, else break.) 155 */ 156 switch (pVarDesc->enmCategory) 157 { 158 /* 159 * Anything goes 160 */ 161 case DBGCVAR_CAT_ANY: 162 return VINF_SUCCESS; 163 164 /* 165 * Pointer with and without range. 166 * We can try resolve strings and symbols as symbols and promote 167 * numbers to flat GC pointers. 168 */ 169 case DBGCVAR_CAT_POINTER_NO_RANGE: 170 case DBGCVAR_CAT_POINTER_NUMBER_NO_RANGE: 171 if (pVar->enmRangeType != DBGCVAR_RANGE_NONE) 172 return VERR_DBGC_PARSE_NO_RANGE_ALLOWED; 173 /* fallthru */ 174 case DBGCVAR_CAT_POINTER: 175 case DBGCVAR_CAT_POINTER_NUMBER: 176 switch (pVar->enmType) 177 { 178 case DBGCVAR_TYPE_GC_FLAT: 179 case DBGCVAR_TYPE_GC_FAR: 180 case DBGCVAR_TYPE_GC_PHYS: 181 case DBGCVAR_TYPE_HC_FLAT: 182 case DBGCVAR_TYPE_HC_PHYS: 183 return VINF_SUCCESS; 184 185 case DBGCVAR_TYPE_SYMBOL: 186 case DBGCVAR_TYPE_STRING: 187 { 188 DBGCVAR Var; 189 int rc = dbgcSymbolGet(pDbgc, pVar->u.pszString, DBGCVAR_TYPE_GC_FLAT, &Var); 190 if (RT_SUCCESS(rc)) 191 { 192 /* deal with range */ 193 if (pVar->enmRangeType != DBGCVAR_RANGE_NONE) 194 { 195 Var.enmRangeType = pVar->enmRangeType; 196 Var.u64Range = pVar->u64Range; 197 } 198 else if (pVarDesc->enmCategory == DBGCVAR_CAT_POINTER_NO_RANGE) 199 Var.enmRangeType = DBGCVAR_RANGE_NONE; 200 *pVar = Var; 201 return rc; 202 } 203 break; 204 } 205 206 case DBGCVAR_TYPE_NUMBER: 207 if ( pVarDesc->enmCategory != DBGCVAR_CAT_POINTER_NUMBER 208 && pVarDesc->enmCategory != DBGCVAR_CAT_POINTER_NUMBER_NO_RANGE) 209 { 210 RTGCPTR GCPtr = (RTGCPTR)pVar->u.u64Number; 211 pVar->enmType = DBGCVAR_TYPE_GC_FLAT; 212 pVar->u.GCFlat = GCPtr; 213 } 214 return VINF_SUCCESS; 215 216 default: 217 break; 218 } 219 break; 220 221 /* 222 * GC pointer with and without range. 223 * We can try resolve strings and symbols as symbols and 224 * promote numbers to flat GC pointers. 225 */ 226 case DBGCVAR_CAT_GC_POINTER_NO_RANGE: 227 if (pVar->enmRangeType != DBGCVAR_RANGE_NONE) 228 return VERR_DBGC_PARSE_NO_RANGE_ALLOWED; 229 /* fallthru */ 230 case DBGCVAR_CAT_GC_POINTER: 231 switch (pVar->enmType) 232 { 233 case DBGCVAR_TYPE_GC_FLAT: 234 case DBGCVAR_TYPE_GC_FAR: 235 case DBGCVAR_TYPE_GC_PHYS: 236 return VINF_SUCCESS; 237 238 case DBGCVAR_TYPE_HC_FLAT: 239 case DBGCVAR_TYPE_HC_PHYS: 240 return VERR_DBGC_PARSE_CONVERSION_FAILED; 241 242 case DBGCVAR_TYPE_SYMBOL: 243 case DBGCVAR_TYPE_STRING: 244 { 245 DBGCVAR Var; 246 int rc = dbgcSymbolGet(pDbgc, pVar->u.pszString, DBGCVAR_TYPE_GC_FLAT, &Var); 247 if (RT_SUCCESS(rc)) 248 { 249 /* deal with range */ 250 if (pVar->enmRangeType != DBGCVAR_RANGE_NONE) 251 { 252 Var.enmRangeType = pVar->enmRangeType; 253 Var.u64Range = pVar->u64Range; 254 } 255 else if (pVarDesc->enmCategory == DBGCVAR_CAT_POINTER_NO_RANGE) 256 Var.enmRangeType = DBGCVAR_RANGE_NONE; 257 *pVar = Var; 258 return rc; 259 } 260 break; 261 } 262 263 case DBGCVAR_TYPE_NUMBER: 264 { 265 RTGCPTR GCPtr = (RTGCPTR)pVar->u.u64Number; 266 pVar->enmType = DBGCVAR_TYPE_GC_FLAT; 267 pVar->u.GCFlat = GCPtr; 268 return VINF_SUCCESS; 269 } 270 271 default: 272 break; 273 } 274 break; 275 276 /* 277 * Number with or without a range. 278 * Numbers can be resolved from symbols, but we cannot demote a pointer 279 * to a number. 280 */ 281 case DBGCVAR_CAT_NUMBER_NO_RANGE: 282 if (pVar->enmRangeType != DBGCVAR_RANGE_NONE) 283 return VERR_DBGC_PARSE_NO_RANGE_ALLOWED; 284 /* fallthru */ 285 case DBGCVAR_CAT_NUMBER: 286 switch (pVar->enmType) 287 { 288 case DBGCVAR_TYPE_NUMBER: 289 return VINF_SUCCESS; 290 291 case DBGCVAR_TYPE_SYMBOL: 292 case DBGCVAR_TYPE_STRING: 293 { 294 DBGCVAR Var; 295 int rc = dbgcSymbolGet(pDbgc, pVar->u.pszString, DBGCVAR_TYPE_NUMBER, &Var); 296 if (RT_SUCCESS(rc)) 297 { 298 *pVar = Var; 299 return rc; 300 } 301 break; 302 } 303 default: 304 break; 305 } 306 break; 307 308 /* 309 * Strings can easily be made from symbols (and of course strings). 310 * We could consider reformatting the addresses and numbers into strings later... 311 */ 312 case DBGCVAR_CAT_STRING: 313 switch (pVar->enmType) 314 { 315 case DBGCVAR_TYPE_SYMBOL: 316 pVar->enmType = DBGCVAR_TYPE_STRING; 317 /* fallthru */ 318 case DBGCVAR_TYPE_STRING: 319 return VINF_SUCCESS; 320 default: 321 break; 322 } 323 break; 324 325 /* 326 * Symol is pretty much the same thing as a string (at least until we actually implement it). 327 */ 328 case DBGCVAR_CAT_SYMBOL: 329 switch (pVar->enmType) 330 { 331 case DBGCVAR_TYPE_STRING: 332 pVar->enmType = DBGCVAR_TYPE_SYMBOL; 333 /* fallthru */ 334 case DBGCVAR_TYPE_SYMBOL: 335 return VINF_SUCCESS; 336 default: 337 break; 338 } 339 break; 340 341 /* 342 * Anything else is illegal. 343 */ 160 char const ch = pszExpr[0]; 161 char const ch2 = pszExpr[1]; 162 163 /* 0x<hex digits> */ 164 if (ch == '0' && (ch2 == 'x' || ch2 == 'X')) 165 return dbgcEvalSubNum(pszExpr + 2, 16, pResult); 166 167 /* <hex digits>h */ 168 if (RT_C_IS_XDIGIT(*pszExpr) && (pszExpr[cchExpr - 1] == 'h' || pszExpr[cchExpr - 1] == 'H')) 169 { 170 pszExpr[cchExpr] = '\0'; 171 return dbgcEvalSubNum(pszExpr, 16, pResult); 172 } 173 174 /* 0i<decimal digits> */ 175 if (ch == '0' && ch2 == 'i') 176 return dbgcEvalSubNum(pszExpr + 2, 10, pResult); 177 178 /* 0t<octal digits> */ 179 if (ch == '0' && ch2 == 't') 180 return dbgcEvalSubNum(pszExpr + 2, 8, pResult); 181 182 /* 0y<binary digits> */ 183 if (ch == '0' && ch2 == 'y') 184 return dbgcEvalSubNum(pszExpr + 2, 10, pResult); 185 186 /* Hex number? */ 187 unsigned off = 0; 188 while (RT_C_IS_XDIGIT(pszExpr[off]) || pszExpr[off] == '`') 189 off++; 190 if (off == cchExpr) 191 return dbgcEvalSubNum(pszExpr, 16, pResult); 192 193 /* 194 * Some kind of symbol? 195 */ 196 DBGCVARTYPE enmType; 197 bool fStripRange = false; 198 switch (enmCategory) 199 { 200 case DBGCVAR_CAT_POINTER_NUMBER: enmType = DBGCVAR_TYPE_NUMBER; break; 201 case DBGCVAR_CAT_POINTER_NUMBER_NO_RANGE: enmType = DBGCVAR_TYPE_NUMBER; fStripRange = true; break; 202 case DBGCVAR_CAT_POINTER: enmType = DBGCVAR_TYPE_NUMBER; break; 203 case DBGCVAR_CAT_POINTER_NO_RANGE: enmType = DBGCVAR_TYPE_NUMBER; fStripRange = true; break; 204 case DBGCVAR_CAT_GC_POINTER: enmType = DBGCVAR_TYPE_GC_FLAT; break; 205 case DBGCVAR_CAT_GC_POINTER_NO_RANGE: enmType = DBGCVAR_TYPE_GC_FLAT; fStripRange = true; break; 206 case DBGCVAR_CAT_NUMBER: enmType = DBGCVAR_TYPE_NUMBER; break; 207 case DBGCVAR_CAT_NUMBER_NO_RANGE: enmType = DBGCVAR_TYPE_NUMBER; fStripRange = true; break; 344 208 default: 345 AssertMsgFailed(("enmCategory=%d\n", pVar->enmType)); 346 break; 347 } 348 349 return VERR_DBGC_PARSE_NO_ARGUMENT_MATCH; 209 AssertFailedReturn(VERR_DBGC_PARSE_NOT_IMPLEMENTED); 210 } 211 212 if ( (*pszExpr == '"' || *pszExpr == '\'') 213 && pszExpr[cchExpr - 1] == *pszExpr) 214 { 215 pszExpr[cchExpr - 1] = '\0'; 216 pszExpr++; 217 } 218 219 int rc = dbgcSymbolGet(pDbgc, pszExpr, enmType, pResult); 220 if (RT_SUCCESS(rc)) 221 { 222 if (fStripRange) 223 { 224 pResult->enmRangeType = DBGCVAR_RANGE_NONE; 225 pResult->u64Range = 0; 226 } 227 } 228 else if (rc == VERR_DBGC_PARSE_NOT_IMPLEMENTED) 229 rc = VERR_DBGC_PARSE_INVALID_NUMBER; 230 return rc; 350 231 } 351 232 352 233 353 234 /** 354 * Matches a set of variables with a description set. 355 * 356 * This is typically used for routine arguments before a call. The effects in 357 * addition to the validation, is that some variables might be propagated to 358 * other types in order to match the description. The following transformations 359 * are supported: 360 * - String reinterpreted as a symbol and resolved to a number or pointer. 361 * - Number to a pointer. 362 * - Pointer to a number. 363 * 364 * @returns VBox status code. Modified @a paVars on success. 235 * dbgcEvalSubUnary worker that handles simple DBGCVAR_CAT_ANY expressions. 236 * 237 * @returns VBox status code. pResult contains the result on success. 238 * @param pDbgc Debugger console instance data. 239 * @param pszExpr The expression string. 240 * @param cchExpr The length of the expression. 241 * @param pResult Where to store the result of the expression evaluation. 365 242 */ 366 static int dbgcEvalSubMatchVars(PDBGC pDbgc, unsigned cVarsMin, unsigned cVarsMax, 367 PCDBGCVARDESC paVarDescs, unsigned cVarDescs, 368 PDBGCVAR paVars, unsigned cVars) 243 static int dbgcEvalSubUnaryAny(PDBGC pDbgc, char *pszExpr, size_t cchExpr, PDBGCVAR pResult) 369 244 { 370 /* 371 * Just do basic min / max checks first. 372 */ 373 if (cVars < cVarsMin) 374 return VERR_DBGC_PARSE_TOO_FEW_ARGUMENTS; 375 if (cVars > cVarsMax) 376 return VERR_DBGC_PARSE_TOO_MANY_ARGUMENTS; 377 378 /* 379 * Match the descriptors and actual variables. 380 */ 381 PCDBGCVARDESC pPrevDesc = NULL; 382 unsigned cCurDesc = 0; 383 unsigned iVar = 0; 384 unsigned iVarDesc = 0; 385 while (iVar < cVars) 386 { 387 /* walk the descriptors */ 388 if (iVarDesc >= cVarDescs) 389 return VERR_DBGC_PARSE_TOO_MANY_ARGUMENTS; 390 if ( ( paVarDescs[iVarDesc].fFlags & DBGCVD_FLAGS_DEP_PREV 391 && &paVarDescs[iVarDesc - 1] != pPrevDesc) 392 || cCurDesc >= paVarDescs[iVarDesc].cTimesMax) 393 { 394 iVarDesc++; 395 if (iVarDesc >= cVarDescs) 396 return VERR_DBGC_PARSE_TOO_MANY_ARGUMENTS; 397 cCurDesc = 0; 398 } 399 400 /* 401 * Skip thru optional arguments until we find something which matches 402 * or can easily be promoted to what the descriptor want. 403 */ 404 for (;;) 405 { 406 int rc = dbgcEvalSubMatchVar(pDbgc, &paVars[iVar], &paVarDescs[iVarDesc]); 407 if (RT_SUCCESS(rc)) 408 { 409 paVars[iVar].pDesc = &paVarDescs[iVarDesc]; 410 cCurDesc++; 411 break; 412 } 413 414 /* can we advance? */ 415 if (paVarDescs[iVarDesc].cTimesMin > cCurDesc) 416 return VERR_DBGC_PARSE_ARGUMENT_TYPE_MISMATCH; 417 if (++iVarDesc >= cVarDescs) 418 return VERR_DBGC_PARSE_ARGUMENT_TYPE_MISMATCH; 419 cCurDesc = 0; 420 } 421 422 /* next var */ 423 iVar++; 424 } 425 426 /* 427 * Check that the rest of the descriptors are optional. 428 */ 429 while (iVarDesc < cVarDescs) 430 { 431 if (paVarDescs[iVarDesc].cTimesMin > cCurDesc) 432 return VERR_DBGC_PARSE_TOO_FEW_ARGUMENTS; 433 cCurDesc = 0; 434 435 /* next */ 436 iVarDesc++; 437 } 438 439 return VINF_SUCCESS; 245 char const ch = pszExpr[0]; 246 char const ch2 = pszExpr[1]; 247 unsigned off = 2; 248 249 /* 0x<hex digits> */ 250 if (ch == '0' && (ch2 == 'x' || ch2 == 'X')) 251 { 252 while (RT_C_IS_XDIGIT(pszExpr[off]) || pszExpr[off] == '`') 253 off++; 254 if (off == cchExpr) 255 return dbgcEvalSubNum(pszExpr + 2, 16, pResult); 256 return dbgcEvalSubString(pDbgc, pszExpr, cchExpr, pResult); 257 } 258 259 /* <hex digits>h */ 260 if (RT_C_IS_XDIGIT(*pszExpr) && (pszExpr[cchExpr - 1] == 'h' || pszExpr[cchExpr - 1] == 'H')) 261 { 262 cchExpr--; 263 while (off < cchExpr && (RT_C_IS_XDIGIT(pszExpr[off]) || pszExpr[off] == '`')) 264 off++; 265 if (off == cchExpr) 266 { 267 pszExpr[cchExpr] = '\0'; 268 return dbgcEvalSubNum(pszExpr, 16, pResult); 269 } 270 return dbgcEvalSubString(pDbgc, pszExpr, cchExpr + 1, pResult); 271 } 272 273 /* 0i<decimal digits> */ 274 if (ch == '0' && ch2 == 'i') 275 { 276 while (RT_C_IS_DIGIT(pszExpr[off]) || pszExpr[off] == '`') 277 off++; 278 if (off == cchExpr) 279 return dbgcEvalSubNum(pszExpr + 2, 10, pResult); 280 return dbgcEvalSubString(pDbgc, pszExpr, cchExpr, pResult); 281 } 282 283 /* 0t<octal digits> */ 284 if (ch == '0' && ch2 == 't') 285 { 286 while (RT_C_IS_ODIGIT(pszExpr[off]) || pszExpr[off] == '`') 287 off++; 288 if (off == cchExpr) 289 return dbgcEvalSubNum(pszExpr + 2, 8, pResult); 290 return dbgcEvalSubString(pDbgc, pszExpr, cchExpr, pResult); 291 } 292 293 /* 0y<binary digits> */ 294 if (ch == '0' && ch2 == 'y') 295 { 296 while (pszExpr[off] == '0' || pszExpr[off] == '1' || pszExpr[off] == '`') 297 off++; 298 if (off == cchExpr) 299 return dbgcEvalSubNum(pszExpr + 2, 10, pResult); 300 return dbgcEvalSubString(pDbgc, pszExpr, cchExpr, pResult); 301 } 302 303 /* Ok, no prefix of suffix. Is it a hex number after all? If not it must 304 be a string. */ 305 off = 0; 306 while (RT_C_IS_XDIGIT(pszExpr[off]) || pszExpr[off] == '`') 307 off++; 308 if (off == cchExpr) 309 return dbgcEvalSubNum(pszExpr, 16, pResult); 310 return dbgcEvalSubString(pDbgc, pszExpr, cchExpr, pResult); 440 311 } 441 312 … … 481 352 pszExpr2++; 482 353 483 if (!*pszExpr2) 484 rc = VERR_DBGC_PARSE_EMPTY_ARGUMENT; 485 else 354 if (*pszExpr2) 486 355 { 487 356 DBGCVAR Arg; … … 493 362 rc = pOp->pfnHandlerUnary(pDbgc, &Arg, enmCategory, pResult); 494 363 } 495 }496 else497 {498 /*499 * Didn't find any operators, so it we have to check if this can be an 500 * function call before assuming numeric or string expression.501 *502 * (ASSUMPTIONS:)503 * A function name only contains alphanumerical chars and it can not start504 * with a numerical character.505 * Immediately following the name is a parenthesis which must over506 * the remaining part of the expression.507 */508 bool fExternal = *pszExpr == '.';509 char *pszFun = fExternal ? pszExpr + 1 : pszExpr;510 char *pszFunEnd = NULL;511 if (pszExpr[cchExpr - 1] == ')' && RT_C_IS_ALPHA(*pszFun))512 {513 pszFunEnd = pszExpr + 1;514 while (*pszFunEnd != '(' && RT_C_IS_ALNUM(*pszFunEnd))515 pszFunEnd++;516 if (*pszFunEnd != '(')517 pszFunEnd = NULL;518 }519 520 521 522 523 524 525 526 527 528 529 364 else 365 rc = VERR_DBGC_PARSE_EMPTY_ARGUMENT; 366 return rc; 367 } 368 369 /* 370 * Could this be a function call? 371 * 372 * ASSUMPTIONS: 373 * - A function name only contains alphanumerical chars and it can not 374 * start with a numerical character. 375 * - Immediately following the name is a parenthesis which must cover 376 * the remaining part of the expression. 377 */ 378 bool fExternal = *pszExpr == '.'; 379 char *pszFun = fExternal ? pszExpr + 1 : pszExpr; 380 char *pszFunEnd = NULL; 381 if (pszExpr[cchExpr - 1] == ')' && RT_C_IS_ALPHA(*pszFun)) 382 { 383 pszFunEnd = pszExpr + 1; 384 while (*pszFunEnd != '(' && RT_C_IS_ALNUM(*pszFunEnd)) 385 pszFunEnd++; 386 if (*pszFunEnd != '(') 387 pszFunEnd = NULL; 388 } 389 if (pszFunEnd) 390 { 391 /* 392 * Ok, it's a function call. 393 */ 394 if (fExternal) 395 pszExpr++, cchExpr--; 396 PCDBGCCMD pFun = dbgcRoutineLookup(pDbgc, pszExpr, pszFunEnd - pszExpr, fExternal); 397 if (!pFun) 398 return VERR_DBGC_PARSE_FUNCTION_NOT_FOUND; 530 399 #if 0 531 if (!pFun->pResultDesc) 532 return VERR_DBGC_PARSE_NOT_A_FUNCTION; 533 534 /* 535 * Parse the expression in parenthesis. 536 */ 537 cchExpr -= pszFunEnd - pszExpr; 538 pszExpr = pszFunEnd; 539 /** @todo implement multiple arguments. */ 540 DBGCVAR Arg; 541 rc = dbgcEvalSub(pDbgc, pszExpr, cchExpr, enmCategory, &Arg); 400 if (!pFun->pResultDesc) 401 return VERR_DBGC_PARSE_NOT_A_FUNCTION; 402 403 /* 404 * Parse the expression in parenthesis. 405 */ 406 cchExpr -= pszFunEnd - pszExpr; 407 pszExpr = pszFunEnd; 408 /** @todo implement multiple arguments. */ 409 DBGCVAR Arg; 410 rc = dbgcEvalSub(pDbgc, pszExpr, cchExpr, enmCategory, &Arg); 411 if (!rc) 412 { 413 rc = dbgcEvalSubMatchVars(pDbgc, pFun->cArgsMin, pFun->cArgsMax, pFun->paArgDescs, pFun->cArgDescs, &Arg, 1); 542 414 if (!rc) 543 { 544 rc = dbgcEvalSubMatchVars(pDbgc, pFun->cArgsMin, pFun->cArgsMax, pFun->paArgDescs, pFun->cArgDescs, &Arg, 1); 545 if (!rc) 546 rc = pFun->pfnHandler(pFun, &pDbgc->CmdHlp, pDbgc->pVM, &Arg, 1, pResult); 547 } 548 else if (rc == VERR_DBGC_PARSE_EMPTY_ARGUMENT && pFun->cArgsMin == 0) 549 rc = pFun->pfnHandler(pFun, &pDbgc->CmdHlp, pDbgc->pVM, NULL, 0, pResult); 415 rc = pFun->pfnHandler(pFun, &pDbgc->CmdHlp, pDbgc->pVM, &Arg, 1, pResult); 416 } 417 else if (rc == VERR_DBGC_PARSE_EMPTY_ARGUMENT && pFun->cArgsMin == 0) 418 rc = pFun->pfnHandler(pFun, &pDbgc->CmdHlp, pDbgc->pVM, NULL, 0, pResult); 550 419 #else 551 420 rc = VERR_NOT_IMPLEMENTED; 552 421 #endif 553 } 554 else if ( enmCategory == DBGCVAR_CAT_STRING 555 || enmCategory == DBGCVAR_CAT_SYMBOL) 556 rc = dbgcEvalSubString(pDbgc, pszExpr, cchExpr, pResult); 557 else 558 { 559 /* 560 * Didn't find any operators, so it must be a plain expression. 561 * This might be numeric or a string expression. 562 */ 563 char ch = pszExpr[0]; 564 char ch2 = pszExpr[1]; 565 if (ch == '0' && (ch2 == 'x' || ch2 == 'X')) 566 rc = dbgcEvalSubNum(pszExpr + 2, 16, pResult); 567 else if (ch == '0' && (ch2 == 'i' || ch2 == 'i')) 568 rc = dbgcEvalSubNum(pszExpr + 2, 10, pResult); 569 else if (ch == '0' && (ch2 == 't' || ch2 == 'T')) 570 rc = dbgcEvalSubNum(pszExpr + 2, 8, pResult); 571 /// @todo 0b doesn't work as a binary prefix, we confuse it with 0bf8:0123 and stuff. 572 //else if (ch == '0' && (ch2 == 'b' || ch2 == 'b')) 573 // rc = dbgcEvalSubNum(pszExpr + 2, 2, pResult); 574 else 575 { 576 /* 577 * Hexadecimal number or a string? 578 */ 579 char *psz = pszExpr; 580 while (RT_C_IS_XDIGIT(*psz)) 581 psz++; 582 if (!*psz) 583 rc = dbgcEvalSubNum(pszExpr, 16, pResult); 584 else if ((*psz == 'h' || *psz == 'H') && !psz[1]) 585 { 586 *psz = '\0'; 587 rc = dbgcEvalSubNum(pszExpr, 16, pResult); 588 } 589 else 590 rc = dbgcEvalSubString(pDbgc, pszExpr, cchExpr, pResult); 591 } 592 } 593 } 422 return rc; 423 } 424 425 /* 426 * Assuming plain expression. 427 * Didn't find any operators, so it must be a plain expression. 428 * Go by desired category first, then if anythings go, try guess. 429 */ 430 switch (enmCategory) 431 { 432 case DBGCVAR_CAT_ANY: 433 return dbgcEvalSubUnaryAny(pDbgc, pszExpr, cchExpr, pResult); 434 435 case DBGCVAR_CAT_POINTER_NUMBER: 436 case DBGCVAR_CAT_POINTER_NUMBER_NO_RANGE: 437 case DBGCVAR_CAT_POINTER: 438 case DBGCVAR_CAT_POINTER_NO_RANGE: 439 case DBGCVAR_CAT_GC_POINTER: 440 case DBGCVAR_CAT_GC_POINTER_NO_RANGE: 441 case DBGCVAR_CAT_NUMBER: 442 case DBGCVAR_CAT_NUMBER_NO_RANGE: 443 /* Pointers will be promoted later. */ 444 return dbgcEvalSubNumericOrPointer(pDbgc, pszExpr, cchExpr, enmCategory, pResult); 445 446 case DBGCVAR_CAT_STRING: 447 case DBGCVAR_CAT_SYMBOL: 448 /* Symbols will be promoted later. */ 449 return dbgcEvalSubString(pDbgc, pszExpr, cchExpr, pResult); 450 451 case DBGCVAR_CAT_OPTION: 452 case DBGCVAR_CAT_OPTION_STRING: 453 case DBGCVAR_CAT_OPTION_NUMBER: 454 return VERR_DBGC_PARSE_NOT_IMPLEMENTED; 455 } 456 457 AssertMsgFailed(("enmCategory=%d\n", enmCategory)); 458 rc = VERR_NOT_IMPLEMENTED; 594 459 595 460 return rc; … … 623 488 if (!*pszExpr) 624 489 return VERR_DBGC_PARSE_EMPTY_ARGUMENT; 625 626 /* it there is any kind of quoting in the expression, it's string meat. */627 if (strpbrk(pszExpr, "\"'`"))628 return dbgcEvalSubString(pDbgc, pszExpr, cchExpr, pResult);629 490 630 491 /* … … 671 532 } 672 533 673 /* tabs to spaces. */ 534 #if 0 /* why was this needed? It'll screw up strings. */ 535 /* tabs to spaces */ 674 536 char *psz = pszExpr; 675 537 while ((psz = strchr(psz, '\t')) != NULL) 676 538 *psz = ' '; 539 #endif 677 540 678 541 /* … … 682 545 * evaluate with respect to unary operators 683 546 */ 684 char *pszOpSplit = NULL; 685 PCDBGCOP pOpSplit = NULL; 686 unsigned cBinaryOps = 0; 687 unsigned cPar = 0; 547 char *pszOpSplit = NULL; 548 PCDBGCOP pOpSplit = NULL; 549 unsigned cBinaryOps = 0; 550 unsigned cPar = 0; 551 char chQuote = '\0'; 552 char chPrev = ' '; 553 bool fBinary = false; 554 char *psz = pszExpr; 688 555 char ch; 689 char chPrev = ' ';690 bool fBinary = false;691 psz = pszExpr;692 556 693 557 while ((ch = *psz) != '\0') … … 695 559 //Log2(("ch=%c cPar=%d fBinary=%d\n", ch, cPar, fBinary)); 696 560 /* 697 * Parenthesis. 698 */ 699 if (ch == '(') 561 * String quoting. 562 */ 563 if (chQuote) 564 { 565 if ( ch == chQuote 566 && psz[1] != chQuote) 567 { 568 chQuote = '\0'; 569 fBinary = true; 570 } 571 } 572 else if (ch == '"' || ch == '\'') 573 chQuote = ch; 574 /* 575 * Parentheses. 576 */ 577 else if (ch == '(') 700 578 { 701 579 cPar++; … … 754 632 } /* parse loop. */ 755 633 634 if (chQuote) 635 return VERR_DBGC_PARSE_UNBALANCED_QUOTE; 756 636 757 637 /* … … 791 671 } 792 672 else 793 /* plain expression or using unary operators perhaps with parentheses. */673 /* plain expression, qutoed string, or using unary operators perhaps with parentheses. */ 794 674 rc = dbgcEvalSubUnary(pDbgc, pszExpr, cchExpr, enmCategory, pResult); 795 675 796 676 return rc; 677 } 678 679 680 /** 681 * Worker for dbgcProcessArguments that performs type checking and promoptions. 682 * 683 * @returns VBox status code. 684 * 685 * @param pDbgc Debugger console instance data. 686 * @param enmCategory The target category for the result. 687 * @param pArg The argument to check and promote. 688 */ 689 static int dbgcCheckAndTypePromoteArgument(PDBGC pDbgc, DBGCVARCAT enmCategory, PDBGCVAR pArg) 690 { 691 switch (enmCategory) 692 { 693 /* 694 * Anything goes 695 */ 696 case DBGCVAR_CAT_ANY: 697 return VINF_SUCCESS; 698 699 /* 700 * Pointer with and without range. 701 * We can try resolve strings and symbols as symbols and promote 702 * numbers to flat GC pointers. 703 */ 704 case DBGCVAR_CAT_POINTER_NO_RANGE: 705 case DBGCVAR_CAT_POINTER_NUMBER_NO_RANGE: 706 if (pArg->enmRangeType != DBGCVAR_RANGE_NONE) 707 return VERR_DBGC_PARSE_NO_RANGE_ALLOWED; 708 /* fallthru */ 709 case DBGCVAR_CAT_POINTER: 710 case DBGCVAR_CAT_POINTER_NUMBER: 711 switch (pArg->enmType) 712 { 713 case DBGCVAR_TYPE_GC_FLAT: 714 case DBGCVAR_TYPE_GC_FAR: 715 case DBGCVAR_TYPE_GC_PHYS: 716 case DBGCVAR_TYPE_HC_FLAT: 717 case DBGCVAR_TYPE_HC_PHYS: 718 return VINF_SUCCESS; 719 720 case DBGCVAR_TYPE_SYMBOL: 721 case DBGCVAR_TYPE_STRING: 722 { 723 DBGCVAR Var; 724 int rc = dbgcSymbolGet(pDbgc, pArg->u.pszString, DBGCVAR_TYPE_GC_FLAT, &Var); 725 if (RT_SUCCESS(rc)) 726 { 727 /* deal with range */ 728 if (pArg->enmRangeType != DBGCVAR_RANGE_NONE) 729 { 730 Var.enmRangeType = pArg->enmRangeType; 731 Var.u64Range = pArg->u64Range; 732 } 733 else if (enmCategory == DBGCVAR_CAT_POINTER_NO_RANGE) 734 Var.enmRangeType = DBGCVAR_RANGE_NONE; 735 *pArg = Var; 736 } 737 return rc; 738 } 739 740 case DBGCVAR_TYPE_NUMBER: 741 if ( enmCategory != DBGCVAR_CAT_POINTER_NUMBER 742 && enmCategory != DBGCVAR_CAT_POINTER_NUMBER_NO_RANGE) 743 { 744 RTGCPTR GCPtr = (RTGCPTR)pArg->u.u64Number; 745 pArg->enmType = DBGCVAR_TYPE_GC_FLAT; 746 pArg->u.GCFlat = GCPtr; 747 } 748 return VINF_SUCCESS; 749 750 default: 751 AssertMsgFailedReturn(("Invalid type %d\n"), VERR_DBGC_PARSE_INCORRECT_ARG_TYPE); 752 } 753 break; /* (not reached) */ 754 755 /* 756 * GC pointer with and without range. 757 * We can try resolve strings and symbols as symbols and 758 * promote numbers to flat GC pointers. 759 */ 760 case DBGCVAR_CAT_GC_POINTER_NO_RANGE: 761 if (pArg->enmRangeType != DBGCVAR_RANGE_NONE) 762 return VERR_DBGC_PARSE_NO_RANGE_ALLOWED; 763 /* fallthru */ 764 case DBGCVAR_CAT_GC_POINTER: 765 switch (pArg->enmType) 766 { 767 case DBGCVAR_TYPE_GC_FLAT: 768 case DBGCVAR_TYPE_GC_FAR: 769 case DBGCVAR_TYPE_GC_PHYS: 770 return VINF_SUCCESS; 771 772 case DBGCVAR_TYPE_HC_FLAT: 773 case DBGCVAR_TYPE_HC_PHYS: 774 return VERR_DBGC_PARSE_CONVERSION_FAILED; 775 776 case DBGCVAR_TYPE_SYMBOL: 777 case DBGCVAR_TYPE_STRING: 778 { 779 DBGCVAR Var; 780 int rc = dbgcSymbolGet(pDbgc, pArg->u.pszString, DBGCVAR_TYPE_GC_FLAT, &Var); 781 if (RT_SUCCESS(rc)) 782 { 783 /* deal with range */ 784 if (pArg->enmRangeType != DBGCVAR_RANGE_NONE) 785 { 786 Var.enmRangeType = pArg->enmRangeType; 787 Var.u64Range = pArg->u64Range; 788 } 789 else if (enmCategory == DBGCVAR_CAT_POINTER_NO_RANGE) 790 Var.enmRangeType = DBGCVAR_RANGE_NONE; 791 *pArg = Var; 792 } 793 return rc; 794 } 795 796 case DBGCVAR_TYPE_NUMBER: 797 { 798 RTGCPTR GCPtr = (RTGCPTR)pArg->u.u64Number; 799 pArg->enmType = DBGCVAR_TYPE_GC_FLAT; 800 pArg->u.GCFlat = GCPtr; 801 return VINF_SUCCESS; 802 } 803 804 default: 805 AssertMsgFailedReturn(("Invalid type %d\n"), VERR_DBGC_PARSE_INCORRECT_ARG_TYPE); 806 } 807 break; /* (not reached) */ 808 809 /* 810 * Number with or without a range. 811 * Numbers can be resolved from symbols, but we cannot demote a pointer 812 * to a number. 813 */ 814 case DBGCVAR_CAT_NUMBER_NO_RANGE: 815 if (pArg->enmRangeType != DBGCVAR_RANGE_NONE) 816 return VERR_DBGC_PARSE_NO_RANGE_ALLOWED; 817 /* fallthru */ 818 case DBGCVAR_CAT_NUMBER: 819 switch (pArg->enmType) 820 { 821 case DBGCVAR_TYPE_GC_FLAT: 822 case DBGCVAR_TYPE_GC_FAR: 823 case DBGCVAR_TYPE_GC_PHYS: 824 case DBGCVAR_TYPE_HC_FLAT: 825 case DBGCVAR_TYPE_HC_PHYS: 826 return VERR_DBGC_PARSE_INCORRECT_ARG_TYPE; 827 828 case DBGCVAR_TYPE_NUMBER: 829 return VINF_SUCCESS; 830 831 case DBGCVAR_TYPE_SYMBOL: 832 case DBGCVAR_TYPE_STRING: 833 { 834 DBGCVAR Var; 835 int rc = dbgcSymbolGet(pDbgc, pArg->u.pszString, DBGCVAR_TYPE_NUMBER, &Var); 836 if (RT_SUCCESS(rc)) 837 { 838 /* deal with range */ 839 if (pArg->enmRangeType != DBGCVAR_RANGE_NONE) 840 { 841 Var.enmRangeType = pArg->enmRangeType; 842 Var.u64Range = pArg->u64Range; 843 } 844 else if (enmCategory == DBGCVAR_CAT_POINTER_NO_RANGE) 845 Var.enmRangeType = DBGCVAR_RANGE_NONE; 846 *pArg = Var; 847 } 848 return rc; 849 } 850 851 default: 852 AssertMsgFailedReturn(("Invalid type %d\n"), VERR_DBGC_PARSE_INCORRECT_ARG_TYPE); 853 } 854 break; /* (not reached) */ 855 856 /* 857 * Symbols and strings are basically the same thing for the time being. 858 */ 859 case DBGCVAR_CAT_STRING: 860 case DBGCVAR_CAT_SYMBOL: 861 { 862 switch (pArg->enmType) 863 { 864 case DBGCVAR_TYPE_STRING: 865 if (enmCategory == DBGCVAR_CAT_SYMBOL) 866 pArg->enmType = DBGCVAR_TYPE_SYMBOL; 867 return VINF_SUCCESS; 868 869 case DBGCVAR_TYPE_SYMBOL: 870 if (enmCategory == DBGCVAR_CAT_STRING) 871 pArg->enmType = DBGCVAR_TYPE_STRING; 872 return VINF_SUCCESS; 873 default: 874 break; 875 } 876 877 /* Stringify numeric and poitner values. */ 878 size_t cbScratch = sizeof(pDbgc->achScratch) - (pDbgc->pszScratch - &pDbgc->achScratch[0]); 879 size_t cch = pDbgc->CmdHlp.pfnStrPrintf(&pDbgc->CmdHlp, pDbgc->pszScratch, cbScratch, "%Dv", pArg); 880 if (cch + 1 >= cbScratch) 881 return VERR_DBGC_PARSE_NO_SCRATCH; 882 883 pArg->enmType = enmCategory == DBGCVAR_CAT_STRING ? DBGCVAR_TYPE_STRING : DBGCVAR_TYPE_SYMBOL; 884 pArg->u.pszString = pDbgc->pszScratch; 885 pArg->enmRangeType = DBGCVAR_RANGE_BYTES; 886 pArg->u64Range = cch; 887 888 pDbgc->pszScratch += cch + 1; 889 return VINF_SUCCESS; 890 } 891 892 /* 893 * These are not yet implemented. 894 */ 895 case DBGCVAR_CAT_OPTION: 896 case DBGCVAR_CAT_OPTION_STRING: 897 case DBGCVAR_CAT_OPTION_NUMBER: 898 AssertMsgFailedReturn(("Not implemented enmCategory=%d\n", enmCategory), VERR_DBGC_PARSE_NOT_IMPLEMENTED); 899 900 default: 901 AssertMsgFailedReturn(("Bad enmCategory=%d\n", enmCategory), VERR_DBGC_PARSE_NOT_IMPLEMENTED); 902 } 797 903 } 798 904 … … 835 941 836 942 /* 837 * This is a hack, it's "temporary" and should go away "when" the parser is838 * modified to match arguments while parsing.839 */840 if ( pCmd->cArgsMax == 1841 && pCmd->cArgsMin == 1842 && pCmd->cArgDescs == 1843 && ( pCmd->paArgDescs[0].enmCategory == DBGCVAR_CAT_STRING844 || pCmd->paArgDescs[0].enmCategory == DBGCVAR_CAT_SYMBOL)845 && cArgs >= 1)846 {847 *pcArgs = 1;848 RTStrStripR(pszArgs);849 return dbgcEvalSubString(pDbgc, pszArgs, strlen(pszArgs), &paArgs[0]);850 }851 852 /*853 943 * The parse loop. 854 944 */ … … 871 961 if (pArg >= &paArgs[cArgs]) 872 962 return VERR_DBGC_PARSE_ARGUMENT_OVERFLOW; 873 #ifdef DEBUG_bird /* work in progress. */874 963 if (iVarDesc >= cVarDescs) 875 964 return VERR_DBGC_PARSE_TOO_MANY_ARGUMENTS; 876 965 877 966 /* Walk argument descriptors. */ 878 if ( ( paVarDescs[iVarDesc].fFlags & DBGCVD_FLAGS_DEP_PREV 879 && &paVarDescs[iVarDesc - 1] != pPrevDesc) 880 || cCurDesc >= paVarDescs[iVarDesc].cTimesMax) 967 if (cCurDesc >= paVarDescs[iVarDesc].cTimesMax) 881 968 { 882 969 iVarDesc++; … … 885 972 cCurDesc = 0; 886 973 } 887 #endif888 974 889 975 /* … … 914 1000 * We use the REXX way of escaping the quotation char, i.e. double occurrence. 915 1001 */ 916 else if (ch == '\'' || ch == '"' || ch == '`')1002 else if (ch == '\'' || ch == '"') 917 1003 { 918 1004 if (chQuote) … … 933 1019 * Parenthesis can of course be nested. 934 1020 */ 935 else if ( ch == '(')1021 else if (!chQuote && ch == '(') 936 1022 { 937 1023 cPar++; 938 1024 fBinary = false; 939 1025 } 940 else if ( ch == ')')1026 else if (!chQuote && ch == ')') 941 1027 { 942 1028 if (!cPar) … … 997 1083 size_t cchArgs = strlen(pszArgs); 998 1084 999 1000 #ifdef DEBUG_bird /* work in progress. */1001 1085 /* 1002 1086 * Try optional arguments until we find something which matches … … 1007 1091 char *pszArgsCopy = (char *)RTMemDup(pszArgs, cchArgs + 1); 1008 1092 if (!pszArgsCopy) 1009 return VERR_NO_MEMORY; 1010 1011 int rc = dbgcEvalSub(pDbgc, pszArgs, strlen(pszArgs), paVarDescs[iVarDesc].enmCategory, pArg); 1093 return VERR_DBGC_PARSE_NO_MEMORY; 1094 1095 int rc = dbgcEvalSub(pDbgc, pszArgs, cchArgs, paVarDescs[iVarDesc].enmCategory, pArg); 1096 if (RT_SUCCESS(rc)) 1097 rc = dbgcCheckAndTypePromoteArgument(pDbgc, paVarDescs[iVarDesc].enmCategory, pArg); 1012 1098 if (RT_SUCCESS(rc)) 1013 1099 { … … 1021 1107 RTMemFree(pszArgsCopy); 1022 1108 1023 /* can we advance? */ 1109 /* Continue searching optional descriptors? */ 1110 if ( rc != VERR_DBGC_PARSE_INCORRECT_ARG_TYPE 1111 && rc != VERR_DBGC_PARSE_INVALID_NUMBER 1112 && rc != VERR_DBGC_PARSE_NO_RANGE_ALLOWED 1113 ) 1114 return rc; 1115 1116 /* Try advance to the next descriptor. */ 1024 1117 if (paVarDescs[iVarDesc].cTimesMin > cCurDesc) 1025 1118 return rc; 1026 if (++iVarDesc >= cVarDescs) 1119 iVarDesc++; 1120 if (!cCurDesc) 1121 while ( iVarDesc < cVarDescs 1122 && (paVarDescs[iVarDesc].fFlags & DBGCVD_FLAGS_DEP_PREV)) 1123 iVarDesc++; 1124 if (iVarDesc >= cVarDescs) 1027 1125 return rc; 1028 1126 cCurDesc = 0; 1029 1127 } 1030 1128 1031 #else 1032 /* 1033 * Parse and evaluate the argument. 1034 */ 1035 int rc = dbgcEvalSub(pDbgc, pszArgs, cchArgs, DBGCVAR_CAT_ANY, pArg); 1036 if (RT_FAILURE(rc)) 1037 return rc; 1038 #endif 1039 1040 /* 1041 * Next. 1129 /* 1130 * Next argument. 1042 1131 */ 1043 1132 iVar++; … … 1050 1139 1051 1140 /* 1052 * Match the arguments. 1053 */ 1054 return dbgcEvalSubMatchVars(pDbgc, pCmd->cArgsMin, pCmd->cArgsMax, pCmd->paArgDescs, pCmd->cArgDescs, pArg0, pArg - pArg0); 1141 * Check that the rest of the argument descriptors indicate optional args. 1142 */ 1143 if (iVarDesc < cVarDescs) 1144 { 1145 if (cCurDesc < paVarDescs[iVarDesc].cTimesMin) 1146 return VERR_DBGC_PARSE_TOO_FEW_ARGUMENTS; 1147 iVarDesc++; 1148 while (iVarDesc < cVarDescs) 1149 { 1150 if (paVarDescs[iVarDesc].cTimesMin) 1151 return VERR_DBGC_PARSE_TOO_FEW_ARGUMENTS; 1152 iVarDesc++; 1153 } 1154 } 1155 1156 return VINF_SUCCESS; 1055 1157 } 1056 1158 -
trunk/src/VBox/Debugger/testcase/tstDBGCParser.cpp
r41553 r41558 406 406 407 407 408 /* 409 * 410 * CodeView emulation commands. 411 * CodeView emulation commands. 412 * CodeView emulation commands. 413 * 414 */ 415 408 416 409 417 static void testCodeView_ba(PDBGC pDbgc) … … 447 455 DBGCVAR_TYPE_STRING, "command", DBGCVAR_RANGE_BYTES, UINT64_C(7)); 448 456 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); 457 tstTry(pDbgc, "ba x 1 0f000:1234 qnx 1000 \"command\"\n", VERR_DBGC_PARSE_TOO_MANY_ARGUMENTS); 458 tstTry(pDbgc, "ba x 1 0f000:1234 5 qnx \"command\"\n", VERR_DBGC_PARSE_TOO_MANY_ARGUMENTS); 459 tstTry(pDbgc, "ba x qnx 0f000:1234 5 1000 \"command\"\n", VERR_DBGC_PARSE_INVALID_NUMBER); 460 tstTry(pDbgc, "ba x 1 qnx 5 1000 \"command\"\n", VERR_DBGC_PARSE_INVALID_NUMBER); 461 } 462 463 464 static void testCodeView_bc(PDBGC pDbgc) 465 { 466 RTTestISub("codeview - bc"); 467 } 468 469 470 static void testCodeView_bd(PDBGC pDbgc) 471 { 472 RTTestISub("codeview - bc"); 473 } 474 475 476 static void testCodeView_be(PDBGC pDbgc) 477 { 478 RTTestISub("codeview - be"); 479 } 480 481 482 static void testCodeView_bl(PDBGC pDbgc) 483 { 484 RTTestISub("codeview - bl"); 485 } 486 487 488 static void testCodeView_bp(PDBGC pDbgc) 489 { 490 RTTestISub("codeview - bp"); 491 } 492 493 494 static void testCodeView_br(PDBGC pDbgc) 495 { 496 RTTestISub("codeview - br"); 497 } 498 499 500 static void testCodeView_d(PDBGC pDbgc) 501 { 502 RTTestISub("codeview - d"); 503 } 504 505 506 static void testCodeView_da(PDBGC pDbgc) 507 { 508 RTTestISub("codeview - da"); 509 } 510 511 512 static void testCodeView_db(PDBGC pDbgc) 513 { 514 RTTestISub("codeview - db"); 515 } 516 517 518 static void testCodeView_dd(PDBGC pDbgc) 519 { 520 RTTestISub("codeview - dd"); 521 } 522 523 524 static void testCodeView_dg(PDBGC pDbgc) 525 { 526 RTTestISub("codeview - dg"); 527 } 528 529 530 static void testCodeView_dga(PDBGC pDbgc) 531 { 532 RTTestISub("codeview - dga"); 533 } 534 535 536 static void testCodeView_di(PDBGC pDbgc) 537 { 538 RTTestISub("codeview - di"); 539 } 540 541 542 static void testCodeView_dia(PDBGC pDbgc) 543 { 544 RTTestISub("codeview - dia"); 545 } 546 547 548 static void testCodeView_dl(PDBGC pDbgc) 549 { 550 RTTestISub("codeview - dl"); 551 } 552 553 554 static void testCodeView_dla(PDBGC pDbgc) 555 { 556 RTTestISub("codeview - dla"); 557 } 558 559 560 static void testCodeView_dpd(PDBGC pDbgc) 561 { 562 RTTestISub("codeview - dpd"); 563 } 564 565 566 static void testCodeView_dpda(PDBGC pDbgc) 567 { 568 RTTestISub("codeview - dpda"); 569 } 570 571 572 static void testCodeView_dpdb(PDBGC pDbgc) 573 { 574 RTTestISub("codeview - dpdb"); 575 } 576 577 578 static void testCodeView_dpdg(PDBGC pDbgc) 579 { 580 RTTestISub("codeview - dpdg"); 581 } 582 583 584 static void testCodeView_dpdh(PDBGC pDbgc) 585 { 586 RTTestISub("codeview - dpdh"); 587 } 588 589 590 static void testCodeView_dph(PDBGC pDbgc) 591 { 592 RTTestISub("codeview - dph"); 593 } 594 595 596 static void testCodeView_dphg(PDBGC pDbgc) 597 { 598 RTTestISub("codeview - dphg"); 599 } 600 601 602 static void testCodeView_dphh(PDBGC pDbgc) 603 { 604 RTTestISub("codeview - dphh"); 605 } 606 607 608 static void testCodeView_dq(PDBGC pDbgc) 609 { 610 RTTestISub("codeview - dq"); 611 } 612 613 614 static void testCodeView_dt(PDBGC pDbgc) 615 { 616 RTTestISub("codeview - dt"); 617 } 618 619 620 static void testCodeView_dt16(PDBGC pDbgc) 621 { 622 RTTestISub("codeview - dt16"); 623 } 624 625 626 static void testCodeView_dt32(PDBGC pDbgc) 627 { 628 RTTestISub("codeview - dt32"); 629 } 630 631 632 static void testCodeView_dt64(PDBGC pDbgc) 633 { 634 RTTestISub("codeview - dt64"); 635 } 636 637 638 static void testCodeView_dw(PDBGC pDbgc) 639 { 640 RTTestISub("codeview - dw"); 641 } 642 643 644 static void testCodeView_eb(PDBGC pDbgc) 645 { 646 RTTestISub("codeview - eb"); 647 } 648 649 650 static void testCodeView_ew(PDBGC pDbgc) 651 { 652 RTTestISub("codeview - ew"); 653 } 654 655 656 static void testCodeView_ed(PDBGC pDbgc) 657 { 658 RTTestISub("codeview - ed"); 659 } 660 661 662 static void testCodeView_eq(PDBGC pDbgc) 663 { 664 RTTestISub("codeview - eq"); 665 } 666 667 668 static void testCodeView_g(PDBGC pDbgc) 669 { 670 RTTestISub("codeview - g"); 671 } 672 673 674 static void testCodeView_k(PDBGC pDbgc) 675 { 676 RTTestISub("codeview - k"); 677 } 678 679 680 static void testCodeView_kg(PDBGC pDbgc) 681 { 682 RTTestISub("codeview - kg"); 683 } 684 685 686 static void testCodeView_kh(PDBGC pDbgc) 687 { 688 RTTestISub("codeview - kh"); 689 } 690 691 692 static void testCodeView_lm(PDBGC pDbgc) 693 { 694 RTTestISub("codeview - lm"); 695 } 696 697 698 static void testCodeView_lmo(PDBGC pDbgc) 699 { 700 RTTestISub("codeview - lmo"); 701 } 702 703 704 static void testCodeView_ln(PDBGC pDbgc) 705 { 706 RTTestISub("codeview - ln"); 707 } 708 709 710 static void testCodeView_ls(PDBGC pDbgc) 711 { 712 RTTestISub("codeview - ls"); 713 } 714 715 716 static void testCodeView_m(PDBGC pDbgc) 717 { 718 RTTestISub("codeview - m"); 719 } 720 721 722 static void testCodeView_r(PDBGC pDbgc) 723 { 724 RTTestISub("codeview - r"); 725 } 726 727 728 static void testCodeView_rg(PDBGC pDbgc) 729 { 730 RTTestISub("codeview - rg"); 731 } 732 733 734 static void testCodeView_rg32(PDBGC pDbgc) 735 { 736 RTTestISub("codeview - rg32"); 737 } 738 739 740 static void testCodeView_rg64(PDBGC pDbgc) 741 { 742 RTTestISub("codeview - rg64"); 743 } 744 745 746 static void testCodeView_rh(PDBGC pDbgc) 747 { 748 RTTestISub("codeview - rh"); 749 } 750 751 752 static void testCodeView_rt(PDBGC pDbgc) 753 { 754 RTTestISub("codeview - rt"); 755 } 756 757 758 static void testCodeView_s(PDBGC pDbgc) 759 { 760 RTTestISub("codeview - s"); 761 } 762 763 764 static void testCodeView_sa(PDBGC pDbgc) 765 { 766 RTTestISub("codeview - sa"); 767 } 768 769 770 static void testCodeView_sb(PDBGC pDbgc) 771 { 772 RTTestISub("codeview - sb"); 773 } 774 775 776 static void testCodeView_sd(PDBGC pDbgc) 777 { 778 RTTestISub("codeview - sd"); 779 } 780 781 782 static void testCodeView_sq(PDBGC pDbgc) 783 { 784 RTTestISub("codeview - sq"); 785 } 786 787 788 static void testCodeView_su(PDBGC pDbgc) 789 { 790 RTTestISub("codeview - su"); 791 } 792 793 794 static void testCodeView_sw(PDBGC pDbgc) 795 { 796 RTTestISub("codeview - sw"); 797 } 798 799 800 static void testCodeView_t(PDBGC pDbgc) 801 { 802 RTTestISub("codeview - t"); 803 } 804 805 806 static void testCodeView_y(PDBGC pDbgc) 807 { 808 RTTestISub("codeview - y"); 809 } 810 811 812 static void testCodeView_u64(PDBGC pDbgc) 813 { 814 RTTestISub("codeview - u64"); 815 } 816 817 818 static void testCodeView_u32(PDBGC pDbgc) 819 { 820 RTTestISub("codeview - u32"); 821 } 822 823 824 static void testCodeView_u16(PDBGC pDbgc) 825 { 826 RTTestISub("codeview - u16"); 827 } 828 829 830 static void testCodeView_uv86(PDBGC pDbgc) 831 { 832 RTTestISub("codeview - uv86"); 833 } 834 835 836 /* 837 * Common commands. 838 */ 839 840 static void testCommon_bye_exit_quit(PDBGC pDbgc) 841 { 842 RTTestISub("common - bye/exit/quit"); 843 /* These have the same parameter descriptor and handler, the command really 844 just has a couple of aliases.*/ 845 tstTry(pDbgc, "bye\n", VINF_SUCCESS); 846 tstTry(pDbgc, "bye x\n", VERR_DBGC_PARSE_TOO_MANY_ARGUMENTS); 847 tstTry(pDbgc, "bye 1\n", VERR_DBGC_PARSE_TOO_MANY_ARGUMENTS); 848 tstTry(pDbgc, "bye %bad:bad\n", VERR_DBGC_PARSE_TOO_MANY_ARGUMENTS); 849 tstTry(pDbgc, "exit\n", VINF_SUCCESS); 850 tstTry(pDbgc, "quit\n", VINF_SUCCESS); 851 } 852 853 854 static void testCommon_cpu(PDBGC pDbgc) 855 { 856 RTTestISub("common - cpu"); 857 tstTry(pDbgc, "cpu\n", VINF_SUCCESS); 858 tstTry(pDbgc, "cpu 1\n", VINF_SUCCESS); 859 tstTry(pDbgc, "cpu 1 1\n", VERR_DBGC_PARSE_TOO_MANY_ARGUMENTS); 860 tstTry(pDbgc, "cpu emt\n", VERR_DBGC_PARSE_INVALID_NUMBER); 861 tstTry(pDbgc, "cpu @eax\n", VINF_SUCCESS); 862 tstTry(pDbgc, "cpu %bad:bad\n", VERR_DBGC_PARSE_CONVERSION_FAILED); 863 } 864 865 866 static void testCommon_echo(PDBGC pDbgc) 867 { 868 RTTestISub("common - echo"); 869 tstTry(pDbgc, "echo\n", VERR_DBGC_PARSE_TOO_FEW_ARGUMENTS); 870 tstTry(pDbgc, "echo 1\n", VINF_SUCCESS); 871 tstTryEx(pDbgc, "echo 1 2 3 4 5 6\n", VINF_SUCCESS, false, "1 2 3 4 5 6", -1); 872 873 /* The idea here is that since the prefered input is a string, we 874 definitely won't be mistaking number like beginnings as numbers. */ 875 tstTryEx(pDbgc, "echo 1234567890abcdefghijklmn\n", VINF_SUCCESS, false, "1234567890abcdefghijklmn", -1); 876 877 /* The idea here is that we'll perform the + operation and then convert the 878 result to a string (hex). */ 879 tstTryEx(pDbgc, "echo 1 + 1\n", VINF_SUCCESS, false, "2", -1); 880 tstTryEx(pDbgc, "echo \"1 + 1\"\n", VINF_SUCCESS, false, "1 + 1", -1); 881 882 tstTryEx(pDbgc, "echo 0i10 + 6\n", VINF_SUCCESS, false, "10", -1); 883 tstTryEx(pDbgc, "echo \"0i10 + 6\"\n", VINF_SUCCESS, false, "0i10 + 6", -1); 884 885 tstTryEx(pDbgc, "echo %f000:0010\n", VINF_SUCCESS, false, "%00000000000f0010", -1); 886 tstTryEx(pDbgc, "echo \"%f000:0010\"\n", VINF_SUCCESS, false, "%f000:0010", -1); 887 888 tstTry(pDbgc, "echo %bad:bad\n", VERR_DBGC_PARSE_CONVERSION_FAILED); 889 } 890 891 892 static void testCommon_format(PDBGC pDbgc) 893 { 894 RTTestISub("common - format"); 895 } 896 897 898 static void testCommon_detect(PDBGC pDbgc) 899 { 900 RTTestISub("common - detect"); 901 } 902 903 904 static void testCommon_harakiri(PDBGC pDbgc) 905 { 906 RTTestISub("common - harakiri"); 907 } 908 909 910 static void testCommon_help(PDBGC pDbgc) 911 { 912 RTTestISub("common - help"); 913 } 914 915 916 static void testCommon_info(PDBGC pDbgc) 917 { 918 RTTestISub("common - info"); 919 tstTry(pDbgc, "info 12fg\n", VINF_SUCCESS); 920 tstTry(pDbgc, "info fflags argument\n", VINF_SUCCESS); 921 } 922 923 924 static void testCommon_loadimage(PDBGC pDbgc) 925 { 926 RTTestISub("common - loadimage"); 927 } 928 929 930 static void testCommon_loadmap(PDBGC pDbgc) 931 { 932 RTTestISub("common - loadmap"); 933 } 934 935 936 static void testCommon_loadplugin(PDBGC pDbgc) 937 { 938 RTTestISub("common - loadplugin"); 939 } 940 941 942 static void testCommon_loadseg(PDBGC pDbgc) 943 { 944 RTTestISub("common - loadseg"); 945 } 946 947 948 static void testCommon_loadsyms(PDBGC pDbgc) 949 { 950 RTTestISub("common - loadsyms"); 951 } 952 953 954 static void testCommon_loadvars(PDBGC pDbgc) 955 { 956 RTTestISub("common - loadvars"); 957 } 958 959 960 static void testCommon_log(PDBGC pDbgc) 961 { 962 RTTestISub("common - log"); 963 } 964 965 966 static void testCommon_logdest(PDBGC pDbgc) 967 { 968 RTTestISub("common - logdest"); 969 } 970 971 972 static void testCommon_logflags(PDBGC pDbgc) 973 { 974 RTTestISub("common - logflags"); 975 } 976 977 978 static void testCommon_runscript(PDBGC pDbgc) 979 { 980 RTTestISub("common - runscript"); 981 } 982 983 984 static void testCommon_set(PDBGC pDbgc) 985 { 986 RTTestISub("common - set"); 987 } 988 989 990 static void testCommon_showplugins(PDBGC pDbgc) 991 { 992 RTTestISub("common - showplugins"); 993 } 994 995 996 static void testCommon_showvars(PDBGC pDbgc) 997 { 998 RTTestISub("common - showvars"); 999 } 1000 1001 1002 static void testCommon_stop(PDBGC pDbgc) 1003 { 1004 RTTestISub("common - stop"); 1005 } 1006 1007 1008 static void testCommon_unloadplugin(PDBGC pDbgc) 1009 { 1010 RTTestISub("common - unloadplugin"); 1011 } 1012 1013 1014 static void testCommon_unset(PDBGC pDbgc) 1015 { 1016 RTTestISub("common - unset"); 1017 } 1018 1019 1020 static void testCommon_writecore(PDBGC pDbgc) 1021 { 1022 RTTestISub("common - writecore"); 1023 } 1024 1025 1026 1027 /* 1028 * Basic tests. 1029 */ 1030 1031 static void testBasicsOddCases(PDBGC pDbgc) 1032 { 1033 RTTestISub("Odd cases"); 1034 tstTry(pDbgc, "r @rax\n", VINF_SUCCESS); 1035 tstTry(pDbgc, "r @eax\n", VINF_SUCCESS); 1036 tstTry(pDbgc, "r @ah\n", VINF_SUCCESS); 1037 tstTry(pDbgc, "r @notavalidregister\n", VERR_DBGF_REGISTER_NOT_FOUND); 1038 } 1039 1040 1041 static void testBasicsOperators(PDBGC pDbgc) 1042 { 1043 RTTestISub("Operators"); 1044 tstNumOp(pDbgc, "1", 1); 1045 tstNumOp(pDbgc, "1", 1); 1046 tstNumOp(pDbgc, "1", 1); 1047 1048 tstNumOp(pDbgc, "+1", 1); 1049 tstNumOp(pDbgc, "++++++1", 1); 1050 1051 tstNumOp(pDbgc, "-1", UINT64_MAX); 1052 tstNumOp(pDbgc, "--1", 1); 1053 tstNumOp(pDbgc, "---1", UINT64_MAX); 1054 tstNumOp(pDbgc, "----1", 1); 1055 1056 tstNumOp(pDbgc, "~0", UINT64_MAX); 1057 tstNumOp(pDbgc, "~1", UINT64_MAX-1); 1058 tstNumOp(pDbgc, "~~0", 0); 1059 tstNumOp(pDbgc, "~~1", 1); 1060 1061 tstNumOp(pDbgc, "!1", 0); 1062 tstNumOp(pDbgc, "!0", 1); 1063 tstNumOp(pDbgc, "!42", 0); 1064 tstNumOp(pDbgc, "!!42", 1); 1065 tstNumOp(pDbgc, "!!!42", 0); 1066 tstNumOp(pDbgc, "!!!!42", 1); 1067 1068 tstNumOp(pDbgc, "1 +1", 2); 1069 tstNumOp(pDbgc, "1 + 1", 2); 1070 tstNumOp(pDbgc, "1+1", 2); 1071 tstNumOp(pDbgc, "1+ 1", 2); 1072 1073 tstNumOp(pDbgc, "1 - 1", 0); 1074 tstNumOp(pDbgc, "99 - 90", 9); 1075 1076 tstNumOp(pDbgc, "2 * 2", 4); 1077 1078 tstNumOp(pDbgc, "2 / 2", 1); 1079 tstNumOp(pDbgc, "2 / 0", UINT64_MAX); 1080 tstNumOp(pDbgc, "0i1024 / 0i4", 256); 1081 1082 tstNumOp(pDbgc, "8 mod 7", 1); 1083 1084 tstNumOp(pDbgc, "1<<1", 2); 1085 tstNumOp(pDbgc, "1<<0i32", UINT64_C(0x0000000100000000)); 1086 tstNumOp(pDbgc, "1<<0i48", UINT64_C(0x0001000000000000)); 1087 tstNumOp(pDbgc, "1<<0i63", UINT64_C(0x8000000000000000)); 1088 1089 tstNumOp(pDbgc, "fedcba0987654321>>0i04", UINT64_C(0x0fedcba098765432)); 1090 tstNumOp(pDbgc, "fedcba0987654321>>0i32", UINT64_C(0xfedcba09)); 1091 tstNumOp(pDbgc, "fedcba0987654321>>0i48", UINT64_C(0x0000fedc)); 1092 1093 tstNumOp(pDbgc, "0ef & 4", 4); 1094 tstNumOp(pDbgc, "01234567891 & fff", UINT64_C(0x00000000891)); 1095 tstNumOp(pDbgc, "01234567891 & ~fff", UINT64_C(0x01234567000)); 1096 1097 tstNumOp(pDbgc, "1 | 1", 1); 1098 tstNumOp(pDbgc, "0 | 4", 4); 1099 tstNumOp(pDbgc, "4 | 0", 4); 1100 tstNumOp(pDbgc, "4 | 4", 4); 1101 tstNumOp(pDbgc, "1 | 4 | 2", 7); 1102 1103 tstNumOp(pDbgc, "1 ^ 1", 0); 1104 tstNumOp(pDbgc, "1 ^ 0", 1); 1105 tstNumOp(pDbgc, "0 ^ 1", 1); 1106 tstNumOp(pDbgc, "3 ^ 1", 2); 1107 tstNumOp(pDbgc, "7 ^ 3", 4); 1108 1109 tstNumOp(pDbgc, "7 || 3", 1); 1110 tstNumOp(pDbgc, "1 || 0", 1); 1111 tstNumOp(pDbgc, "0 || 1", 1); 1112 tstNumOp(pDbgc, "0 || 0", 0); 1113 1114 tstNumOp(pDbgc, "0 && 0", 0); 1115 tstNumOp(pDbgc, "1 && 0", 0); 1116 tstNumOp(pDbgc, "0 && 1", 0); 1117 tstNumOp(pDbgc, "1 && 1", 1); 1118 tstNumOp(pDbgc, "4 && 1", 1); 1119 } 1120 1121 1122 static void testBasicsFundametalParsing(PDBGC pDbgc) 1123 { 1124 RTTestISub("Fundamental parsing"); 1125 tstTry(pDbgc, "stop\n", VINF_SUCCESS); 1126 tstTry(pDbgc, "format 1\n", VINF_SUCCESS); 1127 tstTry(pDbgc, "format \n", VERR_DBGC_PARSE_TOO_FEW_ARGUMENTS); 1128 tstTry(pDbgc, "format 0 1 23 4\n", VERR_DBGC_PARSE_TOO_MANY_ARGUMENTS); 1129 tstTry(pDbgc, "sa 3 23 4 'q' \"21123123\" 'b' \n", VINF_SUCCESS); 453 1130 } 454 1131 … … 477 1154 if (RT_SUCCESS(rc)) 478 1155 { 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 1156 /* 1157 * Perform basic tests first. 1158 */ 1159 testBasicsFundametalParsing(pDbgc); 486 1160 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 1161 testBasicsOperators(pDbgc); 566 1162 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 } 1163 testBasicsOddCases(pDbgc); 574 1164 575 1165 /* 576 * Test co deview commands.1166 * Test commands. 577 1167 */ 578 #ifdef DEBUG_bird /* This will fail for a while */579 1168 if (RTTestErrorCount(g_hTest) == 0) 580 1169 { 581 1170 testCodeView_ba(pDbgc); 582 1171 testCodeView_bc(pDbgc); 1172 testCodeView_bd(pDbgc); 1173 testCodeView_be(pDbgc); 1174 testCodeView_bl(pDbgc); 1175 testCodeView_bp(pDbgc); 1176 testCodeView_br(pDbgc); 1177 testCodeView_d(pDbgc); 1178 testCodeView_da(pDbgc); 1179 testCodeView_db(pDbgc); 1180 testCodeView_dd(pDbgc); 1181 testCodeView_dg(pDbgc); 1182 testCodeView_dga(pDbgc); 1183 testCodeView_di(pDbgc); 1184 testCodeView_dia(pDbgc); 1185 testCodeView_dl(pDbgc); 1186 testCodeView_dla(pDbgc); 1187 testCodeView_dpd(pDbgc); 1188 testCodeView_dpda(pDbgc); 1189 testCodeView_dpdb(pDbgc); 1190 testCodeView_dpdg(pDbgc); 1191 testCodeView_dpdh(pDbgc); 1192 testCodeView_dph(pDbgc); 1193 testCodeView_dphg(pDbgc); 1194 testCodeView_dphh(pDbgc); 1195 testCodeView_dq(pDbgc); 1196 testCodeView_dt(pDbgc); 1197 testCodeView_dt16(pDbgc); 1198 testCodeView_dt32(pDbgc); 1199 testCodeView_dt64(pDbgc); 1200 testCodeView_dw(pDbgc); 1201 testCodeView_eb(pDbgc); 1202 testCodeView_ew(pDbgc); 1203 testCodeView_ed(pDbgc); 1204 testCodeView_eq(pDbgc); 1205 testCodeView_g(pDbgc); 1206 testCodeView_k(pDbgc); 1207 testCodeView_kg(pDbgc); 1208 testCodeView_kh(pDbgc); 1209 testCodeView_lm(pDbgc); 1210 testCodeView_lmo(pDbgc); 1211 testCodeView_ln(pDbgc); 1212 testCodeView_ls(pDbgc); 1213 testCodeView_m(pDbgc); 1214 testCodeView_r(pDbgc); 1215 testCodeView_rg(pDbgc); 1216 testCodeView_rg32(pDbgc); 1217 testCodeView_rg64(pDbgc); 1218 testCodeView_rh(pDbgc); 1219 testCodeView_rt(pDbgc); 1220 testCodeView_s(pDbgc); 1221 testCodeView_sa(pDbgc); 1222 testCodeView_sb(pDbgc); 1223 testCodeView_sd(pDbgc); 1224 testCodeView_sq(pDbgc); 1225 testCodeView_su(pDbgc); 1226 testCodeView_sw(pDbgc); 1227 testCodeView_t(pDbgc); 1228 testCodeView_y(pDbgc); 1229 testCodeView_u64(pDbgc); 1230 testCodeView_u32(pDbgc); 1231 testCodeView_u16(pDbgc); 1232 testCodeView_uv86(pDbgc); 1233 1234 testCommon_bye_exit_quit(pDbgc); 1235 testCommon_cpu(pDbgc); 1236 testCommon_echo(pDbgc); 1237 testCommon_format(pDbgc); 1238 testCommon_detect(pDbgc); 1239 testCommon_harakiri(pDbgc); 1240 testCommon_help(pDbgc); 1241 testCommon_info(pDbgc); 1242 testCommon_loadimage(pDbgc); 1243 testCommon_loadmap(pDbgc); 1244 testCommon_loadplugin(pDbgc); 1245 testCommon_loadseg(pDbgc); 1246 testCommon_loadsyms(pDbgc); 1247 testCommon_loadvars(pDbgc); 1248 testCommon_log(pDbgc); 1249 testCommon_logdest(pDbgc); 1250 testCommon_logflags(pDbgc); 1251 testCommon_runscript(pDbgc); 1252 testCommon_set(pDbgc); 1253 testCommon_showplugins(pDbgc); 1254 testCommon_showvars(pDbgc); 1255 testCommon_stop(pDbgc); 1256 testCommon_unloadplugin(pDbgc); 1257 testCommon_unset(pDbgc); 1258 testCommon_writecore(pDbgc); 583 1259 } 584 #endif585 1260 } 586 1261
Note:
See TracChangeset
for help on using the changeset viewer.