VirtualBox

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

Last change on this file since 91312 was 83223, checked in by vboxsync, 5 years ago

webservice: Strip inline functions from soapH.h and put them in separate C++ files to speed up compilation and avoid gcc 9.2+ internal compiler error. This avoid having to compile soapC.cpp in one go with gcc 9.2+ and waste ages waiting for that to complete (yeah, even with -O0 that takes forever).

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

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