1 /******************************************************************************
2 * Copyright (c) 2000-2016 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
12 ******************************************************************************/
19 #include "ProfilerTools.hh"
20 #include "version_internal.h"
26 /** the name of the executable */
27 const char* program_name
;
29 /** error flag, set automatically when an error occurs */
30 boolean erroneous
= FALSE
;
32 /** prints usage information */
36 "usage: %s [-pc] [-o file] [-s file] [-f filter] db_file1 [db_file2 ...]\n"
39 " -p: discard profiling data\n"
40 " -c: discard code coverage data\n"
41 " -o file: write merged database into file\n"
42 " -s file: generate statistics file from merged database\n"
43 " -f filter: filter the generated statistics file (the filter is a hexadecimal number)\n"
44 " -v: show version\n", program_name
, program_name
);
47 /** displays an error message and sets the erroneous flag */
48 void error(const char *fmt
, ...)
50 fprintf(stderr
, "%s: error: ", program_name
);
52 va_start(parameters
, fmt
);
53 vfprintf(stderr
, fmt
, parameters
);
60 /** checks if the specified file exists */
61 boolean
file_exists(const char* p_filename
)
63 FILE* file
= fopen(p_filename
, "r");
72 int main(int argc
, char* argv
[])
74 // store the executable name
75 program_name
= argv
[0];
77 // initialize variables for command line options
78 const char* out_file
= NULL
;
79 const char* stats_file
= NULL
;
80 boolean disable_profiler
= FALSE
;
81 boolean disable_coverage
= FALSE
;
82 unsigned int stats_flags
= Profiler_Tools::STATS_ALL
;
83 boolean has_stats_flag
= FALSE
;
84 boolean print_version
= FALSE
;
87 // no command line options
93 // read the next command line option (and its argument)
94 int c
= getopt(argc
, argv
, "o:s:pcf:v");
99 case 'o': // output database file
102 case 's': // statistics file
106 disable_profiler
= TRUE
;
109 disable_coverage
= TRUE
;
111 case 'f': { // statistics filter (hex number)
112 has_stats_flag
= TRUE
;
113 size_t len
= strlen(optarg
);
115 if (len
> STATS_MAX_HEX_DIGITS
) {
116 // the rest of the bits are not needed, and stats_flags might run out of bits
117 start
= len
- STATS_MAX_HEX_DIGITS
;
120 // extract the hex digits from the argument
121 for (size_t i
= start
; i
< len
; ++i
) {
123 if ('0' <= optarg
[i
] && '9' >= optarg
[i
]) {
124 stats_flags
+= optarg
[i
] - '0';
126 else if ('a' <= optarg
[i
] && 'f' >= optarg
[i
]) {
127 stats_flags
+= optarg
[i
] - 'a' + 10;
129 else if ('A' <= optarg
[i
] && 'F' >= optarg
[i
]) {
130 stats_flags
+= optarg
[i
] - 'A' + 10;
133 error("Invalid statistics filter. Expected hexadecimal value.");
139 print_version
= TRUE
;
148 // no other flags are allowed when printing version info
149 if (disable_profiler
|| disable_coverage
|| has_stats_flag
||
150 NULL
!= out_file
|| NULL
!= stats_file
) {
155 fputs("Profiler and Code Coverage Merge Tool for the TTCN-3 Test Executor\n"
156 "Product number: " PRODUCT_NUMBER
"\n"
157 "Build date: " __DATE__
" " __TIME__
"\n"
158 "Compiled with: " C_COMPILER_VERSION
"\n\n"
159 COPYRIGHT_STRING
"\n\n", stderr
);
161 print_license_info();
167 if (optind
== argc
) {
168 error("No input files specified.");
173 if (disable_profiler
&& disable_coverage
) {
174 error("Both profiling and code coverage data are discarded, nothing to do.");
178 if (NULL
== out_file
&& NULL
== stats_file
) {
179 error("No output files specified (either the output database file or the "
180 "statistics file must be set).");
185 if (has_stats_flag
&& NULL
== stats_file
) {
186 fprintf(stderr
, "Notify: No statistics file specified, the statistics filter "
190 // create the local database
191 Profiler_Tools::profiler_db_t profiler_db
;
193 for (int i
= optind
; i
< argc
; i
++) {
194 // import each input file's contents into the local database
195 fprintf(stderr
, "Notify: Importing database file '%s'...\n", argv
[i
]);
196 Profiler_Tools::import_data(profiler_db
, argv
[i
], error
);
198 // an import failed -> exit
203 boolean out_file_success
= TRUE
;
204 if (NULL
!= out_file
) {
205 // print the local database into the output file
206 boolean update
= file_exists(out_file
);
207 Profiler_Tools::export_data(profiler_db
, out_file
, disable_profiler
,
208 disable_coverage
, error
);
209 out_file_success
= !erroneous
;
210 if (out_file_success
) {
211 fprintf(stderr
, "Notify: Database file '%s' was %s.\n", out_file
,
212 update
? "updated" : "generated");
216 boolean stats_file_success
= TRUE
;
217 if (NULL
!= stats_file
) {
218 // reset the error flag, in case export_data failed
220 // print the statistics into the designated file
221 boolean update
= file_exists(stats_file
);
222 Profiler_Tools::print_stats(profiler_db
, stats_file
, disable_profiler
,
223 disable_coverage
, stats_flags
, error
);
224 stats_file_success
= !erroneous
;
225 if (stats_file_success
) {
226 fprintf(stderr
, "Notify: Statistics file '%s' was %s.\n", stats_file
,
227 update
? "updated" : "generated");
231 // return an error code if printing either output file failed
232 return (out_file_success
&& stats_file_success
) ? EXIT_SUCCESS
: EXIT_FAILURE
;
235 // this is needed by version.h
236 reffer::reffer(const char*) {}