VirtualBox

source: vbox/trunk/src/VBox/Runtime/win/errmsgwin-sorter.cpp@ 83922

Last change on this file since 83922 was 83746, checked in by vboxsync, 5 years ago

IPRT: Sort IPRT status messages so we can look them up using binary searching. [build fix + update] bugref:8489

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Revision
File size: 6.9 KB
Line 
1/* $Id: errmsgwin-sorter.cpp 83746 2020-04-17 12:36:20Z vboxsync $ */
2/** @file
3 * IPRT - Status code messages, Windows, sorter build program.
4 */
5
6/*
7 * Copyright (C) 2006-2020 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 *
17 * The contents of this file may alternatively be used under the terms
18 * of the Common Development and Distribution License Version 1.0
19 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
20 * VirtualBox OSE distribution, in which case the provisions of the
21 * CDDL are applicable instead of those of the GPL.
22 *
23 * You may elect to license modified versions of this file under the
24 * terms and conditions of either the GPL or the CDDL or both.
25 */
26
27
28/*********************************************************************************************************************************
29* Header Files *
30*********************************************************************************************************************************/
31#include <iprt/win/windows.h>
32
33#include <iprt/errcore.h>
34#include <iprt/asm.h>
35#include <iprt/string.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 */
54
55
56/*********************************************************************************************************************************
57* Global Variables *
58*********************************************************************************************************************************/
59static RTWINERRMSG g_aStatusMsgs[] =
60{
61#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
66#endif
67 { "Success.", "ERROR_SUCCESS", 0 },
68};
69
70
71/** qsort callback. */
72static int CompareWinErrMsg(const void *pv1, const void *pv2)
73{
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;
84}
85
86
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
131int main(int argc, char **argv)
132{
133 /*
134 * Argument check.
135 */
136 if (argc != 1 && argc != 2)
137 {
138 fprintf(stderr,
139 "syntax error!\n"
140 "Usage: %s [outfile]\n", argv[0]);
141 return RTEXITCODE_SYNTAX;
142 }
143
144 /*
145 * Sort the table.
146 */
147 qsort(g_aStatusMsgs, RT_ELEMENTS(g_aStatusMsgs), sizeof(g_aStatusMsgs[0]), CompareWinErrMsg);
148
149 /*
150 * Prepare output file.
151 */
152 int rcExit = RTEXITCODE_FAILURE;
153 FILE *pOut = stdout;
154 if (argc > 1)
155 pOut = fopen(argv[1], "wt");
156 if (pOut)
157 {
158 /*
159 * Print the table.
160 */
161 static char s_szMsgTmp[_256K];
162 long iPrev = (long)0x80000000;
163 rcExit = RTEXITCODE_SUCCESS;
164 for (size_t i = 0; i < RT_ELEMENTS(g_aStatusMsgs); i++)
165 {
166 PCRTWINERRMSG pMsg = &g_aStatusMsgs[i];
167
168 /* Paranoid ERROR_SUCCESS handling: */
169 if (pMsg->iCode > 0 && iPrev < 0)
170 fprintf(pOut, "/*%#010lx:*/ { \"Success.\", \"ERROR_SUCCESS\", 0 }\n", (unsigned long)0);
171 else if (pMsg->iCode == 0 && iPrev == 0)
172 continue;
173
174 /* Deal with duplicates in a gentle manner: */
175 if (pMsg->iCode == iPrev && i != 0)
176 {
177 PCRTWINERRMSG pPrev = &g_aStatusMsgs[i - 1];
178 if (strcmp(pMsg->pszDefine, pPrev->pszDefine) == 0)
179 continue;
180 fprintf(stderr, "%s: error: Duplicate value %#lx (%ld) - %s and %s\n",
181 argv[0], (unsigned long)iPrev, iPrev, pMsg->pszDefine, pPrev->pszDefine);
182 rcExit = RTEXITCODE_FAILURE;
183 }
184 iPrev = pMsg->iCode;
185
186 /* Produce the output: */
187 fprintf(pOut, "/*%#010lx:*/ { \"%s\", \"%s\", %ld },\n", (unsigned long)pMsg->iCode,
188 EscapeString(pMsg->pszMsgFull, s_szMsgTmp, sizeof(s_szMsgTmp)), pMsg->pszDefine, pMsg->iCode);
189 }
190
191 /*
192 * Close the output file and we're done.
193 */
194 if (fclose(pOut) != 0)
195 {
196 fprintf(stderr, "%s: Failed to flush/close '%s' after writing it!\n", argv[0], argv[1]);
197 rcExit = RTEXITCODE_FAILURE;
198 }
199 }
200 else
201 fprintf(stderr, "%s: Failed to open '%s' for writing!\n", argv[0], argv[1]);
202 return rcExit;
203}
204
Note: See TracBrowser for help on using the repository browser.

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