VirtualBox

source: vbox/trunk/src/VBox/Runtime/common/err/errmsg-sorter.cpp@ 84050

Last change on this file since 84050 was 83984, checked in by vboxsync, 5 years ago

IPRT: Reduce the amoung of strings in errmsg and errmsgwin in static builds (IN_RT_STATIC). The windows ones are almost never used anywhere anyways.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Revision
File size: 7.1 KB
Line 
1/* $Id: errmsg-sorter.cpp 83984 2020-04-27 00:17:19Z vboxsync $ */
2/** @file
3 * IPRT - Status code messages, 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/err.h>
32#include <iprt/asm.h>
33#include <iprt/string.h>
34#include <VBox/err.h>
35
36#include <stdio.h>
37#include <stdlib.h>
38
39
40/*********************************************************************************************************************************
41* Global Variables *
42*********************************************************************************************************************************/
43static RTSTATUSMSG g_aStatusMsgs[] =
44{
45#if !defined(IPRT_NO_ERROR_DATA) && !defined(DOXYGEN_RUNNING)
46# include "errmsgdata.h"
47#else
48 { "Success.", "Success.", "VINF_SUCCESS", 0 },
49#endif
50};
51
52
53/** qsort callback. */
54static int CompareErrMsg(const void *pv1, const void *pv2)
55{
56 PCRTSTATUSMSG p1 = (PCRTSTATUSMSG)pv1;
57 PCRTSTATUSMSG p2 = (PCRTSTATUSMSG)pv2;
58 int iDiff;
59 if (p1->iCode < p2->iCode)
60 iDiff = -1;
61 else if (p1->iCode > p2->iCode)
62 iDiff = 1;
63 else
64 iDiff = 0;
65 return iDiff;
66}
67
68
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
149int main(int argc, char **argv)
150{
151 /*
152 * Argument check.
153 */
154 if (argc != 1 && argc != 2)
155 {
156 fprintf(stderr,
157 "syntax error!\n"
158 "Usage: %s [outfile]\n", argv[0]);
159 return RTEXITCODE_SYNTAX;
160 }
161
162 /*
163 * Sort the table.
164 */
165 qsort(g_aStatusMsgs, RT_ELEMENTS(g_aStatusMsgs), sizeof(g_aStatusMsgs[0]), CompareErrMsg);
166
167 /*
168 * Prepare output file.
169 */
170 int rcExit = RTEXITCODE_FAILURE;
171 FILE *pOut = stdout;
172 if (argc > 1)
173 pOut = fopen(argv[1], "wt");
174 if (pOut)
175 {
176 /*
177 * Print the table.
178 */
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 }
214
215 /*
216 * Close the output file and we're done.
217 */
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]);
222 }
223 else
224 fprintf(stderr, "%s: Failed to open '%s' for writing!\n", argv[0], argv[1]);
225 return rcExit;
226}
227
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