// Copyright (c) 2008, Simone Cociancich // 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 #ifndef _AUTO4_PERL_H #define _AUTO4_PERL_H #include "auto4_base.h" #include #include #include "ass_file.h" #undef _ #include #include #include #include "auto4_perldata.inc" // Perl variables manipulation macros #undef bool // the fucking perl.h redefines _() -.- #undef _ #define _(s) wxGetTranslation(_T(s)) // String conversions between wxWidgets and Perl #define wx2pl wxConvUTF8 #define pl2wx wxConvUTF8 #define PERL_SCRIPT_EXTENSION ".pl" /* TODO maybe: make it multi-extension */ // Debug support /* define the following to activate tracing for the perl engine */ #define WXTRACE_AUTOPERL #define wxTRACE_AutoPerl _T("auto4_perl") #define wxTRACE_METH(name) \ wxLogTrace(wxTRACE_AutoPerl, _T("\t=== %p::%s() ==="), this, _T(#name)) #define wxTRACE_FUNC(name) \ wxLogTrace(wxTRACE_AutoPerl, _T("\t=== %s() ==="), _T(#name)) #define wxTRACE_RET(name) \ wxLogTrace(wxTRACE_AutoPerl, _T("\t___ %s() returned ___"), _T(#name)) namespace Automation4 { ///////////// // PerlLog // #define LOG_FATAL 0 #define LOG_ERROR 1 #define LOG_WARNING 2 #define LOG_HINT 3 #define LOG_DEBUG 4 #define LOG_TRACE 5 #define LOG_MESSAGE 6 #define LOG_WX 8 #define PerlLogFatal(str) PerlLog(LOG_FATAL, str) #define PerlLogFatalError(str) PerlLog(LOG_FATAL, str) #define PerlLogError(str) PerlLog(LOG_ERROR, str) #define PerlLogWarning(str) PerlLog(LOG_WARNING, str) #define PerlLogHint(str) PerlLog(LOG_HINT, str) #define PerlLogVerbose(str) PerlLog(LOG_HINT, str) #define PerlLogDebug(str) PerlLog(LOG_DEBUG, str) #define PerlLogTrace(str) PerlLog(LOG_TRACE, str) #define PerlLogMessage(str) PerlLog(LOG_MESSAGE, str) void PerlLog(unsigned int level, const wxString &msg); //////////////// // PerlThread // class PerlThread : public wxThread { private: const char *pv; SV *sv; I32 flags; bool type; wxThreadError launch(); public: enum { EVAL = 0, CALL = 1 }; PerlThread(); PerlThread(const char *sub_name, I32 flags, bool type = CALL); PerlThread(SV *sv, I32 flags, bool type = CALL); wxThreadError Call(const char *sub_name, I32 flags); wxThreadError Call(SV *sv, I32 flags); wxThreadError Eval(const char* p, I32 croak_on_error); wxThreadError Eval(SV* sv, I32 flags); virtual ExitCode Entry(); }; /////////////////// // Script object // class PerlScript : public Script { private: static PerlScript *active; // The active script (at any given time) AV *inc_saved; wxString package; // Every script resides in a package named at random bool reload; // Automatically reload if source file has changed time_t mtime; // The mtime of the loaded source file void load(); // It doas all the script initialization void unload(); // It does all the script disposing static void activate(PerlScript *script); // Set the active script static void deactivate(); // Unset the active script public: PerlScript(const wxString &filename); virtual ~PerlScript(); static PerlScript *GetScript() { return active; } // Query the value of the active script virtual void Reload(); // Reloading of a loaded script void Activate() { activate(this); } // Set the script as active void Deactivate() const { deactivate(); } // Unset the active script /* TODO maybe: move to tied scalars */ void ReadVars(); // Sync the script's vars from perl package to script object void WriteVars() const; // Sync the script's vars from script object to perl package void AddFeature(Feature *feature); void DeleteFeature(Feature *feature); const wxString& GetPackage() const { return package; } // The perl package containing script code void SetName(const wxString &str) { name = str; } void SetDescription(const wxString &str) { description = str; } void SetAuthor(const wxString &str) { author = str; } void SetVersion(const wxString &str) { version = str; } }; ////////////////// // Macro object // class PerlFeatureMacro : public FeatureMacro { private: SV *processing_sub; // May be reference or name of sub SV *validation_sub; // here too protected: PerlScript *script; // The owner script public: PerlFeatureMacro(const wxString &name, const wxString &description, PerlScript *perl_script, SV *proc_sub, SV *val_sub); virtual ~PerlFeatureMacro(); virtual bool Validate(AssFile *subs, const std::vector &selected, int active); virtual void Process(AssFile *subs, std::vector &selected, int active, wxWindow * const progress_parent); }; ////////////////////// // PerlProgressSink // class PerlProgressSink : public ProgressSink { private: static PerlProgressSink *sink; public: PerlProgressSink(wxWindow *parent, const wxString &title = _T("...")); ~PerlProgressSink(); static PerlProgressSink *GetProgressSink() { return sink; } bool IsCancelled() const { return cancelled; } void Log(int level, const wxString &message) { if(level <= trace_level) AddDebugOutput(message); } }; /////////////////////////////////////////////////// // Conversion between aegisub data and perl data // class PerlAss { private: public: static wxString GetEntryClass(AssEntry *entry); static HV *MakeHasshEntry(AssEntry *entry); static HV *MakeHasshStyle(AssStyle *style); static HV *MakeHasshDialogue(AssDialogue *diag); static AV *MakeHasshLines(AV *lines, AssFile *ass); static AssEntry *MakeAssEntry(HV *entry); static AssStyle *MakeAssStyle(HV *style); static AssDialogue *MakeAssDialogue(HV *diag); static AssFile *MakeAssLines(AssFile *ass, AV *lines); }; }; #endif