11 #include "Exception.h"
12 #include "OffsetFile.h"
13 #include "ResourceFile.h"
16 const char kUsage
[] = {
17 "Usage: %s <options> <filenames>\n"
19 " -h, --help print this help\n"
20 " -l, --list list each file's resources (short version)\n"
21 " -L, --list-long list each file's resources (long version)\n"
22 " -s, --summary print a summary\n"
23 " -w, --write-test write the file resources (in memory only) and\n"
24 " compare the data with the file's\n"
27 const status_t USAGE_ERROR
= B_ERRORS_END
+ 1;
28 const status_t USAGE_HELP
= B_ERRORS_END
+ 2;
37 listing_level listing
;
43 TestResult(const char* filename
)
44 : filename(filename
), warnings(), exception(NULL
)
60 print_indented(const char* str
, uint32 chars
, bool indentFirst
= true)
62 const uint32 MAX_CHARS_PER_LINE
= 75;
63 int32 charsLeft
= strlen(str
);
64 if (chars
< MAX_CHARS_PER_LINE
) {
65 for (int32 line
= 0; charsLeft
> 0; line
++) {
66 if (line
!= 0 || indentFirst
) {
67 for (int32 i
= 0; (uint32
)i
< chars
; i
++)
70 int32 bytesLeftOnLine
= MAX_CHARS_PER_LINE
- chars
;
71 int32 printChars
= min(bytesLeftOnLine
, charsLeft
);
72 printf("%.*s\n", (int)printChars
, str
);
74 charsLeft
-= printChars
;
86 print_indented(const char* indentStr
, const char* str
)
88 uint32 chars
= strlen(indentStr
);
90 print_indented(str
, chars
, false);
95 parse_arguments(int argc
, const char* const* argv
, BList
& files
,
99 options
.listing
= NO_LISTING
;
100 options
.write_test
= false;
101 options
.summary
= false;
103 for (int32 i
= 1; i
< argc
; i
++) {
104 const char* arg
= argv
[i
];
105 int32 len
= strlen(arg
);
107 throw Exception(USAGE_ERROR
, "Illegal argument: `'.");
110 throw Exception(USAGE_ERROR
, "Illegal argument: `-'.");
112 const char* option
= arg
+ 2;
114 if (!strcmp(option
, "help")) {
115 throw Exception(USAGE_HELP
);
117 } else if (!strcmp(option
, "list")) {
118 if (options
.listing
== NO_LISTING
)
119 options
.listing
= SHORT_LISTING
;
121 } else if (!strcmp(option
, "list-long")) {
122 options
.listing
= LONG_LISTING
;
124 } else if (!strcmp(option
, "summary")) {
125 options
.summary
= true;
127 } else if (!strcmp(option
, "write-test")) {
128 options
.write_test
= true;
131 throw Exception(USAGE_ERROR
, BString("Illegal option: `")
135 for (int32 i
= 1; i
< len
; i
++) {
136 char option
= arg
[i
];
140 throw Exception(USAGE_HELP
);
144 if (options
.listing
== NO_LISTING
)
145 options
.listing
= SHORT_LISTING
;
149 options
.listing
= LONG_LISTING
;
153 options
.summary
= true;
157 options
.write_test
= true;
161 throw Exception(USAGE_ERROR
,
162 BString("Illegal option: `")
169 files
.AddItem(const_cast<char*>(arg
));
175 test_file(const char* filename
, const TestOptions
& options
,
176 TestResult
& testResult
)
178 Warnings::SetCurrentWarnings(&testResult
.warnings
);
179 ResourceFile resFile
;
181 // check if the file exists
182 BEntry
entry(filename
, true);
183 status_t error
= entry
.InitCheck();
185 throw Exception(error
);
186 if (!entry
.Exists() || !entry
.IsFile())
187 throw Exception("Entry doesn't exist or is no regular file.");
190 BFile
file(filename
, B_READ_ONLY
);
191 error
= file
.InitCheck();
193 throw Exception(error
, "Failed to open file.");
194 // do the actual test
196 if (options
.write_test
)
198 } catch (Exception exception
) {
199 testResult
.exception
= new Exception(exception
);
201 Warnings::SetCurrentWarnings(NULL
);
202 // print warnings and error
203 if (options
.listing
!= NO_LISTING
204 || testResult
.warnings
.CountWarnings() > 0 || testResult
.exception
) {
205 printf("\nFile `%s':\n", filename
);
208 if (testResult
.warnings
.CountWarnings() > 0) {
210 const char* warning
= testResult
.warnings
.WarningAt(i
);
212 print_indented(" Warning: ", warning
);
216 if (testResult
.exception
) {
217 status_t error
= testResult
.exception
->GetError();
218 const char* description
= testResult
.exception
->GetDescription();
219 if (strlen(description
) > 0) {
220 print_indented(" Error: ", description
);
222 print_indented(" ", strerror(error
));
223 } else if (error
!= B_OK
)
224 print_indented(" Error: ", strerror(error
));
227 if (resFile
.InitCheck() == B_OK
) {
228 switch (options
.listing
) {
232 resFile
.PrintToStream(false);
235 resFile
.PrintToStream(true);
243 test_files(BList
& files
, TestOptions
& options
)
246 int32 successTestCount
= 0;
247 int32 warningTestCount
= 0;
248 int32 failedTestCount
= 0;
250 const char* filename
= (const char*)files
.ItemAt(i
);
252 TestResult
* testResult
= new TestResult(filename
);
253 testResults
.AddItem(testResult
);
254 test_file(filename
, options
, *testResult
);
255 if (testResult
->exception
)
257 else if (testResult
->warnings
.CountWarnings() > 0)
263 if (options
.summary
) {
264 printf("\nSummary:\n");
265 printf( "=======\n");
267 if (successTestCount
> 0) {
268 if (successTestCount
== 1)
269 printf("one successful test\n");
271 printf("%ld successful tests\n", successTestCount
);
273 // tests with warnings
274 if (warningTestCount
> 0) {
275 if (warningTestCount
== 1)
276 printf("one test with warnings:\n");
278 printf("%ld tests with warnings:\n", warningTestCount
);
280 TestResult
* testResult
= (TestResult
*)testResults
.ItemAt(i
);
282 if (!testResult
->exception
283 && testResult
->warnings
.CountWarnings() > 0) {
284 printf(" `%s'\n", testResult
->filename
.String());
289 if (failedTestCount
> 0) {
290 if (failedTestCount
== 1)
291 printf("one test failed:\n");
293 printf("%ld tests failed:\n", failedTestCount
);
295 TestResult
* testResult
= (TestResult
*)testResults
.ItemAt(i
);
297 if (testResult
->exception
)
298 printf(" `%s'\n", testResult
->filename
.String());
304 TestResult
* testResult
= (TestResult
*)testResults
.ItemAt(i
);
312 main(int argc
, const char* const* argv
)
315 const char* cmdName
= argv
[0];
320 parse_arguments(argc
, argv
, files
, options
);
321 if (files
.CountItems() == 0)
322 throw Exception(USAGE_ERROR
, "No files given.");
324 test_files(files
, options
);
325 } catch (Exception exception
) {
326 status_t error
= exception
.GetError();
327 const char* description
= exception
.GetDescription();
330 if (strlen(description
) > 0)
331 fprintf(stderr
, "%s\n", description
);
335 if (strlen(description
) > 0)
336 fprintf(stderr
, "%s\n", description
);
337 fprintf(stderr
, kUsage
, cmdName
);
341 printf(kUsage
, cmdName
);
344 fprintf(stderr
, " error: %s\n", strerror(error
));