VirtualBox

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

Last change on this file since 29532 was 28800, checked in by vboxsync, 15 years ago

Automated rebranding to Oracle copyright/license strings via filemuncher

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Revision
File size: 5.7 KB
Line 
1/** @file
2 * File splitter: splits a text file according to ###### markers in it.
3 */
4
5/*
6 * Copyright (C) 2006-2009 Oracle Corporation
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
17#include <sys/types.h>
18#include <sys/stat.h>
19#include <stdio.h>
20#include <string.h>
21#include <stdlib.h>
22
23static unsigned long lineNumber(const char *pStr, const char *pPos)
24{
25 unsigned long cLine = 0;
26 while (*pStr && pStr < pPos)
27 {
28 pStr = strchr(pStr, '\n');
29 if (!pStr)
30 break;
31 ++cLine;
32 ++pStr;
33 }
34
35 return cLine;
36}
37
38int main(int argc, char *argv[])
39{
40 int rc = 0;
41 const char *pcszBeginMarker = "\n// ##### BEGINFILE \"";
42 const char *pcszEndMarker = "\n// ##### ENDFILE";
43 const size_t cbBeginMarker = strlen(pcszBeginMarker);
44 FILE *pFileIn = NULL;
45 char *pBuffer = NULL;
46
47 do {
48 if (argc != 3)
49 {
50 fprintf(stderr, "filesplitter: Must be started with exactly two arguments,\n"
51 "1) the input file and 2) the directory where to put the output files\n");
52 rc = 2;
53 break;
54 }
55
56 struct stat lStat;
57 if ( stat(argv[2], &lStat) != 0
58 || (lStat.st_mode & S_IFMT) != S_IFDIR)
59 {
60 fprintf(stderr, "filesplitter: Given argument \"%s\" is not a valid directory.\n", argv[2]);
61 rc = 2;
62 break;
63 }
64
65 if ( stat(argv[1], &lStat)
66 || !(pFileIn = fopen(argv[1], "r")))
67 {
68 fprintf(stderr, "filesplitter: Cannot open file \"%s\" for reading.\n", argv[1]);
69 rc = 2;
70 break;
71 }
72
73 if (!(pBuffer = (char*)malloc(lStat.st_size + 1)))
74 {
75 fprintf(stderr, "filesplitter: Failed to allocate %ld bytes.\n", (long)lStat.st_size);
76 rc = 2;
77 break;
78 }
79
80 if (fread(pBuffer, 1, lStat.st_size, pFileIn) != lStat.st_size)
81 {
82 fprintf(stderr, "filesplitter: Failed to read %ld bytes from input file.\n", (long)lStat.st_size);
83 rc = 2;
84 break;
85 }
86 pBuffer[lStat.st_size] = '\0';
87
88 const char *pSearch = pBuffer;
89 unsigned long cFiles = 0;
90 size_t cbDirName = strlen(argv[2]);
91
92 do
93 {
94 /* find begin marker */
95 const char *pBegin = strstr(pSearch, pcszBeginMarker);
96 if (!pBegin)
97 break;
98
99 /* find line after begin marker */
100 const char *pLineAfterBegin = strchr(pBegin + cbBeginMarker, '\n');
101 if (!pLineAfterBegin)
102 {
103 fprintf(stderr, "filesplitter: No newline after begin-file marker found.\n");
104 rc = 2;
105 break;
106 }
107 ++pLineAfterBegin;
108
109 /* find second quote in begin marker line */
110 const char *pSecondQuote = strchr(pBegin + cbBeginMarker, '\"');
111 if ( !pSecondQuote
112 || pSecondQuote >= pLineAfterBegin)
113 {
114 fprintf(stderr, "filesplitter: Can't parse filename after begin-file marker (line %lu).\n", lineNumber(pBuffer, pcszBeginMarker));
115 rc = 2;
116 break;
117 }
118
119 /* find end marker */
120 const char *pEnd = strstr(pLineAfterBegin, pcszEndMarker);
121 if (!pEnd)
122 {
123 fprintf(stderr, "filesplitter: No matching end-line marker for begin-file marker found (line %lu).\n", lineNumber(pBuffer, pcszBeginMarker));
124 rc = 2;
125 break;
126 }
127
128 /* construct output filename */
129 char *pszFilename;
130 size_t cbFilename;
131 cbFilename = pSecondQuote - (pBegin + cbBeginMarker);
132 if (!(pszFilename = (char*)malloc(cbDirName + 1 + cbFilename + 1)))
133 {
134 fprintf(stderr, "filesplitter: Can't allocate memory for filename.\n");
135 rc = 2;
136 break;
137 }
138 memcpy(pszFilename, argv[2], cbDirName);
139 pszFilename[cbDirName] = '/';
140 memcpy(pszFilename + cbDirName + 1, pBegin + cbBeginMarker, cbFilename);
141 pszFilename[cbFilename + 1 + cbDirName] = '\0';
142
143 /* create output file and write file contents */
144 FILE *pFileOut;
145 if (!(pFileOut = fopen(pszFilename, "w")))
146 {
147 fprintf(stderr, "filesplitter: Failed to open file \"%s\" for writing\n", pszFilename);
148 rc = 2;
149 }
150 else
151 {
152 size_t cbFile = pEnd - pLineAfterBegin;
153 if (fwrite(pLineAfterBegin, 1, cbFile, pFileOut) != cbFile)
154 {
155 fprintf(stderr, "filesplitter: Failed to write %ld bytes to file \"%s\"\n", (long)cbFile, pszFilename);
156 rc = 2;
157 }
158
159 fclose(pFileOut);
160
161 if (!rc)
162 {
163 ++cFiles;
164 pSearch = strchr(pEnd, '\n');
165 }
166 }
167
168 free(pszFilename);
169
170 if (rc)
171 break;
172
173 } while (pSearch);
174
175 printf("filesplitter: Created %lu files.\n", cFiles);
176 } while (0);
177
178 if (pBuffer)
179 free(pBuffer);
180 if (pFileIn)
181 fclose(pFileIn);
182
183 return rc;
184}
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