From: Jeff King <peff@peff.net>
To: git@vger.kernel.org
Subject: [PATCH 2/3] add basic lua infrastructure
Date: Mon, 24 Sep 2012 20:25:12 -0400 [thread overview]
Message-ID: <20120925002511.GB19605@sigill.intra.peff.net> (raw)
In-Reply-To: <20120925002325.GA19560@sigill.intra.peff.net>
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@peff.net>
---
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
next prev parent reply other threads:[~2012-09-25 0:25 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-09-25 0:23 [RFC/PATCH 0/3] git log --pretty=lua Jeff King
2012-09-25 0:24 ` [PATCH 1/3] pretty: make some commit-parsing helpers more public Jeff King
2012-09-25 0:25 ` Jeff King [this message]
2012-09-25 1:55 ` [PATCH 2/3] add basic lua infrastructure Nguyen Thai Ngoc Duy
2012-09-25 4:53 ` Jeff King
2012-09-25 3:21 ` Robin H. Johnson
2012-09-25 3:42 ` Jeff King
2012-09-25 21:18 ` Junio C Hamano
2012-09-25 0:25 ` [PATCH 3/3] add a "lua" pretty format Jeff King
2012-10-06 17:33 ` Jeff King
2012-09-25 11:22 ` [RFC/PATCH 0/3] git log --pretty=lua Nguyen Thai Ngoc Duy
2012-09-25 13:49 ` Stephen Bash
2012-09-25 15:19 ` Matthieu Moy
2012-09-25 16:40 ` Junio C Hamano
2012-09-30 4:31 ` Nguyen Thai Ngoc Duy
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: http://vger.kernel.org/majordomo-info.html
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20120925002511.GB19605@sigill.intra.peff.net \
--to=peff@peff.net \
--cc=git@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://80x24.org/mirrors/git.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).