sassc 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (151) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +15 -0
  3. data/.gitmodules +3 -0
  4. data/.travis.yml +9 -0
  5. data/Gemfile +4 -0
  6. data/LICENSE.txt +22 -0
  7. data/README.md +24 -0
  8. data/Rakefile +21 -0
  9. data/ext/libsass/.editorconfig +15 -0
  10. data/ext/libsass/.gitattributes +2 -0
  11. data/ext/libsass/.gitignore +61 -0
  12. data/ext/libsass/.travis.yml +38 -0
  13. data/ext/libsass/COPYING +25 -0
  14. data/ext/libsass/INSTALL +1 -0
  15. data/ext/libsass/LICENSE +25 -0
  16. data/ext/libsass/Makefile +223 -0
  17. data/ext/libsass/Makefile.am +145 -0
  18. data/ext/libsass/Readme.md +93 -0
  19. data/ext/libsass/appveyor.yml +76 -0
  20. data/ext/libsass/ast.cpp +581 -0
  21. data/ext/libsass/ast.hpp +1949 -0
  22. data/ext/libsass/ast_def_macros.hpp +16 -0
  23. data/ext/libsass/ast_factory.hpp +87 -0
  24. data/ext/libsass/ast_fwd_decl.hpp +72 -0
  25. data/ext/libsass/b64/cencode.h +32 -0
  26. data/ext/libsass/b64/encode.h +77 -0
  27. data/ext/libsass/backtrace.hpp +81 -0
  28. data/ext/libsass/base64vlq.cpp +43 -0
  29. data/ext/libsass/base64vlq.hpp +28 -0
  30. data/ext/libsass/bind.cpp +187 -0
  31. data/ext/libsass/bind.hpp +18 -0
  32. data/ext/libsass/cencode.c +102 -0
  33. data/ext/libsass/color_names.hpp +324 -0
  34. data/ext/libsass/configure.ac +130 -0
  35. data/ext/libsass/constants.cpp +144 -0
  36. data/ext/libsass/constants.hpp +145 -0
  37. data/ext/libsass/context.cpp +507 -0
  38. data/ext/libsass/context.hpp +150 -0
  39. data/ext/libsass/contextualize.cpp +157 -0
  40. data/ext/libsass/contextualize.hpp +65 -0
  41. data/ext/libsass/copy_c_str.cpp +13 -0
  42. data/ext/libsass/copy_c_str.hpp +5 -0
  43. data/ext/libsass/debug.hpp +39 -0
  44. data/ext/libsass/environment.hpp +75 -0
  45. data/ext/libsass/error_handling.cpp +28 -0
  46. data/ext/libsass/error_handling.hpp +28 -0
  47. data/ext/libsass/eval.cpp +1149 -0
  48. data/ext/libsass/eval.hpp +80 -0
  49. data/ext/libsass/expand.cpp +430 -0
  50. data/ext/libsass/expand.hpp +77 -0
  51. data/ext/libsass/extconf.rb +6 -0
  52. data/ext/libsass/extend.cpp +1962 -0
  53. data/ext/libsass/extend.hpp +50 -0
  54. data/ext/libsass/file.cpp +291 -0
  55. data/ext/libsass/file.hpp +18 -0
  56. data/ext/libsass/functions.cpp +1565 -0
  57. data/ext/libsass/functions.hpp +187 -0
  58. data/ext/libsass/inspect.cpp +727 -0
  59. data/ext/libsass/inspect.hpp +108 -0
  60. data/ext/libsass/json.cpp +1411 -0
  61. data/ext/libsass/json.hpp +117 -0
  62. data/ext/libsass/kwd_arg_macros.hpp +23 -0
  63. data/ext/libsass/m4/.gitkeep +0 -0
  64. data/ext/libsass/mapping.hpp +17 -0
  65. data/ext/libsass/memory_manager.hpp +54 -0
  66. data/ext/libsass/node.cpp +251 -0
  67. data/ext/libsass/node.hpp +122 -0
  68. data/ext/libsass/operation.hpp +153 -0
  69. data/ext/libsass/output_compressed.cpp +401 -0
  70. data/ext/libsass/output_compressed.hpp +95 -0
  71. data/ext/libsass/output_nested.cpp +364 -0
  72. data/ext/libsass/output_nested.hpp +108 -0
  73. data/ext/libsass/parser.cpp +2016 -0
  74. data/ext/libsass/parser.hpp +264 -0
  75. data/ext/libsass/paths.hpp +69 -0
  76. data/ext/libsass/position.hpp +22 -0
  77. data/ext/libsass/posix/getopt.c +562 -0
  78. data/ext/libsass/posix/getopt.h +95 -0
  79. data/ext/libsass/prelexer.cpp +688 -0
  80. data/ext/libsass/prelexer.hpp +513 -0
  81. data/ext/libsass/remove_placeholders.cpp +59 -0
  82. data/ext/libsass/remove_placeholders.hpp +43 -0
  83. data/ext/libsass/res/resource.rc +35 -0
  84. data/ext/libsass/sass.cpp +33 -0
  85. data/ext/libsass/sass.h +60 -0
  86. data/ext/libsass/sass2scss.cpp +834 -0
  87. data/ext/libsass/sass2scss.h +110 -0
  88. data/ext/libsass/sass_context.cpp +709 -0
  89. data/ext/libsass/sass_context.h +120 -0
  90. data/ext/libsass/sass_functions.cpp +137 -0
  91. data/ext/libsass/sass_functions.h +90 -0
  92. data/ext/libsass/sass_interface.cpp +277 -0
  93. data/ext/libsass/sass_interface.h +97 -0
  94. data/ext/libsass/sass_util.cpp +136 -0
  95. data/ext/libsass/sass_util.hpp +259 -0
  96. data/ext/libsass/sass_values.cpp +337 -0
  97. data/ext/libsass/sass_values.h +124 -0
  98. data/ext/libsass/script/bootstrap +10 -0
  99. data/ext/libsass/script/branding +10 -0
  100. data/ext/libsass/script/ci-build-libsass +72 -0
  101. data/ext/libsass/script/ci-install-compiler +4 -0
  102. data/ext/libsass/script/ci-install-deps +19 -0
  103. data/ext/libsass/script/ci-report-coverage +25 -0
  104. data/ext/libsass/script/coveralls-debug +32 -0
  105. data/ext/libsass/script/spec +5 -0
  106. data/ext/libsass/script/tap-driver +652 -0
  107. data/ext/libsass/script/tap-runner +1 -0
  108. data/ext/libsass/source_map.cpp +133 -0
  109. data/ext/libsass/source_map.hpp +46 -0
  110. data/ext/libsass/subset_map.hpp +145 -0
  111. data/ext/libsass/support/libsass.pc.in +11 -0
  112. data/ext/libsass/test-driver +127 -0
  113. data/ext/libsass/test/test_node.cpp +98 -0
  114. data/ext/libsass/test/test_paths.cpp +29 -0
  115. data/ext/libsass/test/test_selector_difference.cpp +28 -0
  116. data/ext/libsass/test/test_specificity.cpp +28 -0
  117. data/ext/libsass/test/test_subset_map.cpp +472 -0
  118. data/ext/libsass/test/test_superselector.cpp +71 -0
  119. data/ext/libsass/test/test_unification.cpp +33 -0
  120. data/ext/libsass/to_c.cpp +61 -0
  121. data/ext/libsass/to_c.hpp +44 -0
  122. data/ext/libsass/to_string.cpp +29 -0
  123. data/ext/libsass/to_string.hpp +32 -0
  124. data/ext/libsass/token.hpp +32 -0
  125. data/ext/libsass/units.cpp +54 -0
  126. data/ext/libsass/units.hpp +10 -0
  127. data/ext/libsass/utf8.h +34 -0
  128. data/ext/libsass/utf8/checked.h +327 -0
  129. data/ext/libsass/utf8/core.h +329 -0
  130. data/ext/libsass/utf8/unchecked.h +228 -0
  131. data/ext/libsass/utf8_string.cpp +102 -0
  132. data/ext/libsass/utf8_string.hpp +36 -0
  133. data/ext/libsass/util.cpp +189 -0
  134. data/ext/libsass/util.hpp +26 -0
  135. data/ext/libsass/win/libsass.filters +291 -0
  136. data/ext/libsass/win/libsass.sln +28 -0
  137. data/ext/libsass/win/libsass.vcxproj +255 -0
  138. data/lib/sassc.rb +6 -0
  139. data/lib/sassc/engine.rb +13 -0
  140. data/lib/sassc/native.rb +44 -0
  141. data/lib/sassc/native/native_context_api.rb +140 -0
  142. data/lib/sassc/native/native_functions_api.rb +41 -0
  143. data/lib/sassc/native/sass_input_style.rb +11 -0
  144. data/lib/sassc/native/sass_output_style.rb +10 -0
  145. data/lib/sassc/native/sass_value.rb +95 -0
  146. data/lib/sassc/native/string_list.rb +8 -0
  147. data/lib/sassc/version.rb +3 -0
  148. data/sassc.gemspec +43 -0
  149. data/test/smoke_test.rb +171 -0
  150. data/test/test_helper.rb +4 -0
  151. metadata +281 -0
@@ -0,0 +1,71 @@
1
+ #include "../ast.hpp"
2
+ #include "../context.hpp"
3
+ #include "../parser.hpp"
4
+ #include "../to_string.hpp"
5
+ #include <string>
6
+
7
+ using namespace Sass;
8
+
9
+ Context ctx = Context(Context::Data());
10
+ To_String to_string;
11
+
12
+ Compound_Selector* compound_selector(string src)
13
+ { return Parser::from_c_str(src.c_str(), ctx, "", Position()).parse_simple_selector_sequence(); }
14
+
15
+ Complex_Selector* complex_selector(string src)
16
+ { return Parser::from_c_str(src.c_str(), ctx, "", Position()).parse_selector_combination(); }
17
+
18
+ void check_compound(string s1, string s2)
19
+ {
20
+ cout << "Is "
21
+ << s1
22
+ << " a superselector of "
23
+ << s2
24
+ << "?\t"
25
+ << compound_selector(s1 + ";")->is_superselector_of(compound_selector(s2 + ";"))
26
+ << endl;
27
+ }
28
+
29
+ void check_complex(string s1, string s2)
30
+ {
31
+ cout << "Is "
32
+ << s1
33
+ << " a superselector of "
34
+ << s2
35
+ << "?\t"
36
+ << complex_selector(s1 + ";")->is_superselector_of(complex_selector(s2 + ";"))
37
+ << endl;
38
+ }
39
+
40
+ int main()
41
+ {
42
+ check_compound(".foo", ".foo.bar");
43
+ check_compound(".foo.bar", ".foo");
44
+ check_compound(".foo.bar", "div.foo");
45
+ check_compound(".foo", "div.foo");
46
+ check_compound("div.foo", ".foo");
47
+ check_compound("div.foo", "div.bar.foo");
48
+ check_compound("p.foo", "div.bar.foo");
49
+ check_compound(".hux", ".mumble");
50
+
51
+ cout << endl;
52
+
53
+ check_complex(".foo ~ .bar", ".foo + .bar");
54
+ check_complex(".foo .bar", ".foo + .bar");
55
+ check_complex(".foo .bar", ".foo > .bar");
56
+ check_complex(".foo .bar > .hux", ".foo.a .bar.b > .hux");
57
+ check_complex(".foo ~ .bar .hux", ".foo.a + .bar.b > .hux");
58
+ check_complex(".foo", ".bar .foo");
59
+ check_complex(".foo", ".foo.a");
60
+ check_complex(".foo.bar", ".foo");
61
+ check_complex(".foo .bar .hux", ".bar .hux");
62
+ check_complex(".foo ~ .bar .hux.x", ".foo.a + .bar.b > .hux.y");
63
+ check_complex(".foo ~ .bar .hux", ".foo.a + .bar.b > .mumble");
64
+ check_complex(".foo + .bar", ".foo ~ .bar");
65
+ check_complex("a c e", "a b c d e");
66
+ check_complex("c a e", "a b c d e");
67
+
68
+ return 0;
69
+ }
70
+
71
+
@@ -0,0 +1,33 @@
1
+ #include "../ast.hpp"
2
+ #include "../context.hpp"
3
+ #include "../parser.hpp"
4
+ #include "../to_string.hpp"
5
+ #include <string>
6
+
7
+ using namespace Sass;
8
+
9
+ Context ctx = Context(Context::Data());
10
+ To_String to_string;
11
+
12
+ Compound_Selector* selector(string src)
13
+ { return Parser::from_c_str(src.c_str(), ctx, "", Position()).parse_simple_selector_sequence(); }
14
+
15
+ void unify(string lhs, string rhs)
16
+ {
17
+ Compound_Selector* unified = selector(lhs + ";")->unify_with(selector(rhs + ";"), ctx);
18
+ cout << lhs << " UNIFIED WITH " << rhs << " =\t" << (unified ? unified->perform(&to_string) : "NOTHING") << endl;
19
+ }
20
+
21
+ int main()
22
+ {
23
+ unify(".foo", ".foo.bar");
24
+ unify("div:nth-of-type(odd)", "div:first-child");
25
+ unify("div", "span:whatever");
26
+ unify("div", "span");
27
+ unify("foo:bar::after", "foo:bar::first-letter");
28
+ unify(".foo#bar.hux", ".hux.foo#bar");
29
+ unify(".foo#bar.hux", ".hux.foo#baz");
30
+ unify("*:blah:fudge", "p:fudge:blah");
31
+
32
+ return 0;
33
+ }
@@ -0,0 +1,61 @@
1
+ #include "to_c.hpp"
2
+ #include "ast.hpp"
3
+
4
+ #include "sass_values.h"
5
+
6
+ namespace Sass {
7
+ using namespace std;
8
+
9
+ Sass_Value* To_C::fallback_impl(AST_Node* n)
10
+ { return sass_make_null(); }
11
+
12
+ Sass_Value* To_C::operator()(Boolean* b)
13
+ { return sass_make_boolean(b->value()); }
14
+
15
+ Sass_Value* To_C::operator()(Number* n)
16
+ { return sass_make_number(n->value(), n->unit().c_str()); }
17
+
18
+ Sass_Value* To_C::operator()(Color* c)
19
+ { return sass_make_color(c->r(), c->g(), c->b(), c->a()); }
20
+
21
+ Sass_Value* To_C::operator()(String_Constant* s)
22
+ { return sass_make_string(s->value().c_str()); }
23
+
24
+ Sass_Value* To_C::operator()(List* l)
25
+ {
26
+ Sass_Value* v = sass_make_list(l->length(), l->separator() == List::COMMA ? SASS_COMMA : SASS_SPACE);
27
+ for (size_t i = 0, L = l->length(); i < L; ++i) {
28
+ sass_list_set_value(v, i, (*l)[i]->perform(this));
29
+ }
30
+ return v;
31
+ }
32
+
33
+ Sass_Value* To_C::operator()(Map* m)
34
+ {
35
+ Sass_Value* v = sass_make_map(m->length());
36
+ int i = 0;
37
+ for (auto key : m->keys()) {
38
+ sass_map_set_key(v, i, key->perform(this));
39
+ sass_map_set_value(v, i, m->at(key)->perform(this));
40
+ i++;
41
+ }
42
+ return v;
43
+ }
44
+
45
+ Sass_Value* To_C::operator()(Arguments* a)
46
+ {
47
+ Sass_Value* v = sass_make_list(a->length(), SASS_COMMA);
48
+ for (size_t i = 0, L = a->length(); i < L; ++i) {
49
+ sass_list_set_value(v, i, (*a)[i]->perform(this));
50
+ }
51
+ return v;
52
+ }
53
+
54
+ Sass_Value* To_C::operator()(Argument* a)
55
+ { return a->value()->perform(this); }
56
+
57
+ // not strictly necessary because of the fallback
58
+ Sass_Value* To_C::operator()(Null* n)
59
+ { return sass_make_null(); }
60
+
61
+ };
@@ -0,0 +1,44 @@
1
+ #define SASS_TO_C
2
+
3
+ #ifndef SASS_OPERATION
4
+ #include "operation.hpp"
5
+ #endif
6
+
7
+ #include "sass_values.h"
8
+
9
+ namespace Sass {
10
+ using namespace std;
11
+
12
+ class AST_Node;
13
+ class Boolean;
14
+ class Number;
15
+ class String_Constant;
16
+ class List;
17
+ class Map;
18
+ class Null;
19
+
20
+ class To_C : public Operation_CRTP<Sass_Value*, To_C> {
21
+
22
+ Sass_Value* fallback_impl(AST_Node* n);
23
+
24
+ public:
25
+
26
+ To_C() { }
27
+ virtual ~To_C() { }
28
+ using Operation<Sass_Value*>::operator();
29
+
30
+ Sass_Value* operator()(Boolean*);
31
+ Sass_Value* operator()(Number*);
32
+ Sass_Value* operator()(Color*);
33
+ Sass_Value* operator()(String_Constant*);
34
+ Sass_Value* operator()(List*);
35
+ Sass_Value* operator()(Map*);
36
+ Sass_Value* operator()(Null*);
37
+ Sass_Value* operator()(Arguments*);
38
+ Sass_Value* operator()(Argument*);
39
+
40
+ template <typename U>
41
+ Sass_Value* fallback(U x) { return fallback_impl(x); }
42
+ };
43
+
44
+ }
@@ -0,0 +1,29 @@
1
+ #include <cmath>
2
+ #include <sstream>
3
+ #include <iomanip>
4
+
5
+ #ifndef SASS_TO_STRING
6
+ #include "to_string.hpp"
7
+ #endif
8
+
9
+ #include "inspect.hpp"
10
+ #include "ast.hpp"
11
+ #include "context.hpp"
12
+ #include <iostream>
13
+
14
+ namespace Sass {
15
+ using namespace std;
16
+
17
+ To_String::To_String(Context* ctx) : ctx(ctx) { }
18
+ To_String::~To_String() { }
19
+
20
+ inline string To_String::fallback_impl(AST_Node* n)
21
+ {
22
+ Inspect i(ctx);
23
+ n->perform(&i);
24
+ return i.get_buffer();
25
+ }
26
+
27
+ inline string To_String::operator()(Null* n)
28
+ { return ""; }
29
+ }
@@ -0,0 +1,32 @@
1
+ #define SASS_TO_STRING
2
+
3
+ #include <string>
4
+
5
+ #ifndef SASS_OPERATION
6
+ #include "operation.hpp"
7
+ #endif
8
+
9
+ namespace Sass {
10
+ using namespace std;
11
+
12
+ struct Context;
13
+ class Null;
14
+
15
+ class To_String : public Operation_CRTP<string, To_String> {
16
+ // import all the class-specific methods and override as desired
17
+ using Operation<string>::operator();
18
+ // override this to define a catch-all
19
+ string fallback_impl(AST_Node* n);
20
+
21
+ Context* ctx;
22
+
23
+ public:
24
+ To_String(Context* ctx = 0);
25
+ virtual ~To_String();
26
+
27
+ string operator()(Null* n);
28
+
29
+ template <typename U>
30
+ string fallback(U n) { return fallback_impl(n); }
31
+ };
32
+ }
@@ -0,0 +1,32 @@
1
+ #define SASS_TOKEN
2
+
3
+ #include <cstring>
4
+ #include <string>
5
+ #include <sstream>
6
+
7
+ namespace Sass {
8
+ using namespace std;
9
+
10
+ // Token type for representing lexed chunks of text
11
+ struct Token {
12
+
13
+ const char* begin;
14
+ const char* end;
15
+
16
+ Token() : begin(0), end(0) { }
17
+ Token(const char* s) : begin(s), end(s + strlen(s)) { }
18
+ Token(const char* b, const char* e) : begin(b), end(e) { }
19
+
20
+ size_t length() const { return end - begin; }
21
+ string to_string() const { return string(begin, end - begin); }
22
+
23
+ string unquote() const;
24
+ void unquote_to_stream(stringstream& buf) const;
25
+
26
+ operator bool() { return begin && end && begin >= end; }
27
+ operator string() { return to_string(); }
28
+
29
+ bool operator==(Token t) { return to_string() == t.to_string(); }
30
+ };
31
+
32
+ }
@@ -0,0 +1,54 @@
1
+ #include "units.hpp"
2
+
3
+ #define PI 3.14159265358979323846
4
+
5
+ namespace Sass {
6
+
7
+ double conversion_factors[10][10] = {
8
+ /* in cm pc mm pt px deg grad rad turn */
9
+ /* in */ { 1, 2.54, 6, 25.4, 72, 96, 1, 1, 1, 1 },
10
+ /* cm */ { 1.0/2.54, 1, 6.0/2.54, 10, 72.0/2.54, 96.0/2.54, 1, 1, 1, 1 },
11
+ /* pc */ { 1.0/6.0, 2.54/6.0, 1, 25.4/6.0, 72.0/6.0, 96.0/6.0, 1, 1, 1, 1 },
12
+ /* mm */ { 1.0/25.4, 1.0/10.0, 6.0/25.4, 1, 72.0/25.4, 96.0/25.4, 1, 1, 1, 1 },
13
+ /* pt */ { 1.0/72.0, 2.54/72.0, 6.0/72.0, 25.4/72.0, 1, 96.0/72.0, 1, 1, 1, 1 },
14
+ /* px */ { 1.0/96.0, 2.54/96.0, 6.0/96.0, 25.4/96.0, 72.0/96.0, 1, 1, 1, 1, 1 },
15
+ /* deg */ { 1 , 1 , 1 , 1 , 1 , 1, 1, 40.0/36.0, PI/180.0, 1.0/360.0 },
16
+ /* grad */ { 1 , 1 , 1 , 1 , 1 , 1, 36.0/40.0, 1, PI/200.0, 1.0/400.0 },
17
+ /* rad */ { 1 , 1 , 1 , 1 , 1 , 1, 180.0/PI, 200.0/PI, 1, PI/2.0 },
18
+ /* turn */ { 1 , 1 , 1 , 1 , 1 , 1, 360.0/1.0, 400.0/1.0, 2.0*PI, 1 }
19
+ };
20
+
21
+ Unit string_to_unit(const string& s)
22
+ {
23
+ if (s == "in") return IN;
24
+ else if (s == "cm") return CM;
25
+ else if (s == "pc") return PC;
26
+ else if (s == "mm") return MM;
27
+ else if (s == "pt") return PT;
28
+ else if (s == "px") return PX;
29
+ else if (s == "deg") return DEG;
30
+ else if (s == "grad") return GRAD;
31
+ else if (s == "rad") return RAD;
32
+ else if (s == "turn") return TURN;
33
+ else return INCOMMENSURABLE;
34
+ }
35
+
36
+ double conversion_factor(const string& s1, const string& s2)
37
+ {
38
+ Unit u1 = string_to_unit(s1);
39
+ Unit u2 = string_to_unit(s2);
40
+ double factor;
41
+ if (u1 == INCOMMENSURABLE || u2 == INCOMMENSURABLE)
42
+ factor = 0;
43
+ else
44
+ factor = conversion_factors[u1][u2];
45
+ return factor;
46
+ }
47
+
48
+ double convert(double n, const string& from, const string& to)
49
+ {
50
+ double factor = conversion_factor(from, to);
51
+ return factor ? factor * n : n;
52
+ }
53
+
54
+ }
@@ -0,0 +1,10 @@
1
+ #include <string>
2
+
3
+ namespace Sass {
4
+ using namespace std;
5
+ enum Unit { IN, CM, PC, MM, PT, PX, DEG, GRAD, RAD, TURN, INCOMMENSURABLE };
6
+ extern double conversion_factors[10][10];
7
+ Unit string_to_unit(const string&);
8
+ double conversion_factor(const string&, const string&);
9
+ double convert(double, const string&, const string&);
10
+ }
@@ -0,0 +1,34 @@
1
+ // Copyright 2006 Nemanja Trifunovic
2
+
3
+ /*
4
+ Permission is hereby granted, free of charge, to any person or organization
5
+ obtaining a copy of the software and accompanying documentation covered by
6
+ this license (the "Software") to use, reproduce, display, distribute,
7
+ execute, and transmit the Software, and to prepare derivative works of the
8
+ Software, and to permit third-parties to whom the Software is furnished to
9
+ do so, all subject to the following:
10
+
11
+ The copyright notices in the Software and this entire statement, including
12
+ the above license grant, this restriction and the following disclaimer,
13
+ must be included in all copies of the Software, in whole or in part, and
14
+ all derivative works of the Software, unless such copies or derivative
15
+ works are solely in the form of machine-executable object code generated by
16
+ a source language processor.
17
+
18
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
+ FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
21
+ SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
22
+ FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
23
+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24
+ DEALINGS IN THE SOFTWARE.
25
+ */
26
+
27
+
28
+ #ifndef UTF8_FOR_CPP_2675DCD0_9480_4c0c_B92A_CC14C027B731
29
+ #define UTF8_FOR_CPP_2675DCD0_9480_4c0c_B92A_CC14C027B731
30
+
31
+ #include "utf8/checked.h"
32
+ #include "utf8/unchecked.h"
33
+
34
+ #endif // header guard
@@ -0,0 +1,327 @@
1
+ // Copyright 2006 Nemanja Trifunovic
2
+
3
+ /*
4
+ Permission is hereby granted, free of charge, to any person or organization
5
+ obtaining a copy of the software and accompanying documentation covered by
6
+ this license (the "Software") to use, reproduce, display, distribute,
7
+ execute, and transmit the Software, and to prepare derivative works of the
8
+ Software, and to permit third-parties to whom the Software is furnished to
9
+ do so, all subject to the following:
10
+
11
+ The copyright notices in the Software and this entire statement, including
12
+ the above license grant, this restriction and the following disclaimer,
13
+ must be included in all copies of the Software, in whole or in part, and
14
+ all derivative works of the Software, unless such copies or derivative
15
+ works are solely in the form of machine-executable object code generated by
16
+ a source language processor.
17
+
18
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
+ FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
21
+ SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
22
+ FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
23
+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24
+ DEALINGS IN THE SOFTWARE.
25
+ */
26
+
27
+
28
+ #ifndef UTF8_FOR_CPP_CHECKED_H_2675DCD0_9480_4c0c_B92A_CC14C027B731
29
+ #define UTF8_FOR_CPP_CHECKED_H_2675DCD0_9480_4c0c_B92A_CC14C027B731
30
+
31
+ #include "core.h"
32
+ #include <stdexcept>
33
+
34
+ namespace utf8
35
+ {
36
+ // Base for the exceptions that may be thrown from the library
37
+ class exception : public ::std::exception {
38
+ };
39
+
40
+ // Exceptions that may be thrown from the library functions.
41
+ class invalid_code_point : public exception {
42
+ uint32_t cp;
43
+ public:
44
+ invalid_code_point(uint32_t cp) : cp(cp) {}
45
+ virtual const char* what() const throw() { return "Invalid code point"; }
46
+ uint32_t code_point() const {return cp;}
47
+ };
48
+
49
+ class invalid_utf8 : public exception {
50
+ uint8_t u8;
51
+ public:
52
+ invalid_utf8 (uint8_t u) : u8(u) {}
53
+ virtual const char* what() const throw() { return "Invalid UTF-8"; }
54
+ uint8_t utf8_octet() const {return u8;}
55
+ };
56
+
57
+ class invalid_utf16 : public exception {
58
+ uint16_t u16;
59
+ public:
60
+ invalid_utf16 (uint16_t u) : u16(u) {}
61
+ virtual const char* what() const throw() { return "Invalid UTF-16"; }
62
+ uint16_t utf16_word() const {return u16;}
63
+ };
64
+
65
+ class not_enough_room : public exception {
66
+ public:
67
+ virtual const char* what() const throw() { return "Not enough space"; }
68
+ };
69
+
70
+ /// The library API - functions intended to be called by the users
71
+
72
+ template <typename octet_iterator>
73
+ octet_iterator append(uint32_t cp, octet_iterator result)
74
+ {
75
+ if (!utf8::internal::is_code_point_valid(cp))
76
+ throw invalid_code_point(cp);
77
+
78
+ if (cp < 0x80) // one octet
79
+ *(result++) = static_cast<uint8_t>(cp);
80
+ else if (cp < 0x800) { // two octets
81
+ *(result++) = static_cast<uint8_t>((cp >> 6) | 0xc0);
82
+ *(result++) = static_cast<uint8_t>((cp & 0x3f) | 0x80);
83
+ }
84
+ else if (cp < 0x10000) { // three octets
85
+ *(result++) = static_cast<uint8_t>((cp >> 12) | 0xe0);
86
+ *(result++) = static_cast<uint8_t>(((cp >> 6) & 0x3f) | 0x80);
87
+ *(result++) = static_cast<uint8_t>((cp & 0x3f) | 0x80);
88
+ }
89
+ else { // four octets
90
+ *(result++) = static_cast<uint8_t>((cp >> 18) | 0xf0);
91
+ *(result++) = static_cast<uint8_t>(((cp >> 12) & 0x3f) | 0x80);
92
+ *(result++) = static_cast<uint8_t>(((cp >> 6) & 0x3f) | 0x80);
93
+ *(result++) = static_cast<uint8_t>((cp & 0x3f) | 0x80);
94
+ }
95
+ return result;
96
+ }
97
+
98
+ template <typename octet_iterator, typename output_iterator>
99
+ output_iterator replace_invalid(octet_iterator start, octet_iterator end, output_iterator out, uint32_t replacement)
100
+ {
101
+ while (start != end) {
102
+ octet_iterator sequence_start = start;
103
+ internal::utf_error err_code = utf8::internal::validate_next(start, end);
104
+ switch (err_code) {
105
+ case internal::UTF8_OK :
106
+ for (octet_iterator it = sequence_start; it != start; ++it)
107
+ *out++ = *it;
108
+ break;
109
+ case internal::NOT_ENOUGH_ROOM:
110
+ throw not_enough_room();
111
+ case internal::INVALID_LEAD:
112
+ out = utf8::append (replacement, out);
113
+ ++start;
114
+ break;
115
+ case internal::INCOMPLETE_SEQUENCE:
116
+ case internal::OVERLONG_SEQUENCE:
117
+ case internal::INVALID_CODE_POINT:
118
+ out = utf8::append (replacement, out);
119
+ ++start;
120
+ // just one replacement mark for the sequence
121
+ while (start != end && utf8::internal::is_trail(*start))
122
+ ++start;
123
+ break;
124
+ }
125
+ }
126
+ return out;
127
+ }
128
+
129
+ template <typename octet_iterator, typename output_iterator>
130
+ inline output_iterator replace_invalid(octet_iterator start, octet_iterator end, output_iterator out)
131
+ {
132
+ static const uint32_t replacement_marker = utf8::internal::mask16(0xfffd);
133
+ return utf8::replace_invalid(start, end, out, replacement_marker);
134
+ }
135
+
136
+ template <typename octet_iterator>
137
+ uint32_t next(octet_iterator& it, octet_iterator end)
138
+ {
139
+ uint32_t cp = 0;
140
+ internal::utf_error err_code = utf8::internal::validate_next(it, end, cp);
141
+ switch (err_code) {
142
+ case internal::UTF8_OK :
143
+ break;
144
+ case internal::NOT_ENOUGH_ROOM :
145
+ throw not_enough_room();
146
+ case internal::INVALID_LEAD :
147
+ case internal::INCOMPLETE_SEQUENCE :
148
+ case internal::OVERLONG_SEQUENCE :
149
+ throw invalid_utf8(*it);
150
+ case internal::INVALID_CODE_POINT :
151
+ throw invalid_code_point(cp);
152
+ }
153
+ return cp;
154
+ }
155
+
156
+ template <typename octet_iterator>
157
+ uint32_t peek_next(octet_iterator it, octet_iterator end)
158
+ {
159
+ return utf8::next(it, end);
160
+ }
161
+
162
+ template <typename octet_iterator>
163
+ uint32_t prior(octet_iterator& it, octet_iterator start)
164
+ {
165
+ // can't do much if it == start
166
+ if (it == start)
167
+ throw not_enough_room();
168
+
169
+ octet_iterator end = it;
170
+ // Go back until we hit either a lead octet or start
171
+ while (utf8::internal::is_trail(*(--it)))
172
+ if (it == start)
173
+ throw invalid_utf8(*it); // error - no lead byte in the sequence
174
+ return utf8::peek_next(it, end);
175
+ }
176
+
177
+ /// Deprecated in versions that include "prior"
178
+ template <typename octet_iterator>
179
+ uint32_t previous(octet_iterator& it, octet_iterator pass_start)
180
+ {
181
+ octet_iterator end = it;
182
+ while (utf8::internal::is_trail(*(--it)))
183
+ if (it == pass_start)
184
+ throw invalid_utf8(*it); // error - no lead byte in the sequence
185
+ octet_iterator temp = it;
186
+ return utf8::next(temp, end);
187
+ }
188
+
189
+ template <typename octet_iterator, typename distance_type>
190
+ void advance (octet_iterator& it, distance_type n, octet_iterator end)
191
+ {
192
+ for (distance_type i = 0; i < n; ++i)
193
+ utf8::next(it, end);
194
+ }
195
+
196
+ template <typename octet_iterator>
197
+ typename std::iterator_traits<octet_iterator>::difference_type
198
+ distance (octet_iterator first, octet_iterator last)
199
+ {
200
+ typename std::iterator_traits<octet_iterator>::difference_type dist;
201
+ for (dist = 0; first < last; ++dist)
202
+ utf8::next(first, last);
203
+ return dist;
204
+ }
205
+
206
+ template <typename u16bit_iterator, typename octet_iterator>
207
+ octet_iterator utf16to8 (u16bit_iterator start, u16bit_iterator end, octet_iterator result)
208
+ {
209
+ while (start != end) {
210
+ uint32_t cp = utf8::internal::mask16(*start++);
211
+ // Take care of surrogate pairs first
212
+ if (utf8::internal::is_lead_surrogate(cp)) {
213
+ if (start != end) {
214
+ uint32_t trail_surrogate = utf8::internal::mask16(*start++);
215
+ if (utf8::internal::is_trail_surrogate(trail_surrogate))
216
+ cp = (cp << 10) + trail_surrogate + internal::SURROGATE_OFFSET;
217
+ else
218
+ throw invalid_utf16(static_cast<uint16_t>(trail_surrogate));
219
+ }
220
+ else
221
+ throw invalid_utf16(static_cast<uint16_t>(cp));
222
+
223
+ }
224
+ // Lone trail surrogate
225
+ else if (utf8::internal::is_trail_surrogate(cp))
226
+ throw invalid_utf16(static_cast<uint16_t>(cp));
227
+
228
+ result = utf8::append(cp, result);
229
+ }
230
+ return result;
231
+ }
232
+
233
+ template <typename u16bit_iterator, typename octet_iterator>
234
+ u16bit_iterator utf8to16 (octet_iterator start, octet_iterator end, u16bit_iterator result)
235
+ {
236
+ while (start != end) {
237
+ uint32_t cp = utf8::next(start, end);
238
+ if (cp > 0xffff) { //make a surrogate pair
239
+ *result++ = static_cast<uint16_t>((cp >> 10) + internal::LEAD_OFFSET);
240
+ *result++ = static_cast<uint16_t>((cp & 0x3ff) + internal::TRAIL_SURROGATE_MIN);
241
+ }
242
+ else
243
+ *result++ = static_cast<uint16_t>(cp);
244
+ }
245
+ return result;
246
+ }
247
+
248
+ template <typename octet_iterator, typename u32bit_iterator>
249
+ octet_iterator utf32to8 (u32bit_iterator start, u32bit_iterator end, octet_iterator result)
250
+ {
251
+ while (start != end)
252
+ result = utf8::append(*(start++), result);
253
+
254
+ return result;
255
+ }
256
+
257
+ template <typename octet_iterator, typename u32bit_iterator>
258
+ u32bit_iterator utf8to32 (octet_iterator start, octet_iterator end, u32bit_iterator result)
259
+ {
260
+ while (start != end)
261
+ (*result++) = utf8::next(start, end);
262
+
263
+ return result;
264
+ }
265
+
266
+ // The iterator class
267
+ template <typename octet_iterator>
268
+ class iterator : public std::iterator <std::bidirectional_iterator_tag, uint32_t> {
269
+ octet_iterator it;
270
+ octet_iterator range_start;
271
+ octet_iterator range_end;
272
+ public:
273
+ iterator () {}
274
+ explicit iterator (const octet_iterator& octet_it,
275
+ const octet_iterator& range_start,
276
+ const octet_iterator& range_end) :
277
+ it(octet_it), range_start(range_start), range_end(range_end)
278
+ {
279
+ if (it < range_start || it > range_end)
280
+ throw std::out_of_range("Invalid utf-8 iterator position");
281
+ }
282
+ // the default "big three" are OK
283
+ octet_iterator base () const { return it; }
284
+ uint32_t operator * () const
285
+ {
286
+ octet_iterator temp = it;
287
+ return utf8::next(temp, range_end);
288
+ }
289
+ bool operator == (const iterator& rhs) const
290
+ {
291
+ if (range_start != rhs.range_start || range_end != rhs.range_end)
292
+ throw std::logic_error("Comparing utf-8 iterators defined with different ranges");
293
+ return (it == rhs.it);
294
+ }
295
+ bool operator != (const iterator& rhs) const
296
+ {
297
+ return !(operator == (rhs));
298
+ }
299
+ iterator& operator ++ ()
300
+ {
301
+ utf8::next(it, range_end);
302
+ return *this;
303
+ }
304
+ iterator operator ++ (int)
305
+ {
306
+ iterator temp = *this;
307
+ utf8::next(it, range_end);
308
+ return temp;
309
+ }
310
+ iterator& operator -- ()
311
+ {
312
+ utf8::prior(it, range_start);
313
+ return *this;
314
+ }
315
+ iterator operator -- (int)
316
+ {
317
+ iterator temp = *this;
318
+ utf8::prior(it, range_start);
319
+ return temp;
320
+ }
321
+ }; // class iterator
322
+
323
+ } // namespace utf8
324
+
325
+ #endif //header guard
326
+
327
+