VirtualBox

Changeset 83745 in vbox


Ignore:
Timestamp:
Apr 17, 2020 12:33:33 PM (5 years ago)
Author:
vboxsync
Message:

IPRT: Sort IPRT status messages so we can look them up using binary searching. bugref:8489

Location:
trunk/src/VBox/Runtime
Files:
5 edited
1 copied

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/.scm-settings

    r82968 r83745  
    2727--license-ose-dual
    2828
    29 
    3029/common/asn1/oiddb.cfg: --treat-as Makefile
     30/common/err/errmsg.cpp: --no-fix-err-h
    3131
    3232# Skip test certificates.
  • trunk/src/VBox/Runtime/Makefile.kmk

    r83744 r83745  
    36473647# errmsg.cpp depends on a generated header.
    36483648#
    3649 common/err/errmsg.cpp_DEPS = $(IPRT_OUT_DIR)/errmsgdata.h
     3649common/err/errmsg.cpp_DEPS = $(IPRT_OUT_DIR)/errmsgdata-sorted.h
    36503650common/err/errmsg.cpp_INCS = $(IPRT_OUT_DIR)
    36513651
     
    36733673        $(QUIET)$(REDIRECT) -wo $@ -- $(SED) -f $< $(filter %.h,$^)
    36743674
     3675$(IPRT_OUT_DIR)/errmsgdata-sorted.h.ts +| $(IPRT_OUT_DIR)/errmsgdata-sorted.h: \
     3676                $$(bldRTErrMsgSorter_1_TARGET)
     3677        $(call MSG_GENERATE,,$@,$<)
     3678        $(QUIET)"$<" "$(IPRT_OUT_DIR)/errmsgdata-sorted.h.ts"
     3679        $(QUIET)$(CP) --changed -fv -- "$(IPRT_OUT_DIR)/errmsgdata-sorted.h.ts" "$(IPRT_OUT_DIR)/errmsgdata-sorted.h"
     3680
     3681
    36753682$(IPRT_OUT_DIR)/errmsgwindata.h: \
    36763683                $(VBOX_PATH_RUNTIME_SRC)/common/err/errmsgcom.sed \
     
    36943701        $(QUIET)$(CP) --changed -fv -- "$(IPRT_OUT_DIR)/errmsgwindata-sorted.h.ts" "$(IPRT_OUT_DIR)/errmsgwindata-sorted.h"
    36953702
     3703
     3704#
     3705# Sorter for the IPRT status codes.
     3706#
     3707BLDPROGS.win += bldRTErrMsgSorter
     3708bldRTErrMsgSorter_TEMPLATE = VBoxBldProg
     3709bldRTErrMsgSorter_INCS     = $(IPRT_OUT_DIR)
     3710bldRTErrMsgSorter_DEPS     = $(IPRT_OUT_DIR)/errmsgdata.h
     3711bldRTErrMsgSorter_SOURCES  = common/err/errmsg-sorter.cpp
     3712
    36963713#
    36973714# Sorter for the windows error codes.
     
    36993716BLDPROGS.win += bldRTErrMsgWinSorter
    37003717bldRTErrMsgWinSorter_TEMPLATE = VBoxBldProg
    3701 bldRTErrMsgWinSorter_SOURCES  = win/errmsgwin-sorter.cpp
    3702 win/errmsgwin-sorter.cpp_INCS = $(IPRT_OUT_DIR)
    3703 win/errmsgwin-sorter.cpp_DEPS = \
     3718bldRTErrMsgWinSorter_INCS     = $(IPRT_OUT_DIR)
     3719bldRTErrMsgWinSorter_DEPS     = \
    37043720        $(IPRT_OUT_DIR)/errmsgwindata.h \
    37053721        $(IPRT_OUT_DIR)/errmsgvboxcomdata.h
     3722bldRTErrMsgWinSorter_SOURCES  = win/errmsgwin-sorter.cpp
    37063723
    37073724
  • trunk/src/VBox/Runtime/common/err/errmsg-sorter.cpp

    r83744 r83745  
    11/* $Id$ */
    22/** @file
    3  * IPRT - Status code messages, Windows, sorter build program.
     3 * IPRT - Status code messages, sorter build program.
    44 */
    55
     
    2929*   Header Files                                                                                                                 *
    3030*********************************************************************************************************************************/
    31 #include <iprt/win/windows.h>
    32 
    33 #include <iprt/errcore.h>
     31#include <iprt/err.h>
    3432#include <iprt/asm.h>
    3533#include <iprt/string.h>
     34#include <VBox/err.h>
    3635
    3736#include <stdio.h>
    3837#include <stdlib.h>
    39 
    40 
    41 /*********************************************************************************************************************************
    42 *   Defined Constants And Macros                                                                                                 *
    43 *********************************************************************************************************************************/
    44 /* This is define casts the result to DWORD, whereas HRESULT and RTWINERRMSG
    45    are using long, causing newer compilers to complain. */
    46 #undef _NDIS_ERROR_TYPEDEF_
    47 #define _NDIS_ERROR_TYPEDEF_(lErr) (long)(lErr)
    48 
    49 
    50 /*********************************************************************************************************************************
    51 *   Defined Constants And Macros                                                                                                 *
    52 *********************************************************************************************************************************/
    53 typedef long VBOXSTATUSTYPE; /* used by errmsgvboxcomdata.h */
    5438
    5539
     
    5741*   Global Variables                                                                                                             *
    5842*********************************************************************************************************************************/
    59 static RTWINERRMSG g_aStatusMsgs[] =
     43static RTSTATUSMSG g_aStatusMsgs[] =
    6044{
    6145#if !defined(IPRT_NO_ERROR_DATA) && !defined(DOXYGEN_RUNNING)
    62 # include "errmsgwindata.h"
    63 # if defined(VBOX) && !defined(IN_GUEST)
    64 #  include "errmsgvboxcomdata.h"
    65 # endif
     46# include "errmsgdata.h"
     47#else
     48    { "Success.", "Success.", "VINF_SUCCESS", 0 },
    6649#endif
    67     { "Success.", "ERROR_SUCCESS", 0 },
    6850};
    6951
    7052
    7153/** qsort callback. */
    72 static int CompareWinErrMsg(const void *pv1, const void *pv2)
    73 {
    74     PCRTWINERRMSG p1 = (PCRTWINERRMSG)pv1;
    75     PCRTWINERRMSG p2 = (PCRTWINERRMSG)pv2;
     54static int CompareErrMsg(const void *pv1, const void *pv2)
     55{
     56    PCRTSTATUSMSG p1 = (PCRTSTATUSMSG)pv1;
     57    PCRTSTATUSMSG p2 = (PCRTSTATUSMSG)pv2;
    7658    int iDiff;
    7759    if (p1->iCode < p2->iCode)
     
    8567
    8668
     69/**
     70 * Checks whether @a pszDefine is a deliberate duplicate define that should be
     71 * omitted.
     72 */
     73static bool IgnoreDuplicateDefine(const char *pszDefine)
     74{
     75    size_t const cchDefine = strlen(pszDefine);
     76
     77    static const RTSTRTUPLE s_aTails[] =
     78    {
     79        { RT_STR_TUPLE("_FIRST") },
     80        { RT_STR_TUPLE("_LAST") },
     81        { RT_STR_TUPLE("_HIGEST") },
     82        { RT_STR_TUPLE("_LOWEST") },
     83    };
     84    for (size_t i = 0; i < RT_ELEMENTS(s_aTails); i++)
     85        if (   cchDefine > s_aTails[i].cch
     86            && memcmp(&pszDefine[cchDefine - s_aTails[i].cch], s_aTails[i].psz, s_aTails[i].cch) == 0)
     87            return true;
     88
     89    static const RTSTRTUPLE s_aDeliberateOrSilly[] =
     90    {
     91        { RT_STR_TUPLE("VERR_VRDP_TIMEOUT") },
     92        { RT_STR_TUPLE("VINF_VRDP_SUCCESS") },
     93        { RT_STR_TUPLE("VWRN_CONTINUE_RECOMPILE") },
     94        { RT_STR_TUPLE("VWRN_PATM_CONTINUE_SEARCH") },
     95    };
     96    for (size_t i = 0; i < RT_ELEMENTS(s_aDeliberateOrSilly); i++)
     97        if (   cchDefine == s_aDeliberateOrSilly[i].cch
     98            && memcmp(pszDefine, s_aDeliberateOrSilly[i].psz, cchDefine) == 0)
     99            return true;
     100
     101    return false;
     102}
     103
     104
     105/**
     106 * Escapes @a pszString using @a pszBuf as needed.
     107 * @note Duplicated in errmsg-sorter.cpp.
     108 */
     109static 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
    87149int main(int argc, char **argv)
    88150{
     
    101163     * Sort the table.
    102164     */
    103     qsort(g_aStatusMsgs, RT_ELEMENTS(g_aStatusMsgs), sizeof(g_aStatusMsgs[0]), CompareWinErrMsg);
     165    qsort(g_aStatusMsgs, RT_ELEMENTS(g_aStatusMsgs), sizeof(g_aStatusMsgs[0]), CompareErrMsg);
    104166
    105167    /*
     
    115177         * Print the table.
    116178         */
    117         static char s_szMsgTmp[_256K];
    118         long iPrev = (long)0x80000000;
     179        static char s_szMsgTmp1[_32K];
     180        static char s_szMsgTmp2[_64K];
     181        int iPrev = INT32_MAX;
    119182        for (size_t i = 0; i < RT_ELEMENTS(g_aStatusMsgs); i++)
    120183        {
    121             PCRTWINERRMSG pMsg = &g_aStatusMsgs[i];
    122 
    123             /* Paranoid ERROR_SUCCESS handling: */
    124             if (pMsg->iCode > 0 && iPrev < 0)
    125                 fprintf(pOut, "/*%#010lx:*/ { \"Success.\", \"ERROR_SUCCESS\", 0 }\n", (unsigned long)0);
    126             else if (pMsg->iCode == 0 && iPrev == 0)
    127                 continue;
    128 
    129             /* Deal with duplicates in a gentle manner: */
     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. */
    130189            if (pMsg->iCode == iPrev && i != 0)
    131190            {
    132                 PCRTWINERRMSG pPrev = &g_aStatusMsgs[i - 1];
    133                 if (strcmp(pMsg->pszDefine, pPrev->pszDefine) == 0)
     191                if (IgnoreDuplicateDefine(pMsg->pszDefine))
    134192                    continue;
     193                PCRTSTATUSMSG pPrev = &g_aStatusMsgs[i - 1];
    135194                fprintf(stderr, "%s: warning: Duplicate value %#lx (%ld) - %s and %s\n",
    136195                        argv[0], (unsigned long)iPrev, iPrev, pMsg->pszDefine, pPrev->pszDefine);
    137196            }
     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            }
    138204            iPrev = pMsg->iCode;
    139205
    140             /* Make sure the message string doesn't contain problematic characters: */
    141             const char *pszMsgFull = pMsg->pszMsgFull;
    142             if (strpbrk(pszMsgFull, "\"\\"))
    143             {
    144                 char *pszDst = s_szMsgTmp;
    145                 char  ch;
    146                 do
    147                 {
    148                     ch = *pszMsgFull++;
    149                     if (ch == '\\' || ch == '"')
    150                         *pszDst++ = '\\';
    151                     *pszDst++ = ch;
    152                 } while (ch);
    153                 pszMsgFull = s_szMsgTmp;
    154             }
    155 
    156206            /* Produce the output: */
    157             fprintf(pOut, "/*%#010lx:*/ { \"%s\", \"%s\", %ld },\n",
    158                     (unsigned long)pMsg->iCode, pszMsgFull, pMsg->pszDefine, pMsg->iCode);
     207            fprintf(pOut, "/*%8d:*/ { \"%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);
    159212        }
    160213
  • trunk/src/VBox/Runtime/common/err/errmsg.cpp

    r82968 r83745  
    3434#include <iprt/asm.h>
    3535#include <iprt/string.h>
    36 #include <iprt/err.h>
    3736#include <VBox/err.h>
    3837
     
    4746{
    4847#if !defined(IPRT_NO_ERROR_DATA) && !defined(DOXYGEN_RUNNING)
    49 # include "errmsgdata.h"
     48# include "errmsgdata-sorted.h"
    5049#else
    5150    { "Success.", "Success.", "VINF_SUCCESS", 0 },
    5251#endif
    53     { NULL, NULL, NULL, 0 }
    5452};
    5553
     
    5856 * @{
    5957 */
    60 static char                 g_aszUnknownStr[4][64];
    61 static RTSTATUSMSG          g_aUnknownMsgs[4] =
     58static char                 g_aszUnknownStr[8][64];
     59static RTSTATUSMSG          g_aUnknownMsgs[8] =
    6260{
    6361    { &g_aszUnknownStr[0][0], &g_aszUnknownStr[0][0], &g_aszUnknownStr[0][0], 0 },
    6462    { &g_aszUnknownStr[1][0], &g_aszUnknownStr[1][0], &g_aszUnknownStr[1][0], 0 },
    6563    { &g_aszUnknownStr[2][0], &g_aszUnknownStr[2][0], &g_aszUnknownStr[2][0], 0 },
    66     { &g_aszUnknownStr[3][0], &g_aszUnknownStr[3][0], &g_aszUnknownStr[3][0], 0 }
     64    { &g_aszUnknownStr[3][0], &g_aszUnknownStr[3][0], &g_aszUnknownStr[3][0], 0 },
     65    { &g_aszUnknownStr[4][0], &g_aszUnknownStr[4][0], &g_aszUnknownStr[4][0], 0 },
     66    { &g_aszUnknownStr[5][0], &g_aszUnknownStr[5][0], &g_aszUnknownStr[5][0], 0 },
     67    { &g_aszUnknownStr[6][0], &g_aszUnknownStr[6][0], &g_aszUnknownStr[6][0], 0 },
     68    { &g_aszUnknownStr[7][0], &g_aszUnknownStr[7][0], &g_aszUnknownStr[7][0], 0 },
    6769};
    6870/** Last used index in g_aUnknownMsgs. */
     
    7981RTDECL(PCRTSTATUSMSG) RTErrGet(int rc)
    8082{
    81     unsigned iFound = ~0U;
    82     unsigned i;
    83     for (i = 0; i < RT_ELEMENTS(g_aStatusMsgs) - 1; i++)
     83    /*
     84     * Perform binary search (duplicate code in RTErrWinGet).
     85     */
     86    size_t iStart = 0;
     87    size_t iEnd   = RT_ELEMENTS(g_aStatusMsgs);
     88    for (;;)
    8489    {
    85         if (g_aStatusMsgs[i].iCode == rc)
     90        size_t i = iStart + (iEnd - iStart) / 2;
     91        int const iCode = g_aStatusMsgs[i].iCode;
     92        if (rc < iCode)
    8693        {
    87             /*
    88              * Found a match.
    89              * Since this isn't a unique key, we must check that it's not
    90              * one of those start/end #defines before we return.
    91              */
    92 #define STR_ENDS_WITH(a_psz, a_cch, a_sz) \
    93     ( (a_cch) >= sizeof(a_sz) && !strncmp((a_psz) + (a_cch) - sizeof(a_sz) + 1, RT_STR_TUPLE(a_sz)) )
    94             size_t const cchDefine = strlen(g_aStatusMsgs[i].pszDefine);
    95             if (   !STR_ENDS_WITH(g_aStatusMsgs[i].pszDefine, cchDefine, "_FIRST")
    96                 && !STR_ENDS_WITH(g_aStatusMsgs[i].pszDefine, cchDefine, "_LAST")
    97                 && !STR_ENDS_WITH(g_aStatusMsgs[i].pszDefine, cchDefine, "_LOWEST")
    98                 && !STR_ENDS_WITH(g_aStatusMsgs[i].pszDefine, cchDefine, "_HIGHEST")
    99                )
    100                 return &g_aStatusMsgs[i];
    101             iFound = i;
     94            if (iStart < i)
     95                iEnd = i;
     96            else
     97                break;
    10298        }
     99        else if (rc > iCode)
     100        {
     101            i++;
     102            if (i < iEnd)
     103                iStart = i;
     104            else
     105                break;
     106        }
     107        else
     108            return &g_aStatusMsgs[i];
    103109    }
    104     if (iFound != ~0U)
    105         return &g_aStatusMsgs[iFound];
     110
     111#ifdef RT_STRICT
     112    for (size_t i = 0; i < RT_ELEMENTS(g_aStatusMsgs); i++)
     113        Assert(g_aStatusMsgs[i].iCode != rc);
     114#endif
    106115
    107116    /*
  • trunk/src/VBox/Runtime/win/errmsgwin-sorter.cpp

    r83744 r83745  
    8585
    8686
     87/**
     88 * Escapes @a pszString using @a pszBuf as needed.
     89 * @note Duplicated in errmsg-sorter.cpp.
     90 */
     91static const char *EscapeString(const char *pszString, char *pszBuf, size_t cbBuf)
     92{
     93    if (strpbrk(pszString, "\n\t\r\"\\") == NULL)
     94        return pszString;
     95
     96    char *pszDst = pszBuf;
     97    char  ch;
     98    do
     99    {
     100        ch = *pszString++;
     101        switch (ch)
     102        {
     103            default:
     104                *pszDst++ = ch;
     105                break;
     106            case '\\':
     107            case '"':
     108                *pszDst++ = '\\';
     109                *pszDst++ = ch;
     110                break;
     111            case '\n':
     112                *pszDst++ = '\\';
     113                *pszDst++ = 'n';
     114                break;
     115            case '\t':
     116                *pszDst++ = '\\';
     117                *pszDst++ = 't';
     118                break;
     119            case '\r':
     120                break; /* drop it */
     121        }
     122    } while (ch);
     123
     124    if ((uintptr_t)(pszDst - pszBuf) > cbBuf)
     125        fprintf(stderr, "Escape buffer overrun!\n");
     126
     127    return pszBuf;
     128}
     129
     130
    87131int main(int argc, char **argv)
    88132{
     
    138182            iPrev = pMsg->iCode;
    139183
    140             /* Make sure the message string doesn't contain problematic characters: */
    141             const char *pszMsgFull = pMsg->pszMsgFull;
    142             if (strpbrk(pszMsgFull, "\"\\"))
    143             {
    144                 char *pszDst = s_szMsgTmp;
    145                 char  ch;
    146                 do
    147                 {
    148                     ch = *pszMsgFull++;
    149                     if (ch == '\\' || ch == '"')
    150                         *pszDst++ = '\\';
    151                     *pszDst++ = ch;
    152                 } while (ch);
    153                 pszMsgFull = s_szMsgTmp;
    154             }
    155 
    156184            /* Produce the output: */
    157             fprintf(pOut, "/*%#010lx:*/ { \"%s\", \"%s\", %ld },\n",
    158                     (unsigned long)pMsg->iCode, pszMsgFull, pMsg->pszDefine, pMsg->iCode);
     185            fprintf(pOut, "/*%#010lx:*/ { \"%s\", \"%s\", %ld },\n", (unsigned long)pMsg->iCode,
     186                    EscapeString(pMsg->pszMsgFull, s_szMsgTmp, sizeof(s_szMsgTmp)), pMsg->pszDefine, pMsg->iCode);
    159187        }
    160188
  • trunk/src/VBox/Runtime/win/errmsgwin.cpp

    r83744 r83745  
    8181{
    8282    /*
    83      * Perform binary search.
     83     * Perform binary search (duplicate code in RTErrGet).
    8484     */
    8585    size_t iStart = 0;
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