VirtualBox

source: vbox/trunk/src/VBox/Main/webservice/split-soapC.cpp

Last change on this file was 98297, checked in by vboxsync, 16 months ago

Main: rc -> hrc/vrc for all but testcases. Enabled scm rc checks accordingly. bugref:10223

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 7.4 KB
RevLine 
[83223]1/* $Id: split-soapC.cpp 98297 2023-01-25 01:59:25Z vboxsync $ */
[26497]2/** @file
[83223]3 * Splits soapC.cpp and soapH-noinline.cpp into more manageable portions.
[26497]4 */
5
6/*
[98103]7 * Copyright (C) 2009-2023 Oracle and/or its affiliates.
[23400]8 *
[96407]9 * This file is part of VirtualBox base platform packages, as
10 * available from https://www.virtualbox.org.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation, in version 3 of the
15 * License.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, see <https://www.gnu.org/licenses>.
24 *
25 * SPDX-License-Identifier: GPL-3.0-only
[26497]26 */
27
[83223]28
29/*********************************************************************************************************************************
30* Header Files *
31*********************************************************************************************************************************/
[62766]32#include <iprt/types.h>
[83223]33#include <iprt/path.h>
[26497]34#include <sys/types.h>
35#include <stdio.h>
36#include <string.h>
37#include <stdlib.h>
38#include <limits.h>
39
40
[83223]41static char *readfileIntoBuffer(const char *pszFile, size_t *pcbFile)
[62766]42{
43 FILE *pFileIn = fopen(pszFile, "rb");
44 if (pFileIn)
45 {
[98297]46 int iRc2 = fseek(pFileIn, 0, SEEK_END);
[62766]47 long cbFileIn = ftell(pFileIn);
[98297]48 int iRc3 = fseek(pFileIn, 0, SEEK_SET);
49 if (iRc3 != -1 && iRc2 != -1 && cbFileIn >= 0)
[62766]50 {
51 char *pBuffer = (char *)malloc(cbFileIn + 1);
52 if (pBuffer)
53 {
54 size_t cbRead = fread(pBuffer, 1, cbFileIn, pFileIn);
55 if (cbRead == (size_t)cbFileIn)
56 {
57 pBuffer[cbFileIn] = '\0';
58 fclose(pFileIn);
59 *pcbFile = (size_t)cbFileIn;
60 return pBuffer;
61 }
62
63 fprintf(stderr, "split-soapC: Failed to read %ld bytes from input file.\n", cbFileIn);
64 free(pBuffer);
65 }
66 else
67 fprintf(stderr, "split-soapC: Failed to allocate %ld bytes.\n", cbFileIn);
68 }
69 else
70 fprintf(stderr, "split-soapC: Seek failure.\n");
71 fclose(pFileIn);
72 }
73 else
74 fprintf(stderr, "split-soapC: Cannot open file \"%s\" for reading.\n", pszFile);
75 return NULL;
76}
77
78
[26497]79int main(int argc, char *argv[])
80{
[62766]81 /*
82 * Check argument count.
83 */
84 if (argc != 4)
85 {
[83223]86 fprintf(stderr, "split-soapC: Must be started with exactly four arguments,\n"
87 "1) the input file, 2) the output filename prefix and\n"
88 "3) the number chunks to create.");
[62766]89 return RTEXITCODE_SYNTAX;
90 }
[26497]91
[62766]92 /*
93 * Number of chunks (argv[3]).
94 */
95 char *pszEnd = NULL;
96 unsigned long cChunks = strtoul(argv[3], &pszEnd, 0);
97 if (cChunks == ULONG_MAX || cChunks == 0 || !argv[3] || *pszEnd)
98 {
99 fprintf(stderr, "split-soapC: Given argument \"%s\" is not a valid chunk count.\n", argv[3]);
100 return RTEXITCODE_SYNTAX;
101 }
102
103 /*
104 * Read the input file into a zero terminated memory buffer.
105 */
106 size_t cbFileIn;
107 char *pszBuffer = readfileIntoBuffer(argv[1], &cbFileIn);
108 if (!pszBuffer)
109 return RTEXITCODE_FAILURE;
110
111 /*
112 * Split the file.
113 */
114 RTEXITCODE rcExit = RTEXITCODE_SUCCESS;
115 FILE *pFileOut = NULL;
116 const char *pszLine = pszBuffer;
117 size_t cbChunk = cbFileIn / cChunks;
[63392]118 unsigned long cFiles = 0;
[62766]119 size_t cbLimit = 0;
120 size_t cbWritten = 0;
121 unsigned long cIfNesting = 0;
[69772]122 unsigned long cWarningNesting = 0;
[62766]123 unsigned long cBraceNesting = 0;
124 unsigned long cLinesSinceStaticMap = ~0UL / 2;
125 bool fJustZero = false;
126
[26497]127 do
128 {
[62766]129 if (!pFileOut)
[26497]130 {
[62766]131 /* construct output filename */
132 char szFilename[1024];
[83223]133 sprintf(szFilename, "%s%lu.cpp", argv[2], ++cFiles);
[62766]134 szFilename[sizeof(szFilename)-1] = '\0';
[26497]135
[83223]136 size_t offName = strlen(szFilename);
137 while (offName > 0 && !RTPATH_IS_SEP(szFilename[offName - 1]))
138 offName -= 1;
139 printf("info: %s\n", &szFilename[offName]);
140
[62766]141 /* create output file */
142 pFileOut = fopen(szFilename, "wb");
143 if (!pFileOut)
144 {
145 fprintf(stderr, "split-soapC: Failed to open file \"%s\" for writing\n", szFilename);
146 rcExit = RTEXITCODE_FAILURE;
147 break;
148 }
149 if (cFiles > 1)
150 fprintf(pFileOut, "#include \"soapH.h\"%s\n",
151#ifdef RT_OS_WINDOWS
152 "\r"
153#else
154 ""
155#endif
156 );
157 cbLimit += cbChunk;
158 cLinesSinceStaticMap = ~0UL / 2;
[26497]159 }
160
[62766]161 /* find begin of next line and print current line */
162 const char *pszNextLine = strchr(pszLine, '\n');
163 size_t cbLine;
164 if (pszNextLine)
[26497]165 {
[62766]166 pszNextLine++;
167 cbLine = pszNextLine - pszLine;
[26497]168 }
[62766]169 else
170 cbLine = strlen(pszLine);
171 if (fwrite(pszLine, 1, cbLine, pFileOut) != cbLine)
[26497]172 {
[62766]173 fprintf(stderr, "split-soapC: Failed to write to output file\n");
174 rcExit = RTEXITCODE_FAILURE;
[26497]175 break;
176 }
[62766]177 cbWritten += cbLine;
[26497]178
[62766]179 /* process nesting depth information */
180 if (!strncmp(pszLine, "#if", 3))
181 cIfNesting++;
182 else if (!strncmp(pszLine, "#endif", 6))
[26497]183 {
[62766]184 cIfNesting--;
185 if (!cBraceNesting && !cIfNesting)
186 fJustZero = true;
[26497]187 }
[69772]188 else if (!strncmp(pszLine, RT_STR_TUPLE("#pragma warning(push)")))
189 cWarningNesting++;
190 else if (!strncmp(pszLine, RT_STR_TUPLE("#pragma warning(pop)")))
191 cWarningNesting--;
[62766]192 else
[26497]193 {
[62766]194 for (const char *p = pszLine; p < pszLine + cbLine; p++)
[26497]195 {
[62766]196 if (*p == '{')
197 cBraceNesting++;
198 else if (*p == '}')
[26497]199 {
[62766]200 cBraceNesting--;
201 if (!cBraceNesting && !cIfNesting)
202 fJustZero = true;
[26497]203 }
204 }
[62766]205 }
[26497]206
[62766]207 /* look for static variables used for enum conversion. */
208 if (!strncmp(pszLine, "static const struct soap_code_map", sizeof("static const struct soap_code_map") - 1))
209 cLinesSinceStaticMap = 0;
210 else
211 cLinesSinceStaticMap++;
[26497]212
[62766]213 /* start a new output file if necessary and possible */
214 if ( cbWritten >= cbLimit
215 && cIfNesting == 0
[69772]216 && cWarningNesting == 0
[62766]217 && fJustZero
218 && cFiles < cChunks
219 && cLinesSinceStaticMap > 150 /*hack!*/)
220 {
221 fclose(pFileOut);
222 pFileOut = NULL;
223 }
[26497]224
[62766]225 fJustZero = false;
226 pszLine = pszNextLine;
227 } while (pszLine);
[26497]228
[63392]229 printf("split-soapC: Created %lu files.\n", (unsigned long)cFiles);
[26497]230
[62766]231 free(pszBuffer);
[26497]232 if (pFileOut)
233 fclose(pFileOut);
234
[62766]235 return rcExit;
[26497]236}
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use