VirtualBox

Ignore:
Timestamp:
Apr 28, 2020 4:05:00 PM (5 years ago)
Author:
vboxsync
Message:

IPRT,++: Apply bldprog-strtab.h and friends to the IPRT status message database (errmsg.cpp) to reduce size. The interface (RTErrMsg*) has been reworked as we no longer have C-strings in the database, but 'compressed' string w/o zero terminators. bugref:9726

Location:
trunk/src/VBox/Runtime/common/err
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/common/err/errmsg-sorter.cpp

    r83984 r84054  
    3838
    3939
     40#define ERRMSG_WITH_STRTAB
     41#ifdef ERRMSG_WITH_STRTAB
     42/*
     43 * Include the string table code.
     44 */
     45# define BLDPROG_STRTAB_MAX_STRLEN           512
     46# define BLDPROG_STRTAB_WITH_COMPRESSION
     47# define BLDPROG_STRTAB_PURE_ASCII
     48# define BLDPROG_STRTAB_WITH_CAMEL_WORDS
     49# include <iprt/bldprog-strtab-template.cpp.h>
     50#endif
     51
     52
     53/*********************************************************************************************************************************
     54*   Structures and Typedefs                                                                                                      *
     55*********************************************************************************************************************************/
     56/** Used for raw-input and sorting. */
     57typedef struct RTSTATUSMSGINT1
     58{
     59    /** Pointer to the short message string. */
     60    const char     *pszMsgShort;
     61    /** Pointer to the full message string. */
     62    const char     *pszMsgFull;
     63    /** Pointer to the define string. */
     64    const char     *pszDefine;
     65    /** Status code number. */
     66    int             iCode;
     67    /** Set if duplicate. */
     68    bool            fDuplicate;
     69} RTSTATUSMSGINT1;
     70typedef RTSTATUSMSGINT1 *PRTSTATUSMSGINT1;
     71
     72
     73/** This is used when building the string table and printing it. */
     74typedef struct RTSTATUSMSGINT2
     75{
     76    /** The short message string. */
     77    BLDPROGSTRING   MsgShort;
     78    /** The full message string. */
     79    BLDPROGSTRING   MsgFull;
     80    /** The define string. */
     81    BLDPROGSTRING   Define;
     82    /** Pointer to the define string. */
     83    const char     *pszDefine;
     84    /** Status code number. */
     85    int             iCode;
     86} RTSTATUSMSGINT2;
     87typedef RTSTATUSMSGINT2 *PRTSTATUSMSGINT2;
     88
     89
    4090/*********************************************************************************************************************************
    4191*   Global Variables                                                                                                             *
    4292*********************************************************************************************************************************/
    43 static RTSTATUSMSG g_aStatusMsgs[] =
     93static const char *g_pszProgName = "errmsg-sorter";
     94static RTSTATUSMSGINT1 g_aStatusMsgs[] =
    4495{
    4596#if !defined(IPRT_NO_ERROR_DATA) && !defined(DOXYGEN_RUNNING)
     
    51102
    52103
     104static RTEXITCODE error(const char *pszFormat,  ...)
     105{
     106    va_list va;
     107    va_start(va, pszFormat);
     108    fprintf(stderr, "%s: error: ", g_pszProgName);
     109    vfprintf(stderr, pszFormat, va);
     110    va_end(va);
     111    return RTEXITCODE_FAILURE;
     112}
     113
     114
    53115/** qsort callback. */
    54116static int CompareErrMsg(const void *pv1, const void *pv2)
    55117{
    56     PCRTSTATUSMSG p1 = (PCRTSTATUSMSG)pv1;
    57     PCRTSTATUSMSG p2 = (PCRTSTATUSMSG)pv2;
     118    PRTSTATUSMSGINT1 p1 = (PRTSTATUSMSGINT1)pv1;
     119    PRTSTATUSMSGINT1 p2 = (PRTSTATUSMSGINT1)pv2;
    58120    int iDiff;
    59121    if (p1->iCode < p2->iCode)
     
    103165
    104166
    105 /**
    106  * Escapes @a pszString using @a pszBuf as needed.
    107  * @note Duplicated in errmsg-sorter.cpp.
    108  */
    109 static const char *EscapeString(const char *pszString, char *pszBuf, size_t cbBuf)
    110 {
    111     if (strpbrk(pszString, "\n\t\r\"\\") == NULL)
    112         return pszString;
    113 
    114     char *pszDst = pszBuf;
    115     char  ch;
    116     do
    117     {
    118         ch = *pszString++;
    119         switch (ch)
    120         {
    121             default:
    122                 *pszDst++ = ch;
    123                 break;
    124             case '\\':
    125             case '"':
    126                 *pszDst++ = '\\';
    127                 *pszDst++ = ch;
    128                 break;
    129             case '\n':
    130                 *pszDst++ = '\\';
    131                 *pszDst++ = 'n';
    132                 break;
    133             case '\t':
    134                 *pszDst++ = '\\';
    135                 *pszDst++ = 't';
    136                 break;
    137             case '\r':
    138                 break; /* drop it */
    139         }
    140     } while (ch);
    141 
    142     if ((uintptr_t)(pszDst - pszBuf) > cbBuf)
    143         fprintf(stderr, "Escape buffer overrun!\n");
    144 
    145     return pszBuf;
    146 }
    147 
    148 
    149167int main(int argc, char **argv)
    150168{
    151169    /*
    152      * Argument check.
     170     * Parse arguments.
    153171     */
    154     if (argc != 1 && argc != 2)
     172    enum { kMode_All, kMode_NoFullMsg, kMode_OnlyDefines } enmMode;
     173    if (argc == 3 && strcmp(argv[1], "--all") == 0)
     174        enmMode = kMode_All;
     175    else if (argc == 3 && strcmp(argv[1], "--no-full-msg") == 0)
     176        enmMode = kMode_NoFullMsg;
     177    else if (argc == 3 && strcmp(argv[1], "--only-defines") == 0)
     178        enmMode = kMode_OnlyDefines;
     179    else
    155180    {
    156181        fprintf(stderr,
    157182                "syntax error!\n"
    158                 "Usage: %s [outfile]\n", argv[0]);
     183                "Usage: %s <--all|--no-full-msg|--only-defines> <outfile>\n", argv[0]);
    159184        return RTEXITCODE_SYNTAX;
    160185    }
     186    const char * const pszOutFile = argv[2];
    161187
    162188    /*
    163      * Sort the table.
     189     * Sort the table and mark duplicates.
    164190     */
    165191    qsort(g_aStatusMsgs, RT_ELEMENTS(g_aStatusMsgs), sizeof(g_aStatusMsgs[0]), CompareErrMsg);
     192
     193    int rcExit = RTEXITCODE_SUCCESS;
     194    int iPrev  = INT32_MAX;
     195    for (size_t i = 0; i < RT_ELEMENTS(g_aStatusMsgs); i++)
     196    {
     197        /* Deal with duplicates, trying to eliminate unnecessary *_FIRST, *_LAST,
     198           *_LOWEST, and *_HIGHEST entries as well as some deliberate duplicate entries.
     199           This means we need to look forward and backwards here. */
     200        PRTSTATUSMSGINT1 pMsg = &g_aStatusMsgs[i];
     201        if (pMsg->iCode == iPrev && i != 0)
     202        {
     203            if (IgnoreDuplicateDefine(pMsg->pszDefine))
     204            {
     205                pMsg->fDuplicate = true;
     206                continue;
     207            }
     208            PRTSTATUSMSGINT1 pPrev = &g_aStatusMsgs[i - 1];
     209            rcExit = error("Duplicate value %d - %s and %s\n", iPrev, pMsg->pszDefine, pPrev->pszDefine);
     210        }
     211        else if (i + 1 < RT_ELEMENTS(g_aStatusMsgs))
     212        {
     213            PRTSTATUSMSGINT1 pNext = &g_aStatusMsgs[i];
     214            if (   pMsg->iCode == pNext->iCode
     215                && IgnoreDuplicateDefine(pMsg->pszDefine))
     216            {
     217                pMsg->fDuplicate = true;
     218                continue;
     219            }
     220        }
     221        iPrev = pMsg->iCode;
     222        pMsg->fDuplicate = false;
     223    }
     224
     225    /*
     226     * Create a string table for it all.
     227     */
     228    BLDPROGSTRTAB StrTab;
     229    if (!BldProgStrTab_Init(&StrTab, RT_ELEMENTS(g_aStatusMsgs) * 3))
     230        return error("Out of memory!\n");
     231
     232    static RTSTATUSMSGINT2 s_aStatusMsgs2[RT_ELEMENTS(g_aStatusMsgs)];
     233    size_t                 cStatusMsgs = 0;
     234    for (size_t i = 0; i < RT_ELEMENTS(g_aStatusMsgs); i++)
     235    {
     236        if (!g_aStatusMsgs[i].fDuplicate)
     237        {
     238            s_aStatusMsgs2[cStatusMsgs].iCode     = g_aStatusMsgs[i].iCode;
     239            s_aStatusMsgs2[cStatusMsgs].pszDefine = g_aStatusMsgs[i].pszDefine;
     240            BldProgStrTab_AddStringDup(&StrTab, &s_aStatusMsgs2[cStatusMsgs].Define, g_aStatusMsgs[i].pszDefine);
     241            if (enmMode != kMode_OnlyDefines)
     242            {
     243                BldProgStrTab_AddStringDup(&StrTab, &s_aStatusMsgs2[cStatusMsgs].MsgShort, g_aStatusMsgs[i].pszMsgShort);
     244                if (enmMode == kMode_All)
     245                    BldProgStrTab_AddStringDup(&StrTab, &s_aStatusMsgs2[cStatusMsgs].MsgFull, g_aStatusMsgs[i].pszMsgFull);
     246            }
     247            cStatusMsgs++;
     248        }
     249    }
     250
     251    if (!BldProgStrTab_CompileIt(&StrTab, true))
     252        return error("BldProgStrTab_CompileIt failed!\n");
    166253
    167254    /*
    168255     * Prepare output file.
    169256     */
    170     int rcExit = RTEXITCODE_FAILURE;
    171     FILE *pOut = stdout;
    172     if (argc > 1)
    173         pOut = fopen(argv[1], "wt");
     257    FILE *pOut = fopen(pszOutFile, "wt");
    174258    if (pOut)
    175259    {
     
    177261         * Print the table.
    178262         */
    179         static char s_szMsgTmp1[_32K];
    180         static char s_szMsgTmp2[_64K];
    181         int iPrev = INT32_MAX;
    182         for (size_t i = 0; i < RT_ELEMENTS(g_aStatusMsgs); i++)
    183         {
    184             PCRTSTATUSMSG pMsg = &g_aStatusMsgs[i];
    185 
    186             /* Deal with duplicates, trying to eliminate unnecessary *_FIRST, *_LAST,
    187                *_LOWEST, and *_HIGHEST entries as well as some deliberate duplicate entries.
    188                This means we need to look forward and backwards here. */
    189             if (pMsg->iCode == iPrev && i != 0)
    190             {
    191                 if (IgnoreDuplicateDefine(pMsg->pszDefine))
    192                     continue;
    193                 PCRTSTATUSMSG pPrev = &g_aStatusMsgs[i - 1];
    194                 fprintf(stderr, "%s: warning: Duplicate value %d - %s and %s\n",
    195                         argv[0], iPrev, pMsg->pszDefine, pPrev->pszDefine);
    196             }
    197             else if (i + 1 < RT_ELEMENTS(g_aStatusMsgs))
    198             {
    199                 PCRTSTATUSMSG pNext = &g_aStatusMsgs[i];
    200                 if (   pMsg->iCode == pNext->iCode
    201                     && IgnoreDuplicateDefine(pMsg->pszDefine))
    202                     continue;
    203             }
    204             iPrev = pMsg->iCode;
    205 
    206             /* Produce the output: */
    207             fprintf(pOut, "/*%8d:*/ ENTRY(\"%s\", \"%s\", \"%s\", %s),\n",
    208                     pMsg->iCode,
    209                     EscapeString(pMsg->pszMsgShort, s_szMsgTmp1, sizeof(s_szMsgTmp1)),
    210                     EscapeString(pMsg->pszMsgFull, s_szMsgTmp2, sizeof(s_szMsgTmp2)),
    211                     pMsg->pszDefine, pMsg->pszDefine);
    212 
    213         }
     263        fprintf(pOut,
     264                "\n"
     265                "typedef struct RTMSGENTRYINT\n"
     266                "{\n"
     267                "    uint32_t offDefine : 20;\n"
     268                "    uint32_t cchDefine : 9;\n"
     269                "%s"
     270                "%s"
     271                "    int32_t  iCode;\n"
     272                "} RTMSGENTRYINT;\n"
     273                "typedef RTMSGENTRYINT *PCRTMSGENTRYINT;\n"
     274                "\n"
     275                "static const RTMSGENTRYINT g_aStatusMsgs[] =\n"
     276                "{\n"
     277                ,
     278                enmMode != kMode_OnlyDefines
     279                ? "    uint32_t offMsgShort : 23;\n"
     280                  "    uint32_t cchMsgShort : 9;\n" : "",
     281                enmMode == kMode_All
     282                ? "    uint32_t offMsgFull  : 23;\n"
     283                  "    uint32_t cchMsgFull  : 9;\n" : "");
     284
     285        if (enmMode == kMode_All)
     286            for (size_t i = 0; i < cStatusMsgs; i++)
     287                fprintf(pOut, "/*%8d:*/ { %#08x, %3u, %#08x, %3u, %#08x, %3u, %s },\n",
     288                        s_aStatusMsgs2[i].iCode,
     289                        s_aStatusMsgs2[i].Define.offStrTab,
     290                        (unsigned)s_aStatusMsgs2[i].Define.cchString,
     291                        s_aStatusMsgs2[i].MsgShort.offStrTab,
     292                        (unsigned)s_aStatusMsgs2[i].MsgShort.cchString,
     293                        s_aStatusMsgs2[i].MsgFull.offStrTab,
     294                        (unsigned)s_aStatusMsgs2[i].MsgFull.cchString,
     295                        s_aStatusMsgs2[i].pszDefine);
     296        else if (enmMode == kMode_NoFullMsg)
     297            for (size_t i = 0; i < cStatusMsgs; i++)
     298                fprintf(pOut, "/*%8d:*/ { %#08x, %3u, %#08x, %3u, %s },\n",
     299                        s_aStatusMsgs2[i].iCode,
     300                        s_aStatusMsgs2[i].Define.offStrTab,
     301                        (unsigned)s_aStatusMsgs2[i].Define.cchString,
     302                        s_aStatusMsgs2[i].MsgShort.offStrTab,
     303                        (unsigned)s_aStatusMsgs2[i].MsgShort.cchString,
     304                        s_aStatusMsgs2[i].pszDefine);
     305        else if (enmMode == kMode_OnlyDefines)
     306            for (size_t i = 0; i < cStatusMsgs; i++)
     307                fprintf(pOut, "/*%8d:*/ { %#08x, %3u, %s },\n",
     308                        s_aStatusMsgs2[i].iCode,
     309                        s_aStatusMsgs2[i].Define.offStrTab,
     310                        (unsigned)s_aStatusMsgs2[i].Define.cchString,
     311                        s_aStatusMsgs2[i].pszDefine);
     312        else
     313            return error("Unsupported message selection (%d)!\n", enmMode);
     314        fprintf(pOut,
     315                "};\n"
     316                "\n");
     317
     318        BldProgStrTab_WriteStringTable(&StrTab, pOut, "static ", "g_", "StatusMsgStrTab");
    214319
    215320        /*
    216321         * Close the output file and we're done.
    217322         */
    218         if (fclose(pOut) == 0)
    219             rcExit = RTEXITCODE_SUCCESS;
    220         else
    221             fprintf(stderr, "%s: Failed to flush/close '%s' after writing it!\n", argv[0], argv[1]);
     323        fflush(pOut);
     324        if (ferror(pOut))
     325            rcExit = error("Error writing '%s'!\n", pszOutFile);
     326        if (fclose(pOut) != 0)
     327            rcExit = error("Failed to close '%s' after writing it!\n", pszOutFile);
    222328    }
    223329    else
    224         fprintf(stderr, "%s: Failed to open '%s' for writing!\n", argv[0], argv[1]);
     330        rcExit = error("Failed to open '%s' for writing!\n", pszOutFile);
    225331    return rcExit;
    226332}
  • trunk/src/VBox/Runtime/common/err/errmsg.cpp

    r83984 r84054  
    3636#include <VBox/err.h>
    3737
     38#include <iprt/bldprog-strtab.h>
     39
    3840
    3941/*********************************************************************************************************************************
    4042*   Defined Constants And Macros                                                                                                 *
    4143*********************************************************************************************************************************/
    42 #ifdef IPRT_ERRMSG_DEFINES_ONLY
    43 # define ENTRY(a_pszMsgShort, a_pszMsgFull, a_pszDefine, a_iCode) \
    44     { a_pszDefine, a_pszDefine, a_pszDefine, a_iCode }
    45 #elif defined(IN_RT_STATIC) /* Skip the full message in static builds to save space. */
    46 # define ENTRY(a_pszMsgShort, a_pszMsgFull, a_pszDefine, a_iCode) \
    47     { a_pszMsgShort, a_pszMsgShort, a_pszDefine, a_iCode }
    48 #else
    49 # define ENTRY(a_pszMsgShort, a_pszMsgFull, a_pszDefine, a_iCode) \
    50     { a_pszMsgShort, a_pszMsgFull, a_pszDefine, a_iCode }
     44#if (defined(IN_RT_STATIC) || defined(IPRT_ERRMSG_DEFINES_ONLY)) && !defined(IPRT_ERRMSG_NO_FULL_MSG)
     45/** Skip the full message in static builds to save space.
     46 * This is defined when IPRT_ERRMSG_DEFINES_ONLY is defined. */
     47# define IPRT_ERRMSG_NO_FULL_MSG
    5148#endif
    5249
     
    5552*   Global Variables                                                                                                             *
    5653*********************************************************************************************************************************/
    57 /** Array of messages.
    58  * The data is generated by a sed script.
    59  */
    60 static const RTSTATUSMSG  g_aStatusMsgs[] =
    61 {
    62 #if !defined(IPRT_NO_ERROR_DATA) && !defined(DOXYGEN_RUNNING)
    63 # include "errmsgdata-sorted.h"
    64 #else
    65     { "Success.", "Success.", "VINF_SUCCESS", 0 },
    66 #endif
     54#ifdef IPRT_NO_ERROR_DATA
     55/* Cook data just for VINF_SUCCESS so that code below compiles fine. */
     56static const char            g_achStrTabData[] = { "VINF_SUCCESS" };
     57static const RTBLDPROGSTRTAB g_StatusMsgStrTab = { g_achStrTabData, sizeof(g_achStrTabData) - 1, 0, NULL };
     58static const struct
     59{
     60    int16_t     iCode;
     61    uint8_t     offDefine;
     62    uint8_t     cchDefine;
     63    uint8_t     offMsgShort;
     64    uint8_t     cchMsgShort;
     65    uint8_t     offMsgFull;
     66    uint8_t     cchMsgFull;
     67} g_aStatusMsgs[] =
     68{
     69    { VINF_SUCCESS, 0, 12, 0, 12, 0, 12, },
    6770};
    68 
    69 
    70 /** Temporary buffers to format unknown messages in.
    71  * @{
    72  */
    73 static char                 g_aszUnknownStr[8][64];
    74 static RTSTATUSMSG          g_aUnknownMsgs[8] =
    75 {
    76     { &g_aszUnknownStr[0][0], &g_aszUnknownStr[0][0], &g_aszUnknownStr[0][0], 0 },
    77     { &g_aszUnknownStr[1][0], &g_aszUnknownStr[1][0], &g_aszUnknownStr[1][0], 0 },
    78     { &g_aszUnknownStr[2][0], &g_aszUnknownStr[2][0], &g_aszUnknownStr[2][0], 0 },
    79     { &g_aszUnknownStr[3][0], &g_aszUnknownStr[3][0], &g_aszUnknownStr[3][0], 0 },
    80     { &g_aszUnknownStr[4][0], &g_aszUnknownStr[4][0], &g_aszUnknownStr[4][0], 0 },
    81     { &g_aszUnknownStr[5][0], &g_aszUnknownStr[5][0], &g_aszUnknownStr[5][0], 0 },
    82     { &g_aszUnknownStr[6][0], &g_aszUnknownStr[6][0], &g_aszUnknownStr[6][0], 0 },
    83     { &g_aszUnknownStr[7][0], &g_aszUnknownStr[7][0], &g_aszUnknownStr[7][0], 0 },
    84 };
    85 /** Last used index in g_aUnknownMsgs. */
    86 static volatile uint32_t    g_iUnknownMsgs;
    87 /** @} */
     71#elif defined(IPRT_ERRMSG_DEFINES_ONLY)
     72# include "errmsgdata-only-defines.h"
     73#elif defined(IPRT_ERRMSG_NO_FULL_MSG)
     74# include "errmsgdata-no-full-msg.h"
     75#else
     76# include "errmsgdata-all.h"
     77#endif
    8878
    8979
    9080/**
    91  * Get the message corresponding to a given status code.
     81 * Looks up the message table entry for @a rc.
    9282 *
    93  * @returns Pointer to read-only message description.
    94  * @param   rc      The status code.
    95  */
    96 RTDECL(PCRTSTATUSMSG) RTErrGet(int rc)
     83 * @returns index into g_aStatusMsgs on success, ~(size_t)0 if not found.
     84 * @param   rc      The status code to locate the entry for.
     85 */
     86static size_t rtErrLookup(int rc)
    9787{
    9888    /*
     
    121111        }
    122112        else
    123             return &g_aStatusMsgs[i];
     113            return i;
    124114    }
    125115
     
    129119#endif
    130120
    131     /*
    132      * Need to use the temporary stuff.
    133      */
    134     int iMsg = ASMAtomicXchgU32(&g_iUnknownMsgs, (g_iUnknownMsgs + 1) % RT_ELEMENTS(g_aUnknownMsgs));
    135     RTStrPrintf(&g_aszUnknownStr[iMsg][0], sizeof(g_aszUnknownStr[iMsg]), "Unknown Status %d (%#x)", rc, rc);
    136     return &g_aUnknownMsgs[iMsg];
    137 }
    138 RT_EXPORT_SYMBOL(RTErrGet);
    139 
     121    return ~(size_t)0;
     122}
     123
     124
     125RTDECL(bool)  RTErrIsKnown(int rc)
     126{
     127    return rtErrLookup(rc) != ~(size_t)0;
     128}
     129RT_EXPORT_SYMBOL(RTErrIsKnown);
     130
     131
     132RTDECL(ssize_t) RTErrQueryDefine(int rc, char *pszBuf, size_t cbBuf, bool fFailIfUnknown)
     133{
     134    size_t idx = rtErrLookup(rc);
     135    if (idx != ~(size_t)0)
     136        return RTBldProgStrTabQueryString(&g_StatusMsgStrTab,
     137                                          g_aStatusMsgs[idx].offDefine, g_aStatusMsgs[idx].cchDefine,
     138                                          pszBuf, cbBuf);
     139    if (fFailIfUnknown)
     140        return VERR_NOT_FOUND;
     141    return RTStrFormatU32(pszBuf, cbBuf, rc, 10, 0, 0, RTSTR_F_VALSIGNED);
     142}
     143RT_EXPORT_SYMBOL(RTErrQueryDefine);
     144
     145
     146/**
     147 * Helper for rtErrQueryMsgNotFound.
     148 */
     149DECLINLINE(ssize_t) rtErrQueryCopyHelper(char **ppszBuf, size_t *pcbBuf, const char *pszSrc, size_t cchSrc, ssize_t cchRet)
     150{
     151    char   *pszDst = *ppszBuf;
     152    size_t  cbDst  = *pcbBuf;
     153    if (cbDst > cchSrc)
     154    {
     155        memcpy(pszDst, pszSrc, cchSrc);
     156        cbDst   -= cchSrc;
     157        pszDst  += cchSrc;
     158        cchRet  += cchSrc;
     159        *pszDst  = '\0';
     160    }
     161    else
     162    {
     163        while (cbDst > 1 && cchSrc > 0)
     164        {
     165            *pszDst++ = *pszSrc++;
     166            cchSrc--;
     167            cbDst--;
     168        }
     169        if (cbDst > 0)
     170            *pszDst = '\0';
     171        cchRet = VERR_BUFFER_OVERFLOW;
     172    }
     173    *ppszBuf = pszDst;
     174    *pcbBuf  = cbDst;
     175    return cchRet;
     176}
     177
     178
     179/**
     180 * RTErrQueryMsgShort & RTErrQueryMsgFull helper.
     181 */
     182DECL_NO_INLINE(static, ssize_t) rtErrQueryMsgNotFound(int rc, char *pszBuf, size_t cbBuf)
     183{
     184    /* Unknown Status %d (%#x) */
     185    ssize_t cchRet = rtErrQueryCopyHelper(&pszBuf, &cbBuf, RT_STR_TUPLE("Unknown Status "), 0);
     186    char   szValue[64];
     187    size_t cchValue = (size_t)RTStrFormatU32(szValue, sizeof(szValue), rc, 10, 0, 0, RTSTR_F_VALSIGNED);
     188    cchRet = rtErrQueryCopyHelper(&pszBuf, &cbBuf, szValue, cchValue, cchRet);
     189    cchRet = rtErrQueryCopyHelper(&pszBuf, &cbBuf, RT_STR_TUPLE(" ("), cchRet);
     190    cchValue = (size_t)RTStrFormatU32(szValue, sizeof(szValue), rc, 16, 0, 0, RTSTR_F_SPECIAL);
     191    cchRet = rtErrQueryCopyHelper(&pszBuf, &cbBuf, szValue, cchValue, cchRet);
     192    cchRet = rtErrQueryCopyHelper(&pszBuf, &cbBuf, RT_STR_TUPLE(")"), cchRet);
     193    return cchRet;
     194}
     195
     196
     197RTDECL(ssize_t) RTErrQueryMsgShort(int rc, char *pszBuf, size_t cbBuf, bool fFailIfUnknown)
     198{
     199    size_t idx = rtErrLookup(rc);
     200    if (idx != ~(size_t)0)
     201#ifdef IPRT_ERRMSG_DEFINES_ONLY
     202        return RTBldProgStrTabQueryString(&g_StatusMsgStrTab,
     203                                          g_aStatusMsgs[idx].offDefine, g_aStatusMsgs[idx].cchDefine,
     204                                          pszBuf, cbBuf);
     205#else
     206    return RTBldProgStrTabQueryString(&g_StatusMsgStrTab,
     207                                      g_aStatusMsgs[idx].offMsgShort, g_aStatusMsgs[idx].cchMsgShort,
     208                                      pszBuf, cbBuf);
     209#endif
     210    if (fFailIfUnknown)
     211        return VERR_NOT_FOUND;
     212    return rtErrQueryMsgNotFound(rc, pszBuf, cbBuf);
     213}
     214RT_EXPORT_SYMBOL(RTErrQueryMsgShort);
     215
     216
     217RTDECL(ssize_t) RTErrQueryMsgFull(int rc, char *pszBuf, size_t cbBuf, bool fFailIfUnknown)
     218{
     219#if defined(IPRT_ERRMSG_DEFINES_ONLY) || defined(IPRT_ERRMSG_NO_FULL_MSG)
     220    return RTErrQueryMsgShort(rc, pszBuf, cbBuf, fFailIfUnknown);
     221#else
     222    size_t idx = rtErrLookup(rc);
     223    if (idx != ~(size_t)0)
     224        return RTBldProgStrTabQueryString(&g_StatusMsgStrTab,
     225                                          g_aStatusMsgs[idx].offMsgFull, g_aStatusMsgs[idx].cchMsgFull,
     226                                          pszBuf, cbBuf);
     227    if (fFailIfUnknown)
     228        return VERR_NOT_FOUND;
     229    return rtErrQueryMsgNotFound(rc, pszBuf, cbBuf);
     230#endif
     231}
     232RT_EXPORT_SYMBOL(RTErrQueryMsgShort);
     233
     234
     235RTDECL(size_t) RTErrFormatDefine(int rc, PFNRTSTROUTPUT pfnOutput, void *pvArgOutput, char *pszTmp, size_t cbTmp)
     236{
     237    size_t idx = rtErrLookup(rc);
     238    if (idx != ~(size_t)0)
     239        return RTBldProgStrTabQueryOutput(&g_StatusMsgStrTab,
     240                                          g_aStatusMsgs[idx].offDefine, g_aStatusMsgs[idx].cchDefine,
     241                                          pfnOutput, pvArgOutput);
     242    size_t cchValue = (size_t)RTStrFormatU32(pszTmp, cbTmp, rc, 10, 0, 0, RTSTR_F_VALSIGNED);
     243    return pfnOutput(pvArgOutput, pszTmp, cchValue);
     244}
     245RT_EXPORT_SYMBOL(RTErrFormatDefine);
     246
     247
     248/**
     249 * RTErrFormatMsgShort & RTErrFormatMsgFull helper.
     250 */
     251static size_t rtErrFormatMsgNotFound(int rc, PFNRTSTROUTPUT pfnOutput, void *pvArgOutput, char *pszTmp, size_t cbTmp)
     252{
     253    size_t cchRet = pfnOutput(pvArgOutput, RT_STR_TUPLE("Unknown Status "));
     254    size_t cchValue = (size_t)RTStrFormatU32(pszTmp, cbTmp, rc, 10, 0, 0, RTSTR_F_VALSIGNED);
     255    cchRet  += pfnOutput(pvArgOutput, pszTmp, cchValue);
     256    cchRet  += pfnOutput(pvArgOutput, RT_STR_TUPLE(" ("));
     257    cchValue = (size_t)RTStrFormatU32(pszTmp, cbTmp, rc, 16, 0, 0, RTSTR_F_SPECIAL);
     258    cchRet  += pfnOutput(pvArgOutput, pszTmp, cchValue);
     259    cchRet  += pfnOutput(pvArgOutput, RT_STR_TUPLE(")"));
     260    return cchRet;
     261}
     262
     263
     264RTDECL(size_t) RTErrFormatMsgShort(int rc, PFNRTSTROUTPUT pfnOutput, void *pvArgOutput, char *pszTmp, size_t cbTmp)
     265{
     266    size_t idx = rtErrLookup(rc);
     267    if (idx != ~(size_t)0)
     268#ifndef IPRT_ERRMSG_DEFINES_ONLY
     269        return RTBldProgStrTabQueryOutput(&g_StatusMsgStrTab,
     270                                          g_aStatusMsgs[idx].offMsgShort, g_aStatusMsgs[idx].cchMsgShort,
     271                                          pfnOutput, pvArgOutput);
     272#else
     273        return RTBldProgStrTabQueryOutput(&g_StatusMsgStrTab,
     274                                          g_aStatusMsgs[idx].offDefine, g_aStatusMsgs[idx].cchDefine,
     275                                          pfnOutput, pvArgOutput);
     276#endif
     277    return rtErrFormatMsgNotFound(rc, pfnOutput, pvArgOutput, pszTmp, cbTmp);
     278}
     279RT_EXPORT_SYMBOL(RTErrFormatMsgShort);
     280
     281
     282RTDECL(size_t) RTErrFormatMsgFull(int rc, PFNRTSTROUTPUT pfnOutput, void *pvArgOutput, char *pszTmp, size_t cbTmp)
     283{
     284#ifdef IPRT_ERRMSG_NO_FULL_MSG
     285    return RTErrFormatMsgShort(rc, pfnOutput, pvArgOutput, pszTmp, cbTmp);
     286#else
     287    size_t idx = rtErrLookup(rc);
     288    if (idx != ~(size_t)0)
     289        return RTBldProgStrTabQueryOutput(&g_StatusMsgStrTab,
     290                                          g_aStatusMsgs[idx].offMsgFull, g_aStatusMsgs[idx].cchMsgFull,
     291                                          pfnOutput, pvArgOutput);
     292    return rtErrFormatMsgNotFound(rc, pfnOutput, pvArgOutput, pszTmp, cbTmp);
     293#endif
     294}
     295RT_EXPORT_SYMBOL(RTErrFormatMsgFull);
     296
     297
     298RTDECL(size_t) RTErrFormatMsgAll(int rc, PFNRTSTROUTPUT pfnOutput, void *pvArgOutput, char *pszTmp, size_t cbTmp)
     299{
     300    size_t idx = rtErrLookup(rc);
     301    if (idx != ~(size_t)0)
     302    {
     303        size_t cchValue;
     304        size_t cchRet = RTBldProgStrTabQueryOutput(&g_StatusMsgStrTab,
     305                                                   g_aStatusMsgs[idx].offDefine, g_aStatusMsgs[idx].cchDefine,
     306                                                   pfnOutput, pvArgOutput);
     307        cchRet += pfnOutput(pvArgOutput, RT_STR_TUPLE(" ("));
     308        cchValue = (size_t)RTStrFormatU32(pszTmp, cbTmp, rc, 10, 0, 0, RTSTR_F_VALSIGNED);
     309        cchRet += pfnOutput(pvArgOutput, pszTmp, cchValue);
     310#ifdef IPRT_ERRMSG_DEFINES_ONLY
     311        cchRet += pfnOutput(pvArgOutput, RT_STR_TUPLE(")"));
     312#elif defined(IPRT_ERRMSG_NO_FULL_MSG)
     313        cchRet += pfnOutput(pvArgOutput, RT_STR_TUPLE(") - "));
     314        cchRet += RTBldProgStrTabQueryOutput(&g_StatusMsgStrTab,
     315                                             g_aStatusMsgs[idx].offMsgShort, g_aStatusMsgs[idx].cchMsgShort,
     316                                             pfnOutput, pvArgOutput);
     317#else
     318        cchRet += pfnOutput(pvArgOutput, RT_STR_TUPLE(") - "));
     319        cchRet += RTBldProgStrTabQueryOutput(&g_StatusMsgStrTab,
     320                                             g_aStatusMsgs[idx].offMsgFull, g_aStatusMsgs[idx].cchMsgFull,
     321                                             pfnOutput, pvArgOutput);
     322#endif
     323        return cchRet;
     324    }
     325    return rtErrFormatMsgNotFound(rc, pfnOutput, pvArgOutput, pszTmp, cbTmp);
     326}
     327RT_EXPORT_SYMBOL(RTErrFormatMsgAll);
     328
Note: See TracChangeset for help on using the changeset viewer.

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