Remove libauto3 that somehow escaped before.

Originally committed to SVN as r3198.
This commit is contained in:
Niels Martin Hansen 2009-07-23 00:22:57 +00:00
parent 98d909b361
commit 2fef9e3111
7 changed files with 0 additions and 1797 deletions

View file

@ -1,12 +0,0 @@
if HAVE_AUTO3_LUA
AM_CFLAGS = -DAUTO3LIB @LUA50_CFLAGS@
AM_LDFLAGS = @LUA50_LDFLAGS@
lib_LTLIBRARIES = libaegisub-auto3-2.2.la
libaegisub_auto3_2_2_la_SOURCES = auto3.c
noinst_HEADERS = auto3.h
endif
EXTRA_DIST= callables.c

View file

@ -1,18 +0,0 @@
Automation 3 support in Automation 4 needs to be built as a separate library,
to be able to have two versions of Lua side by side. This is required since
Automation 3, and especially scripts written for it, relies on the Lua 5.0
API.
Compiling on Windows
--------------------
If you are building on Windows, be aware that Microsoft Visual C++ 2005
(version 8) CAN NOT COMPILE LUA 5.0 CORRECTLY. While the build will succeed,
the built binaries are broken and do not work correctly.
You need to use Microsoft Visual C++ .NET 2003 (version 7.1) to build the
Windows version of this library. Other compilers might also work.
You should not need to build this DLL yourself even if you are building
Aegisub; just get one built on someone else. Unless, of course, you want to
hack the Auto3 code.

View file

@ -1,944 +0,0 @@
// Copyright (c) 2005, 2006, 2007, Niels Martin Hansen
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither the name of the Aegisub Group nor the names of its contributors
// may be used to endorse or promote products derived from this software
// without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// -----------------------------------------------------------------------------
//
// AEGISUB
//
// Website: http://aegisub.cellosoft.com
// Contact: mailto:jiifurusu@gmail.com
//
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "auto3.h"
// Win32 DLL entry point
#ifdef WIN32
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <wchar.h>
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
// TODO: Destroy any still-alive scripts/interpreters here on unload?
return TRUE;
}
#endif
struct script_reader_data {
FILE *f;
int isfirst;
#define SCRIPT_READER_BUFSIZE 512
char databuf[SCRIPT_READER_BUFSIZE];
};
static const char *script_reader_func(lua_State *L, void *data, size_t *size)
{
struct script_reader_data *self;
unsigned char *b;
FILE *f;
self = (struct script_reader_data *)(data);
b = (unsigned char *)self->databuf;
f = self->f;
if (feof(f)) {
*size = 0;
return NULL;
}
if (self->isfirst) {
self->isfirst = 0;
// check if file is sensible and maybe skip bom
if ((*size = fread(b, 1, 4, f)) == 4) {
if (b[0] == 0xEF && b[1] == 0xBB && b[2] == 0xBF) {
// got an utf8 file with bom
// nothing further to do, already skipped the bom
fseek(f, -1, SEEK_CUR);
} else {
// oops, not utf8 with bom
// check if there is some other BOM in place and complain if there is...
if ((b[0] == 0xFF && b[1] == 0xFE && b[2] == 0x00 && b[3] == 0x00) || // utf32be
(b[0] == 0x00 && b[1] == 0x00 && b[2] == 0xFE && b[3] == 0xFF) || // utf32le
(b[0] == 0xFF && b[1] == 0xFE) || // utf16be
(b[0] == 0xFE && b[1] == 0xFF) || // utf16le
(b[0] == 0x2B && b[1] == 0x2F && b[2] == 0x76) || // utf7
(b[0] == 0x00 && b[2] == 0x00) || // looks like utf16be
(b[1] == 0x00 && b[3] == 0x00)) { // looks like utf16le
// can't support these files
*size = 0;
self->isfirst = -1;
strcpy(self->databuf, "File is an unsupported UTF");
return NULL;
}
// assume utf8 without bom, and rewind file
fseek(f, 0, SEEK_SET);
}
} else {
// hmm, rather short file this...
// doesn't have a bom, assume it's just ascii/utf8 without bom
return self->databuf; // *size is already set
}
}
*size = fread(b, 1, SCRIPT_READER_BUFSIZE, f);
return self->databuf;
}
static int Auto3LuaLoad(lua_State *L, filename_t filename, const char *prettyname, char **error)
{
struct script_reader_data script_reader;
int res;
script_reader.f =
#ifdef WIN32
_wfopen(filename, L"rb");
#else
fopen(filename, "rb");
#endif
if (!script_reader.f) return -1;
script_reader.isfirst = 1;
res = lua_load(L, script_reader_func, &script_reader, prettyname);
fclose(script_reader.f);
if (res) {
*error = Auto3Strdup(lua_tostring(L, -1));
return res;
}
if (script_reader.isfirst == -1) {
// Signals we got a bad UTF
*error = Auto3Strdup(script_reader.databuf);
return -1;
}
return 0;
}
// Read the 'config' global and create config struct
static int Auto3ParseConfigData(lua_State *L, struct Auto3Interpreter *script, char **error)
{
struct Auto3ConfigOption *opt;
int i, n;
const char *tmp;
if (!lua_istable(L, -1)) {
// No 'config' table at all, just make the sentinel option
script->config = calloc(1, sizeof(struct Auto3ConfigOption));
return 0;
}
// Get expected number of elements in table
n = luaL_getn(L, -1);
// Allocate memory for max number of elements + 1
script->config = calloc(n+1, sizeof(struct Auto3ConfigOption));
// Prepare traversal
lua_pushnil(L);
opt = script->config;
// Get at most n options
i = 1;
while (lua_next(L, -2)) {
if (i > n) {
// More options than we have space for...
// Just ignore the extra options for now
lua_pop(L, 2);
break;
}
// Top of stack should be the next option living in a table
if (lua_istable(L, -1)) {
// get the "kind"
lua_pushstring(L, "kind");
lua_gettable(L, -2);
if (lua_isstring(L, -1)) {
// use C standard lib functions here, as it's probably faster than messing around with unicode
// lua is known to always properly null-terminate strings, and the strings are known to be pure ascii
tmp = lua_tostring(L, -1);
if (strcmp(tmp, "label") == 0) {
opt->kind = COK_LABEL;
} else if (strcmp(tmp, "text") == 0) {
opt->kind = COK_TEXT;
} else if (strcmp(tmp, "int") == 0) {
opt->kind = COK_INT;
} else if (strcmp(tmp, "float") == 0) {
opt->kind = COK_FLOAT;
} else if (strcmp(tmp, "bool") == 0) {
opt->kind = COK_BOOL;
} else if (strcmp(tmp, "colour") == 0) {
opt->kind = COK_COLOUR;
} else if (strcmp(tmp, "style") == 0) {
opt->kind = COK_STYLE;
} else {
opt->kind = COK_INVALID;
}
} else {
opt->kind = COK_INVALID;
}
// remove "kind" string from stack again
lua_pop(L, 1);
// no need to check for rest if this one is already deemed invalid
if (opt->kind != COK_INVALID) {
// name
lua_pushstring(L, "name");
lua_gettable(L, -2);
if (lua_isstring(L, -1)) {
opt->name = Auto3Strdup(lua_tostring(L, -1));
} else {
// name is required to be valid
opt->kind = COK_INVALID;
}
lua_pop(L, 1);
// label
lua_pushstring(L, "label");
lua_gettable(L, -2);
if (lua_isstring(L, -1)) {
opt->label = Auto3Strdup(lua_tostring(L, -1));
} else {
// label is also required
opt->kind = COK_INVALID;
}
lua_pop(L, 1);
// hint
lua_pushstring(L, "hint");
lua_gettable(L, -2);
if (lua_isstring(L, -1)) {
opt->hint = Auto3Strdup(lua_tostring(L, -1));
} else {
opt->hint = Auto3Strdup("");
}
lua_pop(L, 1);
// min
lua_pushstring(L, "min");
lua_gettable(L, -2);
if (lua_isnumber(L, -1)) {
opt->min.valid = 1;
opt->min.floatval = (float)lua_tonumber(L, -1);
opt->min.intval = (int)opt->min.floatval;
} else {
opt->min.valid = 0;
}
lua_pop(L, 1);
// max
lua_pushstring(L, "max");
lua_gettable(L, -2);
if (lua_isnumber(L, -1)) {
opt->max.valid = 1;
opt->max.floatval = (float)lua_tonumber(L, -1);
opt->max.intval = (int)opt->max.floatval;
} else {
opt->max.valid = 0;
}
lua_pop(L, 1);
// default
lua_pushstring(L, "default");
lua_gettable(L, -2);
switch (opt->kind) {
case COK_LABEL:
// nothing to do, nothing expected
break;
case COK_TEXT:
case COK_STYLE:
case COK_COLOUR:
// expect it to be a string
if (lua_isstring(L, -1)) {
opt->default_val.stringval = Auto3Strdup(lua_tostring(L, -1));
opt->value.stringval = Auto3Strdup(opt->default_val.stringval);
} else {
// not a string, baaaad scripter
opt->kind = COK_INVALID;
}
break;
case COK_INT:
// expect it to be a number
if (lua_isnumber(L, -1)) {
opt->default_val.intval = (int)lua_tonumber(L, -1);
opt->value.intval = opt->default_val.intval;
} else {
opt->kind = COK_INVALID;
}
break;
case COK_FLOAT:
// expect it to be a number
if (lua_isnumber(L, -1)) {
opt->default_val.floatval = (float)lua_tonumber(L, -1);
opt->value.floatval = opt->default_val.floatval;
} else {
opt->kind = COK_INVALID;
}
break;
case COK_BOOL:
// expect it to be a bool
if (lua_isboolean(L, -1)) {
opt->default_val.intval = lua_toboolean(L, -1);
opt->value.intval = opt->default_val.intval;
} else {
opt->kind = COK_INVALID;
}
break;
case COK_INVALID:
break;
}
lua_pop(L, 1);
}
// On to next structure to be filled
opt++;
}
// Remove option table from stack
lua_pop(L, 1);
// Such that the current key is on top, and we can get the next
}
// Remove 'config' table from stack
lua_pop(L, 1);
return 0;
}
// Keeping this file a bit shorter: put all functions called from Lua into a separate file
#define BUILDING_AUTO3_C
#include "callables.c"
// Create a new interpreter
AUTO3_API struct Auto3Interpreter *CreateAuto3Script(const filename_t filename, const char *prettyname, struct Auto3Callbacks *cb, char **error)
{
struct Auto3Interpreter *script;
lua_State *L;
script = malloc(sizeof(struct Auto3Interpreter));
if (!script) return NULL;
// Copy in callbacks
memcpy(&script->cb, cb, sizeof(struct Auto3Callbacks));
// Init Lua
script->L = lua_open();
if (!script->L) goto failearly;
L = script->L;
// register standard libs
lua_pushcfunction(L, luaopen_base); lua_call(L, 0, 0);
lua_pushcfunction(L, luaopen_string); lua_call(L, 0, 0);
lua_pushcfunction(L, luaopen_table); lua_call(L, 0, 0);
lua_pushcfunction(L, luaopen_math); lua_call(L, 0, 0);
// dofile and loadfile are replaced with include
lua_pushnil(L);
lua_setglobal(L, "dofile");
lua_pushnil(L);
lua_setglobal(L, "loadfile");
lua_pushlightuserdata(L, script);
lua_pushcclosure(L, LuaInclude, 1);
lua_setglobal(L, "include");
// reference to the script object
lua_pushlightuserdata(L, script);
// make "aegisub" table
lua_newtable(L);
// put helper functions in it
// colorstring_to_rgb is moved to utils.auto3
lua_pushstring(L, "text_extents");
lua_pushvalue(L, -3);
lua_pushcclosure(L, LuaTextExtents, 1);
lua_settable(L, -3);
lua_pushstring(L, "frame_from_ms");
lua_pushvalue(L, -3);
lua_pushcclosure(L, LuaFrameFromMs, 1);
lua_settable(L, -3);
lua_pushstring(L, "ms_from_frame");
lua_pushvalue(L, -3);
lua_pushcclosure(L, LuaMsFromFrame, 1);
lua_settable(L, -3);
lua_pushstring(L, "report_progress");
lua_pushvalue(L, -3);
lua_pushcclosure(L, LuaReportProgress, 1);
lua_settable(L, -3);
lua_pushstring(L, "output_debug");
lua_pushvalue(L, -3);
lua_pushcclosure(L, LuaOutputDebug, 1);
lua_settable(L, -3);
lua_pushstring(L, "set_status");
lua_pushvalue(L, -3);
lua_pushcclosure(L, LuaSetStatus, 1);
lua_settable(L, -3);
lua_pushstring(L, "lua_automation_version");
lua_pushnumber(L, 3);
lua_settable(L, -3);
// store table
lua_setglobal(L, "aegisub");
// remove ref to script object
lua_pop(L, 1);
// Read the script
if (Auto3LuaLoad(L, filename, prettyname, error)) {
// error is already filled
goto faillua;
}
// Execute the script
if (lua_pcall(L, 0, 0, 0)) {
*error = Auto3Strdup(lua_tostring(L, -1));
goto faillua;
}
// Script has been run, stuff exists in the global environment
lua_getglobal(L, "version");
if (!lua_isnumber(L, -1)) {
*error = Auto3Strdup("'version' value not found or not a number");
goto faillua;
}
if ((int)lua_tonumber(L, -1) != 3) {
// invalid version
*error = Auto3Strdup("'version' must be 3 for Automation 3 scripts");
goto faillua;
}
// skip 'kind', it's useless
// name
lua_getglobal(L, "name");
if (!lua_isstring(L, -1)) {
script->name = Auto3Strdup(prettyname);
} else {
script->name = Auto3Strdup(lua_tostring(L, -1));
}
// description (optional)
lua_getglobal(L, "description");
if (lua_isstring(L, -1)) {
script->description = Auto3Strdup(lua_tostring(L, -1));
} else {
script->description = Auto3Strdup("");
}
lua_pop(L, 3);
// Parse the config data
lua_getglobal(L, "configuration");
if (Auto3ParseConfigData(L, script, error)) {
goto faildescription;
}
return script;
// Various fail-cases
faildescription:
free(script->description);
free(script->name);
faillua:
lua_close(script->L);
failearly:
free(script);
return NULL;
}
// Release an interpreter
AUTO3_API void DestroyAuto3Script(struct Auto3Interpreter *script)
{
struct Auto3ConfigOption *opt;
// free the config data
opt = script->config;
while (opt->name) {
free(opt->name);
free(opt->label);
free(opt->hint);
if (opt->kind == COK_TEXT || opt->kind == COK_COLOUR || opt->kind == COK_STYLE) {
free(opt->default_val.stringval);
free(opt->value.stringval);
}
opt++;
}
free(script->config);
// free the rest
free(script->description);
free(script->name);
lua_close(script->L);
free(script);
}
// Our "malloc" function, allocate memory for strings with this
AUTO3_API void *Auto3Malloc(size_t amount)
{
return malloc(amount);
}
// Convenience function, use this for duplicating strings this lib should own
AUTO3_API char *Auto3Strdup(const char *str)
{
#if _MSC_VER >= 1400
// MS Visual C++ 2004 or newer
return _strdup(str);
#else
return strdup(str);
#endif
}
// Our "free" function, free generated error messages with this
AUTO3_API void Auto3Free(void *ptr)
{
free(ptr);
}
static void MakeMetaInfoTable(lua_State *L, struct Auto3Interpreter *script)
{
int res_x, res_y;
script->cb.get_meta_info(script->cb.rwdata, &res_x, &res_y);
lua_newtable(L);
lua_pushstring(L, "res_x");
lua_pushnumber(L, res_x);
lua_settable(L, -3);
lua_pushstring(L, "res_y");
lua_pushnumber(L, res_y);
lua_settable(L, -3);
}
static void MakeStylesTable(lua_State *L, struct Auto3Interpreter *script)
{
char *name, *fontname, *color1, *color2, *color3, *color4;
int fontsize, bold, italic, underline, strikeout, borderstyle, align, margin_l, margin_r, margin_v, encoding;
float scale_x, scale_y, spacing, angle, outline, shadow;
int n;
lua_newtable(L);
n = -1;
script->cb.reset_style_pointer(script->cb.rwdata);
while (script->cb.get_next_style(script->cb.rwdata, &name, &fontname, &fontsize, &color1, &color2, &color3, &color4,
&bold, &italic, &underline, &strikeout, &scale_x, &scale_y, &spacing, &angle, &borderstyle, &outline,
&shadow, &align, &margin_l, &margin_r, &margin_v, &encoding)) {
n++;
// Got a style...
lua_pushstring(L, name); // name for table index
lua_newtable(L);
// Set properties
lua_pushstring(L, "name");
lua_pushstring(L, name);
lua_settable(L, -3);
lua_pushstring(L, "fontname");
lua_pushstring(L, fontname);
lua_settable(L, -3);
lua_pushstring(L, "fontsize");
lua_pushnumber(L, fontsize);
lua_settable(L, -3);
lua_pushstring(L, "color1");
lua_pushstring(L, color1);
lua_settable(L, -3);
lua_pushstring(L, "color2");
lua_pushstring(L, color2);
lua_settable(L, -3);
lua_pushstring(L, "color3");
lua_pushstring(L, color3);
lua_settable(L, -3);
lua_pushstring(L, "color4");
lua_pushstring(L, color4);
lua_settable(L, -3);
lua_pushstring(L, "bold");
lua_pushboolean(L, bold);
lua_settable(L, -3);
lua_pushstring(L, "italic");
lua_pushboolean(L, italic);
lua_settable(L, -3);
lua_pushstring(L, "underline");
lua_pushboolean(L, underline);
lua_settable(L, -3);
lua_pushstring(L, "strikeout");
lua_pushboolean(L, strikeout);
lua_settable(L, -3);
lua_pushstring(L, "scale_x");
lua_pushnumber(L, scale_x);
lua_settable(L, -3);
lua_pushstring(L, "scale_y");
lua_pushnumber(L, scale_y);
lua_settable(L, -3);
lua_pushstring(L, "spacing");
lua_pushnumber(L, spacing);
lua_settable(L, -3);
lua_pushstring(L, "angle");
lua_pushnumber(L, angle);
lua_settable(L, -3);
lua_pushstring(L, "borderstyle");
lua_pushnumber(L, borderstyle);
lua_settable(L, -3);
lua_pushstring(L, "outline");
lua_pushnumber(L, outline);
lua_settable(L, -3);
lua_pushstring(L, "shadow");
lua_pushnumber(L, shadow);
lua_settable(L, -3);
lua_pushstring(L, "align");
lua_pushnumber(L, align);
lua_settable(L, -3);
lua_pushstring(L, "margin_l");
lua_pushnumber(L, margin_l);
lua_settable(L, -3);
lua_pushstring(L, "margin_r");
lua_pushnumber(L, margin_r);
lua_settable(L, -3);
lua_pushstring(L, "margin_v");
lua_pushnumber(L, margin_v);
lua_settable(L, -3);
lua_pushstring(L, "encoding");
lua_pushnumber(L, encoding);
lua_settable(L, -3);
// Store to numeric index
lua_pushnumber(L, n);
lua_pushvalue(L, -2); // extra copy of table
lua_settable(L, -5);
// And named index
lua_settable(L, -3);
}
// Finally, make -1 key in table (because the name 'n' might clash with a style name)
lua_pushnumber(L, -1);
lua_pushnumber(L, n);
lua_settable(L, -3);
}
static void MakeEventsTable(lua_State *L, struct Auto3Interpreter *script)
{
int layer, start_time, end_time, margin_l, margin_r, margin_v, comment;
char *style, *actor, *effect, *text;
int n;
lua_newtable(L);
n = -1;
script->cb.reset_subs_pointer(script->cb.rwdata);
while (script->cb.get_next_sub(script->cb.rwdata, &layer, &start_time, &end_time, &style, &actor,
&margin_l, &margin_r, &margin_v, &effect, &text, &comment)) {
n++;
// Got a line...
lua_pushnumber(L, n);
lua_newtable(L);
lua_pushstring(L, "kind");
if (comment)
lua_pushstring(L, "comment");
else
lua_pushstring(L, "dialogue");
lua_settable(L, -3);
lua_pushstring(L, "layer");
lua_pushnumber(L, layer);
lua_settable(L, -3);
lua_pushstring(L, "start_time");
lua_pushnumber(L, start_time);
lua_settable(L, -3);
lua_pushstring(L, "end_time");
lua_pushnumber(L, end_time);
lua_settable(L, -3);
lua_pushstring(L, "style");
lua_pushstring(L, style);
lua_settable(L, -3);
lua_pushstring(L, "name");
lua_pushstring(L, actor);
lua_settable(L, -3);
lua_pushstring(L, "margin_l");
lua_pushnumber(L, margin_l);
lua_settable(L, -3);
lua_pushstring(L, "margin_r");
lua_pushnumber(L, margin_r);
lua_settable(L, -3);
lua_pushstring(L, "margin_v");
lua_pushnumber(L, margin_v);
lua_settable(L, -3);
lua_pushstring(L, "effect");
lua_pushstring(L, effect);
lua_settable(L, -3);
lua_pushstring(L, "text");
lua_pushstring(L, text);
lua_settable(L, -3);
// No parsing karaoke data here, that can just as well be done in Lua code
// Store at numeric index
lua_settable(L, -3);
}
// Finally, make 'n' key in table
lua_pushstring(L, "n");
lua_pushnumber(L, n+1);
lua_settable(L, -3);
}
static void MakeConfigSettingsTable(lua_State *L, struct Auto3Interpreter *script)
{
struct Auto3ConfigOption *opt;
lua_newtable(L);
opt = script->config;
while (opt->name) {
lua_pushstring(L, opt->name);
switch (opt->kind) {
case COK_TEXT:
case COK_STYLE:
case COK_COLOUR:
lua_pushstring(L, opt->value.stringval);
break;
case COK_INT:
lua_pushnumber(L, opt->value.intval);
break;
case COK_FLOAT:
lua_pushnumber(L, opt->value.floatval);
break;
case COK_BOOL:
lua_pushboolean(L, opt->value.intval);
break;
default:
lua_pushnil(L);
break;
}
lua_settable(L, -3);
opt++;
}
}
static void ReadBackSubs(lua_State *L, struct Auto3Interpreter *script)
{
int layer, start_time, end_time, margin_l, margin_r, margin_v, comment;
const char *style, *actor, *effect, *text, *kind;
int i, n;
script->cb.start_subs_write(script->cb.rwdata);
i = 0;
n = luaL_getn(L, -1);
while (i <= n) {
// Assume n is always correct, this is not entirely compatible
lua_rawgeti(L, -1, i);
if (script->cb.set_progress) script->cb.set_progress(script->cb.logdata, 100.f * i / n);
i++;
if (!lua_istable(L, -1)) {
lua_pop(L, 1);
continue;
}
lua_pushstring(L, "kind");
lua_gettable(L, -2);
if (!lua_isstring(L, -1)) {
lua_pop(L, 2);
continue;
}
kind = lua_tostring(L, -1);
// leave kind on stack so it won't be gc'd
// Make comment rather tell if this is a "non-dialogue" line
comment = strcmp(kind, "dialogue");
// then test if it's a dialogue line (not non-dialogue) or is an actual comment
if (!comment || strcmp(kind, "comment")) {
lua_pushstring(L, "layer");
lua_gettable(L, -3);
lua_pushstring(L, "start_time");
lua_gettable(L, -4);
lua_pushstring(L, "end_time");
lua_gettable(L, -5);
lua_pushstring(L, "style");
lua_gettable(L, -6);
lua_pushstring(L, "name");
lua_gettable(L, -7);
lua_pushstring(L, "margin_l");
lua_gettable(L, -8);
lua_pushstring(L, "margin_r");
lua_gettable(L, -9);
lua_pushstring(L, "margin_v");
lua_gettable(L, -10);
lua_pushstring(L, "effect");
lua_gettable(L, -11);
lua_pushstring(L, "text");
lua_gettable(L, -12);
if (lua_isnumber(L, -10) && lua_isnumber(L, -9) && lua_isnumber(L, -8) &&
lua_isstring(L, -7) && lua_isstring(L, -6) && lua_isnumber(L, -5) &&
lua_isnumber(L, -4) && lua_isnumber(L, -3) && lua_isstring(L, -2) &&
lua_isstring(L, -1)) {
layer = (int)lua_tonumber(L, -10);
start_time = (int)lua_tonumber(L, -9);
end_time = (int)lua_tonumber(L, -8);
style = lua_tostring(L, -7);
actor = lua_tostring(L, -6);
margin_l = (int)lua_tonumber(L, -5);
margin_r = (int)lua_tonumber(L, -4);
margin_v = (int)lua_tonumber(L, -3);
effect = lua_tostring(L, -2);
text = lua_tostring(L, -1);
script->cb.write_sub(script->cb.rwdata, layer, start_time, end_time, style, actor,
margin_l, margin_r, margin_v, effect, text, comment);
} else {
if (script->cb.log_error) script->cb.log_error(script->cb.logdata, "Skipping output line with invalid fields");
}
lua_pop(L, 10);
}
lua_pop(L, 2); // pop line and 'kind'
}
}
// Start the script execution
AUTO3_API int RunAuto3Script(struct Auto3Interpreter *script)
{
lua_State *L;
L = script->L;
if (script->cb.set_status) script->cb.set_status(script->cb.logdata, "Preparing subtitle data");
if (script->cb.set_progress) script->cb.set_progress(script->cb.logdata, 0);
// first put the function itself on the stack
lua_getglobal(L, "process_lines");
// now put the four arguments on the stack
MakeMetaInfoTable(L, script);
MakeStylesTable(L, script);
MakeEventsTable(L, script);
MakeConfigSettingsTable(L, script);
// do the actual call
if (script->cb.set_status) script->cb.set_status(script->cb.logdata, "Running script");
if (lua_pcall(L, 4, 1, 0)) {
if (script->cb.log_error) {
script->cb.log_error(script->cb.logdata, "Runtime error in script:");
script->cb.log_error(script->cb.logdata, lua_tostring(L, -1));
}
return -1;
}
// Check for initial sanity
if (!lua_istable(L, -1)) {
if (script->cb.log_error) script->cb.log_error(script->cb.logdata, "Script did not return a table, unable to process result");
}
// Read back subtitles
if (script->cb.set_status) script->cb.set_status(script->cb.logdata, "Reading back subtitle data");
if (script->cb.set_progress) script->cb.set_progress(script->cb.logdata, 0);
ReadBackSubs(L, script);
// Finished
if (script->cb.set_progress) script->cb.set_progress(script->cb.logdata, 100);
return 0;
}

View file

@ -1,225 +0,0 @@
// Copyright (c) 2007, Niels Martin Hansen
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither the name of the Aegisub Group nor the names of its contributors
// may be used to endorse or promote products derived from this software
// without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// -----------------------------------------------------------------------------
//
// AEGISUB
//
// Website: http://aegisub.cellosoft.com
// Contact: mailto:jiifurusu@gmail.com
//
#pragma once
#include <stdlib.h>
#ifdef AUTO3LIB
#include <lua.h>
#include <lualib.h>
#include <lauxlib.h>
#endif
#ifdef __cplusplus
extern "C" {
#endif
// On Win32, filenames are wide, but whatever encoding the system uses everywhere else
#ifdef WIN32
typedef wchar_t* filename_t;
#else
typedef char* filename_t;
#endif
// All other strings involved are UTF-8, no need to do conversion back and forth here
// So just hardcode char* as type for everything else
#ifndef AUTO3LIB
// Definitions used when building Aegisub (ie. importing the symbols)
// I believe GCC also knows about __declspec(dllimport) etc. and does something sensible with it
# ifdef _MSC_VER
# define AUTO3_API __declspec(dllimport)
# else
# define AUTO3_API
# endif
#else
// Otherwise we're exporting the symbols
# ifdef _MSC_VER
# define AUTO3_API __declspec(dllexport)
# else
# define AUTO3_API
# endif
#endif
// Stuff for configuration dialogs
enum Auto3ConfigOptionKind {
COK_INVALID = 0,
COK_LABEL, // static text
COK_TEXT, // textbox
COK_INT, // integer entry, should get spin-button is possible
COK_FLOAT, // float entry, also try for spin-button on this
COK_BOOL, // bool entry, use a checkbox
COK_COLOUR, // colour entry, use a picker if possible, otherwise text box
COK_STYLE // style name, listbox with names of styles defined in subs
};
struct Auto3ConfigOption {
char *name;
enum Auto3ConfigOptionKind kind;
char *label;
char *hint;
struct {
int valid; // non-zero if the value is present
int intval;
float floatval;
} min, max;
union {
char *stringval; // text, colour (vb-hex style-line format), style
int intval; // also bool, nonzero is true
float floatval;
} default_val, value;
};
// Callback interface
// The application should provide ALL of these functions
struct Auto3Callbacks {
// Logging and status
// pointer passed to logging/status callbacks
void *logdata;
// log error during script execution
void (*log_error)(void *cbdata, const char *msg);
// log message during script execution
void (*log_message)(void *cbdata, const char *msg);
// set progress during script execution
void (*set_progress)(void *cbdata, float progress);
// set status message during script execution
void (*set_status)(void *cbdata, const char* msg);
// Reading/writing subtitles and related information
// pointer passed to read/write data callbacks
void *rwdata;
// application sets *res_x and *res_y to appropriate values
void (*get_meta_info)(void *cbdata, int *res_x, int *res_y);
// set style pointer to point at first style
void (*reset_style_pointer)(void *cbdata);
// Get the next style, the application must fill the data into its own buffers, which it then fill in pointers to
// (Ie. the application owns all strings allocated for this callback.)
// Return non-zero if a style was found and values filled, otherwise return zero
int (*get_next_style)(
void *cbdata, char **name, char **fontname, int *fontsize, char **color1, char **color2, char **color3, char **color4,
int *bold, int *italic, int *underline, int *strikeout, float *scale_x, float *scale_y, float *spacing, float *angle,
int *borderstyle, float *outline, float *shadow, int *align, int *margin_l, int *margin_r, int *margin_v, int *encoding);
// set subtitle pointer to point at first subtitle line
void (*reset_subs_pointer)(void *cbdata);
// Get next subtitle line, the application must fill the data into its own buffers, and then fill in pointers to those
// Return non-zero if a style was found and values filled, otherwise return zero
int (*get_next_sub)(
void *cbdata, int *layer, int *start_time, int *end_time, char **style, char **actor,
int *margin_l, int *margin_r, int *margin_v, char **effect, char **text, int *comment);
// start writing back new subtitles, application must clear all subtitle lines and be ready to write
void (*start_subs_write)(void *cbdata);
// Write a subtitle line back to subtitle file, char pointers are owned by the lib
void (*write_sub)(void *cbdata, int layer, int start_time, int end_time, const char *style, const char *actor,
int margin_l, int margin_r, int margin_v, const char *effect, const char *text, int comment);
// Getting various environment information during runtime
// pointer passed to runtime data callbacks
void *rundata;
// Resolve a filename passed to the include function
// The result must be allocated with Auto3Malloc and will be free'd by the lib
filename_t (*resolve_include)(void *cbdata, const char *incname);
// Get sizing information for a text string given a style
void (*text_extents)(void *cbdata, const char *text, const char *fontname, int fontsize, int bold, int italic,
int spacing, float scale_x, float scale_y, int encoding,
float *out_width, float *out_height, float *out_descent, float *out_extlead);
// Convert a time in milliseconds to a video frame number
int (*frame_from_ms)(void *cbdata, int ms);
// Convert a video frame number to a time in milliseconds
int (*ms_from_frame)(void *cbdata, int frame);
};
// Describes an interpreter
struct Auto3Interpreter {
// Public attributes, treat them as read-only
char *name;
char *description;
// Configuration dialog options
// End of list marked with name==NULL
// You may change the "value" field of these (in fact, do so)
struct Auto3ConfigOption *config;
// Callbacks
// This is filled in from the 'cb' argument to the Create function,
// but may be modified later by the application
struct Auto3Callbacks cb;
#ifdef AUTO3LIB
// Private data
lua_State *L;
#endif
};
// Create a new interpreter
// filename is name of script file
// prettyname is a UTF-8 string used as identifier for the script in error messages
// cb should point to an Auto3Callbacks struct filled in; a copy of this struct will be made
// error will be filled with any error message on fail, the application is responsible for freeing this string (use Auto3Free)
// Returns pointer to interpreter object if successful, otherwise NULL
AUTO3_API struct Auto3Interpreter *CreateAuto3Script(const filename_t filename, const char *prettyname, struct Auto3Callbacks *cb, char **error);
// Release an interpreter
AUTO3_API void DestroyAuto3Script(struct Auto3Interpreter *script);
// Our "malloc" function, allocate memory for strings with this
AUTO3_API void *Auto3Malloc(size_t amount);
// Convenience function, use this for duplicating strings this lib should own
AUTO3_API char *Auto3Strdup(const char *str);
// Our "free" function, free strings with this
AUTO3_API void Auto3Free(void *ptr);
// Start the script execution
// script->logcbdata and log->rwcbdata should be set to sensible values before this call.
// The value fields in the config dialog should also be set to values entered by the user here.
// This will first call get_meta_info,
// then reset_style pointer followed by a number of calls to get_next_style,
// then a call to reset_subs_pointer followed by a number of calls to get_next_sub,
// then actual processing will take place.
// After processing, start_subs_write will be called, followed by a number of calls to write_sub.
// Any number of calls to the logging/status functions can take place during script execution
// Returns non-zero on error
AUTO3_API int RunAuto3Script(struct Auto3Interpreter *script);
#ifdef __cplusplus
}; // extern "C"
#endif

View file

@ -1,375 +0,0 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="9.00"
Name="auto3_vc9"
ProjectGUID="{F57D079E-3022-40FA-9BC9-C149D89D9EC9}"
RootNamespace="auto3_vc9"
Keyword="Win32Proj"
TargetFrameworkVersion="196613"
>
<Platforms>
<Platform
Name="Win32"
/>
<Platform
Name="x64"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
ConfigurationType="2"
InheritedPropertySheets="..\..\build\aegisub_vs2008\suffix_debug32.vsprops;..\..\build\aegisub_vs2008\libraries_outdirs.vsprops;.\auto3_vc9.vsprops"
CharacterSet="0"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;AUTO3_VC9_EXPORTS"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
WarningLevel="3"
DebugInformationFormat="4"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
LinkIncremental="2"
GenerateDebugInformation="true"
SubSystem="2"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
ConfigurationType="2"
InheritedPropertySheets="..\..\build\aegisub_vs2008\suffix_release32.vsprops;..\..\build\aegisub_vs2008\libraries_outdirs.vsprops;.\auto3_vc9.vsprops"
CharacterSet="0"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
EnableIntrinsicFunctions="true"
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;AUTO3_VC9_EXPORTS"
RuntimeLibrary="2"
EnableFunctionLevelLinking="true"
WarningLevel="3"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
LinkIncremental="1"
GenerateDebugInformation="true"
SubSystem="2"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Debug|x64"
ConfigurationType="2"
InheritedPropertySheets="..\..\build\aegisub_vs2008\suffix_debug64.vsprops;..\..\build\aegisub_vs2008\libraries_outdirs.vsprops;.\auto3_vc9.vsprops"
CharacterSet="0"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
TargetEnvironment="3"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;AUTO3_VC9_EXPORTS"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
WarningLevel="3"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
LinkIncremental="2"
GenerateDebugInformation="true"
SubSystem="2"
TargetMachine="17"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|x64"
ConfigurationType="2"
InheritedPropertySheets="..\..\build\aegisub_vs2008\suffix_release64.vsprops;..\..\build\aegisub_vs2008\libraries_outdirs.vsprops;.\auto3_vc9.vsprops"
CharacterSet="0"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
TargetEnvironment="3"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
EnableIntrinsicFunctions="true"
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;AUTO3_VC9_EXPORTS"
RuntimeLibrary="2"
EnableFunctionLevelLinking="true"
WarningLevel="3"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
LinkIncremental="1"
GenerateDebugInformation="true"
SubSystem="2"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="17"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
>
<File
RelativePath=".\auto3.c"
>
</File>
<File
RelativePath=".\callables.c"
>
<FileConfiguration
Name="Debug|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|x64"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|x64"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
>
<File
RelativePath=".\auto3.h"
>
</File>
</Filter>
<Filter
Name="Resource Files"
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View file

@ -1,16 +0,0 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioPropertySheet
ProjectType="Visual C++"
Version="8.00"
Name="auto3_vc9"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="$(ProjectDir)../../../contrib/lua50/include/"
PreprocessorDefinitions="_CRT_SECURE_NO_WARNINGS;AUTO3LIB"
/>
<Tool
Name="VCLinkerTool"
OutputFile="$(ExecutableOutDir)/libauto3_$(PlatformConfigSuffix).dll"
/>
</VisualStudioPropertySheet>

View file

@ -1,207 +0,0 @@
// Copyright (c) 2005, 2006, 2007, Niels Martin Hansen
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither the name of the Aegisub Group nor the names of its contributors
// may be used to endorse or promote products derived from this software
// without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// -----------------------------------------------------------------------------
//
// AEGISUB
//
// Website: http://aegisub.cellosoft.com
// Contact: mailto:jiifurusu@gmail.com
//
// DO NOT compile this file separately! It's included as part of auto3.c
#ifndef BUILDING_AUTO3_C
# error callables.c can not be compiled separately. It is included as part of auto3.c.
#endif
static struct Auto3Interpreter* GetScriptObject(lua_State *L)
{
return (struct Auto3Interpreter *)lua_touserdata(L, lua_upvalueindex(1));
}
static int LuaInclude(lua_State *L)
{
filename_t filename;
const char *incname;
char *error;
struct Auto3Interpreter *script;
script = GetScriptObject(L);
if (!script->cb.resolve_include) {
lua_pushstring(L, "Attempt to use include, but not implemented by host application");
lua_error(L);
}
incname = luaL_checkstring(L, 1);
filename = script->cb.resolve_include(script->cb.rundata, incname);
if (filename) {
// Load include
if (Auto3LuaLoad(L, filename, incname, &error)) {
free(filename);
lua_pushfstring(L, "Failed to include file '%s', error: %s", incname, error);
lua_error(L);
}
// Run include (don't protect, we're already in a protected environment, we'd just propagate it anyway)
lua_call(L, 0, 0);
free(filename);
} else {
lua_pushfstring(L, "Failed to resolve include file '%s'", incname);
lua_error(L);
}
// Not really compatible, but I don't think anyone have ever exploited that includes can return stuff
return 0;
}
static int LuaTextExtents(lua_State *L)
{
struct Auto3Interpreter *script;
const char *text, *fontname;
int fontsize, bold, italic, spacing, encoding;
float scale_x, scale_y;
float out_width, out_height, out_descent, out_extlead;
script = GetScriptObject(L);
if (!script->cb.text_extents) return 0;
// get text
text = luaL_checkstring(L, 2);
// check we have style table
if (!lua_istable(L, 1)) {
lua_pushstring(L, "First argument to text_extents must be style table");
lua_error(L);
}
// get style def
lua_pushstring(L, "fontname"); lua_gettable(L, 1);
fontname = lua_tostring(L, -1);
lua_pushstring(L, "fontsize"); lua_gettable(L, 1);
fontsize = (int)lua_tonumber(L, -1);
lua_pushstring(L, "bold"); lua_gettable(L, 1);
bold = lua_toboolean(L, -1);
lua_pushstring(L, "italic"); lua_gettable(L, 1);
italic = lua_toboolean(L, -1);
lua_pushstring(L, "scale_x"); lua_gettable(L, 1);
scale_x = (float)lua_tonumber(L, -1);
lua_pushstring(L, "scale_y"); lua_gettable(L, 1);
scale_y = (float)lua_tonumber(L, -1);
lua_pushstring(L, "spacing"); lua_gettable(L, 1);
spacing = (int)lua_tonumber(L, -1);
lua_pushstring(L, "encoding"); lua_gettable(L, 1);
encoding = (int)lua_tonumber(L, -1);
// get measurements
script->cb.text_extents(script->cb.rundata, text, fontname, fontsize, bold, italic,
spacing, scale_x, scale_y, encoding, &out_width, &out_height, &out_descent, &out_extlead);
// remove strings and stuff
lua_pop(L, 8);
// return result
lua_pushnumber(L, out_width);
lua_pushnumber(L, out_height);
lua_pushnumber(L, out_descent);
lua_pushnumber(L, out_extlead);
return 4;
}
static int LuaFrameFromMs(lua_State *L)
{
int frame;
struct Auto3Interpreter *script;
script = GetScriptObject(L);
if (!script->cb.frame_from_ms) return 0;
frame = script->cb.frame_from_ms(script->cb.rundata, luaL_checkint(L, 1));
lua_pushnumber(L, frame);
return 1;
}
static int LuaMsFromFrame(lua_State *L)
{
int ms;
struct Auto3Interpreter *script;
script = GetScriptObject(L);
if (!script->cb.ms_from_frame) return 0;
ms = script->cb.ms_from_frame(script->cb.rundata, luaL_checkint(L, 1));
lua_pushnumber(L, ms);
return 1;
}
static int LuaReportProgress(lua_State *L)
{
struct Auto3Interpreter *script;
script = GetScriptObject(L);
if (script->cb.set_progress) script->cb.set_progress(script->cb.logdata, (float)luaL_checknumber(L, 1));
return 0;
}
static int LuaOutputDebug(lua_State *L)
{
struct Auto3Interpreter *script;
script = GetScriptObject(L);
if (script->cb.log_message) script->cb.log_message(script->cb.logdata, luaL_checkstring(L, 1));
return 0;
}
static int LuaSetStatus(lua_State *L)
{
struct Auto3Interpreter *script;
script = GetScriptObject(L);
if (script->cb.set_status) script->cb.set_status(script->cb.logdata, luaL_checkstring(L, 1));
return 0;
}