VirtualBox

source: vbox/trunk/src/VBox/Main/webservice/filesplitter.cpp@ 25414

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

export to OSE

File size: 5.9 KB
Line 
1/** @file
2 * File splitter: splits a text file according to ###### markers in it.
3 */
4
5/*
6 * Copyright (C) 2006-2009 Sun Microsystems, Inc.
7 *
8 * This file is part of VirtualBox Open Source Edition (OSE), as
9 * available from http://www.virtualbox.org. This file is free software;
10 * you can redistribute it and/or modify it under the terms of the GNU
11 * General Public License (GPL) as published by the Free Software
12 * Foundation, in version 2 as it comes in the "COPYING" file of the
13 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
14 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
15 *
16 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
17 * Clara, CA 95054 USA or visit http://www.sun.com if you need
18 * additional information or have any questions.
19 */
20
21#include <sys/types.h>
22#include <sys/stat.h>
23#include <stdio.h>
24#include <string.h>
25#include <stdlib.h>
26
27static unsigned long lineNumber(const char *pStr, const char *pPos)
28{
29 unsigned long cLine = 0;
30 while (*pStr && pStr < pPos)
31 {
32 pStr = strchr(pStr, '\n');
33 if (!pStr)
34 break;
35 ++cLine;
36 ++pStr;
37 }
38
39 return cLine;
40}
41
42int main(int argc, char *argv[])
43{
44 int rc = 0;
45 const char *pcszBeginMarker = "\n// ##### BEGINFILE \"";
46 const char *pcszEndMarker = "\n// ##### ENDFILE";
47 const size_t cbBeginMarker = strlen(pcszBeginMarker);
48 FILE *pFileIn = NULL;
49 char *pBuffer = NULL;
50
51 do {
52 if (argc != 3)
53 {
54 fprintf(stderr, "filesplitter: Must be started with exactly two arguments,\n"
55 "1) the input file and 2) the directory where to put the output files\n");
56 rc = 2;
57 break;
58 }
59
60 struct stat lStat;
61 if ( stat(argv[2], &lStat) != 0
62 || (lStat.st_mode & S_IFMT) != S_IFDIR)
63 {
64 fprintf(stderr, "filesplitter: Given argument \"%s\" is not a valid directory.\n", argv[2]);
65 rc = 2;
66 break;
67 }
68
69 if ( stat(argv[1], &lStat)
70 || !(pFileIn = fopen(argv[1], "r")))
71 {
72 fprintf(stderr, "filesplitter: Cannot open file \"%s\" for reading.\n", argv[1]);
73 rc = 2;
74 break;
75 }
76
77 if (!(pBuffer = (char*)malloc(lStat.st_size + 1)))
78 {
79 fprintf(stderr, "filesplitter: Failed to allocate %ld bytes.\n", (long)lStat.st_size);
80 rc = 2;
81 break;
82 }
83
84 if (fread(pBuffer, 1, lStat.st_size, pFileIn) != lStat.st_size)
85 {
86 fprintf(stderr, "filesplitter: Failed to read %ld bytes from input file.\n", (long)lStat.st_size);
87 rc = 2;
88 break;
89 }
90 pBuffer[lStat.st_size] = '\0';
91
92 const char *pSearch = pBuffer;
93 unsigned long cFiles = 0;
94 size_t cbDirName = strlen(argv[2]);
95
96 do
97 {
98 /* find begin marker */
99 const char *pBegin = strstr(pSearch, pcszBeginMarker);
100 if (!pBegin)
101 break;
102
103 /* find line after begin marker */
104 const char *pLineAfterBegin = strchr(pBegin + cbBeginMarker, '\n');
105 if (!pLineAfterBegin)
106 {
107 fprintf(stderr, "filesplitter: No newline after begin-file marker found.\n");
108 rc = 2;
109 break;
110 }
111 ++pLineAfterBegin;
112
113 /* find second quote in begin marker line */
114 const char *pSecondQuote = strchr(pBegin + cbBeginMarker, '\"');
115 if ( !pSecondQuote
116 || pSecondQuote >= pLineAfterBegin)
117 {
118 fprintf(stderr, "filesplitter: Can't parse filename after begin-file marker (line %lu).\n", lineNumber(pBuffer, pcszBeginMarker));
119 rc = 2;
120 break;
121 }
122
123 /* find end marker */
124 const char *pEnd = strstr(pLineAfterBegin, pcszEndMarker);
125 if (!pEnd)
126 {
127 fprintf(stderr, "filesplitter: No matching end-line marker for begin-file marker found (line %lu).\n", lineNumber(pBuffer, pcszBeginMarker));
128 rc = 2;
129 break;
130 }
131
132 /* construct output filename */
133 char *pszFilename;
134 size_t cbFilename;
135 cbFilename = pSecondQuote - (pBegin + cbBeginMarker);
136 if (!(pszFilename = (char*)malloc(cbDirName + 1 + cbFilename + 1)))
137 {
138 fprintf(stderr, "filesplitter: Can't allocate memory for filename.\n");
139 rc = 2;
140 break;
141 }
142 memcpy(pszFilename, argv[2], cbDirName);
143 pszFilename[cbDirName] = '/';
144 memcpy(pszFilename + cbDirName + 1, pBegin + cbBeginMarker, cbFilename);
145 pszFilename[cbFilename + 1 + cbDirName] = '\0';
146
147 /* create output file and write file contents */
148 FILE *pFileOut;
149 if (!(pFileOut = fopen(pszFilename, "w")))
150 {
151 fprintf(stderr, "filesplitter: Failed to open file \"%s\" for writing\n", pszFilename);
152 rc = 2;
153 }
154 else
155 {
156 size_t cbFile = pEnd - pLineAfterBegin;
157 if (fwrite(pLineAfterBegin, 1, cbFile, pFileOut) != cbFile)
158 {
159 fprintf(stderr, "filesplitter: Failed to write %ld bytes to file \"%s\"\n", (long)cbFile, pszFilename);
160 rc = 2;
161 }
162
163 fclose(pFileOut);
164
165 if (!rc)
166 {
167 ++cFiles;
168 pSearch = strchr(pEnd, '\n');
169 }
170 }
171
172 free(pszFilename);
173
174 if (rc)
175 break;
176
177 } while (pSearch);
178
179 printf("filesplitter: Created %lu files.\n", cFiles);
180 } while (0);
181
182 if (pBuffer)
183 free(pBuffer);
184 if (pFileIn)
185 fclose(pFileIn);
186
187 return rc;
188}
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use