sassc 1.8.1 → 1.8.2

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 (70) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +3 -1
  3. data/ext/libsass/Makefile +10 -6
  4. data/ext/libsass/Readme.md +4 -4
  5. data/ext/libsass/appveyor.yml +16 -1
  6. data/ext/libsass/docs/README.md +1 -1
  7. data/ext/libsass/docs/api-context-example.md +1 -1
  8. data/ext/libsass/docs/api-context.md +1 -1
  9. data/ext/libsass/docs/api-doc.md +1 -1
  10. data/ext/libsass/docs/api-function-example.md +12 -3
  11. data/ext/libsass/docs/api-function-internal.md +4 -4
  12. data/ext/libsass/docs/api-function.md +15 -13
  13. data/ext/libsass/docs/api-importer-internal.md +9 -4
  14. data/ext/libsass/docs/api-value.md +1 -1
  15. data/ext/libsass/docs/build-shared-library.md +3 -3
  16. data/ext/libsass/docs/custom-functions-internal.md +1 -1
  17. data/ext/libsass/docs/{plugins.go → plugins.md} +0 -0
  18. data/ext/libsass/script/ci-build-libsass +25 -36
  19. data/ext/libsass/script/ci-install-deps +3 -8
  20. data/ext/libsass/script/ci-report-coverage +17 -13
  21. data/ext/libsass/src/ast.cpp +102 -7
  22. data/ext/libsass/src/ast.hpp +53 -27
  23. data/ext/libsass/src/ast_def_macros.hpp +8 -0
  24. data/ext/libsass/src/ast_fwd_decl.hpp +3 -2
  25. data/ext/libsass/src/backtrace.hpp +1 -1
  26. data/ext/libsass/src/bind.cpp +28 -17
  27. data/ext/libsass/src/bind.hpp +1 -1
  28. data/ext/libsass/src/context.cpp +441 -184
  29. data/ext/libsass/src/context.hpp +79 -82
  30. data/ext/libsass/src/debugger.hpp +3 -1
  31. data/ext/libsass/src/emitter.cpp +18 -17
  32. data/ext/libsass/src/emitter.hpp +5 -2
  33. data/ext/libsass/src/error_handling.cpp +78 -7
  34. data/ext/libsass/src/error_handling.hpp +50 -9
  35. data/ext/libsass/src/eval.cpp +100 -36
  36. data/ext/libsass/src/eval.hpp +5 -5
  37. data/ext/libsass/src/expand.cpp +32 -3
  38. data/ext/libsass/src/extend.cpp +1 -1
  39. data/ext/libsass/src/file.cpp +39 -27
  40. data/ext/libsass/src/file.hpp +67 -13
  41. data/ext/libsass/src/functions.cpp +39 -32
  42. data/ext/libsass/src/inspect.cpp +21 -21
  43. data/ext/libsass/src/json.cpp +1 -1
  44. data/ext/libsass/src/lexer.hpp +33 -4
  45. data/ext/libsass/src/output.cpp +11 -11
  46. data/ext/libsass/src/parser.cpp +28 -130
  47. data/ext/libsass/src/parser.hpp +0 -4
  48. data/ext/libsass/src/prelexer.cpp +8 -5
  49. data/ext/libsass/src/prelexer.hpp +1 -3
  50. data/ext/libsass/src/sass_context.cpp +52 -241
  51. data/ext/libsass/src/sass_context.hpp +156 -0
  52. data/ext/libsass/src/sass_functions.cpp +1 -26
  53. data/ext/libsass/src/sass_functions.hpp +32 -0
  54. data/ext/libsass/src/sass_interface.cpp +14 -48
  55. data/ext/libsass/src/sass_values.cpp +3 -77
  56. data/ext/libsass/src/sass_values.hpp +81 -0
  57. data/ext/libsass/src/source_map.cpp +7 -7
  58. data/ext/libsass/src/source_map.hpp +1 -4
  59. data/ext/libsass/src/to_string.cpp +4 -3
  60. data/ext/libsass/src/to_string.hpp +2 -1
  61. data/ext/libsass/src/util.cpp +34 -16
  62. data/ext/libsass/src/util.hpp +10 -8
  63. data/lib/sassc/version.rb +1 -1
  64. data/lib/tasks/libsass.rb +1 -1
  65. data/test/custom_importer_test.rb +6 -4
  66. data/test/engine_test.rb +5 -3
  67. data/test/functions_test.rb +1 -0
  68. data/test/native_test.rb +1 -1
  69. metadata +6 -4
  70. data/ext/libsass/script/coveralls-debug +0 -32
@@ -2,28 +2,69 @@
2
2
  #define SASS_ERROR_HANDLING_H
3
3
 
4
4
  #include <string>
5
-
5
+ #include <sstream>
6
+ #include <stdexcept>
6
7
  #include "position.hpp"
7
8
 
8
9
  namespace Sass {
9
10
 
10
11
  struct Backtrace;
11
12
 
12
- struct Error_Invalid {
13
- enum Type { read, write, syntax, evaluation };
13
+ namespace Exception {
14
+
15
+ const std::string def_msg = "Invalid sass";
16
+
17
+ class Base : public std::runtime_error {
18
+ protected:
19
+ std::string msg;
20
+ public:
21
+ ParserState pstate;
22
+ public:
23
+ Base(ParserState pstate, std::string msg = def_msg);
24
+ virtual const char* what() const throw();
25
+ virtual ~Base() throw() {};
26
+ };
27
+
28
+ class InvalidSass : public Base {
29
+ public:
30
+ InvalidSass(ParserState pstate, std::string msg);
31
+ virtual ~InvalidSass() throw() {};
32
+ };
33
+
34
+ class InvalidParent : public Base {
35
+ protected:
36
+ Selector* parent;
37
+ Selector* selector;
38
+ public:
39
+ InvalidParent(Selector* parent, Selector* selector);
40
+ virtual ~InvalidParent() throw() {};
41
+ };
14
42
 
15
- Type type;
16
- ParserState pstate;
17
- std::string message;
43
+ class InvalidArgumentType : public Base {
44
+ protected:
45
+ std::string fn;
46
+ std::string arg;
47
+ std::string type;
48
+ const Value* value;
49
+ public:
50
+ InvalidArgumentType(ParserState pstate, std::string fn, std::string arg, std::string type, const Value* value = 0);
51
+ virtual ~InvalidArgumentType() throw() {};
52
+ };
18
53
 
19
- Error_Invalid(Type type, ParserState pstate, std::string message);
54
+ class InvalidSyntax : public Base {
55
+ public:
56
+ InvalidSyntax(ParserState pstate, std::string msg);
57
+ virtual ~InvalidSyntax() throw() {};
58
+ };
20
59
 
21
- };
60
+ }
22
61
 
23
62
  void warn(std::string msg, ParserState pstate);
24
63
  void warn(std::string msg, ParserState pstate, Backtrace* bt);
25
64
 
26
- void deprecated(std::string msg, ParserState pstate);
65
+ void deprecated_function(std::string msg, ParserState pstate);
66
+ void deprecated(std::string msg, std::string msg2, ParserState pstate);
67
+ void deprecated_bind(std::string msg, ParserState pstate);
27
68
  // void deprecated(std::string msg, ParserState pstate, Backtrace* bt);
28
69
 
29
70
  void error(std::string msg, ParserState pstate);
@@ -378,7 +378,7 @@ namespace Sass {
378
378
  Expression* Eval::operator()(Debug* d)
379
379
  {
380
380
  Expression* message = d->value()->perform(this);
381
- To_String to_string(&ctx);
381
+ To_String to_string(&ctx, false, true);
382
382
  Env* env = exp.environment();
383
383
 
384
384
  // try to use generic function
@@ -400,10 +400,13 @@ namespace Sass {
400
400
 
401
401
  }
402
402
 
403
- std::string cwd(ctx.get_cwd());
403
+ std::string cwd(ctx.cwd());
404
404
  std::string result(unquote(message->perform(&to_string)));
405
- std::string rel_path(Sass::File::resolve_relative_path(d->pstate().path, cwd, cwd));
406
- std::cerr << rel_path << ":" << d->pstate().line+1 << " DEBUG: " << result;
405
+ std::string abs_path(Sass::File::rel2abs(d->pstate().path, cwd, cwd));
406
+ std::string rel_path(Sass::File::abs2rel(d->pstate().path, cwd, cwd));
407
+ std::string output_path(Sass::File::path_for_console(rel_path, abs_path, d->pstate().path));
408
+
409
+ std::cerr << output_path << ":" << d->pstate().line+1 << " DEBUG: " << result;
407
410
  std::cerr << std::endl;
408
411
  return 0;
409
412
  }
@@ -446,7 +449,7 @@ namespace Sass {
446
449
  // check the evaluated keys aren't duplicates.
447
450
  if (mm->has_duplicate_key()) {
448
451
  To_String to_string(&ctx);
449
- error("Duplicate key \"" + mm->get_duplicate_key()->perform(&to_string) + "\" in map " + mm->perform(&to_string) + ".", mm->pstate());
452
+ error("Duplicate key \"" + mm->get_duplicate_key()->perform(&to_string) + "\" in map " + m->perform(&to_string) + ".", mm->pstate());
450
453
  }
451
454
 
452
455
  mm->is_expanded(true);
@@ -462,7 +465,11 @@ namespace Sass {
462
465
  // if one of the operands is a '/' then make sure it's evaluated
463
466
  Expression* lhs = b->left()->perform(this);
464
467
  lhs->is_delayed(false);
465
- while (typeid(*lhs) == typeid(Binary_Expression)) lhs = lhs->perform(this);
468
+ while (typeid(*lhs) == typeid(Binary_Expression)) {
469
+ Binary_Expression* lhs_ex = static_cast<Binary_Expression*>(lhs);
470
+ if (lhs_ex->type() == Sass_OP::DIV && lhs_ex->is_delayed()) break;
471
+ lhs = Eval::operator()(lhs_ex);
472
+ }
466
473
 
467
474
  switch (op_type) {
468
475
  case Sass_OP::AND:
@@ -520,36 +527,86 @@ namespace Sass {
520
527
  default: break;
521
528
  }
522
529
 
530
+
523
531
  Expression::Concrete_Type l_type = lhs->concrete_type();
524
532
  Expression::Concrete_Type r_type = rhs->concrete_type();
525
533
 
526
- int precision = (int)ctx.precision;
527
- bool compressed = ctx.output_style == COMPRESSED;
534
+ // Is one of the operands an interpolant?
535
+ String_Schema* s1 = dynamic_cast<String_Schema*>(b->left());
536
+ String_Schema* s2 = dynamic_cast<String_Schema*>(b->right());
537
+
538
+ if ((s1 && s1->has_interpolants()) || (s2 && s2->has_interpolants())) {
539
+ std::string sep;
540
+ switch (op_type) {
541
+ case Sass_OP::SUB: sep = "-"; break;
542
+ case Sass_OP::DIV: sep = "/"; break;
543
+ case Sass_OP::ADD: sep = "+"; break;
544
+ case Sass_OP::MUL: sep = "*"; break;
545
+ default: break;
546
+ }
547
+
548
+ // If possible upgrade LHS to a number
549
+ if (op_type == Sass_OP::DIV || op_type == Sass_OP::MUL || op_type == Sass_OP::ADD || op_type == Sass_OP::SUB) {
550
+ if (String_Constant* str = dynamic_cast<String_Constant*>(lhs)) {
551
+ std::string value(str->value());
552
+ const char* start = value.c_str();
553
+ if (Prelexer::sequence < Prelexer::number >(start) != 0) {
554
+ lhs = SASS_MEMORY_NEW(ctx.mem, Textual, lhs->pstate(), Textual::DIMENSION, str->value());
555
+ lhs->is_delayed(false); lhs = lhs->perform(this);
556
+ }
557
+ }
558
+ if (String_Constant* str = dynamic_cast<String_Constant*>(rhs)) {
559
+ std::string value(str->value());
560
+ const char* start = value.c_str();
561
+ if (Prelexer::sequence < Prelexer::number >(start) != 0) {
562
+ rhs = SASS_MEMORY_NEW(ctx.mem, Textual, rhs->pstate(), Textual::DIMENSION, str->value());
563
+ rhs->is_delayed(false); rhs = rhs->perform(this);
564
+ }
565
+ }
566
+ }
567
+
568
+ To_Value to_value(ctx, ctx.mem);
569
+ Value* v_l = dynamic_cast<Value*>(lhs->perform(&to_value));
570
+ Value* v_r = dynamic_cast<Value*>(rhs->perform(&to_value));
571
+ Expression::Concrete_Type l_type = lhs->concrete_type();
572
+ Expression::Concrete_Type r_type = rhs->concrete_type();
573
+
574
+ if (l_type == Expression::NUMBER && r_type == Expression::NUMBER) {
575
+ return SASS_MEMORY_NEW(ctx.mem, String_Constant, lhs->pstate(),
576
+ v_l->to_string() + " " + sep + " " + v_r->to_string());
577
+ }
578
+ }
579
+
580
+ // ToDo: throw error in op functions
581
+ // ToDo: then catch and re-throw them
582
+ ParserState pstate(b->pstate());
583
+ int precision = (int)ctx.c_options->precision;
584
+ bool compressed = ctx.output_style() == SASS_STYLE_COMPRESSED;
528
585
  if (l_type == Expression::NUMBER && r_type == Expression::NUMBER) {
529
586
  const Number* l_n = dynamic_cast<const Number*>(lhs);
530
587
  const Number* r_n = dynamic_cast<const Number*>(rhs);
531
- return op_numbers(ctx.mem, op_type, *l_n, *r_n, compressed, precision);
588
+ return op_numbers(ctx.mem, op_type, *l_n, *r_n, compressed, precision, &pstate);
532
589
  }
533
590
  if (l_type == Expression::NUMBER && r_type == Expression::COLOR) {
534
591
  const Number* l_n = dynamic_cast<const Number*>(lhs);
535
592
  const Color* r_c = dynamic_cast<const Color*>(rhs);
536
- return op_number_color(ctx.mem, op_type, *l_n, *r_c, compressed, precision);
593
+ return op_number_color(ctx.mem, op_type, *l_n, *r_c, compressed, precision, &pstate);
537
594
  }
538
595
  if (l_type == Expression::COLOR && r_type == Expression::NUMBER) {
539
596
  const Color* l_c = dynamic_cast<const Color*>(lhs);
540
597
  const Number* r_n = dynamic_cast<const Number*>(rhs);
541
- return op_color_number(ctx.mem, op_type, *l_c, *r_n, compressed, precision);
598
+ return op_color_number(ctx.mem, op_type, *l_c, *r_n, compressed, precision, &pstate);
542
599
  }
543
600
  if (l_type == Expression::COLOR && r_type == Expression::COLOR) {
544
601
  const Color* l_c = dynamic_cast<const Color*>(lhs);
545
602
  const Color* r_c = dynamic_cast<const Color*>(rhs);
546
- return op_colors(ctx.mem, op_type, *l_c, *r_c, compressed, precision);
603
+ return op_colors(ctx.mem, op_type, *l_c, *r_c, compressed, precision, &pstate);
547
604
  }
548
605
 
549
606
  To_Value to_value(ctx, ctx.mem);
550
607
  Value* v_l = dynamic_cast<Value*>(lhs->perform(&to_value));
551
608
  Value* v_r = dynamic_cast<Value*>(rhs->perform(&to_value));
552
- Value* ex = op_strings(ctx.mem, op_type, *v_l, *v_r, compressed, precision);
609
+ Value* ex = op_strings(ctx.mem, op_type, *v_l, *v_r, compressed, precision, &pstate);
553
610
  if (String_Constant* str = dynamic_cast<String_Constant*>(ex))
554
611
  {
555
612
  if (str->concrete_type() != Expression::STRING) return ex;
@@ -651,14 +708,14 @@ namespace Sass {
651
708
  exp.env_stack.push_back(&fn_env);
652
709
 
653
710
  if (func || body) {
654
- bind("function " + c->name(), params, args, ctx, &fn_env, this);
711
+ bind(std::string("Function"), c->name(), params, args, &ctx, &fn_env, this);
655
712
  Backtrace here(backtrace(), c->pstate(), ", in function `" + c->name() + "`");
656
713
  exp.backtrace_stack.push_back(&here);
657
714
  // if it's user-defined, eval the body
658
715
  if (body) result = body->perform(this);
659
716
  // if it's native, invoke the underlying CPP function
660
717
  else result = func(fn_env, *env, ctx, def->signature(), c->pstate(), backtrace());
661
- if (!result) error(std::string("function ") + c->name() + " did not return a value", c->pstate());
718
+ if (!result) error(std::string("Function ") + c->name() + " did not return a value", c->pstate());
662
719
  exp.backtrace_stack.pop_back();
663
720
  }
664
721
 
@@ -675,7 +732,8 @@ namespace Sass {
675
732
  }
676
733
 
677
734
  // populates env with default values for params
678
- bind("function " + c->name(), params, args, ctx, &fn_env, this);
735
+ std::string ff(c->name());
736
+ bind(std::string("Function"), c->name(), params, args, &ctx, &fn_env, this);
679
737
 
680
738
  Backtrace here(backtrace(), c->pstate(), ", in function `" + c->name() + "`");
681
739
  exp.backtrace_stack.push_back(&here);
@@ -897,7 +955,7 @@ namespace Sass {
897
955
  } else if (List* list = dynamic_cast<List*>(s)) {
898
956
  std::string acc = ""; // ToDo: different output styles
899
957
  std::string sep = list->separator() == SASS_COMMA ? "," : " ";
900
- if (ctx.output_style != COMPRESSED && sep == ",") sep += " ";
958
+ if (ctx.output_style() != SASS_STYLE_COMPRESSED && sep == ",") sep += " ";
901
959
  bool initial = false;
902
960
  for(auto item : list->elements()) {
903
961
  if (item->concrete_type() != Expression::NULL_VAL) {
@@ -914,10 +972,16 @@ namespace Sass {
914
972
  return evacuate_quotes(interpolation(value));
915
973
  } else if (dynamic_cast<Binary_Expression*>(s)) {
916
974
  Expression* ex = s->perform(this);
975
+ // avoid recursive calls if same object gets returned
976
+ // since we will call interpolate again for the result
977
+ if (ex == s) {
978
+ To_String to_string(&ctx);
979
+ return evacuate_quotes(s->perform(&to_string));
980
+ }
917
981
  return evacuate_quotes(interpolation(ex));
918
982
  } else if (dynamic_cast<Function_Call*>(s)) {
919
983
  Expression* ex = s->perform(this);
920
- return evacuate_quotes(interpolation(ex));
984
+ return evacuate_quotes(unquote(interpolation(ex)));
921
985
  } else if (dynamic_cast<Unary_Expression*>(s)) {
922
986
  Expression* ex = s->perform(this);
923
987
  return evacuate_quotes(interpolation(ex));
@@ -1160,15 +1224,15 @@ namespace Sass {
1160
1224
  return *l < *r;
1161
1225
  }
1162
1226
 
1163
- Value* Eval::op_numbers(Memory_Manager& mem, enum Sass_OP op, const Number& l, const Number& r, bool compressed, int precision)
1227
+ Value* Eval::op_numbers(Memory_Manager& mem, enum Sass_OP op, const Number& l, const Number& r, bool compressed, int precision, ParserState* pstate)
1164
1228
  {
1165
1229
  double lv = l.value();
1166
1230
  double rv = r.value();
1167
1231
  if (op == Sass_OP::DIV && !rv) {
1168
- return SASS_MEMORY_NEW(mem, String_Quoted, l.pstate(), "Infinity");
1232
+ return SASS_MEMORY_NEW(mem, String_Quoted, pstate ? *pstate : l.pstate(), "Infinity");
1169
1233
  }
1170
1234
  if (op == Sass_OP::MOD && !rv) {
1171
- error("division by zero", r.pstate());
1235
+ error("division by zero", pstate ? *pstate : r.pstate());
1172
1236
  }
1173
1237
 
1174
1238
  Number tmp(r);
@@ -1178,10 +1242,10 @@ namespace Sass {
1178
1242
  std::string r_unit(tmp.unit());
1179
1243
  if (l_unit != r_unit && !l_unit.empty() && !r_unit.empty() &&
1180
1244
  (op == Sass_OP::ADD || op == Sass_OP::SUB)) {
1181
- error("Incompatible units: '"+r_unit+"' and '"+l_unit+"'.", l.pstate());
1245
+ error("Incompatible units: '"+r_unit+"' and '"+l_unit+"'.", pstate ? *pstate : r.pstate());
1182
1246
  }
1183
1247
  Number* v = SASS_MEMORY_NEW(mem, Number, l);
1184
- v->pstate(l.pstate());
1248
+ v->pstate(pstate ? *pstate : l.pstate());
1185
1249
  if (l_unit.empty() && (op == Sass_OP::ADD || op == Sass_OP::SUB || op == Sass_OP::MOD)) {
1186
1250
  v->numerator_units() = r.numerator_units();
1187
1251
  v->denominator_units() = r.denominator_units();
@@ -1211,7 +1275,7 @@ namespace Sass {
1211
1275
  return v;
1212
1276
  }
1213
1277
 
1214
- Value* Eval::op_number_color(Memory_Manager& mem, enum Sass_OP op, const Number& l, const Color& rh, bool compressed, int precision)
1278
+ Value* Eval::op_number_color(Memory_Manager& mem, enum Sass_OP op, const Number& l, const Color& rh, bool compressed, int precision, ParserState* pstate)
1215
1279
  {
1216
1280
  Color r(rh);
1217
1281
  r.disp("");
@@ -1220,7 +1284,7 @@ namespace Sass {
1220
1284
  case Sass_OP::ADD:
1221
1285
  case Sass_OP::MUL: {
1222
1286
  return SASS_MEMORY_NEW(mem, Color,
1223
- l.pstate(),
1287
+ pstate ? *pstate : l.pstate(),
1224
1288
  ops[op](lv, r.r()),
1225
1289
  ops[op](lv, r.g()),
1226
1290
  ops[op](lv, r.b()),
@@ -1231,13 +1295,13 @@ namespace Sass {
1231
1295
  std::string sep(op == Sass_OP::SUB ? "-" : "/");
1232
1296
  std::string color(r.to_string(compressed||!r.sixtuplet(), precision));
1233
1297
  return SASS_MEMORY_NEW(mem, String_Quoted,
1234
- l.pstate(),
1298
+ pstate ? *pstate : l.pstate(),
1235
1299
  l.to_string(compressed, precision)
1236
1300
  + sep
1237
1301
  + color);
1238
1302
  } break;
1239
1303
  case Sass_OP::MOD: {
1240
- error("cannot divide a number by a color", r.pstate());
1304
+ error("cannot divide a number by a color", pstate ? *pstate : r.pstate());
1241
1305
  } break;
1242
1306
  default: break; // caller should ensure that we don't get here
1243
1307
  }
@@ -1245,35 +1309,35 @@ namespace Sass {
1245
1309
  return SASS_MEMORY_NEW(mem, Color, rh);
1246
1310
  }
1247
1311
 
1248
- Value* Eval::op_color_number(Memory_Manager& mem, enum Sass_OP op, const Color& l, const Number& r, bool compressed, int precision)
1312
+ Value* Eval::op_color_number(Memory_Manager& mem, enum Sass_OP op, const Color& l, const Number& r, bool compressed, int precision, ParserState* pstate)
1249
1313
  {
1250
1314
  double rv = r.value();
1251
- if (op == Sass_OP::DIV && !rv) error("division by zero", r.pstate());
1315
+ if (op == Sass_OP::DIV && !rv) error("division by zero", pstate ? *pstate : r.pstate());
1252
1316
  return SASS_MEMORY_NEW(mem, Color,
1253
- l.pstate(),
1317
+ pstate ? *pstate : l.pstate(),
1254
1318
  ops[op](l.r(), rv),
1255
1319
  ops[op](l.g(), rv),
1256
1320
  ops[op](l.b(), rv),
1257
1321
  l.a());
1258
1322
  }
1259
1323
 
1260
- Value* Eval::op_colors(Memory_Manager& mem, enum Sass_OP op, const Color& l, const Color& r, bool compressed, int precision)
1324
+ Value* Eval::op_colors(Memory_Manager& mem, enum Sass_OP op, const Color& l, const Color& r, bool compressed, int precision, ParserState* pstate)
1261
1325
  {
1262
1326
  if (l.a() != r.a()) {
1263
- error("alpha channels must be equal when combining colors", r.pstate());
1327
+ error("alpha channels must be equal when combining colors", pstate ? *pstate : r.pstate());
1264
1328
  }
1265
1329
  if (op == Sass_OP::DIV && (!r.r() || !r.g() ||!r.b())) {
1266
- error("division by zero", r.pstate());
1330
+ error("division by zero", pstate ? *pstate : r.pstate());
1267
1331
  }
1268
1332
  return SASS_MEMORY_NEW(mem, Color,
1269
- l.pstate(),
1333
+ pstate ? *pstate : l.pstate(),
1270
1334
  ops[op](l.r(), r.r()),
1271
1335
  ops[op](l.g(), r.g()),
1272
1336
  ops[op](l.b(), r.b()),
1273
1337
  l.a());
1274
1338
  }
1275
1339
 
1276
- Value* Eval::op_strings(Memory_Manager& mem, enum Sass_OP op, Value& lhs, Value& rhs, bool compressed, int precision)
1340
+ Value* Eval::op_strings(Memory_Manager& mem, enum Sass_OP op, Value& lhs, Value& rhs, bool compressed, int precision, ParserState* pstate)
1277
1341
  {
1278
1342
  Expression::Concrete_Type ltype = lhs.concrete_type();
1279
1343
  Expression::Concrete_Type rtype = rhs.concrete_type();
@@ -1320,7 +1384,7 @@ namespace Sass {
1320
1384
  switch (op) {
1321
1385
  case Sass_OP::SUB: sep = "-"; break;
1322
1386
  case Sass_OP::DIV: sep = "/"; break;
1323
- default: break;
1387
+ default: break;
1324
1388
  }
1325
1389
  if (ltype == Expression::NULL_VAL) error("Invalid null operation: \"null plus "+quote(unquote(rstr), '"')+"\".", lhs.pstate());
1326
1390
  if (rtype == Expression::NULL_VAL) error("Invalid null operation: \""+quote(unquote(lstr), '"')+" plus null\".", rhs.pstate());
@@ -89,11 +89,11 @@ namespace Sass {
89
89
  static bool eq(Expression*, Expression*);
90
90
  static bool lt(Expression*, Expression*);
91
91
  // -- arithmetic on the combinations that matter
92
- static Value* op_numbers(Memory_Manager&, enum Sass_OP, const Number&, const Number&, bool compressed = false, int precision = 5);
93
- static Value* op_number_color(Memory_Manager&, enum Sass_OP, const Number&, const Color&, bool compressed = false, int precision = 5);
94
- static Value* op_color_number(Memory_Manager&, enum Sass_OP, const Color&, const Number&, bool compressed = false, int precision = 5);
95
- static Value* op_colors(Memory_Manager&, enum Sass_OP, const Color&, const Color&, bool compressed = false, int precision = 5);
96
- static Value* op_strings(Memory_Manager&, enum Sass_OP, Value&, Value&, bool compressed = false, int precision = 5);
92
+ static Value* op_numbers(Memory_Manager&, enum Sass_OP, const Number&, const Number&, bool compressed = false, int precision = 5, ParserState* pstate = 0);
93
+ static Value* op_number_color(Memory_Manager&, enum Sass_OP, const Number&, const Color&, bool compressed = false, int precision = 5, ParserState* pstate = 0);
94
+ static Value* op_color_number(Memory_Manager&, enum Sass_OP, const Color&, const Number&, bool compressed = false, int precision = 5, ParserState* pstate = 0);
95
+ static Value* op_colors(Memory_Manager&, enum Sass_OP, const Color&, const Color&, bool compressed = false, int precision = 5, ParserState* pstate = 0);
96
+ static Value* op_strings(Memory_Manager&, enum Sass_OP, Value&, Value&, bool compressed = false, int precision = 5, ParserState* pstate = 0);
97
97
 
98
98
  private:
99
99
  std::string interpolation(Expression* s, bool into_quotes = false);
@@ -28,6 +28,7 @@ namespace Sass {
28
28
  env_stack.push_back(0);
29
29
  env_stack.push_back(env);
30
30
  block_stack.push_back(0);
31
+ // import_stack.push_back(0);
31
32
  property_stack.push_back(0);
32
33
  selector_stack.push_back(0);
33
34
  backtrace_stack.push_back(0);
@@ -303,19 +304,31 @@ namespace Sass {
303
304
  Statement* Expand::operator()(Import* imp)
304
305
  {
305
306
  Import* result = SASS_MEMORY_NEW(ctx.mem, Import, imp->pstate());
306
- if (imp->media_queries()) {
307
+ if (imp->media_queries() && imp->media_queries()->size()) {
307
308
  Expression* ex = imp->media_queries()->perform(&eval);
308
309
  result->media_queries(dynamic_cast<List*>(ex));
309
310
  }
310
311
  for ( size_t i = 0, S = imp->urls().size(); i < S; ++i) {
311
312
  result->urls().push_back(imp->urls()[i]->perform(&eval));
312
313
  }
314
+ // all resources have been dropped for Input_Stubs
315
+ // for ( size_t i = 0, S = imp->incs().size(); i < S; ++i) {}
313
316
  return result;
314
317
  }
315
318
 
316
319
  Statement* Expand::operator()(Import_Stub* i)
317
320
  {
318
- append_block(ctx.style_sheets[i->file_name()]);
321
+ // we don't seem to need that actually afterall
322
+ Sass_Import_Entry import = sass_make_import(
323
+ i->imp_path().c_str(),
324
+ i->abs_path().c_str(),
325
+ 0, 0
326
+ );
327
+ ctx.import_stack.push_back(import);
328
+ const std::string& abs_path(i->resource().abs_path);
329
+ append_block(ctx.sheets.at(abs_path).root);
330
+ sass_delete_import(ctx.import_stack.back());
331
+ ctx.import_stack.pop_back();
319
332
  return 0;
320
333
  }
321
334
 
@@ -577,6 +590,21 @@ namespace Sass {
577
590
  Definition* dd = SASS_MEMORY_NEW(ctx.mem, Definition, *d);
578
591
  env->local_frame()[d->name() +
579
592
  (d->type() == Definition::MIXIN ? "[m]" : "[f]")] = dd;
593
+
594
+ if (d->type() == Definition::FUNCTION && (
595
+ d->name() == "calc" ||
596
+ d->name() == "element" ||
597
+ d->name() == "expression" ||
598
+ d->name() == "url"
599
+ )) {
600
+ deprecated(
601
+ "Naming a function \"" + d->name() + "\" is disallowed",
602
+ "This name conflicts with an existing CSS function with special parse rules.",
603
+ d->pstate()
604
+ );
605
+ }
606
+
607
+
580
608
  // set the static link so we can have lexical scoping
581
609
  dd->environment(env);
582
610
  return 0;
@@ -613,7 +641,8 @@ namespace Sass {
613
641
  thunk->environment(env);
614
642
  new_env.local_frame()["@content[m]"] = thunk;
615
643
  }
616
- bind("mixin " + c->name(), params, args, ctx, &new_env, &eval);
644
+
645
+ bind(std::string("Mixin"), c->name(), params, args, &ctx, &new_env, &eval);
617
646
  append_block(body);
618
647
  backtrace_stack.pop_back();
619
648
  env_stack.pop_back();