debugger: added help in single mode UI, plus minor fixes
[deliverable/titan.core.git] / core / ProfMerge_main.cc
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
7 *
8 * Contributors:
9 * Balasko, Jeno
10 * Baranyi, Botond
11 *
12 ******************************************************************************/
13
14 #include <stdlib.h>
15 #include <stdio.h>
16 #include <stdarg.h>
17 #include <getopt.h>
18 #include <string.h>
19 #include "ProfilerTools.hh"
20 #include "version_internal.h"
21
22 #ifdef LICENSE
23 #include "license.h"
24 #endif
25
26 /** the name of the executable */
27 const char* program_name;
28
29 /** error flag, set automatically when an error occurs */
30 boolean erroneous = FALSE;
31
32 /** prints usage information */
33 void usage()
34 {
35 fprintf(stderr,
36 "usage: %s [-pc] [-o file] [-s file] [-f filter] db_file1 [db_file2 ...]\n"
37 " or %s -v\n\n"
38 "options:\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);
45 }
46
47 /** displays an error message and sets the erroneous flag */
48 void error(const char *fmt, ...)
49 {
50 fprintf(stderr, "%s: error: ", program_name);
51 va_list parameters;
52 va_start(parameters, fmt);
53 vfprintf(stderr, fmt, parameters);
54 va_end(parameters);
55 putc('\n', stderr);
56 fflush(stderr);
57 erroneous = TRUE;
58 }
59
60 /** checks if the specified file exists */
61 boolean file_exists(const char* p_filename)
62 {
63 FILE* file = fopen(p_filename, "r");
64 if (NULL != file) {
65 fclose(file);
66 return TRUE;
67 }
68 return FALSE;
69 }
70
71
72 int main(int argc, char* argv[])
73 {
74 // store the executable name
75 program_name = argv[0];
76
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;
85
86 if (1 == argc) {
87 // no command line options
88 usage();
89 return EXIT_FAILURE;
90 }
91
92 for (;;) {
93 // read the next command line option (and its argument)
94 int c = getopt(argc, argv, "o:s:pcf:v");
95 if (-1 == c) {
96 break;
97 }
98 switch (c) {
99 case 'o': // output database file
100 out_file = optarg;
101 break;
102 case 's': // statistics file
103 stats_file = optarg;
104 break;
105 case 'p':
106 disable_profiler = TRUE;
107 break;
108 case 'c':
109 disable_coverage = TRUE;
110 break;
111 case 'f': { // statistics filter (hex number)
112 has_stats_flag = TRUE;
113 size_t len = strlen(optarg);
114 size_t start = 0;
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;
118 }
119 stats_flags = 0;
120 // extract the hex digits from the argument
121 for (size_t i = start; i < len; ++i) {
122 stats_flags *= 16;
123 if ('0' <= optarg[i] && '9' >= optarg[i]) {
124 stats_flags += optarg[i] - '0';
125 }
126 else if ('a' <= optarg[i] && 'f' >= optarg[i]) {
127 stats_flags += optarg[i] - 'a' + 10;
128 }
129 else if ('A' <= optarg[i] && 'F' >= optarg[i]) {
130 stats_flags += optarg[i] - 'A' + 10;
131 }
132 else {
133 error("Invalid statistics filter. Expected hexadecimal value.");
134 return EXIT_FAILURE;
135 }
136 }
137 break; }
138 case 'v':
139 print_version = TRUE;
140 break;
141 default:
142 usage();
143 return EXIT_FAILURE;
144 }
145 }
146
147 if (print_version) {
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) {
151 usage();
152 return EXIT_FAILURE;
153 }
154 else {
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);
160 #ifdef LICENSE
161 print_license_info();
162 #endif
163 return EXIT_SUCCESS;
164 }
165 }
166
167 if (optind == argc) {
168 error("No input files specified.");
169 usage();
170 return EXIT_FAILURE;
171 }
172
173 if (disable_profiler && disable_coverage) {
174 error("Both profiling and code coverage data are discarded, nothing to do.");
175 return EXIT_FAILURE;
176 }
177
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).");
181 usage();
182 return EXIT_FAILURE;
183 }
184
185 if (has_stats_flag && NULL == stats_file) {
186 fprintf(stderr, "Notify: No statistics file specified, the statistics filter "
187 "will be ignored.");
188 }
189
190 // create the local database
191 Profiler_Tools::profiler_db_t profiler_db;
192
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);
197 if (erroneous) {
198 // an import failed -> exit
199 return EXIT_FAILURE;
200 }
201 }
202
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");
213 }
214 }
215
216 boolean stats_file_success = TRUE;
217 if (NULL != stats_file) {
218 // reset the error flag, in case export_data failed
219 erroneous = FALSE;
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");
228 }
229 }
230
231 // return an error code if printing either output file failed
232 return (out_file_success && stats_file_success) ? EXIT_SUCCESS : EXIT_FAILURE;
233 }
234
235 // this is needed by version.h
236 reffer::reffer(const char*) {}
This page took 0.035711 seconds and 5 git commands to generate.