VirtualBox

source: vbox/trunk/src/bldprogs/filesplitter.cpp@ 35761

Last change on this file since 35761 was 29822, checked in by vboxsync, 14 years ago

nits.

  • 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 {
49 if (argc != 3)
50 {
51 fprintf(stderr, "filesplitter: Must be started with exactly two arguments,\n"
52 "1) the input file and 2) the directory where to put the output files\n");
53 rc = 2;
54 break;
55 }
56
57 struct stat lStat;
58 if ( stat(argv[2], &lStat) != 0
59 || (lStat.st_mode & S_IFDIR) != S_IFDIR)
60 {
61 fprintf(stderr, "filesplitter: Given argument \"%s\" is not a valid directory.\n", argv[2]);
62 rc = 2;
63 break;
64 }
65
66 if ( stat(argv[1], &lStat)
67 || !(pFileIn = fopen(argv[1], "r")))
68 {
69 fprintf(stderr, "filesplitter: Cannot open file \"%s\" for reading.\n", argv[1]);
70 rc = 2;
71 break;
72 }
73
74 if (!(pBuffer = (char*)malloc(lStat.st_size + 1)))
75 {
76 fprintf(stderr, "filesplitter: Failed to allocate %ld bytes.\n", (long)lStat.st_size);
77 rc = 2;
78 break;
79 }
80
81 if (fread(pBuffer, 1, lStat.st_size, pFileIn) != lStat.st_size)
82 {
83 fprintf(stderr, "filesplitter: Failed to read %ld bytes from input file.\n", (long)lStat.st_size);
84 rc = 2;
85 break;
86 }
87 pBuffer[lStat.st_size] = '\0';
88
89 const char *pSearch = pBuffer;
90 unsigned long cFiles = 0;
91 size_t cbDirName = strlen(argv[2]);
92
93 do
94 {
95 /* find begin marker */
96 const char *pBegin = strstr(pSearch, pcszBeginMarker);
97 if (!pBegin)
98 break;
99
100 /* find line after begin marker */
101 const char *pLineAfterBegin = strchr(pBegin + cbBeginMarker, '\n');
102 if (!pLineAfterBegin)
103 {
104 fprintf(stderr, "filesplitter: No newline after begin-file marker found.\n");
105 rc = 2;
106 break;
107 }
108 ++pLineAfterBegin;
109
110 /* find second quote in begin marker line */
111 const char *pSecondQuote = strchr(pBegin + cbBeginMarker, '\"');
112 if ( !pSecondQuote
113 || pSecondQuote >= pLineAfterBegin)
114 {
115 fprintf(stderr, "filesplitter: Can't parse filename after begin-file marker (line %lu).\n", lineNumber(pBuffer, pcszBeginMarker));
116 rc = 2;
117 break;
118 }
119
120 /* find end marker */
121 const char *pEnd = strstr(pLineAfterBegin, pcszEndMarker);
122 if (!pEnd)
123 {
124 fprintf(stderr, "filesplitter: No matching end-line marker for begin-file marker found (line %lu).\n", lineNumber(pBuffer, pcszBeginMarker));
125 rc = 2;
126 break;
127 }
128
129 /* construct output filename */
130 char *pszFilename;
131 size_t cbFilename;
132 cbFilename = pSecondQuote - (pBegin + cbBeginMarker);
133 if (!(pszFilename = (char*)malloc(cbDirName + 1 + cbFilename + 1)))
134 {
135 fprintf(stderr, "filesplitter: Can't allocate memory for filename.\n");
136 rc = 2;
137 break;
138 }
139 memcpy(pszFilename, argv[2], cbDirName);
140 pszFilename[cbDirName] = '/';
141 memcpy(pszFilename + cbDirName + 1, pBegin + cbBeginMarker, cbFilename);
142 pszFilename[cbFilename + 1 + cbDirName] = '\0';
143
144 /* create output file and write file contents */
145 FILE *pFileOut;
146 if (!(pFileOut = fopen(pszFilename, "w")))
147 {
148 fprintf(stderr, "filesplitter: Failed to open file \"%s\" for writing\n", pszFilename);
149 rc = 2;
150 }
151 else
152 {
153 size_t cbFile = pEnd - pLineAfterBegin;
154 if (fwrite(pLineAfterBegin, 1, cbFile, pFileOut) != cbFile)
155 {
156 fprintf(stderr, "filesplitter: Failed to write %ld bytes to file \"%s\"\n", (long)cbFile, pszFilename);
157 rc = 2;
158 }
159
160 fclose(pFileOut);
161
162 if (!rc)
163 {
164 ++cFiles;
165 pSearch = strchr(pEnd, '\n');
166 }
167 }
168
169 free(pszFilename);
170
171 if (rc)
172 break;
173
174 } while (pSearch);
175
176 printf("filesplitter: Created %lu files.\n", cFiles);
177 } while (0);
178
179 if (pBuffer)
180 free(pBuffer);
181 if (pFileIn)
182 fclose(pFileIn);
183
184 return rc;
185}
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