VirtualBox

Changeset 83743 in vbox for trunk/src/VBox/Runtime


Ignore:
Timestamp:
Apr 17, 2020 11:25:08 AM (5 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
137263
Message:

IPRT: Sort windows error messages so we can look them up using binary searching. Also addressed VC++ 14.1 warnings there. bugref:8489

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

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/Makefile.kmk

    r83727 r83743  
    36483648common/err/errmsg.cpp_INCS = $(IPRT_OUT_DIR)
    36493649
    3650 win/errmsgwin.cpp_DEPS = $(IPRT_OUT_DIR)/errmsgcomdata.h
     3650win/errmsgwin.cpp_DEPS = $(IPRT_OUT_DIR)/errmsgwindata-sorted.h
    36513651win/errmsgwin.cpp_INCS = $(IPRT_OUT_DIR)
    36523652
     
    36713671        $(QUIET)$(REDIRECT) -wo $@ -- $(SED) -f $< $(filter %.h,$^)
    36723672
    3673 ## @todo r=bird: rename this to indicate that it's not only COM errors, but all win32/64 errors.
    36743673$(IPRT_OUT_DIR)/errmsgcomdata.h: \
    36753674                $(VBOX_PATH_RUNTIME_SRC)/common/err/errmsgcom.sed \
     
    36793678        $(QUIET)$(REDIRECT) -wo $@ -- $(SED) -f $< $(filter %.h,$^)
    36803679
    3681 $(IPRT_OUT_DIR)/errmsgvboxcomdata.h.ts +| $(IPRT_OUT_DIR)/errmsgvboxcomdata.h: \
     3680$(IPRT_OUT_DIR)/errmsgvboxdata.h.ts +| $(IPRT_OUT_DIR)/errmsgvboxcomdata.h: \
    36823681                $(VBOX_PATH_RUNTIME_SRC)/VBox/errmsgvboxcom.xsl \
    36833682                $(VBOX_XIDL_FILE_SRC) \
     
    36853684        $(call MSG_GENERATE,,$@,$(filter %.xidl,$^))
    36863685        $(QUIET)$(VBOX_XSLTPROC) -o $(IPRT_OUT_DIR)/errmsgvboxcomdata.h.ts $< $(filter %.xidl,$^)
    3687         $(QUIET)$(CP) --changed -fv $(IPRT_OUT_DIR)/errmsgvboxcomdata.h.ts $(IPRT_OUT_DIR)/errmsgvboxcomdata.h
     3686        $(QUIET)$(CP) --changed -fv -- $(IPRT_OUT_DIR)/errmsgvboxcomdata.h.ts $(IPRT_OUT_DIR)/errmsgvboxcomdata.h
     3687
     3688$(IPRT_OUT_DIR)/errmsgwindata-sorted.h.ts +| $(IPRT_OUT_DIR)/errmsgwindata-sorted.h: \
     3689                $$(bldRTErrMsgWinSorter_1_TARGET)
     3690        $(call MSG_GENERATE,,$@,$<)
     3691        $(QUIET)"$<" "$(IPRT_OUT_DIR)/errmsgwindata-sorted.h.ts"
     3692        $(QUIET)$(CP) --changed -fv -- "$(IPRT_OUT_DIR)/errmsgwindata-sorted.h.ts" "$(IPRT_OUT_DIR)/errmsgwindata-sorted.h"
     3693
     3694#
     3695# Sorter for the windows error codes.
     3696#
     3697BLDPROGS.win += bldRTErrMsgWinSorter
     3698bldRTErrMsgWinSorter_TEMPLATE = VBoxBldProg
     3699bldRTErrMsgWinSorter_SOURCES  = win/errmsgwin-sorter.cpp
     3700win/errmsgwin-sorter.cpp_INCS = $(IPRT_OUT_DIR)
     3701win/errmsgwin-sorter.cpp_DEPS = \
     3702        $(IPRT_OUT_DIR)/errmsgcomdata.h \
     3703        $(IPRT_OUT_DIR)/errmsgvboxcomdata.h
     3704
    36883705
    36893706
  • trunk/src/VBox/Runtime/VBox/errmsgvboxcom.xsl

    r82970 r83743  
    6666    <xsl:text>", "</xsl:text>
    6767    <xsl:value-of select="@name"/>
    68     <xsl:text>", </xsl:text>
     68    <xsl:text>", (VBOXSTATUSTYPE)</xsl:text>
    6969    <xsl:value-of select="@value"/>
    70     <xsl:text> },&#x0A;</xsl:text>
     70    <xsl:text>L },&#x0A;</xsl:text>
    7171  </xsl:for-each>
    7272</xsl:template>
  • trunk/src/VBox/Runtime/common/err/errmsgxpcom.cpp

    r82968 r83743  
    3535#include <iprt/string.h>
    3636#include <iprt/errcore.h>
     37
     38
     39/*********************************************************************************************************************************
     40*   Defined Constants And Macros                                                                                                 *
     41*********************************************************************************************************************************/
     42typedef uint32_t VBOXSTATUSTYPE; /* used by errmsgvboxcomdata.h */
    3743
    3844
  • trunk/src/VBox/Runtime/win/errmsgwin-sorter.cpp

    r83716 r83743  
    11/* $Id$ */
    22/** @file
    3  * IPRT - Status code messages.
     3 * IPRT - Status code messages, Windows, sorter build program.
    44 */
    55
     
    3434#include <iprt/asm.h>
    3535#include <iprt/string.h>
    36 #include <iprt/errcore.h>
     36
     37#include <stdio.h>
     38#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*********************************************************************************************************************************/
     53typedef long VBOXSTATUSTYPE; /* used by errmsgvboxcomdata.h */
    3754
    3855
     
    4057*   Global Variables                                                                                                             *
    4158*********************************************************************************************************************************/
    42 /** Array of messages.
    43  * The data is generated by a sed script.
    44  */
    45 static const RTWINERRMSG  g_aStatusMsgs[] =
     59static RTWINERRMSG  g_aStatusMsgs[] =
    4660{
    4761#if !defined(IPRT_NO_ERROR_DATA) && !defined(DOXYGEN_RUNNING)
     
    5064#  include "errmsgvboxcomdata.h"
    5165# endif
    52 #else
     66#endif
    5367    { "Success.", "ERROR_SUCCESS", 0 },
    54 #endif
    55     { NULL, NULL, 0 }
    5668};
    5769
    5870
    59 /** Temporary buffers to format unknown messages in.
    60  * @{
    61  */
    62 static char                 g_aszUnknownStr[4][64];
    63 static RTWINERRMSG          g_aUnknownMsgs[4] =
     71/** qsort callback. */
     72static int CompareWinErrMsg(const void *pv1, const void *pv2)
    6473{
    65     { &g_aszUnknownStr[0][0], &g_aszUnknownStr[0][0], 0 },
    66     { &g_aszUnknownStr[1][0], &g_aszUnknownStr[1][0], 0 },
    67     { &g_aszUnknownStr[2][0], &g_aszUnknownStr[2][0], 0 },
    68     { &g_aszUnknownStr[3][0], &g_aszUnknownStr[3][0], 0 }
    69 };
    70 /** Last used index in g_aUnknownMsgs. */
    71 static volatile uint32_t    g_iUnknownMsgs;
    72 /** @} */
    73 
    74 
    75 /**
    76  * Get the message corresponding to a given status code.
    77  *
    78  * @returns Pointer to read-only message description.
    79  * @param   rc      The status code.
    80  */
    81 RTDECL(PCRTWINERRMSG) RTErrWinGet(long rc)
    82 {
    83     unsigned i;
    84     for (i = 0; i < RT_ELEMENTS(g_aStatusMsgs) - 1U; i++)
    85         if (g_aStatusMsgs[i].iCode == rc)
    86             return &g_aStatusMsgs[i];
    87 
    88     /* The g_aStatusMsgs table contains a wild mix of error codes with and
    89      * without included facility and severity. So the chance is high that there
    90      * was no exact match. Try to find a non-exact match, and include the
    91      * actual value in case we pick the wrong entry. Better than always using
    92      * the "Unknown Status" case. */
    93     for (i = 0; i < RT_ELEMENTS(g_aStatusMsgs) - 1U; i++)
    94         if (g_aStatusMsgs[i].iCode == HRESULT_CODE(rc))
    95         {
    96             int32_t iMsg = (ASMAtomicIncU32(&g_iUnknownMsgs) - 1) % RT_ELEMENTS(g_aUnknownMsgs);
    97             RTStrPrintf(&g_aszUnknownStr[iMsg][0], sizeof(g_aszUnknownStr[iMsg]), "%s 0x%X", g_aStatusMsgs[i].pszDefine, rc);
    98             return &g_aUnknownMsgs[iMsg];
    99         }
    100 
    101     /*
    102      * Need to use the temporary stuff.
    103      */
    104     int32_t iMsg = (ASMAtomicIncU32(&g_iUnknownMsgs) - 1) % RT_ELEMENTS(g_aUnknownMsgs);
    105     RTStrPrintf(&g_aszUnknownStr[iMsg][0], sizeof(g_aszUnknownStr[iMsg]), "Unknown Status 0x%X", rc);
    106     return &g_aUnknownMsgs[iMsg];
     74    PCRTWINERRMSG p1 = (PCRTWINERRMSG)pv1;
     75    PCRTWINERRMSG p2 = (PCRTWINERRMSG)pv2;
     76    int iDiff;
     77    if (p1->iCode < p2->iCode)
     78        iDiff = -1;
     79    else if (p1->iCode > p2->iCode)
     80        iDiff = 1;
     81    else
     82        iDiff = 0;
     83    return iDiff;
    10784}
    10885
    10986
    110 RTDECL(PCRTCOMERRMSG) RTErrCOMGet(uint32_t rc)
     87int main(int argc, char **argv)
    11188{
    112     return RTErrWinGet((long)rc);
     89    /*
     90     * Argument check.
     91     */
     92    if (argc != 1 && argc != 2)
     93    {
     94        fprintf(stderr,
     95                "syntax error!\n"
     96                "Usage: %s [outfile]\n", argv[0]);
     97        return RTEXITCODE_SYNTAX;
     98    }
     99
     100    /*
     101     * Sort the table.
     102     */
     103    qsort(g_aStatusMsgs, RT_ELEMENTS(g_aStatusMsgs), sizeof(g_aStatusMsgs[0]), CompareWinErrMsg);
     104
     105    /*
     106     * Prepare output file.
     107     */
     108    int rcExit = RTEXITCODE_FAILURE;
     109    FILE *pOut = stdout;
     110    if (argc > 1)
     111        pOut = fopen(argv[1], "wt");
     112    if (pOut)
     113    {
     114        /*
     115         * Print the table.
     116         */
     117        static char s_szMsgTmp[_256K];
     118        long iPrev = (long)0x80000000;
     119        for (size_t i = 0; i < RT_ELEMENTS(g_aStatusMsgs); i++)
     120        {
     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: */
     130            if (pMsg->iCode == iPrev && i != 0)
     131            {
     132                PCRTWINERRMSG pPrev = &g_aStatusMsgs[i - 1];
     133                if (strcmp(pMsg->pszDefine, pPrev->pszDefine) == 0)
     134                    continue;
     135                fprintf(stderr, "%s: warning: Duplicate value %#lx (%ld) - %s and %s\n",
     136                        argv[0], (unsigned long)iPrev, iPrev, pMsg->pszDefine, pPrev->pszDefine);
     137            }
     138            iPrev = pMsg->iCode;
     139
     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
     156            /* Produce the output: */
     157            fprintf(pOut, "/*%#010lx:*/ { \"%s\", \"%s\", %ld },\n",
     158                    (unsigned long)pMsg->iCode, pszMsgFull, pMsg->pszDefine, pMsg->iCode);
     159        }
     160
     161        /*
     162         * Close the output file and we're done.
     163         */
     164        if (fclose(pOut) == 0)
     165            rcExit = RTEXITCODE_SUCCESS;
     166        else
     167            fprintf(stderr, "%s: Failed to flush/close '%s' after writing it!\n", argv[0], argv[1]);
     168    }
     169    else
     170        fprintf(stderr, "%s: Failed to open '%s' for writing!\n", argv[0], argv[1]);
     171    return rcExit;
    113172}
    114173
  • trunk/src/VBox/Runtime/win/errmsgwin.cpp

    r82968 r83743  
    11/* $Id$ */
    22/** @file
    3  * IPRT - Status code messages.
     3 * IPRT - Status code messages, Windows.
    44 */
    55
     
    3434#include <iprt/asm.h>
    3535#include <iprt/string.h>
    36 #include <iprt/errcore.h>
    3736
    3837
     
    4544static const RTWINERRMSG  g_aStatusMsgs[] =
    4645{
    47 #if !defined(IPRT_NO_ERROR_DATA) && !defined(DOXYGEN_RUNNING)
    48 # include "errmsgcomdata.h"
    49 # if defined(VBOX) && !defined(IN_GUEST)
    50 #  include "errmsgvboxcomdata.h"
    51 # endif
    52 #else
    53     { "Success.", "ERROR_SUCCESS", 0 },
    54 #endif
    55     { NULL, NULL, 0 }
     46#include "errmsgwindata-sorted.h"
    5647};
    5748
     
    6051 * @{
    6152 */
    62 static char                 g_aszUnknownStr[4][64];
    63 static RTWINERRMSG          g_aUnknownMsgs[4] =
     53static char                 g_aszUnknownStr[8][64];
     54static RTWINERRMSG          g_aUnknownMsgs[8] =
    6455{
    6556    { &g_aszUnknownStr[0][0], &g_aszUnknownStr[0][0], 0 },
    6657    { &g_aszUnknownStr[1][0], &g_aszUnknownStr[1][0], 0 },
    6758    { &g_aszUnknownStr[2][0], &g_aszUnknownStr[2][0], 0 },
    68     { &g_aszUnknownStr[3][0], &g_aszUnknownStr[3][0], 0 }
     59    { &g_aszUnknownStr[3][0], &g_aszUnknownStr[3][0], 0 },
     60    { &g_aszUnknownStr[4][0], &g_aszUnknownStr[4][0], 0 },
     61    { &g_aszUnknownStr[5][0], &g_aszUnknownStr[5][0], 0 },
     62    { &g_aszUnknownStr[6][0], &g_aszUnknownStr[6][0], 0 },
     63    { &g_aszUnknownStr[7][0], &g_aszUnknownStr[7][0], 0 },
    6964};
    7065/** Last used index in g_aUnknownMsgs. */
     
    8176RTDECL(PCRTWINERRMSG) RTErrWinGet(long rc)
    8277{
    83     unsigned i;
    84     for (i = 0; i < RT_ELEMENTS(g_aStatusMsgs) - 1U; i++)
    85         if (g_aStatusMsgs[i].iCode == rc)
     78    /*
     79     * Perform binary search.
     80     */
     81    size_t iStart = 0;
     82    size_t iEnd   = RT_ELEMENTS(g_aStatusMsgs);
     83    for (;;)
     84    {
     85        size_t i = iStart + (iEnd - iStart) / 2;
     86        long const iCode = g_aStatusMsgs[i].iCode;
     87        if (rc < iCode)
     88        {
     89            if (iStart < i)
     90                iEnd = i;
     91            else
     92                break;
     93        }
     94        else if (rc > iCode)
     95        {
     96            i++;
     97            if (i < iEnd)
     98                iStart = i;
     99            else
     100                break;
     101        }
     102        else
    86103            return &g_aStatusMsgs[i];
     104    }
    87105
    88     /* The g_aStatusMsgs table contains a wild mix of error codes with and
    89      * without included facility and severity. So the chance is high that there
    90      * was no exact match. Try to find a non-exact match, and include the
    91      * actual value in case we pick the wrong entry. Better than always using
    92      * the "Unknown Status" case. */
    93     for (i = 0; i < RT_ELEMENTS(g_aStatusMsgs) - 1U; i++)
    94         if (g_aStatusMsgs[i].iCode == HRESULT_CODE(rc))
     106#ifdef RT_STRICT
     107    for (size_t i = 0; i < RT_ELEMENTS(g_aStatusMsgs); i++)
     108        Assert(g_aStatusMsgs[i].iCode != rc);
     109#endif
     110
     111    /*
     112     * If FACILITY_WIN32 kind of status, look up the win32 code.
     113     */
     114    if (SCODE_FACILITY(rc) == FACILITY_WIN32)
     115    {
     116        long const rcWin32 = HRESULT_CODE(rc);
     117        iStart = 0;
     118        iEnd   = RT_ELEMENTS(g_aStatusMsgs);
     119        for (;;)
    95120        {
    96             int32_t iMsg = (ASMAtomicIncU32(&g_iUnknownMsgs) - 1) % RT_ELEMENTS(g_aUnknownMsgs);
    97             RTStrPrintf(&g_aszUnknownStr[iMsg][0], sizeof(g_aszUnknownStr[iMsg]), "%s 0x%X", g_aStatusMsgs[i].pszDefine, rc);
    98             return &g_aUnknownMsgs[iMsg];
     121            size_t i = iStart + (iEnd - iStart) / 2;
     122            long const iCode = g_aStatusMsgs[i].iCode;
     123            if (rcWin32 < iCode)
     124            {
     125                if (iStart < i)
     126                    iEnd = i;
     127                else
     128                    break;
     129            }
     130            else if (rcWin32 > iCode)
     131            {
     132                i++;
     133                if (i < iEnd)
     134                    iStart = i;
     135                else
     136                    break;
     137            }
     138            else
     139            {
     140                /* Append the incoming rc, so we know it's not a regular WIN32 status: */
     141                int32_t iMsg = (ASMAtomicIncU32(&g_iUnknownMsgs) - 1) % RT_ELEMENTS(g_aUnknownMsgs);
     142                RTStrPrintf(&g_aszUnknownStr[iMsg][0], sizeof(g_aszUnknownStr[iMsg]), "%s/0x%x", g_aStatusMsgs[i].pszDefine, rc);
     143                return &g_aUnknownMsgs[iMsg];
     144            }
    99145        }
     146
     147#ifdef RT_STRICT
     148        for (size_t i = 0; i < RT_ELEMENTS(g_aStatusMsgs); i++)
     149            Assert(g_aStatusMsgs[i].iCode != rcWin32);
     150#endif
     151    }
    100152
    101153    /*
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