VirtualBox

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

Last change on this file since 49935 was 46327, checked in by vboxsync, 12 years ago

not here

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