sassc 2.0.0 → 2.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (260) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -0
  3. data/.gitmodules +1 -1
  4. data/.travis.yml +9 -3
  5. data/CHANGELOG.md +36 -0
  6. data/CODE_OF_CONDUCT.md +1 -1
  7. data/README.md +1 -1
  8. data/Rakefile +43 -7
  9. data/ext/depend +4 -0
  10. data/ext/extconf.rb +92 -0
  11. data/ext/libsass/VERSION +1 -0
  12. data/ext/libsass/include/sass/base.h +9 -1
  13. data/ext/libsass/include/sass/context.h +5 -1
  14. data/ext/libsass/src/MurmurHash2.hpp +91 -0
  15. data/ext/libsass/src/ast.cpp +755 -2028
  16. data/ext/libsass/src/ast.hpp +492 -2477
  17. data/ext/libsass/src/{to_c.cpp → ast2c.cpp} +22 -16
  18. data/ext/libsass/src/ast2c.hpp +39 -0
  19. data/ext/libsass/src/ast_def_macros.hpp +70 -10
  20. data/ext/libsass/src/ast_fwd_decl.cpp +5 -3
  21. data/ext/libsass/src/ast_fwd_decl.hpp +107 -296
  22. data/ext/libsass/src/ast_helpers.hpp +292 -0
  23. data/ext/libsass/src/ast_sel_cmp.cpp +396 -0
  24. data/ext/libsass/src/ast_sel_super.cpp +539 -0
  25. data/ext/libsass/src/ast_sel_unify.cpp +275 -0
  26. data/ext/libsass/src/ast_sel_weave.cpp +616 -0
  27. data/ext/libsass/src/ast_selectors.cpp +1043 -0
  28. data/ext/libsass/src/ast_selectors.hpp +522 -0
  29. data/ext/libsass/src/ast_supports.cpp +114 -0
  30. data/ext/libsass/src/ast_supports.hpp +121 -0
  31. data/ext/libsass/src/ast_values.cpp +1154 -0
  32. data/ext/libsass/src/ast_values.hpp +498 -0
  33. data/ext/libsass/src/backtrace.cpp +11 -7
  34. data/ext/libsass/src/backtrace.hpp +5 -5
  35. data/ext/libsass/src/base64vlq.cpp +5 -2
  36. data/ext/libsass/src/base64vlq.hpp +1 -1
  37. data/ext/libsass/src/bind.cpp +35 -34
  38. data/ext/libsass/src/bind.hpp +3 -1
  39. data/ext/libsass/src/c2ast.cpp +64 -0
  40. data/ext/libsass/src/c2ast.hpp +14 -0
  41. data/ext/libsass/src/cencode.c +4 -6
  42. data/ext/libsass/src/check_nesting.cpp +83 -88
  43. data/ext/libsass/src/check_nesting.hpp +39 -34
  44. data/ext/libsass/src/color_maps.cpp +168 -164
  45. data/ext/libsass/src/color_maps.hpp +152 -160
  46. data/ext/libsass/src/constants.cpp +20 -0
  47. data/ext/libsass/src/constants.hpp +19 -0
  48. data/ext/libsass/src/context.cpp +104 -121
  49. data/ext/libsass/src/context.hpp +43 -55
  50. data/ext/libsass/src/cssize.cpp +103 -188
  51. data/ext/libsass/src/cssize.hpp +45 -51
  52. data/ext/libsass/src/dart_helpers.hpp +199 -0
  53. data/ext/libsass/src/debugger.hpp +524 -361
  54. data/ext/libsass/src/emitter.cpp +26 -26
  55. data/ext/libsass/src/emitter.hpp +20 -18
  56. data/ext/libsass/src/environment.cpp +41 -27
  57. data/ext/libsass/src/environment.hpp +33 -22
  58. data/ext/libsass/src/error_handling.cpp +92 -94
  59. data/ext/libsass/src/error_handling.hpp +73 -50
  60. data/ext/libsass/src/eval.cpp +380 -515
  61. data/ext/libsass/src/eval.hpp +64 -57
  62. data/ext/libsass/src/eval_selectors.cpp +75 -0
  63. data/ext/libsass/src/expand.cpp +322 -263
  64. data/ext/libsass/src/expand.hpp +55 -39
  65. data/ext/libsass/src/extender.cpp +1188 -0
  66. data/ext/libsass/src/extender.hpp +399 -0
  67. data/ext/libsass/src/extension.cpp +43 -0
  68. data/ext/libsass/src/extension.hpp +89 -0
  69. data/ext/libsass/src/file.cpp +134 -88
  70. data/ext/libsass/src/file.hpp +28 -37
  71. data/ext/libsass/src/fn_colors.cpp +596 -0
  72. data/ext/libsass/src/fn_colors.hpp +85 -0
  73. data/ext/libsass/src/fn_lists.cpp +285 -0
  74. data/ext/libsass/src/fn_lists.hpp +34 -0
  75. data/ext/libsass/src/fn_maps.cpp +94 -0
  76. data/ext/libsass/src/fn_maps.hpp +30 -0
  77. data/ext/libsass/src/fn_miscs.cpp +244 -0
  78. data/ext/libsass/src/fn_miscs.hpp +40 -0
  79. data/ext/libsass/src/fn_numbers.cpp +227 -0
  80. data/ext/libsass/src/fn_numbers.hpp +45 -0
  81. data/ext/libsass/src/fn_selectors.cpp +205 -0
  82. data/ext/libsass/src/fn_selectors.hpp +35 -0
  83. data/ext/libsass/src/fn_strings.cpp +268 -0
  84. data/ext/libsass/src/fn_strings.hpp +34 -0
  85. data/ext/libsass/src/fn_utils.cpp +158 -0
  86. data/ext/libsass/src/fn_utils.hpp +62 -0
  87. data/ext/libsass/src/inspect.cpp +253 -266
  88. data/ext/libsass/src/inspect.hpp +72 -74
  89. data/ext/libsass/src/json.cpp +2 -2
  90. data/ext/libsass/src/lexer.cpp +25 -84
  91. data/ext/libsass/src/lexer.hpp +5 -16
  92. data/ext/libsass/src/listize.cpp +27 -43
  93. data/ext/libsass/src/listize.hpp +14 -11
  94. data/ext/libsass/src/mapping.hpp +1 -0
  95. data/ext/libsass/src/memory.hpp +12 -0
  96. data/ext/libsass/src/memory/allocator.cpp +48 -0
  97. data/ext/libsass/src/memory/allocator.hpp +138 -0
  98. data/ext/libsass/src/memory/config.hpp +20 -0
  99. data/ext/libsass/src/memory/memory_pool.hpp +186 -0
  100. data/ext/libsass/src/memory/shared_ptr.cpp +33 -0
  101. data/ext/libsass/src/memory/shared_ptr.hpp +332 -0
  102. data/ext/libsass/src/operation.hpp +193 -143
  103. data/ext/libsass/src/operators.cpp +56 -29
  104. data/ext/libsass/src/operators.hpp +11 -11
  105. data/ext/libsass/src/ordered_map.hpp +112 -0
  106. data/ext/libsass/src/output.cpp +59 -75
  107. data/ext/libsass/src/output.hpp +15 -22
  108. data/ext/libsass/src/parser.cpp +662 -818
  109. data/ext/libsass/src/parser.hpp +96 -100
  110. data/ext/libsass/src/parser_selectors.cpp +189 -0
  111. data/ext/libsass/src/permutate.hpp +164 -0
  112. data/ext/libsass/src/plugins.cpp +12 -8
  113. data/ext/libsass/src/plugins.hpp +8 -8
  114. data/ext/libsass/src/position.cpp +10 -26
  115. data/ext/libsass/src/position.hpp +44 -21
  116. data/ext/libsass/src/prelexer.cpp +14 -8
  117. data/ext/libsass/src/prelexer.hpp +9 -9
  118. data/ext/libsass/src/remove_placeholders.cpp +59 -57
  119. data/ext/libsass/src/remove_placeholders.hpp +20 -18
  120. data/ext/libsass/src/sass.cpp +25 -18
  121. data/ext/libsass/src/sass.hpp +22 -14
  122. data/ext/libsass/src/sass2scss.cpp +49 -18
  123. data/ext/libsass/src/sass_context.cpp +104 -132
  124. data/ext/libsass/src/sass_context.hpp +2 -2
  125. data/ext/libsass/src/sass_functions.cpp +7 -4
  126. data/ext/libsass/src/sass_functions.hpp +1 -1
  127. data/ext/libsass/src/sass_values.cpp +26 -21
  128. data/ext/libsass/src/settings.hpp +19 -0
  129. data/ext/libsass/src/source.cpp +69 -0
  130. data/ext/libsass/src/source.hpp +95 -0
  131. data/ext/libsass/src/source_data.hpp +32 -0
  132. data/ext/libsass/src/source_map.cpp +27 -20
  133. data/ext/libsass/src/source_map.hpp +14 -11
  134. data/ext/libsass/src/stylesheet.cpp +22 -0
  135. data/ext/libsass/src/stylesheet.hpp +57 -0
  136. data/ext/libsass/src/to_value.cpp +24 -22
  137. data/ext/libsass/src/to_value.hpp +18 -22
  138. data/ext/libsass/src/units.cpp +28 -22
  139. data/ext/libsass/src/units.hpp +9 -8
  140. data/ext/libsass/src/utf8/checked.h +12 -10
  141. data/ext/libsass/src/utf8/core.h +3 -0
  142. data/ext/libsass/src/utf8_string.cpp +12 -10
  143. data/ext/libsass/src/utf8_string.hpp +7 -6
  144. data/ext/libsass/src/util.cpp +97 -107
  145. data/ext/libsass/src/util.hpp +74 -30
  146. data/ext/libsass/src/util_string.cpp +125 -0
  147. data/ext/libsass/src/util_string.hpp +73 -0
  148. data/ext/libsass/src/values.cpp +33 -24
  149. data/ext/libsass/src/values.hpp +2 -2
  150. data/lib/sassc.rb +24 -0
  151. data/lib/sassc/engine.rb +7 -5
  152. data/lib/sassc/functions_handler.rb +11 -13
  153. data/lib/sassc/native.rb +10 -9
  154. data/lib/sassc/native/native_functions_api.rb +0 -5
  155. data/lib/sassc/script.rb +4 -6
  156. data/lib/sassc/version.rb +1 -1
  157. data/sassc.gemspec +32 -12
  158. data/test/engine_test.rb +32 -2
  159. data/test/functions_test.rb +38 -1
  160. data/test/native_test.rb +4 -4
  161. metadata +95 -109
  162. data/ext/Rakefile +0 -3
  163. data/ext/libsass/.editorconfig +0 -15
  164. data/ext/libsass/.gitattributes +0 -2
  165. data/ext/libsass/.github/CONTRIBUTING.md +0 -65
  166. data/ext/libsass/.github/ISSUE_TEMPLATE.md +0 -54
  167. data/ext/libsass/.gitignore +0 -85
  168. data/ext/libsass/.travis.yml +0 -64
  169. data/ext/libsass/COPYING +0 -25
  170. data/ext/libsass/GNUmakefile.am +0 -88
  171. data/ext/libsass/INSTALL +0 -1
  172. data/ext/libsass/LICENSE +0 -25
  173. data/ext/libsass/Makefile +0 -351
  174. data/ext/libsass/Makefile.conf +0 -55
  175. data/ext/libsass/Readme.md +0 -104
  176. data/ext/libsass/SECURITY.md +0 -10
  177. data/ext/libsass/appveyor.yml +0 -91
  178. data/ext/libsass/configure.ac +0 -138
  179. data/ext/libsass/contrib/libsass.spec +0 -66
  180. data/ext/libsass/docs/README.md +0 -20
  181. data/ext/libsass/docs/api-context-example.md +0 -45
  182. data/ext/libsass/docs/api-context-internal.md +0 -163
  183. data/ext/libsass/docs/api-context.md +0 -295
  184. data/ext/libsass/docs/api-doc.md +0 -215
  185. data/ext/libsass/docs/api-function-example.md +0 -67
  186. data/ext/libsass/docs/api-function-internal.md +0 -8
  187. data/ext/libsass/docs/api-function.md +0 -74
  188. data/ext/libsass/docs/api-importer-example.md +0 -112
  189. data/ext/libsass/docs/api-importer-internal.md +0 -20
  190. data/ext/libsass/docs/api-importer.md +0 -86
  191. data/ext/libsass/docs/api-value-example.md +0 -55
  192. data/ext/libsass/docs/api-value-internal.md +0 -76
  193. data/ext/libsass/docs/api-value.md +0 -154
  194. data/ext/libsass/docs/build-on-darwin.md +0 -27
  195. data/ext/libsass/docs/build-on-gentoo.md +0 -55
  196. data/ext/libsass/docs/build-on-windows.md +0 -139
  197. data/ext/libsass/docs/build-shared-library.md +0 -35
  198. data/ext/libsass/docs/build-with-autotools.md +0 -78
  199. data/ext/libsass/docs/build-with-makefiles.md +0 -68
  200. data/ext/libsass/docs/build-with-mingw.md +0 -107
  201. data/ext/libsass/docs/build-with-visual-studio.md +0 -90
  202. data/ext/libsass/docs/build.md +0 -97
  203. data/ext/libsass/docs/compatibility-plan.md +0 -48
  204. data/ext/libsass/docs/contributing.md +0 -17
  205. data/ext/libsass/docs/custom-functions-internal.md +0 -122
  206. data/ext/libsass/docs/dev-ast-memory.md +0 -223
  207. data/ext/libsass/docs/implementations.md +0 -56
  208. data/ext/libsass/docs/plugins.md +0 -47
  209. data/ext/libsass/docs/setup-environment.md +0 -68
  210. data/ext/libsass/docs/source-map-internals.md +0 -51
  211. data/ext/libsass/docs/trace.md +0 -26
  212. data/ext/libsass/docs/triage.md +0 -17
  213. data/ext/libsass/docs/unicode.md +0 -39
  214. data/ext/libsass/extconf.rb +0 -6
  215. data/ext/libsass/include/sass/version.h.in +0 -12
  216. data/ext/libsass/m4/.gitkeep +0 -0
  217. data/ext/libsass/m4/m4-ax_cxx_compile_stdcxx_11.m4 +0 -167
  218. data/ext/libsass/res/resource.rc +0 -35
  219. data/ext/libsass/script/bootstrap +0 -13
  220. data/ext/libsass/script/branding +0 -10
  221. data/ext/libsass/script/ci-build-libsass +0 -134
  222. data/ext/libsass/script/ci-build-plugin +0 -62
  223. data/ext/libsass/script/ci-install-compiler +0 -6
  224. data/ext/libsass/script/ci-install-deps +0 -20
  225. data/ext/libsass/script/ci-report-coverage +0 -42
  226. data/ext/libsass/script/spec +0 -5
  227. data/ext/libsass/script/tap-driver +0 -652
  228. data/ext/libsass/script/tap-runner +0 -1
  229. data/ext/libsass/script/test-leaks.pl +0 -103
  230. data/ext/libsass/src/GNUmakefile.am +0 -54
  231. data/ext/libsass/src/extend.cpp +0 -2130
  232. data/ext/libsass/src/extend.hpp +0 -86
  233. data/ext/libsass/src/functions.cpp +0 -2234
  234. data/ext/libsass/src/functions.hpp +0 -198
  235. data/ext/libsass/src/memory/SharedPtr.cpp +0 -114
  236. data/ext/libsass/src/memory/SharedPtr.hpp +0 -206
  237. data/ext/libsass/src/node.cpp +0 -319
  238. data/ext/libsass/src/node.hpp +0 -118
  239. data/ext/libsass/src/paths.hpp +0 -71
  240. data/ext/libsass/src/sass_util.cpp +0 -149
  241. data/ext/libsass/src/sass_util.hpp +0 -256
  242. data/ext/libsass/src/subset_map.cpp +0 -55
  243. data/ext/libsass/src/subset_map.hpp +0 -76
  244. data/ext/libsass/src/support/libsass.pc.in +0 -11
  245. data/ext/libsass/src/to_c.hpp +0 -39
  246. data/ext/libsass/test/test_node.cpp +0 -94
  247. data/ext/libsass/test/test_paths.cpp +0 -28
  248. data/ext/libsass/test/test_selector_difference.cpp +0 -25
  249. data/ext/libsass/test/test_specificity.cpp +0 -25
  250. data/ext/libsass/test/test_subset_map.cpp +0 -472
  251. data/ext/libsass/test/test_superselector.cpp +0 -69
  252. data/ext/libsass/test/test_unification.cpp +0 -31
  253. data/ext/libsass/version.sh +0 -10
  254. data/ext/libsass/win/libsass.sln +0 -39
  255. data/ext/libsass/win/libsass.sln.DotSettings +0 -9
  256. data/ext/libsass/win/libsass.targets +0 -118
  257. data/ext/libsass/win/libsass.vcxproj +0 -188
  258. data/ext/libsass/win/libsass.vcxproj.filters +0 -357
  259. data/lib/sassc/native/lib_c.rb +0 -21
  260. data/lib/tasks/libsass.rb +0 -33
@@ -154,6 +154,21 @@ namespace Sass
154
154
 
155
155
  }
156
156
 
157
+ static size_t findFirstCharacter (std::string& sass, size_t pos)
158
+ {
159
+ return sass.find_first_not_of(SASS2SCSS_FIND_WHITESPACE, pos);
160
+ }
161
+
162
+ static size_t findLastCharacter (std::string& sass, size_t pos)
163
+ {
164
+ return sass.find_last_not_of(SASS2SCSS_FIND_WHITESPACE, pos);
165
+ }
166
+
167
+ static bool isUrl (std::string& sass, size_t pos)
168
+ {
169
+ return sass[pos] == 'u' && sass[pos+1] == 'r' && sass[pos+2] == 'l' && sass[pos+3] == '(';
170
+ }
171
+
157
172
  // check if there is some char data
158
173
  // will ignore everything in comments
159
174
  static bool hasCharData (std::string& sass)
@@ -452,7 +467,7 @@ namespace Sass
452
467
  // right trim input
453
468
  sass = rtrim(sass);
454
469
 
455
- // get postion of first meaningfull character in string
470
+ // get position of first meaningfull character in string
456
471
  size_t pos_left = sass.find_first_not_of(SASS2SCSS_FIND_WHITESPACE);
457
472
 
458
473
  // special case for final run
@@ -542,7 +557,7 @@ namespace Sass
542
557
  // default to a selector
543
558
  // change back if property found
544
559
  converter.selector = true;
545
- // get postion of first whitespace char
560
+ // get position of first whitespace char
546
561
  size_t pos_wspace = sass.find_first_of(SASS2SCSS_FIND_WHITESPACE, pos_left);
547
562
  // assertion check for valid result
548
563
  if (pos_wspace != std::string::npos)
@@ -565,7 +580,7 @@ namespace Sass
565
580
  // assertion for valid result
566
581
  if (pos_colon != std::string::npos)
567
582
  {
568
- // ... after the first word (skip begining colons)
583
+ // ... after the first word (skip beginning colons)
569
584
  pos_colon = sass.find_first_of(":", pos_colon);
570
585
  // it is a selector if there was no colon found
571
586
  converter.selector = pos_colon == std::string::npos;
@@ -587,6 +602,7 @@ namespace Sass
587
602
  sass.substr(pos_left, 5) == "@warn" ||
588
603
  sass.substr(pos_left, 6) == "@debug" ||
589
604
  sass.substr(pos_left, 6) == "@error" ||
605
+ sass.substr(pos_left, 6) == "@value" ||
590
606
  sass.substr(pos_left, 8) == "@charset" ||
591
607
  sass.substr(pos_left, 10) == "@namespace"
592
608
  ) { sass = indent + sass.substr(pos_left); }
@@ -606,23 +622,38 @@ namespace Sass
606
622
  {
607
623
  // get positions for the actual import url
608
624
  size_t pos_import = sass.find_first_of(SASS2SCSS_FIND_WHITESPACE, pos_left + 7);
609
- size_t pos_quote = sass.find_first_not_of(SASS2SCSS_FIND_WHITESPACE, pos_import);
610
- // leave proper urls untouched
611
- if (sass.substr(pos_quote, 4) != "url(")
612
- {
613
- // check if the url appears to be already quoted
614
- if (sass.substr(pos_quote, 1) != "\"" && sass.substr(pos_quote, 1) != "\'")
615
- {
616
- // get position of the last char on the line
617
- size_t pos_end = sass.find_last_not_of(SASS2SCSS_FIND_WHITESPACE);
618
- // assertion check for valid result
619
- if (pos_end != std::string::npos)
620
- {
621
- // add quotes around the full line after the import statement
622
- sass = sass.substr(0, pos_quote) + "\"" + sass.substr(pos_quote, pos_end - pos_quote + 1) + "\"";
625
+ size_t pos = sass.find_first_not_of(SASS2SCSS_FIND_WHITESPACE, pos_import);
626
+ size_t start = pos;
627
+ bool in_dqstr = false;
628
+ bool in_sqstr = false;
629
+ bool is_escaped = false;
630
+ do {
631
+ if (is_escaped) {
632
+ is_escaped = false;
633
+ }
634
+ else if (sass[pos] == '\\') {
635
+ is_escaped = true;
636
+ }
637
+ else if (sass[pos] == '"') {
638
+ if (!in_sqstr) in_dqstr = ! in_dqstr;
639
+ }
640
+ else if (sass[pos] == '\'') {
641
+ if (!in_dqstr) in_sqstr = ! in_sqstr;
642
+ }
643
+ else if (in_dqstr || in_sqstr) {
644
+ // skip over quoted stuff
645
+ }
646
+ else if (sass[pos] == ',' || sass[pos] == 0) {
647
+ if (sass[start] != '"' && sass[start] != '\'' && !isUrl(sass, start)) {
648
+ size_t end = findLastCharacter(sass, pos - 1) + 1;
649
+ sass = sass.replace(end, 0, "\"");
650
+ sass = sass.replace(start, 0, "\"");
651
+ pos += 2;
623
652
  }
653
+ start = findFirstCharacter(sass, pos + 1);
624
654
  }
625
655
  }
656
+ while (sass[pos++] != 0);
626
657
 
627
658
  }
628
659
  else if (
@@ -727,7 +758,7 @@ namespace Sass
727
758
  scss += flush(sass, converter);
728
759
  }
729
760
 
730
- // get postion of last meaningfull char
761
+ // get position of last meaningfull char
731
762
  size_t pos_right = sass.find_last_not_of(SASS2SCSS_FIND_WHITESPACE);
732
763
 
733
764
  // check for invalid result
@@ -1,41 +1,49 @@
1
+ // sass.hpp must go before all system headers to get the
2
+ // __EXTENSIONS__ fix on Solaris.
1
3
  #include "sass.hpp"
2
- #include <cstring>
3
- #include <stdexcept>
4
- #include <sstream>
5
- #include <string>
6
- #include <vector>
7
-
8
- #include "sass.h"
9
4
  #include "ast.hpp"
10
- #include "file.hpp"
11
- #include "json.hpp"
12
- #include "util.hpp"
13
- #include "context.hpp"
14
- #include "sass_context.hpp"
5
+
15
6
  #include "sass_functions.hpp"
16
- #include "ast_fwd_decl.hpp"
17
- #include "error_handling.hpp"
7
+ #include "json.hpp"
18
8
 
19
9
  #define LFEED "\n"
20
10
 
21
11
  // C++ helper
22
12
  namespace Sass {
23
- // see sass_copy_c_string(std::string str)
24
- static inline JsonNode* json_mkstream(const std::stringstream& stream)
13
+ // see sass_copy_c_string(sass::string str)
14
+ static inline JsonNode* json_mkstream(const sass::ostream& stream)
25
15
  {
26
16
  // hold on to string on stack!
27
- std::string str(stream.str());
17
+ sass::string str(stream.str());
28
18
  return json_mkstring(str.c_str());
29
19
  }
30
20
 
21
+ static void handle_string_error(Sass_Context* c_ctx, const sass::string& msg, int severety)
22
+ {
23
+ sass::ostream msg_stream;
24
+ JsonNode* json_err = json_mkobject();
25
+ msg_stream << "Internal Error: " << msg << std::endl;
26
+ json_append_member(json_err, "status", json_mknumber(severety));
27
+ json_append_member(json_err, "message", json_mkstring(msg.c_str()));
28
+ json_append_member(json_err, "formatted", json_mkstream(msg_stream));
29
+ try { c_ctx->error_json = json_stringify(json_err, " "); }
30
+ catch (...) {}
31
+ c_ctx->error_message = sass_copy_string(msg_stream.str());
32
+ c_ctx->error_text = sass_copy_c_string(msg.c_str());
33
+ c_ctx->error_status = severety;
34
+ c_ctx->output_string = 0;
35
+ c_ctx->source_map_string = 0;
36
+ json_delete(json_err);
37
+ }
38
+
31
39
  static int handle_error(Sass_Context* c_ctx) {
32
40
  try {
33
41
  throw;
34
42
  }
35
43
  catch (Exception::Base& e) {
36
- std::stringstream msg_stream;
37
- std::string cwd(Sass::File::get_cwd());
38
- std::string msg_prefix(e.errtype());
44
+ sass::ostream msg_stream;
45
+ sass::string cwd(Sass::File::get_cwd());
46
+ sass::string msg_prefix(e.errtype());
39
47
  bool got_newline = false;
40
48
  msg_stream << msg_prefix << ": ";
41
49
  const char* msg = e.what();
@@ -47,7 +55,7 @@ namespace Sass {
47
55
  got_newline = true;
48
56
  }
49
57
  else if (got_newline) {
50
- msg_stream << std::string(msg_prefix.size() + 2, ' ');
58
+ msg_stream << sass::string(msg_prefix.size() + 2, ' ');
51
59
  got_newline = false;
52
60
  }
53
61
  msg_stream << *msg;
@@ -57,43 +65,44 @@ namespace Sass {
57
65
 
58
66
  if (e.traces.empty()) {
59
67
  // we normally should have some traces, still here as a fallback
60
- std::string rel_path(Sass::File::abs2rel(e.pstate.path, cwd, cwd));
61
- msg_stream << std::string(msg_prefix.size() + 2, ' ');
62
- msg_stream << " on line " << e.pstate.line + 1 << " of " << rel_path << "\n";
68
+ sass::string rel_path(Sass::File::abs2rel(e.pstate.getPath(), cwd, cwd));
69
+ msg_stream << sass::string(msg_prefix.size() + 2, ' ');
70
+ msg_stream << " on line " << e.pstate.getLine() << " of " << rel_path << "\n";
63
71
  }
64
72
  else {
65
- std::string rel_path(Sass::File::abs2rel(e.pstate.path, cwd, cwd));
73
+ sass::string rel_path(Sass::File::abs2rel(e.pstate.getPath(), cwd, cwd));
66
74
  msg_stream << traces_to_string(e.traces, " ");
67
75
  }
68
76
 
69
77
  // now create the code trace (ToDo: maybe have util functions?)
70
- if (e.pstate.line != std::string::npos && e.pstate.column != std::string::npos) {
71
- size_t lines = e.pstate.line;
72
- const char* line_beg = e.pstate.src;
78
+ if (e.pstate.position.line != sass::string::npos &&
79
+ e.pstate.position.column != sass::string::npos &&
80
+ e.pstate.source != nullptr) {
81
+ Offset offset(e.pstate.position);
82
+ size_t lines = offset.line;
73
83
  // scan through src until target line
74
84
  // move line_beg pointer to line start
75
- while (line_beg && *line_beg && lines != 0) {
85
+ const char* line_beg;
86
+ for (line_beg = e.pstate.getRawData(); *line_beg != '\0'; ++line_beg) {
87
+ if (lines == 0) break;
76
88
  if (*line_beg == '\n') --lines;
77
- utf8::unchecked::next(line_beg);
78
89
  }
79
- const char* line_end = line_beg;
80
90
  // move line_end before next newline character
81
- while (line_end && *line_end && *line_end != '\n') {
82
- if (*line_end == '\n') break;
83
- if (*line_end == '\r') break;
84
- utf8::unchecked::next(line_end);
91
+ const char* line_end;
92
+ for (line_end = line_beg; *line_end != '\0'; ++line_end) {
93
+ if (*line_end == '\n' || *line_end == '\r') break;
85
94
  }
86
- if (line_end && *line_end != 0) ++ line_end;
95
+ if (*line_end != '\0') ++line_end;
87
96
  size_t line_len = line_end - line_beg;
88
97
  size_t move_in = 0; size_t shorten = 0;
89
98
  size_t left_chars = 42; size_t max_chars = 76;
90
99
  // reported excerpt should not exceed `max_chars` chars
91
- if (e.pstate.column > line_len) left_chars = e.pstate.column;
92
- if (e.pstate.column > left_chars) move_in = e.pstate.column - left_chars;
100
+ if (offset.column > line_len) left_chars = offset.column;
101
+ if (offset.column > left_chars) move_in = offset.column - left_chars;
93
102
  if (line_len > max_chars + move_in) shorten = line_len - move_in - max_chars;
94
103
  utf8::advance(line_beg, move_in, line_end);
95
104
  utf8::retreat(line_end, shorten, line_beg);
96
- std::string sanitized; std::string marker(e.pstate.column - move_in, '-');
105
+ sass::string sanitized; sass::string marker(offset.column - move_in, '-');
97
106
  utf8::replace_invalid(line_beg, line_end, std::back_inserter(sanitized));
98
107
  msg_stream << ">> " << sanitized << "\n";
99
108
  msg_stream << " " << marker << "^\n";
@@ -101,102 +110,40 @@ namespace Sass {
101
110
 
102
111
  JsonNode* json_err = json_mkobject();
103
112
  json_append_member(json_err, "status", json_mknumber(1));
104
- json_append_member(json_err, "file", json_mkstring(e.pstate.path));
105
- json_append_member(json_err, "line", json_mknumber((double)(e.pstate.line + 1)));
106
- json_append_member(json_err, "column", json_mknumber((double)(e.pstate.column + 1)));
113
+ json_append_member(json_err, "file", json_mkstring(e.pstate.getPath()));
114
+ json_append_member(json_err, "line", json_mknumber((double)(e.pstate.getLine())));
115
+ json_append_member(json_err, "column", json_mknumber((double)(e.pstate.getColumn())));
107
116
  json_append_member(json_err, "message", json_mkstring(e.what()));
108
117
  json_append_member(json_err, "formatted", json_mkstream(msg_stream));
109
118
  try { c_ctx->error_json = json_stringify(json_err, " "); }
110
- catch (...) {}
119
+ catch (...) {} // silently ignore this error?
111
120
  c_ctx->error_message = sass_copy_string(msg_stream.str());
112
121
  c_ctx->error_text = sass_copy_c_string(e.what());
113
122
  c_ctx->error_status = 1;
114
- c_ctx->error_file = sass_copy_c_string(e.pstate.path);
115
- c_ctx->error_line = e.pstate.line + 1;
116
- c_ctx->error_column = e.pstate.column + 1;
117
- c_ctx->error_src = e.pstate.src;
123
+ c_ctx->error_file = sass_copy_c_string(e.pstate.getPath());
124
+ c_ctx->error_line = e.pstate.getLine();
125
+ c_ctx->error_column = e.pstate.getColumn();
126
+ c_ctx->error_src = sass_copy_c_string(e.pstate.getRawData());
118
127
  c_ctx->output_string = 0;
119
128
  c_ctx->source_map_string = 0;
120
129
  json_delete(json_err);
121
130
  }
122
131
  catch (std::bad_alloc& ba) {
123
- std::stringstream msg_stream;
124
- JsonNode* json_err = json_mkobject();
125
- msg_stream << "Unable to allocate memory: " << ba.what() << std::endl;
126
- json_append_member(json_err, "status", json_mknumber(2));
127
- json_append_member(json_err, "message", json_mkstring(ba.what()));
128
- json_append_member(json_err, "formatted", json_mkstream(msg_stream));
129
- try { c_ctx->error_json = json_stringify(json_err, " "); }
130
- catch (...) {}
131
- c_ctx->error_message = sass_copy_string(msg_stream.str());
132
- c_ctx->error_text = sass_copy_c_string(ba.what());
133
- c_ctx->error_status = 2;
134
- c_ctx->output_string = 0;
135
- c_ctx->source_map_string = 0;
136
- json_delete(json_err);
132
+ sass::ostream msg_stream;
133
+ msg_stream << "Unable to allocate memory: " << ba.what();
134
+ handle_string_error(c_ctx, msg_stream.str(), 2);
137
135
  }
138
136
  catch (std::exception& e) {
139
- std::stringstream msg_stream;
140
- JsonNode* json_err = json_mkobject();
141
- msg_stream << "Internal Error: " << e.what() << std::endl;
142
- json_append_member(json_err, "status", json_mknumber(3));
143
- json_append_member(json_err, "message", json_mkstring(e.what()));
144
- json_append_member(json_err, "formatted", json_mkstream(msg_stream));
145
- try { c_ctx->error_json = json_stringify(json_err, " "); }
146
- catch (...) {}
147
- c_ctx->error_message = sass_copy_string(msg_stream.str());
148
- c_ctx->error_text = sass_copy_c_string(e.what());
149
- c_ctx->error_status = 3;
150
- c_ctx->output_string = 0;
151
- c_ctx->source_map_string = 0;
152
- json_delete(json_err);
137
+ handle_string_error(c_ctx, e.what(), 3);
153
138
  }
154
- catch (std::string& e) {
155
- std::stringstream msg_stream;
156
- JsonNode* json_err = json_mkobject();
157
- msg_stream << "Internal Error: " << e << std::endl;
158
- json_append_member(json_err, "status", json_mknumber(4));
159
- json_append_member(json_err, "message", json_mkstring(e.c_str()));
160
- json_append_member(json_err, "formatted", json_mkstream(msg_stream));
161
- try { c_ctx->error_json = json_stringify(json_err, " "); }
162
- catch (...) {}
163
- c_ctx->error_message = sass_copy_string(msg_stream.str());
164
- c_ctx->error_text = sass_copy_c_string(e.c_str());
165
- c_ctx->error_status = 4;
166
- c_ctx->output_string = 0;
167
- c_ctx->source_map_string = 0;
168
- json_delete(json_err);
139
+ catch (sass::string& e) {
140
+ handle_string_error(c_ctx, e, 4);
169
141
  }
170
142
  catch (const char* e) {
171
- std::stringstream msg_stream;
172
- JsonNode* json_err = json_mkobject();
173
- msg_stream << "Internal Error: " << e << std::endl;
174
- json_append_member(json_err, "status", json_mknumber(4));
175
- json_append_member(json_err, "message", json_mkstring(e));
176
- json_append_member(json_err, "formatted", json_mkstream(msg_stream));
177
- try { c_ctx->error_json = json_stringify(json_err, " "); }
178
- catch (...) {}
179
- c_ctx->error_message = sass_copy_string(msg_stream.str());
180
- c_ctx->error_text = sass_copy_c_string(e);
181
- c_ctx->error_status = 4;
182
- c_ctx->output_string = 0;
183
- c_ctx->source_map_string = 0;
184
- json_delete(json_err);
143
+ handle_string_error(c_ctx, e, 4);
185
144
  }
186
145
  catch (...) {
187
- std::stringstream msg_stream;
188
- JsonNode* json_err = json_mkobject();
189
- msg_stream << "Unknown error occurred" << std::endl;
190
- json_append_member(json_err, "status", json_mknumber(5));
191
- json_append_member(json_err, "message", json_mkstring("unknown"));
192
- try { c_ctx->error_json = json_stringify(json_err, " "); }
193
- catch (...) {}
194
- c_ctx->error_message = sass_copy_string(msg_stream.str());
195
- c_ctx->error_text = sass_copy_c_string("unknown");
196
- c_ctx->error_status = 5;
197
- c_ctx->output_string = 0;
198
- c_ctx->source_map_string = 0;
199
- json_delete(json_err);
146
+ handle_string_error(c_ctx, "unknown", 5);
200
147
  }
201
148
  return c_ctx->error_status;
202
149
  }
@@ -212,7 +159,7 @@ namespace Sass {
212
159
  {
213
160
 
214
161
  // assert valid pointer
215
- if (compiler == 0) return 0;
162
+ if (compiler == 0) return {};
216
163
  // The cpp context must be set by now
217
164
  Context* cpp_ctx = compiler->cpp_ctx;
218
165
  Sass_Context* c_ctx = compiler->c_ctx;
@@ -223,8 +170,8 @@ namespace Sass {
223
170
  try {
224
171
 
225
172
  // get input/output path from options
226
- std::string input_path = safe_str(c_ctx->input_path);
227
- std::string output_path = safe_str(c_ctx->output_path);
173
+ sass::string input_path = safe_str(c_ctx->input_path);
174
+ sass::string output_path = safe_str(c_ctx->output_path);
228
175
 
229
176
  // maybe skip some entries of included files
230
177
  // we do not include stdin for data contexts
@@ -233,7 +180,7 @@ namespace Sass {
233
180
  // dispatch parse call
234
181
  Block_Obj root(cpp_ctx->parse());
235
182
  // abort on errors
236
- if (!root) return 0;
183
+ if (!root) return {};
237
184
 
238
185
  // skip all prefixed files? (ToDo: check srcmap)
239
186
  // IMO source-maps should point to headers already
@@ -253,7 +200,7 @@ namespace Sass {
253
200
  catch (...) { handle_errors(c_ctx); }
254
201
 
255
202
  // error
256
- return 0;
203
+ return {};
257
204
 
258
205
  }
259
206
 
@@ -331,10 +278,10 @@ extern "C" {
331
278
  c_ctx->error_message = 0;
332
279
  c_ctx->error_status = 0;
333
280
  // reset error position
334
- c_ctx->error_src = 0;
335
281
  c_ctx->error_file = 0;
336
- c_ctx->error_line = std::string::npos;
337
- c_ctx->error_column = std::string::npos;
282
+ c_ctx->error_src = 0;
283
+ c_ctx->error_line = sass::string::npos;
284
+ c_ctx->error_column = sass::string::npos;
338
285
 
339
286
  // allocate a new compiler instance
340
287
  void* ctxmem = calloc(1, sizeof(struct Sass_Compiler));
@@ -381,7 +328,7 @@ extern "C" {
381
328
 
382
329
  inline void init_options (struct Sass_Options* options)
383
330
  {
384
- options->precision = 5;
331
+ options->precision = 10;
385
332
  options->indent = " ";
386
333
  options->linefeed = LFEED;
387
334
  }
@@ -396,7 +343,9 @@ extern "C" {
396
343
 
397
344
  Sass_File_Context* ADDCALL sass_make_file_context(const char* input_path)
398
345
  {
399
- SharedObj::setTaint(true); // needed for static colors
346
+ #ifdef DEBUG_SHARED_PTR
347
+ SharedObj::setTaint(true);
348
+ #endif
400
349
  struct Sass_File_Context* ctx = (struct Sass_File_Context*) calloc(1, sizeof(struct Sass_File_Context));
401
350
  if (ctx == 0) { std::cerr << "Error allocating memory for file context" << std::endl; return 0; }
402
351
  ctx->type = SASS_CONTEXT_FILE;
@@ -413,6 +362,9 @@ extern "C" {
413
362
 
414
363
  Sass_Data_Context* ADDCALL sass_make_data_context(char* source_string)
415
364
  {
365
+ #ifdef DEBUG_SHARED_PTR
366
+ SharedObj::setTaint(true);
367
+ #endif
416
368
  struct Sass_Data_Context* ctx = (struct Sass_Data_Context*) calloc(1, sizeof(struct Sass_Data_Context));
417
369
  if (ctx == 0) { std::cerr << "Error allocating memory for data context" << std::endl; return 0; }
418
370
  ctx->type = SASS_CONTEXT_DATA;
@@ -448,7 +400,7 @@ extern "C" {
448
400
  return data_ctx->error_status;
449
401
  try {
450
402
  if (data_ctx->source_string == 0) { throw(std::runtime_error("Data context has no source string")); }
451
- // empty source string is a valid case, even if not really usefull (different than with file context)
403
+ // empty source string is a valid case, even if not really useful (different than with file context)
452
404
  // if (*data_ctx->source_string == 0) { throw(std::runtime_error("Data context has empty source string")); }
453
405
  }
454
406
  catch (...) { return handle_errors(data_ctx) | 1; }
@@ -530,7 +482,7 @@ extern "C" {
530
482
  static void sass_clear_options (struct Sass_Options* options)
531
483
  {
532
484
  if (options == 0) return;
533
- // Deallocate custom functions, headers and importes
485
+ // Deallocate custom functions, headers and imports
534
486
  sass_delete_function_list(options->c_functions);
535
487
  sass_delete_importer_list(options->c_importers);
536
488
  sass_delete_importer_list(options->c_headers);
@@ -591,6 +543,7 @@ extern "C" {
591
543
  if (ctx->error_text) free(ctx->error_text);
592
544
  if (ctx->error_json) free(ctx->error_json);
593
545
  if (ctx->error_file) free(ctx->error_file);
546
+ if (ctx->error_src) free(ctx->error_src);
594
547
  free_string_array(ctx->included_files);
595
548
  // play safe and reset properties
596
549
  ctx->output_string = 0;
@@ -599,6 +552,7 @@ extern "C" {
599
552
  ctx->error_text = 0;
600
553
  ctx->error_json = 0;
601
554
  ctx->error_file = 0;
555
+ ctx->error_src = 0;
602
556
  ctx->included_files = 0;
603
557
  // debug leaked memory
604
558
  #ifdef DEBUG_SHARED_PTR
@@ -617,7 +571,7 @@ extern "C" {
617
571
  if (cpp_ctx) delete(cpp_ctx);
618
572
  compiler->cpp_ctx = NULL;
619
573
  compiler->c_ctx = NULL;
620
- compiler->root = NULL;
574
+ compiler->root = {};
621
575
  free(compiler);
622
576
  }
623
577
 
@@ -653,7 +607,7 @@ extern "C" {
653
607
  void ADDCALL sass_file_context_set_options (struct Sass_File_Context* ctx, struct Sass_Options* opt) { copy_options(ctx, opt); }
654
608
  void ADDCALL sass_data_context_set_options (struct Sass_Data_Context* ctx, struct Sass_Options* opt) { copy_options(ctx, opt); }
655
609
 
656
- // Getters for Sass_Compiler options (get conected sass context)
610
+ // Getters for Sass_Compiler options (get connected sass context)
657
611
  enum Sass_Compiler_State ADDCALL sass_compiler_get_state(struct Sass_Compiler* compiler) { return compiler->state; }
658
612
  struct Sass_Context* ADDCALL sass_compiler_get_context(struct Sass_Compiler* compiler) { return compiler->c_ctx; }
659
613
  struct Sass_Options* ADDCALL sass_compiler_get_options(struct Sass_Compiler* compiler) { return compiler->c_ctx; }
@@ -697,9 +651,9 @@ extern "C" {
697
651
  IMPLEMENT_SASS_CONTEXT_GETTER(const char*, error_message);
698
652
  IMPLEMENT_SASS_CONTEXT_GETTER(const char*, error_text);
699
653
  IMPLEMENT_SASS_CONTEXT_GETTER(const char*, error_file);
654
+ IMPLEMENT_SASS_CONTEXT_GETTER(const char*, error_src);
700
655
  IMPLEMENT_SASS_CONTEXT_GETTER(size_t, error_line);
701
656
  IMPLEMENT_SASS_CONTEXT_GETTER(size_t, error_column);
702
- IMPLEMENT_SASS_CONTEXT_GETTER(const char*, error_src);
703
657
  IMPLEMENT_SASS_CONTEXT_GETTER(const char*, output_string);
704
658
  IMPLEMENT_SASS_CONTEXT_GETTER(const char*, source_map_string);
705
659
  IMPLEMENT_SASS_CONTEXT_GETTER(char**, included_files);
@@ -709,6 +663,7 @@ extern "C" {
709
663
  IMPLEMENT_SASS_CONTEXT_TAKER(char*, error_message);
710
664
  IMPLEMENT_SASS_CONTEXT_TAKER(char*, error_text);
711
665
  IMPLEMENT_SASS_CONTEXT_TAKER(char*, error_file);
666
+ IMPLEMENT_SASS_CONTEXT_TAKER(char*, error_src);
712
667
  IMPLEMENT_SASS_CONTEXT_TAKER(char*, output_string);
713
668
  IMPLEMENT_SASS_CONTEXT_TAKER(char*, source_map_string);
714
669
  IMPLEMENT_SASS_CONTEXT_TAKER(char**, included_files);
@@ -748,6 +703,23 @@ extern "C" {
748
703
  return cur->string;
749
704
  }
750
705
 
706
+ // Push function for plugin paths (no manipulation support for now)
707
+ size_t ADDCALL sass_option_get_plugin_path_size(struct Sass_Options* options)
708
+ {
709
+ size_t len = 0;
710
+ struct string_list* cur = options->plugin_paths;
711
+ while (cur) { len++; cur = cur->next; }
712
+ return len;
713
+ }
714
+
715
+ // Push function for plugin paths (no manipulation support for now)
716
+ const char* ADDCALL sass_option_get_plugin_path(struct Sass_Options* options, size_t i)
717
+ {
718
+ struct string_list* cur = options->plugin_paths;
719
+ while (i) { i--; cur = cur->next; }
720
+ return cur->string;
721
+ }
722
+
751
723
  // Push function for plugin paths (no manipulation support for now)
752
724
  void ADDCALL sass_option_push_plugin_path(struct Sass_Options* options, const char* path)
753
725
  {