GCC Code Coverage Report


Directory: ./
File: src/SubDevice.cpp
Date: 2026-09-03 16:05:57
Exec Total Coverage
Lines: 37 42 88.1%
Branches: 40 84 47.6%

Line Branch Exec Source
1 /*****************************************************************************
2 *
3 * This file is part of the ecapp library (EtherCAT application devices).
4 *
5 * Copyright (C) 2026 Florian Pose <fp@igh.de>
6 *
7 * The ecapp library is free software: you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public License
9 * as published by the Free Software Foundation, version 3 of the
10 * License.
11 *
12 * The ecapp library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with the ecapp library. If not, see
19 * <https://www.gnu.org/licenses/>.
20 *
21 ****************************************************************************/
22
23 #include "ecapp/SubDevice.h"
24
25 #include "ecapp/Exceptions.h"
26
27 #include <sstream>
28 #include <string>
29
30 using std::size_t;
31 using std::string;
32 using std::stringstream;
33
34 /****************************************************************************/
35
36 namespace EcApp {
37
38 13 size_t SubDevice::inputIndex(const string &kind, unsigned int index) const
39 {
40 13 size_t position = 0;
41
3/4
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✓ Branch 6 taken 41 times.
✓ Branch 7 taken 1 times.
42 for (const auto &ck : inputKinds()) {
42
2/2
✓ Branch 1 taken 12 times.
✓ Branch 2 taken 29 times.
41 if (ck.name == kind) {
43
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 if (index < ck.count) {
44 24 return position + index;
45 }
46 break;
47 }
48 29 position += ck.count;
49 }
50
51
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
2 stringstream err;
52
5/10
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 1 times.
✗ Branch 14 not taken.
1 err << "Unknown input channel \"" << kind << "\" index " << index << ".";
53
2/4
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
1 throw UnknownChannel(err.str());
54 }
55
56 /****************************************************************************/
57
58 5 size_t SubDevice::inputIndex(unsigned int index) const
59 {
60
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
5 return inputIndex(soleInputKind(), index);
61 }
62
63 /****************************************************************************/
64
65 12 size_t SubDevice::outputIndex(const string &kind, unsigned int index) const
66 {
67 12 size_t position = 0;
68
2/4
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✓ Branch 6 taken 13 times.
✗ Branch 7 not taken.
13 for (const auto &ck : outputKinds()) {
69
2/2
✓ Branch 1 taken 12 times.
✓ Branch 2 taken 1 times.
13 if (ck.name == kind) {
70
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 if (index < ck.count) {
71 24 return position + index;
72 }
73 break;
74 }
75 1 position += ck.count;
76 }
77
78 stringstream err;
79 err << "Unknown output channel \"" << kind << "\" index " << index << ".";
80 throw UnknownChannel(err.str());
81 }
82
83 /****************************************************************************/
84
85 7 size_t SubDevice::outputIndex(unsigned int index) const
86 {
87
1/2
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
7 return outputIndex(soleOutputKind(), index);
88 }
89
90 /****************************************************************************/
91
92 6 string SubDevice::soleInputKind() const
93 {
94 6 const auto &kinds = inputKinds();
95
2/2
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 2 times.
6 if (kinds.size() != 1) {
96
1/2
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
8 stringstream err;
97 err << "Ambiguous input channel: "
98 4 << (kinds.empty() ? "no kind is registered"
99 : "more than one kind is registered")
100
5/8
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3 times.
✓ Branch 4 taken 1 times.
✓ Branch 6 taken 4 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 4 times.
✗ Branch 10 not taken.
8 << " (name one explicitly).";
101
2/4
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 4 times.
✗ Branch 6 not taken.
4 throw UnknownChannel(err.str());
102 }
103 2 return kinds.front().name;
104 }
105
106 /****************************************************************************/
107
108 9 string SubDevice::soleOutputKind() const
109 {
110 9 const auto &kinds = outputKinds();
111
2/2
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 7 times.
9 if (kinds.size() != 1) {
112
1/2
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
4 stringstream err;
113 err << "Ambiguous output channel: "
114 2 << (kinds.empty() ? "no kind is registered"
115 : "more than one kind is registered")
116
4/8
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 2 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 2 times.
✗ Branch 10 not taken.
4 << " (name one explicitly).";
117
2/4
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 2 times.
✗ Branch 6 not taken.
2 throw UnknownChannel(err.str());
118 }
119 7 return kinds.front().name;
120 }
121
122 } // namespace EcApp
123
124 /****************************************************************************/
125