VirtualBox

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

Last change on this file since 25414 was 24220, checked in by vboxsync, 15 years ago

split-soapC.cpp: warnings and seek checks.

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

© 2023 Oracle
ContactPrivacy policyTerms of Use