• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

antonvw / wex / 15349103000

30 May 2025 02:33PM UTC coverage: 28.052% (-30.9%) from 58.951%
15349103000

push

github

antonvw
fixing the segfault

7896 of 31160 branches covered (25.34%)

Branch coverage included in aggregate %.

6430 of 19909 relevant lines covered (32.3%)

64.4 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/src/factory/unified-diff.cpp
1
////////////////////////////////////////////////////////////////////////////////
2
// Name:      unified-diff.cpp
3
// Purpose:   Implementation of class wex::factory::unified_diff
4
//            https://www.gnu.org/software/diffutils/manual/html_node/Detailed-Unified.html
5
// Author:    Anton van Wezenbeek
6
// Copyright: (c) 2024-2025 Anton van Wezenbeek
7
////////////////////////////////////////////////////////////////////////////////
8

9
#include <boost/tokenizer.hpp>
10
#include <wex/core/log.h>
11
#include <wex/core/regex.h>
12
#include <wex/factory/frame.h>
13
#include <wex/factory/unified-diff.h>
14

15
#include <iostream>
16

17
#define NEXT_TOKEN                                                             \
18
  if (++tok_iter == tokens.end())                                              \
19
  {                                                                            \
20
    return false;                                                              \
21
  }
22

23
#define CHANGES_LINES(RANGE, TEXT)                                             \
24
  for (int i = 0; i < m_range[RANGE]; i++)                                     \
25
  {                                                                            \
26
    NEXT_TOKEN                                                                 \
27
    m_text[TEXT].push_back((*tok_iter).substr(1));                             \
28
  }
29

30
#define HEADER_LINES(REGEX, INTO)                                              \
31
  if (!parse_header(REGEX, *tok_iter, INTO))                                   \
32
  {                                                                            \
33
    return false;                                                              \
34
  }                                                                            \
35
  NEXT_TOKEN
36

37
#define SKIP_LINES                                                             \
38
  while (tok_iter != tokens.end())                                             \
39
  {                                                                            \
40
    NEXT_TOKEN                                                                 \
41
    if (!tok_iter->starts_with("diff ") && !tok_iter->starts_with("index "))   \
42
    {                                                                          \
43
      break;                                                                   \
44
    }                                                                          \
45
  }
46

47
namespace wex
48
{
49
size_t stoi(const std::string& i)
×
50
{
51
  return i.empty() ? 1 : std::stoi(i);
×
52
}
53
} // namespace wex
54

55
wex::factory::unified_diff::unified_diff(const std::string& input)
×
56
  : m_input(input)
×
57
{
58
  m_range.fill({0});
×
59
}
×
60

61
bool wex::factory::unified_diff::parse()
×
62
{
63
  typedef boost::tokenizer<boost::char_separator<char>> tokenizer;
64

65
  tokenizer tokens(m_input, boost::char_separator<char>("\r\n"));
×
66

67
  tokenizer::iterator tok_iter = tokens.begin();
×
68

69
  m_diffs = 0;
×
70

71
  while (tok_iter != tokens.end())
×
72
  {
73
    // skip first lines
74
    SKIP_LINES;
×
75

76
    // The unified output format starts with a two-line header
77
    HEADER_LINES("--- a/(.*)", m_path[0]);
×
78
    HEADER_LINES("\\+\\+\\+ b/(.*)", m_path[1]);
×
79

80
    m_is_first = true;
×
81
    m_is_last  = false;
×
82

83
    // Next come one or more chunks of differences
84
    while (tok_iter != tokens.end())
×
85
    {
86
      regex r_chunk("@@ -([0-9]+),?([0-9]*) \\+([0-9]+),?([0-9]*) @@.*");
×
87

88
      if (r_chunk.match(*tok_iter) != 4)
×
89
      {
90
        log("unified_diff") << *tok_iter << r_chunk.size();
×
91
        return false;
×
92
      }
93

94
      m_range[0] = wex::stoi(r_chunk[0]);
×
95
      m_range[1] = wex::stoi(r_chunk[1]);
×
96
      m_range[2] = wex::stoi(r_chunk[2]);
×
97
      m_range[3] = wex::stoi(r_chunk[3]);
×
98

99
      m_text.fill({});
×
100

101
      // Now get all - lines and all + lines, collect them, and invoke callback.
102
      CHANGES_LINES(1, 0);
×
103
      CHANGES_LINES(3, 1);
×
104

105
      if (!report_diff())
×
106
      {
107
        return false;
×
108
      }
109

110
      m_is_first = false;
×
111

112
      if (++tok_iter != tokens.end() && !(*tok_iter).starts_with("@@"))
×
113
      {
114
        m_is_last = true;
×
115
        report_diff();
×
116
        break; // this was last chunk, continue with header lines
×
117
      }
118
    }
×
119
  }
120

121
  m_is_last = true;
×
122

123
  report_diff();
×
124
  report_diff_finish();
×
125

126
  return true;
×
127
}
×
128

129
bool wex::factory::unified_diff::parse_header(
×
130
  const std::string& r,
131
  const std::string& line,
132
  path&              p)
133
{
134
  regex re(r);
×
135

136
  if (!re.match(line))
×
137
  {
138
    log("unified_diff") << line << re.match_data().text();
×
139
    return false;
×
140
  }
141

142
  p = path(re[0]);
×
143

144
  return true;
×
145
}
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc