VirtualBox

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

Last change on this file since 72372 was 69772, checked in by vboxsync, 7 years ago

split-soapC.cpp: Must take warning pushing and poping into account when splitting.

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