Bläddra i källkod

Allow Kepler Syntax for Lua Server pages (part 2/?)

bel2125 7 år sedan
förälder
incheckning
6fe03865fe
1 ändrade filer med 128 tillägg och 8 borttagningar
  1. 128 8
      src/mod_lua.inl

+ 128 - 8
src/mod_lua.inl

@@ -360,8 +360,8 @@ lsp_abort(lua_State *L)
 
 struct lsp_var_reader_data {
 	const char *begin;
-	unsigned len;
-	unsigned state;
+	int64_t len;
+	int64_t state;
 };
 
 
@@ -402,6 +402,86 @@ lsp_var_reader(lua_State *L, void *ud, size_t *sz)
 }
 
 
+static const char *
+lsp_kepler_reader_impl(lua_State *L, void *ud, size_t *sz)
+{
+	struct lsp_var_reader_data *reader = (struct lsp_var_reader_data *)ud;
+	const char *ret;
+	int64_t i;
+	int64_t left;
+	char end[4];
+
+	(void)(L); /* unused */
+
+	/* This reader is called multiple times, to fetch the full Lua script */
+	if (reader->state == -1) {
+		/* First call: what function to call */
+		ret = "mg.write([=======[";
+		*sz = strlen(ret);
+		reader->state = 0;
+		return ret;
+	}
+	if (reader->state == -2) {
+		*sz = 0;
+		return 0;
+	}
+
+	left = reader->len - reader->state;
+	if (left == 0) {
+		ret = "]=======]);\n";
+		*sz = strlen(ret);
+		reader->state = -2;
+		return ret;
+	}
+	if (left > MG_BUF_LEN / 100) {
+		left = MG_BUF_LEN / 100; /* TODO XXX */
+	}
+	i = 0;
+
+forward:
+	while ((i < left) && (reader->begin[i + reader->state] != '<'))
+		i++;
+	if (i > 0) {
+		int64_t j = reader->state;
+		reader->state += i;
+		*sz = (size_t)i; /* cast is ok, i is limited to MG_BUF_LEN */
+		return reader->begin + j;
+	}
+
+	/* assert (reader->begin[reader->state] == '<') */
+	/* assert (i == 0) */
+	if (0 == memcmp(reader->begin, "<?lua", 5)) {
+		i = 5;
+	} else if (0 == memcmp(reader->begin, "<%", 2)) {
+		i = 2;
+	} else {
+		i = 1;
+		goto forward;
+	}
+
+	end[0] = reader->begin[1];
+	end[1] = '>';
+	end[2] = 0;
+	/* here we have a <?lua or <% tag */
+
+	ret = "]=======]);\n";
+	*sz = strlen(ret);
+
+	printf("XXX end\n");
+
+	reader->state = reader->len;
+	return ret;
+}
+
+static const char *
+lsp_kepler_reader(lua_State *L, void *ud, size_t *sz)
+{
+	/* debugging */
+	const char *ret = lsp_kepler_reader_impl(L, ud, sz);
+	printf("%.*s", *sz, ret);
+	return ret;
+}
+
 static int
 run_lsp(struct mg_connection *conn,
         const char *path,
@@ -409,18 +489,58 @@ run_lsp(struct mg_connection *conn,
         int64_t len,
         lua_State *L)
 {
+
+	int lua_ok;
+	struct lsp_var_reader_data data;
+	char date[64];
+	time_t curtime = time(NULL);
+
+	gmt_time_string(date, sizeof(date), &curtime);
+
+	conn->must_close = 1;
+	mg_printf(conn, "HTTP/1.1 200 OK\r\n");
+	send_no_cache_header(conn);
+	send_additional_header(conn);
+	mg_printf(conn,
+	          "Date: %s\r\n"
+	          "Connection: close\r\n"
+	          "Content-Type: text/html; charset=utf-8\r\n\r\n",
+	          date);
+
+	data.begin = p;
+	data.len = len;
+	data.state = -1;
+	lua_ok = mg_lua_load(L, lsp_kepler_reader, &data, path, NULL);
+
+	if (lua_ok) {
+		/* Syntax error or OOM.
+		 * Error message is pushed on stack. */
+		lua_pcall(L, 1, 0, 0);
+		printf("XXX err\n");
+		lua_cry(conn, lua_ok, L, "LSP", "execute"); /* XXX TODO: everywhere ! */
+
+	} else {
+		/* Success loading chunk. Call it. */
+		lua_pcall(L, 0, 0, 1);
+		printf("XXX succ\n");
+	}
+	return 0;
+}
+
+
+static int
+run_lsp_classic(struct mg_connection *conn,
+                const char *path,
+                const char *p,
+                int64_t len,
+                lua_State *L)
+{
 	int i, j, s, pos = 0, lines = 1, lualines = 0, is_var, lua_ok;
 	char chunkname[MG_BUF_LEN];
 	struct lsp_var_reader_data data;
 	const char lsp_mark1 = '?'; /* Use <? code ?> */
 	const char lsp_mark2 = '%'; /* Use <% code %> */
 
-	static void *sp = 0;
-	if (!sp)
-		sp = &i;
-	else
-		printf("stack: %lli", (int64_t)sp - (int64_t)&i);
-
 	for (i = 0; i < len; i++) {
 		if (p[i] == '\n') {
 			lines++;