sassc 0.0.10 → 0.0.11

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 (94) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/ext/libsass/.gitignore +6 -0
  4. data/ext/libsass/.travis.yml +5 -1
  5. data/ext/libsass/Makefile +12 -3
  6. data/ext/libsass/Makefile.am +16 -28
  7. data/ext/libsass/Readme.md +1 -0
  8. data/ext/libsass/appveyor.yml +1 -2
  9. data/ext/libsass/ast.cpp +9 -0
  10. data/ext/libsass/ast.hpp +152 -55
  11. data/ext/libsass/ast_factory.hpp +2 -0
  12. data/ext/libsass/ast_fwd_decl.hpp +1 -0
  13. data/ext/libsass/backtrace.hpp +2 -2
  14. data/ext/libsass/bind.cpp +15 -13
  15. data/ext/libsass/configure.ac +17 -5
  16. data/ext/libsass/constants.cpp +22 -2
  17. data/ext/libsass/constants.hpp +21 -2
  18. data/ext/libsass/context.cpp +79 -57
  19. data/ext/libsass/context.hpp +23 -9
  20. data/ext/libsass/contextualize.cpp +2 -28
  21. data/ext/libsass/contextualize.hpp +6 -10
  22. data/ext/libsass/contextualize_eval.cpp +93 -0
  23. data/ext/libsass/contextualize_eval.hpp +44 -0
  24. data/ext/libsass/contrib/plugin.cpp +57 -0
  25. data/ext/libsass/cssize.cpp +3 -1
  26. data/ext/libsass/debugger.hpp +242 -83
  27. data/ext/libsass/emitter.cpp +1 -1
  28. data/ext/libsass/emitter.hpp +1 -1
  29. data/ext/libsass/environment.hpp +109 -25
  30. data/ext/libsass/error_handling.cpp +3 -3
  31. data/ext/libsass/error_handling.hpp +0 -1
  32. data/ext/libsass/eval.cpp +145 -61
  33. data/ext/libsass/eval.hpp +9 -1
  34. data/ext/libsass/expand.cpp +134 -60
  35. data/ext/libsass/expand.hpp +5 -2
  36. data/ext/libsass/extend.cpp +7 -5
  37. data/ext/libsass/file.cpp +176 -123
  38. data/ext/libsass/file.hpp +44 -7
  39. data/ext/libsass/functions.cpp +36 -17
  40. data/ext/libsass/functions.hpp +2 -2
  41. data/ext/libsass/inspect.cpp +23 -14
  42. data/ext/libsass/inspect.hpp +1 -0
  43. data/ext/libsass/json.cpp +132 -135
  44. data/ext/libsass/lexer.cpp +133 -0
  45. data/ext/libsass/lexer.hpp +239 -0
  46. data/ext/libsass/listize.cpp +83 -0
  47. data/ext/libsass/listize.hpp +41 -0
  48. data/ext/libsass/operation.hpp +2 -0
  49. data/ext/libsass/output.cpp +5 -6
  50. data/ext/libsass/parser.cpp +426 -388
  51. data/ext/libsass/parser.hpp +97 -109
  52. data/ext/libsass/plugins.cpp +15 -2
  53. data/ext/libsass/plugins.hpp +6 -4
  54. data/ext/libsass/position.cpp +52 -17
  55. data/ext/libsass/position.hpp +19 -17
  56. data/ext/libsass/prelexer.cpp +202 -235
  57. data/ext/libsass/prelexer.hpp +73 -333
  58. data/ext/libsass/sass.cpp +21 -11
  59. data/ext/libsass/sass.h +6 -6
  60. data/ext/libsass/sass_context.cpp +167 -81
  61. data/ext/libsass/sass_context.h +26 -6
  62. data/ext/libsass/sass_functions.cpp +49 -40
  63. data/ext/libsass/sass_functions.h +55 -43
  64. data/ext/libsass/sass_interface.cpp +9 -8
  65. data/ext/libsass/sass_interface.h +3 -3
  66. data/ext/libsass/sass_version.h +8 -0
  67. data/ext/libsass/sass_version.h.in +8 -0
  68. data/ext/libsass/script/ci-build-libsass +3 -3
  69. data/ext/libsass/script/ci-report-coverage +2 -1
  70. data/ext/libsass/source_map.cpp +2 -2
  71. data/ext/libsass/util.cpp +60 -11
  72. data/ext/libsass/util.hpp +6 -1
  73. data/ext/libsass/win/libsass.filters +12 -0
  74. data/ext/libsass/win/libsass.vcxproj +10 -0
  75. data/lib/sassc.rb +3 -1
  76. data/lib/sassc/cache_stores/base.rb +2 -0
  77. data/lib/sassc/dependency.rb +3 -1
  78. data/lib/sassc/engine.rb +31 -16
  79. data/lib/sassc/error.rb +3 -2
  80. data/lib/sassc/functions_handler.rb +54 -0
  81. data/lib/sassc/import_handler.rb +41 -0
  82. data/lib/sassc/importer.rb +4 -31
  83. data/lib/sassc/native.rb +1 -1
  84. data/lib/sassc/native/native_context_api.rb +3 -2
  85. data/lib/sassc/script.rb +0 -51
  86. data/lib/sassc/version.rb +1 -1
  87. data/sassc.gemspec +1 -0
  88. data/test/custom_importer_test.rb +72 -69
  89. data/test/engine_test.rb +53 -54
  90. data/test/functions_test.rb +40 -39
  91. data/test/native_test.rb +145 -149
  92. data/test/output_style_test.rb +98 -0
  93. data/test/test_helper.rb +21 -7
  94. metadata +28 -2
@@ -69,6 +69,7 @@ namespace Sass {
69
69
  String_Constant* new_String_Constant(string p, size_t l, const char* beg, const char* end);
70
70
  Feature_Query_Condition* new_Feature_Query_Condition(string p, size_t l, String* f, Expression* v);
71
71
  Media_Expression* new_Media_Expression(string p, size_t l, String* f, Expression* v);
72
+ Parent_Selector* new_Parent_Selector(string p, size_t l, Selector* s);
72
73
  // parameters and arguments
73
74
  Parameter* new_Parameter(string p, size_t l, string n, Expression* def = 0, bool rest = false);
74
75
  Parameters* new_Parameters(string p, size_t l);
@@ -76,6 +77,7 @@ namespace Sass {
76
77
  Arguments* new_Arguments(string p, size_t l);
77
78
  // selectors
78
79
  Selector_Schema* new_Selector_Schema(string p, size_t l, String* c);
80
+ Attribute_Selector* new_Attribute_Selector(string p, size_t l, string n, string m, String* v);
79
81
  Simple_Selector* new_Simple_Selector(string p, size_t l, string c);
80
82
  Reference_Selector* new_Reference_Selector(string p, size_t l);
81
83
  Placeholder_Selector* new_Placeholder_Selector(string p, size_t l, string n);
@@ -60,6 +60,7 @@ namespace Sass {
60
60
  class Feature_Query_Condition;
61
61
  class At_Root_Expression;
62
62
  class Null;
63
+ class Parent_Selector;
63
64
  // parameters and arguments
64
65
  class Parameter;
65
66
  class Parameters;
@@ -41,7 +41,7 @@ namespace Sass {
41
41
  << "\t"
42
42
  << (++i == 0 ? "on" : "from")
43
43
  << " line "
44
- << this_point->pstate.line
44
+ << this_point->pstate.line + 1
45
45
  << " of "
46
46
  << rel_path;
47
47
  } else {
@@ -49,7 +49,7 @@ namespace Sass {
49
49
  << "\t"
50
50
  << rel_path
51
51
  << ":"
52
- << this_point->pstate.line
52
+ << this_point->pstate.line + 1
53
53
  << this_point->parent->caller;
54
54
  }
55
55
 
@@ -20,7 +20,7 @@ namespace Sass {
20
20
  Parameter* p = (*ps)[i];
21
21
  param_map[p->name()] = p;
22
22
  // if (p->default_value()) {
23
- // env->current_frame()[p->name()] = p->default_value()->perform(eval->with(env));
23
+ // env->local_frame()[p->name()] = p->default_value()->perform(eval->with(env));
24
24
  // }
25
25
  }
26
26
 
@@ -41,12 +41,12 @@ namespace Sass {
41
41
  if (p->is_rest_parameter()) {
42
42
  if (a->is_rest_argument()) {
43
43
  // rest param and rest arg -- just add one to the other
44
- if (env->current_frame_has(p->name())) {
45
- *static_cast<List*>(env->current_frame()[p->name()])
44
+ if (env->has_local(p->name())) {
45
+ *static_cast<List*>(env->local_frame()[p->name()])
46
46
  += static_cast<List*>(a->value());
47
47
  }
48
48
  else {
49
- env->current_frame()[p->name()] = a->value();
49
+ env->local_frame()[p->name()] = a->value();
50
50
  }
51
51
  } else {
52
52
 
@@ -55,7 +55,7 @@ namespace Sass {
55
55
  0,
56
56
  List::COMMA,
57
57
  true);
58
- env->current_frame()[p->name()] = arglist;
58
+ env->local_frame()[p->name()] = arglist;
59
59
  while (ia < LA) {
60
60
  a = (*as)[ia];
61
61
  (*arglist) << new (ctx.mem) Argument(a->pstate(),
@@ -99,7 +99,7 @@ namespace Sass {
99
99
  msg << callee << " has no parameter named " << name;
100
100
  error(msg.str(), a->pstate());
101
101
  }
102
- env->current_frame()[name] = argmap->at(key);
102
+ env->local_frame()[name] = argmap->at(key);
103
103
  }
104
104
  ++ia;
105
105
  continue;
@@ -108,14 +108,14 @@ namespace Sass {
108
108
  }
109
109
 
110
110
  if (a->name().empty()) {
111
- if (env->current_frame_has(p->name())) {
111
+ if (env->has_local(p->name())) {
112
112
  stringstream msg;
113
113
  msg << "parameter " << p->name()
114
114
  << " provided more than once in call to " << callee;
115
115
  error(msg.str(), a->pstate());
116
116
  }
117
117
  // ordinal arg -- bind it to the next param
118
- env->current_frame()[p->name()] = a->value();
118
+ env->local_frame()[p->name()] = a->value();
119
119
  ++ip;
120
120
  }
121
121
  else {
@@ -131,13 +131,13 @@ namespace Sass {
131
131
  << "cannot be used as named argument";
132
132
  error(msg.str(), a->pstate());
133
133
  }
134
- if (env->current_frame_has(a->name())) {
134
+ if (env->has_local(a->name())) {
135
135
  stringstream msg;
136
136
  msg << "parameter " << p->name()
137
137
  << "provided more than once in call to " << callee;
138
138
  error(msg.str(), a->pstate());
139
139
  }
140
- env->current_frame()[a->name()] = a->value();
140
+ env->local_frame()[a->name()] = a->value();
141
141
  }
142
142
  }
143
143
 
@@ -150,9 +150,9 @@ namespace Sass {
150
150
  // cerr << "env for default params:" << endl;
151
151
  // env->print();
152
152
  // cerr << "********" << endl;
153
- if (!env->current_frame_has(leftover->name())) {
153
+ if (!env->has_local(leftover->name())) {
154
154
  if (leftover->is_rest_parameter()) {
155
- env->current_frame()[leftover->name()] = new (ctx.mem) List(leftover->pstate(),
155
+ env->local_frame()[leftover->name()] = new (ctx.mem) List(leftover->pstate(),
156
156
  0,
157
157
  List::COMMA,
158
158
  true);
@@ -161,11 +161,13 @@ namespace Sass {
161
161
  // make sure to eval the default value in the env that we've been populating
162
162
  Env* old_env = eval->env;
163
163
  Backtrace* old_bt = eval->backtrace;
164
+ Contextualize* old_context = eval->contextualize;
164
165
  Expression* dv = leftover->default_value()->perform(eval->with(env, eval->backtrace));
165
166
  eval->env = old_env;
166
167
  eval->backtrace = old_bt;
168
+ eval->contextualize = old_context;
167
169
  // dv->perform(&to_string);
168
- env->current_frame()[leftover->name()] = dv;
170
+ env->local_frame()[leftover->name()] = dv;
169
171
  }
170
172
  else {
171
173
  // param is unbound and has no default value -- error
@@ -7,15 +7,17 @@ AC_INIT([libsass], m4_esyscmd_s([./version.sh]), [support@moovweb.com])
7
7
  AC_CONFIG_SRCDIR([ast.hpp])
8
8
  AC_CONFIG_MACRO_DIR([m4])
9
9
  AC_CONFIG_HEADERS([config.h])
10
+ AC_CONFIG_FILES([sass_version.h])
10
11
  AC_CONFIG_AUX_DIR([script])
11
- AM_INIT_AUTOMAKE([foreign parallel-tests])
12
+ # These are flags passed to automake
13
+ # Though they look like gcc flags!
14
+ AM_INIT_AUTOMAKE([foreign parallel-tests -Wall])
12
15
  m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([no])])
13
- LT_INIT
14
16
 
15
17
  # Checks for programs.
16
18
  AC_PROG_CXX
17
-
18
19
  AC_LANG([C++])
20
+ LT_INIT([dlopen])
19
21
 
20
22
  # Checks for header files.
21
23
  AC_CHECK_HEADERS([unistd.h])
@@ -31,6 +33,17 @@ AC_CHECK_FUNCS([floor getcwd strtol])
31
33
  AC_ARG_ENABLE(tests, AS_HELP_STRING([--enable-tests], [enable testing the build]),
32
34
  [enable_tests="$enableval"], [enable_tests=no])
33
35
 
36
+ AS_CASE([$host], [*-*-mingw32], [is_mingw32=yes], [is_mingw32=no])
37
+ AM_CONDITIONAL(COMPILER_IS_MINGW32, test "x$is_mingw32" = "xyes")
38
+
39
+ dnl The dlopen() function is in the C library for *BSD and in
40
+ dnl libdl on GLIBC-based systems
41
+ if test "x$is_mingw32" != "xyes"; then
42
+ AC_SEARCH_LIBS([dlopen], [dl dld], [], [
43
+ AC_MSG_ERROR([unable to find the dlopen() function])
44
+ ])
45
+ fi
46
+
34
47
  if test "x$enable_tests" = "xyes"; then
35
48
  AC_PROG_CC
36
49
  AC_PROG_AWK
@@ -107,8 +120,7 @@ fi
107
120
 
108
121
  AM_CONDITIONAL(ENABLE_COVERAGE, test "x$enable_cov" = "xyes")
109
122
 
110
- AS_CASE([$host], [*-*-mingw32], [is_mingw32=yes], [is_mingw32=no])
111
- AM_CONDITIONAL(COMPILER_IS_MINGW32, test "x$is_mingw32" = "xyes")
123
+ AC_SUBST(PACKAGE_VERSION)
112
124
 
113
125
  AC_MSG_NOTICE([Building libsass ($VERSION)])
114
126
 
@@ -2,7 +2,17 @@
2
2
 
3
3
  namespace Sass {
4
4
  namespace Constants {
5
- extern const int SPECIFICITY_BASE = 1000;
5
+
6
+ // https://github.com/sass/libsass/issues/592
7
+ // https://developer.mozilla.org/en-US/docs/Web/CSS/Specificity
8
+ // https://github.com/sass/sass/issues/1495#issuecomment-61189114
9
+ extern const unsigned long Specificity_Star = 0;
10
+ extern const unsigned long Specificity_Universal = 1 << 0;
11
+ extern const unsigned long Specificity_Type = 1 << 8;
12
+ extern const unsigned long Specificity_Class = 1 << 16;
13
+ extern const unsigned long Specificity_Attr = 1 << 16;
14
+ extern const unsigned long Specificity_Pseudo = 1 << 16;
15
+ extern const unsigned long Specificity_ID = 1 << 24;
6
16
 
7
17
  // sass keywords
8
18
  extern const char at_root_kwd[] = "@at-root";
@@ -78,6 +88,9 @@ namespace Sass {
78
88
  extern const char webkit_calc_kwd[] = "-webkit-calc(";
79
89
  extern const char ms_calc_kwd[] = "-ms-calc(";
80
90
 
91
+ // css selector keywords
92
+ extern const char sel_deep_kwd[] = "/deep/";
93
+
81
94
  // css attribute-matching operators
82
95
  extern const char tilde_equal[] = "~=";
83
96
  extern const char pipe_equal[] = "|=";
@@ -110,7 +123,7 @@ namespace Sass {
110
123
  extern const char sign_chars[] = "-+";
111
124
  extern const char hyphen[] = "-";
112
125
  extern const char ellipsis[] = "...";
113
- extern const char url_space_chars[] = " \t\r\n\f";
126
+ // extern const char url_space_chars[] = " \t\r\n\f";
114
127
  extern const char escape_chars[] = " -~"; // need to include unicode spaces too
115
128
  // type names
116
129
  extern const char numeric_name[] = "numeric value";
@@ -124,6 +137,13 @@ namespace Sass {
124
137
  extern const char map_name[] = "map";
125
138
  extern const char arglist_name[] = "arglist";
126
139
 
140
+ // constants for uri parsing (RFC 3986 Appendix A.)
141
+ extern const char uri_chars[] = ":;/?!$%&#@[]{}'\"*+-.,_=";
142
+
143
+ // some specific constant character classes
144
+ // they must be static to be useable by lexer
145
+ extern const char static_ops[] = "*/%";
146
+
127
147
  // byte order marks
128
148
  // (taken from http://en.wikipedia.org/wiki/Byte_order_mark)
129
149
  extern const unsigned char utf_8_bom[] = { 0xEF, 0xBB, 0xBF };
@@ -3,7 +3,16 @@
3
3
 
4
4
  namespace Sass {
5
5
  namespace Constants {
6
- extern const int SPECIFICITY_BASE;
6
+
7
+ // https://developer.mozilla.org/en-US/docs/Web/CSS/Specificity
8
+ // The following list of selectors is by increasing specificity:
9
+ extern const unsigned long Specificity_Star;
10
+ extern const unsigned long Specificity_Universal;
11
+ extern const unsigned long Specificity_Type;
12
+ extern const unsigned long Specificity_Class;
13
+ extern const unsigned long Specificity_Attr;
14
+ extern const unsigned long Specificity_Pseudo;
15
+ extern const unsigned long Specificity_ID;
7
16
 
8
17
  // sass keywords
9
18
  extern const char at_root_kwd[];
@@ -80,6 +89,9 @@ namespace Sass {
80
89
  extern const char webkit_calc_kwd[];
81
90
  extern const char ms_calc_kwd[];
82
91
 
92
+ // css selector keywords
93
+ extern const char sel_deep_kwd[];
94
+
83
95
  // css attribute-matching operators
84
96
  extern const char tilde_equal[];
85
97
  extern const char pipe_equal[];
@@ -112,7 +124,7 @@ namespace Sass {
112
124
  extern const char sign_chars[];
113
125
  extern const char hyphen[];
114
126
  extern const char ellipsis[];
115
- extern const char url_space_chars[];
127
+ // extern const char url_space_chars[];
116
128
  extern const char escape_chars[];
117
129
 
118
130
  // type names
@@ -127,6 +139,13 @@ namespace Sass {
127
139
  extern const char map_name[];
128
140
  extern const char arglist_name[];
129
141
 
142
+ // constants for uri parsing (RFC 3986 Appendix A.)
143
+ extern const char uri_chars[];
144
+
145
+ // some specific constant character classes
146
+ // they must be static to be useable by lexer
147
+ extern const char static_ops[];
148
+
130
149
  // byte order marks
131
150
  // (taken from http://en.wikipedia.org/wiki/Byte_order_mark)
132
151
  extern const unsigned char utf_8_bom[];
@@ -17,7 +17,9 @@
17
17
  #include "expand.hpp"
18
18
  #include "eval.hpp"
19
19
  #include "contextualize.hpp"
20
+ #include "contextualize_eval.hpp"
20
21
  #include "cssize.hpp"
22
+ #include "listize.hpp"
21
23
  #include "extend.hpp"
22
24
  #include "remove_placeholders.hpp"
23
25
  #include "color_names.hpp"
@@ -48,10 +50,15 @@ namespace Sass {
48
50
  this->source = source;
49
51
  }
50
52
 
53
+ inline bool sort_importers (const Sass_Importer_Entry& i, const Sass_Importer_Entry& j)
54
+ { return sass_importer_get_priority(i) > sass_importer_get_priority(j); }
51
55
 
52
56
  Context::Context(Context::Data initializers)
53
57
  : // Output(this),
58
+ head_imports(0),
54
59
  mem(Memory_Manager<AST_Node>()),
60
+ c_options (initializers.c_options()),
61
+ c_compiler (initializers.c_compiler()),
55
62
  source_c_str (initializers.source_c_str()),
56
63
  sources (vector<const char*>()),
57
64
  plugin_paths (initializers.plugin_paths()),
@@ -59,7 +66,9 @@ namespace Sass {
59
66
  queue (vector<Sass_Queued>()),
60
67
  style_sheets (map<string, Block*>()),
61
68
  emitter (this),
62
- c_functions (vector<Sass_C_Function_Callback>()),
69
+ c_headers (vector<Sass_Importer_Entry>()),
70
+ c_importers (vector<Sass_Importer_Entry>()),
71
+ c_functions (vector<Sass_Function_Entry>()),
63
72
  indent (initializers.indent()),
64
73
  linefeed (initializers.linefeed()),
65
74
  input_path (make_canonical_path(initializers.input_path())),
@@ -72,7 +81,6 @@ namespace Sass {
72
81
  source_map_contents (initializers.source_map_contents()),
73
82
  omit_source_map_url (initializers.omit_source_map_url()),
74
83
  is_indented_syntax_src (initializers.is_indented_syntax_src()),
75
- importer (initializers.importer()),
76
84
  names_to_colors (map<string, Color*>()),
77
85
  colors_to_names (map<int, string>()),
78
86
  precision (initializers.precision()),
@@ -89,9 +97,9 @@ namespace Sass {
89
97
 
90
98
  include_paths.push_back(cwd);
91
99
  collect_include_paths(initializers.include_paths_c_str());
92
- collect_include_paths(initializers.include_paths_array());
100
+ // collect_include_paths(initializers.include_paths_array());
93
101
  collect_plugin_paths(initializers.plugin_paths_c_str());
94
- collect_plugin_paths(initializers.plugin_paths_array());
102
+ // collect_plugin_paths(initializers.plugin_paths_array());
95
103
 
96
104
  setup_color_map();
97
105
 
@@ -102,7 +110,15 @@ namespace Sass {
102
110
  for(auto fn : plugins.get_functions()) {
103
111
  c_functions.push_back(fn);
104
112
  }
113
+ for(auto fn : plugins.get_headers()) {
114
+ c_headers.push_back(fn);
115
+ }
116
+ for(auto fn : plugins.get_importers()) {
117
+ c_importers.push_back(fn);
118
+ }
105
119
 
120
+ sort (c_headers.begin(), c_headers.end(), sort_importers);
121
+ sort (c_importers.begin(), c_importers.end(), sort_importers);
106
122
  string entry_point = initializers.entry_point();
107
123
  if (!entry_point.empty()) {
108
124
  string result(add_file(entry_point));
@@ -111,15 +127,34 @@ namespace Sass {
111
127
  }
112
128
  }
113
129
 
114
- emitter.set_filename(output_path);
130
+ emitter.set_filename(resolve_relative_path(output_path, source_map_file, cwd));
131
+
132
+ }
115
133
 
134
+ void Context::add_c_function(Sass_Function_Entry function)
135
+ {
136
+ c_functions.push_back(function);
137
+ }
138
+ void Context::add_c_header(Sass_Importer_Entry header)
139
+ {
140
+ c_headers.push_back(header);
141
+ // need to sort the array afterwards (no big deal)
142
+ sort (c_headers.begin(), c_headers.end(), sort_importers);
143
+ }
144
+ void Context::add_c_importer(Sass_Importer_Entry importer)
145
+ {
146
+ c_importers.push_back(importer);
147
+ // need to sort the array afterwards (no big deal)
148
+ sort (c_importers.begin(), c_importers.end(), sort_importers);
116
149
  }
117
150
 
118
151
  Context::~Context()
119
152
  {
120
153
  // everything that gets put into sources will be freed by us
121
- for (size_t i = 0; i < sources.size(); ++i) delete[] sources[i];
122
154
  for (size_t n = 0; n < import_stack.size(); ++n) sass_delete_import(import_stack[n]);
155
+ // sources are allocated by strdup or malloc (overtaken from C code)
156
+ for (size_t i = 0; i < sources.size(); ++i) free((void*)sources[i]);
157
+ // clear inner structures (vectors)
123
158
  sources.clear(); import_stack.clear();
124
159
  }
125
160
 
@@ -221,58 +256,45 @@ namespace Sass {
221
256
  include_links.push_back(resolve_relative_path(abs_path, source_map_file, cwd));
222
257
  }
223
258
 
224
- string Context::add_file(string path)
259
+ // Add a new import file to the context
260
+ string Context::add_file(const string& file)
225
261
  {
226
262
  using namespace File;
227
- char* contents = 0;
228
- string real_path;
229
- path = make_canonical_path(path);
230
- for (size_t i = 0, S = include_paths.size(); i < S; ++i) {
231
- string full_path(join_paths(include_paths[i], path));
232
- if (style_sheets.count(full_path)) return full_path;
233
- contents = resolve_and_load(full_path, real_path);
234
- if (contents) {
235
- add_source(full_path, real_path, contents);
236
- style_sheets[full_path] = 0;
237
- return full_path;
238
- }
263
+ string path(make_canonical_path(file));
264
+ string resolved(find_file(path, include_paths));
265
+ if (resolved == "") return resolved;
266
+ if (char* contents = read_file(resolved)) {
267
+ add_source(path, resolved, contents);
268
+ style_sheets[path] = 0;
269
+ return path;
239
270
  }
240
- return string();
271
+ return string("");
241
272
  }
242
273
 
243
- string Context::add_file(string dir, string rel_filepath)
274
+ // Add a new import file to the context
275
+ // This has some previous directory context
276
+ string Context::add_file(const string& base, const string& file)
244
277
  {
245
278
  using namespace File;
246
- char* contents = 0;
247
- string real_path;
248
- rel_filepath = make_canonical_path(rel_filepath);
249
- string full_path(join_paths(dir, rel_filepath));
250
- if (style_sheets.count(full_path)) return full_path;
251
- contents = resolve_and_load(full_path, real_path);
252
- if (contents) {
253
- add_source(full_path, real_path, contents);
254
- style_sheets[full_path] = 0;
255
- return full_path;
256
- }
257
- for (size_t i = 0, S = include_paths.size(); i < S; ++i) {
258
- string full_path(join_paths(include_paths[i], rel_filepath));
259
- if (style_sheets.count(full_path)) return full_path;
260
- contents = resolve_and_load(full_path, real_path);
261
- if (contents) {
262
- add_source(full_path, real_path, contents);
263
- style_sheets[full_path] = 0;
264
- return full_path;
265
- }
279
+ string path(make_canonical_path(file));
280
+ string base_file(join_paths(base, path));
281
+ string resolved(resolve_file(base_file));
282
+ if (style_sheets.count(base_file)) return base_file;
283
+ if (char* contents = read_file(resolved)) {
284
+ add_source(base_file, resolved, contents);
285
+ style_sheets[base_file] = 0;
286
+ return base_file;
266
287
  }
267
- return string();
288
+ // now go the regular code path
289
+ return add_file(path);
268
290
  }
269
291
 
270
292
  void register_function(Context&, Signature sig, Native_Function f, Env* env);
271
293
  void register_function(Context&, Signature sig, Native_Function f, size_t arity, Env* env);
272
294
  void register_overload_stub(Context&, string name, Env* env);
273
295
  void register_built_in_functions(Context&, Env* env);
274
- void register_c_functions(Context&, Env* env, Sass_C_Function_List);
275
- void register_c_function(Context&, Env* env, Sass_C_Function_Callback);
296
+ void register_c_functions(Context&, Env* env, Sass_Function_List);
297
+ void register_c_function(Context&, Env* env, Sass_Function_Entry);
276
298
 
277
299
  char* Context::compile_block(Block* root)
278
300
  {
@@ -291,13 +313,13 @@ namespace Sass {
291
313
  {
292
314
  Block* root = 0;
293
315
  for (size_t i = 0; i < queue.size(); ++i) {
294
- struct Sass_Import* import = sass_make_import(
316
+ Sass_Import_Entry import = sass_make_import(
295
317
  queue[i].load_path.c_str(),
296
318
  queue[i].abs_path.c_str(),
297
319
  0, 0
298
320
  );
299
321
  import_stack.push_back(import);
300
- Parser p(Parser::from_c_str(queue[i].source, *this, ParserState(queue[i].abs_path, i)));
322
+ Parser p(Parser::from_c_str(queue[i].source, *this, ParserState(queue[i].abs_path, queue[i].source, i)));
301
323
  Block* ast = p.parse();
302
324
  sass_delete_import(import_stack.back());
303
325
  import_stack.pop_back();
@@ -311,9 +333,11 @@ namespace Sass {
311
333
  for (size_t i = 0, S = c_functions.size(); i < S; ++i) {
312
334
  register_c_function(*this, &tge, c_functions[i]);
313
335
  }
314
- Eval eval(*this, &tge, &backtrace);
315
- Contextualize contextualize(*this, &eval, &tge, &backtrace);
316
- Expand expand(*this, &eval, &contextualize, &tge, &backtrace);
336
+ Contextualize contextualize(*this, &tge, &backtrace);
337
+ Listize listize(*this);
338
+ Eval eval(*this, &contextualize, &listize, &tge, &backtrace);
339
+ Contextualize_Eval contextualize_eval(*this, &eval, &tge, &backtrace);
340
+ Expand expand(*this, &eval, &contextualize_eval, &tge, &backtrace);
317
341
  Cssize cssize(*this, &tge, &backtrace);
318
342
  root = root->perform(&expand)->block();
319
343
  root = root->perform(&cssize)->block();
@@ -382,7 +406,9 @@ namespace Sass {
382
406
  std::vector<std::string> Context::get_included_files(size_t skip)
383
407
  {
384
408
  vector<string> includes = included_files;
409
+ if (includes.size() == 0) return includes;
385
410
  std::sort( includes.begin() + skip, includes.end() );
411
+ includes.erase( includes.begin(), includes.begin() + skip );
386
412
  includes.erase( std::unique( includes.begin(), includes.end() ), includes.end() );
387
413
  // the skip solution seems more robust, as we may have real files named stdin
388
414
  // includes.erase( std::remove( includes.begin(), includes.end(), "stdin" ), includes.end() );
@@ -417,6 +443,7 @@ namespace Sass {
417
443
  name,
418
444
  0,
419
445
  0,
446
+ &ctx,
420
447
  true);
421
448
  (*env)[name + "[f]"] = stub;
422
449
  }
@@ -515,21 +542,16 @@ namespace Sass {
515
542
  register_function(ctx, unique_id_sig, unique_id, env);
516
543
  }
517
544
 
518
- void register_c_functions(Context& ctx, Env* env, Sass_C_Function_List descrs)
545
+ void register_c_functions(Context& ctx, Env* env, Sass_Function_List descrs)
519
546
  {
520
547
  while (descrs && *descrs) {
521
548
  register_c_function(ctx, env, *descrs);
522
549
  ++descrs;
523
550
  }
524
551
  }
525
- void register_c_function(Context& ctx, Env* env, Sass_C_Function_Callback descr)
552
+ void register_c_function(Context& ctx, Env* env, Sass_Function_Entry descr)
526
553
  {
527
- Definition* def = make_c_function(
528
- sass_function_get_signature(descr),
529
- sass_function_get_function(descr),
530
- sass_function_get_cookie(descr),
531
- ctx
532
- );
554
+ Definition* def = make_c_function(descr, ctx);
533
555
  def->environment(env);
534
556
  (*env)[def->name() + "[f]"] = def;
535
557
  }