Titan Core Initial Contribution
[deliverable/titan.core.git] / core / TCov.cc
1 ///////////////////////////////////////////////////////////////////////////////
2 // Copyright (c) 2000-2014 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 #include "TCov.hh"
9
10 #include "Component.hh"
11 #include "Runtime.hh"
12
13 #include <stdio.h>
14 #include <string.h>
15 #include <unistd.h>
16
17 expstring_t TCov::comp(boolean withname)
18 {
19 enum { SINGLE, HC, MTC, PTC } whoami;
20 if (TTCN_Runtime::is_single()) whoami = SINGLE;
21 else if (TTCN_Runtime::is_hc()) whoami = HC;
22 else if (TTCN_Runtime::is_mtc()) whoami = MTC;
23 else whoami = PTC;
24 expstring_t ret_val = NULL;
25 switch (whoami) {
26 case SINGLE: ret_val = mcopystr("single"); break;
27 case HC: ret_val = mcopystr("hc"); break;
28 case MTC: ret_val = mcopystr("mtc"); break;
29 case PTC:
30 default: {
31 const char *compname = TTCN_Runtime::get_component_name();
32 if (withname && compname != NULL) ret_val = mcopystr(compname);
33 else ret_val = mprintf("%d", self.is_bound() ? (component)self : (component)0);
34 break;
35 }
36 }
37 return ret_val;
38 }
39
40 int TCov::ver_major = 1;
41 int TCov::ver_minor = 0;
42 Vector<FileData *> TCov::m_file_data;
43 pid_t TCov::mypid = getpid();
44 expstring_t TCov::mycomp = TCov::comp();
45 expstring_t TCov::mycomp_name = TCov::comp(TRUE);
46
47 size_t TCov::has_file_name(const char *file_name)
48 {
49 size_t i = 0;
50 for (; i < m_file_data.size(); ++i)
51 if (!strcmp(file_name, m_file_data[i]->get_file_name()))
52 return static_cast<int>(i);
53 return i;
54 }
55
56 void TCov::close_file()
57 {
58 if (m_file_data.empty()) {
59 Free(mycomp);
60 Free(mycomp_name);
61 mycomp = mycomp_name = NULL;
62 return;
63 }
64 expstring_t file_name = mputprintf(NULL, "tcov-%s.tcd", mycomp);
65 FILE *fp = fopen((const char *)file_name, "w");
66 expstring_t output = mputprintf(NULL,
67 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" \
68 "<?xml-stylesheet type=\"text/xsl\" href=\"tcov.xsl\"?>\n" \
69 "<titan_coverage xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" " \
70 "xsi:schemaLocation=\"tcov.xsd\">\n" \
71 "\t<version major=\"%d\" minor=\"%d\" />\n" \
72 "\t<component id=\"%s\" name=\"%s\" />\n" \
73 "\t<files>\n",
74 ver_major, ver_minor, mycomp, mycomp_name);
75 for (size_t i = 0; i < m_file_data.size(); ++i) {
76 const FileData *file_data = m_file_data[i];
77 output = mputprintf(output, "\t\t<file path=\"%s\">\n", file_data->get_file_name());
78 const Vector<FunctionData *>& function_data = file_data->get_function_data();
79 const Vector<LineData *>& line_data = file_data->get_line_data();
80 output = mputstr(output, "\t\t\t<functions>\n");
81 for (size_t j = 0; j < function_data.size(); ++j) {
82 output = mputprintf(output, "\t\t\t\t<function name=\"%s\" count=\"%d\" />\n",
83 function_data[j]->get_name(), function_data[j]->get_count());
84 }
85 output = mputstr(output, "\t\t\t</functions>\n");
86 output = mputstr(output, "\t\t\t<lines>\n");
87 for (size_t j = 0; j < line_data.size(); ++j) {
88 output = mputprintf(output, "\t\t\t\t<line no=\"%d\" count=\"%d\" />\n",
89 line_data[j]->get_no(), line_data[j]->get_count());
90 }
91 output = mputstr(output,
92 "\t\t\t</lines>\n" \
93 "\t\t</file>\n");
94 }
95 output = mputstr(output,
96 "\t</files>\n" \
97 "</titan_coverage>\n");
98 fputs(output, fp);
99 fclose(fp);
100 Free(output);
101 Free(file_name);
102 for (size_t i = 0; i < m_file_data.size(); ++i)
103 delete m_file_data[i];
104 m_file_data.clear();
105 Free(mycomp);
106 Free(mycomp_name);
107 mycomp = mycomp_name = NULL;
108 }
109
110 FileData::FileData(const char *file_name)
111 {
112 m_file_name = mcopystr(file_name);
113 }
114
115 FileData::~FileData()
116 {
117 Free(m_file_name);
118 m_file_name = NULL;
119 for (size_t i = 0; i < m_function_data.size(); ++i)
120 delete m_function_data[i];
121 for (size_t i = 0; i < m_line_data.size(); ++i)
122 delete m_line_data[i];
123 m_function_data.clear();
124 m_line_data.clear();
125 }
126
127 void FileData::reset()
128 {
129 for (size_t i = 0; i < m_function_data.size(); ++i)
130 m_function_data[i]->reset();
131 for (size_t i = 0; i < m_line_data.size(); ++i)
132 m_line_data[i]->reset();
133 }
134
135 size_t FileData::has_function_name(const char *function_name)
136 {
137 size_t i = 0;
138 for (; i < m_function_data.size(); ++i)
139 if (!strcmp(function_name, m_function_data[i]->get_name()))
140 return static_cast<int>(i);
141 return i;
142 }
143
144 size_t FileData::has_line_no(int line_no)
145 {
146 size_t i = 0;
147 for (; i < m_line_data.size(); ++i)
148 if (line_no == m_line_data[i]->get_no())
149 return static_cast<int>(i);
150 return i;
151 }
152
153 void FileData::inc_function(const char *function_name, int /*line_no*/)
154 {
155 size_t i = has_function_name(function_name);
156 if (i == m_function_data.size())
157 m_function_data.push_back(new FunctionData(function_name));
158 ++(*m_function_data[i]);
159 }
160
161 void FileData::inc_line(int line_no)
162 {
163 size_t i = has_line_no(line_no);
164 if (i == m_line_data.size())
165 m_line_data.push_back(new LineData(line_no));
166 ++(*m_line_data[i]);
167 }
168
169 void FileData::init_function(const char *function_name)
170 {
171 size_t i = has_function_name(function_name);
172 if (i == m_function_data.size()) m_function_data.push_back(new FunctionData(function_name));
173 }
174
175 void FileData::init_line(int line_no)
176 {
177 size_t i = has_line_no(line_no);
178 if (i == m_line_data.size()) m_line_data.push_back(new LineData(line_no));
179 }
180
181 void TCov::pid_check()
182 {
183 pid_t p = getpid();
184 if (mypid != p) {
185 mypid = p;
186 Free(mycomp);
187 Free(mycomp_name);
188 mycomp = NULL;
189 mycomp_name = NULL;
190 mycomp = comp();
191 mycomp_name = comp(TRUE);
192 for (size_t i = 0; i < m_file_data.size(); ++i)
193 m_file_data[i]->reset();
194 }
195 }
196
197 void TCov::hit(const char *file_name, int line_no, const char *function_name)
198 {
199 pid_check();
200 size_t i = has_file_name(file_name);
201 if (i == m_file_data.size())
202 m_file_data.push_back(new FileData(file_name));
203 if (function_name)
204 m_file_data[i]->inc_function(function_name, line_no);
205 m_file_data[i]->inc_line(line_no);
206 }
207
208 void TCov::init_file_lines(const char *file_name, const int line_nos[], size_t line_nos_len)
209 {
210 pid_check();
211 size_t i = has_file_name(file_name);
212 if (i == m_file_data.size())
213 m_file_data.push_back(new FileData(file_name));
214 for (size_t j = 0; j < line_nos_len; ++j)
215 m_file_data[i]->init_line(line_nos[j]);
216 }
217
218 void TCov::init_file_functions(const char *file_name, const char *function_names[], size_t function_names_len)
219 {
220 pid_check();
221 size_t i = has_file_name(file_name);
222 if (i == m_file_data.size())
223 m_file_data.push_back(new FileData(file_name));
224 for (size_t j = 0; j < function_names_len; ++j)
225 m_file_data[i]->init_function(function_names[j]);
226 }
This page took 0.050774 seconds and 5 git commands to generate.