summaryrefslogtreecommitdiff
path: root/cd-tool.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'cd-tool.cpp')
-rw-r--r--cd-tool.cpp1369
1 files changed, 685 insertions, 684 deletions
diff --git a/cd-tool.cpp b/cd-tool.cpp
index 5ec9385..f29b535 100644
--- a/cd-tool.cpp
+++ b/cd-tool.cpp
@@ -1,684 +1,685 @@
-/*
- * PSX-Tools Bundle Pack
- * Copyright (C) 2002-2003 Nicolas "Pixel" Noble
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-/* $Id: cd-tool.cpp,v 1.32 2004-07-30 10:01:34 pixel Exp $ */
-
-#define WIP
-
-#define VERSION "0.5"
-
-#include <getopt.h>
-#include "Input.h"
-#include "Output.h"
-#include "Buffer.h"
-#include "BLua.h"
-#include "cdreader.h"
-#include "cdutils.h"
-#include "generic.h"
-#include "Main.h"
-#include "cdabstract.h"
-#include "isobuilder.h"
-#include "luacd.h"
-#include "luapsx.h"
-#include <readline/readline.h>
-#include <readline/history.h>
-
-#include "cd-tool-hc.h"
-
-#ifdef _WIN32
-
-#include <readline/rldefs.h>
-
-#include <windows.h>
-#include <ctype.h>
-#include <conio.h>
-
-#define EXT_PREFIX 0x1f8
-
-#define KEV irec.Event.KeyEvent /* to make life easier */
-#define KST irec.Event.KeyEvent.dwControlKeyState
-
-
-static int pending_key = 0;
-static int pending_count = 0;
-static int pending_prefix = 0;
-
-extern int _rl_last_c_pos; /* imported from display.c */
-extern int _rl_last_v_pos;
-extern int rl_dispatching; /* imported from readline.c */
-extern int rl_point;
-extern int rl_done;
-extern int rl_visible_prompt_length;
-
-extern "C" {
-extern int haveConsole; /* imported from rltty.c */
-extern HANDLE hStdout, hStdin;
-}
-
-int my_getc (FILE * stream)
-{
- int key;
-
- if ( pending_count )
- {
- --pending_count;
- if ( pending_prefix && (pending_count & 1) )
- return pending_prefix;
- else
- return pending_key;
- }
-
- while ( 1 )
- {
- DWORD dummy;
-
- if (WaitForSingleObject(hStdin, WAIT_FOR_INPUT) != WAIT_OBJECT_0)
- {
- if ( rl_done )
- return( 0 );
- else
- continue;
- }
- if ( haveConsole & FOR_INPUT )
- {
- INPUT_RECORD irec;
- ReadConsoleInput(hStdin, &irec, 1, &dummy);
- switch(irec.EventType)
- {
- case KEY_EVENT:
- if ( KEV.bKeyDown
- && ((KEV.wVirtualKeyCode < VK_SHIFT) || (KEV.wVirtualKeyCode > VK_MENU)) )
- {
- int mask = 0;
-
- key = KEV.uChar.AsciiChar & 0xff;
-// if ( KST & (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED) )
-// mask=0x100;
- if ( key )
- {
- /* Ascii direct */
- pending_count = KEV.wRepeatCount - 1;
- pending_key = key;
- pending_prefix = 0;
- if ( mask )
- key = tolower(key) | mask;
- }
- else
- /* Others prefixed */
- {
- key = EXT_PREFIX;
- if ( mask )
- key |= 4;
- if (KST & SHIFT_PRESSED)
- key |= 1;
- if (KST & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED))
- key |= 2;
- mask |= EXT_PREFIX;
- pending_count = (KEV.wRepeatCount << 1) - 1;
- pending_key = KEV.wVirtualKeyCode;
- pending_prefix = key;
- }
- return key;
- }
- break;
- default:
- break;
- }
- }
- else
- {
- ReadFile(hStdin, &key, 1, &dummy, NULL);
- return key;
- }
- }
-}
-#endif
-
-bool interactive = false;
-cdutils * cdutil = 0;
-isobuilder * build = 0;
-
-static int myprint(lua_State * _L) {
- Lua * L = Lua::find(_L);
- String t = "From LUA: " + L->tostring() + "\n";
- char * tc = t.strdup();
-
- Base::printm(M_STATUS, "%s", tc);
-
- free(tc);
-
- return 0;
-}
-
-class Luabasecdtool : public LuaObject {
- public:
- static void pushstatics(Lua *) throw (GeneralException);
-};
-
-typedef void basecdtool;
-
-enum basecdtool_t {
- BASECDTOOL_LOAD = 0,
-};
-
-struct lua_functypes_t basecdtool_functions[] = {
- { BASECDTOOL_LOAD, "load", 0, 1, { LUA_STRING | LUA_OBJECT } },
- { -1, 0, 0, 0, 0 }
-};
-
-class sLua_basecdtool : public Base {
- public:
- DECLARE_FUNCTION(basecdtool, BASECDTOOL_LOAD);
- private:
- static int basecdtool_proceed_statics(Lua * L, int n, int caller);
-};
-
-void Luabasecdtool::pushstatics(Lua * L) throw (GeneralException ) {
- CHECK_FUNCTIONS(basecdtool);
-
- PUSH_FUNCTION(basecdtool, BASECDTOOL_LOAD);
-}
-
-int sLua_basecdtool::basecdtool_proceed_statics(Lua * L, int n, int caller) {
- int r = 0;
-
- switch (caller) {
- case BASECDTOOL_LOAD:
- if (!n) {
- L->load(&Input("cd-tool.lua"));
- } else {
- if (L->isstring(1)) {
- L->load(&Input(L->tostring(1)));
- } else {
- Handle * t = (Handle *) LuaObject::getme(L, 1);
- L->load(t);
- }
- }
- }
-
- return r;
-}
-
-class Luacdtool : public LuaObject {
- public:
- static void pushstatics(Lua *) throw (GeneralException);
-};
-
-typedef void cdtool;
-
-enum cdtool_functions_t {
- CDTOOL_PRINT = 0,
- CDTOOL_PRINTN,
- CDTOOL_QUIT,
- CDTOOL_EXIT,
- CDTOOL_INFOS,
- CDTOOL_PATH,
- CDTOOL_PRINTDIR,
-};
-
-struct lua_functypes_t cdtool_functions[] = {
- { CDTOOL_PRINT, "print", 0, 1, { LUA_ANY } },
- { CDTOOL_PRINTN, "printn", 1, 1, { LUA_ANY } },
- { CDTOOL_QUIT, "quit", 0, 0, 0 },
- { CDTOOL_EXIT, "exit", 0, 0, 0 },
- { CDTOOL_INFOS, "infos", 0, 1, { LUA_OBJECT } },
- { CDTOOL_PATH, "path", 0, 1, { LUA_OBJECT } },
- { CDTOOL_PRINTDIR, "printdir", 1, 2, { LUA_STRING, LUA_OBJECT } },
- { -1, 0, 0, 0, 0 }
-};
-
-class sLua_cdtool : public Base {
- public:
- DECLARE_FUNCTION(cdtool, CDTOOL_PRINT);
- DECLARE_FUNCTION(cdtool, CDTOOL_PRINTN);
- DECLARE_FUNCTION(cdtool, CDTOOL_QUIT);
- DECLARE_FUNCTION(cdtool, CDTOOL_EXIT);
- DECLARE_FUNCTION(cdtool, CDTOOL_INFOS);
- DECLARE_FUNCTION(cdtool, CDTOOL_PATH);
- DECLARE_FUNCTION(cdtool, CDTOOL_PRINTDIR);
- private:
- static int cdtool_proceed_statics(Lua * L, int n, int caller);
-};
-
-void Luacdtool::pushstatics(Lua * L) throw (GeneralException ) {
- CHECK_FUNCTIONS(cdtool);
-
- PUSH_FUNCTION(cdtool, CDTOOL_PRINT);
- PUSH_FUNCTION(cdtool, CDTOOL_PRINTN);
- PUSH_FUNCTION(cdtool, CDTOOL_QUIT);
- PUSH_FUNCTION(cdtool, CDTOOL_EXIT);
- PUSH_FUNCTION(cdtool, CDTOOL_INFOS);
- PUSH_FUNCTION(cdtool, CDTOOL_PATH);
- PUSH_FUNCTION(cdtool, CDTOOL_PRINTDIR);
-}
-
-int sLua_cdtool::cdtool_proceed_statics(Lua * L, int n, int caller) {
- int r = 0;
- String p;
- cdutils * cd = cdutil;
- char * tc;
- String eol = "";
-
- switch (caller) {
- case CDTOOL_PRINT:
- eol = "\n";
- case CDTOOL_PRINTN:
- if (n)
- p = L->tostring(1) + eol;
- else
- p = eol;
- tc = p.strdup();
- printm(M_BARE, "%s", tc);
- free(tc);
- break;
- case CDTOOL_QUIT:
- case CDTOOL_EXIT:
- interactive = false;
- break;
- case CDTOOL_INFOS:
- if (n)
- cd = (cdutils *) LuaObject::getme(L, 1);
- if (cd)
- cd->show_iso_infos();
- else
- L->error("Cdutils object void");
- break;
- case CDTOOL_PATH:
- if (n)
- cd = (cdutils *) LuaObject::getme(L, 1);
- if (cd)
- cd->show_pt_infos();
- else
- L->error("Cdutils object void");
- break;
- case CDTOOL_PRINTDIR:
- p = L->tostring(1);
- if (n == 2)
- cd = (cdutils *) LuaObject::getme(L, 2);
- if (cd) {
- char * f;
- cdutils::DirEntry dir = cd->find_path(f = p.strdup());
- free(f);
- if (!dir.R)
- L->error("Path `" + p + "' not found");
- if (!(dir.Flags & 2))
- L->error("Path `" + p + "' points to a file");
- cd->show_head_entry();
- cd->show_dir(&dir);
- } else
- L->error("Cdutils object void");
- break;
- }
-
- return r;
-}
-
-int lga = 0;
-struct option long_options[] = {
- {"help", 0, NULL, 'h'},
- {"verbose", 0, NULL, 'v'},
- {"file", 1, NULL, 'f'},
- {"write", 0, NULL, 'w'},
- {"output", 1, NULL, 'o'},
- {"archive", 1, NULL, 'a'},
- {"compile", 1, NULL, 'c'},
- {"debug", 0, NULL, 'd'},
- {"interactive", 0, NULL, 'i'},
- {"line", 0, NULL, 'l'},
- {"exec", 1, NULL, 'e'},
- {"built-in", 0, NULL, 'b'},
- {"probe", 0, NULL, 'p'},
- {0, 0, NULL, 0 }
-};
-
-CODE_BEGINS
-
-/* That's the basic lua starter for non interactive mode */
-Lua * start_basic_lua(void) {
- Lua * L = new Lua();
-
- L->open_base();
- L->open_math();
- L->open_string();
- L->open_table();
-
- LuaInput::pushconstruct(L);
- LuaOutput::pushconstruct(L);
- LuaBuffer::pushconstruct(L);
-
- CD_PUSHSTATICS(L);
-
- Luapsx::pushstatics(L);
-
- L->push("print");
- L->push(myprint);
- L->setvar();
-
- Luabasecdtool::pushstatics(L);
-
- return L;
-}
-
-/* That's the extended stuff for interactive mode */
-Lua * start_full_lua(void) {
- Lua * L = start_basic_lua();
-
- Luacdtool::pushstatics(L);
-
- return L;
-}
-
-void showbanner() {
- printm(M_BARE,
-"CD-Tool version " VERSION " (c) 2003-2004 Nicolas \"Pixel\" Noble\n"
-#ifdef WIP
-"Special version Work In Progress, compiled the " __DATE__ " at " __TIME__ "\n"
-#endif
-"This is free software with ABSOLUTELY NO WARRANTY.\n"
-"\n");
-}
-
-void showhelp(bool longhelp = false) {
- printm(M_BARE,
-"Usage:\n"
-"%s [options] [lua-script1] [lua-script2] ...\n"
-"\n"
-"Options:\n"
-" -v for verbose mode.\n"
-" -f <iso> to load an initial iso file (object cdutil).\n"
-" -w to open the previous iso file in write mode.\n"
-" -o <iso> to start creating an output iso (object iso).\n"
-" -a <paq> to load an additionnal archive file.\n"
-" -c <out> to dump the compiled byte code to file.\n"
-" -d to enable debug mode (ie, do not strip)\n"
-" -i to start interactive mode.\n"
-" -l to turn off the exec on end line.\n"
-" -e <cmd> to execute this single command in LUA.\n"
-" -b to force the use of the built-in cd-tool.lua\n"
-" -p to run a CD device probe.\n"
-" -h for a help page.\n"
-, argv[0]);
-
- if (longhelp)
- printm(M_BARE,
-"\n"
-"Verbose mode can be somewhat a floody thing.\n"
-"Options -i/-e and -c are mutually exclusive.\n"
-"Options -i and -e are NOT mutually exclusive. For example:\n"
-"\n"
-" $ %s -i -e \"main()\" somescript.lua\n"
-"\n"
-"This will first load the script 'somescript.lua', then execute main, and\n"
-"afterward, start the interactive mode.\n"
-"\n"
-"If a script contains inlined code, it will be run right after loading.\n"
-, argv[0]);
-}
-
-void probe(void) {
- std::vector<String> p;
-
- if (!cdabstract::canprobe()) {
- printm(M_ERROR, "Can't probe on this platform.\n");
- exit(-1);
- }
-
- p = cdabstract::probe();
-
- printm(M_BARE, "Alvaible devices:\n");
- for (std::vector<String>::iterator i = p.begin(); i != p.end(); i++) {
- printm(M_BARE, *i + "\n");
- }
-}
-
-virtual int startup() throw (GeneralException) {
- char c;
-
- bool auto_exec = true, strip = true, todo = false, runit, write = false, builtin = false;
- char * file = 0, * output = 0, * compile = 0, * exec = 0, * line_read = 0;
- char prompt[10];
- Lua * L = 0;
- Handle * read_iso = 0;
- Output * build_iso = 0, * write_iso = 0;
- Buffer command;
- String line, endline;
- int pos;
-
- verbosity = M_WARNING;
-
- showbanner();
-
- /* Let's start parsing options */
-
- while ((c = getopt_long(argc, argv, "Hhvf:wo:a:c:dile:pb", long_options, NULL)) != EOF) {
- switch (c) {
- case 'h':
- case 'H':
- case '?':
- showhelp(true);
- throw Exit(0);
- case 'v':
- verbosity = M_INFO;
- break;
- case 'f':
- file = strdup(optarg);
- break;
- case 'w':
- write = true;
- break;
- case 'o':
- output = strdup(optarg);
- break;
- case 'a':
- new Archive(optarg);
- break;
- case 'c':
- compile = strdup(optarg);
- break;
- case 'd':
- strip = false;
- break;
- case 'i':
- interactive = true;
- todo = true;
- break;
- case 'l':
- auto_exec = false;
- break;
- case 'e':
- exec = strdup(optarg);
- todo = true;
- break;
- case 'p':
- probe();
- throw Exit(0);
- case 'b':
- builtin = true;
- break;
- default:
- showhelp();
- throw Exit(-1);
- }
- }
-
- if (interactive)
- L = start_full_lua();
- else
- L = start_basic_lua();
-
- /* Loading cd-tool.lua (only when not compiling) */
- if (!compile && !builtin) {
- try {
- L->load(&Input("cd-tool.lua"));
- }
- catch (GeneralException e) {
- printm(M_WARNING, "There was an error loading cd-tool.lua, using built-in: %s\n", e.GetMsg());
- builtin = true;
- }
- }
-
- if (!compile && builtin) {
- Buffer built;
- int i;
-
- for (i = 0; i < cd_tool_lua_size; i++) {
- built.writeU8(cd_tool_lua[i]);
- }
- try {
- L->load(&built);
- }
- catch (GeneralException e) {
- printm(M_WARNING, "There was an error loading built-in cd-tool.lua: %s\n", e.GetMsg());
- builtin = true;
- }
- }
-
- /* Loading all the scripts */
- while (optind < argc) {
- todo = true;
- L->load(&Input(argv[optind++]), !compile);
- }
-
- /* Doh... */
- if (!todo) {
- showhelp();
- throw Exit(0);
- }
-
- /* Compilation process will exit from itself right after */
- if (compile) {
- L->dump(&Output(compile), strip);
- throw Exit(0);
- }
-
- /* The basic input (and eventually output) iso file */
- if (file) {
- /* The write mode can't apply on a CD of course... */
- if (write) {
- read_iso = new Input(file);
- write_iso = new Output(file, 0, 0);
- } else {
- read_iso = cdabstract::open_cd(file);
- }
- cdutil = new cdutils(read_iso, write_iso);
- if (!cdutil->get_iso_infos())
- throw Exit(-1);
- Luacdutils lcdutil(cdutil);
- L->push("cdutil");
- lcdutil.push(L);
- L->setvar();
- }
-
- /* The generated iso file */
- if (output) {
- build_iso = new Output(output);
- build = new isobuilder(build_iso);
- Luaisobuilder lbuild(build);
- L->push("iso");
- lbuild.push(L);
- L->setvar();
- }
-
- /* One shot command */
- if (exec) {
- command << exec;
- L->load(&command);
- }
-
- /* Interactive mode loop */
- strcpy(prompt, "> ");
-#ifdef _WIN32
- rl_getc_function = my_getc;
-#endif
- rl_bind_key('\t', rl_insert);
- while (interactive) {
- /* Basic usage of readline */
- if (line_read)
- free(line_read);
-
- line_read = readline(prompt);
-
- if (!line_read) {
- printm(M_BARE, "\n");
- break;
- }
-
- if (*line_read)
- add_history(line_read);
-
- line = line_read;
- line = line.trim();
- endline = "";
-
- /* Splitting the line between ;; */
- while (line.strlen()) {
- runit = false;
-
- if ((pos = line.strstr(";;")) >= 0) {
- endline = line.extract(pos + 2);
- line = line.extract(0, pos);
- runit = true;
- } else {
- endline = "";
- }
-
- if (line[line.strlen() - 1] == '\\') {
- line[line.strlen() - 1] = ' ';
- } else if (auto_exec) {
- runit = true;
- }
-
- command << line;
-
- if (runit) {
- try {
- L->load(&command);
- }
- catch (LuaException e) {
- /* If there was an error, ignore it, and free the stack */
- while(L->gettop())
- L->pop();
- }
- 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, "- ");
- }
- line = endline.trim();
- };
- }
-
- /* Finishing off the work, cleaning out the dust */
- if (output) {
- delete build;
- delete build_iso;
- }
-
- if (file) {
- delete cdutil;
- }
-
- return 0;
-}
-CODE_ENDS
+/*
+ * PSX-Tools Bundle Pack
+ * Copyright (C) 2002-2003 Nicolas "Pixel" Noble
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/* $Id: cd-tool.cpp,v 1.33 2004-11-27 21:01:20 pixel Exp $ */
+
+#define WIP
+
+#define VERSION "0.5"
+
+#include <getopt.h>
+#include "Input.h"
+#include "Output.h"
+#include "Buffer.h"
+#include "BLua.h"
+#include "cdreader.h"
+#include "cdutils.h"
+#include "generic.h"
+#include "Main.h"
+#include "cdabstract.h"
+#include "isobuilder.h"
+#include "luacd.h"
+#include "luapsx.h"
+#include <readline/readline.h>
+#include <readline/history.h>
+
+#include "cd-tool-hc.h"
+
+#ifdef _WIN32
+
+#include <readline/rldefs.h>
+
+#include <windows.h>
+#include <ctype.h>
+#include <conio.h>
+
+#define EXT_PREFIX 0x1f8
+
+#define KEV irec.Event.KeyEvent /* to make life easier */
+#define KST irec.Event.KeyEvent.dwControlKeyState
+
+
+static int pending_key = 0;
+static int pending_count = 0;
+static int pending_prefix = 0;
+
+extern int _rl_last_c_pos; /* imported from display.c */
+extern int _rl_last_v_pos;
+extern int rl_dispatching; /* imported from readline.c */
+extern int rl_point;
+extern int rl_done;
+extern int rl_visible_prompt_length;
+
+extern "C" {
+extern int haveConsole; /* imported from rltty.c */
+extern HANDLE hStdout, hStdin;
+}
+
+int my_getc (FILE * stream)
+{
+ int key;
+
+ if ( pending_count )
+ {
+ --pending_count;
+ if ( pending_prefix && (pending_count & 1) )
+ return pending_prefix;
+ else
+ return pending_key;
+ }
+
+ while ( 1 )
+ {
+ DWORD dummy;
+
+ if (WaitForSingleObject(hStdin, WAIT_FOR_INPUT) != WAIT_OBJECT_0)
+ {
+ if ( rl_done )
+ return( 0 );
+ else
+ continue;
+ }
+ if ( haveConsole & FOR_INPUT )
+ {
+ INPUT_RECORD irec;
+ ReadConsoleInput(hStdin, &irec, 1, &dummy);
+ switch(irec.EventType)
+ {
+ case KEY_EVENT:
+ if ( KEV.bKeyDown
+ && ((KEV.wVirtualKeyCode < VK_SHIFT) || (KEV.wVirtualKeyCode > VK_MENU)) )
+ {
+ int mask = 0;
+
+ key = KEV.uChar.AsciiChar & 0xff;
+// if ( KST & (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED) )
+// mask=0x100;
+ if ( key )
+ {
+ /* Ascii direct */
+ pending_count = KEV.wRepeatCount - 1;
+ pending_key = key;
+ pending_prefix = 0;
+ if ( mask )
+ key = tolower(key) | mask;
+ }
+ else
+ /* Others prefixed */
+ {
+ key = EXT_PREFIX;
+ if ( mask )
+ key |= 4;
+ if (KST & SHIFT_PRESSED)
+ key |= 1;
+ if (KST & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED))
+ key |= 2;
+ mask |= EXT_PREFIX;
+ pending_count = (KEV.wRepeatCount << 1) - 1;
+ pending_key = KEV.wVirtualKeyCode;
+ pending_prefix = key;
+ }
+ return key;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ else
+ {
+ ReadFile(hStdin, &key, 1, &dummy, NULL);
+ return key;
+ }
+ }
+}
+#endif
+
+bool interactive = false;
+cdutils * cdutil = 0;
+isobuilder * build = 0;
+
+static int myprint(lua_State * _L) {
+ Lua * L = Lua::find(_L);
+ String t = "From LUA: " + L->tostring() + "\n";
+ char * tc = t.strdup();
+
+ Base::printm(M_STATUS, "%s", tc);
+
+ free(tc);
+
+ return 0;
+}
+
+class Luabasecdtool : public LuaObject {
+ public:
+ static void pushstatics(Lua *) throw (GeneralException);
+};
+
+typedef void basecdtool;
+
+enum basecdtool_t {
+ BASECDTOOL_LOAD = 0,
+};
+
+struct lua_functypes_t basecdtool_functions[] = {
+ { BASECDTOOL_LOAD, "load", 0, 1, { LUA_STRING | LUA_OBJECT } },
+ { -1, 0, 0, 0, 0 }
+};
+
+class sLua_basecdtool : public Base {
+ public:
+ DECLARE_FUNCTION(basecdtool, BASECDTOOL_LOAD);
+ private:
+ static int basecdtool_proceed_statics(Lua * L, int n, int caller);
+};
+
+void Luabasecdtool::pushstatics(Lua * L) throw (GeneralException ) {
+ CHECK_FUNCTIONS(basecdtool);
+
+ PUSH_FUNCTION(basecdtool, BASECDTOOL_LOAD);
+}
+
+int sLua_basecdtool::basecdtool_proceed_statics(Lua * L, int n, int caller) {
+ int r = 0;
+
+ switch (caller) {
+ case BASECDTOOL_LOAD:
+ if (!n) {
+ L->load(&Input("cd-tool.lua"));
+ } else {
+ if (L->isstring(1)) {
+ L->load(&Input(L->tostring(1)));
+ } else {
+ Handle * t = (Handle *) LuaObject::getme(L, 1);
+ L->load(t);
+ }
+ }
+ }
+
+ return r;
+}
+
+class Luacdtool : public LuaObject {
+ public:
+ static void pushstatics(Lua *) throw (GeneralException);
+};
+
+typedef void cdtool;
+
+enum cdtool_functions_t {
+ CDTOOL_PRINT = 0,
+ CDTOOL_PRINTN,
+ CDTOOL_QUIT,
+ CDTOOL_EXIT,
+ CDTOOL_INFOS,
+ CDTOOL_PATH,
+ CDTOOL_PRINTDIR,
+};
+
+struct lua_functypes_t cdtool_functions[] = {
+ { CDTOOL_PRINT, "print", 0, 1, { LUA_ANY } },
+ { CDTOOL_PRINTN, "printn", 1, 1, { LUA_ANY } },
+ { CDTOOL_QUIT, "quit", 0, 0, 0 },
+ { CDTOOL_EXIT, "exit", 0, 0, 0 },
+ { CDTOOL_INFOS, "infos", 0, 1, { LUA_OBJECT } },
+ { CDTOOL_PATH, "path", 0, 1, { LUA_OBJECT } },
+ { CDTOOL_PRINTDIR, "printdir", 1, 2, { LUA_STRING, LUA_OBJECT } },
+ { -1, 0, 0, 0, 0 }
+};
+
+class sLua_cdtool : public Base {
+ public:
+ DECLARE_FUNCTION(cdtool, CDTOOL_PRINT);
+ DECLARE_FUNCTION(cdtool, CDTOOL_PRINTN);
+ DECLARE_FUNCTION(cdtool, CDTOOL_QUIT);
+ DECLARE_FUNCTION(cdtool, CDTOOL_EXIT);
+ DECLARE_FUNCTION(cdtool, CDTOOL_INFOS);
+ DECLARE_FUNCTION(cdtool, CDTOOL_PATH);
+ DECLARE_FUNCTION(cdtool, CDTOOL_PRINTDIR);
+ private:
+ static int cdtool_proceed_statics(Lua * L, int n, int caller);
+};
+
+void Luacdtool::pushstatics(Lua * L) throw (GeneralException ) {
+ CHECK_FUNCTIONS(cdtool);
+
+ PUSH_FUNCTION(cdtool, CDTOOL_PRINT);
+ PUSH_FUNCTION(cdtool, CDTOOL_PRINTN);
+ PUSH_FUNCTION(cdtool, CDTOOL_QUIT);
+ PUSH_FUNCTION(cdtool, CDTOOL_EXIT);
+ PUSH_FUNCTION(cdtool, CDTOOL_INFOS);
+ PUSH_FUNCTION(cdtool, CDTOOL_PATH);
+ PUSH_FUNCTION(cdtool, CDTOOL_PRINTDIR);
+}
+
+int sLua_cdtool::cdtool_proceed_statics(Lua * L, int n, int caller) {
+ int r = 0;
+ String p;
+ cdutils * cd = cdutil;
+ char * tc;
+ String eol = "";
+
+ switch (caller) {
+ case CDTOOL_PRINT:
+ eol = "\n";
+ case CDTOOL_PRINTN:
+ if (n)
+ p = L->tostring(1) + eol;
+ else
+ p = eol;
+ tc = p.strdup();
+ printm(M_BARE, "%s", tc);
+ free(tc);
+ break;
+ case CDTOOL_QUIT:
+ case CDTOOL_EXIT:
+ interactive = false;
+ break;
+ case CDTOOL_INFOS:
+ if (n)
+ cd = (cdutils *) LuaObject::getme(L, 1);
+ if (cd)
+ cd->show_iso_infos();
+ else
+ L->error("Cdutils object void");
+ break;
+ case CDTOOL_PATH:
+ if (n)
+ cd = (cdutils *) LuaObject::getme(L, 1);
+ if (cd)
+ cd->show_pt_infos();
+ else
+ L->error("Cdutils object void");
+ break;
+ case CDTOOL_PRINTDIR:
+ p = L->tostring(1);
+ if (n == 2)
+ cd = (cdutils *) LuaObject::getme(L, 2);
+ if (cd) {
+ char * f;
+ cdutils::DirEntry dir = cd->find_path(f = p.strdup());
+ free(f);
+ if (!dir.R)
+ L->error("Path `" + p + "' not found");
+ if (!(dir.Flags & 2))
+ L->error("Path `" + p + "' points to a file");
+ cd->show_head_entry();
+ cd->show_dir(&dir);
+ } else
+ L->error("Cdutils object void");
+ break;
+ }
+
+ return r;
+}
+
+int lga = 0;
+struct option long_options[] = {
+ {"help", 0, NULL, 'h'},
+ {"verbose", 0, NULL, 'v'},
+ {"file", 1, NULL, 'f'},
+ {"write", 0, NULL, 'w'},
+ {"output", 1, NULL, 'o'},
+ {"archive", 1, NULL, 'a'},
+ {"compile", 1, NULL, 'c'},
+ {"debug", 0, NULL, 'd'},
+ {"interactive", 0, NULL, 'i'},
+ {"line", 0, NULL, 'l'},
+ {"exec", 1, NULL, 'e'},
+ {"built-in", 0, NULL, 'b'},
+ {"probe", 0, NULL, 'p'},
+ {0, 0, NULL, 0 }
+};
+
+CODE_BEGINS
+
+/* That's the basic lua starter for non interactive mode */
+Lua * start_basic_lua(void) {
+ Lua * L = new Lua();
+
+ L->open_base();
+ L->open_math();
+ L->open_string();
+ L->open_table();
+ L->open_dir();
+
+ LuaInput::pushconstruct(L);
+ LuaOutput::pushconstruct(L);
+ LuaBuffer::pushconstruct(L);
+
+ CD_PUSHSTATICS(L);
+
+ Luapsx::pushstatics(L);
+
+ L->push("print");
+ L->push(myprint);
+ L->setvar();
+
+ Luabasecdtool::pushstatics(L);
+
+ return L;
+}
+
+/* That's the extended stuff for interactive mode */
+Lua * start_full_lua(void) {
+ Lua * L = start_basic_lua();
+
+ Luacdtool::pushstatics(L);
+
+ return L;
+}
+
+void showbanner() {
+ printm(M_BARE,
+"CD-Tool version " VERSION " (c) 2003-2004 Nicolas \"Pixel\" Noble\n"
+#ifdef WIP
+"Special version Work In Progress, compiled the " __DATE__ " at " __TIME__ "\n"
+#endif
+"This is free software with ABSOLUTELY NO WARRANTY.\n"
+"\n");
+}
+
+void showhelp(bool longhelp = false) {
+ printm(M_BARE,
+"Usage:\n"
+"%s [options] [lua-script1] [lua-script2] ...\n"
+"\n"
+"Options:\n"
+" -v for verbose mode.\n"
+" -f <iso> to load an initial iso file (object cdutil).\n"
+" -w to open the previous iso file in write mode.\n"
+" -o <iso> to start creating an output iso (object iso).\n"
+" -a <paq> to load an additionnal archive file.\n"
+" -c <out> to dump the compiled byte code to file.\n"
+" -d to enable debug mode (ie, do not strip)\n"
+" -i to start interactive mode.\n"
+" -l to turn off the exec on end line.\n"
+" -e <cmd> to execute this single command in LUA.\n"
+" -b to force the use of the built-in cd-tool.lua\n"
+" -p to run a CD device probe.\n"
+" -h for a help page.\n"
+, argv[0]);
+
+ if (longhelp)
+ printm(M_BARE,
+"\n"
+"Verbose mode can be somewhat a floody thing.\n"
+"Options -i/-e and -c are mutually exclusive.\n"
+"Options -i and -e are NOT mutually exclusive. For example:\n"
+"\n"
+" $ %s -i -e \"main()\" somescript.lua\n"
+"\n"
+"This will first load the script 'somescript.lua', then execute main, and\n"
+"afterward, start the interactive mode.\n"
+"\n"
+"If a script contains inlined code, it will be run right after loading.\n"
+, argv[0]);
+}
+
+void probe(void) {
+ std::vector<String> p;
+
+ if (!cdabstract::canprobe()) {
+ printm(M_ERROR, "Can't probe on this platform.\n");
+ exit(-1);
+ }
+
+ p = cdabstract::probe();
+
+ printm(M_BARE, "Alvaible devices:\n");
+ for (std::vector<String>::iterator i = p.begin(); i != p.end(); i++) {
+ printm(M_BARE, *i + "\n");
+ }
+}
+
+virtual int startup() throw (GeneralException) {
+ char c;
+
+ bool auto_exec = true, strip = true, todo = false, runit, write = false, builtin = false;
+ char * file = 0, * output = 0, * compile = 0, * exec = 0, * line_read = 0;
+ char prompt[10];
+ Lua * L = 0;
+ Handle * read_iso = 0;
+ Output * build_iso = 0, * write_iso = 0;
+ Buffer command;
+ String line, endline;
+ int pos;
+
+ verbosity = M_WARNING;
+
+ showbanner();
+
+ /* Let's start parsing options */
+
+ while ((c = getopt_long(argc, argv, "Hhvf:wo:a:c:dile:pb", long_options, NULL)) != EOF) {
+ switch (c) {
+ case 'h':
+ case 'H':
+ case '?':
+ showhelp(true);
+ throw Exit(0);
+ case 'v':
+ verbosity = M_INFO;
+ break;
+ case 'f':
+ file = strdup(optarg);
+ break;
+ case 'w':
+ write = true;
+ break;
+ case 'o':
+ output = strdup(optarg);
+ break;
+ case 'a':
+ new Archive(optarg);
+ break;
+ case 'c':
+ compile = strdup(optarg);
+ break;
+ case 'd':
+ strip = false;
+ break;
+ case 'i':
+ interactive = true;
+ todo = true;
+ break;
+ case 'l':
+ auto_exec = false;
+ break;
+ case 'e':
+ exec = strdup(optarg);
+ todo = true;
+ break;
+ case 'p':
+ probe();
+ throw Exit(0);
+ case 'b':
+ builtin = true;
+ break;
+ default:
+ showhelp();
+ throw Exit(-1);
+ }
+ }
+
+ if (interactive)
+ L = start_full_lua();
+ else
+ L = start_basic_lua();
+
+ /* Loading cd-tool.lua (only when not compiling) */
+ if (!compile && !builtin) {
+ try {
+ L->load(&Input("cd-tool.lua"));
+ }
+ catch (GeneralException e) {
+ printm(M_WARNING, "There was an error loading cd-tool.lua, using built-in: %s\n", e.GetMsg());
+ builtin = true;
+ }
+ }
+
+ if (!compile && builtin) {
+ Buffer built;
+ int i;
+
+ for (i = 0; i < cd_tool_lua_size; i++) {
+ built.writeU8(cd_tool_lua[i]);
+ }
+ try {
+ L->load(&built);
+ }
+ catch (GeneralException e) {
+ printm(M_WARNING, "There was an error loading built-in cd-tool.lua: %s\n", e.GetMsg());
+ builtin = true;
+ }
+ }
+
+ /* Loading all the scripts */
+ while (optind < argc) {
+ todo = true;
+ L->load(&Input(argv[optind++]), !compile);
+ }
+
+ /* Doh... */
+ if (!todo) {
+ showhelp();
+ throw Exit(0);
+ }
+
+ /* Compilation process will exit from itself right after */
+ if (compile) {
+ L->dump(&Output(compile), strip);
+ throw Exit(0);
+ }
+
+ /* The basic input (and eventually output) iso file */
+ if (file) {
+ /* The write mode can't apply on a CD of course... */
+ if (write) {
+ read_iso = new Input(file);
+ write_iso = new Output(file, 0, 0);
+ } else {
+ read_iso = cdabstract::open_cd(file);
+ }
+ cdutil = new cdutils(read_iso, write_iso);
+ if (!cdutil->get_iso_infos())
+ throw Exit(-1);
+ Luacdutils lcdutil(cdutil);
+ L->push("cdutil");
+ lcdutil.push(L);
+ L->setvar();
+ }
+
+ /* The generated iso file */
+ if (output) {
+ build_iso = new Output(output);
+ build = new isobuilder(build_iso);
+ Luaisobuilder lbuild(build);
+ L->push("iso");
+ lbuild.push(L);
+ L->setvar();
+ }
+
+ /* One shot command */
+ if (exec) {
+ command << exec;
+ L->load(&command);
+ }
+
+ /* Interactive mode loop */
+ strcpy(prompt, "> ");
+#ifdef _WIN32
+ rl_getc_function = my_getc;
+#endif
+ rl_bind_key('\t', rl_insert);
+ while (interactive) {
+ /* Basic usage of readline */
+ if (line_read)
+ free(line_read);
+
+ line_read = readline(prompt);
+
+ if (!line_read) {
+ printm(M_BARE, "\n");
+ break;
+ }
+
+ if (*line_read)
+ add_history(line_read);
+
+ line = line_read;
+ line = line.trim();
+ endline = "";
+
+ /* Splitting the line between ;; */
+ while (line.strlen()) {
+ runit = false;
+
+ if ((pos = line.strstr(";;")) >= 0) {
+ endline = line.extract(pos + 2);
+ line = line.extract(0, pos);
+ runit = true;
+ } else {
+ endline = "";
+ }
+
+ if (line[line.strlen() - 1] == '\\') {
+ line[line.strlen() - 1] = ' ';
+ } else if (auto_exec) {
+ runit = true;
+ }
+
+ command << line;
+
+ if (runit) {
+ try {
+ L->load(&command);
+ }
+ catch (LuaException e) {
+ /* If there was an error, ignore it, and free the stack */
+ while(L->gettop())
+ L->pop();
+ }
+ 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, "- ");
+ }
+ line = endline.trim();
+ };
+ }
+
+ /* Finishing off the work, cleaning out the dust */
+ if (output) {
+ delete build;
+ delete build_iso;
+ }
+
+ if (file) {
+ delete cdutil;
+ }
+
+ return 0;
+}
+CODE_ENDS