Removed the incomplete support for the Lua extensions.

This commit is contained in:
Federico Hernandez 2013-04-02 21:52:13 +02:00
parent c7df1f7acc
commit 7db5377d3b
27 changed files with 17 additions and 928 deletions

View file

@ -1,258 +0,0 @@
////////////////////////////////////////////////////////////////////////////////
// Taskwarrior Lua API
//
// Copyright 2006-2013, Paul Beckingham, Federico Hernandez.
// Copyright © 19942008 Lua.org, PUC-Rio.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
// http://www.opensource.org/licenses/mit-license.php
////////////////////////////////////////////////////////////////////////////////
#define L10N // Localization complete.
#include <algorithm>
#include <iostream>
#include <Context.h>
#include <API.h>
#include <text.h>
#include <i18n.h>
extern Context context;
#ifdef HAVE_LIBLUA
////////////////////////////////////////////////////////////////////////////////
static int api_task_header_message (lua_State* L)
{
std::string message = luaL_checkstring (L, 1);
context.header (message);
return 0;
}
////////////////////////////////////////////////////////////////////////////////
static int api_task_footnote_message (lua_State* L)
{
std::string message = luaL_checkstring (L, 1);
context.footnote (message);
return 0;
}
////////////////////////////////////////////////////////////////////////////////
static int api_task_debug_message (lua_State* L)
{
std::string message = luaL_checkstring (L, 1);
context.debug (message);
return 0;
}
////////////////////////////////////////////////////////////////////////////////
// Causes the shell mode task to exit. Ordinarily this does not occur.
static int api_task_exit (lua_State*)
{
// TODO Is this the correct exception? How does the shell handle this?
std::cout << STRING_API_EXITING << std::endl;
exit (0);
return 0;
}
////////////////////////////////////////////////////////////////////////////////
// DOM reads.
static int api_task_get (lua_State* L)
{
std::string name = luaL_checkstring (L, 1);
try
{
lua_pushstring (L, context.dom.get (name).c_str ());
}
catch (...)
{
// TODO Error!
lua_pushstring (L, "");
}
return 1; // 1 returned value.
}
////////////////////////////////////////////////////////////////////////////////
// DOM writes.
static int api_task_set (lua_State* L)
{
std::string name = luaL_checkstring (L, 1);
std::string value = luaL_checkstring (L, 2);
try
{
context.dom.set (name, value);
}
catch (...)
{
// TODO Error!
lua_pushstring (L, "");
}
return 0;
}
////////////////////////////////////////////////////////////////////////////////
API::API ()
: _state (NULL)
{
}
////////////////////////////////////////////////////////////////////////////////
API::~API ()
{
if (_state)
{
lua_close (_state);
_state = NULL;
}
}
////////////////////////////////////////////////////////////////////////////////
void API::initialize ()
{
// Initialize Lua.
_state = luaL_newstate ();
luaL_openlibs (_state); // TODO Error handling
// Register all the API functions in Lua global space.
lua_pushcfunction (_state, api_task_header_message); lua_setglobal (_state, "task_header_message");
lua_pushcfunction (_state, api_task_footnote_message); lua_setglobal (_state, "task_footnote_message");
lua_pushcfunction (_state, api_task_debug_message); lua_setglobal (_state, "task_debug_message");
lua_pushcfunction (_state, api_task_exit); lua_setglobal (_state, "task_exit");
lua_pushcfunction (_state, api_task_get); lua_setglobal (_state, "task_get");
lua_pushcfunction (_state, api_task_set); lua_setglobal (_state, "task_set");
}
////////////////////////////////////////////////////////////////////////////////
bool API::callProgramHook (
const std::string& file,
const std::string& function)
{
loadFile (file);
// Get function.
lua_getglobal (_state, function.c_str ());
if (!lua_isfunction (_state, -1))
{
lua_pop (_state, 1);
throw format (STRING_API_NOFUNC, function);
}
// Make call.
if (lua_pcall (_state, 0, 2, 0) != 0)
throw format (STRING_API_ERROR_CALLING, function, lua_tostring (_state, -1));
// Call successful - get return values.
if (!lua_isnumber (_state, -2))
throw format (STRING_API_ERROR_FAIL, function);
if (!lua_isstring (_state, -1) && !lua_isnil (_state, -1))
throw format (STRING_API_ERROR_NORET, function);
int rc = lua_tointeger (_state, -2);
const char* message = lua_tostring (_state, -1);
if (rc == 0)
{
if (message)
context.footnote (format (STRING_API_WARNING, message));
}
else
{
if (message)
throw std::string (message);
}
lua_pop (_state, 1);
return rc == 0 ? true : false;
}
////////////////////////////////////////////////////////////////////////////////
bool API::callTaskHook (
const std::string& file,
const std::string& function,
Task& task)
{
loadFile (file);
// Save the task for reference via the API.
_current = task;
// Get function.
lua_getglobal (_state, function.c_str ());
if (!lua_isfunction (_state, -1))
{
lua_pop (_state, 1);
throw format (STRING_API_NOFUNC, function);
}
// Prepare args.
lua_pushnumber (_state, _current.id);
// Make call.
if (lua_pcall (_state, 1, 2, 0) != 0)
throw format (STRING_API_ERROR_CALLING, function, lua_tostring (_state, -1));
// Call successful - get return values.
if (!lua_isnumber (_state, -2))
throw format (STRING_API_ERROR_FAIL, function);
if (!lua_isstring (_state, -1) && !lua_isnil (_state, -1))
throw format (STRING_API_ERROR_NORET, function);
int rc = lua_tointeger (_state, -2);
const char* message = lua_tostring (_state, -1);
if (rc == 0)
{
if (message)
context.footnote (format (STRING_API_WARNING, message));
}
else
{
if (message)
throw std::string (message);
}
lua_pop (_state, 1);
return rc == 0 ? true : false;
}
////////////////////////////////////////////////////////////////////////////////
void API::loadFile (const std::string& file)
{
// If the file is not loaded.
if (std::find (_loaded.begin (), _loaded.end (), file) == _loaded.end ())
{
// Load the file, if possible.
if (luaL_loadfile (_state, file.c_str ()) || lua_pcall (_state, 0, 0, 0))
throw format (STRING_API_ERROR, lua_tostring (_state, -1));
// Mark this as _loaded, so as to not bother again.
_loaded.push_back (file);
}
}
////////////////////////////////////////////////////////////////////////////////
#endif

View file

@ -1,74 +0,0 @@
////////////////////////////////////////////////////////////////////////////////
// Taskwarrior Lua API
//
// Copyright 2006-2013, Paul Beckingham, Federico Hernandez.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
// http://www.opensource.org/licenses/mit-license.php
//
////////////////////////////////////////////////////////////////////////////////
#ifndef INCLUDED_API
#define INCLUDED_API
#define L10N // Localization complete.
#include <cmake.h>
#ifdef HAVE_LIBLUA
#include <vector>
#include <string>
#include <Task.h>
extern "C"
{
#include <lua.h>
#include <lualib.h>
#include <lauxlib.h>
}
class API
{
public:
API ();
API (const API&);
API& operator= (const API&);
~API ();
void initialize ();
bool callProgramHook (const std::string&, const std::string&);
bool callTaskHook (const std::string&, const std::string&, Task&);
private:
void loadFile (const std::string&);
public:
lua_State* _state;
std::vector <std::string> _loaded;
// Context for the API.
// std::vector <Task> all;
Task _current;
// std::string& name;
// std::string& value;
};
#endif
#endif
////////////////////////////////////////////////////////////////////////////////

View file

@ -6,7 +6,6 @@ include_directories (${CMAKE_SOURCE_DIR}
${TASK_INCLUDE_DIRS})
set (task_SRCS A3.cpp A3.h
API.cpp API.h
Arg.cpp Arg.h
Color.cpp Color.h
Config.cpp Config.h

View file

@ -497,7 +497,7 @@ bool Context::verbose (const std::string& token)
}
////////////////////////////////////////////////////////////////////////////////
// This needs to be taken out and shot, as soon as Lua extensions will allow.
// This needs to be taken out and shot, as soon as...
void Context::shadow ()
{
std::string file_name = config.get ("shadow.file");

View file

@ -35,13 +35,6 @@
#include <DOM.h>
#include <cmake.h>
#ifdef HAVE_LIBLUA
extern "C"
{
#include <lua.h>
}
#endif
extern Context context;
////////////////////////////////////////////////////////////////////////////////
@ -64,7 +57,6 @@ const std::vector <std::string> DOM::get_references () const
refs.push_back ("context.width");
refs.push_back ("context.height");
refs.push_back ("system.version");
refs.push_back ("system.lua.version");
refs.push_back ("system.os");
return refs;
@ -82,7 +74,6 @@ const std::vector <std::string> DOM::get_references () const
// TODO stats.<name> <-- context.stats
//
// system.version
// system.lua.version
// system.os
const std::string DOM::get (const std::string& name)
{
@ -117,12 +108,6 @@ const std::string DOM::get (const std::string& name)
if (name == "system.version")
return VERSION;
#ifdef HAVE_LIBLUA
// Lua version number.
else if (name == "system.lua.version")
return LUA_RELEASE;
#endif
// OS type.
else if (name == "system.os")
#if defined (DARWIN)
@ -245,8 +230,6 @@ const std::string DOM::get (const std::string& name, const Task& task)
return this->get (name);
}
// TODO Need a context-specific DOM::set. For Lua. Probably.
////////////////////////////////////////////////////////////////////////////////
void DOM::set (const std::string& name, const std::string& value)
{

View file

@ -103,10 +103,6 @@ Hooks::~Hooks ()
// that if it isn't called, a script will not be loaded.
void Hooks::initialize ()
{
#ifdef HAVE_LIBLUA
_api.initialize ();
#endif
// Allow a master switch to turn the whole thing off.
bool big_red_switch = context.config.getBoolean ("extensions");
if (big_red_switch)
@ -147,7 +143,7 @@ void Hooks::initialize ()
(void) n.skip (',');
}
else
throw std::string (format (STRING_LUA_BAD_HOOK_DEF, *it));
; // Was: throw std::string (format (STRING_LAU_BAD_HOOK_DEF, *it));
}
}
}
@ -160,54 +156,14 @@ void Hooks::initialize ()
// Program hooks.
bool Hooks::trigger (const std::string& event)
{
#ifdef HAVE_LIBLUA
std::vector <Hook>::iterator it;
for (it = _all.begin (); it != _all.end (); ++it)
{
if (it->_event == event)
{
Timer timer (std::string ("Hooks::trigger ") + event);
if (validProgramEvent (event))
{
context.debug (std::string ("Event ") + event + " triggered");
if (! _api.callProgramHook (it->_file, it->_function))
return false;
}
else
throw std::string (format (STRING_LUA_BAD_EVENT, event));
}
}
#endif
return true;
return false;
}
////////////////////////////////////////////////////////////////////////////////
// Task hooks.
bool Hooks::trigger (const std::string& event, Task& task)
{
#ifdef HAVE_LIBLUA
std::vector <Hook>::iterator it;
for (it = _all.begin (); it != _all.end (); ++it)
{
if (it->_event == event)
{
Timer timer (std::string ("Hooks::trigger ") + event);
if (validTaskEvent (event))
{
context.debug (std::string ("Event ") + event + " triggered");
if (! _api.callTaskHook (it->_file, it->_function, task))
return false;
}
else
throw std::string (format (STRING_LUA_BAD_EVENT, event));
}
}
#endif
return true;
return false;
}
////////////////////////////////////////////////////////////////////////////////

View file

@ -31,7 +31,6 @@
#include <vector>
#include <string>
#include <API.h>
#include <cmake.h>
// Hook class representing a single hook, which is just a three-way map.
@ -68,9 +67,6 @@ private:
bool validTaskEvent (const std::string&);
private:
#ifdef HAVE_LIBLUA
API _api;
#endif
std::vector <Hook> _all; // All current hooks.
std::vector <std::string> _validProgramEvents;

View file

@ -39,13 +39,6 @@
#include <cmake.h>
#include <commit.h>
#ifdef HAVE_LIBLUA
extern "C"
{
#include <lua.h>
}
#endif
#include <CmdDiagnostics.h>
extern Context context;
@ -132,27 +125,6 @@ int CmdDiagnostics::execute (std::string& output)
<< " +vp" << sizeof (void*)
<< "\n\n";
out << bold.colorize (STRING_CMD_DIAG_LIBRARIES)
<< "\n";
out << " Lua: "
#ifdef HAVE_LIBLUA
<< LUA_RELEASE
#else
<< "n/a"
#endif
<< "\n";
out << " libuuid: "
#if defined (HAVE_UUID) and defined (HAVE_UUID_UNPARSE_LOWER)
<< "libuuid + uuid_unparse_lower"
#elif defined (HAVE_UUID) and !defined (HAVE_UUID_UNPARSE_LOWER)
<< "libuuid, no uuid_unparse_lower"
#else
<< "n/a"
#endif
<< "\n\n";
out << bold.colorize (STRING_CMD_DIAG_FEATURES)
<< "\n"
@ -183,6 +155,15 @@ int CmdDiagnostics::execute (std::string& output)
<< " +uuid"
#else
<< " -uuid"
#endif
<< "\n";
out << " libuuid: "
#if defined (HAVE_UUID) and defined (HAVE_UUID_UNPARSE_LOWER)
<< "libuuid + uuid_unparse_lower"
#elif defined (HAVE_UUID) and !defined (HAVE_UUID_UNPARSE_LOWER)
<< "libuuid, no uuid_unparse_lower"
#else
<< "n/a"
#endif
<< "\n\n";

View file

@ -351,46 +351,6 @@ int CmdShow::execute (std::string& output)
// TODO Check for referenced but missing string files.
// TODO Check for referenced but missing tips files.
// Check for referenced but missing hook scripts.
#ifdef HAVE_LIBLUA
std::vector <std::string> missing_scripts;
for (i = all.begin (); i != all.end (); ++i)
{
if (i->substr (0, 5) == "hook.")
{
std::string value = context.config.get (*i);
Nibbler n (value);
// <path>:<function> [, ...]
while (!n.depleted ())
{
std::string file;
std::string function;
if (n.getUntil (':', file) &&
n.skip (':') &&
n.getUntil (',', function))
{
Path script (file);
if (!script.exists () || !script.readable ())
missing_scripts.push_back (file);
(void) n.skip (',');
}
}
}
}
if (missing_scripts.size ())
{
out << STRING_CMD_SHOW_HOOKS << "\n";
for (i = missing_scripts.begin (); i != missing_scripts.end (); ++i)
out << " " << *i << "\n";
out << "\n";
}
#endif
// Check for bad values in rc.calendar.details.
std::string calendardetails = context.config.get ("calendar.details");
if (calendardetails != "full" &&

View file

@ -94,10 +94,6 @@ int CmdVersion::execute (std::string& output)
<< STRING_CMD_VERSION_UNKNOWN
#endif
#ifdef HAVE_LIBLUA
<< "-lua"
#endif
#if PACKAGE_LANGUAGE != LANGUAGE_EN_US
<< " "
<< STRING_LOCALIZATION_DESC
@ -105,12 +101,7 @@ int CmdVersion::execute (std::string& output)
<< "\n"
<< STRING_CMD_VERSION_COPY
<< "\n"
#ifdef HAVE_LIBLUA
<< STRING_CMD_VERSION_COPY2
<< "\n"
#endif
<< "\n"
<< "\n\n"
<< disclaimer.render ()
<< "\n"
<< link.render ()

View file

@ -118,15 +118,6 @@
#define STRING_A3_RANGE_INVERTED "Inverted range 'high-low' instead of 'low-high'"
#define STRING_A3_UUID_AFTER_COMMA "Unrecognized UUID after comma."
// API
#define STRING_API_EXITING "Exiting."
#define STRING_API_NOFUNC "The Lua function '{1}' was not found."
#define STRING_API_ERROR_CALLING "Error calling '{1}' - {2}."
#define STRING_API_ERROR_FAIL "Error: '{1}' did not return a success indicator."
#define STRING_API_ERROR_NORET "Error: '{1}' did not return a message or nil."
#define STRING_API_WARNING "Warning: {1}"
#define STRING_API_ERROR "Error: {1}"
// Color
#define STRING_COLOR_UNRECOGNIZED "The color '{1}' is not recognized."
@ -210,7 +201,6 @@
#define STRING_CMD_VERSION_BUILT "{1} {2} built for "
#define STRING_CMD_VERSION_UNKNOWN "unknown"
#define STRING_CMD_VERSION_COPY "Copyright (C) 2006 - 2013 P. Beckingham, F. Hernandez."
#define STRING_CMD_VERSION_COPY2 "Portions of this software Copyright (C) 1994 2008 Lua.org, PUC-Rio."
#define STRING_CMD_LOGO_USAGE "Displays the Taskwarrior logo"
#define STRING_CMD_LOGO_COLOR_REQ "The logo command requires that color support is enabled."
#define STRING_CMD_EXEC_USAGE "Executes external commands and scripts"
@ -752,10 +742,6 @@
// Legacy
#define STRING_LEGACY_FEATURE "Note: the '{1}' feature is deprecated."
// Lua
#define STRING_LUA_BAD_HOOK_DEF "Malformed hook definition '{1}'."
#define STRING_LUA_BAD_EVENT "Unrecognized hook event '{1}'."
// Record
#define STRING_RECORD_EMPTY "Empty record in input."
#define STRING_RECORD_JUNK_AT_EOL "Unrecognized characters at end of line."

View file

@ -118,15 +118,6 @@
#define STRING_A3_RANGE_INVERTED "Rango invertido 'alto-bajo' en vez de 'bajo-alto'"
#define STRING_A3_UUID_AFTER_COMMA "UUID no reconocido tras coma."
// API
#define STRING_API_EXITING "Saliendo."
#define STRING_API_NOFUNC "No se encontró la función Lua '{1}'."
#define STRING_API_ERROR_CALLING "Error al llamar '{1}' - {2}."
#define STRING_API_ERROR_FAIL "Error: '{1}' no devolvió un indicador de éxito."
#define STRING_API_ERROR_NORET "Error: '{1}' no devolvió un mensaje o nulo."
#define STRING_API_WARNING "Advertencia: {1}"
#define STRING_API_ERROR "Error: {1}"
// Color
#define STRING_COLOR_UNRECOGNIZED "El color '{1}' no se reconoce."
@ -214,7 +205,6 @@
#define STRING_CMD_VERSION_BUILT "{1} {2} construido para "
#define STRING_CMD_VERSION_UNKNOWN "desconocido"
#define STRING_CMD_VERSION_COPY "Copyright (C) 2006 - 2013 P. Beckingham, F. Hernandez."
#define STRING_CMD_VERSION_COPY2 "Partes de este software Copyright (C) 1994 2008 Lua.org, PUC-Rio."
#define STRING_CMD_LOGO_USAGE "Muestra el logo de Taskwarrior"
#define STRING_CMD_LOGO_COLOR_REQ "El comando logo requiere que el soporte de color esté habilitado."
#define STRING_CMD_EXEC_USAGE "Ejecuta comandos y scripts externos"
@ -766,10 +756,6 @@
// Legacy
#define STRING_LEGACY_FEATURE "Note: la función '{1}' está en desuso."
// Lua
#define STRING_LUA_BAD_HOOK_DEF "Definición de hook incorrecta '{1}'."
#define STRING_LUA_BAD_EVENT "Evento hook no reconocido '{1}'."
// Record
#define STRING_RECORD_EMPTY "Registro vacío en la entrada."
#define STRING_RECORD_JUNK_AT_EOL "Caracteres no reconocidos al final de línea."