VirtualBox

Changeset 7183 in vbox


Ignore:
Timestamp:
Feb 27, 2008 5:41:30 PM (17 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
28483
Message:

Added RTStrFormatTypeRegister/SetUser/Deregister for runtime registration of custom format types. Example: RTStrFormat("%R[pgmpage]", pPage);

Location:
trunk
Files:
1 added
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/iprt/string.h

    r7170 r7183  
    537537RTDECL(int) RTStrFormatNumber(char *psz, uint64_t u64Value, unsigned int uiBase, signed int cchWidth, signed int cchPrecision, unsigned int fFlags);
    538538
     539
     540/**
     541 * Callback for formatting a type.
     542 *
     543 * This is registered using the RTStrFormatTypeRegister function and will
     544 * be called during string formatting to handle the specified %R[type].
     545 * The argument for this format type is assumed to be a pointer and it's
     546 * passed in the @a pvValue argument.
     547 *
     548 * @returns Length of the formatted output.
     549 * @param   pfnOutput       Output worker.
     550 * @param   pvArgOutput     Argument to the output worker.
     551 * @param   pszType         The type name.
     552 * @param   pvValue         The argument value.
     553 * @param   cchWidth        Width.
     554 * @param   cchPrecision    Precision.
     555 * @param   fFlags          Flags (NTFS_*).
     556 * @param   pvUser          The user argument.
     557 */
     558typedef DECLCALLBACK(size_t) FNRTSTRFORMATTYPE(PFNRTSTROUTPUT pfnOutput, void *pvArgOutput,
     559                                               const char *pszType, void const *pvValue,
     560                                               int cchWidth, int cchPrecision, unsigned fFlags,
     561                                               void *pvUser);
     562/** Pointer to a FNRTSTRFORMATTYPE. */
     563typedef FNRTSTRFORMATTYPE *PFNRTSTRFORMATTYPE;
     564
     565
     566/**
     567 * Register a format handler for a type.
     568 *
     569 * The format handler is used to handle '%R[type]' format types, where the argument
     570 * in the vector is a pointer value (a bit restrictive, but keeps it simple).
     571 *
     572 * The caller must ensure that no other thread will be making use of any of
     573 * the dynamic formatting type facilities simultaneously with this call.
     574 *
     575 * @returns IPRT status code.
     576 * @retval  VINF_SUCCESS on success.
     577 * @retval  VERR_ALREADY_EXISTS if the type has already been registered.
     578 * @retval  VERR_TOO_MANY_OPEN_FILES if all the type slots has been allocated already.
     579 *
     580 * @param   pszType         The type name.
     581 * @param   pfnHandler      The handler address. See FNRTSTRFORMATTYPE for details.
     582 * @param   pvUser          The user argument to pass to the handler. See RTStrFormatTypeSetUser
     583 *                          for how to update this later.
     584 */
     585RTDECL(int) RTStrFormatTypeRegister(const char *pszType, PFNRTSTRFORMATTYPE pfnHandler, void *pvUser);
     586
     587/**
     588 * Deregisters a format type.
     589 *
     590 * The caller must ensure that no other thread will be making use of any of
     591 * the dynamic formatting type facilities simultaneously with this call.
     592 *
     593 * @returns IPRT status code.
     594 * @retval  VINF_SUCCESS on success.
     595 * @retval  VERR_FILE_NOT_FOUND if not found.
     596 *
     597 * @param   pszType     The type to deregister.
     598 */
     599RTDECL(int) RTStrFormatTypeDeregister(const char *pszType);
     600
     601/**
     602 * Sets the user argument for a type.
     603 *
     604 * This can be used if a user argument needs relocating in GC.
     605 *
     606 * @returns IPRT status code.
     607 * @retval  VINF_SUCCESS on success.
     608 * @retval  VERR_FILE_NOT_FOUND if not found.
     609 *
     610 * @param   pszType     The type to update.
     611 * @param   pvUser      The new user argument value.
     612 */
     613RTDECL(int) RTStrFormatTypeSetUser(const char *pszType, void *pvUser);
     614
     615
    539616/**
    540617 * String printf.
  • trunk/src/VBox/Additions/linux/module/Makefile.module

    r6857 r7183  
    4242        strformat.o \
    4343        strformatrt.o \
     44        strformattype.o \
    4445        strformat-vbox.o
    4546
  • trunk/src/VBox/Additions/linux/module/files_vboxadd

    r5999 r7183  
    6060    ${PATH_ROOT}/src/VBox/Runtime/common/string/strformat.cpp=>strformat.c \
    6161    ${PATH_ROOT}/src/VBox/Runtime/common/string/strformatrt.cpp=>strformatrt.c \
     62    ${PATH_ROOT}/src/VBox/Runtime/common/string/strformattype.cpp=>strformattype.c \
    6263    ${PATH_ROOT}/src/VBox/Runtime/r0drv/alloc-r0drv.cpp=>r0drv/alloc-r0drv.c \
    6364    ${PATH_ROOT}/src/VBox/Runtime/r0drv/alloc-r0drv.h=>r0drv/alloc-r0drv.h \
  • trunk/src/VBox/HostDrivers/Support/linux/Makefile

    r7130 r7183  
    9494        common/string/strformat.o \
    9595        common/string/strformatrt.o \
     96        common/string/strformattype.o \
    9697        common/string/strprintf.o \
    9798        common/string/strtonum.o \
  • trunk/src/VBox/HostDrivers/Support/linux/files_vboxdrv

    r7004 r7183  
    6969    ${PATH_ROOT}/src/VBox/Runtime/common/string/strformat.cpp=>common/string/strformat.c \
    7070    ${PATH_ROOT}/src/VBox/Runtime/common/string/strformatrt.cpp=>common/string/strformatrt.c \
     71    ${PATH_ROOT}/src/VBox/Runtime/common/string/strformattype.cpp=>common/string/strformattype.c \
    7172    ${PATH_ROOT}/src/VBox/Runtime/common/string/strprintf.cpp=>common/string/strprintf.c \
    7273    ${PATH_ROOT}/src/VBox/Runtime/common/string/strtonum.cpp=>common/string/strtonum.c \
  • trunk/src/VBox/Runtime/Makefile.kmk

    r7169 r7183  
    188188        common/string/strformat.cpp \
    189189        common/string/strformatrt.cpp \
     190        common/string/strformattype.cpp \
    190191        common/string/string.cpp \
    191192        common/string/strprintf.cpp \
     
    566567        common/string/strformat.cpp \
    567568        common/string/strformatrt.cpp \
     569        common/string/strformattype.cpp \
    568570        common/string/string.cpp \
    569571        common/string/strprintf.cpp \
     
    766768        common/string/strformat.cpp \
    767769        common/string/strformatrt.cpp \
     770        common/string/strformattype.cpp \
    768771        common/string/strlen.cpp \
    769772        common/string/strncmp.cpp \
     
    861864        common/string/strformat.cpp \
    862865        common/string/strformatrt.cpp \
     866        common/string/strformattype.cpp \
    863867        common/string/strprintf.cpp \
    864868        common/string/strtonum.cpp \
     
    11101114        common/string/strformat.cpp \
    11111115        common/string/strformatrt.cpp \
     1116        common/string/strformattype.cpp \
    11121117        common/string/strlen.cpp \
    11131118        common/string/strncmp.cpp \
  • trunk/src/VBox/Runtime/common/string/strformat.cpp

    r6296 r7183  
    770770                    case 'R':
    771771                    {
    772                         pszFormat--;
    773                         cch += rtstrFormatRt(pfnOutput, pvArgOutput, &pszFormat, &args, cchPrecision, cchWidth, fFlags, chArgSize);
     772                        if (*pszFormat != '[')
     773                        {
     774                            pszFormat--;
     775                            cch += rtstrFormatRt(pfnOutput, pvArgOutput, &pszFormat, &args, cchPrecision, cchWidth, fFlags, chArgSize);
     776                        }
     777                        else
     778                        {
     779                            pszFormat--;
     780                            cch += rtstrFormatType(pfnOutput, pvArgOutput, &pszFormat, &args, cchPrecision, cchWidth, fFlags, chArgSize);
     781                        }
    774782                        break;
    775783                    }
  • trunk/src/VBox/Runtime/include/internal/string.h

    r5999 r7183  
    5252#endif
    5353size_t rtstrFormatRt(PFNRTSTROUTPUT pfnOutput, void *pvArgOutput, const char **ppszFormat, va_list *pArgs, int cchWidth, int cchPrecision, unsigned fFlags, char chArgSize);
     54size_t rtstrFormatType(PFNRTSTROUTPUT pfnOutput, void *pvArgOutput, const char **ppszFormat, va_list *pArgs, int cchWidth, int cchPrecision, unsigned fFlags, char chArgSize);
    5455
    5556__END_DECLS
  • trunk/src/VBox/Runtime/testcase/tstStrFormat.cpp

    r5999 r7183  
    3434#include <iprt/stream.h>
    3535
     36/*******************************************************************************
     37*   Global Variables                                                           *
     38*******************************************************************************/
     39static int g_cErrors = 0;
     40
     41
     42/** See FNRTSTRFORMATTYPE. */
     43static DECLCALLBACK(size_t) TstType(PFNRTSTROUTPUT pfnOutput, void *pvArgOutput,
     44                                    const char *pszType, void const *pvValue,
     45                                    int cchWidth, int cchPrecision, unsigned fFlags,
     46                                    void *pvUser)
     47{
     48    /* validate */
     49    if (strncmp(pszType, "type", 4))
     50    {
     51        RTPrintf("tstStrFormat: pszType=%s expected 'typeN'\n", pszType);
     52        g_cErrors++;
     53    }
     54
     55    int iType = pszType[4] - '0';
     56    if ((uintptr_t)pvUser != (uintptr_t)TstType + iType)
     57    {
     58        RTPrintf("tstStrFormat: pvValue=%p expected %p\n", pvUser, (void *)((uintptr_t)TstType + iType));
     59        g_cErrors++;
     60    }
     61
     62    /* format */
     63    size_t cch = pfnOutput(pvArgOutput, pszType, 5);
     64    cch += pfnOutput(pvArgOutput, "=", 1);
     65    char szNum[64];
     66    size_t cchNum = RTStrFormatNumber(szNum, (uintptr_t)pvValue, 0, cchWidth, cchPrecision, fFlags);
     67    cch += pfnOutput(pvArgOutput, szNum, cchNum);
     68    return cch;
     69}
     70
     71
    3672int main()
    3773{
    3874    RTR3Init();
    3975
    40     int         cErrors = 0;
    4176    uint32_t    u32 = 0x010;
    4277    uint64_t    u64 = 0x100;
     
    4984        RTPrintf("error: '%s'\n"
    5085               "wanted 'u32=16 u64=256 u64=0x100'\n", szStr);
    51         cErrors++;
     86        g_cErrors++;
    5287    }
    5388
     
    6095                 "wanted 'u64=0x8070605040302010 42=42 u64=8102081627430068240 42=42'\n", szStr);
    6196        RTPrintf("%d\n", (int)(u64 % 10));
    62         cErrors++;
     97        g_cErrors++;
    6398    }
    6499
     
    72107                 "wanted 'u64=0x8070605040302010 42=42 u64=9255003132036915216 42=42 u64=-9191740941672636400 42=42'\n", szStr);
    73108        RTPrintf("%d\n", (int)(u64 % 10));
    74         cErrors++;
     109        g_cErrors++;
    75110    }
    76111
     
    82117        RTPrintf("error: '%s'\n"
    83118                 "wanted 'u64=0xa0000000 42=42 u64=2684354560 42=42'\n", szStr);
    84         cErrors++;
     119        g_cErrors++;
    85120    }
    86121
     
    96131                 "expected: '%s'\n",
    97132                 szStr, szCorrect);
    98         cErrors++;
     133        g_cErrors++;
    99134    }
    100135
     
    105140    {
    106141        RTPrintf("error: RTStrAPrintf failed, cch2=%d\n", cch2);
    107         cErrors++;
     142        g_cErrors++;
    108143    }
    109144    else if (strcmp(psz, "Hey there! This is a test!"))
     
    113148                 "wanted: 'Hey there! This is a test!'\n",
    114149               psz);
    115         cErrors++;
     150        g_cErrors++;
    116151    }
    117152    else if ((int)strlen(psz) != cch2)
    118153    {
    119154        RTPrintf("error: RTStrAPrintf failed, cch2 == %d expected %u\n", cch2, strlen(psz));
    120         cErrors++;
     155        g_cErrors++;
    121156    }
    122157    RTStrFree(psz);
     
    131166                     "    wanted: '%s'\n", \
    132167                     __LINE__, fmt, szStr, out " 42=42 " out " 42=42"); \
    133             cErrors++; \
     168            g_cErrors++; \
    134169        } \
    135170        else if (cch != sizeof(out " 42=42 " out " 42=42") - 1) \
     
    137172            RTPrintf("error(%d): Invalid length %d returned, expected %u!\n", \
    138173                     __LINE__, cch, sizeof(out " 42=42 " out " 42=42") - 1); \
    139             cErrors++; \
     174            g_cErrors++; \
    140175        } \
    141176    } while (0)
     
    314349                 "expected: '%s'\n",
    315350                 szStr, szCorrect);
    316         cErrors++;
     351        g_cErrors++;
    317352    }
    318353
     
    351386        RTPrintf("error:    '%s'\n" \
    352387                 "expected: '%s'\n", szStr, Correct); \
    353         cErrors++; \
     388        g_cErrors++; \
    354389    }
    355390
     
    394429#endif
    395430
     431    /*
     432     * Custom types.
     433     */
     434#define CHECK(expr)  do { if (!(expr)) { RTPrintf("tstEnv: error line %d: %s\n", __LINE__, #expr); g_cErrors++; } } while (0)
     435#define CHECK_RC(expr, rc)  do { int rc2 = expr; if (rc2 != (rc)) { RTPrintf("tstEnv: error line %d: %s -> %Rrc expected %Rrc\n", __LINE__, #expr, rc2, rc); g_cErrors++; } } while (0)
     436
     437    CHECK_RC(RTStrFormatTypeRegister("type3", TstType, (void *)((uintptr_t)TstType)), VINF_SUCCESS);
     438    CHECK_RC(RTStrFormatTypeSetUser("type3",           (void *)((uintptr_t)TstType + 3)), VINF_SUCCESS);
     439    cch = RTStrPrintf(szStr, sizeof(szStr), "%R[type3]", (void *)1);
     440    CHECKSTR("type3=1");
     441
     442    CHECK_RC(RTStrFormatTypeRegister("type1", TstType, (void *)((uintptr_t)TstType)), VINF_SUCCESS);
     443    CHECK_RC(RTStrFormatTypeSetUser("type1",           (void *)((uintptr_t)TstType + 1)), VINF_SUCCESS);
     444    cch = RTStrPrintf(szStr, sizeof(szStr), "%R[type3] %R[type1]", (void *)1, (void *)2);
     445    CHECKSTR("type3=1 type1=2");
     446
     447    CHECK_RC(RTStrFormatTypeRegister("type4", TstType, (void *)((uintptr_t)TstType)), VINF_SUCCESS);
     448    CHECK_RC(RTStrFormatTypeSetUser("type4",           (void *)((uintptr_t)TstType + 4)), VINF_SUCCESS);
     449    cch = RTStrPrintf(szStr, sizeof(szStr), "%R[type3] %R[type1] %R[type4]", (void *)1, (void *)2, (void *)3);
     450    CHECKSTR("type3=1 type1=2 type4=3");
     451
     452    CHECK_RC(RTStrFormatTypeRegister("type2", TstType, (void *)((uintptr_t)TstType)), VINF_SUCCESS);
     453    CHECK_RC(RTStrFormatTypeSetUser("type2",           (void *)((uintptr_t)TstType + 2)), VINF_SUCCESS);
     454    cch = RTStrPrintf(szStr, sizeof(szStr), "%R[type3] %R[type1] %R[type4] %R[type2]", (void *)1, (void *)2, (void *)3, (void *)4);
     455    CHECKSTR("type3=1 type1=2 type4=3 type2=4");
     456
     457    CHECK_RC(RTStrFormatTypeRegister("type5", TstType, (void *)((uintptr_t)TstType)), VINF_SUCCESS);
     458    CHECK_RC(RTStrFormatTypeSetUser("type5",           (void *)((uintptr_t)TstType + 5)), VINF_SUCCESS);
     459    cch = RTStrPrintf(szStr, sizeof(szStr), "%R[type3] %R[type1] %R[type4] %R[type2] %R[type5]", (void *)1, (void *)2, (void *)3, (void *)4, (void *)5);
     460    CHECKSTR("type3=1 type1=2 type4=3 type2=4 type5=5");
     461
     462    CHECK_RC(RTStrFormatTypeSetUser("type1",           (void *)((uintptr_t)TstType + 1)), VINF_SUCCESS);
     463    CHECK_RC(RTStrFormatTypeSetUser("type2",           (void *)((uintptr_t)TstType + 2)), VINF_SUCCESS);
     464    CHECK_RC(RTStrFormatTypeSetUser("type3",           (void *)((uintptr_t)TstType + 3)), VINF_SUCCESS);
     465    CHECK_RC(RTStrFormatTypeSetUser("type4",           (void *)((uintptr_t)TstType + 4)), VINF_SUCCESS);
     466    CHECK_RC(RTStrFormatTypeSetUser("type5",           (void *)((uintptr_t)TstType + 5)), VINF_SUCCESS);
     467
     468    cch = RTStrPrintf(szStr, sizeof(szStr), "%R[type3] %R[type1] %R[type4] %R[type2] %R[type5]", (void *)10, (void *)20, (void *)30, (void *)40, (void *)50);
     469    CHECKSTR("type3=10 type1=20 type4=30 type2=40 type5=50");
     470
     471    CHECK_RC(RTStrFormatTypeDeregister("type2"), VINF_SUCCESS);
     472    cch = RTStrPrintf(szStr, sizeof(szStr), "%R[type3] %R[type1] %R[type4] %R[type5]", (void *)10, (void *)20, (void *)30, (void *)40);
     473    CHECKSTR("type3=10 type1=20 type4=30 type5=40");
     474
     475    CHECK_RC(RTStrFormatTypeDeregister("type5"), VINF_SUCCESS);
     476    cch = RTStrPrintf(szStr, sizeof(szStr), "%R[type3] %R[type1] %R[type4]", (void *)10, (void *)20, (void *)30);
     477    CHECKSTR("type3=10 type1=20 type4=30");
     478
     479    CHECK_RC(RTStrFormatTypeDeregister("type4"), VINF_SUCCESS);
     480    cch = RTStrPrintf(szStr, sizeof(szStr), "%R[type3] %R[type1]", (void *)10, (void *)20);
     481    CHECKSTR("type3=10 type1=20");
     482
     483    CHECK_RC(RTStrFormatTypeDeregister("type1"), VINF_SUCCESS);
     484    cch = RTStrPrintf(szStr, sizeof(szStr), "%R[type3]", (void *)10);
     485    CHECKSTR("type3=10");
     486
     487    CHECK_RC(RTStrFormatTypeDeregister("type3"), VINF_SUCCESS);
    396488
    397489    /*
    398490     * Summarize and exit.
    399491     */
    400     if (!cErrors)
     492    if (!g_cErrors)
    401493        RTPrintf("tstStrFormat: SUCCESS\n");
    402494    else
    403         RTPrintf("tstStrFormat: FAILED - %d errors\n", cErrors);
    404     return !!cErrors;
     495        RTPrintf("tstStrFormat: FAILED - %d errors\n", g_cErrors);
     496    return !!g_cErrors;
    405497}
    406498
Note: See TracChangeset for help on using the changeset viewer.

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