<commit_before>/**
 * Lua-powered dynamic language lexer for Scintillua.
 * http://scintillua.googlecode.com
 *
 * Copyright 2006-2011 Mitchell mitchell<att>caladbolg.net.
 * This file is distributed under Scintilla's license.
 *
 * Documentation can be found in the README, /lexers/lexer.lua, and
 * http://caladbolg.net/luadoc/textadept/modules/lexer.html.
 */

#if LPEG_LEXER || LPEG_LEXER_EXTERNAL

#include <assert.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "ILexer.h"
#include "Scintilla.h"
#include "SciLexer.h"

#include "PropSetSimple.h"
#include "LexAccessor.h"
#include "LexerModule.h"

extern "C" {
#include <lua.h>
#include <lualib.h>
#include <lauxlib.h>
LUALIB_API int (luaopen_lpeg) (lua_State *L);
}

#ifdef __WIN32__
#define strcasecmp _stricmp
#endif

#define streq(s1, s2) (strcasecmp((s1), (s2)) == 0)

#ifdef SCI_NAMESPACE
using namespace Scintilla;
#endif

/**
 * Prints a Lua error message.
 * If an error message is not specified, the Lua error message at the top of the
 * stack is used and the stack is subsequently cleared.
 * @return false
 */
static bool l_error(lua_State *L, const char *str=NULL) {
	fprintf(stderr, "Lua Error: %s.\n", str ? str : lua_tostring(L, -1));
	lua_settop(L, 0);
	return false;
}

/**
 * Retrieves the style at a position.
 * Lua interface: StyleAt(pos)
 * @param pos The position to get the style for.
 */
static int lua_style_at(lua_State *L) {
	lua_getfield(L, LUA_REGISTRYINDEX, "pAccess");
	IDocument *pAccess = static_cast<IDocument *>(lua_touserdata(L, -1));
	LexAccessor styler(pAccess);
	int style = styler.StyleAt(luaL_checkinteger(L, 1) - 1);
	lua_getglobal(L, "_LEXER");
	lua_getfield(L, -1, "_TOKENS");
	lua_pushnil(L);
	while (lua_next(L, -2)) {
		// stylename = num
		if (luaL_checkinteger(L, -1) == style)
			break;
		else
			lua_pop(L, 1); // value
	}
	return 2;
}

/**
 * Gets an integer property value.
 * Lua interface: GetProperty(key [, default])
 * @param key The property key.
 * @param default Optional default value.
 * @return integer value of the property.
 */
static int lua_get_property(lua_State *L) {
	lua_getfield(L, LUA_REGISTRYINDEX, "props");
	PropSetSimple *props = static_cast<PropSetSimple *>(lua_touserdata(L, -1));
	lua_pushnumber(L, props->GetInt(luaL_checkstring(L, 1),
								 (lua_gettop(L) > 1) ? luaL_checkinteger(L, 2) : 0));
	return 1;
}

/**
 * Gets the fold level of a line number.
 * Lua interface: GetFoldLevel(line_number)
 * @param line_number The line number to get the fold level of.
 * @return the integer fold level.
 */
static int lua_get_fold_level(lua_State *L) {
	lua_getfield(L, LUA_REGISTRYINDEX, "pAccess");
	IDocument *pAccess = static_cast<IDocument *>(lua_touserdata(L, -1));<commit_msg>Fix segfault when props is null; LexLPeg.cxx<commit_after>/**
 * Lua-powered dynamic language lexer for Scintillua.
 * http://scintillua.googlecode.com
 *
 * Copyright 2006-2011 Mitchell mitchell<att>cal<EMAIL>.
 * This file is distributed under Scintilla's license.
 *
 * Documentation can be found in the README, /lexers/lexer.lua, and
 * http://caladbolg.net/luadoc/textadept/modules/lexer.html.
 */

#if LPEG_LEXER || LPEG_LEXER_EXTERNAL

#include <assert.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "ILexer.h"
#include "Scintilla.h"
#include "SciLexer.h"

#include "PropSetSimple.h"
#include "LexAccessor.h"
#include "LexerModule.h"

extern "C" {
#include <lua.h>
#include <lualib.h>
#include <lauxlib.h>
LUALIB_API int (luaopen_lpeg) (lua_State *L);
}

#ifdef __WIN32__
#define strcasecmp _stricmp
#endif

#define streq(s1, s2) (strcasecmp((s1), (s2)) == 0)

#ifdef SCI_NAMESPACE
using namespace Scintilla;
#endif

/**
 * Prints a Lua error message.
 * If an error message is not specified, the Lua error message at the top of the
 * stack is used and the stack is subsequently cleared.
 * @return false
 */
static bool l_error(lua_State *L, const char *str=NULL) {
	fprintf(stderr, "Lua Error: %s.\n", str ? str : lua_tostring(L, -1));
	lua_settop(L, 0);
	return false;
}

/**
 * Retrieves the style at a position.
 * Lua interface: StyleAt(pos)
 * @param pos The position to get the style for.
 */
static int lua_style_at(lua_State *L) {
	lua_getfield(L, LUA_REGISTRYINDEX, "pAccess");
	IDocument *pAccess = static_cast<IDocument *>(lua_touserdata(L, -1));
	LexAccessor styler(pAccess);
	int style = styler.StyleAt(luaL_checkinteger(L, 1) - 1);
	lua_getglobal(L, "_LEXER");
	lua_getfield(L, -1, "_TOKENS");
	lua_pushnil(L);
	while (lua_next(L, -2)) {
		// stylename = num
		if (luaL_checkinteger(L, -1) == style)
			break;
		else
			lua_pop(L, 1); // value
	}
	return 2;
}

/**
 * Gets an integer property value.
 * Lua interface: GetProperty(key [, default])
 * @param key The property key.
 * @param default Optional default value.
 * @return integer value of the property.
 */
static int lua_get_property(lua_State *L) {
	lua_getfield(L, LUA_REGISTRYINDEX, "props");
	PropSetSimple *props = static_cast<PropSetSimple *>(lua_touserdata(L, -1));
	int value = (lua_gettop(L) > 1) ? luaL_checkinteger(L, 2) : 0;
	if (props) value = props->GetInt(luaL_checkstring(L, 1), value);
	lua_pushnumber(L, value);
	return 1;
}

/**
 * Gets the fold level of a line number.
 * Lua interface: GetFoldLevel(line_number)
 * @param line_number The line number to get the fold level of.
 * @return the integer fold level.
 */
static int lua_get_fold_level(lua_State *L) {
	lua_getfield(L, LUA_REGISTRYINDEX, "pAccess");
	IDocument *pAccess = static_cast<IDocument *>(lua_touserdata(L, -1));
{'fraction_non_alphanumeric': 0.13823319027181688, 'fraction_numerical': 0.011444921316165951, 'mean_word_length': 4.598598598598598, 'pattern_counts': {'":': 0, '<': 28, '<?xml version=': 0, '>': 32, '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': '3038889', 'n_tokens_mistral': 2213, 'n_tokens_neox': 2109, 'n_words': 574}