sassc 0.0.10 → 0.0.11

Sign up to get free protection for your applications and to get access to all the features.
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
  }