319f8f820db4356edaff70c2e019376e1ec71487vboxsync/** @file
319f8f820db4356edaff70c2e019376e1ec71487vboxsync * File splitter: splits soapC.cpp into manageable pieces. It is somewhat
319f8f820db4356edaff70c2e019376e1ec71487vboxsync * intelligent and avoids splitting inside functions or similar places.
319f8f820db4356edaff70c2e019376e1ec71487vboxsync */
319f8f820db4356edaff70c2e019376e1ec71487vboxsync
319f8f820db4356edaff70c2e019376e1ec71487vboxsync/*
c7814cf6e1240a519cbec0441e033d0e2470ed00vboxsync * Copyright (C) 2009-2010 Oracle Corporation
a3e5b1cf4ab5395f45b7ed855c72f70e4bcf4219vboxsync *
a3e5b1cf4ab5395f45b7ed855c72f70e4bcf4219vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
a3e5b1cf4ab5395f45b7ed855c72f70e4bcf4219vboxsync * available from http://www.virtualbox.org. This file is free software;
a3e5b1cf4ab5395f45b7ed855c72f70e4bcf4219vboxsync * you can redistribute it and/or modify it under the terms of the GNU
a3e5b1cf4ab5395f45b7ed855c72f70e4bcf4219vboxsync * General Public License (GPL) as published by the Free Software
a3e5b1cf4ab5395f45b7ed855c72f70e4bcf4219vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
a3e5b1cf4ab5395f45b7ed855c72f70e4bcf4219vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
a3e5b1cf4ab5395f45b7ed855c72f70e4bcf4219vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
319f8f820db4356edaff70c2e019376e1ec71487vboxsync */
319f8f820db4356edaff70c2e019376e1ec71487vboxsync
319f8f820db4356edaff70c2e019376e1ec71487vboxsync#include <sys/types.h>
319f8f820db4356edaff70c2e019376e1ec71487vboxsync#include <stdio.h>
319f8f820db4356edaff70c2e019376e1ec71487vboxsync#include <string.h>
319f8f820db4356edaff70c2e019376e1ec71487vboxsync#include <stdlib.h>
319f8f820db4356edaff70c2e019376e1ec71487vboxsync#include <limits.h>
319f8f820db4356edaff70c2e019376e1ec71487vboxsync
319f8f820db4356edaff70c2e019376e1ec71487vboxsync
319f8f820db4356edaff70c2e019376e1ec71487vboxsyncint main(int argc, char *argv[])
319f8f820db4356edaff70c2e019376e1ec71487vboxsync{
319f8f820db4356edaff70c2e019376e1ec71487vboxsync int rc = 0;
319f8f820db4356edaff70c2e019376e1ec71487vboxsync FILE *pFileIn = NULL;
319f8f820db4356edaff70c2e019376e1ec71487vboxsync FILE *pFileOut = NULL;
319f8f820db4356edaff70c2e019376e1ec71487vboxsync char *pBuffer = NULL;
319f8f820db4356edaff70c2e019376e1ec71487vboxsync
319f8f820db4356edaff70c2e019376e1ec71487vboxsync do
319f8f820db4356edaff70c2e019376e1ec71487vboxsync {
319f8f820db4356edaff70c2e019376e1ec71487vboxsync if (argc != 4)
319f8f820db4356edaff70c2e019376e1ec71487vboxsync {
319f8f820db4356edaff70c2e019376e1ec71487vboxsync fprintf(stderr, "split-soapC: Must be started with exactly three arguments,\n"
319f8f820db4356edaff70c2e019376e1ec71487vboxsync "1) the input file, 2) the directory where to put the output files and\n"
319f8f820db4356edaff70c2e019376e1ec71487vboxsync "3) the number chunks to create.\n");
319f8f820db4356edaff70c2e019376e1ec71487vboxsync rc = 2;
319f8f820db4356edaff70c2e019376e1ec71487vboxsync break;
319f8f820db4356edaff70c2e019376e1ec71487vboxsync }
319f8f820db4356edaff70c2e019376e1ec71487vboxsync
319f8f820db4356edaff70c2e019376e1ec71487vboxsync char *pEnd = NULL;
319f8f820db4356edaff70c2e019376e1ec71487vboxsync unsigned long cChunk = strtoul(argv[3], &pEnd, 0);
319f8f820db4356edaff70c2e019376e1ec71487vboxsync if (cChunk == ULONG_MAX || cChunk == 0 || !argv[3] || *pEnd)
319f8f820db4356edaff70c2e019376e1ec71487vboxsync {
319f8f820db4356edaff70c2e019376e1ec71487vboxsync fprintf(stderr, "split-soapC: Given argument \"%s\" is not a valid chunk count.\n", argv[3]);
319f8f820db4356edaff70c2e019376e1ec71487vboxsync rc = 2;
319f8f820db4356edaff70c2e019376e1ec71487vboxsync break;
319f8f820db4356edaff70c2e019376e1ec71487vboxsync }
319f8f820db4356edaff70c2e019376e1ec71487vboxsync
319f8f820db4356edaff70c2e019376e1ec71487vboxsync pFileIn = fopen(argv[1], "rb");
319f8f820db4356edaff70c2e019376e1ec71487vboxsync if (!pFileIn)
319f8f820db4356edaff70c2e019376e1ec71487vboxsync {
319f8f820db4356edaff70c2e019376e1ec71487vboxsync fprintf(stderr, "split-soapC: Cannot open file \"%s\" for reading.\n", argv[1]);
319f8f820db4356edaff70c2e019376e1ec71487vboxsync rc = 2;
319f8f820db4356edaff70c2e019376e1ec71487vboxsync break;
319f8f820db4356edaff70c2e019376e1ec71487vboxsync }
319f8f820db4356edaff70c2e019376e1ec71487vboxsync int rc2 = fseek(pFileIn, 0, SEEK_END);
319f8f820db4356edaff70c2e019376e1ec71487vboxsync long cbFileIn = ftell(pFileIn);
319f8f820db4356edaff70c2e019376e1ec71487vboxsync int rc3 = fseek(pFileIn, 0, SEEK_SET);
319f8f820db4356edaff70c2e019376e1ec71487vboxsync if (rc3 == -1 || rc2 == -1 || cbFileIn < 0)
319f8f820db4356edaff70c2e019376e1ec71487vboxsync {
319f8f820db4356edaff70c2e019376e1ec71487vboxsync fprintf(stderr, "split-soapC: Seek failure.\n");
319f8f820db4356edaff70c2e019376e1ec71487vboxsync rc = 2;
319f8f820db4356edaff70c2e019376e1ec71487vboxsync break;
319f8f820db4356edaff70c2e019376e1ec71487vboxsync }
319f8f820db4356edaff70c2e019376e1ec71487vboxsync
319f8f820db4356edaff70c2e019376e1ec71487vboxsync if (!(pBuffer = (char*)malloc(cbFileIn + 1)))
319f8f820db4356edaff70c2e019376e1ec71487vboxsync {
319f8f820db4356edaff70c2e019376e1ec71487vboxsync fprintf(stderr, "split-soapC: Failed to allocate %ld bytes.\n", cbFileIn);
319f8f820db4356edaff70c2e019376e1ec71487vboxsync rc = 2;
319f8f820db4356edaff70c2e019376e1ec71487vboxsync break;
319f8f820db4356edaff70c2e019376e1ec71487vboxsync }
319f8f820db4356edaff70c2e019376e1ec71487vboxsync
319f8f820db4356edaff70c2e019376e1ec71487vboxsync if (fread(pBuffer, 1, cbFileIn, pFileIn) != (size_t)cbFileIn)
319f8f820db4356edaff70c2e019376e1ec71487vboxsync {
319f8f820db4356edaff70c2e019376e1ec71487vboxsync fprintf(stderr, "split-soapC: Failed to read %ld bytes from input file.\n", cbFileIn);
319f8f820db4356edaff70c2e019376e1ec71487vboxsync rc = 2;
319f8f820db4356edaff70c2e019376e1ec71487vboxsync break;
319f8f820db4356edaff70c2e019376e1ec71487vboxsync }
319f8f820db4356edaff70c2e019376e1ec71487vboxsync pBuffer[cbFileIn] = '\0';
319f8f820db4356edaff70c2e019376e1ec71487vboxsync
319f8f820db4356edaff70c2e019376e1ec71487vboxsync const char *pLine = pBuffer;
319f8f820db4356edaff70c2e019376e1ec71487vboxsync unsigned long cbChunk = cbFileIn / cChunk;
319f8f820db4356edaff70c2e019376e1ec71487vboxsync unsigned long cFiles = 0;
319f8f820db4356edaff70c2e019376e1ec71487vboxsync unsigned long uLimit = 0;
319f8f820db4356edaff70c2e019376e1ec71487vboxsync unsigned long cbWritten = 0;
319f8f820db4356edaff70c2e019376e1ec71487vboxsync unsigned long cIfNesting = 0;
319f8f820db4356edaff70c2e019376e1ec71487vboxsync unsigned long cBraceNesting = 0;
319f8f820db4356edaff70c2e019376e1ec71487vboxsync unsigned long cLinesSinceStaticMap = ~0UL / 2;
319f8f820db4356edaff70c2e019376e1ec71487vboxsync bool fJustZero = false;
319f8f820db4356edaff70c2e019376e1ec71487vboxsync
319f8f820db4356edaff70c2e019376e1ec71487vboxsync do
319f8f820db4356edaff70c2e019376e1ec71487vboxsync {
319f8f820db4356edaff70c2e019376e1ec71487vboxsync if (!pFileOut)
319f8f820db4356edaff70c2e019376e1ec71487vboxsync {
319f8f820db4356edaff70c2e019376e1ec71487vboxsync /* construct output filename */
319f8f820db4356edaff70c2e019376e1ec71487vboxsync char szFilename[1024];
319f8f820db4356edaff70c2e019376e1ec71487vboxsync sprintf(szFilename, "%s/soapC-%lu.cpp", argv[2], ++cFiles);
319f8f820db4356edaff70c2e019376e1ec71487vboxsync szFilename[sizeof(szFilename)-1] = '\0';
319f8f820db4356edaff70c2e019376e1ec71487vboxsync printf("info: soapC-%lu.cpp\n", cFiles);
319f8f820db4356edaff70c2e019376e1ec71487vboxsync
319f8f820db4356edaff70c2e019376e1ec71487vboxsync /* create output file */
319f8f820db4356edaff70c2e019376e1ec71487vboxsync if (!(pFileOut = fopen(szFilename, "wb")))
319f8f820db4356edaff70c2e019376e1ec71487vboxsync {
319f8f820db4356edaff70c2e019376e1ec71487vboxsync fprintf(stderr, "split-soapC: Failed to open file \"%s\" for writing\n", szFilename);
319f8f820db4356edaff70c2e019376e1ec71487vboxsync rc = 2;
319f8f820db4356edaff70c2e019376e1ec71487vboxsync break;
319f8f820db4356edaff70c2e019376e1ec71487vboxsync }
319f8f820db4356edaff70c2e019376e1ec71487vboxsync if (cFiles > 1)
319f8f820db4356edaff70c2e019376e1ec71487vboxsync fprintf(pFileOut, "#include \"soapH.h\"%s\n",
319f8f820db4356edaff70c2e019376e1ec71487vboxsync#ifdef RT_OS_WINDOWS
319f8f820db4356edaff70c2e019376e1ec71487vboxsync "\r"
319f8f820db4356edaff70c2e019376e1ec71487vboxsync#else /* !RT_OS_WINDOWS */
319f8f820db4356edaff70c2e019376e1ec71487vboxsync ""
319f8f820db4356edaff70c2e019376e1ec71487vboxsync#endif /* !RT_OS_WINDOWS */
319f8f820db4356edaff70c2e019376e1ec71487vboxsync );
319f8f820db4356edaff70c2e019376e1ec71487vboxsync uLimit += cbChunk;
319f8f820db4356edaff70c2e019376e1ec71487vboxsync cLinesSinceStaticMap = ~0UL / 2;
319f8f820db4356edaff70c2e019376e1ec71487vboxsync }
319f8f820db4356edaff70c2e019376e1ec71487vboxsync
319f8f820db4356edaff70c2e019376e1ec71487vboxsync /* find begin of next line and print current line */
319f8f820db4356edaff70c2e019376e1ec71487vboxsync const char *pNextLine = strchr(pLine, '\n');
319f8f820db4356edaff70c2e019376e1ec71487vboxsync size_t cbLine;
319f8f820db4356edaff70c2e019376e1ec71487vboxsync if (pNextLine)
319f8f820db4356edaff70c2e019376e1ec71487vboxsync {
319f8f820db4356edaff70c2e019376e1ec71487vboxsync pNextLine++;
319f8f820db4356edaff70c2e019376e1ec71487vboxsync cbLine = pNextLine - pLine;
319f8f820db4356edaff70c2e019376e1ec71487vboxsync }
319f8f820db4356edaff70c2e019376e1ec71487vboxsync else
319f8f820db4356edaff70c2e019376e1ec71487vboxsync cbLine = strlen(pLine);
319f8f820db4356edaff70c2e019376e1ec71487vboxsync if (fwrite(pLine, 1, cbLine, pFileOut) != cbLine)
319f8f820db4356edaff70c2e019376e1ec71487vboxsync {
319f8f820db4356edaff70c2e019376e1ec71487vboxsync fprintf(stderr, "split-soapC: Failed to write to output file\n");
319f8f820db4356edaff70c2e019376e1ec71487vboxsync rc = 2;
319f8f820db4356edaff70c2e019376e1ec71487vboxsync break;
319f8f820db4356edaff70c2e019376e1ec71487vboxsync }
319f8f820db4356edaff70c2e019376e1ec71487vboxsync cbWritten += cbLine;
319f8f820db4356edaff70c2e019376e1ec71487vboxsync
319f8f820db4356edaff70c2e019376e1ec71487vboxsync /* process nesting depth information */
4416c4532cd042735f08cdc4c5ea825f4faf6b25vboxsync if (!strncmp(pLine, "#if", 3))
319f8f820db4356edaff70c2e019376e1ec71487vboxsync cIfNesting++;
4416c4532cd042735f08cdc4c5ea825f4faf6b25vboxsync else if (!strncmp(pLine, "#endif", 6))
319f8f820db4356edaff70c2e019376e1ec71487vboxsync {
319f8f820db4356edaff70c2e019376e1ec71487vboxsync cIfNesting--;
319f8f820db4356edaff70c2e019376e1ec71487vboxsync if (!cBraceNesting && !cIfNesting)
319f8f820db4356edaff70c2e019376e1ec71487vboxsync fJustZero = true;
319f8f820db4356edaff70c2e019376e1ec71487vboxsync }
319f8f820db4356edaff70c2e019376e1ec71487vboxsync else
319f8f820db4356edaff70c2e019376e1ec71487vboxsync {
319f8f820db4356edaff70c2e019376e1ec71487vboxsync for (const char *p = pLine; p < pLine + cbLine; p++)
319f8f820db4356edaff70c2e019376e1ec71487vboxsync {
319f8f820db4356edaff70c2e019376e1ec71487vboxsync if (*p == '{')
319f8f820db4356edaff70c2e019376e1ec71487vboxsync cBraceNesting++;
319f8f820db4356edaff70c2e019376e1ec71487vboxsync else if (*p == '}')
319f8f820db4356edaff70c2e019376e1ec71487vboxsync {
319f8f820db4356edaff70c2e019376e1ec71487vboxsync cBraceNesting--;
319f8f820db4356edaff70c2e019376e1ec71487vboxsync if (!cBraceNesting && !cIfNesting)
319f8f820db4356edaff70c2e019376e1ec71487vboxsync fJustZero = true;
319f8f820db4356edaff70c2e019376e1ec71487vboxsync }
319f8f820db4356edaff70c2e019376e1ec71487vboxsync }
319f8f820db4356edaff70c2e019376e1ec71487vboxsync }
319f8f820db4356edaff70c2e019376e1ec71487vboxsync
319f8f820db4356edaff70c2e019376e1ec71487vboxsync /* look for static variables used for enum conversion. */
4416c4532cd042735f08cdc4c5ea825f4faf6b25vboxsync if (!strncmp(pLine, "static const struct soap_code_map", sizeof("static const struct soap_code_map") - 1))
319f8f820db4356edaff70c2e019376e1ec71487vboxsync cLinesSinceStaticMap = 0;
319f8f820db4356edaff70c2e019376e1ec71487vboxsync else
319f8f820db4356edaff70c2e019376e1ec71487vboxsync cLinesSinceStaticMap++;
319f8f820db4356edaff70c2e019376e1ec71487vboxsync
319f8f820db4356edaff70c2e019376e1ec71487vboxsync /* start a new output file if necessary and possible */
319f8f820db4356edaff70c2e019376e1ec71487vboxsync if ( cbWritten >= uLimit
319f8f820db4356edaff70c2e019376e1ec71487vboxsync && cIfNesting == 0
319f8f820db4356edaff70c2e019376e1ec71487vboxsync && fJustZero
319f8f820db4356edaff70c2e019376e1ec71487vboxsync && cFiles < cChunk
319f8f820db4356edaff70c2e019376e1ec71487vboxsync && cLinesSinceStaticMap > 150 /*hack!*/)
319f8f820db4356edaff70c2e019376e1ec71487vboxsync {
319f8f820db4356edaff70c2e019376e1ec71487vboxsync fclose(pFileOut);
319f8f820db4356edaff70c2e019376e1ec71487vboxsync pFileOut = NULL;
319f8f820db4356edaff70c2e019376e1ec71487vboxsync }
319f8f820db4356edaff70c2e019376e1ec71487vboxsync
319f8f820db4356edaff70c2e019376e1ec71487vboxsync if (rc)
319f8f820db4356edaff70c2e019376e1ec71487vboxsync break;
319f8f820db4356edaff70c2e019376e1ec71487vboxsync
319f8f820db4356edaff70c2e019376e1ec71487vboxsync fJustZero = false;
319f8f820db4356edaff70c2e019376e1ec71487vboxsync pLine = pNextLine;
319f8f820db4356edaff70c2e019376e1ec71487vboxsync } while (pLine);
319f8f820db4356edaff70c2e019376e1ec71487vboxsync
319f8f820db4356edaff70c2e019376e1ec71487vboxsync printf("split-soapC: Created %lu files.\n", cFiles);
319f8f820db4356edaff70c2e019376e1ec71487vboxsync } while (0);
319f8f820db4356edaff70c2e019376e1ec71487vboxsync
319f8f820db4356edaff70c2e019376e1ec71487vboxsync if (pBuffer)
319f8f820db4356edaff70c2e019376e1ec71487vboxsync free(pBuffer);
319f8f820db4356edaff70c2e019376e1ec71487vboxsync if (pFileIn)
319f8f820db4356edaff70c2e019376e1ec71487vboxsync fclose(pFileIn);
319f8f820db4356edaff70c2e019376e1ec71487vboxsync if (pFileOut)
319f8f820db4356edaff70c2e019376e1ec71487vboxsync fclose(pFileOut);
319f8f820db4356edaff70c2e019376e1ec71487vboxsync
319f8f820db4356edaff70c2e019376e1ec71487vboxsync return rc;
319f8f820db4356edaff70c2e019376e1ec71487vboxsync}