1// sass.hpp must go before all system headers to get the
2// __EXTENSIONS__ fix on Solaris.
3#include "sass.hpp"
4
5#include "position.hpp"
6#include "source.hpp"
7
8namespace Sass {
9
10
11 Offset::Offset(const char chr)
12 : line(chr == '\n' ? 1 : 0),
13 column(chr == '\n' ? 0 : 1)
14 {}
15
16 Offset::Offset(const char* string)
17 : line(0), column(0)
18 {
19 *this = inc(begin: string, end: string + strlen(s: string));
20 }
21
22 Offset::Offset(const sass::string& text)
23 : line(0), column(0)
24 {
25 *this = inc(begin: text.c_str(), end: text.c_str() + text.size());
26 }
27
28 Offset::Offset(const size_t line, const size_t column)
29 : line(line), column(column) { }
30
31 // init/create instance from const char substring
32 Offset Offset::init(const char* beg, const char* end)
33 {
34 Offset offset(0, 0);
35 if (end == 0) {
36 end += strlen(s: beg);
37 }
38 offset.add(begin: beg, end);
39 return offset;
40 }
41
42 // increase offset by given string (mostly called by lexer)
43 // increase line counter and count columns on the last line
44 Offset Offset::add(const char* begin, const char* end)
45 {
46 if (end == 0) return *this;
47 while (begin < end && *begin) {
48 if (*begin == '\n') {
49 ++ line;
50 // start new line
51 column = 0;
52 } else {
53 // do not count any utf8 continuation bytes
54 // https://stackoverflow.com/a/9356203/1550314
55 // https://en.wikipedia.org/wiki/UTF-8#Description
56 unsigned char chr = *begin;
57 // skip over 10xxxxxx
58 // is 1st bit not set
59 if ((chr & 128) == 0) {
60 // regular ASCII char
61 column += 1;
62 }
63 // is 2nd bit not set
64 else if ((chr & 64) == 0) {
65 // first utf8 byte
66 column += 1;
67 }
68 }
69 ++ begin;
70 }
71 return *this;
72 }
73
74 // increase offset by given string (mostly called by lexer)
75 // increase line counter and count columns on the last line
76 Offset Offset::inc(const char* begin, const char* end) const
77 {
78 Offset offset(line, column);
79 offset.add(begin, end);
80 return offset;
81 }
82
83 bool Offset::operator== (const Offset &pos) const
84 {
85 return line == pos.line && column == pos.column;
86 }
87
88 bool Offset::operator!= (const Offset &pos) const
89 {
90 return line != pos.line || column != pos.column;
91 }
92
93 void Offset::operator+= (const Offset &off)
94 {
95 *this = Offset(line + off.line, off.line > 0 ? off.column : column + off.column);
96 }
97
98 Offset Offset::operator+ (const Offset &off) const
99 {
100 return Offset(line + off.line, off.line > 0 ? off.column : column + off.column);
101 }
102
103 Offset Offset::operator- (const Offset &off) const
104 {
105 return Offset(line - off.line, off.line == line ? column - off.column : column);
106 }
107
108 Position::Position(const size_t file)
109 : Offset(0, 0), file(file) { }
110
111 Position::Position(const size_t file, const Offset& offset)
112 : Offset(offset), file(file) { }
113
114 Position::Position(const size_t line, const size_t column)
115 : Offset(line, column), file(-1) { }
116
117 Position::Position(const size_t file, const size_t line, const size_t column)
118 : Offset(line, column), file(file) { }
119
120
121 SourceSpan::SourceSpan(const char* path)
122 : source(SASS_MEMORY_NEW(SynthFile, path)), position(0, 0), offset(0, 0) { }
123
124 SourceSpan::SourceSpan(SourceDataObj source, const Offset& position, const Offset& offset)
125 : source(source), position(position), offset(offset) { }
126
127 Position Position::add(const char* begin, const char* end)
128 {
129 Offset::add(begin, end);
130 return *this;
131 }
132
133 Position Position::inc(const char* begin, const char* end) const
134 {
135 Offset offset(line, column);
136 offset = offset.inc(begin, end);
137 return Position(file, offset);
138 }
139
140 bool Position::operator== (const Position &pos) const
141 {
142 return file == pos.file && line == pos.line && column == pos.column;
143 }
144
145 bool Position::operator!= (const Position &pos) const
146 {
147 return file == pos.file || line != pos.line || column != pos.column;
148 }
149
150 void Position::operator+= (const Offset &off)
151 {
152 *this = Position(file, line + off.line, off.line > 0 ? off.column : column + off.column);
153 }
154
155 const Position Position::operator+ (const Offset &off) const
156 {
157 return Position(file, line + off.line, off.line > 0 ? off.column : column + off.column);
158 }
159
160 const Offset Position::operator- (const Offset &off) const
161 {
162 return Offset(line - off.line, off.line == line ? column - off.column : column);
163 }
164
165}
166

source code of gtk/subprojects/libsass/src/position.cpp