1 ///////////////////////////////////////////////////////////////////////////////
2 // Copyright (c) 2000-2015 Ericsson Telecom AB
3 // All rights reserved. This program and the accompanying materials
4 // are made available under the terms of the Eclipse Public License v1.0
5 // which accompanies this distribution, and is available at
6 // http://www.eclipse.org/legal/epl-v10.html
7 ///////////////////////////////////////////////////////////////////////////////
14 #include "ProfilerTools.hh"
15 #include "version_internal.h"
21 /** the name of the executable */
22 const char* program_name
;
24 /** error flag, set automatically when an error occurs */
25 boolean erroneous
= FALSE
;
27 /** prints usage information */
31 "usage: %s [-pc] [-o file] [-s file] [-f filter] db_file1 [db_file2 ...]\n"
34 " -p: discard profiling data\n"
35 " -c: discard code coverage data\n"
36 " -o file: write merged database into file\n"
37 " -s file: generate statistics file from merged database\n"
38 " -f filter: filter the generated statistics file (the filter is a hexadecimal number)\n"
39 " -v: show version\n", program_name
, program_name
);
42 /** displays an error message and sets the erroneous flag */
43 void error(const char *fmt
, ...)
45 fprintf(stderr
, "%s: error: ", program_name
);
47 va_start(parameters
, fmt
);
48 vfprintf(stderr
, fmt
, parameters
);
55 /** checks if the specified file exists */
56 boolean
file_exists(const char* p_filename
)
58 FILE* file
= fopen(p_filename
, "r");
67 int main(int argc
, char* argv
[])
69 // store the executable name
70 program_name
= argv
[0];
72 // initialize variables for command line options
73 const char* out_file
= NULL
;
74 const char* stats_file
= NULL
;
75 boolean disable_profiler
= FALSE
;
76 boolean disable_coverage
= FALSE
;
77 unsigned int stats_flags
= Profiler_Tools::STATS_ALL
;
78 boolean has_stats_flag
= FALSE
;
79 boolean print_version
= FALSE
;
82 // no command line options
88 // read the next command line option (and its argument)
89 int c
= getopt(argc
, argv
, "o:s:pcf:v");
94 case 'o': // output database file
97 case 's': // statistics file
101 disable_profiler
= TRUE
;
104 disable_coverage
= TRUE
;
106 case 'f': { // statistics filter (hex number)
107 has_stats_flag
= TRUE
;
108 size_t len
= strlen(optarg
);
110 if (len
> STATS_MAX_HEX_DIGITS
) {
111 // the rest of the bits are not needed, and stats_flags might run out of bits
112 start
= len
- STATS_MAX_HEX_DIGITS
;
115 // extract the hex digits from the argument
116 for (size_t i
= start
; i
< len
; ++i
) {
118 if ('0' <= optarg
[i
] && '9' >= optarg
[i
]) {
119 stats_flags
+= optarg
[i
] - '0';
121 else if ('a' <= optarg
[i
] && 'f' >= optarg
[i
]) {
122 stats_flags
+= optarg
[i
] - 'a' + 10;
124 else if ('A' <= optarg
[i
] && 'F' >= optarg
[i
]) {
125 stats_flags
+= optarg
[i
] - 'A' + 10;
128 error("Invalid statistics filter. Expected hexadecimal value.");
134 print_version
= TRUE
;
143 // no other flags are allowed when printing version info
144 if (disable_profiler
|| disable_coverage
|| has_stats_flag
||
145 NULL
!= out_file
|| NULL
!= stats_file
) {
150 fputs("Profiler and Code Coverage Merge Tool for the TTCN-3 Test Executor\n"
151 "Product number: " PRODUCT_NUMBER
"\n"
152 "Build date: " __DATE__
" " __TIME__
"\n"
153 "Compiled with: " C_COMPILER_VERSION
"\n\n"
154 COPYRIGHT_STRING
"\n\n", stderr
);
156 print_license_info();
162 if (optind
== argc
) {
163 error("No input files specified.");
168 if (disable_profiler
&& disable_coverage
) {
169 error("Both profiling and code coverage data are discarded, nothing to do.");
173 if (NULL
== out_file
&& NULL
== stats_file
) {
174 error("No output files specified (either the output database file or the "
175 "statistics file must be set).");
180 if (has_stats_flag
&& NULL
== stats_file
) {
181 fprintf(stderr
, "Notify: No statistics file specified, the statistics filter "
185 // create the local database
186 Profiler_Tools::profiler_db_t profiler_db
;
188 for (int i
= optind
; i
< argc
; i
++) {
189 // import each input file's contents into the local database
190 fprintf(stderr
, "Notify: Importing database file '%s'...\n", argv
[i
]);
191 Profiler_Tools::import_data(profiler_db
, argv
[i
], FALSE
, error
);
193 // an import failed -> exit
198 boolean out_file_success
= TRUE
;
199 if (NULL
!= out_file
) {
200 // print the local database into the output file
201 boolean update
= file_exists(out_file
);
202 Profiler_Tools::export_data(profiler_db
, out_file
, disable_profiler
,
203 disable_coverage
, error
);
204 out_file_success
= !erroneous
;
205 if (out_file_success
) {
206 fprintf(stderr
, "Notify: Database file '%s' was %s.\n", out_file
,
207 update
? "updated" : "generated");
211 boolean stats_file_success
= TRUE
;
212 if (NULL
!= stats_file
) {
213 // reset the error flag, in case export_data failed
215 // print the statistics into the designated file
216 boolean update
= file_exists(stats_file
);
217 Profiler_Tools::print_stats(profiler_db
, stats_file
, disable_profiler
,
218 disable_coverage
, stats_flags
, error
);
219 stats_file_success
= !erroneous
;
220 if (stats_file_success
) {
221 fprintf(stderr
, "Notify: Statistics file '%s' was %s.\n", stats_file
,
222 update
? "updated" : "generated");
226 // return an error code if printing either output file failed
227 return (out_file_success
&& stats_file_success
) ? EXIT_SUCCESS
: EXIT_FAILURE
;
230 // this is needed by version.h
231 reffer::reffer(const char*) {}