<commit_before>#include <nan.h>
#include <vector>
#include "sass_context_wrapper.h"

char* CreateString(Local<Value> value) {
  if (value->IsNull() || !value->IsString()) {
    return const_cast<char*>(""); // return empty string.
  }

  String::Utf8Value string(value);
  char *str = (char *)malloc(string.length() + 1);
  strcpy(str, *string);
  return str;
}

std::vector<sass_context_wrapper*> imports_collection;

void dispatched_async_uv_callback(uv_async_t *req){
  NanScope();
  sass_context_wrapper* ctx_w = static_cast<sass_context_wrapper*>(req->data);

  TryCatch try_catch;

  imports_collection.push_back(ctx_w);

  Handle<Value> argv[] = {
    NanNew<String>(strdup(ctx_w->file)),
    NanNew<String>(strdup(ctx_w->prev)),
    NanNew<Number>(imports_collection.size() - 1)
  };

  NanNew<Value>(ctx_w->importer_callback->Call(3, argv));

  if (try_catch.HasCaught()) {
    node::FatalException(try_catch);
  }
}

struct Sass_Import** sass_importer(const char* file, const char* prev, void* cookie)
{
  sass_context_wrapper* ctx_w = static_cast<sass_context_wrapper*>(cookie);

  ctx_w->file = strdup(file);
  ctx_w->prev = strdup(prev);
  ctx_w->async.data = (void*)ctx_w;
  uv_async_send(&ctx_w->async);

  if (ctx_w->success_callback) {
    /*  that is async: Render() or RenderFile(),
     *  the default even loop is unblocked so it
     *  can run uv_async_send without a push.
     */
    uv_cond_wait(&ctx_w->importer_condition_variable, &ctx_w->importer_mutex);
  }
  else{
    /*  that is sync: RenderSync() or RenderFileSync,
     *  we need to explicitly uv_run as the event loop
     *  is blocked; waiting down the chain.
     */
    uv_run(ctx_w->async.loop, UV_RUN_DEFAULT);
  }

  return ctx_w->imports;
}

void ExtractOptions(Local<Object> options, void* cptr, sass_context_wrapper* ctx_w, bool isFile, bool isSync) {
  struct Sass_Context* ctx;

  if (isFile) {
    ctx = sass_file_context_get_context((struct Sass_File_Context*) cptr);
    ctx_w->fctx = (struct Sass_File_Context*) cptr;
  }
  else {
    ctx = sass_data_context_get_context((struct Sass_Data_Context*) cptr);
    ctx_w->dctx = (struct Sass_Data_Context*) cptr;
  }

  struct Sass_Options* sass_options = sass_context_get_options(ctx);

  if (!isSync) {
    NanAssignPersistent(ctx_w->stats, options->Get(NanNew("stats"))->ToObject());

    ctx_w->request.data = ctx_w;

    // async (callback) style
    Local<Function> success_callback = Local<Function>::Cast(options->Get(NanNew("success")));
    Local<Function> error_callback = Local<Function>::Cast(options->Get(NanNew("error")));

    ctx_w->success_callback = new NanCallback(success_callback);
    ctx_w->error_callback = new NanCallback(error_callback);
  }

  Local<Function> importer_callback = Local<Function>::Cast(options->Get(NanNew("importer")));

  ctx_w->importer_callback = new NanCallback(importer_callback);

  if (!importer_callback->IsUndefined()) {
    uv_async_init(uv_default_loop(), &ctx_w->async, (uv_async_cb)dispatched_async_uv_callback);
    sass_option_set_importer(sass_options, sass_make_importer(sass_importer, ctx_w));
  }

  sass_option_set_input_path(sass_options, CreateString(options->Get(NanNew("file"))));
  sass_option_set_output_path(sass_options, CreateString(options->Get(NanNew("outFile"))));
  sass_option_set_output_path(sass_options, CreateString(options->Get(NanNew("outFile"))));
  sass_option_set_image_path(sass_options, CreateString(options->Get(NanNew("imagePath"))));
  sass_option_set_output_style(sass_options, (Sass_Output_Style)options->Get(NanNew("style"))->Int32Value());
  sass_option_set_is_indented_syntax_src(sass_options, options->Get(NanNew("indentedSyntax"))->BooleanValue());
  sass_option_set_source_comments(sass_options, options->Get(NanNew("comments"))->BooleanValue());
  sass_option_set_omit_source_map_url(sass_options, options->Get(NanNew("omitSourceMapUrl"))->BooleanValue());
  sass_option_set_source_map_embed(sass_options, options->Get(NanNew("sourceMapEmbed"))->BooleanValue());
  sass_option_set_source_map_contents(sass_options, options->Get(NanNew("sourceMapContents"))->BooleanValue());
  sass_option_set_source_map_file(sass_options, CreateString(options->Get(NanNew("sourceMap"))));
  sass_option_set_include_path(sass_options, CreateString(options->Get(NanNew("paths"))));
  sass_option_set_precision(sass_options, options->Get(NanNew("precision"))->Int32Value());
}

void FillStatsObj(Handle<Object> stats, Sass_Context* ctx) {
  char** included_files = sass_context_get_included_files(ctx);
  Handle<Array> arr = NanNew<Array>();

  if (included_files) {
    for (int i = 0; included_files[i] != nullptr; ++i) {
      arr->Set(i, NanNew<String>(included_files[i]));
    }
  }

  (*stats)->Set(NanNew("includedFiles"), arr);

  Handle<Value> source_map;

  if (sass_context_get_error_status(ctx)) {
    return;<commit_msg>Binding: Removes duplicate statement.<commit_after>#include <nan.h>
#include <vector>
#include "sass_context_wrapper.h"

char* CreateString(Local<Value> value) {
  if (value->IsNull() || !value->IsString()) {
    return const_cast<char*>(""); // return empty string.
  }

  String::Utf8Value string(value);
  char *str = (char *)malloc(string.length() + 1);
  strcpy(str, *string);
  return str;
}

std::vector<sass_context_wrapper*> imports_collection;

void dispatched_async_uv_callback(uv_async_t *req){
  NanScope();
  sass_context_wrapper* ctx_w = static_cast<sass_context_wrapper*>(req->data);

  TryCatch try_catch;

  imports_collection.push_back(ctx_w);

  Handle<Value> argv[] = {
    NanNew<String>(strdup(ctx_w->file)),
    NanNew<String>(strdup(ctx_w->prev)),
    NanNew<Number>(imports_collection.size() - 1)
  };

  NanNew<Value>(ctx_w->importer_callback->Call(3, argv));

  if (try_catch.HasCaught()) {
    node::FatalException(try_catch);
  }
}

struct Sass_Import** sass_importer(const char* file, const char* prev, void* cookie)
{
  sass_context_wrapper* ctx_w = static_cast<sass_context_wrapper*>(cookie);

  ctx_w->file = strdup(file);
  ctx_w->prev = strdup(prev);
  ctx_w->async.data = (void*)ctx_w;
  uv_async_send(&ctx_w->async);

  if (ctx_w->success_callback) {
    /*  that is async: Render() or RenderFile(),
     *  the default even loop is unblocked so it
     *  can run uv_async_send without a push.
     */
    uv_cond_wait(&ctx_w->importer_condition_variable, &ctx_w->importer_mutex);
  }
  else{
    /*  that is sync: RenderSync() or RenderFileSync,
     *  we need to explicitly uv_run as the event loop
     *  is blocked; waiting down the chain.
     */
    uv_run(ctx_w->async.loop, UV_RUN_DEFAULT);
  }

  return ctx_w->imports;
}

void ExtractOptions(Local<Object> options, void* cptr, sass_context_wrapper* ctx_w, bool isFile, bool isSync) {
  struct Sass_Context* ctx;

  if (isFile) {
    ctx = sass_file_context_get_context((struct Sass_File_Context*) cptr);
    ctx_w->fctx = (struct Sass_File_Context*) cptr;
  }
  else {
    ctx = sass_data_context_get_context((struct Sass_Data_Context*) cptr);
    ctx_w->dctx = (struct Sass_Data_Context*) cptr;
  }

  struct Sass_Options* sass_options = sass_context_get_options(ctx);

  if (!isSync) {
    NanAssignPersistent(ctx_w->stats, options->Get(NanNew("stats"))->ToObject());

    ctx_w->request.data = ctx_w;

    // async (callback) style
    Local<Function> success_callback = Local<Function>::Cast(options->Get(NanNew("success")));
    Local<Function> error_callback = Local<Function>::Cast(options->Get(NanNew("error")));

    ctx_w->success_callback = new NanCallback(success_callback);
    ctx_w->error_callback = new NanCallback(error_callback);
  }

  Local<Function> importer_callback = Local<Function>::Cast(options->Get(NanNew("importer")));

  ctx_w->importer_callback = new NanCallback(importer_callback);

  if (!importer_callback->IsUndefined()) {
    uv_async_init(uv_default_loop(), &ctx_w->async, (uv_async_cb)dispatched_async_uv_callback);
    sass_option_set_importer(sass_options, sass_make_importer(sass_importer, ctx_w));
  }

  sass_option_set_input_path(sass_options, CreateString(options->Get(NanNew("file"))));
  sass_option_set_output_path(sass_options, CreateString(options->Get(NanNew("outFile"))));
  sass_option_set_image_path(sass_options, CreateString(options->Get(NanNew("imagePath"))));
  sass_option_set_output_style(sass_options, (Sass_Output_Style)options->Get(NanNew("style"))->Int32Value());
  sass_option_set_is_indented_syntax_src(sass_options, options->Get(NanNew("indentedSyntax"))->BooleanValue());
  sass_option_set_source_comments(sass_options, options->Get(NanNew("comments"))->BooleanValue());
  sass_option_set_omit_source_map_url(sass_options, options->Get(NanNew("omitSourceMapUrl"))->BooleanValue());
  sass_option_set_source_map_embed(sass_options, options->Get(NanNew("sourceMapEmbed"))->BooleanValue());
  sass_option_set_source_map_contents(sass_options, options->Get(NanNew("sourceMapContents"))->BooleanValue());
  sass_option_set_source_map_file(sass_options, CreateString(options->Get(NanNew("sourceMap"))));
  sass_option_set_include_path(sass_options, CreateString(options->Get(NanNew("paths"))));
  sass_option_set_precision(sass_options, options->Get(NanNew("precision"))->Int32Value());
}

void FillStatsObj(Handle<Object> stats, Sass_Context* ctx) {
  char** included_files = sass_context_get_included_files(ctx);
  Handle<Array> arr = NanNew<Array>();

  if (included_files) {
    for (int i = 0; included_files[i] != nullptr; ++i) {
      arr->Set(i, NanNew<String>(included_files[i]));
    }
  }

  (*stats)->Set(NanNew("includedFiles"), arr);

  Handle<Value> source_map;

  if (sass_context_get_error_status(ctx)) {
    return;
{'fraction_non_alphanumeric': 0.14575569358178053, 'fraction_numerical': 0.0018633540372670807, 'mean_word_length': 6.198956780923994, 'pattern_counts': {'":': 0, '<': 51, '<?xml version=': 0, '>': 154, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4762518', 'n_tokens_mistral': 3503, 'n_tokens_neox': 3366, 'n_words': 496}