Initial commit
[yaffs-website] / node_modules / node-sass / src / libsass / src / sass.cpp
1 #include "sass.hpp"
2 #include <cstdlib>
3 #include <cstring>
4 #include <vector>
5 #include <sstream>
6
7 #include "sass.h"
8 #include "file.hpp"
9 #include "util.hpp"
10 #include "sass_context.hpp"
11 #include "sass_functions.hpp"
12
13 namespace Sass {
14
15   // helper to convert string list to vector
16   std::vector<std::string> list2vec(struct string_list* cur)
17   {
18     std::vector<std::string> list;
19     while (cur) {
20       list.push_back(cur->string);
21       cur = cur->next;
22     }
23     return list;
24   }
25
26 }
27
28 extern "C" {
29   using namespace Sass;
30
31   // Allocate libsass heap memory
32   // Don't forget string termination!
33   void* ADDCALL sass_alloc_memory(size_t size)
34   {
35     void* ptr = malloc(size);
36     if (ptr == NULL)
37       out_of_memory();
38     return ptr;
39   }
40
41   char* ADDCALL sass_copy_c_string(const char* str)
42   {
43     size_t len = strlen(str) + 1;
44     char* cpy = (char*) sass_alloc_memory(len);
45     std::memcpy(cpy, str, len);
46     return cpy;
47   }
48
49   // Deallocate libsass heap memory
50   void ADDCALL sass_free_memory(void* ptr)
51   {
52     if (ptr) free (ptr);
53   }
54
55   // caller must free the returned memory
56   char* ADDCALL sass_string_quote (const char *str, const char quote_mark)
57   {
58     std::string quoted = quote(str, quote_mark);
59     return sass_copy_c_string(quoted.c_str());
60   }
61
62   // caller must free the returned memory
63   char* ADDCALL sass_string_unquote (const char *str)
64   {
65     std::string unquoted = unquote(str);
66     return sass_copy_c_string(unquoted.c_str());
67   }
68
69   char* ADDCALL sass_compiler_find_include (const char* file, struct Sass_Compiler* compiler)
70   {
71     // get the last import entry to get current base directory
72     Sass_Import_Entry import = sass_compiler_get_last_import(compiler);
73     const std::vector<std::string>& incs = compiler->cpp_ctx->include_paths;
74     // create the vector with paths to lookup
75     std::vector<std::string> paths(1 + incs.size());
76     paths.push_back(File::dir_name(import->abs_path));
77     paths.insert( paths.end(), incs.begin(), incs.end() );
78     // now resolve the file path relative to lookup paths
79     std::string resolved(File::find_include(file, paths));
80     return sass_copy_c_string(resolved.c_str());
81   }
82
83   char* ADDCALL sass_compiler_find_file (const char* file, struct Sass_Compiler* compiler)
84   {
85     // get the last import entry to get current base directory
86     Sass_Import_Entry import = sass_compiler_get_last_import(compiler);
87     const std::vector<std::string>& incs = compiler->cpp_ctx->include_paths;
88     // create the vector with paths to lookup
89     std::vector<std::string> paths(1 + incs.size());
90     paths.push_back(File::dir_name(import->abs_path));
91     paths.insert( paths.end(), incs.begin(), incs.end() );
92     // now resolve the file path relative to lookup paths
93     std::string resolved(File::find_file(file, paths));
94     return sass_copy_c_string(resolved.c_str());
95   }
96
97   // Make sure to free the returned value!
98   // Incs array has to be null terminated!
99   // this has the original resolve logic for sass include
100   char* ADDCALL sass_find_include (const char* file, struct Sass_Options* opt)
101   {
102     std::vector<std::string> vec(list2vec(opt->include_paths));
103     std::string resolved(File::find_include(file, vec));
104     return sass_copy_c_string(resolved.c_str());
105   }
106
107   // Make sure to free the returned value!
108   // Incs array has to be null terminated!
109   char* ADDCALL sass_find_file (const char* file, struct Sass_Options* opt)
110   {
111     std::vector<std::string> vec(list2vec(opt->include_paths));
112     std::string resolved(File::find_file(file, vec));
113     return sass_copy_c_string(resolved.c_str());
114   }
115
116   // Get compiled libsass version
117   const char* ADDCALL libsass_version(void)
118   {
119     return LIBSASS_VERSION;
120   }
121
122   // Get compiled libsass version
123   const char* ADDCALL libsass_language_version(void)
124   {
125     return LIBSASS_LANGUAGE_VERSION;
126   }
127
128 }
129
130 namespace Sass {
131
132   // helper to aid dreaded MSVC debug mode
133   char* sass_copy_string(std::string str)
134   {
135     // In MSVC the following can lead to segfault:
136     // sass_copy_c_string(stream.str().c_str());
137     // Reason is that the string returned by str() is disposed before
138     // sass_copy_c_string is invoked. The string is actually a stack
139     // object, so indeed nobody is holding on to it. So it seems
140     // perfectly fair to release it right away. So the const char*
141     // by c_str will point to invalid memory. I'm not sure if this is
142     // the behavior for all compiler, but I'm pretty sure we would
143     // have gotten more issues reported if that would be the case.
144     // Wrapping it in a functions seems the cleanest approach as the
145     // function must hold on to the stack variable until it's done.
146     return sass_copy_c_string(str.c_str());
147   }
148
149 }