diff options
| -rw-r--r-- | src/lua-interface.cpp | 120 | 
1 files changed, 92 insertions, 28 deletions
| diff --git a/src/lua-interface.cpp b/src/lua-interface.cpp index 3343b98..ee5f721 100644 --- a/src/lua-interface.cpp +++ b/src/lua-interface.cpp @@ -37,6 +37,7 @@  #include <BLua.h>  #include <LuaCommandLine.h>  #include <HttpServ.h> +#include <CopyJob.h>  #include <MailServer.h>  #include <Message.h>  #include <Form.h> @@ -521,8 +522,6 @@ Lua * start_basic_lua(bool nested = false) {      LUAJIT_VERSION_SYM();      Lua * L = new Lua(); -    L->lock(); -      L->open_base();      L->open_math();      L->open_string(); @@ -536,8 +535,6 @@ Lua * start_basic_lua(bool nested = false) {      L->SetPrinter(&lp_stderr); -    L->unlock(); -          return L;  } @@ -638,13 +635,79 @@ class lua_interface_printer_t : public printer_t {      Handle * log;  }; -static void * interactive_prompt(void * __L) { +static bool runlua(Lua * L, Buffer * command) { +    try { +        L->load(command); +    } +    catch (LuaException e) { +        /* If there was an error, ignore it, and free the stack */ +        while(L->gettop()) +	    L->pop(); +        printm(M_ERROR, "%s\n", e.GetMsg()); +        return false; +    } +    catch (GeneralException e) { +        /* A more severe exception... */ +	while(L->gettop()) +	    L->pop(); +        printm(M_ERROR, "Aborted. LUA caused the following exception: %s\n", e.GetMsg()); +        return false; +    } +    return true; +} + +class PrompterTask : public Task { +  public: +      PrompterTask(Lua * L) : r(Socket::CreatePair()), w(r.GetPair()), c(0), L(L) { +          r.SetNonBlock(); +          SetBurst(); +      } +    int Do() throw (GeneralException) { +        int len; + +        switch(current) { +        case 3: +            delete c; +        case 0: +            c = new CopyJob(&r, &b, 4); +            WaitFor(c); +            current = 1; +            Suspend(TASK_ON_HOLD); +        case 1: +            delete c; +            c = new CopyJob(&r, &b, b.readU32()); +            WaitFor(c); +            current = 2; +            Suspend(TASK_ON_HOLD); +        case 2: +            delete c; +            b.writeU32(runlua(L, &b) ? 1 : 0); +            c = new CopyJob(&b, &r, 4); +            WaitFor(c); +            current = 3; +            Suspend(TASK_ON_HOLD); +        } +    } +    Handle * GetWriter() { return &w; } +  private: +    Socket r, w; +    Buffer b; +    Task * c; +    Lua * L; +}; + +struct interactive_prompt_data_t { +    Lua * L; +    Handle * w; +}; + +static void * interactive_prompt(void * __ipd) {      char prompt[10], * line_read = 0;      String line, endline;      bool runit;      Buffer command;      int pos; -    Lua * L = (Lua *) __L; +    interactive_prompt_data_t * ipd = (interactive_prompt_data_t *) __ipd;      /* Interactive mode loop */      strcpy(prompt, "> "); @@ -694,23 +757,17 @@ static void * interactive_prompt(void * __L) {              }  	    command << line; +	     +	    Uint32 got_error;  	    if (runit) { -		try { -		    L->load(&command); +	        if (ipd->L) { +	            got_error = runlua(ipd->L, &command) ? 1 : 0; +	        } else { +	            ipd->w->writeU32(command.GetRemaining()); +	            command.copyto(ipd->w); +	            got_error = ipd->w->readU32();  	        } -		catch (LuaException e) { -		    /* If there was an error, ignore it, and free the stack */ -		    while(L->gettop()) -			L->pop(); -                    printm(M_ERROR, "%s\n", e.GetMsg()); -	        } -		catch (GeneralException e) { -		    /* A more severe exception... */ -		    while(L->gettop()) -			L->pop(); -		    printm(M_ERROR, "Aborted. LUA caused the following exception: %s\n", e.GetMsg()); -		}  		strcpy(prompt, "> ");  	    } else {  		strcpy(prompt, "- "); @@ -720,6 +777,8 @@ static void * interactive_prompt(void * __L) {  	}      } +    free(ipd); +          return NULL;  } @@ -938,20 +997,25 @@ virtual int startup() throw (GeneralException) {      }  #endif -    if (interactive) { -        if (mserver || tserver || hserver) { -    	    pthread_create(&interactive_thread, NULL, interactive_prompt, L); -        } else { -            interactive_prompt(L); -        } -    } -      if (mserver || hserver || tserver) {  	TaskMan::Init();          if (hserver)  	    L->load(&Input(server_fname));      } +    if (interactive) { +        interactive_prompt_data_t * ipd = (interactive_prompt_data_t *) malloc(sizeof(interactive_prompt_data_t)); +        if (mserver || tserver || hserver) { +            ipd->w = (new PrompterTask(L))->GetWriter(); +            ipd->L = NULL; +    	    pthread_create(&interactive_thread, NULL, interactive_prompt, ipd); +        } else { +            ipd->L = L; +            ipd->w = NULL; +            interactive_prompt(ipd); +        } +    } +      if (hserver) {  	HttpServ * httpserv = new HttpServ(new Message("Welcome", "Welcome.", "start"), hport.to_int(), "Lua Interface");  	new Form("LUACall", "luacallform", "Enter the function name to call", LUACall_Names, LUACall_Invites, LUACall_Defaults, LUACall_Lists, LUACall_Descs, 1, new LUACall(L)); | 
