<commit_before>/**
 * See stratego_sglr_parse_table.c for information on the reasons for
 * using the "language" hacks.
 *
 * @author <NAME>
 * @author <NAME>
 */

#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <aterm2.h>
#include <srts/stratego.h>
#include <stratego-lib/stratego-lib-common.h>
#include <sglr.h>
#include <parse-table.h>
#include <rsrc-usage.h>
#include <MEPT-utils.h>

#include "stratego_sglr.h"
#include "stratego_sglr_internal.h"

/**
 * State
 */
static ATerm parse_error_term = NULL;
static ATerm none_term = NULL;
static ATerm *inactive_parse_tables;
static int num_inactive_parse_tables = 0;
static ATermList active_parse_tables = NULL;

/**
 * Prototypes
 */
static char* read_text_from_stream(FILE* stream);

/**
 * Parse tables must be killed using SG_DiscardParseTable. This must
 * be done after the last parse table blob has died, and cannot be
 * done when the parse table is closed (because dangling refs might
 * remain). This callback ensures that's done propely.
 */
ATbool parse_table_blob_destructor(ATermBlob t) {
  int i;
  for(i = 0; i < num_inactive_parse_tables; i++) {
    if(inactive_parse_tables[i] == (ATerm)t)
      break; 
  }
  if(i < num_inactive_parse_tables) {
    inactive_parse_tables[i] = inactive_parse_tables[num_inactive_parse_tables - 1];
    num_inactive_parse_tables--;
    SG_DiscardParseTable(parse_table_from_term((ATerm)t));
    return ATtrue;
  }
  return ATfalse;
}

/**
 * When a parse table is opened, we keep track of it as 'active'.
 */
ATerm activate_parse_table(ATerm t) {
  active_parse_tables = ATinsert(active_parse_tables, t);
  return t;
}

/**
 * When a parse table is closed again, we move it to an 'inactive' list.
 * Our blob_destructor() will only destruct inactive parse tables. 
 */
void inactivate_parse_table(ATerm t) {
  active_parse_tables = ATremoveElement(active_parse_tables,  t);
  assert(num_inactive_parse_tables < MAX_INACTIVE_PARSE_TABLES);
  inactive_parse_tables[num_inactive_parse_tables++] = t;
}

void STRSGLR_ensure_init(void)
{
  ATerm foo;

  static ATbool STRSGLR_init = ATfalse;
  if(STRSGLR_init)
    return;

  STRSGLR_init = ATtrue;

 
  ATregisterBlobDestructor(parse_table_blob_destructor);

  PT_initMEPTApi();
  PT_initAsFix2Api();
  initErrorApi();

  SG_TOOLBUS_OFF();
  SG_OUTPUT_ON();
  foo = STRSGLR_set_default_config();

  none_term = (ATerm) ATmakeAppl(ATmakeAFun("None", 0, ATfalse));
  active_parse_tables = ATmakeList(0);
  inactive_parse_tables = malloc(sizeof(ATerm*) * MAX_INACTIVE_PARSE_TABLES);
  num_inactive_parse_tables = 0;

  ATprotect(&none_term);
  ATprotect(&parse_error_term);
  ATprotect((ATerm*)&active_parse_tables);
}

ATerm STRSGLR_set_default_config(void)
{
  STRSGLR_ensure_init();

  STRSGLR_set_default_filters();
  SG_ASFIX2_ON();
  SG_AMBIGUITY_ERROR_OFF();
  return (ATerm) ATempty;
}

static ATerm parse_string_pt(const char* string, ATerm tbl_term, ATerm start_term, ATerm path_term)
{
  ATerm result = NULL;
  parse_table* tbl = NULL;
  const char* start = NULL;
  const char* path = NULL;

  STRSGLR_ensure_init();
  STRSGLR_clear_parse_error();

  tbl = parse_table_from_term(tbl_term);
  if(tbl == NULL)
    return NULL; // @todo: set the error term.
<commit_msg>Should hopefully fix type-punning warning.<commit_after>/**
 * See stratego_sglr_parse_table.c for information on the reasons for
 * using the "language" hacks.
 *
 * @author <NAME>
 * @author <NAME>
 */

#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <aterm2.h>
#include <srts/stratego.h>
#include <stratego-lib/stratego-lib-common.h>
#include <sglr.h>
#include <parse-table.h>
#include <rsrc-usage.h>
#include <MEPT-utils.h>

#include "stratego_sglr.h"
#include "stratego_sglr_internal.h"

/**
 * State
 */
static ATerm parse_error_term = NULL;
static ATerm none_term = NULL;
static ATerm *inactive_parse_tables;
static int num_inactive_parse_tables = 0;
static ATermList active_parse_tables = NULL;

/**
 * Prototypes
 */
static char* read_text_from_stream(FILE* stream);

/**
 * Parse tables must be killed using SG_DiscardParseTable. This must
 * be done after the last parse table blob has died, and cannot be
 * done when the parse table is closed (because dangling refs might
 * remain). This callback ensures that's done propely.
 */
ATbool parse_table_blob_destructor(ATermBlob t) {
  int i;
  for(i = 0; i < num_inactive_parse_tables; i++) {
    if(inactive_parse_tables[i] == (ATerm)t)
      break; 
  }
  if(i < num_inactive_parse_tables) {
    inactive_parse_tables[i] = inactive_parse_tables[num_inactive_parse_tables - 1];
    num_inactive_parse_tables--;
    SG_DiscardParseTable(parse_table_from_term((ATerm)t));
    return ATtrue;
  }
  return ATfalse;
}

/**
 * When a parse table is opened, we keep track of it as 'active'.
 */
ATerm activate_parse_table(ATerm t) {
  active_parse_tables = ATinsert(active_parse_tables, t);
  return t;
}

/**
 * When a parse table is closed again, we move it to an 'inactive' list.
 * Our blob_destructor() will only destruct inactive parse tables. 
 */
void inactivate_parse_table(ATerm t) {
  active_parse_tables = ATremoveElement(active_parse_tables,  t);
  assert(num_inactive_parse_tables < MAX_INACTIVE_PARSE_TABLES);
  inactive_parse_tables[num_inactive_parse_tables++] = t;
}

void STRSGLR_ensure_init(void)
{
  ATerm foo;

  static ATbool STRSGLR_init = ATfalse;
  if(STRSGLR_init)
    return;

  STRSGLR_init = ATtrue;

 
  ATregisterBlobDestructor(parse_table_blob_destructor);

  PT_initMEPTApi();
  PT_initAsFix2Api();
  initErrorApi();

  SG_TOOLBUS_OFF();
  SG_OUTPUT_ON();
  foo = STRSGLR_set_default_config();

  none_term = (ATerm) ATmakeAppl(ATmakeAFun("None", 0, ATfalse));
  active_parse_tables = ATmakeList(0);
  inactive_parse_tables = malloc(sizeof(ATerm*) * MAX_INACTIVE_PARSE_TABLES);
  num_inactive_parse_tables = 0;

  ATprotect(&none_term);
  ATprotect(&parse_error_term);
  ATprotectList(&active_parse_tables);
}

ATerm STRSGLR_set_default_config(void)
{
  STRSGLR_ensure_init();

  STRSGLR_set_default_filters();
  SG_ASFIX2_ON();
  SG_AMBIGUITY_ERROR_OFF();
  return (ATerm) ATempty;
}

static ATerm parse_string_pt(const char* string, ATerm tbl_term, ATerm start_term, ATerm path_term)
{
  ATerm result = NULL;
  parse_table* tbl = NULL;
  const char* start = NULL;
  const char* path = NULL;

  STRSGLR_ensure_init();
  STRSGLR_clear_parse_error();

  tbl = parse_table_from_term(tbl_term);
  if(tbl == NULL)
    return NULL; // @todo: set the error term.

{'fraction_non_alphanumeric': 0.10940616848243057, 'fraction_numerical': 0.0027620070584624826, 'mean_word_length': 4.941659070191431, 'pattern_counts': {'":': 0, '<': 33, '<?xml version=': 0, '>': 27, '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': '7586703', 'n_tokens_mistral': 2473, 'n_tokens_neox': 2390, 'n_words': 536}