Coverage Report

Created: 2023-12-08 06:59

/src/aspell/common/getdata.cpp
Line
Count
Source (jump to first uncovered line)
1
// This file is part of The New Aspell
2
// Copyright (C) 2001 by Kevin Atkinson under the GNU LGPL license
3
// version 2.0 or 2.1.  You should have received a copy of the LGPL
4
// license along with this library if you did not you can find
5
// it at http://www.gnu.org/.
6
7
#include <string.h>
8
9
#include "getdata.hpp"
10
#include "string.hpp"
11
#include "asc_ctype.hpp"
12
13
#include "iostream.hpp"
14
15
namespace acommon {
16
  unsigned int linenumber = 0 ;
17
18
  bool getdata_pair(IStream & in, DataPair & d, String & buf)
19
895k
  {
20
895k
    char * p;
21
22
    // get first non blank line and count all read ones
23
1.17M
    do {
24
1.17M
      buf.clear();
25
1.17M
      buf.append('\0'); // to avoid some special cases
26
1.17M
      if (!in.append_line(buf)) return false;
27
1.16M
      d.line_num++;
28
1.16M
      p = buf.mstr() + 1;
29
1.17M
      while (*p == ' ' || *p == '\t') ++p;
30
1.16M
    } while (*p == '#' || *p == '\0');
31
32
    // get key
33
884k
    d.key.str = p;
34
3.96M
    while (*p != '\0' &&
35
3.96M
           ((*p != ' ' && *p != '\t' && *p != '#') || *(p-1) == '\\')) ++p;
36
884k
    d.key.size = p - d.key.str;
37
38
    // figure out if there is a value and add terminate key
39
884k
    d.value.str = p; // in case there is no value
40
884k
    d.value.size = 0;
41
884k
    if (*p == '#' || *p == '\0') {*p = '\0'; return true;}
42
868k
    *p = '\0';
43
44
    // skip any whitespace
45
868k
    ++p;
46
3.06M
    while (*p == ' ' || *p == '\t') ++p;
47
868k
    if (*p == '\0' || *p == '#') {return true;}
48
49
    // get value
50
868k
    d.value.str = p;
51
20.1M
    while (*p != '\0' && (*p != '#' || *(p-1) == '\\')) ++p;
52
    
53
    // remove trailing white space and terminate value
54
868k
    --p;
55
874k
    while (*p == ' ' || *p == '\t') --p;
56
868k
    if (*p == '\\' && *(p + 1) != '\0') ++p;
57
868k
    ++p;
58
868k
    d.value.size = p - d.value.str;
59
868k
    *p = '\0';
60
61
868k
    return true;
62
868k
  }
63
64
  char * unescape(char * dest, const char * src)
65
34.5k
  {
66
1.09M
    while (*src) {
67
1.06M
      if (*src == '\\' && src[1]) {
68
2.45k
  ++src;
69
2.45k
  switch (*src) {
70
40
  case 'n': *dest = '\n'; break;
71
20
  case 'r': *dest = '\r'; break;
72
128
  case 't': *dest = '\t'; break;
73
0
  case 'f': *dest = '\f'; break;
74
0
  case 'v': *dest = '\v'; break;
75
2.27k
  default: *dest = *src;
76
2.45k
  }
77
1.05M
      } else {
78
1.05M
  *dest = *src;
79
1.05M
      }
80
1.06M
      ++src;
81
1.06M
      ++dest;
82
1.06M
    }
83
34.5k
    *dest = '\0';
84
34.5k
    return dest;
85
34.5k
  }
86
87
  bool escape(char * dest, const char * src, size_t limit, const char * others)
88
0
  {
89
0
    const char * begin = src;
90
0
    const char * end = dest + limit;
91
0
    if (asc_isspace(*src)) {
92
0
      if (dest == end) return false;
93
0
      *dest++ = '\\';
94
0
      if (dest == end) return false;
95
0
      *dest++ = *src++;
96
0
    }
97
0
    while (*src) {
98
0
      if (dest == end) return false;
99
0
      switch (*src) {
100
0
      case '\n': *dest++ = '\\'; *dest = 'n'; break;
101
0
      case '\r': *dest++ = '\\'; *dest = 'r'; break;
102
0
      case '\t': *dest++ = '\\'; *dest = 't'; break;
103
0
      case '\f': *dest++ = '\\'; *dest = 'f'; break;
104
0
      case '\v': *dest++ = '\\'; *dest = 'v'; break;
105
0
      case '\\': *dest++ = '\\'; *dest = '\\'; break;
106
0
      case '#' : *dest++ = '\\'; *dest = '#'; break;
107
0
      default:
108
0
  if (others && strchr(others, *src)) *dest++ = '\\';
109
0
  *dest = *src;
110
0
      }
111
0
      ++src;
112
0
      ++dest;
113
0
    }
114
0
    if (src > begin + 1 && asc_isspace(src[-1])) {
115
0
      --dest;
116
0
      *dest++ = '\\';
117
0
      if (dest == end) return false;
118
0
      *dest++ = src[-1];
119
0
    }
120
0
    *dest = '\0';
121
0
    return true;
122
0
  }
123
124
  void to_lower(char * str)
125
83.0k
  {
126
500k
    for (; *str; str++) *str = asc_tolower(*str);
127
83.0k
  }
128
129
  void to_lower(String & res, const char * str)
130
0
  {
131
0
    for (; *str; str++) res += asc_tolower(*str);
132
0
  }
133
134
  bool split(DataPair & d)
135
2.28M
  {
136
2.28M
    char * p   = d.value;
137
2.28M
    char * end = p + d.value.size;
138
2.28M
    d.key.str = p;
139
8.05M
    while (p != end) {
140
7.48M
      ++p;
141
7.48M
      if ((*p == ' ' || *p == '\t') && *(p-1) != '\\') break;
142
7.48M
    }
143
2.28M
    d.key.size = p - d.key.str;
144
2.28M
    *p = 0;
145
2.28M
    if (p != end) {
146
1.71M
      ++p;
147
10.1M
      while (p != end && (*p == ' ' || *p == '\t')) ++p;
148
1.71M
    }
149
2.28M
    d.value.str = p;
150
2.28M
    d.value.size = end - p;
151
2.28M
    return d.key.size != 0;
152
2.28M
  }
153
154
  void init(ParmString str, DataPair & d, String & buf)
155
718
  {
156
718
    const char * s = str;
157
718
    while (*s == ' ' || *s == '\t') ++s;
158
718
    size_t l = str.size() - (s - str);
159
718
    buf.assign(s, l);
160
718
    d.value.str  = buf.mstr();
161
718
    d.value.size = l;
162
718
  }
163
164
  bool getline(IStream & in, DataPair & d, String & buf)
165
0
  {
166
0
    if (!in.getline(buf)) return false;
167
0
    d.value.str  = buf.mstr();
168
0
    d.value.size = buf.size();
169
0
    return true;
170
0
  }
171
172
  char * get_nb_line(IStream & in, String & buf)
173
1.46M
  {
174
1.46M
    char * p;
175
    // get first non blank line
176
1.47M
    do {
177
1.47M
      if (!in.getline(buf)) return 0;
178
1.47M
      p = buf.mstr();
179
2.04M
      while (*p == ' ' || *p == '\t') ++p;
180
1.47M
    } while (*p == '#' || *p == '\0');
181
1.46M
    return p;
182
1.46M
  }
183
184
  void remove_comments(String & buf)
185
6.68k
  {
186
6.68k
    char * p = buf.mstr();
187
6.68k
    char * b = p;
188
28.7k
    while (*p && *p != '#') ++p;
189
6.68k
    if (*p == '#') {--p; while (p >= b && asc_isspace(*p)) --p; ++p;}
190
6.68k
    buf.resize(p - b);
191
6.68k
  }
192
193
}