<commit_before>#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#include <ctype.h>

#include "macro.h"
#include "parse.h"
#include "../util/alloc.h"
#include "../util/dynarray.h"
#include "../util/util.h"
#include "str.h"
#include "main.h"

#define VA_ARGS_STR "__VA_ARGS__"

macro **macros = NULL;
char **lib_dirs = NULL;

void macro_add_dir(char *d)
{
	dynarray_add(&lib_dirs, d);
}

macro *macro_find(const char *sp)
{
	macro **i;
	for(i = macros; i && *i; i++)
		if(!strcmp((*i)->nam, sp))
			return *i;
	return NULL;
}

macro *macro_add(const char *nam, const char *val)
{
	macro *m;

	m = macro_find(nam);

	if(m){
		CPP_WARN("cpp: warning: redefining \"%s\"", nam);
		free(m->nam);
		free(m->val);
	}else{
		m = umalloc(sizeof *m);
		dynarray_add(&macros, m);
	}

	m->nam = ustrdup(nam);
	m->val = val ? ustrdup(val) : NULL;
	m->type = MACRO;

	DEBUG(DEBUG_NORM, "macro_add(\"%s\", \"%s\")\n", nam, val);

	return m;
}

macro *macro_add_func(const char *nam, const char *val, char **args, int variadic)
{
	macro *m  = macro_add(nam, val);
	m->args = args;
	m->type = variadic ? VARIADIC : FUNC;
	return m;
}

void macro_remove(const char *nam)
{
	macro *m = macro_find(nam);

	if(m){
		free(m->nam);
		free(m->val);
		dynarray_rm(macros, m);
		free(m);
	}
}

static char **split_args(char *open_b, char *close_b)
{
	char **arg_separators = NULL;
	char *arg;

	arg = open_b;

	do{
		dynarray_add(&arg_separators, arg);
		arg = strchr_nest(arg, ',');
	}while(arg && arg < close_b);

	dynarray_add(&arg_separators, close_b);

	{
		char **args = NULL;
		size_t i;

		for(i = 0; arg_separators[i + 1]; i++){
			char *from = arg_separators[i] + 1;
			char *to   = arg_separators[i + 1] - 1;

			if(from < to)
				arg = ustrdup2(from, to);
			else
				arg = ustrdup("");

			dynarray_add(&args, arg);
		}

		dynarray_free(arg_separators, NULL);

		return args;
	}
}

static char *eval_macro_r(macro *m, char *start, char *at)
{
	if(m->type == MACRO){
		static int counter = 0; /* __COUNTER__ */
		int free_val = 0;
		char *val;<commit_msg>Fixed bad free<commit_after>#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#include <ctype.h>

#include "macro.h"
#include "parse.h"
#include "../util/alloc.h"
#include "../util/dynarray.h"
#include "../util/util.h"
#include "str.h"
#include "main.h"

#define VA_ARGS_STR "__VA_ARGS__"

macro **macros = NULL;
char **lib_dirs = NULL;

void macro_add_dir(char *d)
{
	dynarray_add(&lib_dirs, d);
}

macro *macro_find(const char *sp)
{
	macro **i;
	for(i = macros; i && *i; i++)
		if(!strcmp((*i)->nam, sp))
			return *i;
	return NULL;
}

macro *macro_add(const char *nam, const char *val)
{
	macro *m;

	m = macro_find(nam);

	if(m){
		CPP_WARN("cpp: warning: redefining \"%s\"", nam);
		free(m->nam);
		free(m->val);
	}else{
		m = umalloc(sizeof *m);
		dynarray_add(&macros, m);
	}

	m->nam = ustrdup(nam);
	m->val = val ? ustrdup(val) : NULL;
	m->type = MACRO;

	DEBUG(DEBUG_NORM, "macro_add(\"%s\", \"%s\")\n", nam, val);

	return m;
}

macro *macro_add_func(const char *nam, const char *val, char **args, int variadic)
{
	macro *m  = macro_add(nam, val);
	m->args = args;
	m->type = variadic ? VARIADIC : FUNC;
	return m;
}

void macro_remove(const char *nam)
{
	macro *m = macro_find(nam);

	if(m){
		free(m->nam);
		free(m->val);
		dynarray_rm(macros, m);
		free(m);
	}
}

static char **split_args(char *open_b, char *close_b)
{
	char **arg_separators = NULL;
	char *arg;

	arg = open_b;

	do{
		dynarray_add(&arg_separators, arg);
		arg = strchr_nest(arg, ',');
	}while(arg && arg < close_b);

	dynarray_add(&arg_separators, close_b);

	{
		char **args = NULL;
		size_t i;

		for(i = 0; arg_separators[i + 1]; i++){
			char *from = arg_separators[i] + 1;
			char *to   = arg_separators[i + 1] - 1;

			if(from < to)
				arg = ustrdup2(from, to);
			else
				arg = ustrdup("");

			dynarray_add(&args, arg);
		}

		dynarray_free(&arg_separators, NULL);

		return args;
	}
}

static char *eval_macro_r(macro *m, char *start, char *at)
{
	if(m->type == MACRO){
		static int counter = 0; /* __COUNTER__ */
		int free_val = 0;
		char *val;
{'fraction_non_alphanumeric': 0.19154589371980676, 'fraction_numerical': 0.003864734299516908, 'mean_word_length': 3.754305396096441, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 35, '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': '758756', 'n_tokens_mistral': 1941, 'n_tokens_neox': 1779, 'n_words': 415}