[PATCH 2/3] add basic lua infrastructure

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This adds a small module for examining parts of a commit
from inside a lua interpreter. Eventually you'll be able to
do grep-like filtering and --pretty formatting.

The most naive presentation would be to parse the whole
commit and put it in a lua table. However, instead we build
upon the incremental parsing used by the --format parser,
and lazily parse bits of the commit as the lua code requests
them.

Signed-off-by: Jeff King <peff@xxxxxxxx>
---
Set "USE_LUA" in your Makefile to turn it on.

 Makefile     |   7 +++
 lua-commit.c | 166 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 lua-commit.h |   9 ++++
 3 files changed, 182 insertions(+)
 create mode 100644 lua-commit.c
 create mode 100644 lua-commit.h

diff --git a/Makefile b/Makefile
index a49d1db..54473e2 100644
--- a/Makefile
+++ b/Makefile
@@ -636,6 +636,7 @@ LIB_H += log-tree.h
 LIB_H += list-objects.h
 LIB_H += ll-merge.h
 LIB_H += log-tree.h
+LIB_H += lua-commit.h
 LIB_H += mailmap.h
 LIB_H += merge-file.h
 LIB_H += merge-recursive.h
@@ -749,6 +750,7 @@ LIB_OBJS += log-tree.o
 LIB_OBJS += ll-merge.o
 LIB_OBJS += lockfile.o
 LIB_OBJS += log-tree.o
+LIB_OBJS += lua-commit.o
 LIB_OBJS += mailmap.o
 LIB_OBJS += match-trees.o
 LIB_OBJS += merge-file.o
@@ -1818,6 +1820,11 @@ endif
        COMPAT_OBJS += compat/nedmalloc/nedmalloc.o
 endif
 
+ifdef USE_LUA
+	BASIC_CFLAGS += -DUSE_LUA `pkg-config --cflags lua5.2`
+	EXTLIBS += `pkg-config --libs lua5.2`
+endif
+
 ifdef GIT_TEST_CMP_USE_COPIED_CONTEXT
 	export GIT_TEST_CMP_USE_COPIED_CONTEXT
 endif
diff --git a/lua-commit.c b/lua-commit.c
new file mode 100644
index 0000000..ce1eeeb
--- /dev/null
+++ b/lua-commit.c
@@ -0,0 +1,166 @@
+#include "cache.h"
+#include "lua-commit.h"
+#include "commit.h"
+
+#ifndef USE_LUA
+
+static const char msg[] = "git was built without lua support";
+
+void lua_commit_init(const char *)
+{
+	die(msg);
+}
+
+void lua_commit_format(struct strbuf *,
+		       struct format_commit_context *)
+{
+	die(msg);
+}
+
+#else
+
+#include <lua.h>
+#include <lauxlib.h>
+#include <lualib.h>
+
+static lua_State *lua;
+
+/* XXX
+ * We need to access this from functions called from inside lua. Probably it
+ * would be cleaner use a lua "register" to let each function access it, but I
+ * haven't looked into it.
+ */
+static struct format_commit_context *c;
+
+static int lua_fun_hash(lua_State *lua)
+{
+	lua_pushstring(lua, sha1_to_hex(c->commit->object.sha1));
+	return 1;
+}
+
+static int lua_fun_abbrev(lua_State *lua)
+{
+	const char *hex;
+	unsigned char sha1[20];
+
+	hex = lua_tostring(lua, -1);
+	if (!hex || get_sha1_hex(hex, sha1)) {
+		lua_pushstring(lua, "abbrev requires a sha1");
+		lua_error(lua);
+	}
+
+	lua_pushstring(lua, find_unique_abbrev(sha1, c->pretty_ctx->abbrev));
+	return 1;
+}
+
+static int get_ident(lua_State *lua, const char *line, int len)
+{
+	struct ident_split s;
+
+	if (split_ident_line(&s, line, len) < 0) {
+		lua_pushstring(lua, "unable to parse ident line");
+		lua_error(lua);
+	}
+
+	lua_createtable(lua, 0, 2);
+	lua_pushstring(lua, "name");
+	lua_pushlstring(lua, s.name_begin, s.name_end - s.name_begin);
+	lua_settable(lua, -3);
+	lua_pushstring(lua, "email");
+	lua_pushlstring(lua, s.mail_begin, s.mail_end - s.mail_begin);
+	lua_settable(lua, -3);
+
+	/* XXX should also put date in the table */
+
+	return 1;
+}
+
+static int lua_fun_author(lua_State *lua)
+{
+	if (!c->commit_header_parsed)
+		parse_commit_header(c);
+	return get_ident(lua, c->message + c->author.off, c->author.len);
+}
+
+static int lua_fun_committer(lua_State *lua)
+{
+	if (!c->commit_header_parsed)
+		parse_commit_header(c);
+	return get_ident(lua, c->message + c->committer.off, c->committer.len);
+}
+
+static int lua_fun_message(lua_State *lua)
+{
+	lua_pushstring(lua, c->message + c->message_off + 1);
+	return 1;
+}
+
+static int lua_fun_subject(lua_State *lua)
+{
+	struct strbuf tmp = STRBUF_INIT;
+
+	if (!c->commit_header_parsed)
+		parse_commit_header(c);
+	if (!c->commit_message_parsed)
+		parse_commit_message(c);
+
+	format_subject(&tmp, c->message + c->subject_off, " ");
+	lua_pushlstring(lua, tmp.buf, tmp.len);
+	return 1;
+}
+
+static int lua_fun_body(lua_State *lua)
+{
+	if (!c->commit_header_parsed)
+		parse_commit_header(c);
+	if (!c->commit_message_parsed)
+		parse_commit_message(c);
+
+	lua_pushstring(lua, c->message + c->body_off);
+	return 1;
+}
+
+void lua_commit_init(const char *snippet)
+{
+	if (!lua) {
+		lua = luaL_newstate();
+		if (!lua)
+			die("unable to open lua interpreter");
+		luaL_openlibs(lua);
+
+#define REG(name) do { \
+	lua_pushcfunction(lua, lua_fun_##name); \
+	lua_setglobal(lua, #name); \
+} while(0)
+
+		REG(hash);
+		REG(abbrev);
+		REG(author);
+		REG(committer);
+		REG(message);
+		REG(subject);
+		REG(body);
+	}
+
+	if (luaL_loadstring(lua, snippet))
+		die("unable to load lua snippet: %s", snippet);
+}
+
+void lua_commit_format(struct strbuf *out,
+		       struct format_commit_context *context)
+{
+	const char *ret;
+	size_t len;
+
+	c = context;
+
+	lua_pushvalue(lua, -1);
+	if (lua_pcall(lua, 0, 1, 0))
+		die("lua failed: %s", lua_tostring(lua, -1));
+
+	ret = lua_tolstring(lua, -1, &len);
+	strbuf_add(out, ret, len);
+	lua_pop(lua, 1);
+}
+
+#endif /* USE_LUA */
diff --git a/lua-commit.h b/lua-commit.h
new file mode 100644
index 0000000..aaffced
--- /dev/null
+++ b/lua-commit.h
@@ -0,0 +1,9 @@
+#ifndef LUA_COMMIT_H
+#define LUA_COMMIT_H
+
+struct format_commit_context;
+
+void lua_commit_init(const char *snippet);
+void lua_commit_format(struct strbuf *out, struct format_commit_context *context);
+
+#endif
-- 
1.7.12.1.10.g6537447

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]