scite228.zip

SciTE 2.28 - edytor tekstu dla programistów

SciTE 2.28 to darmowy edytor tekstu skierowany głównie do programistów i webmasterów. Cechuje go prostota i szybkość działania. Obsługuje kolorowanie składni dla wielu języków programowania (ze względu na oszczędność miejsca nie będę ich wymieniał). Podobnie jak inne edytory ma takie opcje jak numerowanie linii, przeglądanie plików w zakładkach, rozbudowane możliwości wyszukiwania/zamieniania tekstu i tym podobne. Posiada szerokie możliwości konfiguracji. Dla niektórych wadą może być sposób konfiguracji - trzeba ręcznie edytować pliki konfiguracyjne. Działa w systemie Windows i Linux. Bazuje na Scintilli, podobnie jak Notepad++, który może być bardziej odpowiedni dla osób którym nie odpowiada sposób konfiguracji SciTE. Sam używam do pisania programów i polecam. Program jest dostępny pod systemy: Windows i GTK+/Linux Strona domowa: Link

  • scite228.zip
    • upxsc1.bat
    • Array
    • .hgtags
    • Array
    • Array
    • zipwscite.bat
    • tgzsrc
    • License.txt
    • Array
    • README
    • Array
    • delcvs.bat
    • .hgignore
    • .hg_archival.txt
    • delbin.bat
    • zipsrc.bat
    • tgzgscite
    • Array
    • Array
    • .hgeol
    • Array
    • zipwscited.bat


Pobierz plik - link do postu

scite228.zip > empty.txt

This empty files ensures that the directory is created.


scite228.zip > Extender.h

// SciTE - Scintilla based Text Editor
/** @file Extender.h
** SciTE extension interface.
**/
// Copyright 1998-2001 by Neil Hodgson & lt; neilh@scintilla.org & gt;
// The License.txt file describes the conditions under which this software may be distributed.

#ifndef EXTENDER_H
#define EXTENDER_H

#include " Scintilla.h "

class StyleWriter;

class ExtensionAPI {
public:
virtual ~ExtensionAPI() {
}
enum Pane { paneEditor=1, paneOutput=2, paneFindOutput=3 };
virtual sptr_t Send(Pane p, unsigned int msg, uptr_t wParam=0, sptr_t lParam=0)=0;
virtual char *Range(Pane p, int start, int end)=0;
virtual void Remove(Pane p, int start, int end)=0;
virtual void Insert(Pane p, int pos, const char *s)=0;
virtual void Trace(const char *s)=0;
virtual char *Property(const char *key)=0;
virtual void SetProperty(const char *key, const char *val)=0;
virtual void UnsetProperty(const char *key)=0;
virtual uptr_t GetInstance()=0;
virtual void ShutDown()=0;
virtual void Perform(const char *actions)=0;
virtual void DoMenuCommand(int cmdID)=0;
virtual void UpdateStatusBar(bool bUpdateSlowData)=0;
};

/**
* Methods in extensions return true if they have completely handled an event and
* false if default processing is to continue.
*/
class Extension {
public:
virtual ~Extension() {}

virtual bool Initialise(ExtensionAPI *host_)=0;
virtual bool Finalise()=0;
virtual bool Clear()=0;
virtual bool Load(const char *filename)=0;

virtual bool InitBuffer(int) { return false; }
virtual bool ActivateBuffer(int) { return false; }
virtual bool RemoveBuffer(int) { return false; }

virtual bool OnOpen(const char *) { return false; }
virtual bool OnSwitchFile(const char *) { return false; }
virtual bool OnBeforeSave(const char *) { return false; }
virtual bool OnSave(const char *) { return false; }
virtual bool OnChar(char) { return false; }
virtual bool OnExecute(const char *) { return false; }
virtual bool OnSavePointReached() { return false; }
virtual bool OnSavePointLeft() { return false; }
virtual bool OnStyle(unsigned int, int, int, StyleWriter *) {
return false;
}
virtual bool OnDoubleClick() { return false; }
virtual bool OnUpdateUI() { return false; }
virtual bool OnMarginClick() { return false; }
virtual bool OnMacro(const char *, const char *) { return false; }
virtual bool OnUserListSelection(int, const char *) { return false; }

virtual bool SendProperty(const char *) { return false; }

virtual bool OnKey(int, int) { return false; }
virtual bool OnDwellStart(int, const char *) { return false; }
virtual bool OnClose(const char *) { return false; }
};

#endif


scite228.zip > IFaceTable.h

// SciTE - Scintilla based Text Editor
/** @file IFaceTable.h
** SciTE iface function and constant descriptors.
**/
// Copyright 1998-2004 by Neil Hodgson & lt; neilh@scintilla.org & gt;
// The License.txt file describes the conditions under which this software may be distributed.

#ifndef IFACETABLE_H
#define IFACETABLE_H

enum IFaceType {
iface_void,
iface_int,
iface_length,
iface_position,
iface_colour,
iface_bool,
iface_keymod,
iface_string,
iface_stringresult,
iface_cells,
iface_textrange,
iface_findtext,
iface_formatrange
};

struct IFaceConstant {
const char *name;
int value;
};

struct IFaceFunction {
const char *name;
int value;
IFaceType returnType;
IFaceType paramType[2];
};

struct IFaceProperty {
const char *name;
int getter;
int setter;
IFaceType valueType;
IFaceType paramType;

IFaceFunction GetterFunction() const {
IFaceFunction result = { " (property getter) " ,getter,valueType,{paramType,iface_void}};
return result;
}

IFaceFunction SetterFunction() const {
IFaceFunction result = { " (property setter) " ,setter,iface_void,{valueType, iface_void}};
if (paramType != iface_void) {
result.paramType[0] = paramType;
result.paramType[1] = valueType;
}
if ((paramType == iface_void) & & (valueType == iface_string)){
result.paramType[0] = paramType;
result.paramType[1] = valueType;
}
return result;
}
};

struct IFaceObject {
const char *name;
const char *prefix;
IFaceType indexType;
};

class IFaceTable {
public:
static const IFaceFunction * const functions;
static const IFaceConstant * const constants;
static const IFaceProperty * const properties;

static const int functionCount;
static const int constantCount;
static const int propertyCount;

static int FindConstant(const char *name);
static int FindFunction(const char *name);
static int FindFunctionByConstantName(const char *name);
static int FindProperty(const char *name);

static int GetConstantName(int value, char *nameOut, unsigned nameBufferLen);
};

#endif


scite228.zip > SciTEBase.h

// SciTE - Scintilla based Text Editor
/** @file SciTEBase.h
** Definition of platform independent base class of editor.
**/
// Copyright 1998-2011 by Neil Hodgson & lt; neilh@scintilla.org & gt;
// The License.txt file describes the conditions under which this software may be distributed.

extern const GUI::gui_char appName[];

extern const GUI::gui_char propUserFileName[];
extern const GUI::gui_char propGlobalFileName[];
extern const GUI::gui_char propAbbrevFileName[];

#ifdef WIN32
#ifdef _MSC_VER
// Shut up level 4 warning:
// warning C4710: function 'void whatever(...)' not inlined
// warning C4800: forcing value to bool 'true' or 'false' (performance warning)
#pragma warning(disable: 4710 4800)
#endif
#ifdef __DMC__
#include & lt; time.h & gt;
#endif
#endif

#define ELEMENTS(a) (sizeof(a) / sizeof(a[0]))

inline int Minimum(int a, int b) {
return (a & lt; b) ? a : b;
}

inline int Maximum(int a, int b) {
return (a & gt; b) ? a : b;
}

inline long LongFromTwoShorts(short a,short b) {
return (a) | ((b) & lt; & lt; 16);
}

typedef long Colour;
inline Colour ColourRGB(unsigned int red, unsigned int green, unsigned int blue) {
return red | (green & lt; & lt; 8) | (blue & lt; & lt; 16);
}

/**
* The order of menus on Windows - the Buffers menu may not be present
* and there is a Help menu at the end.
*/
enum {
menuFile = 0, menuEdit = 1, menuSearch = 2, menuView = 3,
menuTools = 4, menuOptions = 5, menuLanguage = 6, menuBuffers = 7,
menuHelp = 8
};

class RecentFile : public FilePath {
public:
Sci_CharacterRange selection;
int scrollPosition;
RecentFile() {
selection.cpMin = INVALID_POSITION;
selection.cpMax = INVALID_POSITION;
scrollPosition = 0;
}
void Init() {
FilePath::Init();
selection.cpMin = INVALID_POSITION;
selection.cpMax = INVALID_POSITION;
scrollPosition = 0;
}
};

// Related to Utf8_16::encodingType but with additional values at end
enum UniMode {
uni8Bit = 0, uni16BE = 1, uni16LE = 2, uniUTF8 = 3,
uniCookie = 4
};

class Buffer : public RecentFile {
public:
sptr_t doc;
bool isDirty;
bool useMonoFont;
UniMode unicodeMode;
time_t fileModTime;
time_t fileModLastAsk;
enum { fmNone, fmMarked, fmModified} findMarks;
SString overrideExtension; /// & lt; User has chosen to use a particular language
std::vector & lt; int & gt; foldState;
Buffer() :
RecentFile(), doc(0), isDirty(false), useMonoFont(false),
unicodeMode(uni8Bit), fileModTime(0), fileModLastAsk(0), findMarks(fmNone), foldState() {}

void Init() {
RecentFile::Init();
isDirty = false;
useMonoFont = false;
unicodeMode = uni8Bit;
fileModTime = 0;
fileModLastAsk = 0;
findMarks = fmNone;
overrideExtension = " " ;
foldState.clear();
}

void SetTimeFromFile() {
fileModTime = ModifiedTime();
fileModLastAsk = fileModTime;
}
};

class BufferList {
protected:
int current;
int stackcurrent;
int *stack;
public:
Buffer *buffers;
int size;
int length;
bool initialised;
BufferList();
~BufferList();
void Allocate(int maxSize);
int Add();
int GetDocumentByName(FilePath filename, bool excludeCurrent=false);
void RemoveCurrent();
int Current() const;
Buffer *CurrentBuffer();
void SetCurrent(int index);
int StackNext();
int StackPrev();
void CommitStackSelection();
void MoveToStackTop(int index);
void ShiftTo(int indexFrom, int indexTo);
private:
void PopStack();
};

// class to hold user defined keyboard short cuts
class ShortcutItem {
public:
SString menuKey; // the keyboard short cut
SString menuCommand; // the menu command to be passed to " SciTEBase::MenuCommand "
};

class LanguageMenuItem {
public:
SString menuItem;
SString menuKey;
SString extension;
};

enum {
heightTools = 24,
heightTab = 24,
heightStatus = 20,
statusPosWidth = 256
};

/// Warning IDs.
enum {
warnFindWrapped = 1,
warnNotFound,
warnNoOtherBookmark,
warnWrongFile,
warnExecuteOK,
warnExecuteKO
};

/// Codes representing the effect a line has on indentation.
enum IndentationStatus {
isNone, // no effect on indentation
isBlockStart, // indentation block begin such as " { " or VB " function "
isBlockEnd, // indentation end indicator such as " } " or VB " end "
isKeyWordStart // Keywords that cause indentation
};

int IntFromHexDigit(int ch);
int IntFromHexByte(const char *hexByte);

class StyleDefinition {
public:
SString font;
int size;
SString fore;
SString back;
bool bold;
bool italics;
bool eolfilled;
bool underlined;
int caseForce;
bool visible;
bool changeable;
enum flags { sdNone = 0, sdFont = 0x1, sdSize = 0x2, sdFore = 0x4, sdBack = 0x8,
sdBold = 0x10, sdItalics = 0x20, sdEOLFilled = 0x40, sdUnderlined = 0x80,
sdCaseForce = 0x100, sdVisible = 0x200, sdChangeable = 0x400} specified;
StyleDefinition(const char *definition);
bool ParseStyleDefinition(const char *definition);
long ForeAsLong() const;
long BackAsLong() const;
};

struct StyleAndWords {
int styleNumber;
SString words;
StyleAndWords() : styleNumber(0) {
}
bool IsEmpty() { return words.length() == 0; }
bool IsSingleChar() { return words.length() == 1; }
};

struct CurrentWordHighlight {
enum {
noDelay, // No delay, and no word at the caret.
delay, // Delay before to highlight the word at the caret.
delayJustEnded, // Delay has just ended. This state allows to ignore next HighlightCurrentWord (SCN_UPDATEUI and SC_UPDATE_CONTENT for setting indicators).
delayAlreadyElapsed // Delay has already elapsed, word at the caret and occurrences are (or have to be) highlighted.
} statesOfDelay;
bool isEnabled;
GUI::ElapsedTime elapsedTimes;
bool isOnlyWithSameStyle;

CurrentWordHighlight() {
statesOfDelay = noDelay;
isEnabled = false;
isOnlyWithSameStyle = false;
}
};

class Localization : public PropSetFile, public ILocalize {
SString missing;
public:
bool read;
Localization() : PropSetFile(true), read(false) {
}
GUI::gui_string Text(const char *s, bool retainIfNotFound=true);
void SetMissing(const SString & missing_) {
missing = missing_;
}
};

// Interface between SciTE and dialogs and strips for find and replace
class Searcher {
public:
SString findWhat;
SString replaceWhat;

bool wholeWord;
bool matchCase;
bool regExp;
bool unSlash;
bool wrapFind;
bool reverseFind;

bool replacing;
bool havefound;
bool findInStyle;
int findStyle;
bool closeFind;
ComboMemory memFinds;
ComboMemory memReplaces;

bool focusOnReplace;

Searcher();

virtual void SetFind(const char *sFind) = 0;
virtual bool FindHasText() const = 0;
virtual void SetReplace(const char *sReplace) = 0;
virtual void MoveBack(int distance) = 0;
virtual void ScrollEditorIfNeeded() = 0;

virtual int FindNext(bool reverseDirection, bool showWarnings = true) = 0;
virtual int MarkAll() = 0;
virtual int ReplaceAll(bool inSelection) = 0;
virtual void ReplaceOnce() = 0;
virtual void UIClosed() = 0;
virtual void UIHasFocus() = 0;
bool & FlagFromCmd(int cmd);
};

class SearchUI {
protected:
Searcher *pSearcher;
public:
SearchUI() : pSearcher(0) {
}
void SetSearcher(Searcher *pSearcher_) {
pSearcher = pSearcher_;
}
};

class SciTEBase : public ExtensionAPI, public Searcher {
protected:
GUI::gui_string windowName;
FilePath filePath;
FilePath dirNameAtExecute;
FilePath dirNameForExecute;

enum { fileStackMax = 10 };
RecentFile recentFileStack[fileStackMax];
enum { fileStackCmdID = IDM_MRUFILE, bufferCmdID = IDM_BUFFER };

enum { importMax = 50 };
FilePath importFiles[importMax];
enum { importCmdID = IDM_IMPORT };

enum { indicatorMatch = INDIC_CONTAINER, indicatorHightlightCurrentWord, indicatorSentinel };
enum { markerBookmark = 1 };
ComboMemory memFiles;
ComboMemory memDirectory;
SString parameterisedCommand;
char abbrevInsert[200];

enum { languageCmdID = IDM_LANGUAGE };
LanguageMenuItem *languageMenu;
int languageItems;

// an array of short cut items that are defined by the user in the properties file.
ShortcutItem *shortCutItemList; // array
int shortCutItems; // length of array

int codePage;
int characterSet;
SString language;
int lexLanguage;
int lexLPeg;
StringList apis;
SString apisFileNames;
SString functionDefinition;

bool indentOpening;
bool indentClosing;
bool indentMaintain;
int statementLookback;
StyleAndWords statementIndent;
StyleAndWords statementEnd;
StyleAndWords blockStart;
StyleAndWords blockEnd;
enum { noPPC, ppcStart, ppcMiddle, ppcEnd, ppcDummy }; /// & lt; Indicate the kind of preprocessor condition line
char preprocessorSymbol; /// & lt; Preprocessor symbol (in C: #)
StringList preprocCondStart; /// & lt; List of preprocessor conditional start keywords (in C: if ifdef ifndef)
StringList preprocCondMiddle; /// & lt; List of preprocessor conditional middle keywords (in C: else elif)
StringList preprocCondEnd; /// & lt; List of preprocessor conditional end keywords (in C: endif)

GUI::Window wSciTE; /// & lt; Contains wToolBar, wTabBar, wContent, and wStatusBar
GUI::Window wContent; /// & lt; Contains wEditor and wOutput
GUI::ScintillaWindow wEditor;
GUI::ScintillaWindow wOutput;
GUI::Window wIncrement;
GUI::Window wToolBar;
GUI::Window wStatusBar;
GUI::Window wTabBar;
GUI::Menu popup;
bool tbVisible;
bool tabVisible;
bool tabHideOne; // Hide tab bar if one buffer is opened only
bool tabMultiLine;
bool sbVisible; /// & lt; @c true if status bar is visible.
SString sbValue; /// & lt; Status bar text.
int sbNum; /// & lt; Number of the currenly displayed status bar information.
int visHeightTools;
int visHeightTab;
int visHeightStatus;
int visHeightEditor;
int heightBar;
// Prevent automatic load dialog appearing at the same time as
// other dialogs as this can leads to reentry errors.
int dialogsOnScreen;
bool topMost;
bool wrap;
bool wrapOutput;
int wrapStyle;
bool isReadOnly;
bool openFilesHere;
bool fullScreen;
enum { toolMax = 50 };
Extension *extender;
bool needReadProperties;

int heightOutput;
int heightOutputStartDrag;
GUI::Point ptStartDrag;
bool capturedMouse;
int previousHeightOutput;
bool firstPropertiesRead;
bool splitVertical; /// & lt; @c true if the split bar between editor and output is vertical.
bool bufferedDraw;
bool twoPhaseDraw;
bool bracesCheck;
bool bracesSloppy;
int bracesStyle;
int braceCount;

bool indentationWSVisible;
int indentExamine;

bool autoCompleteIgnoreCase;
bool callTipIgnoreCase;
bool autoCCausedByOnlyOne;
SString calltipWordCharacters;
SString calltipParametersStart;
SString calltipParametersEnd;
SString calltipParametersSeparators;
SString calltipEndDefinition;
SString autoCompleteStartCharacters;
SString autoCompleteFillUpCharacters;
SString wordCharacters;
SString whitespaceCharacters;
int startCalltipWord;
int currentCallTip;
int maxCallTips;
SString currentCallTipWord;
int lastPosCallTip;

bool margin;
int marginWidth;
enum { marginWidthDefault = 20};

bool foldMargin;
int foldMarginWidth;
enum { foldMarginWidthDefault = 14};

bool lineNumbers;
int lineNumbersWidth;
enum { lineNumbersWidthDefault = 4 };
bool lineNumbersExpand;

bool usePalette;
bool allowMenuActions;
int scrollOutput;
bool returnOutputToCommand;
JobQueue jobQueue;

bool macrosEnabled;
SString currentMacro;
bool recording;

PropSetFile propsEmbed;
PropSetFile propsBase;
PropSetFile propsUser;
PropSetFile propsDirectory;
PropSetFile propsLocal;
PropSetFile props;

PropSetFile propsAbbrev;

PropSetFile propsSession;

FilePath pathAbbreviations;

Localization localiser;

PropSetFile propsStatus; // Not attached to a file but need SetInteger method.

enum { bufferMax = 100 };
BufferList buffers;

// Handle buffers
sptr_t GetDocumentAt(int index);
int AddBuffer();
void UpdateBuffersCurrent();
bool IsBufferAvailable();
bool CanMakeRoom(bool maySaveIfDirty = true);
void SetDocumentAt(int index, bool updateStack = true);
Buffer *CurrentBuffer() {
return buffers.CurrentBuffer();
}
void BuffersMenu();
void Next();
void Prev();
void NextInStack();
void PrevInStack();
void EndStackedTabbing();

virtual void TabInsert(int index, const GUI::gui_char *title) = 0;
virtual void TabSelect(int index) = 0;
virtual void RemoveAllTabs() = 0;
void ShiftTab(int indexFrom, int indexTo);
void MoveTabRight();
void MoveTabLeft();

void ReadGlobalPropFile();
void ReadAbbrevPropFile();
void ReadLocalPropFile();
void ReadDirectoryPropFile();

sptr_t CallFocused(unsigned int msg, uptr_t wParam = 0, sptr_t lParam = 0);
sptr_t CallPane(int destination, unsigned int msg, uptr_t wParam = 0, sptr_t lParam = 0);
void CallChildren(unsigned int msg, uptr_t wParam = 0, sptr_t lParam = 0);
SString GetTranslationToAbout(const char * const propname, bool retainIfNotFound = true);
int LengthDocument();
int GetCaretInLine();
void GetLine(char *text, int sizeText, int line = -1);
SString GetLine(int line = -1);
void GetRange(GUI::ScintillaWindow & win, int start, int end, char *text);
int IsLinePreprocessorCondition(char *line);
bool FindMatchingPreprocessorCondition(int & curLine, int direction, int condEnd1, int condEnd2);
bool FindMatchingPreprocCondPosition(bool isForward, int & mppcAtCaret, int & mppcMatch);
bool FindMatchingBracePosition(bool editor, int & braceAtCaret, int & braceOpposite, bool sloppy);
void BraceMatch(bool editor);

virtual void WarnUser(int warnID) = 0;
void SetWindowName();
void SetFileName(FilePath openName, bool fixCase = true);
FilePath FileNameExt() const {
return filePath.Name();
}
void ClearDocument();
void CreateBuffers();
void InitialiseBuffers();
FilePath UserFilePath(const GUI::gui_char *name);
void LoadSessionFile(const GUI::gui_char *sessionName);
void RestoreRecentMenu();
void RestoreSession();
void SaveSessionFile(const GUI::gui_char *sessionName);
virtual void GetWindowPosition(int *left, int *top, int *width, int *height, int *maximize) = 0;
void SetIndentSettings();
void SetEol();
void New();
void RestoreState(const Buffer & buffer);
void Close(bool updateUI = true, bool loadingSession = false, bool makingRoomForNew = false);
bool IsAbsolutePath(const char *path);
bool Exists(const GUI::gui_char *dir, const GUI::gui_char *path, FilePath *resultPath);
void DiscoverEOLSetting();
void DiscoverIndentSetting();
SString DiscoverLanguage(const char *buf, size_t length);
void OpenFile(long fileSize, bool suppressMessage);
virtual void OpenUriList(const char *) {}
virtual bool OpenDialog(FilePath directory, const GUI::gui_char *filter) = 0;
virtual bool SaveAsDialog() = 0;
virtual void LoadSessionDialog() {}
virtual void SaveSessionDialog() {}
void CountLineEnds(int & linesCR, int & linesLF, int & linesCRLF);
enum OpenFlags {
ofNone = 0, // Default
ofNoSaveIfDirty = 1, // Suppress check for unsaved changes
ofForceLoad = 2, // Reload file even if already in a buffer
ofPreserveUndo = 4, // Do not delete undo history
ofQuiet = 8 // Avoid " Could not open file " message
};
virtual bool PreOpenCheck(const GUI::gui_char *file);
bool Open(FilePath file, OpenFlags of = ofNone);
bool OpenSelected();
void Revert();
FilePath SaveName(const char *ext);
int SaveIfUnsure(bool forceQuestion = false);
int SaveIfUnsureAll(bool forceQuestion = false);
int SaveIfUnsureForBuilt();
bool SaveIfNotOpen(const FilePath & destFile, bool fixCase);
bool Save();
void SaveAs(const GUI::gui_char *file, bool fixCase);
virtual void SaveACopy() = 0;
void SaveToHTML(FilePath saveName);
void StripTrailingSpaces();
void EnsureFinalNewLine();
bool SaveBuffer(FilePath saveName);
virtual void SaveAsHTML() = 0;
void SaveToRTF(FilePath saveName, int start = 0, int end = -1);
virtual void SaveAsRTF() = 0;
void SaveToPDF(FilePath saveName);
virtual void SaveAsPDF() = 0;
void SaveToTEX(FilePath saveName);
virtual void SaveAsTEX() = 0;
void SaveToXML(FilePath saveName);
virtual void SaveAsXML() = 0;
virtual FilePath GetDefaultDirectory() = 0;
virtual FilePath GetSciteDefaultHome() = 0;
virtual FilePath GetSciteUserHome() = 0;
FilePath GetDefaultPropertiesFileName();
FilePath GetUserPropertiesFileName();
FilePath GetDirectoryPropertiesFileName();
FilePath GetLocalPropertiesFileName();
FilePath GetAbbrevPropertiesFileName();
void OpenProperties(int propsFile);
int GetMenuCommandAsInt(SString commandName);
virtual void Print(bool) {}
virtual void PrintSetup() {}
Sci_CharacterRange GetSelection();
void SetSelection(int anchor, int currentPos);
// void SelectionExtend(char *sel, int len, char *notselchar);
void GetCTag(char *sel, int len);
SString GetRange(GUI::ScintillaWindow & win, int selStart, int selEnd);
virtual SString GetRangeInUIEncoding(GUI::ScintillaWindow & win, int selStart, int selEnd);
SString GetLine(GUI::ScintillaWindow & win, int line);
SString RangeExtendAndGrab(GUI::ScintillaWindow & wCurrent, int & selStart, int & selEnd,
bool (SciTEBase::*ischarforsel)(char ch), bool stripEol = true);
SString SelectionExtend(bool (SciTEBase::*ischarforsel)(char ch), bool stripEol = true);
void FindWordAtCaret(int & start, int & end);
bool SelectWordAtCaret();
SString SelectionWord(bool stripEol = true);
SString SelectionFilename();
void SelectionIntoProperties();
void SelectionIntoFind(bool stripEol = true);
virtual SString EncodeString(const SString & s);
virtual void Find() = 0;
virtual int WindowMessageBox(GUI::Window & w, const GUI::gui_string & msg, int style) = 0;
virtual void FindMessageBox(const SString & msg, const SString *findItem = 0) = 0;
int FindInTarget(const char *findWhat, int lenFind, int startPosition, int endPosition);
virtual void SetFind(const char *sFind);
virtual bool FindHasText() const;
virtual void SetReplace(const char *sReplace);
virtual void MoveBack(int distance);
virtual void ScrollEditorIfNeeded();
int FindNext(bool reverseDirection, bool showWarnings = true);
virtual void FindIncrement() = 0;
int IncrementSearchMode();
virtual void FindInFiles() = 0;
virtual void Replace() = 0;
void ReplaceOnce();
int DoReplaceAll(bool inSelection); // returns number of replacements or negative value if error
int ReplaceAll(bool inSelection);
int ReplaceInBuffers();
virtual void UIClosed();
virtual void UIHasFocus();
virtual void DestroyFindReplace() = 0;
virtual void GoLineDialog() = 0;
virtual bool AbbrevDialog() = 0;
virtual void TabSizeDialog() = 0;
virtual bool ParametersOpen() = 0;
virtual void ParamGrab() = 0;
virtual bool ParametersDialog(bool modal) = 0;
bool HandleXml(char ch);
SString FindOpenXmlTag(const char sel[], int nSize);
void GoMatchingBrace(bool select);
void GoMatchingPreprocCond(int direction, bool select);
virtual void FindReplace(bool replace) = 0;
void OutputAppendString(const char *s, int len = -1);
void OutputAppendStringSynchronised(const char *s, int len = -1);
void MakeOutputVisible();
void ClearJobQueue();
virtual void Execute();
virtual void StopExecute() = 0;
void GoMessage(int dir);
virtual bool StartCallTip();
char *GetNearestWords(const char *wordStart, int searchLen,
const char *separators, bool ignoreCase=false, bool exactLen=false);
virtual void FillFunctionDefinition(int pos = -1);
void ContinueCallTip();
virtual void EliminateDuplicateWords(char *words);
virtual bool StartAutoComplete();
virtual bool StartAutoCompleteWord(bool onlyOneWord);
virtual bool StartExpandAbbreviation();
virtual bool StartInsertAbbreviation();
virtual bool StartBlockComment();
virtual bool StartBoxComment();
virtual bool StartStreamComment();
unsigned int GetLinePartsInStyle(int line, int style1, int style2, SString sv[], int len);
void SetLineIndentation(int line, int indent);
int GetLineIndentation(int line);
int GetLineIndentPosition(int line);
void ConvertIndentation(int tabSize, int useTabs);
bool RangeIsAllWhitespace(int start, int end);
IndentationStatus GetIndentState(int line);
int IndentOfBlock(int line);
void MaintainIndentation(char ch);
void AutomaticIndentation(char ch);
void CharAdded(char ch);
void CharAddedOutput(int ch);
void SetTextProperties(PropSetFile & ps);
virtual void SetFileProperties(PropSetFile & ps) = 0;
virtual void UpdateStatusBar(bool bUpdateSlowData);
int GetLineLength(int line);
int GetCurrentLineNumber();
int GetCurrentScrollPosition();
virtual void AddCommand(const SString & cmd, const SString & dir,
JobSubsystem jobType, const SString & input = " " ,
int flags = 0);
virtual void AboutDialog() = 0;
virtual void QuitProgram() = 0;
void CloseTab(int tab);
void CloseAllBuffers(bool loadingSession = false);
int SaveAllBuffers(bool forceQuestion, bool alwaysYes = false);
void SaveTitledBuffers();
virtual void CopyAsRTF() {}
virtual void CopyPath() {}
void SetLineNumberWidth();
void MenuCommand(int cmdID, int source = 0);
void FoldChanged(int line, int levelNow, int levelPrev);
void FoldChanged(int position);
void Expand(int & line, bool doExpand, bool force = false,
int visLevels = 0, int level = -1);
void FoldAll();
void ToggleFoldRecursive(int line, int level);
void EnsureAllChildrenVisible(int line, int level);
void EnsureRangeVisible(int posStart, int posEnd, bool enforcePolicy = true);
void GotoLineEnsureVisible(int line);
bool MarginClick(int position, int modifiers);
void NewLineInOutput();
virtual void SetStatusBarText(const char *s) = 0;
virtual void Notify(SCNotification *notification);
virtual void ShowToolBar() = 0;
virtual void ShowTabBar() = 0;
virtual void ShowStatusBar() = 0;
virtual void ActivateWindow(const char *timestamp) = 0;

void RemoveFindMarks();
int MarkAll();
void BookmarkAdd(int lineno = -1);
void BookmarkDelete(int lineno = -1);
bool BookmarkPresent(int lineno = -1);
void BookmarkToggle(int lineno = -1);
void BookmarkNext(bool forwardScan = true, bool select = false);
void ToggleOutputVisible();
virtual void SizeContentWindows() = 0;
virtual void SizeSubWindows() = 0;

virtual void SetMenuItem(int menuNumber, int position, int itemID,
const GUI::gui_char *text, const GUI::gui_char *mnemonic = 0) = 0;
virtual void RedrawMenu() {}
virtual void DestroyMenuItem(int menuNumber, int itemID) = 0;
virtual void CheckAMenuItem(int wIDCheckItem, bool val) = 0;
virtual void EnableAMenuItem(int wIDCheckItem, bool val) = 0;
virtual void CheckMenusClipboard();
virtual void CheckMenus();
virtual void AddToPopUp(const char *label, int cmd = 0, bool enabled = true) = 0;
void ContextMenu(GUI::ScintillaWindow & wSource, GUI::Point pt, GUI::Window wCmd);

void DeleteFileStackMenu();
void SetFileStackMenu();
void DropFileStackTop();
bool AddFileToBuffer(FilePath file, int pos);
void AddFileToStack(FilePath file, Sci_CharacterRange selection, int scrollPos);
void RemoveFileFromStack(FilePath file);
RecentFile GetFilePosition();
void DisplayAround(const RecentFile & rf);
void StackMenu(int pos);
void StackMenuNext();
void StackMenuPrev();

void RemoveToolsMenu();
void SetMenuItemLocalised(int menuNumber, int position, int itemID,
const char *text, const char *mnemonic);
void SetToolsMenu();
JobSubsystem SubsystemType(char c);
JobSubsystem SubsystemType(const char *cmd, int item = -1);
void ToolsMenu(int item);

void AssignKey(int key, int mods, int cmd);
void ViewWhitespace(bool view);
void SetAboutMessage(GUI::ScintillaWindow & wsci, const char *appTitle);
void SetImportMenu();
void ImportMenu(int pos);
void SetLanguageMenu();
void SetPropertiesInitial();
GUI::gui_string LocaliseMessage(const char *s,
const GUI::gui_char *param0 = 0, const GUI::gui_char *param1 = 0, const GUI::gui_char *param2 = 0);
virtual void ReadLocalization();
SString GetFileNameProperty(const char *name);
virtual void ReadPropertiesInitial();
void ReadFontProperties();
void SetOverrideLanguage(int cmdID);
StyleAndWords GetStyleAndWords(const char *base);
SString ExtensionFileName();
const char *GetNextPropItem(const char *pStart, char *pPropItem, int maxLen);
void ForwardPropertyToEditor(const char *key);
void DefineMarker(int marker, int markerType, Colour fore, Colour back, Colour backSelected);
void ReadAPI(const SString & fileNameForExtension);
SString FindLanguageProperty(const char *pattern, const char *defaultValue = " " );
virtual void ReadProperties();
void SetOneStyle(GUI::ScintillaWindow & win, int style, const StyleDefinition & sd);
void SetStyleFor(GUI::ScintillaWindow & win, const char *language);
void ReloadProperties();

void CheckReload();
void Activate(bool activeApp);
GUI::Rectangle GetClientRectangle();
void Redraw();
int NormaliseSplit(int splitPos);
void MoveSplit(GUI::Point ptNewDrag);

void UIAvailable();
void PerformOne(char *action);
void StartRecordMacro();
void StopRecordMacro();
void StartPlayMacro();
bool RecordMacroCommand(SCNotification *notification);
void ExecuteMacroCommand(const char *command);
void AskMacroList();
bool StartMacroList(const char *words);
void ContinueMacroList(const char *stxt);
bool ProcessCommandLine(GUI::gui_string & args, int phase);
virtual bool IsStdinBlocked();
void OpenFromStdin(bool UseOutputPane);
void OpenFilesFromStdin();
enum GrepFlags {
grepNone = 0, grepWholeWord = 1, grepMatchCase = 2, grepStdOut = 4,
grepDot = 8, grepBinary = 16
};
virtual bool GrepIntoDirectory(const FilePath & directory);
void GrepRecursive(GrepFlags gf, FilePath baseDir, const char *searchString, const GUI::gui_char *fileTypes);
void InternalGrep(GrepFlags gf, const GUI::gui_char *directory, const GUI::gui_char *files, const char *search);
void EnumProperties(const char *action);
void SendOneProperty(const char *kind, const char *key, const char *val);
void PropertyFromDirector(const char *arg);
void PropertyToDirector(const char *arg);

// ExtensionAPI
sptr_t Send(Pane p, unsigned int msg, uptr_t wParam = 0, sptr_t lParam = 0);
char *Range(Pane p, int start, int end);
void Remove(Pane p, int start, int end);
void Insert(Pane p, int pos, const char *s);
void Trace(const char *s);
char *Property(const char *key);
void SetProperty(const char *key, const char *val);
void UnsetProperty(const char *key);
uptr_t GetInstance();
void ShutDown();
void Perform(const char *actions);
void DoMenuCommand(int cmdID);

// Valid CurrentWord characters
bool iswordcharforsel(char ch);
bool isfilenamecharforsel(char ch);
bool islexerwordcharforsel(char ch);

CurrentWordHighlight currentWordHighlight;
void HighlightCurrentWord(bool highlight);
public:

enum { maxParam = 4 };

SciTEBase(Extension *ext = 0);
virtual ~SciTEBase();

void ProcessExecute();
GUI::WindowID GetID() { return wSciTE.GetID(); }

private:
// un-implemented copy-constructor and assignment operator
SciTEBase(const SciTEBase & );
void operator=(const SciTEBase & );
};

/// Base size of file I/O operations.
const int blockSize = 131072;

#if defined(__unix__)
// MessageBox
#define MB_OK (0L)
#define MB_YESNO (0x4L)
#define MB_YESNOCANCEL (0x3L)
#define MB_ICONWARNING (0x30L)
#define MB_ICONQUESTION (0x20L)
#define IDOK (1)
#define IDCANCEL (2)
#define IDYES (6)
#define IDNO (7)
#endif

int ControlIDOfCommand(unsigned long);
void LowerCaseString(char *s);
long ColourOfProperty(PropSetFile & props, const char *key, Colour colourDefault);
void WindowSetFocus(GUI::ScintillaWindow & w);

inline bool isspacechar(unsigned char ch) {
return (ch == ' ') || ((ch & gt; = 0x09) & & (ch & lt; = 0x0d));
}


scite228.zip > scite_lua_win.h

// SciTE - Scintilla based Text Editor
/** @file scite_lua_win.h
** SciTE Lua scripting interface.
**/
// Copyright 2010 by Neil Hodgson & lt; neilh@scintilla.org & gt;
// The License.txt file describes the conditions under which this software may be distributed.

/* Modifications for Windows to allow UTF-8 file names and command lines */
/*
Imported into Lua build with -DLUA_USER_H=\ " scite_lua_win.h\ "
Redirect fopen and _popen to functions that treat their arguments as UTF-8.
If UTF-8 does not work then retry with the original strings as may be in locale characters.
*/
#if defined(LUA_WIN)
#include & lt; stdio.h & gt;
FILE *scite_lua_fopen(const char *filename, const char *mode);
#define fopen scite_lua_fopen
FILE *scite_lua_popen(const char *filename, const char *mode);
#define _popen scite_lua_popen
#endif


scite228.zip > StyleWriter.h

// SciTE - Scintilla based Text Editor
/** @file StyleWriter.h
** Simple buffered interface to the text and styles of a document held by Scintilla.
**/
// Copyright 1998-2010 by Neil Hodgson & lt; neilh@scintilla.org & gt;
// The License.txt file describes the conditions under which this software may be distributed.

#ifndef STYLEWRITER_H
#define STYLEWRITER_H

// Read only access to a document, its styles and other data
class TextReader {
// Private so TextReader objects can not be copied
TextReader(const TextReader & source);
TextReader & operator=(const TextReader & );
protected:
enum {extremePosition=0x7FFFFFFF};
/** @a bufferSize is a trade off between time taken to copy the characters
* and retrieval overhead.
* @a slopSize positions the buffer before the desired position
* in case there is some backtracking. */
enum {bufferSize=4000, slopSize=bufferSize/8};
char buf[bufferSize+1];
int startPos;
int endPos;
int codePage;

GUI::ScintillaWindow & sw;
int lenDoc;

bool InternalIsLeadByte(char ch) const;
void Fill(int position);
public:
TextReader(GUI::ScintillaWindow & sw_) :
startPos(extremePosition),
endPos(0),
codePage(0),
sw(sw_),
lenDoc(-1) {
}
char operator[](int position) {
if (position & lt; startPos || position & gt; = endPos) {
Fill(position);
}
return buf[position - startPos];
}
/** Safe version of operator[], returning a defined value for invalid position. */
char SafeGetCharAt(int position, char chDefault=' ') {
if (position & lt; startPos || position & gt; = endPos) {
Fill(position);
if (position & lt; startPos || position & gt; = endPos) {
// Position is outside range of document
return chDefault;
}
}
return buf[position - startPos];
}
bool IsLeadByte(char ch) const {
return codePage & & InternalIsLeadByte(ch);
}
void SetCodePage(int codePage_) {
codePage = codePage_;
}
bool Match(int pos, const char *s);
char StyleAt(int position);
int GetLine(int position);
int LineStart(int line);
int LevelAt(int line);
int Length();
int GetLineState(int line);
};

// Adds methods needed to write styles and folding
class StyleWriter : public TextReader {
// Private so StyleWriter objects can not be copied
StyleWriter(const StyleWriter & source);
StyleWriter & operator=(const StyleWriter & );
protected:
char styleBuf[bufferSize];
int validLen;
unsigned int startSeg;
public:
StyleWriter(GUI::ScintillaWindow & sw_) :
TextReader(sw_),
validLen(0),
startSeg(0) {
}
void Flush();
int SetLineState(int line, int state);

void StartAt(unsigned int start, char chMask=31);
unsigned int GetStartSegment() { return startSeg; }
void StartSegment(unsigned int pos);
void ColourTo(unsigned int pos, int chAttr);
void SetLevel(int line, int level);
};

#endif


scite228.zip > SciTEKeys.h

// SciTE - Scintilla based Text Editor
/** @file SciTEKeys.h
** SciTE keyboard shortcut facilities.
**/
// Copyright 1998-2004 by Neil Hodgson & lt; neilh@scintilla.org & gt;
// The License.txt file describes the conditions under which this software may be distributed.

#ifndef SCITEKEYS_H
#define SCITEKEYS_H

class SciTEKeys {
public:
static long ParseKeyCode(const char *mnemonic);
static bool MatchKeyCode(long parsedKeyCode, int key, int modifiers);
};

#endif


scite228.zip > GUI.h

// SciTE - Scintilla based Text Editor
/** @file GUI.h
** Interface to platform GUI facilities.
** Split off from Scintilla's Platform.h to avoid SciTE depending on implementation of Scintilla.
** Implementation in win32/GUIWin.cxx for Windows and gtk/GUIGTK.cxx for GTK+.
**/
// Copyright 1998-2010 by Neil Hodgson & lt; neilh@scintilla.org & gt;
// The License.txt file describes the conditions under which this software may be distributed.

#ifndef GUI_H
#define GUI_H

namespace GUI {

class Point {
public:
int x;
int y;

explicit Point(int x_=0, int y_=0) : x(x_), y(y_) {
}
};

class Rectangle {
public:
int left;
int top;
int right;
int bottom;

Rectangle(int left_=0, int top_=0, int right_=0, int bottom_ = 0) :
left(left_), top(top_), right(right_), bottom(bottom_) {
}
bool Contains(Point pt) const {
return (pt.x & gt; = left) & & (pt.x & lt; = right) & &
(pt.y & gt; = top) & & (pt.y & lt; = bottom);
}
int Width() const { return right - left; }
int Height() const { return bottom - top; }
bool operator==(const Rectangle & other) const {
return (left == other.left) & &
(top == other.top) & &
(right == other.right) & &
(bottom == other.bottom);
}
};

#if defined(GTK) || defined(__APPLE__)

// On GTK+ and OS X use UTF-8 char strings

typedef char gui_char;
typedef std::string gui_string;

#define GUI_TEXT(q) q

#else

// On Win32 use UTF-16 wide char strings

typedef wchar_t gui_char;
typedef std::wstring gui_string;

#define GUI_TEXT(q) L##q

#endif

gui_string StringFromUTF8(const char *s);
std::string UTF8FromString(const gui_string & s);
gui_string StringFromInteger(int i);

typedef void *WindowID;
class Window {
protected:
WindowID wid;
public:
Window() : wid(0) {
}
Window & operator=(WindowID wid_) {
wid = wid_;
return *this;
}
WindowID GetID() const {
return wid;
}
void SetID(WindowID wid_) {
wid = wid_;
}
bool Created() const {
return wid != 0;
}
void Destroy();
bool HasFocus();
Rectangle GetPosition();
void SetPosition(Rectangle rc);
Rectangle GetClientPosition();
void Show(bool show=true);
void InvalidateAll();
void SetTitle(const gui_char *s);
};

typedef void *MenuID;
class Menu {
MenuID mid;
public:
Menu() : mid(0) {
}
MenuID GetID() const {
return mid;
}
void CreatePopUp();
void Destroy();
void Show(Point pt, Window & w);
};

class ElapsedTime {
long bigBit;
long littleBit;
public:
ElapsedTime();
double Duration(bool reset=false);
};

struct ScintillaFailure {
sptr_t status;
ScintillaFailure(sptr_t status_) : status(status_) {
}
};

class ScintillaWindow : public Window {
// Private so ScintillaWindow objects can not be copied
ScintillaWindow(const ScintillaWindow & source);
ScintillaWindow & operator=(const ScintillaWindow & );
SciFnDirect fn;
sptr_t ptr;
public:
ScintillaWindow() : fn(0), ptr(0) {
}
void SetID(WindowID wid_) {
wid = wid_;
fn = 0;
ptr = 0;
if (wid) {
fn = reinterpret_cast & lt; SciFnDirect & gt; (
Send(SCI_GETDIRECTFUNCTION, 0, 0));
ptr = Send(SCI_GETDIRECTPOINTER, 0, 0);
}
}
bool CanCall() const {
return wid & & fn & & ptr;
}
sptr_t Call(unsigned int msg, uptr_t wParam=0, sptr_t lParam=0) {
sptr_t retVal = fn(ptr, msg, wParam, lParam);
sptr_t status = fn(ptr, SCI_GETSTATUS, 0, 0);
if (status & gt; 0)
throw ScintillaFailure(status);
return retVal;
}
sptr_t CallString(unsigned int msg, uptr_t wParam, const char *s) {
return Call(msg, wParam, reinterpret_cast & lt; sptr_t & gt; (s));
}
sptr_t Send(unsigned int msg, uptr_t wParam=0, sptr_t lParam=0);
sptr_t SendPointer(unsigned int msg, uptr_t wParam=0, void *lParam=0);
};

bool IsDBCSLeadByte(int codePage, char ch);

}

#if defined(SCI_NAMESPACE)

// Scintilla namespace may or may not be turned on.
// If it is turned on, then make the structures usable without the Scintilla:: prefix

using Scintilla::Sci_CharacterRange;
using Scintilla::Sci_TextRange;
using Scintilla::Sci_TextToFind;
using Scintilla::SCNotification;

#endif

#endif


scite228.zip > FilePath.h

// SciTE - Scintilla based Text Editor
/** @file FilePath.h
** Definition of platform independent base class of editor.
**/
// Copyright 1998-2005 by Neil Hodgson & lt; neilh@scintilla.org & gt;
// The License.txt file describes the conditions under which this software may be distributed.

extern const GUI::gui_char pathSepString[];
extern const GUI::gui_char pathSepChar;
extern const GUI::gui_char listSepString[];
extern const GUI::gui_char configFileVisibilityString[];
extern const GUI::gui_char fileRead[];
extern const GUI::gui_char fileWrite[];

#if defined(__unix__)
#include & lt; limits.h & gt;
#ifdef PATH_MAX
#define MAX_PATH PATH_MAX
#else
#define MAX_PATH 260
#endif
#endif

#ifdef WIN32
#ifdef _MSC_VER
// Shut up level 4 warning:
// warning C4710: function 'void whatever(...)' not inlined
// warning C4800: forcing value to bool 'true' or 'false' (performance warning)
#pragma warning(disable: 4710 4800)
#endif
#ifdef __DMC__
#include & lt; time.h & gt;
#endif
#endif

class FilePath;

class FilePathSet;

class FilePath {
GUI::gui_string fileName;
public:
FilePath(const GUI::gui_char *fileName_ = GUI_TEXT( " " ));
FilePath(const GUI::gui_string & fileName_);
FilePath(FilePath const & directory, FilePath const & name);
void Set(const GUI::gui_char *fileName_);
void Set(FilePath const & other);
void Set(FilePath const & directory, FilePath const & name);
void SetDirectory(FilePath directory);
void Init();
bool SameNameAs(const GUI::gui_char *other) const;
bool SameNameAs(const FilePath & other) const;
bool IsSet() const;
bool IsUntitled() const;
bool IsAbsolute() const;
bool IsRoot() const;
static int RootLength();
const GUI::gui_char *AsInternal() const;
std::string AsUTF8() const;
FilePath Name() const;
FilePath BaseName() const;
FilePath Extension() const;
FilePath Directory() const;
void FixName();
void LowerCaseExtension();
FilePath AbsolutePath() const;
FilePath NormalizePath() const;
static FilePath GetWorkingDirectory();
bool SetWorkingDirectory() const;
void List(FilePathSet & directories, FilePathSet & files);
FILE *Open(const GUI::gui_char *mode) const;
void Remove() const;
time_t ModifiedTime() const;
long GetFileLength() const;
bool Exists() const;
bool IsDirectory() const;
bool Matches(const GUI::gui_char *pattern) const;
};

class FilePathSet {
size_t size;
size_t lengthBody;
FilePath *body;
// Private so won't be called.
FilePathSet & operator=(const FilePathSet & );
public:
FilePathSet(int size_ = 10);
FilePathSet(const FilePathSet & other);
~FilePathSet();
FilePath At(size_t pos) const;
void Append(FilePath fp);
size_t Length() const;
};


scite228.zip > JobQueue.h

// SciTE - Scintilla based Text Editor
/** @file JobQueue.h
** Define job queue
**/
// SciTE & Scintilla copyright 1998-2003 by Neil Hodgson & lt; neilh@scintilla.org & gt;
// Copyright 2007 by Neil Hodgson & lt; neilh@scintilla.org & gt; , from April White & lt; april_white@sympatico.ca & gt;
// The License.txt file describes the conditions under which this software may be distributed.

// TODO: see http://www.codeproject.com/threads/cppsyncstm.asp

#ifndef JOBQUEUE_H
#define JOBQUEUE_H

enum JobSubsystem {
jobCLI = 0, jobGUI = 1, jobShell = 2, jobExtension = 3, jobHelp = 4, jobOtherHelp = 5, jobGrep = 6};

enum JobFlags {
jobForceQueue = 1,
jobHasInput = 2,
jobQuiet = 4,
// 8 reserved for jobVeryQuiet
jobRepSelMask = 48,
jobRepSelYes = 16,
jobRepSelAuto = 32,
jobGroupUndo = 64
};

class Job {
public:
SString command;
FilePath directory;
SString input;
JobSubsystem jobType;
int flags;

Job() {
Clear();
}

void Clear() {
command = " " ;
directory.Init();
input = " " ;
jobType = jobCLI;
flags = 0;
}
};

class JobQueue {
public:
Mutex *mutex;
bool clearBeforeExecute;
bool isBuilding;
bool isBuilt;
bool executing;
enum { commandMax = 2 };
int commandCurrent;
Job jobQueue[commandMax];
bool jobUsesOutputPane;
long cancelFlag;
bool timeCommands;

JobQueue() {
mutex = Mutex::Create();
clearBeforeExecute = false;
isBuilding = false;
isBuilt = false;
executing = false;
commandCurrent = 0;
jobUsesOutputPane = false;
cancelFlag = 0L;
timeCommands = false;
}

~JobQueue() {
delete mutex;
mutex = 0;
}

bool TimeCommands() const {
Lock lock(mutex);
return timeCommands;
}

bool ClearBeforeExecute() const {
Lock lock(mutex);
return clearBeforeExecute;
}

bool ShowOutputPane() const {
Lock lock(mutex);
return jobUsesOutputPane;
}

bool IsExecuting() const {
Lock lock(mutex);
return executing;
}

void SetExecuting(bool state) {
Lock lock(mutex);
executing = state;
}

long SetCancelFlag(long value) {
Lock lock(mutex);
long cancelFlagPrevious = cancelFlag;
cancelFlag = value;
return cancelFlagPrevious;
}

long Cancelled() {
Lock lock(mutex);
return cancelFlag;
}
};

#endif


scite228.zip > StringHelpers.h

// SciTE - Scintilla based Text Editor
/** @file StringHelpers.h
** Definition of widely useful string functions.
**/
// Copyright 2010 by Neil Hodgson & lt; neilh@scintilla.org & gt;
// The License.txt file describes the conditions under which this software may be distributed.

bool StartsWith(GUI::gui_string const & s, GUI::gui_string const & end);
bool EndsWith(GUI::gui_string const & s, GUI::gui_string const & end);
int Substitute(GUI::gui_string & s, const GUI::gui_string & sFind, const GUI::gui_string & sReplace);

char *Slash(const char *s, bool quoteQuotes);
unsigned int UnSlash(char *s);
unsigned int UnSlashLowOctal(char *s);

class ILocalize {
public:
virtual GUI::gui_string Text(const char *s, bool retainIfNotFound=true) = 0;
};

/**
* This is a fixed length list of strings suitable for display in combo boxes
* as a memory of user entries.
*/
template & lt; int sz & gt;
class EntryMemory {
std::string entries[sz];
public:
void Insert(const std::string & s) {
for (int i = 0; i & lt; sz; i++) {
if (entries[i] == s) {
for (int j = i; j & gt; 0; j--) {
entries[j] = entries[j - 1];
}
entries[0] = s;
return;
}
}
for (int k = sz - 1; k & gt; 0; k--) {
entries[k] = entries[k - 1];
}
entries[0] = s;
}
void AppendIfNotPresent(const std::string & s) {
for (int i = 0; i & lt; sz; i++) {
if (entries[i] == s) {
return;
}
if (0 == entries[i].length()) {
entries[i] = s;
return;
}
}
}
void AppendList(const std::string & s, char sep = '|') {
int start = 0;
int end = 0;
while (s[end] != '\0') {
end = start;
while ((s[end] != sep) & & (s[end] != '\0'))
++end;
AppendIfNotPresent(s.substr(start, end-start));
start = end + 1;
}
}
int Length() const {
int len = 0;
for (int i = 0; i & lt; sz; i++)
if (entries[i].length())
len++;
return len;
}
std::string At(int n) const {
return entries[n];
}
std::vector & lt; std::string & gt; AsVector() {
std::vector & lt; std::string & gt; ret;
for (int i = 0; i & lt; sz; i++) {
if (entries[i].length())
ret.push_back(entries[i].c_str());
}
return ret;
}
};

typedef EntryMemory & lt; 10 & gt; ComboMemory;


scite228.zip > SciTE.h

// SciTE - Scintilla based Text Editor
/** @file SciTE.h
** Define command IDs used within SciTE.
**/
// Copyright 1998-2003 by Neil Hodgson & lt; neilh@scintilla.org & gt;
// The License.txt file describes the conditions under which this software may be distributed.

#ifndef SCITE_H
#define SCITE_H

// Version numbers and dates
#define VERSION_SCITE " 2.28 "
#define VERSION_WORDS 2, 2, 8, 0
#define COPYRIGHT_DATES " December 1998-August 2011 "
#define COPYRIGHT_YEARS " 1998-2011 "

// Menu IDs.
// These are located 100 apart. No one will want more than 100 in each menu ;)
#define IDM_MRUFILE 1000
#define IDM_TOOLS 1100
#define IDM_BUFFER 1200
#define IDM_IMPORT 1300
#define IDM_LANGUAGE 1400

// File
#define IDM_NEW 101
#define IDM_OPEN 102
#define IDM_OPENSELECTED 103
#define IDM_REVERT 104
#define IDM_CLOSE 105
#define IDM_SAVE 106
#define IDM_SAVEAS 110
#define IDM_SAVEASHTML 111
#define IDM_SAVEASRTF 112
#define IDM_SAVEASPDF 113
#define IDM_FILER 114
#define IDM_SAVEASTEX 115
#define IDM_SAVEACOPY 116
#define IDM_SAVEASXML 117
#define IDM_COPYPATH 118
#define IDM_MRU_SEP 120
#define IDM_MRU_SUB 121
#define IDM_PRINTSETUP 130
#define IDM_PRINT 131
#define IDM_LOADSESSION 132
#define IDM_SAVESESSION 133
#define IDM_QUIT 140
#define IDM_ENCODING_DEFAULT 150
#define IDM_ENCODING_UCS2BE 151
#define IDM_ENCODING_UCS2LE 152
#define IDM_ENCODING_UTF8 153
#define IDM_ENCODING_UCOOKIE 154

#define MRU_START 17
#define IMPORT_START 20
#define TOOLS_START 3

// Edit
#define IDM_UNDO 201
#define IDM_REDO 202
#define IDM_CUT 203
#define IDM_COPY 204
#define IDM_PASTE 205
#define IDM_CLEAR 206
#define IDM_SELECTALL 207
#define IDM_PASTEANDDOWN 208
#define IDM_FIND 210
#define IDM_FINDNEXT 211
#define IDM_FINDNEXTBACK 212
#define IDM_FINDNEXTSEL 213
#define IDM_FINDNEXTBACKSEL 214
#define IDM_FINDINFILES 215
#define IDM_REPLACE 216
#define IDM_SELECTION_FOR_FIND 217
#define IDM_GOTO 220
#define IDM_BOOKMARK_NEXT 221
#define IDM_BOOKMARK_TOGGLE 222
#define IDM_BOOKMARK_PREV 223
#define IDM_BOOKMARK_CLEARALL 224
#define IDM_BOOKMARK_NEXT_SELECT 225
#define IDM_BOOKMARK_PREV_SELECT 226
#define IDM_MATCHBRACE 230
#define IDM_SELECTTOBRACE 231
#define IDM_SHOWCALLTIP 232
#define IDM_COMPLETE 233
#define IDM_COMPLETEWORD 234
#define IDM_EXPAND 235
#define IDM_TOGGLE_FOLDALL 236
#define IDM_TOGGLE_FOLDRECURSIVE 237
#define IDM_EXPAND_ENSURECHILDRENVISIBLE 238
#define IDM_UPRCASE 240
#define IDM_LWRCASE 241
#define IDM_ABBREV 242
#define IDM_BLOCK_COMMENT 243
#define IDM_STREAM_COMMENT 244
#define IDM_COPYASRTF 245
#define IDM_BOX_COMMENT 246
#define IDM_INS_ABBREV 247
#define IDM_JOIN 248
#define IDM_SPLIT 249
#define IDM_DUPLICATE 250
#define IDM_INCSEARCH 252
#define IDM_ENTERSELECTION 256

#define IDC_INCFINDTEXT 253
#define IDC_INCFINDBTNOK 254
#define IDC_EDIT1 1000
#define IDC_STATIC -1


#define IDM_PREVMATCHPPC 260
#define IDM_SELECTTOPREVMATCHPPC 261
#define IDM_NEXTMATCHPPC 262
#define IDM_SELECTTONEXTMATCHPPC 263

// Tools
#define IDM_COMPILE 301
#define IDM_BUILD 302
#define IDM_GO 303
#define IDM_STOPEXECUTE 304
#define IDM_FINISHEDEXECUTE 305
#define IDM_NEXTMSG 306
#define IDM_PREVMSG 307

#define IDM_MACRO_SEP 310
#define IDM_MACRORECORD 311
#define IDM_MACROSTOPRECORD 312
#define IDM_MACROPLAY 313
#define IDM_MACROLIST 314

#define IDM_ACTIVATE 320

#define IDM_SRCWIN 350
#define IDM_RUNWIN 351
#define IDM_TOOLWIN 352
#define IDM_STATUSWIN 353
#define IDM_TABWIN 354

// Options
#define IDM_SPLITVERTICAL 401
#define IDM_VIEWSPACE 402
#define IDM_VIEWEOL 403
#define IDM_VIEWGUIDES 404
#define IDM_SELMARGIN 405
#define IDM_FOLDMARGIN 406
#define IDM_LINENUMBERMARGIN 407
#define IDM_VIEWTOOLBAR 408
#define IDM_TOGGLEOUTPUT 409
#define IDM_VIEWTABBAR 410
#define IDM_VIEWSTATUSBAR 411
#define IDM_TOGGLEPARAMETERS 412
#define IDM_OPENFILESHERE 413
#define IDM_WRAP 414
#define IDM_WRAPOUTPUT 415
#define IDM_READONLY 416

#define IDM_CLEAROUTPUT 420
#define IDM_SWITCHPANE 421

#define IDM_EOL_CRLF 430
#define IDM_EOL_CR 431
#define IDM_EOL_LF 432
#define IDM_EOL_CONVERT 433

#define IDM_TABSIZE 440

#define IDM_MONOFONT 450

#define IDM_OPENLOCALPROPERTIES 460
#define IDM_OPENUSERPROPERTIES 461
#define IDM_OPENGLOBALPROPERTIES 462
#define IDM_OPENABBREVPROPERTIES 463
#define IDM_OPENLUAEXTERNALFILE 464
#define IDM_OPENDIRECTORYPROPERTIES 465

//#define IDM_SELECTIONMARGIN 490
//#define IDM_BUFFEREDDRAW 491
//#define IDM_USEPALETTE 492

// Buffers
#define IDM_PREVFILE 501
#define IDM_NEXTFILE 502
#define IDM_CLOSEALL 503
#define IDM_SAVEALL 504
#define IDM_BUFFERSEP 505
#define IDM_PREVFILESTACK 506
#define IDM_NEXTFILESTACK 507
#define IDM_MOVETABRIGHT 508
#define IDM_MOVETABLEFT 509

#define IDM_WHOLEWORD 800
#define IDM_MATCHCASE 801
#define IDM_REGEXP 802
#define IDM_WRAPAROUND 803
#define IDM_UNSLASH 804
#define IDM_DIRECTIONUP 805
#define IDM_DIRECTIONDOWN 806

// Help
#define IDM_HELP 901
#define IDM_ABOUT 902
#define IDM_HELP_SCITE 903

// Windows specific windowing options
#define IDM_ONTOP 960
#define IDM_FULLSCREEN 961
#define IDC_TABCLOSE 962
#define IDC_SHIFTTAB 963

// Dialog control IDs
#define IDGOLINE 220
#define IDABOUTSCINTILLA 221
#define IDFINDWHAT 222
#define IDFILES 223
#define IDDIRECTORY 224
#define IDCURRLINE 225
#define IDLASTLINE 226
#define IDEXTEND 227
#define IDTABSIZE 228
#define IDINDENTSIZE 229
#define IDUSETABS 230

#define IDREPLACEWITH 231
#define IDWHOLEWORD 232
#define IDMATCHCASE 233
#define IDDIRECTIONUP 234
#define IDDIRECTIONDOWN 235
#define IDREPLACE 236
#define IDREPLACEALL 237
#define IDREPLACEINSEL 238
#define IDREGEXP 239
#define IDWRAP 240

#define IDUNSLASH 241
#define IDCMD 242

// id for the browse button in the grep dialog
#define IDBROWSE 243

#define IDABBREV 244

#define IDREPLACEINBUF 244
#define IDMARKALL 245

#define IDGOLINECHAR 246
#define IDCURRLINECHAR 247
#define IDREPLDONE 248

#define IDDOTDOT 249
#define IDFINDINSTYLE 250
#define IDFINDSTYLE 251
#define IDCONVERT 252

#define IDPARAMSTART 300

// Dialog IDs
#define IDD_FIND 400
#define IDD_REPLACE 401
#define IDD_BUFFERS 402
#define IDD_FIND_ADV 403
#define IDD_REPLACE_ADV 404

// Resource IDs
#define IDR_CLOSEFILE 100
#define IDC_DRAGDROP 401
#define IDBM_WORD 101
#define IDBM_CASE 102
#define IDBM_REGEX 103
#define IDBM_BACKSLASH 104
#define IDBM_AROUND 105
#define IDBM_UP 106
#endif


scite228.zip > MultiplexExtension.h

// SciTE - Scintilla based Text Editor
/** @file MultiplexExtension.h
** Extension that manages / dispatches messages to multiple extensions.
**/
// Copyright 1998-2003 by Neil Hodgson & lt; neilh@scintilla.org & gt;
// The License.txt file describes the conditions under which this software may be distributed.

#ifndef MULTIPLEXEXTENSION_H
#define MULTIPLEXEXTENSION_H

#include " Extender.h "

// MultiplexExtension manages multiple Extension objects, similar to
// what is proposed in the SciTE Extension documentation. Each
// message is sent to each contained extension object in turn until
// one indicates that the message has been handled and does not need
// to be processed further. Certain messages (Initialise, Finalise
// Clear, and SendProperty) are sent to all contained extensions
// regardless of return code.
//
// The Director extension incorrectly returns true for all messages,
// meaning that other extensions will never see the message if
// DirectorExtension comes before them in the list. This has been
// fixed at source.
//
// Extensions are added to the multiplexer by calling RegisterExtension.
// The extensions are prioritized with the first one added having the
// highest priority. If more flexibility is needed in order to support
// dynamic discovery of extensions and assignment of priority, that will
// be added later. If the ability to remove extensions becomes important,
// that can be added as well (later).
//
// The multiplexer does not manage the lifetime of the extension objects
// that are registered with it. If that functionality later turns out
// to be needed, it will be added at that time. (Broken record? Do the
// simplest thing...) However, the option to " not " manage the lifecycle
// is a valid one, since it often makes sense to implement extensions as
// singletons.

class MultiplexExtension: public Extension {
public:
MultiplexExtension();
virtual ~MultiplexExtension();

bool RegisterExtension(Extension & ext_);

virtual bool Initialise(ExtensionAPI *host_);
virtual bool Finalise();
virtual bool Clear();
virtual bool Load(const char *filename);

virtual bool InitBuffer(int);
virtual bool ActivateBuffer(int);
virtual bool RemoveBuffer(int);

virtual bool OnOpen(const char *);
virtual bool OnSwitchFile(const char *);
virtual bool OnBeforeSave(const char *);
virtual bool OnSave(const char *);
virtual bool OnChar(char);
virtual bool OnExecute(const char *);
virtual bool OnSavePointReached();
virtual bool OnSavePointLeft();
virtual bool OnStyle(unsigned int, int, int, StyleWriter *);
virtual bool OnDoubleClick();
virtual bool OnUpdateUI();
virtual bool OnMarginClick();
virtual bool OnMacro(const char *, const char *);
virtual bool OnUserListSelection(int, const char *);

virtual bool SendProperty(const char *);

virtual bool OnKey(int, int);
virtual bool OnDwellStart(int, const char *);
virtual bool OnClose(const char *);

private:
Extension **extensions;
int extensionCount;
ExtensionAPI *host;

// Copying is unsupported.
MultiplexExtension(const MultiplexExtension & copy);
MultiplexExtension & operator=(const MultiplexExtension & copy);
};

#endif


scite228.zip > LuaExtension.h

// SciTE - Scintilla based Text Editor
// LuaExtension.h - Lua scripting extension
// Copyright 1998-2000 by Neil Hodgson & lt; neilh@scintilla.org & gt;
// The License.txt file describes the conditions under which this software may be distributed.

class LuaExtension : public Extension {
private:
LuaExtension(); // Singleton
LuaExtension(const LuaExtension & ); // Disable copy ctor
void operator=(const LuaExtension & ); // Disable operator=

public:
static LuaExtension & Instance();

virtual ~LuaExtension();

virtual bool Initialise(ExtensionAPI *host_);
virtual bool Finalise();
virtual bool Clear();
virtual bool Load(const char *filename);

virtual bool InitBuffer(int);
virtual bool ActivateBuffer(int);
virtual bool RemoveBuffer(int);

virtual bool OnOpen(const char *filename);
virtual bool OnSwitchFile(const char *filename);
virtual bool OnBeforeSave(const char *filename);
virtual bool OnSave(const char *filename);
virtual bool OnChar(char ch);
virtual bool OnExecute(const char *s);
virtual bool OnSavePointReached();
virtual bool OnSavePointLeft();
virtual bool OnStyle(unsigned int startPos, int lengthDoc, int initStyle, StyleWriter *styler);
virtual bool OnDoubleClick();
virtual bool OnUpdateUI();
virtual bool OnMarginClick();
virtual bool OnUserListSelection(int listType, const char *selection);
virtual bool OnKey(int keyval, int modifiers);
virtual bool OnDwellStart(int pos, const char *word);
virtual bool OnClose(const char *filename);
};


scite228.zip > Utf8_16.h

// Utf8_16.h
// Copyright (C) 2002 Scott Kirkwood
//
// Permission to use, copy, modify, distribute and sell this code
// and its documentation for any purpose is hereby granted without fee,
// provided that the above copyright notice appear in all copies or
// any derived copies. Scott Kirkwood makes no representations
// about the suitability of this software for any purpose.
// It is provided " as is " without express or implied warranty.
//
// Notes: Used the UTF information I found at:
// http://www.cl.cam.ac.uk/~mgk25/unicode.html
////////////////////////////////////////////////////////////////////////////////

#include & lt; stdio.h & gt;
#include & lt; assert.h & gt;

#ifdef _MSC_VER
#pragma warning(disable: 4514) // nreferenced inline function has been removed
#endif

class Utf8_16 {
public:
typedef unsigned short utf16; // 16 bits
typedef unsigned char utf8; // 8 bits
typedef unsigned char ubyte;
enum encodingType {
eUnknown,
eUtf16BigEndian,
eUtf16LittleEndian, // Default on Windows
eUtf8,
eLast
};
static const utf8 k_Boms[eLast][3];
};

// Reads UTF-16 and outputs UTF-8
class Utf16_Iter : public Utf8_16 {
public:
Utf16_Iter();
void reset();
void set(const ubyte* pBuf, size_t nLen, encodingType eEncoding);
utf8 get() const {
return m_nCur;
}
void operator++();
operator bool() { return m_pRead & lt; = m_pEnd; }

protected:
enum eState {
eStart,
eSecondOf4Bytes,
ePenultimate,
eFinal
};
protected:
encodingType m_eEncoding;
eState m_eState;
utf8 m_nCur;
int m_nCur16;
const ubyte* m_pBuf;
const ubyte* m_pRead;
const ubyte* m_pEnd;
};

// Reads UTF-8 and outputs UTF-16
class Utf8_Iter : public Utf8_16 {
public:
Utf8_Iter();
void reset();
void set(const ubyte* pBuf, size_t nLen, encodingType eEncoding);
int get() const {
#ifdef _DEBUG
assert(m_eState == eStart);
#endif
return m_nCur;
}
bool canGet() const { return m_eState == eStart; }
void operator++();
operator bool() { return m_pRead & lt; = m_pEnd; }

protected:
void toStart(); // Put to start state
enum eState {
eStart,
eSecondOf4Bytes,
ePenultimate,
eFinal
};
protected:
encodingType m_eEncoding;
eState m_eState;
int m_nCur;
const ubyte* m_pBuf;
const ubyte* m_pRead;
const ubyte* m_pEnd;
};

// Reads UTF16 and outputs UTF8
class Utf8_16_Read : public Utf8_16 {
public:
Utf8_16_Read();
~Utf8_16_Read();

size_t convert(char* buf, size_t len);
char* getNewBuf() { return reinterpret_cast & lt; char* & gt; (m_pNewBuf); }

encodingType getEncoding() const { return m_eEncoding; }
protected:
int determineEncoding();
private:
encodingType m_eEncoding;
ubyte* m_pBuf;
ubyte* m_pNewBuf;
size_t m_nBufSize;
bool m_bFirstRead;
size_t m_nLen;
Utf16_Iter m_Iter16;
};

// Read in a UTF-8 buffer and write out to UTF-16 or UTF-8
class Utf8_16_Write : public Utf8_16 {
public:
Utf8_16_Write();
~Utf8_16_Write();

void setEncoding(encodingType eType);

void setfile(FILE *pFile);
size_t fwrite(const void* p, size_t _size);
void fclose();
protected:
encodingType m_eEncoding;
FILE* m_pFile;
utf16* m_pBuf;
size_t m_nBufSize;
bool m_bFirstWrite;
};


scite228.zip > PropSetFile.h

// SciTE - Scintilla based Text Editor
/** @file PropSetFile.h
** Definition of platform independent base class of editor.
**/
// Copyright 1998-2009 by Neil Hodgson & lt; neilh@scintilla.org & gt;
// The License.txt file describes the conditions under which this software may be distributed.

/**
*/

typedef std::map & lt; std::string, std::string & gt; mapss;

class PropSetFile {
bool lowerKeys;
SString GetWildUsingStart(const PropSetFile & psStart, const char *keybase, const char *filename);
static bool caseSensitiveFilenames;
mapss props;
std::string enumnext;
public:
PropSetFile *superPS;
PropSetFile(bool lowerKeys_=false);
virtual ~PropSetFile();
void Set(const char *key, const char *val, ptrdiff_t lenKey=-1, ptrdiff_t lenVal=-1);
void Set(const char *keyVal);
void Unset(const char *key, int lenKey=-1);
void SetMultiple(const char *s);
bool Exists(const char *key) const;
SString Get(const char *key) const;
SString GetExpanded(const char *key) const;
SString Expand(const char *withVars, int maxExpands=100) const;
int GetInt(const char *key, int defaultValue=0) const;
void Clear();
char *ToString() const; // Caller must delete[] the return value

bool ReadLine(const char *data, bool ifIsTrue, FilePath directoryForImports, FilePath imports[] = 0, int sizeImports = 0);
void ReadFromMemory(const char *data, int len, FilePath directoryForImports, FilePath imports[] = 0, int sizeImports = 0);
bool Read(FilePath filename, FilePath directoryForImports, FilePath imports[] = 0, int sizeImports = 0);
void SetInteger(const char *key, int i);
SString GetWild(const char *keybase, const char *filename);
SString GetNewExpand(const char *keybase, const char *filename= " " );
bool GetFirst(const char * & key, const char * & val);
bool GetNext(const char * & key, const char * & val);
static void SetCaseSensitiveFilenames(bool caseSensitiveFilenames_) {
caseSensitiveFilenames = caseSensitiveFilenames_;
}

private:
// copy-value semantics not implemented
PropSetFile(const PropSetFile & copy);
void operator=(const PropSetFile & assign);
};


scite228.zip > SString.h

// SciTE - Scintilla based Text Editor
/** @file SString.h
** A simple string class.
**/
// Copyright 1998-2004 by Neil Hodgson & lt; neilh@scintilla.org & gt;
// The License.txt file describes the conditions under which this software may be distributed.

#ifndef SSTRING_H
#define SSTRING_H

// Define another string class.
// An SString may contain embedded nul characters.

/**
* Base class from which the two other classes (SBuffer & SString)
* are derived.
*/
class SContainer {
public:
/** Type of string lengths (sizes) and positions (indexes). */
typedef size_t lenpos_t;
/** Out of bounds value indicating that the string argument should be measured. */
enum { measure_length=0xffffffffU};

protected:
char *s; /// & lt; The C string
lenpos_t sSize; /// & lt; The size of the buffer, less 1: ie. the maximum size of the string

SContainer() : s(0), sSize(0) {}
~SContainer() {
delete []s; // Suppose it was allocated using StringAllocate
s = 0;
sSize = 0;
}
/** Size of buffer. */
lenpos_t size() const {
if (s) {
return sSize;
} else {
return 0;
}
}
public:
/**
* Allocate uninitialized memory big enough to fit a string of the given length.
* @return the pointer to the new string
*/
static char *StringAllocate(lenpos_t len);
/**
* Duplicate a buffer/C string.
* Allocate memory of the given size, or big enough to fit the string if length isn't given;
* then copy the given string in the allocated memory.
* @return the pointer to the new string
*/
static char *StringAllocate(
const char *s, /// & lt; The string to duplicate
lenpos_t len=measure_length); /// & lt; The length of memory to allocate. Optional.
};


/**
* @brief A string buffer class.
*
* Main use is to ask an API the length of a string it can provide,
* then to allocate a buffer of the given size, and to provide this buffer
* to the API to put the string.
* This class is intended to be shortlived, to be transformed as SString
* as soon as it holds the string, so it has little members.
* Note: we assume the buffer is filled by the API. If the length can be shorter,
* we should set sLen to strlen(sb.ptr()) in related SString constructor and assignment.
*/
class SBuffer : protected SContainer {
public:
SBuffer(lenpos_t len) {
s = StringAllocate(len);
if (s) {
*s = '\0';
sSize = len;
} else {
sSize = 0;
}
}
private:
/// Copy constructor
// Here only to be on the safe size, user should avoid returning SBuffer values.
SBuffer(const SBuffer & source) : SContainer() {
s = StringAllocate(source.s, source.sSize);
sSize = (s) ? source.sSize : 0;
}
/// Default assignment operator
// Same here, shouldn't be used
SBuffer & operator=(const SBuffer & source) {
if (this != & source) {
delete []s;
s = StringAllocate(source.s, source.sSize);
sSize = (s) ? source.sSize : 0;
}
return *this;
}
public:
/** Provide direct read/write access to buffer. */
char *ptr() {
return s;
}
/** Ownership of the buffer have been taken, so release it. */
void reset() {
s = 0;
sSize = 0;
}
/** Size of buffer. */
lenpos_t size() const {
return SContainer::size();
}
};


/**
* @brief A simple string class.
*
* Hold the length of the string for quick operations,
* can have a buffer bigger than the string to avoid too many memory allocations and copies.
* May have embedded zeroes as a result of @a substitute, but relies too heavily on C string
* functions to allow reliable manipulations of these strings, other than simple appends, etc.
*/
class SString : protected SContainer {
lenpos_t sLen; /// & lt; The size of the string in s
lenpos_t sizeGrowth; /// & lt; Minimum growth size when appending strings
enum { sizeGrowthDefault = 64 };

bool grow(lenpos_t lenNew);
SString & assign(const char *sOther, lenpos_t sSize_=measure_length);

public:
SString() : sLen(0), sizeGrowth(sizeGrowthDefault) {}
SString(const SString & source) : SContainer(), sizeGrowth(sizeGrowthDefault) {
s = StringAllocate(source.s, source.sLen);
sSize = sLen = (s) ? source.sLen : 0;
}
SString(const char *s_) : sizeGrowth(sizeGrowthDefault) {
s = StringAllocate(s_);
sSize = sLen = (s) ? strlen(s) : 0;
}
SString(SBuffer & buf) : sizeGrowth(sizeGrowthDefault) {
s = buf.ptr();
sSize = sLen = buf.size();
// Consumes the given buffer!
buf.reset();
}
SString(const char *s_, lenpos_t first, lenpos_t last) : sizeGrowth(sizeGrowthDefault) {
// note: expects the " last " argument to point one beyond the range end (a la STL iterators)
s = StringAllocate(s_ + first, last - first);
sSize = sLen = (s) ? last - first : 0;
}
SString(int i);
SString(size_t i);
SString(double d, int precision);
~SString() {
sLen = 0;
}
void clear() {
if (s) {
*s = '\0';
}
sLen = 0;
}
/** Size of buffer. */
lenpos_t size() const {
return SContainer::size();
}
/** Size of string in buffer. */
lenpos_t length() const {
return sLen;
}
/** Read access to a character of the string. */
char operator[](lenpos_t i) const {
return (s & & i & lt; sSize) ? s[i] : '\0';
}
SString & operator=(const char *source) {
return assign(source);
}
SString & operator=(const SString & source) {
if (this != & source) {
assign(source.s, source.sLen);
}
return *this;
}
bool operator==(const SString & sOther) const;
bool operator!=(const SString & sOther) const {
return !operator==(sOther);
}
bool operator==(const char *sOther) const;
bool operator!=(const char *sOther) const {
return !operator==(sOther);
}
bool contains(char ch) const {
return (s & & *s) ? strchr(s, ch) != 0 : false;
}
void setsizegrowth(lenpos_t sizeGrowth_) {
sizeGrowth = sizeGrowth_;
}
const char *c_str() const {
return s ? s : " " ;
}
/** Give ownership of buffer to caller which must use delete[] to free buffer. */
char *detach() {
char *sRet = s;
s = 0;
sSize = 0;
sLen = 0;
return sRet;
}
SString substr(lenpos_t subPos, lenpos_t subLen=measure_length) const;
SString & lowercase(lenpos_t subPos = 0, lenpos_t subLen=measure_length);
SString & uppercase(lenpos_t subPos = 0, lenpos_t subLen=measure_length);
SString & append(const char *sOther, lenpos_t sLenOther=measure_length, char sep = '\0');
SString & operator+=(const char *sOther) {
return append(sOther, static_cast & lt; lenpos_t & gt; (measure_length));
}
SString & operator+=(const SString & sOther) {
return append(sOther.s, sOther.sLen);
}
SString & operator+=(char ch) {
return append( & ch, 1);
}
SString & appendwithseparator(const char *sOther, char sep) {
return append(sOther, strlen(sOther), sep);
}
SString & insert(lenpos_t pos, const char *sOther, lenpos_t sLenOther=measure_length);

/**
* Remove @a len characters from the @a pos position, included.
* Characters at pos + len and beyond replace characters at pos.
* If @a len is 0, or greater than the length of the string
* starting at @a pos, the string is just truncated at @a pos.
*/
void remove(lenpos_t pos, lenpos_t len);

SString & change(lenpos_t pos, char ch) {
if (pos & lt; sLen) { // character changed must be in string bounds
*(s + pos) = ch;
}
return *this;
}
/** Read an integral numeric value from the string. */
int value() const {
return s ? atoi(s) : 0;
}
bool startswith(const char *prefix);
bool endswith(const char *suffix);
int search(const char *sFind, lenpos_t start=0) const;
bool contains(const char *sFind) const {
return search(sFind) & gt; = 0;
}
int substitute(char chFind, char chReplace);
int substitute(const char *sFind, const char *sReplace);
int remove(const char *sFind) {
return substitute(sFind, " " );
}
};


/**
* Duplicate a C string.
* Allocate memory of the given size, or big enough to fit the string if length isn't given;
* then copy the given string in the allocated memory.
* @return the pointer to the new string
*/
inline char *StringDup(
const char *s, /// & lt; The string to duplicate
SContainer::lenpos_t len=SContainer::measure_length) /// & lt; The length of memory to allocate. Optional.
{
return SContainer::StringAllocate(s, len);
}

bool isprefix(const char *target, const char *prefix);
int CompareNoCase(const char *a, const char *b);
bool EqualCaseInsensitive(const char *a, const char *b);

#endif


scite228.zip > Mutex.h

// SciTE - Scintilla based Text Editor
/** @file Mutex.h
** Define mutex
**/
// SciTE & Scintilla copyright 1998-2003 by Neil Hodgson & lt; neilh@scintilla.org & gt;
// Copyright 2007 by Neil Hodgson & lt; neilh@scintilla.org & gt; , from April White & lt; april_white@sympatico.ca & gt;
// The License.txt file describes the conditions under which this software may be distributed.

// TODO: see http://www.codeproject.com/threads/cppsyncstm.asp

#ifndef MUTEX_H
#define MUTEX_H

class Mutex {
public:
virtual void Lock() = 0;
virtual void Unlock() = 0;
virtual ~Mutex() {}
static Mutex *Create();
};

class Lock {
Mutex *mute;
public:
Lock(Mutex *mute_) : mute(mute_) {
mute- & gt; Lock();
}
~Lock() {
mute- & gt; Unlock();
}
};

#endif


scite228.zip > StringList.h

// SciTE - Scintilla based Text Editor
/** @file StringList.h
** Definition of class holding a list of strings.
**/
// Copyright 1998-2005 by Neil Hodgson & lt; neilh@scintilla.org & gt;
// The License.txt file describes the conditions under which this software may be distributed.

class StringList {
public:
// Each word contains at least one character - a empty word acts as sentinel at the end.
char **words;
char **wordsNoCase;
char *list;
int len;
bool onlyLineEnds; /// & lt; Delimited by any white space or only line ends
bool sorted;
bool sortedNoCase;
int starts[256];
StringList(bool onlyLineEnds_ = false) :
words(0), wordsNoCase(0), list(0), len(0), onlyLineEnds(onlyLineEnds_),
sorted(false), sortedNoCase(false) {}
~StringList() { Clear(); }
operator bool() const { return len ? true : false; }
char *operator[](int ind) { return words[ind]; }
void Clear();
void Set(const char *s);
char *Allocate(int size);
void SetFromAllocated();
bool InList(const char *s);
//bool InListAbbreviated(const char *s, const char marker);
const char *GetNearestWord(const char *wordStart, int searchLen,
bool ignoreCase = false, SString wordCharacters= " " , int wordIndex = -1);
char *GetNearestWords(const char *wordStart, int searchLen,
bool ignoreCase=false, char otherSeparator='\0', bool exactLen=false);
};


scite228.zip > License.txt

License for Scintilla and SciTE

Copyright 1998-2003 by Neil Hodgson & lt; neilh@scintilla.org & gt;

All Rights Reserved

Permission to use, copy, modify, and distribute this software and its
documentation for any purpose and without fee is hereby granted,
provided that the above copyright notice appear in all copies and that
both that copyright notice and this permission notice appear in
supporting documentation.

NEIL HODGSON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS, IN NO EVENT SHALL NEIL HODGSON BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE
OR PERFORMANCE OF THIS SOFTWARE.


scite228.zip > ScriptLexer.html

SciTE Script Lexer



.S0 {
color: #FF0000;
}
.S2 {
font-family: 'Comic Sans MS';
color: #007F00;
font-size: 9pt;
}
.S4 {
color: #007F7F;
}
.S5 {
color: #00007F;
font-weight: bold;
}
.S6 {
color: #7F007F;
}
.S10 {
color: #000000;
}
.S14 {
color: #00007F;
background: #F5F5FF;
text-decoration: inherit;
}
.Z0 {
color: #7f007f;
font-weight: bold;
}
.Z1 {
color: #000000;
}
.Z2 {
color: #000080;
font-weight: bold;
}
.Z3 {
color: #008000;
font-family: 'Georgia';
font-size: 9pt;
font-style:italic;
}
span {
font-family: 'Verdana';
color: #000000;
font-size: 10pt;
}
.example {
color: #008000;
font-weight: bold;
}
DIV.example {
background: #F7FCF7;
border: 1px solid #C0D7C0;
margin: 0.3em 3em;
padding: 0.3em 0.6em;
font-size: 80%;
}
DIV.highlighted {
background: #F7FCF7;
border: 1px solid #C0D7C0;
margin: 0.3em 3em;
padding: 0.3em 0.6em;
font-size: 80%;
}
table {
border: 1px solid #1F1F1F;
border-collapse: collapse;
}
td {
border: 1px solid #1F1F1F;
padding: 1px 5px 1px 5px;
}
th {
border: 1px solid #1F1F1F;
padding: 1px 5px 1px 5px;
}










SciTE Script Lexer




Warning

This feature is being developed and is not stable. The API may change in the future.

Writing lexers in Lua

A lexer may be written as a script in the Lua language instead of in C++.
This is a little simpler and allows lexers to be developed without using a C++ compiler.
A script lexer is attached by setting the file lexer to be a name that starts with " script_ " .
Styles and other properties can then be assigned using this name. For example,

lexer.*.zog=script_zog
style.script_zog.0=fore:#7f007f,bold
style.script_zog.1=fore:#000000
style.script_zog.2=fore:#000080,bold
style.script_zog.3=fore:#008000,font:Georgia,italics,size:9

Then the lexer is implemented in Lua similar to this:

-- -*- coding: utf-8 -*-

function OnStyle ( styler )
& nbsp; & nbsp; & nbsp; & nbsp; S_DEFAULT = 0
& nbsp; & nbsp; & nbsp; & nbsp; S_IDENTIFIER = 1
& nbsp; & nbsp; & nbsp; & nbsp; S_KEYWORD = 2
& nbsp; & nbsp; & nbsp; & nbsp; S_UNICODECOMMENT = 3
& nbsp; & nbsp; & nbsp; & nbsp; identifierCharacters = " abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ "

& nbsp; & nbsp; & nbsp; & nbsp; styler : StartStyling ( styler.startPos , styler.lengthDoc , styler.initStyle )
& nbsp; & nbsp; & nbsp; & nbsp; while styler : More () do

& nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; -- Exit state if needed
& nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; if styler : State () == S_IDENTIFIER then
& nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; if not identifierCharacters : find ( styler : Current (), 1 , true ) then
& nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; identifier = styler : Token ()
& nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; if identifier == " if " or identifier == " end " then
& nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; styler : ChangeState ( S_KEYWORD )
& nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; end
& nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; styler : SetState ( S_DEFAULT )
& nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; end
& nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; elseif styler : State () == S_UNICODECOMMENT then
& nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; if styler : Match ( " >> " ) then
& nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; styler : ForwardSetState ( S_DEFAULT )
& nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; end
& nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; end

& nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; -- Enter state if needed
& nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; if styler : State () == S_DEFAULT then
&amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; if styler : Match ( &quot; << &quot; ) then
&amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; styler : SetState ( S_UNICODECOMMENT )
&amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; elseif identifierCharacters : find ( styler : Current (), 1 , true ) then
&amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; styler : SetState ( S_IDENTIFIER )
&amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; end
&amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; end

&amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; styler : Forward ()
&amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; end
&amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; styler : EndStyling ()
end




The result looks like



proc clip ( int a )
<< Clip into the positive zone >>
if ( a &amp; gt; 0) a
0
end


Code Structure
Document Loop
The lexer loops through the part of the document indicated assigning a style to each character.

styler:StartStyling ( styler.startPos , styler.lengthDoc , styler.initStyle )
while styler:More () do
&amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; -- Code that examines the text and sets lexical states
&amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; styler:Forward ()
end
styler:EndStyling ()

There are many different ways to structure the code that examines the text and sets lexical states.
A structure that has proven useful in C++ lexers is to write two blocks of code as shown in the example.
The first block checks if the current state should end and if so sets the state to the default 0.
The second block is responsible for detecting whether a new state should be entered from the default state.
This structure means everything is dealt with as switching from or to the default state and avoids having to consider many
combinations of states.
Encodings
The styler iterates over whole characters rather than bytes. Thus if the document is encoded in UTF-8, styler:Current() may be a multibyte string. If the script is also encoded in UTF-8,
then it is easy to check against Unicode characters with code like

if styler:Current () == &quot; << &quot; then

If using an encoding like Latin-1 and the script is also encoded in the same encoding then literals can be used as above.
If the language can be encoded in different ways then more complex code may be needed along with encoding-specific code.
Checking Before
Sometimes a lexer needs to see some information earlier in the file, perhaps a declaration changes the syntax or the particular form of quote
at the start of a string must be matched at its end. Since the standard loop only goes forward from the starting position, different calls must be used like CharAt and StyleAt.
These use byte positions and do not treat multi-byte characters as single entities.
Performance
The lexer above can lex approximately 90K per second on a 2.4 GHz Athlon 64. For most situations, this will
feel completely fluid.
More complex lexers will be slower. If a lexer is so slow that the application becomes unresponsive then
the lexer can choose to split up each request. It can do so by deciding upon a range of whole lines and using this range as the
arguments to StartStyling. This allows the user's keystrokes and mouse moves to be processed.
The lexer will automatically be called again to lex more of the document.

API
The API of the styler object passed to OnStyle:


Name Explanation

StartStyling(startPos, length, initStyle)
Start setting styles from startPos for length with initial style initStyle
EndStyling()
Styling has been completed so tidy up
More() -> boolean
Are there any more characters to process
Forward()
Move forward one character
Position() -> integer
What is the position in the document of the current character
AtLineStart() -> boolean
Is the current character the first on a line
AtLineEnd() -> boolean
Is the current character the last on a line
State() -> integer
The current lexical state value
SetState(state)
Set the style of the current token to the current state and then change the state to the argument
ForwardSetState(state)
Combination of moving forward and setting the state. Useful when the current character is a token terminator like &quot; for a string.
ChangeState(state)
Change the current state so that the state of the current token will be set to the argument
Current() -> string
The current character
Next() -> string
The next character
Previous() -> string
The previous character
Token() -> string
The current token
Match(string) -> boolean
Is the text from the current position the same as the argument?

Line(position) -> integer
Convert a byte position into a line number
CharAt(position) -> integer
Unsigned byte value at argument
StyleAt(position) -> integer
Style value at argument
LevelAt(line) -> integer
Fold level for a line
SetLevelAt(line, level)
Set the fold level for a line
LineState(line) -> integer
State value for a line
SetLineState(line, state)
Set state value for a line. This can be used to store extra information from lexing,
such as a current language mode, so that there is no need to look back in the document.

startPos : integer
Start of the range to be lexed
lengthDoc : integer
Length of the range to be lexed
initStyle : integer
Starting style
language : string
Name of the language. Allows implementation of multiple languages with one OnStyle function.



A line-oriented example.

This example is for a line-oriented language as is sometimes used for configuration files.
It uses low level direct calls instead of the StartStyling/More/Forward/EndStyling calls.

-- A line oriented lexer - style the line according to the first character
function OnStyle ( styler )
&amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; lineStart = editor : LineFromPosition ( styler.startPos )
&amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; lineEnd = editor : LineFromPosition ( styler.startPos + styler.lengthDoc )
&amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; editor : StartStyling ( styler.startPos , 31 )
&amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; for line = lineStart , lineEnd , 1 do
&amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; lengthLine = editor : PositionFromLine ( line + 1 ) - editor : PositionFromLine ( line )
&amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; lineText = editor : GetLine ( line )
&amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; first = string.sub ( lineText , 1 , 1 )
&amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; style = 0
&amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; if first == &quot; + &quot; then
&amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; style = 1
&amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; elseif first == &quot; &quot; or first == &quot; \t &quot; then
&amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; style = 2
&amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; end
&amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; editor : SetStyling ( lengthLine , style )
&amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; end
end


scite228.zip > SciTEExternalLexer.html

Add an external lexer to SciTE




Lexer addition.

This document has been superceded by the new
lexer object design


scite228.zip > CommandValues.html

table { border: 1px solid #1F1F1F; border-collapse: collapse; }
td { border: 1px solid; border-color: #E0E0E0 #000000; padding: 1px 5px 1px 5px; }
th { border: 1px solid #1F1F1F; padding: 1px 5px 1px 5px; }
thead { background-color: #000000; color: #FFFFFF; }


SciTE menu commands

Command Menu text
IDM_NEW New
IDM_OPEN Open
IDM_OPENSELECTED Open Selected Filename
IDM_REVERT Revert
IDM_CLOSE Close
IDM_SAVE Save
IDM_SAVEAS Save As
IDM_SAVEACOPY Save a Copy
IDM_COPYPATH Copy Path
IDM_ENCODING_DEFAULT Code Page Property
IDM_ENCODING_UCS2BE UTF-16 Big Endian
IDM_ENCODING_UCS2LE UTF-16 Little Endian
IDM_ENCODING_UTF8 UTF-8 with BOM
IDM_ENCODING_UCOOKIE UTF-8
IDM_SAVEASHTML As HTML
IDM_SAVEASRTF As RTF
IDM_SAVEASPDF As PDF
IDM_SAVEASTEX As LaTeX
IDM_SAVEASXML As XML
IDM_PRINTSETUP Page Setup
IDM_PRINT Print
IDM_LOADSESSION Load Session
IDM_SAVESESSION Save Session
IDM_QUIT Exit
IDM_UNDO Undo
IDM_REDO Redo
IDM_CUT Cut
IDM_COPY Copy
IDM_PASTE Paste
IDM_DUPLICATE Duplicate
IDM_CLEAR Delete
IDM_SELECTALL Select All
IDM_COPYASRTF Copy as RTF
IDM_MATCHBRACE Match Brace
IDM_SELECTTOBRACE Select to Brace
IDM_SHOWCALLTIP Show Calltip
IDM_COMPLETE Complete Symbol
IDM_COMPLETEWORD Complete Word
IDM_ABBREV Expand Abbreviation
IDM_INS_ABBREV Insert Abbreviation
IDM_BLOCK_COMMENT Block Comment or Uncomment
IDM_BOX_COMMENT Box Comment
IDM_STREAM_COMMENT Stream Comment
IDM_UPRCASE Make Selection Uppercase
IDM_LWRCASE Make Selection Lowercase
IDM_JOIN Join
IDM_SPLIT Split
IDM_FIND Find
IDM_FINDNEXT Find Next
IDM_FINDNEXTBACK Find Previous
IDM_FINDINFILES Find in Files
IDM_REPLACE Replace
IDM_INCSEARCH Incremental Search
IDM_GOTO Go to
IDM_BOOKMARK_NEXT Next Bookmark
IDM_BOOKMARK_PREV Previous Bookmark
IDM_BOOKMARK_TOGGLE Toggle Bookmark
IDM_BOOKMARK_CLEARALL Clear All Bookmarks
IDM_EXPAND Toggle current fold
IDM_TOGGLE_FOLDALL Toggle all folds
IDM_FULLSCREEN Full Screen
IDM_VIEWTOOLBAR Tool Bar
IDM_VIEWTABBAR Tab Bar
IDM_VIEWSTATUSBAR Status Bar
IDM_VIEWSPACE Whitespace
IDM_VIEWEOL End of Line
IDM_VIEWGUIDES Indentation Guides
IDM_LINENUMBERMARGIN Line Numbers
IDM_SELMARGIN Margin
IDM_FOLDMARGIN Fold Margin
IDM_TOGGLEOUTPUT Output
IDM_TOGGLEPARAMETERS Parameters
IDM_COMPILE Compile
IDM_BUILD Build
IDM_GO Go
IDM_STOPEXECUTE Stop Executing
IDM_NEXTMSG Next Message
IDM_PREVMSG Previous Message
IDM_CLEAROUTPUT Clear Output
IDM_SWITCHPANE Switch Pane
IDM_ONTOP Always On Top
IDM_OPENFILESHERE Open Files Here
IDM_SPLITVERTICAL Vertical Split
IDM_WRAP Wrap
IDM_WRAPOUTPUT Wrap Output
IDM_READONLY Read-Only
IDM_EOL_CRLF CR + LF
IDM_EOL_CR CR
IDM_EOL_LF LF
IDM_EOL_CONVERT Convert Line End Characters
IDM_TABSIZE Change Indentation Settings
IDM_MONOFONT Use Monospaced Font
IDM_OPENLOCALPROPERTIES Open Local Options File
IDM_OPENDIRECTORYPROPERTIES Open Directory Options File
IDM_OPENUSERPROPERTIES Open User Options File
IDM_OPENGLOBALPROPERTIES Open Global Options File
IDM_OPENABBREVPROPERTIES Open Abbreviations File
IDM_OPENLUAEXTERNALFILE Open Lua Startup Script
IDM_PREVFILE Previous
IDM_NEXTFILE Next
IDM_CLOSEALL Close All
IDM_SAVEALL Save All
IDM_HELP Help
IDM_HELP_SCITE Sc1 Help
IDM_ABOUT About Sc1
IDM_HELP_SCITE SciTE Help
IDM_ABOUT About SciTE

Scintilla key commands

Command Name Explanation
2547 AnnotationClearAll Clear the annotations from all lines
2101 AutoCCancel Remove the auto-completion list from the screen.
2104 AutoCComplete User has selected an item so remove the list and insert the selection.
2328 BackTab Dedent the selected lines.
2078 BeginUndoAction Start a sequence of actions that is undone and redone as a unit. May be nested.
2201 CallTipCancel Remove the call tip from the screen.
2325 Cancel Cancel any modes such as call tip or auto-completion list display.
2304 CharLeft Move caret left one character.
2305 CharLeftExtend Move caret left one character extending selection to new caret position.
2428 CharLeftRectExtend Move caret left one character, extending rectangular selection to new caret position.
2306 CharRight Move caret right one character.
2307 CharRightExtend Move caret right one character extending selection to new caret position.
2429 CharRightRectExtend Move caret right one character, extending rectangular selection to new caret position.
2399 ChooseCaretX Set the last x chosen value to be the caret x position.
2180 Clear Clear the selection.
2004 ClearAll Delete all text in the document.
2072 ClearAllCmdKeys Drop all key mappings.
2005 ClearDocumentStyle Set all style bytes to 0, remove all folding information.
2408 ClearRegisteredImages Clear all the registered XPM images.
2571 ClearSelections Clear selections to a single empty stream selection
2178 Copy Copy the selection to the clipboard.
2519 CopyAllowLine Copy the selection, if selection empty copy the line with the caret
2177 Cut Cut the selection to the clipboard.
2395 DelLineLeft Delete back from the current position to the start of the line.
2396 DelLineRight Delete forwards from the current position to the end of the line.
2335 DelWordLeft Delete the word to the left of the caret.
2336 DelWordRight Delete the word to the right of the caret.
2518 DelWordRightEnd Delete the word to the right of the caret, but not the trailing non-word characters.
2326 DeleteBack Delete the selection or if no selection, the character before the caret.
2344 DeleteBackNotLine Delete the selection or if no selection, the character before the caret. Will not delete the character before at the start of a line.
2318 DocumentEnd Move caret to last position in document.
2319 DocumentEndExtend Move caret to last position in document extending selection to new caret position.
2316 DocumentStart Move caret to first position in document.
2317 DocumentStartExtend Move caret to first position in document extending selection to new caret position.
2324 EditToggleOvertype Switch from insert to overtype mode or the reverse.
2175 EmptyUndoBuffer Delete the undo history.
2079 EndUndoAction End a sequence of actions that is undone and redone as a unit.
2330 FormFeed Insert a Form Feed character.
2400 GrabFocus Set the focus to this Scintilla widget.
2312 Home Move caret to first position on line.
2345 HomeDisplay Move caret to first position on display line.
2346 HomeDisplayExtend Move caret to first position on display line extending selection to new caret position.
2313 HomeExtend Move caret to first position on line extending selection to new caret position.
2430 HomeRectExtend Move caret to first position on line, extending rectangular selection to new caret position.
2349 HomeWrap These are like their namesakes Home(Extend)?, LineEnd(Extend)?, VCHome(Extend)? except they behave differently when word-wrap is enabled: They go first to the start / end of the display line, like (Home|LineEnd)Display The difference is that, the cursor is already at the point, it goes on to the start or end of the document line, as appropriate for (Home|LineEnd|VCHome)(Extend)?.
2450 HomeWrapExtend These are like their namesakes Home(Extend)?, LineEnd(Extend)?, VCHome(Extend)? except they behave differently when word-wrap is enabled: They go first to the start / end of the display line, like (Home|LineEnd)Display The difference is that, the cursor is already at the point, it goes on to the start or end of the document line, as appropriate for (Home|LineEnd|VCHome)(Extend)?.
2455 LineCopy Copy the line containing the caret.
2337 LineCut Cut the line containing the caret.
2338 LineDelete Delete the line containing the caret.
2300 LineDown Move caret down one line.
2301 LineDownExtend Move caret down one line extending selection to new caret position.
2426 LineDownRectExtend Move caret down one line, extending rectangular selection to new caret position.
2404 LineDuplicate Duplicate the current line.
2314 LineEnd Move caret to last position on line.
2347 LineEndDisplay Move caret to last position on display line.
2348 LineEndDisplayExtend Move caret to last position on display line extending selection to new caret position.
2315 LineEndExtend Move caret to last position on line extending selection to new caret position.
2432 LineEndRectExtend Move caret to last position on line, extending rectangular selection to new caret position.
2451 LineEndWrap These are like their namesakes Home(Extend)?, LineEnd(Extend)?, VCHome(Extend)? except they behave differently when word-wrap is enabled: They go first to the start / end of the display line, like (Home|LineEnd)Display The difference is that, the cursor is already at the point, it goes on to the start or end of the document line, as appropriate for (Home|LineEnd|VCHome)(Extend)?.
2452 LineEndWrapExtend These are like their namesakes Home(Extend)?, LineEnd(Extend)?, VCHome(Extend)? except they behave differently when word-wrap is enabled: They go first to the start / end of the display line, like (Home|LineEnd)Display The difference is that, the cursor is already at the point, it goes on to the start or end of the document line, as appropriate for (Home|LineEnd|VCHome)(Extend)?.
2342 LineScrollDown Scroll the document down, keeping the caret visible.
2343 LineScrollUp Scroll the document up, keeping the caret visible.
2339 LineTranspose Switch the current line with the previous.
2302 LineUp Move caret up one line.
2303 LineUpExtend Move caret up one line extending selection to new caret position.
2427 LineUpRectExtend Move caret up one line, extending rectangular selection to new caret position.
2288 LinesJoin Join the lines in the target.
2340 LowerCase Transform the selection to lower case.
2536 MarginTextClearAll Clear the margin text on all lines
2401 MoveCaretInsideView Move the caret inside current view if it's not there already.
2621 MoveSelectedLinesDown Move the selected lines down one line, shifting the line below before the selection
2620 MoveSelectedLinesUp Move the selected lines up one line, shifting the line above after the selection
2329 NewLine Insert a new line, may use a CRLF, CR or LF depending on EOL mode.
2172 Null Null operation.
2322 PageDown Move caret one page down.
2323 PageDownExtend Move caret one page down extending selection to new caret position.
2434 PageDownRectExtend Move caret one page down, extending rectangular selection to new caret position.
2320 PageUp Move caret one page up.
2321 PageUpExtend Move caret one page up extending selection to new caret position.
2433 PageUpRectExtend Move caret one page up, extending rectangular selection to new caret position.
2413 ParaDown Move caret between paragraphs (delimited by empty lines).
2414 ParaDownExtend Move caret between paragraphs (delimited by empty lines).
2415 ParaUp Move caret between paragraphs (delimited by empty lines).
2416 ParaUpExtend Move caret between paragraphs (delimited by empty lines).
2179 Paste Paste the contents of the clipboard into the document replacing the selection.
2011 Redo Redoes the next action on the undo history.
2606 RotateSelection Set the main selection to the next selection.
2169 ScrollCaret Ensure the caret is visible.
2629 ScrollToEnd Scroll to end of document.
2628 ScrollToStart Scroll to start of document.
2366 SearchAnchor Sets the current caret position to be the search anchor.
2013 SelectAll Select all the text in the document.
2469 SelectionDuplicate Duplicate the selection. If selection empty duplicate the line containing the caret.
2444 SetCharsDefault Reset the set of characters for whitespace and word characters to the defaults.
2014 SetSavePoint Remember the current position in the undo history as the position at which the document was saved.
3001 StartRecord Start notifying the container of all key presses and commands.
3002 StopRecord Stop notifying the container of all key presses and commands.
2437 StutteredPageDown Move caret to bottom of page, or one page down if already at bottom of page.
2438 StutteredPageDownExtend Move caret to bottom of page, or one page down if already at bottom of page, extending selection to new caret position.
2435 StutteredPageUp Move caret to top of page, or one page up if already at top of page.
2436 StutteredPageUpExtend Move caret to top of page, or one page up if already at top of page, extending selection to new caret position.
2058 StyleResetDefault Reset the default style to its state at startup
2607 SwapMainAnchorCaret Swap that caret and anchor of the main selection.
2327 Tab If selection is empty or all on one line replace the selection with a tab character. If more than one line selected, indent the lines.
2287 TargetFromSelection Make the target range start and end be the same as the selection range start and end.
2459 ToggleCaretSticky Switch between sticky and non-sticky: meant to be bound to a key.
2176 Undo Undo one action in the undo history.
2341 UpperCase Transform the selection to upper case.
2331 VCHome Move caret to before first visible character on line. If already there move to first character on line.
2332 VCHomeExtend Like VCHome but extending selection to new caret position.
2431 VCHomeRectExtend Move caret to before first visible character on line. If already there move to first character on line. In either case, extend rectangular selection to new caret position.
2453 VCHomeWrap These are like their namesakes Home(Extend)?, LineEnd(Extend)?, VCHome(Extend)? except they behave differently when word-wrap is enabled: They go first to the start / end of the display line, like (Home|LineEnd)Display The difference is that, the cursor is already at the point, it goes on to the start or end of the document line, as appropriate for (Home|LineEnd|VCHome)(Extend)?.
2454 VCHomeWrapExtend These are like their namesakes Home(Extend)?, LineEnd(Extend)?, VCHome(Extend)? except they behave differently when word-wrap is enabled: They go first to the start / end of the display line, like (Home|LineEnd)Display The difference is that, the cursor is already at the point, it goes on to the start or end of the document line, as appropriate for (Home|LineEnd|VCHome)(Extend)?.
2619 VerticalCentreCaret Centre current line in window.
2308 WordLeft Move caret left one word.
2439 WordLeftEnd Move caret left one word, position cursor at end of word.
2440 WordLeftEndExtend Move caret left one word, position cursor at end of word, extending selection to new caret position.
2309 WordLeftExtend Move caret left one word extending selection to new caret position.
2390 WordPartLeft Move to the previous change in capitalisation.
2391 WordPartLeftExtend Move to the previous change in capitalisation extending selection to new caret position.
2392 WordPartRight Move to the change next in capitalisation.
2393 WordPartRightExtend Move to the next change in capitalisation extending selection to new caret position.
2310 WordRight Move caret right one word.
2441 WordRightEnd Move caret right one word, position cursor at end of word.
2442 WordRightEndExtend Move caret right one word, position cursor at end of word, extending selection to new caret position.
2311 WordRightExtend Move caret right one word extending selection to new caret position.
2333 ZoomIn Magnify the displayed text by increasing the sizes by 1 point.
2334 ZoomOut Make the displayed text smaller by decreasing the sizes by 1 point.


scite228.zip > SciTEFAQ.html

SciTE FAQ


table {
border: 1px solid #1F1F1F;
border-collapse: collapse;
}
td {
border: 1px solid #1F1F1F;
padding: 1px 5px 1px 5px;
}
th {
border: 1px solid #1F1F1F;
padding: 1px 5px 1px 5px;
}
h4 {
background-color: #000000;
color: #FFFFFF;
padding: 2px 6px;
}
.example {
color: #00A000;
font-weight: bold;
}
DIV.example {
background: #F7FCF7;
border: 1px solid #C0D7C0;
margin: 0.3em 3em;
padding: 0.3em 0.6em;
font-size: 80%;
}










SciTE




SciTE Frequently Asked Question



How do I use a fixed width font for all text?

What happened to use.monospaced ?

Why doesn't my line.numbers setting work?

How do I change SciTE to use black as the background colour?

How do I change the colours of the output pane?

How do I make the horizontal scroll bar adjust to the width of text?

How do I enable tabbed window mode in SciTE?

How do I enable autocomplete?

When I try to compile/build/run my [some language] source files, I get the following error:
'The system cannot find the file specified'.

How can I add [some external application] to the Tools menu on SciTE?

How can I add a keyboard command without adding it to the Tools menu?

Is there a command to replace a string in multiple files together?

How do I make SciTE run faster on GTK+?

Is it possible to use the newline character (\n) in a regular expression?

How do I get SciTE to understand the error messages from my compiler?

Why do GCC error messages include ugly characters?

How do I make Windows open a file associated with SciTE when its path contains spaces?

Why does a //{ comment affect folding?


How do I use a fixed width font for all text?


Use these properties:
font.base=$(font.monospace)
font.small=$(font.monospace)
font.comment=$(font.monospace)
font.text=$(font.monospace)
font.text.comment=$(font.monospace)
font.embedded.base=$(font.monospace)
font.embedded.comment=$(font.monospace)
font.vbs=$(font.monospace)

What happened to use.monospaced ?


The use.monospaced property was removed as
people were using it to ask for fixed width fonts and then
requiring support to cope with its limitations. The correct way to
set fixed width fonts is here .


Why doesn't my line.numbers setting work?


line.numbers has been replaced with two properties: line.margin.visible
and line.margin.width which are explained earlier in
the main SciTE document .


How do I change SciTE to use black as the background colour?


You need to change the style settings. The main change is in the user
options file to the global default style and caret colour but you may have
to change other style settings to make this work well:
style.*.32=$(font.base),back:#000000,fore:#ffffff
style.*.33=back:#C0C0C0,$(font.base)
style.*.37=fore:#939393
caret.fore=#FFFFFF
selection.alpha=75
selection.back=#FFFFFF
colour.keyword=fore:#649bff
colour.operator=fore:#727272

How do I change the colours of the output pane?


The output pane often lists error and warning messages and
is styled by the &quot; errorlist &quot; lexer. The default errorlist styles are found
in others.properties. To change the output pane background to black
and the default text to white set
style.errorlist.32=$(font.small),back:#000000
style.errorlist.0=fore:#FFFFFF

How do I make the horizontal scroll bar adjust to the width of text?


To avoid slow performance the horizontal scroll bar does not automatically adjust.
You can use the horizontal.scroll.width property to change the horizontal scroll range.


How do I enable tabbed window mode in SciTE?


Multiple buffers must be allocated by setting, for example, buffers=10
in your SciTEGlobal.properties. To have the tab bar visible upon starting
SciTE, set tabbar.visible=1 .
You can also set tabbar.hide.one=0 to always show tabs,
or 1 to hide when only one file is open.
tabbar.multiline=1 splits tabs across various lines if necessary.


How do I enable autocomplete?


Goto Options | Open Global Options File and uncomment
autocompleteword.automatic=1

When I try to compile/build/run my [some language] source files, I get the following error:
'The system cannot find the file specified'.


Make sure that the path to your compiler is set correctly on your system.
Try to execute from console the same command you get in SciTE and see if it works.
You can also search in your [language].properties for the compile
commands used. If you have a different compiler or use different arguments,
edit the commands to suit your needs.
The lines to look for:
command.compile.filepattern=
command.build.filepattern=
command.go.filepattern=

How can I add [some external application] to the Tools menu on SciTE?


In your properties file, you'll need to add some lines:


command.name.number.filepattern
(e.g.: command.name.1.$(file.patterns.web)=HTML Tidy )
This defines the Text that will appear on the Tools Menu.


command.number.filepattern
(e.g.: command.1.$(file.patterns.web)=tidy -i -wrap 0 -m $(FilePath) )
This is the actual command that SciTE executes. You should provide the appropriate paths, options and parameters as you would from a command line. See SciTEDoc.html for more information on parameters and how to make SciTE prompt a Parameters Dialog.


command.is.filter.number.filepattern
(e.g.: command.is.filter.1.$(file.patterns.web)=1 )
The external application may have modified your file, so setting this to true makes SciTE reload the file after execution of the command.


command.subsystem.number.filepattern
(e.g.: command.subsystem.1.$(file.patterns.web)=2 )
This is for Windows and defines the subsystem through which the program is called. See SciTEDoc.html for more information on this.


You can set a command for all files using * as a file pattern. Up to 10 commands (0 - 9) can be defined in the Tools Menu at any time. Commands also get executed with Ctrl+number.


How can I add a keyboard command without adding it to the Tools menu?


This is similar to adding to the tools menu except that you set the name to be empty.
Then the command is included in user.shortcuts by adding 1100 to produce its command ID. For example,

command.name.21.*.properties=
command.21.*.properties=cmd /c echo $(FileNameExt)
user.shortcuts=\
Ctrl+Shift+V|1121|


Is there a command to replace a string in multiple files together?


It is possible to replace a string in all opened buffers with the Replace in Buffers
button in the Replace dialog.
However this button is hidden by default, it can be displayed with
find.replace.advanced=1 .


How do I make SciTE run faster on GTK+?


The default settings for SciTE were changed in version 1.63 to use the Pango font
system and antialiased fonts. You can return to using X core fonts which are faster
with these settings:
font.base=font:lucidatypewriter,size:12
font.small=font:lucidatypewriter,size:10
font.comment=font:new century schoolbook,size:12
font.code.comment.box=$(font.comment)
font.code.comment.line=$(font.comment)
font.code.comment.doc=$(font.comment)
font.text=font:times,size:14
font.text.comment=font:lucidatypewriter,size:10
font.embedded.base=font:lucidatypewriter,size:12
font.embedded.comment=font:lucidatypewriter,size:12
font.monospace=font:courier,size:12
font.vbs=font:new century schoolbook,size:12

Line wrapping also slows SciTE down and this can be turned off with wrap=0 .


Is it possible to use the newline character (\n) in a regular expression?


No.


The &quot; Transform backslash expressions &quot; option allows using \n and \r but that option does
not work with regular expressions.


How do I get SciTE to understand the error messages from my compiler?


The set of error message formats is embedded in the Scintilla and SciTE code.
To add support for another compiler, you will need to add a new style to
scintilla/include/Scintilla.iface after the other SCE_ERR_* values, run HFacer.py,
edit RecogniseErrorListLine in scintilla/src/LexOthers.cxx to recognise the error message,
and edit DecodeMessage in scite/src/SciTEBuffers.cxx to extract the file name and line
number.


Why do GCC error messages include ugly characters?


Linux distributions now often set the locale to UTF-8 by, for
example, setting LANG=en_US.UTF-8. gcc takes this as an indication
that it can use any Unicode character encoded as UTF-8 so quotes using
&amp; lsquo;these &amp; rsquo; rather than ASCII. To see these as intended, set

output.code.page=65001

How do I make Windows open a file associated with SciTE when its path contains spaces?


On some versions of Windows, associating a particular file type
with SciTE does not allow paths containing spaces to work.
To fix this, the path variable %1 needs to be surrounded by double quotes.
This is done either directly in the registry or through the Explorer in
Tools | Folder Options | File Types | (Select type) | Advanced | open | Edit.
Change the &quot; Application used to perform action &quot; field to be similar to
&quot; C:\bin\SciTE\SciTE.exe &quot; &quot; %1 &quot;

Why does a //{ comment affect folding?


For C++ and similar languages, explicit folds can be added with //{ and //} .
This feature can be turned off with

fold.comment=0


scite228.zip > SciTEImage.html

Scintilla and SciTE









Scintilla
and SciTE


scite228.zip > SciTEExtension.html

SciTE Extension Interface


.example {
color: #00A000;
font-weight: bold;
}
DIV.example {
background: #F7FCF7;
border: 1px solid #C0D7C0;
margin: 0.3em 3em;
padding: 0.3em 0.6em;
font-size: 80%;
}










SciTE Extension Interface




Purpose.

Some people want to create enhanced versions of the SciTE editor, while
still receiving the benefits of new SciTE features. This could be for an
editor designed for a particular environment such as developing games,
to incorporate a scripting capability within SciTE or to allow SciTE to be
controlled by another process through an IPC mechanism.
There are two example extensions.
The SciTE Director Interface allows
SciTE on Windows to be controlled by an external application such as a
project manager.
The SciTE Lua Scripting Extension is an
integration of the Lua scripting language into SciTE, done using the Extension
interface.

Extension Interface.


bool Initialise(ExtensionAPI *host_);
bool Finalise();
bool Clear();
bool Load(const char *filename);
bool InitBuffer(int index);
bool ActivateBuffer(int index);
bool RemoveBuffer(int index);
bool OnOpen(const char *path);
bool OnSwitchFile(const char *path);
bool OnBeforeSave(const char *path);
bool OnSave(const char *path);
bool OnChar(char ch);
bool OnExecute(const char *s);
bool OnSavePointReached();
bool OnSavePointLeft();
bool OnStyle(unsigned int, int, int, Accessor *);
bool OnDoubleClick();
bool OnUpdateUI();
bool OnMarginClick();
bool OnMacro(const char *, const char *);
bool SendProperty(const char *);
bool OnKey(int keyval, int modifiers);
bool OnDwellStart(int pos, const char *word);
bool OnClose(const char *filename);

An extension must implement the Extension interface defined in scite/src/Extender.h
Only the first 4 methods must be implemented although an implementation can be as
simple as just returning false. The other methods have empty default implementations.
Methods added to this interface in the future should have default implementations so
existing extensions will continue to compile.
Each method returns a bool indicating whether the method handled all processing that
is needed and so no additional processing is required. Normally, false is returned to indicate
that further processing may be done.
The extension should use the Initialise and Finalise methods to allocate
and deallocate resources. The ExtensionAPI pointer should be saved in the
Initialise method so the extension can communicate back to SciTE.
The Clear and Load methods are used to support extensions that need
to load a resource such as a script file when a file is opened. When a file is
opened in SciTE, first the extension is asked to clear any data associated with
the previous file through Clear. Then SciTE checks for a property called
&quot; extension &quot; which matches the file name, so for x.cpp, looks for extension.*.cpp.
A file with this name is searched for in standard property file locations and if found
Load is called with the path as an argument.
The InitBuffer, ActivateBuffer, and RemoveBuffer methods provide the necessary hooks
so that extensions have a mechanism to associate data with a specific buffer, similar
to the way SciTE itself remembers the monospace setting of each buffer. InitBuffer is
called whenever a new document is opened in a given buffer. The buffer might be a newly
allocated one, or it might be recycled if the maximum number of buffers has been reached.
Once the buffer has been initialized, it will be the active buffer. Thereafter,
ActivateBuffer is called whenever the user switches to another loaded buffer.
RemoveBuffer is called when an existing buffer is closed. Thereafter, the indexes of
the buffers that come after the removed buffer are shifted down by one. After
RemoveBuffer, the extension will receive an InitBuffer or ActivateBuffer to establish
the new active buffer.
OnExecute is called only when an extension command is executed. These are
indicated in properties as subsystem 3.
OnBeforeSave is called before saving the file and an extension may implement
file saving itself and return true to prevent the default file save code from executing.
Other methods are called upon events occurring in SciTE allowing an extension
to respond to those events.

ExtensionAPI Interface.


enum Pane { paneEditor=1, paneOutput=2, paneFindOutput=3 };
sptr_t Send(Pane p, unsigned int msg, uptr_t wParam=0, sptr_t lParam=0);
char *Range(Pane p, int start, int end);
void Remove(Pane p, int start, int end);
void Insert(Pane p, int pos, const char *s);
void Trace(const char *s);
char *Property(const char *key);
void SetProperty(const char *key, const char *val);
uptr_t GetInstance();
void ShutDown();
void Perform(const char *actions);
void DoMenuCommand(int cmdID);
void UpdateStatusBar(bool bUpdateSlowData);

An extension can call back into SciTE using this interface which is a simplified
way to access the functionality of SciTE.
As well as the normal editor pane and output pane, this interface allows for
a future feature where a third pane may be used for the output of search
commands. This is currently mapped to the output pane.
Send allows sending messages to the Scintilla control contained in each pane.
Range retrieves text from the pane. This must be deleted with delete[].
Remove and Insert are used to remove and insert text in a pane.
Trace displays a string at the end of the output pane.
SciTE's properties can be read and written with Property and
SetProperty. The result from Property should be deleted with delete[].
GetInstance is Windows specific and returns the HINSTANCE of
the application which is needed when accessing platform facilities.
ShutDown is equivalent to the user choosing the Quit menu item.
If there are any unsaved files loaded, then the user is asked whether to save them
and may cancel from this dialog. So under some circumstances, the application will
continue to run after ShutDown is called.
Perform takes a string containing an action, a ':' character, and an argument.
Currently the only known action is open and then the argument is a path.
This is used by the Director extension
to relay commands from another application.
In the future more actions will be possible through this method.

Attaching the extension.

Extensions are currently added explicitly by code in the start up function.
On Windows, the DirectorExtension is attached with code similar to this simplified
example:

DirectorExtension director;
Extension *extender = &amp; director;
//...
SciTEWin MainWind(extender);

It would be better to move to an implicit attachment mechanism similar to the
way lexers are attached to Scintilla, determining which extensions are used
by simply linking their object files into SciTE. It would also be good to
allow run-time attachment of extensions housed in DLLs or shared object libraries.

Multiplexing.

SciTE supports multiple extensions at a time. A multiplexer extension
maintains a list of extensions and calls each in turn for each method. Once an extension
returns true indicating processing should stop, the multiplexer returns without traversing
any remaining list members. However, for some methods such as Initialise and Finalise,
the remaining extensions are traversed regardless of the return value of the previous
extension.

Thread safety.

In general, SciTE is a single threaded application. However, on Windows, command
tools call OnExecute from a separate worker thread. The SingleThreadExtension adapter
class can be used to wrap an extension so that OnExecute calls are marshalled to the
main thread. Of course, this is not necessary if your extension is thread safe, or
if it does not implement OnExecute, or if it is a GTK-specific extension.


scite228.zip > SciTE.html

function IsRemote() {
var loc = '' + window.location;
return loc.indexOf('http:') != -1;
}


#versionlist {
margin: 0;
padding: .5em;
list-style-type: none;
color: #FFCC99;
background: #000000;
}
#versionlist li {
margin-bottom: .5em;
}
#menu {
margin: 0;
padding: .5em 0;
list-style-type: none;
font-size: larger;
background: #CCCCCC;
}
#menu li {
margin: 0;
padding: 0 .5em;
display: inline;
}


Scintilla and SciTE









A free source code editor for Win32 and
X


Release version 2.28
Site last modified August 1 2011


&amp; nbsp;






&amp; nbsp;




Version 2.28 makes Asian language input through an IME work on GTK+ 3.x.
Version 2.27 fixes a performance problem on GTK+.
Version 2.26 can highlight all occurrences of the current word or selected text.
Version 2.25 is a minor bug fix and improvement release.
Version 2.24 fixes a memory leak on GTK+.


Screenshot
Download
Documentation
Scintilla
Extras
Translations
Frequently Asked Questions



SciTE is a SCIntilla based Text Editor. Originally built to
demonstrate Scintilla , it has grown to be a generally useful editor with facilities for
building and running programs. It is best used for jobs with simple configurations - I use it
for building test and demonstration programs as well as SciTE and Scintilla, themselves.


SciTE is currently available for Intel Windows (XP or later) and Linux compatible operating
systems with GTK+. It has been run on Windows 7 and on Fedora 12 and Ubuntu 10.10
with GTK+ 2.20. Here is a screenshot of
SciTE.

You can download Scintilla and SciTE. ');
}
//-- &amp; gt;

You can download Scintilla and SciTE.


There are some extra configuration files that can
enhance SciTE for various languages and APIs.


Questions and comments about SciTE should be directed to the
scite-interest
mailing list,
which is for discussion of SciTE and related projects, their bugs and future features.
This is a low traffic list, averaging less than 50 messages per week.
To avoid spam, only list members can write to the list.
New versions of SciTE are announced on scite-interest and may also be received by SourceForge
members by clicking on the Monitor column icon for &quot; scite &quot; on
the downloads page .
Messages sent to my personal email address that could have been sent to the list
may receive no response.


There is a Scintilla project page hosted on

');
document.write(' ');
} else {
document.write(' SourceForge ');
}
//-- &amp; gt;


scite228.zip > SciTEDoc.html

SciTE


table {
border: 1px solid #1F1F1F;
border-collapse: collapse;
}
td {
border: 1px solid #1F1F1F;
padding: 1px 5px 1px 5px;
}
th {
border: 1px solid #1F1F1F;
padding: 1px 5px 1px 5px;
}
.windowsonly {
background: #EBF3FF;
}
.gtkonly {
background: #FFFFE7;
}
.example {
color: #008000;
font-weight: bold;
}
DIV.example {
background: #F7FCF7;
border: 1px solid #C0D7C0;
margin: 0.3em 3em;
padding: 0.3em 0.6em;
font-size: 80%;
}
h3 {
border: 2px solid #FFCC00;
background-color: #FFF7EE;
padding: 2px 5px;
}
.header{
border: 1px solid #CCCCCC;
}
.headerlinks {
padding: 7px;
background-color: #CCCCCC;
border: 0px solid #FF0000;
font-size: 120%;
}










SciTE Documentation







Frequently Asked Questions &amp; nbsp; &amp; nbsp;

Scripting &amp; nbsp; &amp; nbsp;
Regular Expressions &amp; nbsp; &amp; nbsp;




Standard Editing


Text editing in SciTE works similarly to most Macintosh or Windows editors with the added
feature of automatic syntax styling. SciTE can hold multiple files in memory at one time but
only one file will be visible. Rectangular
blocks of text can be selected in SciTE by holding down the Alt key on Windows or the Ctrl
key on GTK+ while dragging the mouse over the text. The modifier key used on GTK+
can be changed with the rectangular.selection.modifier property.


There are two panes in SciTE, the editing pane and the output pane. The output pane is
located either to the right of the editing pane or below it. Initially it is of zero size, but
it can be made larger by dragging the divider between it and the editing pane. The Options |
Vertical Split command can be used to move the output pane beneath the editing pane.


SciTE can perform commands to compile or run source files with the output from these
commands directed into the output pane.


For example, if Python is installed on the machine, open
a new document, type:



print &quot; Hi &quot;



as that document's text.

Save the document as printhi.py.
The document should now appear coloured as SciTE is using the file's extension to decide upon
the syntax styling to use:


print
&quot; hi &quot;


Perform the Tools | Go command.
The output window will be made visible if it is not already visible and will show:


&amp; gt;python -u printhi.py
hi
&amp; gt;Exit code: 0


The first blue line is from SciTE showing the command it will use to run the program. The black
line is the output from running the Python program. The last blue line is from SciTE showing
that the program has finished and displaying its exit code. An exit code of zero indicates a
successful run.


SciTE partially understands the error messages produced by Python, GCC, Visual C++, Borland
C++, PHP and other tools which use the same format as one of these. To see this, add a mistake to
the Python file by adding a second line to make the file:



print
&quot; hi &quot;
mistake



Perform the Tools | Go command. The results should look like:



&amp; gt;python -u printhi.py
hi
Traceback (innermost last):
File &quot; printhi.py &quot; , line 2, in ?
mistake
NameError: mistake
&amp; gt;Exit code: 1



While it is easy to see where the problem is in this simple case, when a file is larger the
Tools | Next Message command can be used to view each of the reported errors. Upon performing
Tools | Next Message, the first error message in the output pane is highlighted with a yellow
background, and an error indicator is displayed for the appropriate line in the editing pane.
The caret is moved to this line and the pane is scrolled if needed to show the line. SciTE
now looks like this:



SciTE understands both the file name and line number parts of error messages in most cases
so can open another file (such as a header file) if errors were caused by that file. This
feature may not work where the file name is complicated by containing spaces or &quot; .. &quot;


If command execution has failed and is taking too long to complete then the Tools | Stop
Executing command can be used.


Command subsystem


Tools can be executed in various modes by SciTE which are called &quot; subsystems &quot; . Different
subsystems are supported on Windows and GTK+. The default subsystem is 0.


Windows
0 console Command line programs Do not use for GUI programs as their windows will not be visible.
1 windows Programs that create their own windows
2 shellexec Run using ShellExecute
A good way to open HTML files and
similar as it handles this similarly to a user opening the file from the shell.
3 lua director Internal extension or director extension
4 htmlhelp Open in HtmlHelp program
Two part command separated by ! with the first
part being the topic to search for and the second the name of the help file

5 winhelp Open with WinHelp function
Two part command similar to subsystem 4



GTK+
0 console Execute tool and wait for it to finish
2 shellexec Execute in background


Command line arguments


Command line arguments to SciTE include file names, commands and properties.
Commands and properties are preceded by &quot; - &quot; and are differentiated by the use in
commands of ':' as the first character that is not '.' or alphabetic.
Properties use the syntax used in property set files and override any
properties set in property files. If there is no value given for a property, it is set to 1.
Double quotes may be placed around arguments that contain spaces but they must be
placed around the whole argument, not just around a file name, so &quot; -open:x y.txt &quot; works but
-open: &quot; x y.txt &quot; doesn't.
On Linux, the standard shell quoting is available.
The &quot; -p &quot; argument causes SciTE to print the file and then exit.


For Windows :
The command line arguments &quot; - &quot; and &quot; -- &quot; (without the quotes) are special in that they read the
stdin stream into the last buffer ( &quot; - &quot; ), or the output pane ( &quot; -- &quot; ))
The command line argument &quot; -@ &quot; (without the quotes) is special in that file names are read from stdin
and opened.
Note: when reading stdin into the output pane, when the property split.vertical is 0, the
output pane is increased to its maximum height. When the property split.vertical is 1, the output pane is
increased to approximately half of the screen width.
Note: If stdin is not redirected, these arguments are effectively ignored.


For example,

SciTE &quot; -font.base=font:MS Gothic,size:11 &quot; -save.recent ScintillaGTK.cxx

starts SciTE, opens ScintillaGTK.cxx, loads the recent file list, and uses
11 point MS Gothic as the base font.
A group of properties can be saved as a property set file (with the extension
&quot; .properties &quot; ) and the import command used on the command line:

SciTE &quot; -import c:\os\web_work &quot; SciTEDoc.html


A few commands are currently available although this will expand in the future.
These commands are available:


Command Argument

close:
cwd: change working directory
find: search text
goto: line number[,column number]
open: file name
loadsession: file name
quit:
replaceall: search text\000replacement text
saveas: file name


Commands use C style escape sequences which include:


Escape Sequence Meaning

\\ backslash
\a bell
\b backspace
\f form feed
\n new line
\r carriage return
\t tab
\v vertical tab
\ &amp; lt;ooo &amp; gt; octal number specified by 1, 2, or 3 digits
\x &amp; lt;hh &amp; gt; hexadecimal number specified by 2 digits

The following opens /big/icon.txt:

SciTE -open:/big/icon.txt

On Windows, the following opens C:\Program Files\SciTE\SciTEDoc.html
and goes to the 123rd line:

SciTE &quot; -open:C:\\Program Files\\SciTE\\SciTEDoc.html &quot; -goto:123


Command line arguments are evaluated left to right in two phases because
opening files requires the user interface to be available and there is also a need
to set some user interface properties before the user interface is displayed.
The first phase process arguments until just before the first file name would be opened.
The second phase processes the remaining arguments.


So, if you need to perform e.g. a find: or a goto: command on a file, you must put
the command after the filename, to allow SciTE to open the file before performing the command.


For Windows :
If any simple file name on the command line matches a directory name, the file open dialog appears - this is dependant upon the property
&quot; open.dialog.in.file.directory &quot;
If the property &quot; buffers &quot; is greater than one and the file name matches either a existing file or by means of a wildcard search, one or more files, the
matching files are loaded up to the property &quot; buffers &quot; count. Directories are not considered a match in this case
If the file name is an extension, optionally preceded by a path, and no such simple file name exists, the file open dialog appears, with the given extension as
the filter.
If the file name contains no extension, the property &quot; source.default.extensions &quot; is used to provide default extensions to attempt to match the file name to an
existing file.


Buffers


SciTE may be configured to use between 1 and 100 buffers each containing a
file. The default is 1 and this effectively turns off buffers. With more than one buffer,
the Buffers menu can be used to switch between buffers, either by selecting the
file name or using the Previous (F6) and Next (Shift+F6) commands.
A tab is displayed for each buffer in the tab bar although this can be turned off with the
View | Tab Bar command.
A tab may be closed by clicking on it with the middle mouse button.
Setting large numbers of buffers may cause problems as some menus are fixed in length
and thus files beyond that length may not be accessible.


When all the buffers contain files, then opening a new file causes a buffer to be reused
which may require a file to be saved. In this case an alert is displayed to ensure the user
wants the file saved.


Sessions


A session is a list of file names. You can save a complete set of your
currently opened buffers as a session for fast batch-loading in the
future.
Sessions are stored as properties files with the extension &quot; .session &quot; .


Use File | Load Session and File | Save Session to load/save sessions.
You can turn on/off &quot; last session autoloading &quot; using SciTE properties
variable &quot; save.session &quot; .


If &quot; buffers &quot; variable is set to &quot; 0 &quot; session management is turned off.


Loading previously saved session will close your currently opened
buffers. However you will not lose your edits, because you will be
asked to save unsaved buffers first.


Opening a specific file from command line overrides &quot; save.session &quot;
variable state. When you start SciTE loading a specific file from
command line last session will not restore even if &quot; save.session &quot;
variable is set to &quot; 1 &quot; . This makes &quot; save.session &quot; safe to use - you
will never open a couple of files when you are trying to open just
one, specific file.


By setting &quot; session.bookmarks &quot; and &quot; session.folds &quot; variables bookmarks
and folding states of the currently opened buffers are saved in session
files and restored when sessions are loaded.


Languages understood by SciTE


SciTE currently is able to syntax style these languages (* denotes
support for folding):


Abaqus*
Ada
ANS.1 MIB definition files*
APDL
Assembler (NASM, MASM)
Asymptote*
AutoIt*
Avenue*
Batch files (MS-DOS)
Baan*
Bash*
BlitzBasic*
Bullant*
C/C++/C#*
Clarion*
cmake*
conf (Apache)*
CSound*
CSS*
D
diff files*
E-Script*
Eiffel*
Erlang*
Flagship (Clipper / XBase)*
Flash (ActionScript)*
Fortran*
Forth*
GAP*
Gettext
Haskell
HTML*
HTML with embedded JavaScript, VBScript, PHP and ASP*
Gui4Cli*
IDL - both MSIDL and XPIDL*
INI, properties* and similar
InnoSetup*
Java*
JavaScript*
LISP*
LOT*
Lout*
Lua*
Make
Matlab*
Metapost*
MMIXAL
MSSQL
nnCron
NSIS*
Objective Caml*
Opal
Octave*
Pascal/Delphi*
Perl, most of it except for some ambiguous cases*
PL/M*
Progress*
PostScript*
POV-Ray*
PowerBasic*
PowerShell*
PureBasic*
Python*
R*
Rebol*
Ruby*
Scheme*
scriptol*
Specman E*
Spice
Smalltalk
SQL and PLSQL
TADS3*
TeX and LaTeX
Tcl/Tk*
VB and VBScript*
Verilog*
VHDL*
XML*
YAML*


Running and building commands for some of these languages have been set up but should be
checked as they will have to be modified to work for many people.


To keep menus to a reasonable length some languages are included but have been commented
out in global options. These should be enabled by removing the comment character '#'.


Language settings are determined from the file extension but this can be changed
by selecting another language from the Language menu. The language menu can be
changed with the menu.language property.


Find and Replace


Either dialogs or strips may be used for find and replace, with dialogs being the default.
Strips are similar to find in web browsers, appearing at the bottom of the
window and are smaller and less distracting than dialogs.
They are specified with the find.use.strip and replace.use.strip properties.


SciTE has options to allow searching for words, regular expressions,
matching case, in the reverse direction, wrapping around the end of the
document.
C style backslash escapes which are listed in the command line
arguments section, may be used to search and replace control
characters.
Replacements can be made individually, over the current selection or
over the whole file. When regular expressions are used tagged
subexpressions can be used in the replacement text.
Regular expressions will not match across a line end.


SciTE supports
basic regular expressions
with tagging.


On Windows, pressing Shift+Enter when the focus is in a text entry field will search
in the opposite of the current direction, so will normally search backwards.


Keyboard commands


Keyboard commands in SciTE mostly follow common Windows and GTK+ conventions.
All movement keys (arrows, page up/down, home and end)
allow to extend or reduce a stream selection when holding the Shift key,
and a rectangular selection when holding the Shift and Alt keys.
Some keys may not be available with some national keyboards or because
they are taken by the system such as by a window manager on GTK+.
The user.shortcuts setting may be used to assign a key to a function.
Note that Home key behaviour is changed by the vc.home.key option.
Keyboard equivalents of menu commands are listed in the menus.
Some less common commands with no menu equivalent are:



Magnify text size. Ctrl+Keypad+


Reduce text size. Ctrl+Keypad-


Restore text size to normal. Ctrl+Keypad/


Cycle through recent files. Ctrl+Tab


Indent block. Tab


Dedent block. Shift+Tab


Delete to start of word. Ctrl+BackSpace


Delete to end of word. Ctrl+Delete


Delete to start of line. Ctrl+Shift+BackSpace


Delete to end of line. Ctrl+Shift+Delete


Go to start of document. Ctrl+Home


Extend selection to start of document. Ctrl+Shift+Home


Go to start of display line. Alt+Home


Go to end of document. Ctrl+End


Extend selection to end of document. Ctrl+Shift+End


Go to end of display line. Alt+End


Expand or contract a fold point. Ctrl+Keypad*


Select to next bookmark. Alt+F2


Select to previous bookmark. Alt+Shift+F2


Find selection. Ctrl+F3


Find selection backwards. Ctrl+Shift+F3


Scroll up. Ctrl+Up


Scroll down. Ctrl+Down


Line cut. Ctrl+L


Line copy. Ctrl+Shift+T


Line delete. Ctrl+Shift+L


Line transpose with previous. Ctrl+T


Selection duplicate. Ctrl+D


Find matching preprocessor conditional, skipping nested ones. Ctrl+K


Select to matching preprocessor conditional. Ctrl+Shift+K


Find matching preprocessor conditional backwards, skipping nested ones. Ctrl+J


Select to matching preprocessor conditional backwards. Ctrl+Shift+J


Previous paragraph. Shift extends selection. Ctrl+[


Next paragraph. Shift extends selection. Ctrl+]


Previous word. Shift extends selection. Ctrl+Left


Next word. Shift extends selection. Ctrl+Right


Previous word part. Shift extends selection Ctrl+/


Next word part. Shift extends selection. Ctrl+\


Rectangular block selection. Alt+Shift+Movement


Extend rectangular selection to start of line. Alt+Shift+Home


Extend rectangular selection to end of line. Alt+Shift+End



On Windows, a search can be performed in the opposite direction by
using Shift+Enter in the Find or Replace strips or dialogs.


Abbreviations


To use an abbreviation, type it and use the Expand Abbreviation
command or the Ctrl+B key. The abbreviation is replaced by an
expansion defined in the Abbreviations file. You can open the
Abbreviations file with a command in the Options menu and
add abbreviations. There is a default abbreviations file but a different
abbreviations file can be set for particular file extensions.


Each line in the files looks like &quot; abbreviation=expansion &quot; .
The abbreviations names can have any character (except perhaps control chars,
surely for CR and LF), including high Ascii chars (accented chars).
Names have properties files limits: they cannot start with sharp (#) or space or tab
(but can have spaces inside); and they cannot have '=' character inside.
Abbreviations names are limited to 32 characters. It is probably enough for
abbreviations ...


An expansion may contain new line characters indicated by '\n' and
a caret position indicated by the '|' character. To include a literal '|'
character, use '||'.
Some simple examples are included in the distributed Abbreviations file.
When expanding, the names don't need to be separated from the previous text.
Ie. if you define 'é' as ' &amp; amp;eacute;', you can expand it inside a word.
When multiple abbreviation names match, the longest matching name will be expanded.


Folding


SciTE supports folding for many languages (see the list of languages
understood by SciTE for more information.) Fold points are based upon
indentation for Python and on counting braces for the other languages.



The fold point markers (in the fold margin) can be clicked to expand and
contract folds. Normal clicking does not alter the fold state of child fold
points; naturally the children are hidden when the parent fold is
contracted, but when the parent is expanded again, each child is still
folded or not, as before.



Ctrl+Click on a fold point toggles it and performs the same operation on
all children.



Shift+Click on a fold point does not toggle that fold, it expands all the
child folds.



Ctrl+Shift+Click in the fold margin expands or contracts all the top level
folds.
&quot; Toggle all folds &quot; in the View menu does the same; it toggles only
top-level folds.



Tip:
To open a large code block with all its children folded, fold it with
Ctrl+Click, then open it with a normal click. Then on opening a child fold,
you will see that the grandchild folds are still closed; if you want those
'grandchild' folds open, Shift+Click the child fold.


Properties file


Much of SciTE's behaviour can be changed by editing the properties files.


There are four properties files used:

Local properties file called &quot; SciTE.properties &quot; which may be
present in the same directory as the file being edited.
Directory properties file called &quot; SciTEDirectory.properties &quot; which may be
present in the same or in a parent directory as the file being edited.
User properties file called &quot; SciTEUser.properties &quot; on Windows
and &quot; .SciTEUser.properties &quot; on GTK+
Global properties file called &quot; SciTEGlobal.properties &quot;


Settings in the local properties file override those in the directory properties file
which overrides those in the user properties file which override those
in the global properties files. Environment variables are also available as properties and these
are overridden by an explicit setting in one of the properties files.


The directory properties file can be used as project options file where user commands and
compile, build commands should work in the same manner in subdirectories of a project. The
benefit is that local properties files in subdirectories can be replaced by one properties file
which is located at the root of the project.
The evalution of the directory properties file is disabled by default and must be enabled by
setting the variable properties.directory.enable to 1 in the user or global properties file.


The user properties file is intended for customisation by the user,
leaving the global properties file to contain the default options distributed with SciTE.
The main use of the local properties files is to change the effects of the
Compile, Build and Go commands for the files in a directory. For example, I use the javac
compiler from the Java Development Kit for most work, so SciTEGlobal.properties sets the
command for compiling .java files to &quot; javac &quot; . If I want to use the jvc compiler for the files
in one directory, then the SciTE.properties file in that directory contains an entry setting
the command to &quot; jvc &quot; .


On Windows, the global properties file is located in the directory of the executable.
The user properties file is looked for in the user profile directory as set in the
USERPROFILE environment variable, or in the directory of the executable if
USERPROFILE is not set.
For GTK+ the user properties file is found in the user's home directory and the global
properties in a directory set at build time - normally /usr/share/scite.
If the &quot; SciTE_HOME &quot; environment variable is set on either Windows or GTK+ then it is where
both the global and user properties files are found.


There are commands in the Options menu for opening each of the properties files.


The files are in approximately the same format as Java properties files which have a simple
text format. Lines that start with '#' or that are completely blank are comments. Other lines
are of the form


variable=value


For long values, a '\' character at the end of the line continues that value on the next
line. Space characters are significant so x &amp; nbsp;=1 defines a variable called
&quot; x &amp; nbsp; &quot; .
Values may include the values of other variables by using $(variablename). There are
some variables set by the environment to access the name of the current file as well:



Name Meaning

FilePath full path of the current file
FileDir directory of the current file without a trailing slash
FileName base name of the current file
FileExt extension of the current file
FileNameExt $(FileName).$(FileExt)
Language name of the lexer used for the current file
SessionPath full path of the current session
CurrentSelection value of the currently selected text
CurrentWord value of word which the caret is within or near
Replacements number of replacements made by last Replace command
SelectionStartColumn column where selection starts
SelectionStartLine line where selection starts
SelectionEndColumn column where selection ends
SelectionEndLine line where selection ends
CurrentMessage most recently selected output pane message
SciteDefaultHome directory in which the Global Options file is found
SciteUserHome directory in which the User Options file is found
SciteDirectoryHome directory in which the Directory Options file is found
APIPath list of full paths of API files from api. filepattern
AbbrevPath full path of abbreviations file


Some features use file name patterns to see which variable to use. For example, the lexer
variable can be specialised for a particular file, or a group of files based upon wildcard
matching so:
lexer.makefile=makefile indicates that the lexer called &quot; makefile &quot; should be used on
files called &quot; makefile &quot; .
lexer.*.cxx=cpp indicates that the lexer called &quot; cpp &quot; should be used on files with a
&quot; cxx &quot; extension.
Variable substitution is available on the left hand side of file pattern assignments and
look like this:
file.patterns.html=*.html;*.htm;*.asp;*.shtml
command.go.$(file.patterns.html)=file://$(FilePath)


Wildcard matching only works where the wildcard is at the start of a file specification, so &quot; *.mak &quot; will match &quot; proj.mak &quot; but
&quot; Makefile* &quot; will not match &quot; Makefile.in &quot; .


Properties files are not treated as having a particular encoding, however individual property values
may be treated as having an encoding. For file names, commands, and user interface text, this is
UTF-8 so it may be easier to edit properties files as UTF-8 by inserting a coding cookie as explained later.
Other properties may be treated as byte sequences (like word.characters. filepattern ) or in an implicit
encoding (such as keywords. filepattern matching the document encoding) so that it may be better to
edit these settings using a non-UTF-8 encoding. Where both UTF-8 and non-UTF-8 values are wanted,
two files can be used with different encodings and an import statement to include one in the other.


Importing properties files and conditional logic


The 'import' statement includes a properties file as if the text were
inline at that point. The imported properties file
must be in the same directory as the current file and a properties
extension is assumed. Therefore a &quot; import Lua &quot; statement in
c:\os\scite\bin\SciTEGlobal.properties will import
c:\os\scite\bin\Lua.properties.


The 'if' statement takes one argument which is a
symbol that may be defined earlier in this property set file or in a base
property set. If the symbol evaluates to '0' then the test fails. An empty
string or not present symbol evaluates to 0. Into the very top property set
is inserted one of 'PLAT_GTK' with value '1',
'PLAT_WIN' with value '1', or 'PLAT_MAC' with value '1'.
If the test succeeds then following indented statements are executed. When a
non-indented statement is found the if clause is finished. Only simple set
statements are allowed in if clauses. The evaluation of if statements occurs
at read time, not at evaluation time.


Command parameters and prompting


SciTE has 4 properties $(1) .. $(4) which can be used to run commands with
changeable parameters. To set the parameter values, use the View | Parameters
command to view the modeless Parameters dialog which shows the current values
of these parameters and allows setting new values. The accelerator keys for the main
window remain active while this dialog is displayed, so it can be used to rapidly run
a command several times with different parameters. Alternatively, a command can be
made to display the modal Parameters dialog when executed by starting the
command with a '*' which is otherwise ignored. If the modeless Parameters dialog is
already visible, then the '*' is ignored.


Encodings


SciTE will automatically detect the encoding scheme used for Unicode files that
start with a Byte Order Mark (BOM).
The UTF-8 and UTF-16 encodings are recognised including both Little Endian and
Big Endian variants of UTF-16.


UTF-8 files will also be recognised when they contain a coding cookie on one of the
first two lines. A coding cookie looks similar to &quot; coding: utf-8 &quot; ( &quot; coding &quot; followed by ':'
or '=', optional whitespace, optional quote, &quot; utf-8 &quot; ) and is normally contained in
a comment:
# -*- coding: utf-8 -*-
For XML there is a declaration:
&amp; lt;?xml version='1.0' encoding='utf-8'? &amp; gt;

For other encodings set the code.page and character.set properties.


Defined variables in properties files


Some properties are only available on
Windows or
GTK+ .




position.left
position.top
position.width
position.height
position.maximize


Set the initial window size and position. If these are omitted then the
environment's defaults are used. If the width or height are -1 or the
position.maximize property is set then the window is maximised.




position.tile


If there is another copy of SciTE open, set the initial window position to be
with the left side at position.left + position.width so that most of the time
you can see both copies at once without overlap.
Works nicely if position.left set to 0 and position.width set to half of the
screen width.




buffers


Set to a number between 1 and 100 to configure that many buffers.
Values outside this range are clamped to be within the range.
The default is 1 which turns off UI features concerned with buffers.
This value is read only once, early in the startup process and only from the
global properties files. So after changing it, restart SciTE to see the effect.




buffers.zorder.switching


This setting chooses the ordering of buffer switching when Ctrl+Tab pressed.
Set to 1, the buffers are selected in the order of their previous selection otherwise
they are chosen based on the buffer number.




are.you.sure
are.you.sure.for.build


The classic GUI question. Normally, when SciTE is about to close a file which has unsaved
edits it asks this annoying question. To turn off the question, set are.you.sure to 0 and
files will be automatically saved without bothering the user. To abandon edits to a file
use the New command. New always asks &quot; Are you sure? &quot; giving an opportunity to not save
the file.
When running or building a file, its most likely that you want the file to be saved
first. To enable a confirmation dialog for performing Compile, Build or Go commands, set
are.you.sure.for.build=1.




save.all.for.build


SciTE normally saves the current buffer when performing a Compile, Build, or Go
command. To save all buffers set save.all.for.build=1




view.whitespace
view.indentation.whitespace


Setting view.whitespace to 1 makes SciTE start up with whitespace visible.
Setting view.indentation.whitespace to 0 hides visible whitespace inside indentation.




whitespace.fore
whitespace.back


Sets the colours used for displaying all visible whitespace, overriding any styling
applied by the lexer.




view.indentation.guides
view.indentation.examine
view.indentation.examine. filepattern
highlight.indentation.guides


Setting view.indentation.guides to 1 displays dotted vertical lines within indentation white
space every indent.size columns.
Setting view.indentation.examine to 1 to display guides within real indentation whitespace only,
2 according to the next non-empty line (good for Python) or 3 according to both the next and
previous non-empty lines (good for most languages).
Setting highlight.indentation.guides to 1 highlights the indentation guide associated with a
brace when that brace is highlighted.




view.eol


Setting this to 1 makes SciTE display the characters that make up line ends. This looks
similar to (CR), (LF), or (CR)(LF). This is useful when using files created on another
operating system with software that is picky about line ends.




eol.mode


The default EOL mode (characters that make up line ends)
depends on your platform.
You can overwrite this behaviour by setting the property to

LF for UNIX and OS X format
CR for Macintosh format prior to OS X
CRLF for DOS/Windows format




eol.auto


This setting overrides the eol.mode value and chooses the end of
line character sequence based on the current contents of the file
when it is opened. The line ending used the most in the file is chosen.




blank.margin.left
blank.margin.right


There is a blank margin on both sides of the text. It is drawn in the background colour
of default text. This defaults to one pixel for both left and right sides but may be
altered with these settings.




margin.width


Setting this to a number makes SciTE display a selection margin to the left of the text.
The value is the number of pixels wide the selection margin should be. Line markers are
displayed in the selection margin area.




full.screen.hides.menu


Setting this to 1 hides the menu bar when the Full Screen command is used on
Windows.
On GTK+ the menu is always visible.




minimize.to.tray


Setting this to 1 minimizes SciTE to the system tray rather than to the task bar.




line.margin.visible
line.margin.width


SciTE is able to display a column of line numbers to the left of the selection
margin. Setting line.margin.visible to 1 makes this column visible at startup.
The line.margin.width property controls how much space is reserved for the line
numbers, in terms of the number of digits that can be displayed. To specify that
the margin should expand if needed to accomodate larger line numbers, add a '+'
after the number of digits, e.g. line.margin.width=3+ .




tabbar.visible


Setting tabbar.visible to 1 makes the tab bar visible at start up.
The buffers property must be set to a value greater than 1 for this option to work.




tabbar.hide.one


Setting tabbar.hide.one to 1 hides the tab bar until there is more than one tab.




tabbar.multiline


Setting tabbar.multiline uses multiple lines for the tab bar




toolbar.visible


Setting this to 1 makes the tool bar visible at start up.




toolbar.detachable


Setting this to 1 makes the tool bar detachable from the main window.




toolbar.usestockicons


SciTE has a built-in icon set for the toolbar, setting this to 1 makes
SciTE more integrated in the GNOME desktop by using the icons
provided by the current theme used in GNOME.




pathbar.visible


The path bar is a line of text under the tab bar showing the full path of the currently selected tab.
Setting pathbar.visible to 1 makes the path bar visible on GTK+.




undo.redo.lazy


Setting this to 1 changes the technique used to determine when to enable or disable
tool bar buttons to be less accurate. This may improve performance on slow machines.




statusbar.visible


Setting this to 1 makes the status bar visible at start up.




statusbar.number
statusbar.text. number


The statusbar.text.1 option defines the information displayed in the status bar
by default on all platforms.
Property values may be used in this text using the $() syntax.
Commonly used properties are: ReadOnly, EOLMode, BufferLength,
NbOfLines (in buffer), SelLength (chars), SelHeight (lines).
Extra properties defined for the status bar are LineNumber, ColumnNumber, and
OverType which is either &quot; OVR &quot; or &quot; INS &quot; depending on the overtype status.
You can also use file properties, which, unlike those above, are not updated
on each keystroke: FileName or FileNameExt, FileDate and FileTime and
FileAttr. Plus CurrentDate and CurrentTime.
On Windows only, further texts may be set as statusbar.text.2 .. and these may be
cycled between by clicking the status bar.
The statusbar.number option defines how many texts are to be cycled through.




use.palette


Setting this to 1 makes SciTE use a palette to enable it to display more colours on 8 bit
displays. Without this option SciTE will only display with colours already available
which is normally the 20 colour Windows system palette. The downside of turning on this
option is that there will be some flashing as windows are activated. This option has no
effect on GTK+ where a palette is always used.




buffered.draw


Setting this to 0 rather than the default 1 makes SciTE draw output directly to the
screen rather than into a buffer bitmap first and then to the screen. Buffered drawing
flickers less but is slower.




two.phase.draw


Two phase drawing is a better but slower way of drawing text.
In single phase drawing each run of characters in one style is drawn along with
its background.
If a character overhangs the end of a run, such as in &quot; V _ &quot; where the
&quot; V &quot; is in a different style from the &quot; _ &quot; , then this can cause the right hand
side of the &quot; V &quot; to be overdrawn by the background of the &quot; _ &quot; which
cuts it off. Two phase drawing
fixes this by drawing all the backgrounds first and then drawing the text in
transparent mode. Two phase drawing may flicker more than single phase
unless buffered drawing is on. The default is for drawing to be two phase.




load.on.activate
save.on.deactivate


The load.on.activate property causes SciTE to check whether the current file has been
updated by another process whenever it is activated. This is useful when another editor
such as a WYSIWYG HTML editor, is being used in conjunction with SciTE.
The save.on.deactivate property causes SciTE to save the file whenever the SciTE
application loses focus. This is useful when developing web pages and you want to often
check the appearance of the page in a browser.




are.you.sure.on.reload


When both this and load.on.activate are set to 1, SciTE will ask if you really want to
reload the modified file, giving you the chance to keep the file as it is. By default this
property is disabled, causing SciTE to reload the file without bothering you.




reload.preserves.undo


When set to 1, reloading a file does not delete all the undo history. This is useful
when load.on.activate is used in conjunction with filter commands.




check.if.already.open


This option allows opening files in an existing instance of SciTE rather than
always opening a new instance.
When this option is set and SciTE is started, it checks to see if
there are any other instances of SciTE open. If there is, another
instance is asked to open the file and become active and the new
instance exits.
On Windows, the instance with the Options | Open Files Here
menu item checked opens the file.
On GTK+, an arbitrary instance opens the file.




read.only


When this option is set then opened documents are initially read only.
New files are not affected by this setting.




temp.files.sync.load


Files dropped on SciTE on Windows are normally opened asynchronously
as there may be a long list. However, files dragged from some applications
such as 7-Zip may only exist for a moment in the temporary directory and
be deleted once the drop has occurred.
Setting this to 1 makes SciTE open dropped files in the temporary directory
immediately.




quit.on.close.last


If this option is set, SciTE will close when its last buffer has been
closed, e.g. with File/Close. (By default, if this option is not set,
SciTE will remain open and will create a new blank document when its
last buffer is closed.)




highlight.current.word


When set to 1, all occurrences of the selected word are highlighted with the
colour defined by highlight.current.word.colour. By default, this option is disabled. (See indicators.alpha and indicators.under)




highlight.current.word.colour
highlight.current.word.by.style


The option highlight.current.word.colour defines the colour of highlight.
The default value is #A0A000.
If the option highlight.current.word.by.style is set, then only words with the same style
are highlighted (e.g. if you select this word in a comment, then only occurrences of words in
comments are selected).




rectangular.selection.modifier


On GTK+, the modifier key used to make rectangular selections can be set with this
property. Valid options are 2 (Ctrl), 4 (Alt) or 8 (Super). Super is often assigned to the
Windows/Start key on Windows keyboards or the Command key on Mac keyboards.

Since the Alt key is often used by window managers to move windows, this will need to
be configured off to use the combination in SciTE. This can be done for Metacity using
gconf-editor to modify the /apps/metacity/general/mouse_button_modifier. A valid value here
is &amp; lt;Super &amp; gt;.




selection.fore
selection.back
selection.alpha


Sets the colours used for displaying selected text. If one of these is not set then that
attribute is not changed for the selection. The default is to show the selection by
changing the background to light grey and leaving the foreground the same as when it was
not selected. The translucency of the selection is set with selection.alpha with an alpha
of 256 turning translucency off.




caret.fore


Sets the colour used for the caret.




selection.additional.fore
selection.additional.back
selection.additional.alpha


Similar to selection.fore, selection.back, selection.alpha.
Sets the colours used for displaying additional selections when multiple selections are
enabled or a rectangular selection is made.




caret.additional.blinks


Set whether all carets blink. 0 means only the main caret blinks. Default is 1.




caret.line.back
caret.line.back.alpha


Sets the background colour and translucency used for line containing the caret.
Translucency ranges from 0 for completely transparent to 255 for opaque with
256 being opaque and not using translucent drawing code which may be slower.




caret.period


Sets the rate at which the caret blinks. The value is the time in milliseconds that the
caret is visible before it is switched to invisible. It then stays invisible for the same
period before appearing again. A value of 0 stops the caret from blinking.




caret.width


Sets the width of the caret in pixels. Only values of 1, 2, or 3 work.




selection.multiple
selection.additional.typing


Set selection.multiple to make multiple selections with the mouse by holding down the Ctrl key.
Set selection.additional.typing to 1. to allow typing, backspace and delete to affect all selections including each line
of rectangular selections. When set to 0, typing only affectes the main selection.




virtual.space


Determines whether the caret can be moved into virtual space, that is, beyond the last character on a line.
Set to 1 to allow virtual space when making a rectangular selection, 2 to allow the arrow keys or a mouse
click to move the caret into virtual space, and 3 to allow both.




caret.policy.xslop
caret.policy.width
caret.policy.xstrict
caret.policy.xeven
caret.policy.xjumps
caret.policy.yslop
caret.policy.lines
caret.policy.ystrict
caret.policy.yeven
caret.policy.yjumps


If slop is set, we can define a slop value: width for xslop, lines for yslop.
This value defines an unwanted zone (UZ) where the caret is... unwanted.
This zone is defined as a number of pixels near the vertical margins,
and as a number of lines near the horizontal margins.
By keeping the caret away from the edges, it is seen within its context,
so it is likely that the identifier that the caret is on can be completely seen,
and that the current line is seen with some of the lines following it which are
often dependent on that line.

If strict is set, the policy is enforced... strictly.
The caret is centred on the display if slop is not set,
and cannot go in the UZ if slop is set.

If jumps is set, the display is moved more energetically
so the caret can move in the same direction longer before the policy is applied again.
'3UZ' notation is used to indicate three time the size of the UZ as a distance to the margin.

If even is not set, instead of having symmetrical UZs,
the left and bottom UZs are extended up to right and top UZs respectively.
This way, we favour the displaying of useful information: the begining of lines,
where most code reside, and the lines after the caret, eg. the body of a function.
See the table below to see how these settings interact.
Default: xslop, yslop, xeven, yeven=1, width=50, all others = 0.




visible.policy.strict
visible.policy.slop
visible.policy.lines


Determines how the display area is determined after a Go to command or
equivalent such as a Find or Next Message. Options are similar to caret.policy.*.




edge.mode
edge.column
edge.colour


Indicates long lines. The default edge.mode, 0, does not indicate long lines. An
edge.mode of 1 uses a vertical line to indicate the specified column and an edge.mode of
2 changes the background colour of characters beyond that column. For proportional fonts,
an edge.mode of 2 is more useful than 1.




control.char.symbol


Sets the character to use to indicate control characters. If
not set, control characters are shown as mnemonics.




error.marker.fore
error.marker.back


The colours used to indicate error and warning lines in both the edit and output panes
are set with these two values.
If there is a margin on a pane then a symbol is displayed in the margin to indicate
the error message for the output pane or the line causing the error message for the edit pane.
The error.marker.back is used as the fill colour of the symbol and the error.marker.fore
as the outline colour. If there is no margin then the background to the line is set to the
error.marker.back colour.




bookmark.fore
bookmark.back
bookmark.alpha


The colours used to display bookmarks in the margin. If bookmark.fore is not set then
a blue sphere is used. When the margin is turned off, bookmarks are shown by a
change in the background colour of the line with the translucency set with bookmark.alpha.




find.mark


If set, then the Mark All command in the Find dialog will draw translucent boxes over
each string found. (See indicators.alpha and indicators.under)




indicators.alpha


This property defines the alpha level for indicators (default value is 30).
The alpha value can range from 0 (completely transparent) to 255 (no transparency).
A value out of this range is ignored and the default one is used.




indicators.under


If set, the indicators are drawn under text or over (by default, it is over).




error.select.line


When a command execution produces error messages, and you step with F4 key through
the matching source lines, this option selects the line where the error occurs.
Most useful if the error message contains the column of error too as the selection will
start at the column of the error. The error message must contain the column and must be
understood by SciTE (currently only supported for HTML Tidy). The tab size assumed by
the external tool must match the tab size of your source file for correct column reporting.



openpath. filepattern
Defines a path for the Open Selected Filename command in the File
menu. The path is searched if the selected filename doesn't contain an
absolute path or the file is not found in the document directory. The
directories in openpath are separated by ';' on Windows and ':' on OS X and GTK+.
An openpath setting may look like:

openpath.*.txt=c:\dos\;f:\;
openpath.$(file.patterns.cpp)=$(cpp_includes)



open.suffix. filepattern
Defines a suffix to add to the selected file name for the
Open Selected Filename command in the File menu.
This is used in languages where the suffix is not given when accessing a file.
An example is python where &quot; import xlib &quot; will most often mean to import from
a file called &quot; xlib.py &quot; .
An open.suffix setting may look like:
open.suffix.*.py=.py




strip.trailing.spaces


Strips trailing white spaces from the file while saving.




ensure.final.line.end


Ensures file ends with a line end when saved.




ensure.consistent.line.ends


Ensures all lines end with the current Line End Characters setting when saved.




abbreviations. filepattern


Loads an abbreviations file for a particular language overriding the default abbreviations file.
For example,

abbreviations.*.c=$(SciteUserHome)/c_abbrev.properties





api. filepattern


Loads a set of API files for a particular language.
If there is more than one API file then the file names are separated by ';'.
API files contain a sorted list of
identifiers and function prototypes, one per line. If there are multiple files then each file should
end with a line end or the next file's first line will merge with the previous file's last line.
The &quot; Complete Symbol &quot; command
looks at the characters before the caret and displayed the subset of the API file
starting with that string. When an opening brace is typed, the file is searched for the
text preceding the caret and if a function prototype is found then it is displayed as a
calltip.
For example, the setting

api.*.c=w.api

could be used with a w.api file containing

fclose(FILE* fileClose)
FILE
fopen(const char* szFileName, const char* szMode)
fpos_t
fread(void* buf, size_t size, size_t count, FILE* file)
fseek(FILE* file, long lnOffset, int nOrigin)

to provide autocompletion and calltips for some of the C file functions. It is best to
use the full path to the API file as otherwise the current directory is used.
See the Creating API files section for ways to create API files.




autocomplete.choose.single


When set to 1 and an autocompletion list is invoked and there is only one element
in that list then that element is automatically chosen. This means that the matched
element is inserted and the list is not displayed.




autocomplete. lexer .ignorecase
autocomplete.*.ignorecase


When set to 1 the API file is searched in a case insensitive way to find elements
for autocompletion lists. Otherwise matches only occur if case also matches.
The * form is used if there is no lexer specific setting.




autocomplete. lexer .start.characters
autocomplete.*.start.characters


If this setting is not empty, typing any of the characters will cause
autocompletion to start. For example, if
autocomplete.python.start.characters=. and the API file for Python
contains &quot; string.rjust &quot; and &quot; string.replace &quot; then typing &quot; string. &quot; will
cause the autocompletion to display both identifiers.
The * form is used if there is no lexer specific setting.




autocomplete. lexer .fillups
autocomplete.*.fillups


If this setting is not empty, typing any of the characters will cause
autocompletion to complete.
For example, if
autocomplete.python.fillups=( and the API file for Python
contains &quot; string.replace &quot; then typing &quot; string.r( &quot; will
cause &quot; string.replace( &quot; to be inserted.
The * form is used if there is no lexer specific setting.




autocompleteword.automatic


If this setting is 1 then when typing a word, if only one word in the document
starts with that string then an autocompletion list is displayed with that word so it
can be chosen by pressing Tab.




calltip. lexer .ignorecase
calltip.*.ignorecase


When set to 1 the API file is searched in a case insensitive way to find the function
which will have its signature displayed as a calltip. The * form is use if there
is no lexer specific setting.




calltip. lexer .word.characters
calltip.*.word.characters


To determine the identifier to look up for calltips, a search is performed
allowing the characters in this set to be included in the identifier.
While the same setting can be used as for word.characters, sometimes
additional characters may be allowed.
For example, in Python, '.' is not normally considered part of a word
when selecting text, but it is good to allow &quot; string.replace &quot; to show a
calltip so calltip.python.word.characters=._$(chars.alpha) would be a
reasonable setting.
The * form is used if there is no lexer specific setting.




calltip. lexer .parameters.start
calltip. lexer .parameters.end
calltip. lexer .parameters.separators
calltip.*.parameters.start
calltip.*.parameters.end
calltip.*.parameters.separators


Allows you to specify characters which start, end and separate
parameters. For most common languages, it's usually left brace for
start, right brace for end and comma or semicolon for separator.
E.g. CSS has colon for start, space for separator and nothing for
end. You can specify more characters for each property.
The * form is used if there is no lexer specific setting.




calltip. lexer .end.definition
calltip.*.end.definition


API files may contain explanatory text after each function definition.
To display the explanation on a second line, set this property to the character used at the
end of the definition part. For most languages, this is ')'.
The * form is used if there is no lexer specific setting.




xml.auto.close.tags


For XML and HTML, setting this property to 1 will automatically insert the
corresponding end tag when ' &amp; gt;' is typed to end a start tag.
Type &quot; &amp; lt;td &amp; gt; &quot; and the result will be &quot; &amp; lt;td &amp; gt; &amp; lt;/td &amp; gt; &quot; with the caret
placed between the tags.





asp.default.language
Script in ASP code is initially assumed to be in JavaScript. To change this to VBScript set asp.default.language to 2. Python is 3.


fold.asm.comment.explicit
This option enables folding explicit fold points when using the Asm lexer. Explicit fold points allows adding extra folding by placing a ;{ comment at the start and a ;} at the end of a section that should fold.


fold.asm.comment.multiline
Set this property to 1 to enable folding multi-line comments.


fold.asm.explicit.anywhere
Set this property to 1 to enable explicit fold points anywhere, not just in line comments.


fold.asm.explicit.end
The string to use for explicit fold end points, replacing the standard ;}.


fold.asm.explicit.start
The string to use for explicit fold start points, replacing the standard ;{.


fold.asm.syntax.based
Set this property to 0 to disable syntax based folding.


fold.at.else
This option enables C++ folding on a &quot; } else { &quot; line of an if statement.


fold.basic.comment.explicit
This option enables folding explicit fold points when using the Basic lexer. Explicit fold points allows adding extra folding by placing a ;{ (BB/PB) or '{ (FB) comment at the start and a ;} (BB/PB) or '} (FB) at the end of a section that should be folded.


fold.basic.explicit.anywhere
Set this property to 1 to enable explicit fold points anywhere, not just in line comments.


fold.basic.explicit.end
The string to use for explicit fold end points, replacing the standard ;} (BB/PB) or '} (FB).


fold.basic.explicit.start
The string to use for explicit fold start points, replacing the standard ;{ (BB/PB) or '{ (FB).


fold.basic.syntax.based
Set this property to 0 to disable syntax based folding.


fold.comment
This option enables folding multi-line comments and explicit fold points when using the C++ lexer. Explicit fold points allows adding extra folding by placing a //{ comment at the start and a //} at the end of a section that should fold.


fold.cpp.comment.explicit
Set this property to 0 to disable folding explicit fold points when fold.comment=1.


fold.cpp.comment.multiline
Set this property to 0 to disable folding multi-line comments when fold.comment=1.


fold.cpp.explicit.anywhere
Set this property to 1 to enable explicit fold points anywhere, not just in line comments.


fold.cpp.explicit.end
The string to use for explicit fold end points, replacing the standard //}.


fold.cpp.explicit.start
The string to use for explicit fold start points, replacing the standard //{.


fold.cpp.syntax.based
Set this property to 0 to disable syntax based folding.


fold.d.comment.explicit
Set this property to 0 to disable folding explicit fold points when fold.comment=1.


fold.d.comment.multiline
Set this property to 0 to disable folding multi-line comments when fold.comment=1.


fold.d.explicit.anywhere
Set this property to 1 to enable explicit fold points anywhere, not just in line comments.


fold.d.explicit.end
The string to use for explicit fold end points, replacing the standard //}.


fold.d.explicit.start
The string to use for explicit fold start points, replacing the standard //{.


fold.d.syntax.based
Set this property to 0 to disable syntax based folding.


fold.html
Folding is turned on or off for HTML and XML files with this option. The fold option must also be on for folding to occur.


fold.html.preprocessor
Folding is turned on or off for scripts embedded in HTML files with this option. The default is on.


fold.hypertext.comment
Allow folding for comments in scripts embedded in HTML. The default is off.


fold.hypertext.heredoc
Allow folding for heredocs in scripts embedded in HTML. The default is off.


fold.perl.at.else
This option enables Perl folding on a &quot; } else { &quot; line of an if statement.


fold.perl.comment.explicit
Set to 0 to disable explicit folding.


fold.perl.package
Set to 0 to disable folding packages when using the Perl lexer.


fold.perl.pod
Set to 0 to disable folding Pod blocks when using the Perl lexer.


fold.preprocessor
This option enables folding preprocessor directives when using the C++ lexer. Includes C#'s explicit #region and #endregion folding directives.


fold.quotes.python
This option enables folding multi-line quoted strings when using the Python lexer.


fold.sql.at.else
This option enables SQL folding on a &quot; ELSE &quot; and &quot; ELSIF &quot; line of an IF statement.


html.tags.case.sensitive
For XML and HTML, setting this property to 1 will make tags match in a case sensitive way which is the expected behaviour for XML and XHTML.


lexer.asm.comment.delimiter
Character used for COMMENT directive's delimiter, replacing the standard &quot; ~ &quot; .


lexer.cpp.allow.dollars
Set to 0 to disallow the '$' character in identifiers with the cpp lexer.


lexer.cpp.track.preprocessor
Set to 1 to interpret #if/#else/#endif to grey out code that is not active.


lexer.cpp.triplequoted.strings
Set to 1 to enable highlighting of triple-quoted strings.


lexer.cpp.update.preprocessor
Set to 1 to update preprocessor definitions when #define found.


lexer.d.fold.at.else
This option enables D folding on a &quot; } else { &quot; line of an if statement.


lexer.errorlist.value.separate
For lines in the output pane that are matches from Find in Files or GCC-style diagnostics, style the path and line number separately from the rest of the line with style 21 used for the rest of the line. This allows matched text to be more easily distinguished from its location.


lexer.flagship.styling.within.preprocessor
For Harbour code, determines whether all preprocessor code is styled in the preprocessor style (0) or only from the initial # to the end of the command word(1, the default). It also determines how to present text, dump, and disabled code.


lexer.html.django
Set to 1 to enable the django template language.


lexer.html.mako
Set to 1 to enable the mako template language.


lexer.props.allow.initial.spaces
For properties files, set to 0 to style all lines that start with whitespace in the default style. This is not suitable for SciTE .properties files which use indentation for flow control but can be used for RFC2822 text where indentation is used for continuation lines.


lexer.python.keywords2.no.sub.identifiers
When enabled, it will not style keywords2 items that are used as a sub-identifier. Example: when set, will not highlight &quot; foo.open &quot; when &quot; open &quot; is a keywords2 item.


lexer.python.literals.binary
Set to 0 to not recognise Python 3 binary and octal literals: 0b1011 0o712.


lexer.python.strings.b
Set to 0 to not recognise Python 3 bytes literals b &quot; x &quot; .


lexer.python.strings.over.newline
Set to 1 to allow strings to span newline characters.


lexer.python.strings.u
Set to 0 to not recognise Python Unicode literals u &quot; x &quot; as used before Python 3.


lexer.sql.allow.dotted.word
Set to 1 to colourise recognized words with dots (recommended for Oracle PL/SQL objects).


lexer.sql.numbersign.comment
If &quot; lexer.sql.numbersign.comment &quot; property is set to 0 a line beginning with '#' will not be a comment.


lexer.xml.allow.scripts
Set to 0 to disable scripts in XML.


sql.backslash.escapes
Enables backslash as an escape character in SQL.


styling.within.preprocessor
For C++ code, determines whether all preprocessor code is styled in the preprocessor style (0, the default) or only from the initial # to the end of the command word(1).


tab.timmy.whinge.level
For Python code, checks whether indenting is consistent. The default, 0 turns off indentation checking, 1 checks whether each line is potentially inconsistent with the previous line, 2 checks whether any space characters occur before a tab character in the indentation, 3 checks whether any spaces are in the indentation, and 4 checks for any tab characters in the indentation. 1 is a good level to use.





user.shortcuts


Define keys that perform commands.
This is a '|' delimited list of keys and the commands they produce.
The commands are either string or numeric IDs .
Numeric IDs above 2000 are Scintilla commands and are sent to the focussed pane.
Named IDs and numeric IDs below 2000 are SciTE menu commands.
The modifiers are Ctrl, Shift, and Alt and the named keys are Left,
Right, Up, Down, Insert, End, Home, Enter, Space, Tab, KeypadPlus, KeypadMinus,
KeypadMultiply, KeypadDivide, Escape, Delete, PageUp, PageDown, Slash,
Question, Equal, Win.


user.shortcuts=\
Ctrl+Shift+I|IDM_OPEN|\
Ctrl+Shift+Left|IDM_CLOSE|

This property is only read at start up.





user.context.menu


Define additional commands for the context menu.
This is a '|' delimited list of menu items and the commands they
produce with commands defined as in user.shortcuts. An empty
item produces a separator.


user.context.menu=\
||\
Next File|IDM_NEXTFILE|\
Prev File|IDM_PREVFILE|





magnification
output.magnification


Sets the initial magnification factor of the edit and output panes. This is useful
when you want to change the size of text globally, such as after changing the
screen resolution without having to touch every style setting. 0 is default,
negative values makes the size smaller and positive values make it larger.




split.vertical
output.horizontal.size
output.vertical.size
output.initial.hide


If split.vertical is set to 1 then the output pane is to the right of the editing pane,
if set to 0 then the output pane is below the editing pane.
The output.*.size settings determine the initial size of the output pane.
If output.initial.hide is 1, then the output pane is hidden when SciTE first
starts up even when output.*.size is set; otherwise the output pane is shown at
startup.




clear.before.execute


If set to 1 then the output pane is cleared before any tool commands are run.




horizontal.scrollbar
horizontal.scroll.width
horizontal.scroll.width.tracking
output.horizontal.scrollbar
output.horizontal.scroll.width
output.horizontal.scroll.width.tracking
output.scroll
end.at.last.line


If horizontal.scrollbar set to 0 then the edit pane's horizontal scrollbar is not displayed.
horizontal.scroll.width is the document width assumed for scrolling.
Similarly, output.horizontal.scrollbar and output.horizontal.scroll.width controls the
horizontal scroll bar of the output pane.
The horizontal scroll bar widths can automatically grow as needed to ensure all displayed lines can be fully
scrolled with horizontal.scroll.width.tracking and output.horizontal.scroll.width.tracking.
To stop the output pane from automatically scrolling, set output.scroll to 0.
To have the output pane scroll and return back to the line of the executed command,
set output.scroll to 1. If you want the output pane to scroll and remain at
the bottom after execution, set output.scroll to 2.
The vertical scroll range is normally set so that maximum scroll position has
the last line at the bottom of the view. Set end.at.last.line to 0 to allow
scrolling one page below the last line.




wrap
output.wrap


If wrap set to 1 then the edit pane is dynamically line wrapped.
If output.wrap set to 1 then the output pane is dynamically line wrapped.
These options have a high performance cost which is proportional to the amount of text
so should be turned off for large documents on slow machines.




wrap.style


Chooses between word wrapping (1, the default) and character wrapping (2).
Character wrapping is a better choice for Asian languages with no spaces
between words.




wrap.visual.flags


Flags to display markers at end and begin of wrapped lines for visual identify them.
Set to 0 to not display markers (default). Set to 1 to display markers at end of
wrapped lines, to 2 to display markers at begin of wrapped lines and to 3 to
display markers at begin and end.




wrap.visual.flags.location


Flags to set the location of the display markers (if enabled) near to text or near to border.
Set to 0 to have begin and end markers near to border (default). Set to 1 to
have end markers near text, to 2 to have begin markers near text and
to 3 to have all markers near text.




wrap.indent.mode


Wrapped sublines can be indented in various ways relative to the initial subline.
Default mode 0 indents sublines to the left of window plus wrap.visual.startindent.
Mode 1 aligns sublines to the first subline.
Mode 2 aligns sublines to the first subline plus one more level of indentation.




wrap.visual.startindent


Sets the indention of continued wrapped lines to better visually identify the wrapping.
Default is 0 (no indention). Note if wrap.visual.flags is 2 or 3 (begin marker displayed)
the line is indented at least 1, even if wrap.visual.startindent is still 0.



wrap.aware.home.end.keys

This property changes the behaviour of the home and end keys when dynamic
line wrapping is turned on. When set to 0 (the default), the Home and End
keys will move the caret to the very beginning / end of the 'logical'
line, whether or not the line is wrapped over multiple lines in the display.
When this property is set to 1, the caret moves to the end of the current
'display' line if you press End once, or to the very end of the 'logical'
line if you press End again. Likewise, the Home key moves first to the
beginning of the 'display' line, then on to the very beginning of the line.
In a pane where dynamic line-wrapping is not enabled, this setting has no
effect.




cache.layout
output.cache.layout


A large proportion of the time spent in the editor is used to lay out text prior
to drawing it. This information often stays static between repaints so can
be cached with these settings. There are four levels of caching. 0 is no caching,
1 caches the line that the caret is on, 2 caches the visible page as well as the caret,
and 3 caches the whole document. The more that is cached, the greater the
amount of memory used, with 3 using large amounts of memory, 7 times the
size of the text in the document. However,
level 3 dramatically speeds up dynamic wrapping by around 25 times on large
source files so is a very good option to use when wrapping is turned on and
memory is plentiful.




open.filter


This is a complex expression used for determining the file types that will be available in
the open file dialog. For each type of file, there is some explanatory text, a '|'
character, some file patterns, and another '|' character. In the distributed
SciTEGlobal.properties file, the line continuation character '\', is used to spread these
items out, one per line. These file types appear in the &quot; Files of type: &quot; pull down. The
first item is the default, so you may wish to change the first item to include the file
types you commonly open.




save.filter


This is a complex expression used for determining the file types that will be available in
the save file dialog. The structure of the property is the same as open.filter.
Does not work on GTK+.




max.file.size


To avoid accidentally loading huge files on slow media, or just to ensure SciTE is used
only to edit human readable code, the user can set the max.file.size property to specify
a limit to file loading.
If unset or set to 0, there is no limit.
If set to a given size in bytes and if a file to load exceeds this limit, the user is asked
if the file should be loaded. If accepted, the file is read as usual. If rejected then no
action is taken (no file loaded, no buffer created).




save.deletes.first


Causes files to be deleted before being opened for saving. Can be used
to ensure saving under a different capitalisation changes the files capitalisation rather
than silently using the old capitalisation.




save.check.modified.time


With save.check.modified.time=1, when saving and the file has been modified by another
process, check if it should be overwritten by the current contents.




save.session
save.recent
save.position


If you set save.session, the list of currently opened buffers will be saved on exit
in a session file. When you start SciTE next time (without specifying a file name
on the command line) the last session will be restored automatically.
For GTK+, the file is called &quot; .SciTE.session &quot; and is located in the directory
given by the SciTE_HOME environment variable and if that is not set, the value
of the HOME environment variable and if that is not set, the top level directory.
For Windows, the file is called &quot; SciTE.session &quot; and is located in the directory
given by the SciTE_HOME environment variable and if that is not set, the value
of the USERPROFILE environment variable and if that is not set, the directory
of the SciTE executable.
Setting save.recent causes the most recently used files list to be saved on
exit in the session file and read at start up.
Setting save.position causes the SciTE window position on the desktop to be
saved on exit in the session file and restored at start up.




session.bookmarks
session.folds


Setting session.bookmarks causes bookmarks to be saved in session files.
If you set session.folds then the folding state will be saved in session
files. When loading a session file bookmarks and/or folds are restored.
Folding states are not restored if fold.on.open is set.




open.dialog.in.file.directory


Setting open.dialog.in.file.directory causes the open dialog to initially
display the same directory as the current file. If it is not set then the
system default is used.




find.close.on.find


Set to 0 to prevent the Find dialog from closing when &quot; Find &quot; pressed.




find.replace.matchcase
find.replace.regexp
find.replace.wrap
find.replace.escapes


These properties define the initial conditions for find and replace commands.
The find.replace.matchcase property turns of the &quot; Match case &quot; option,
find.replace.regexp the &quot; Regular expression &quot; option,
find.replace.wrap the &quot; Wrap around &quot; option and
find.replace.escapes the &quot; Transform backslash expressions &quot; option.




find.replacewith.focus


If the find.replacewith.focus property is set, the Replace With input box is focused
in the Replace dialog if Find What is non-empty.




find.replace.regexp.posix


Change behaviour of Regular expression search.
If set to 0 (the default), characters '(' and ')' must be escaped by '\' to behave as regexp meta characters.
If set to 1, these characters are meta characters itself.




find.use.strip
replace.use.strip


Use in-window strips rather than dialogs for performing Find or Replace commands.




strip.button.height


Buttons on GTK+ often contain extra spacing that makes strips take too much room.
This setting tries to limit the height of buttons.
A value of 23 or 24 may work well.




find.replace.advanced


Enables Replace in Buffers command
and Search only in this style checkbox.
If enabled, searches can be restricted to a particular style (e.g. strings).




find.command
find.input


The Find in Files command works in a similar way to the building commands executing a
command line tool with output redirected to the output pane. If the command produces
output understood by one of the error output passes, as does grep, then the F4 and
Shift+F4 keys can be used to move through all the matches. The $(find.what),
$(find.files), and $(find.directory) variables can be used for the values from the
Find in Files dialog.
There are some scripts that implement this feature in Perl better than grep does
itself
here and
here .
This command line works with Cygwin on Windows, with modifications to suit
the Cygwin installation directory:

find.command=cmd /c c:\cygwin\bin\find &quot; $(find.directory) &quot;
-name &quot; $(find.files) &quot; -print0 |
c:\cygwin\bin\xargs -0 fgrep -G -n &quot; $(find.what) &quot;

On Windows, the find string can be given to the find command through
its standard input stream to avoid problems with quote interpretation.
To do this, specify find.input to be the search string, $(find.what).

If find.command is empty then SciTE's own search code is used. This only does a
simple search without regular expressions and is faster than running an external program.




find.files


This is the default set of files to search through using the Find in Files command.
The find.files property can contain a list of sets of files separated by '|' like
&quot; *.cxx *.h|*.py *.pyw|*.html &quot; which adds three entries to the history and
uses the first as the default value.
The evaluation of this setting is a little unusual in that each entry in the value
from the property files is appended to the end of the history if that entry is
not already present. This means that opening files from different directories
will result in any local setting of find.files being added to the list.




find.in.dot


If find.in.dot is 1 then Find in Files searches in directories that start with '.'.
The default behaviour is to prevent SciTE finding matches in the unmodified versions of
files kept by Subversion in .svn subdirectories.




find.in.binary


If find.in.binary is 1 then Find in Files displays matches in binary files.
For Find in Files, a binary file is a file that contains a NUL byte in the first 64K block read from the file.




find.in.files.close.on.find


Set to 0 to prevent the Find in Files dialog from closing when &quot; Find &quot; pressed.




code.page
output.code.page


To support a DBCS language such as Japanese, a code page can be set here. This ensures
that double byte characters are always treated as a unit so the caret is never located
between the two bytes of a double byte character.

Code page Value
Default (single byte character set) 0
UTF-8 65001
Japanese Shift-JIS 932
Simplified Chinese GBK 936
Korean Wansung 949
Traditional Chinese Big5 950
Korean Johab 1361

Setting code.page to 65001 starts Unicode mode and the document is treated as
a sequence of characters expressed as UTF-8. Display is performed by converting to the
platform's normal Unicode encoding first so characters from any language will be displayed.
Correct glyphs may only be displayed if fonts are chosen that contain the appropriate glyphs.
The Tahoma font contains a wide range of glyphs so may be a good choice.
This property can not set a single byte character set.
If output.code.page is set then it is used for the output pane which otherwise
matches the edit pane.




character.set


This setting allows changing the character set that is asked for when setting up fonts.
Not all of the values will work on all platforms.

Character set Value
Default 0
Japanese 128
Chinese GB2312 134
Chinese BIG5 136
Korean 129
Greek 161
Eastern European 238
Baltic 186
Turkish 162
Hebrew 177
Arabic 178
Thai 222
Vietnamese 163
Cyrillic (CP1251 on Windows, KOI8-R on GTK+) 204
Cyrillic (CP1251 on GTK+) 1251
European with Euro (ISO 8859-15) 1000

All of these values except for 1251 and 1000 should work on OS X or Windows.
On GTK+ Baltic, Turkish, Thai and Vietnamese will probably not work.




comment.block. lexer
comment.block.at.line.start. lexer
comment.stream.start. lexer
comment.stream.end. lexer
comment.box.start. lexer
comment.box.middle. lexer
comment.box.end. lexer


These settings are for the comment commands in the Edit menu and are
defined separately for each lexer. Not all languages support
both stream and block comments.
Block comments are comments that start with a particular string and
continue until the end of line.
The comment.block property sets the string to be inserted or deleted
at the start of the selected lines when the Block Comment or Uncomment
command is performed. To make this command perform sensibly over
a range of text that already contains comments and other code, the string
can be defined to contain a character such as '~' that is not used in real
comments.
Set comment.block.at.line.start to &quot; 1 &quot; to place block comment symbols
at the start of the lines, instead of just before the first non-blank
character of the lines.
Stream comments start with a particular string and end with another
particular string and may continue over line ends. These are defined
with comment.stream.start and comment.stream.end.
Box comments are a form of stream comment that takes several lines
and uses different strings for the start, end and other lines in the range.
These are defined with comment.box.start,
comment.box.middle and comment.box.end.




preprocessor.symbol. filepattern
preprocessor.start. filepattern
preprocessor.middle. filepattern
preprocessor.end. filepattern


These settings make the preprocessor conditional movement and selection commands work.
The character that defines preprocessor lines is defined by preprocessor.symbol.
The preprocessor keywords that make up the start (if), middle (else), and end (endif)
of preprocessor conditionals are defined by the other three properties.
There may be multiple values for each of these, as, for example, C uses &quot; if &quot; , &quot; ifdef &quot; ,
and &quot; ifndef &quot; to begin preprocessor conditionals.




lexer. filepattern


A lexer splits a file up into syntactic pieces. SciTE can then display these pieces in
different visual styles. Many lexers are included in SciTE for popular
programming languages such as Python, Java, C/C++, JavaScript and VB. Often several file
extensions (.cpp, .cc, .h) can map to one language (C++) and hence one lexer. These
settings associate a file name with a lexer.
The lexers included in SciTE are written in C++ and compiled into the SciTE executable.
Lexers can also be written as a Lua script
or as a Lua LPeg lexer using scintillua .




shbang. command


On Unix, command files often have no extension and instead specify the interpreter
to use for the file in an initial line that starts with &quot; #! &quot; . When the lexer can not be
otherwise determined and the file starts with &quot; #! &quot; , the initial line is split up into words and
each word is prepended with &quot; shbang. &quot; . If a property with this name exists then it is
treated as the extension of the file. For example, shbang.python=py will be
triggered by an initial line #!/usr/bin/env python so the file will be treated as Python.




lexerpath. filepattern


Specifies the path to an external lexer module that will be loaded into Scintilla.




keywords. filepattern
keywords2. filepattern
keywords3. filepattern
keywords4. filepattern
keywords5. filepattern
keywords6. filepattern
keywords7. filepattern
keywords8. filepattern
keywords9. filepattern
keywordclass. lexer


Most of the lexers differentiate between names and keywords and use the keywords
variables to do so. To avoid repeating the keyword list for each file extension, where
several file extensions are used for one language, a keywordclass variable is defined in
the distributed properties file although this is just a convention. Some lexers define a
second set of keywords which will be displayed in a different style to the first set of
keywords. This is used in the HTML lexer to display JavaScript keywords in a different
style to HTML tags and attributes.
Keywords can be prefix based so ^GTK_ will treat all words that start
with GTK_ as keywords.




default.file.ext


Defines the language mode used before the file has a name. For example, if
default.file.ext=.py, then when the New command is used to create a new file then Python
syntax styling is used.




word.characters. filepattern


Defines which characters can be parts of words. The default value here is all the
alphabetic and numeric characters and the underscore which is a reasonable value for
languages such as C++.




whitespace.characters. filepattern


Defines which characters are considered whitespace. The default value is that initially set up
by Scintilla, which is space and all chars less than 0x20. Setting this property allows you to
force Scintilla to consider other characters as whitespace (e.g. punctuation) during such activities
as cursor navigation (ctrl+left/right).




style.*. stylenumber
style. lexer . stylenumber


The lexers determine a style number for each lexical type, such as keyword, comment or
number. These settings determine the visual style to be used for each style number of
each lexer.
The value of each setting is a set of ',' separated fields, some of which have a
subvalue after a ':'. The fields are font, size, fore, back, italics, notitalics, bold,
notbold, eolfilled, noteolfilled, underlined, notunderlined, and case.
The font field has a subvalue which is the name of
the font, the fore and back have colour subvalues, the size field has a numeric size
subvalue, the case field has a subvalue of 'm', 'u', or 'l' for mixed, upper or lower case,
and the bold, italics and eolfilled fields have no subvalue. The value
&quot; fore:#FF0000,font:Courier,size:14 &quot; represents 14 point, red Courier text.
A global style can be set up using style.*. stylenumber . Any style options set in
the global style will be inherited by each lexer style unless overridden.
On GTK+, the font name should be prefixed with &quot; ! &quot; such as &quot; font:!Sans &quot; to ensure Pango
anti-aliased fonts are used. If this is not done, an older font system will be used which may not work well.




style. lexer .32
style. lexer .33
style. lexer .34
style. lexer .35
style. lexer .36
style. lexer .37
style. lexer .38


As well as the styles generated by the lexer, there are other numbered styles used.
Style 32 is the default style and its features will be inherited by all other styles
unless overridden.
Style 33 is used to display line numbers in the margin.
Styles 34 and 35 are used to display matching and non-matching braces
respectively.
Style 36 is used for displaying control characters. This is not a full style as the
foreground and background colours for control characters are determined by their lexical
state rather than this style.
Style 37 is used for displaying indentation guides. Only the fore and back are used.
Style 38 is used for displaying calltips. Only the font, size, fore and back are used.
A * can be used instead of a lexer to indicate a global style setting.




braces.check
braces.sloppy
style. lexer .34
style. lexer .35
braces. lexer .style


Brace highlighting is a feature that shows the range of a brace when the caret is
positioned immediately after it. It is especially useful when complex nested braces are
used. The characters '(', ')', '[', ']', '{', and '}' are considered braces. The feature
defaults to off (because it slows cursor movement) unless braces.check is set to 1. If
braces.sloppy is set to 1 then if there is no brace before the caret then the character
after the caret is checked. The highlighting is performed by displaying the braces in
style number 34 or in style number 35 if there is no matching brace. While this is a full
style, to avoid partial display of the braces, it is best to make this style differ from
the standard style of braces only in foreground and background colour. Only braces with
style set to braces. lexer .style (which defaults to 0) are candidates for brace
match highlighting.




font.monospace


Defines, with the same syntax as the style properties,
the font name and size to be used when the Use Monospaced Font
command is performed.




command.compile. filepattern
command.compile.subsystem. filepattern
command.build. filepattern
command.build.subsystem. filepattern
command.build.directory. filepattern
command.go. filepattern
command.go.subsystem. filepattern


These settings choose which commands to execute when the Compile, Build or Go menu items
are selected. The subsystem options are explained in the subsystem section.
When source files are in a different directory to that they should be built in, the
command.build.directory property can be set to change to a particular directory before performing
the build.




command.go.needs. filepattern
command.go.needs.subsystem. filepattern


Sometimes a file must be compiled or built before it can be run. If this is the case,
this setting indicates what command needs to be run to perform the compile or build step
before running the file. When a file is compiled, this is noted and future runs will not
perform a compile or build. To make a 'compile and go' Go command for .c files:

command.go.*.c=$(FileName)
command.go.needs.*.c=g++ $(FileNameExt) -o $(FileName)





command.name. number . filepattern
command. number . filepattern
command.is.filter. number . filepattern
command.subsystem. number . filepattern
command.save.before. number . filepattern
command.input. number . filepattern
command.replace.selection. number . filepattern
command.quiet. number . filepattern
command.mode. number . filepattern
command.shortcut. number . filepattern


Extra commands can be added to the Tools menu. For example to include the 'astyle'
indenter, the properties file could contain
command.name.0.*.cc=Indent
command.0.*.cc=astyle -taO $(FileNameExt)
command.is.filter.0.*.cc=1
The first line defines the string that will appear in the Tools menu (immediately below
'Go'). The second line is the command string, similar to those of the compile, build, and
go commands. The optional command.is.filter property states that the command modifies the
current file so it may need to be read in after performing the command if
load.on.activate is set.
If command.save.before is set to 1, SciTE automatically saves the file before execution.
If it is set to 2, SciTE will not save the file, otherwise SciTE asks you.

On Windows, the optional command.input property specifies text that will be piped
to the command. This may reference other properties; for example,
command.input.0.*.cc=$(CurrentSelection)
would pipe the current selection to the command processes.
The command.input property is only supported for subsystem 0
(command line programs).


The optional command.replace.selection can be used to specify that the
command output should replace the current selection (or be inserted at the cursor
location, if there is no selection). This property has three available settings:
0, the default, means do not replace the selection. 1 means replace the selection
when the command finishes. 2 means replace the selection only if the command
finishes with an exit code of 0. If the user cancels the command via &quot; Tools / Stop
Executing &quot; , the selection will not be replaced even in mode 1. Note, commands run
asynchronously, so you are not prevented from modifying the document or even
switching buffers while a command is running. However, please bear in mind that
command.replace.selection will send the output to whatever window is active when
the command completes .

A final command property that is currently supported only on windows is command.quiet.
A value of 1 indicates that the command I/O should not be echoed to the output pane.
This may be useful in combination with command.input and command.replace.selection.


The command.mode property is a comma-separated list of flags / settings. Each mode
setting can have an argument, separated from the setting name by a colon. For
most of these, the argument portion is optional; if the setting name appears without
an argument, this works the same as &quot; setting:yes &quot; . If a setting is included in
the command.mode but also appears as a separate command property, the mode property
will be overridden. Similarly, if a single setting appears more than once with
different arguments, the last valid argument takes priority. The supported
command.mode settings are:

filter - accepts keyword arguments yes and no
quiet - accepts keyword arguments yes and no
replaceselection - accepts yes, no, and auto
savebefore - accepts yes, no, and prompt
subsystem - console, windows, shellexec, lua, director, winhelp, htmlhelp
groupundo - yes or no

Currently, all of these except groupundo are based on individual properties with
similar names, and so are not described separately here. The groupundo setting
works with subsystem 3 (lua / director), and indicates that SciTE should treat any
changes made by the command as a single undo action. A command that uses the
groupundo setting should not change which buffer is active in the editor.

The command.shortcut property allows you to specify a keyboard shortcut for the
command. By default, commands 0 to 9 have keyboard shortcuts Ctrl+0 to Ctrl+9
respectively, but this can be overridden. For commands numbered higher than 9,
there is no default keyboard shortcut. The notation used to specify keyboard
shortcuts is the same as for the user.shortcuts property, described elsewhere
in this document.


If the text of a command starts with '*' then the Parameters dialog is displayed to
prompt for parameters before executing the command. The initial '*' is not included
in the command that is executed.


The command number can be in the range of 0 to 49. Command numbers 0 to 9 are
assigned Ctrl+Number shortcuts. Internally these commands use IDs starting from
1100 (IDM_TOOLS) which can be used in user.shortcuts and user.context.menu as:
user.context.menu=Indent|1100|
If command.name is empty then no item is added to the Tools menu. This can be used
for commands that are only in the context menu or user shortcuts.




command.help. filepattern
command.help.subsystem. filepattern


Defines a command to be executed when the help command is
invoked or F1 pressed. On Windows, this often uses subsystem 4 as described above.
On OS X or Linux, running man or a browser are common ways of displaying help.
The word at the cursor is copied to $(CurrentWord) and this is often a good argument
to the help application. The subsystem property works in the same way as for other
commands.




command.scite.help
command.scite.help.subsystem


Defines a command to be executed for help on the SciTE program itself which normally
means displaying this file in a browser.




command.print. filepattern
command.print.subsystem. filepattern


Defines a command to be executed when print is invoked on GTK+.




time.commands


When a command is completed, print the time it took in seconds.




print.magnification


Printing is normally done with the same settings as screen display.
To make the printing larger or smaller, the print.magnification
setting is added to the size of every font when printed. To get a
good miniaturisation of text, set print.magnification to -4.




print.colour.mode


Some people prefer light coloured text on a black background on
screen but dark text on white on paper. If print.colour.mode is set
to 1 then each colour is inverted for printing. If set to 2 then
printing produces black text on white background. 3 forces the
background to white and 4 forces the default background to white.




print.margins


Specify the default margins on the printer on Windows in left right top bottom order.
Units depends on your locale, either hundredths of millimetres or thousandths
of inches. You can see which units by the units used in the page setup dialog.
This property is only read at start up.




print.header.format
print.footer.format


These settings determine what will be printed if anything as headers and
footers. Property settings can be substituted into the values using the $(property)
syntax. There are some extra properties set up while printing:
CurrentPage, FileTime, FileDate, CurrentDate, and CurrentTime (at start of
printing).
Common properties to use in headers and footers are FileNameExt and FilePath.
A header setting may look like:

print.header.format=$(FileNameExt) - Printed on $(CurrentDate),$(CurrentTime) - Page $(CurrentPage)





print.header.style
print.footer.style


These settings determine the style of the header and footer using the same
format as other styles in SciTE. Only the fore, back, font, size, bold, italics,
and underlined attributes are supported.




export.keep.ext


This property determines how the file name
(for example, LineMarker.cxx) is transformed when
exporting to include the appropriate export format extension -
.html for HTML and .rtf for RTF.
If export.keep.ext is the default, 0, then the current extension is replaced
(LineMarker.html).
If it is 1, then the export format extension is added (LineMarker.cxx.html).
If it is 2 then the final '.' is replaced by '_' and the
export format extension added (LineMarker_cxx.html).




export.html.wysiwyg
export.html.tabs
export.html.folding
export.html.styleused
export.html.title.fullpath


When export.html.wysiwyg is set to 0 then exporting to a HTML file produces a smaller
file but which is less completely specified so may look more different to the on screen display.
When export.html.tabs is set to 1 and export.html.wysiwyg is set to 0 then tab characters in
the file are exported as tab characters rather than a sequence of space characters.
The exported file can be made to fold in browsers that support CSS well (Mozilla and Internet
Explorer) by setting export.html.folding to 1.
Only export styles actually used when export.html.styleused set to 1.
The full path name of the file is put in the title, instead of just the file name
when export.html.title.fullpath set to 1.




export.rtf.wysiwyg
export.rtf.tabs
export.rtf.font.face
export.rtf.font.size
export.rtf.tabsize


When export.rtf.wysiwyg is set to 0 then exporting to a RTF file produces a smaller
file but which is less completely specified so may look more different to the on screen display.
When export.rtf.tabs is set to 1 and export.rtf.wysiwyg is set to 0 then tab characters in
the file are exported as tab characters rather than a sequence of space characters.
export.rtf.font.face and export.rtf.font.size can be used to select a particular font and size
for the exported RTF file. export.rtf.tabsize can be set to use a different tab size than that
defined by the tabsize setting.




export.pdf.magnification
export.pdf.font
export.pdf.pagesize
export.pdf.margins


export.pdf.magnification is a value that is added to the font size of the default screen style in use.
A positive value increases the PDF document's font size, and vice versa.
export.pdf.font accepts a one-word parameter that selects one of the default PDF fonts: Courier,
Helvetica or Times. Helvetica is the default. Helvetica and Times do not line wrap, Courier line
wraps.
export.pdf.pagesize is used to set the document's page size, using points (1/72th of an inch) as
the unit. E.g. Letter paper (8.5 inch x 11 inch) is specified using the values 612,792.
export.pdf.margins sets the widths of the page margins. Margins defaults to 72 points,
or 1 inch.
The PDF exporter is necessarily feature-limited because PDF is a document archival format. Supporting
a full set of features will bloat SciTE. Wrapping Helvetica or Times adequately isn't possible without
the complexities of font metrics and kerning. The PDF produced uses WinAnsiEncoding, so pre-encoding
has to be done before exporting to PDF, if you want to use extended characters.




export.tex.title.fullpath


The full path name of the file is put in the title, instead of just the file name
when export.tex.title.fullpath set to 1.




export.xml.collapse.spaces
export.xml.collapse.lines


export.xml.collapse.spaces and export.xml.collapse.lines are flags that control how empty lines
and runs of space characters are converted into XML. The flags are enabled if set to 1. Tab
characters are always converted by the XML exporter into spaces according to the tabsize property.



fold
Folding is turned on by setting fold=1.



fold.symbols


The fold.symbols setting chooses between four ways of showing folding.
Set to 0 (the default) for MacOS style arrows to indicate contracted
(facing right) and expanded (facing down); 1 to display contracted folds
with &quot; + &quot; and expanded with &quot; - &quot; ; 2 for a flattened tree control with round
headers and rounded joins; 3 for a flattened tree control with square headers.




fold.margin.width


Sets the width of the fold margin.




fold.margin.colour
fold.margin.highlight.colour


These two properties defined the fold margin colour and fold
margin highlight colour. If they are not defined (left commented out) the colours for the
fold margin will default to a reasonable pair of colours.
On Windows, the system colours are used to make the fold margin appear like the background
of scroll bars. As an example, with fold.margin.colour=#FF0000 and
fold.margin.highlight.colour=#0000FF , the fold margin is a mixture of red
and blue.




fold.on.open


To automatically fold files as much as possible when loaded, set
fold.on.open to 1.




fold.flags


Not really documented ;) bit flags which may go away.
2, 4, 8, and 16 control drawing lines above and below folding lines if
expanded or not expanded.
Set to 64 to help debug folding by showing hexadecimal fold levels in margin.




fold.compact


For HTML, XML, Lua and C++ and similar files, turning this option on leads to blank lines following the
end of an element folding with that element. Defaults to on.




fold.highlight


Set to 1 to enable highlight for current folding block (smallest one that contains the caret).
By default, it's disable. Note : The highlight is enabled only when fold.symbols equals
to 2 (round headers) or 3 (square headers).




fold.highlight.colour


Define the colour of highlight. The colour by default is red (#FF0000).




title.full.path


Chooses how the file name is displayed in the title bar.
When 0 (default) the file name is displayed. When 1 the full path is displayed.
When 2 the window title displays &quot; filename in directory &quot; .




title.show.buffers


When set to 1 shows the current buffer number in the title bar.




tabsize
tab.size. filepattern
indent.size
indent.size. filepattern
use.tabs
use.tabs. filepattern
indent.auto
tab.indents
backspace.unindents


Sets the size of a tab as a multiple of the size of a space character in the style of the
default style definition. The indent size is the size to use when performing automatic
indentation and may be different from the tab size. Many people use a tab size of 8 but
4 character indentation. When creating indentation, use.tabs determines whether the
indentation is made up purely from space characters or from a mix of tabs and spaces
using as many tabs as possible.
The global tabsize, indent.size, and use.tabs properties can be overridden for
files that match a pattern by using the file pattern forms:

indent.size.*.pas=3
If indent.auto is set then indent.size and use.tabs are set according to the contents
of the opened document.
The properties file settings apply to newly opened files but remain constant once the file is open
unless changed using the Change Indentation Settings dialog.
If tab.indents is set then pressing tab within indentation whitespace indents by indent.size
rather than inserting a tab character. If backspace.unindents then pressing backspace
within indentation whitespace unindents by indent.size rather than deleting the character
before the caret.




indent.automatic
indent.opening
indent.closing
indent.maintain. filepattern


Determines the look of automatic indentation. Automatic indentation is turned on with
indent.automatic=1. To indent a brace line after a compound statement start set
indent.opening=1, likewise for the terminating brace. So with both set to 0:

if (c)
{
&amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp;s;
}

And with both set to 1:

if (c)
&amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp;{
&amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp;s;
&amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp;}

Automatic indentation may be changed to simply repeat the indentation of the
previous line for some files with indent.maintain. filepattern =1 which
overrides the other language specific settings.




statement.indent. filepattern
statement.end. filepattern
statement.lookback. filepattern
block.start. filepattern
block.end. filepattern


Each of these settings starts with a style number and then a set of words or characters
that define how to recognise that feature. If there is a second space in the setting then
it is a set of words, otherwise a set of characters. The set of keywords used to indicate
the start of a compound statement is defined in statement.indent. For example:

statement.indent.$(file.patterns.cpp)=5 if else while

says that for C++ the words &quot; if &quot; , &quot; else &quot; , and &quot; while &quot; in keyword style, 5, start compound
statements which leads to the next line being indented if no other factors affect it. However,
if a statement end is found on the same line then the next line is not indented. For C++ the
statement end is the semicolon in the operator style, so this is defined:

statement.end.$(file.patterns.cpp)=10 ;

The number of lines looked at to determine indentation can be set with statement.lookback.
This can be used either to bound the amount of time spent on this task or to specify
that only the last line be examined for indentation.
The block.start and block.end properties define the language elements used to bracket groups
of statements. In C++ these are '{' and '}'.




indent.python.colon


For Python, automatically indent by one level if the previous line ended in a ':'
ignoring comments and whitespace. Otherwise use the same indentation as the previous line.
This property overrides other indentation settings.




vc.home.key


Chooses the behaviour of the Home and Shift+Home keys. 1, the default is like
Visual C++ moving the caret to the end of the line indentation unless already
there, in which case it moves to the start of the line. 0 moves to the start of the line.




warning.findwrapped
warning.notfound
warning.wrongfile
warning.executeok
warning.executeko
warning.nootherbookmark


Allows for sounds to be played and the window to be flashed
on Windows when particular events occur.
The values consist of three items separated by ',': flash duration, sound
and sound duration. If sound is a number then it is treated as a pitch and
played for the duration in milliseconds.
Otherwise it is treated as a path to a sound file
that is played. If you do not want a flash, specify 0 for flash duration.
For example,

warning.wrongfile=0,C:\Windows\Media\SFX\Glass.wav

will play the glass sound if open selected is given a bad file name.
The findwrapped warning occurs when a find operation wraps past
either end of the file,
notfound when the find or preprocessor conditional move commands
fail to find a match,
executeok when a command such as build
executes successfully, executeko when a command fails, and
nootherbookmark when there is no bookmark to find.




fileselector.width
fileselector.height


For the GTK+ version determines the initial size of the file
selector dialog invoked by the Open and Save commands.
Setting has no effect on Windows.




fileselector.show.hidden


On GTK+ setting this to 1 makes the file selector dialog
invoked by the Open command show hidden files automatically.




locale.properties


Set the name of the localisation file. For a multi-user installation
this allows each user to set a preferred user interface language.




translation.missing


When using a localised version, if a term is not found in the locale.properties
translation file then use the value of translation.missing instead. By setting
this to a marker such as &quot; *** &quot; it is easier to check where terms have not been
provided with translations.




menu.language


Defines the entries in the Language menu and the file extensions they map to.
Each menu item is defined by 3 elements, language name, extension and an optional
keyboard equivalent. Each element is terminated by '|'. For example:
H &amp; amp;ypertext|html|F12|
Menu items may be commented out by prefixing the name with '#'.




menukey.*


The menukey.* settings allow the user to redefine accelerator keys for menus
without having to resort to modifying the SciTE source code. The syntax for the setting is:

menukey.menu_title.menu_name= &amp; lt;modifier &amp; gt;key

For example, the File | Exit command accelerator could be specifed as follows:

menukey.file.exit= &amp; lt;control &amp; gt;Q

Note that spaces in menu titles and names must be converted to underscores,
and trailing ellipses removed. For example, &quot; File | Save As.... &quot; is referenced as &quot; menukey.file.save_as &quot; .

Multiple modifiers may be specified, though each must be surrounded by angle brackets. The
recognised modifiers are the same as for the user.shortcuts setting described above. The recognised named
keys are also the same as for user.shortcuts, with the addition of &quot; none &quot; to indicate that no accelerator
key should be defined for a particular menu.




source.default.extensions


If the name specified on the command line cannot be found as a directory or file - including a wild-card
search, the contents of the property are treated as default extensions to be used to locate the file name.
An example is: .cxx|.cpp|.c|.hxx|.hpp|.h|.bat|.txt|.lua
Attempting to open win32\SciTEWin would open win32\SciTEWin.cxx since it matches before win32\SciTEWin.h

If the property contains an entry such as Bar.cxx|.cxx and you attempt to open win32\SciTEWin, it will open
ScTEWinBar.cxx since that is the first match.




ext.lua.startup.script
ext.lua.auto.reload
ext.lua.reset
extension. filepattern


The ext.lua properties are specific to the
SciTE Lua Scripting Extension . The extension. filepattern property
is part of the generic SciTE Extension
Interface but is currently only used by the Lua Scripting Extension.

The ext.lua.startup.script property defines the filename of a Lua script that
will be loaded when SciTE starts to set up the global state for Lua.
The default value is $(SciteUserHome)/SciTEStartup.lua.
You should use an absolute path for this property, but can reference the
$(SciteDefaultHome) or $(SciteUserHome) properties. Global event handlers,
command functions, as well as other functions and objects can be defined here.

The ext.lua.auto.reload property determines what happens if you save the
startup script, or the active extension script, from within SciTE. If it
is set to 0, the startup script only applied at startup time
or when you switch buffers (depending on ext.lua.reset), and changes to the
extension script are only applied when you switch buffers. If
ext.lua.auto.reload is set to 1 (the default), SciTE will re-initialize the global scope
immediately when either script is saved from within SciTE. Even
when ext.lua.auto.reload is enabled, SciTE will not notice if the files
are changed from outside the current SciTE instance. For that, see
ext.lua.reset below.

The ext.lua.reset property is primarily for debugging. If ext.lua.reset
is 0 (the default), the startup script property is checked only once -
when SciTE starts. If ext.lua.reset is changed to 1, SciTE will check
the startup script property, and reload the new startup script, each
time you switch buffers. As such, it has a different (larger) set of
side effects than ext.lua.auto.reload. In some situations it will make
sense for both auto.reload and reset to be enabled, but usually
ext.lua.auto.reload alone will suffice.

Aside from ext.lua.startup.script, the extension. filepattern property
provides a way to load additional functions and event handlers that may be
specific to a given file type. If the extension property value ends in .lua
and names a file that exists, the Lua extension evaluates the script so that event
handlers and commands defined in the script are available while that buffer
is active. Functions and objects defined through ext.lua.startup.script are
still accessible, unless they are overridden.

The extension property can also define behavior that is specific to a given
directory. If a bare filename (no path) is specified in the extension
property, SciTE looks for the file in the standard property file locations,
starting with the local directory. This can be very useful in combination
with a local SciTE.properties file.




caret.sticky


Controls when the last position of the caret on the line is modified.
When set to 1, the position is not modified when you type a character, a tab,
paste the clipboard content or press backspace. The default is 0 which turns
off this feature.




properties.directory.enable


Enables or disables the evaluation of the directory properties file.
The default is 0 which disables the evaluation. Any other value enables
this properties file.




caret.policy.{x|y} &amp; lt;param &amp; gt; interaction:



slop
strict
jumps
even
Caret can go to the margin
When reaching limit
(going out of visibility or
going into the UZ)
display is...


0
0
0
0
Yes
moved to put caret on top/on right


0
0
0
1
Yes
moved by one position


0
0
1
0
Yes
moved to put caret on top/on right


0
0
1
1
Yes
centred on the caret


0
1
-
0
Caret is always on top/on right of display
-


0
1
-
1
No, caret is always centred
-


1
0
0
0
Yes
moved to put caret out of the asymmetrical UZ


1
0
0
1
Yes
moved to put caret out of the UZ


1
0
1
0
Yes
moved to put caret at 3UZ of the top or right margin


1
0
1
1
Yes
moved to put caret at 3UZ of the margin


1
1
-
0
Caret is always at UZ of top/right margin
-


1
1
0
1
No, kept out of UZ
moved by one position


1
1
1
0
No, kept out of UZ
moved to put caret at 3UZ of the margin



Supporting a new language


For languages very similar to existing supported languages, which may only differ in a minor
feature such as the keywords used, the existing lexers can often be reused. The set of
keywords can then be changed to suit the new language. Java and JavaScript could have
reasonably reused the C++ lexer. The Java lexer was added only to support doc comments.


For languages that can not be lexed with the existing lexers, a new lexer can be coded in
C++. &amp; nbsp; These can either be built into Scintilla, or put into an
external module and loaded when SciTE runs (See lexerpath).
Installing a lexer into SciTE

Creating and installing an external
lexer

The open.filter should be modified to include the file extensions used for the new language
and entries added for command.compile, command.build, command.go and command.go.needs for the
language.


Creating API files


The .api files can be generated by hand or by using a program.
There are also downloadable ready-to-use
.api files.


For C/C++ headers, an API file can be generated using
ctags
and then the
tags2api Python script (which assumes C/C++ source) on the tags file to grab complete
multiple line function prototypes.
Some common headers surround parameter lists with a __P macro and may have
comments. The cleanapi utility may be used on these files.


To generate an API file for Python modules, there is a
gen_python script .


To generate an API file for Java classes, there is a
ApiBuilder.java program.


Open Selected Filename


This command opens the file for the file name selected in either the edit or output pane.
It uses the current selection or searches around the caret to try to
find a file name based on which characters are normally used in a path.
If there is no extension then an extension may be inferred from the current file using the
open.suffix property which defaults to .properties in a .properties file.
If the file name is followed by a number (in a format similar to ctags, grep output,
or Visual Studio messages) then that line is displayed in the opened file.
If the file name is an absolute path then it is opened directly otherwise it is looked for
in the current directory and then in the directory specified by the openpath property.
On Windows, web, ftp, mail and news URLs are handled by opening their
associated application.


SciTE in other languages


SciTE can be and has been translated into other languages .


Building SciTE


The procedure for building and installing SciTE is described in the README file in the scite
directory.


Extending SciTE


There are two formal extension interfaces for SciTE, the
SciTE Extension Interface
is for extending SciTE with code compiled into the SciTE executable and the
SciTE Director Interface is for
manipulating SciTE on Windows from another application.


scite228.zip > SciTELua.html

SciTE Lua Scripting Extension


.example {
color: #00A000;
font-weight: bold;
}
DIV.example {
background: #F7FCF7;
border: 1px solid #C0D7C0;
margin: 0.3em 3em;
padding: 0.3em 0.6em;
font-size: 80%;
}










SciTE Lua Scripting Extension



Lua Scripting Extension Notes
The SciTE Lua Scripting Extension uses a copy of Lua 5.1 as
its scripting engine. Currently, all of the standard libraries are
included, although this list may be trimmed in a future revision.

Lua is Copyright (C) 1994-2007 Lua.org, PUC-Rio. The complete Lua license
is included in luaCOPYRIGHT in the SciTE installation directory. To
find more information about Lua, including documentation for the
language itself, visit www.lua.org .

For more ideas about what Lua can do, you may also want to check out
the community portal, lua-users.org ,
an introduction to using Lua with SciTE,
and some example scripts .

SciTE Properties and Lua Event / Command Handlers

The properties ext.lua.startup.script and extension. filepattern
can be used to define commands and event handlers that will be called
by the SciTE. Other properties beginning with ext.lua may also
influence how Lua behaves. See the SciTE Documentation
for more details on this.

By defining functions in the startup script or the active extension
script, you can tailor SciTE to your needs, adding new behavior and
functionality that is tightly integrated.

To begin, you can handle any many of the events exposed by the
SciTE Extension Interface . You do
this simply by defining functions with the same name as the event.
Currently, OnOpen , OnClose , OnSwitchFile , OnSave ,
OnBeforeSave , OnChar , OnKey ,
OnSavePointReached , OnSavePointLeft , OnDwellStart ,
OnDoubleClick , OnMarginClick ,
and OnUserListSelection are supported.

For some of these events, SciTE will pass one or more arguments to
the event handler function: OnOpen , OnClose ,
OnSwitchFile , OnSave , and
OnBeforeSave will receive the filename of the affected buffer as
their first argument.
An OnChar handler should expect a single-character string argument.
An OnKey handler should expect an integer keycode and boolean
shift, control, and alt arguments. The keycode is currently a platform specific value
but this may change in future.
OnDwellStart will receive the position of the mouse and the
word under the mouse as arguments and the word will be empty when the mouse starts moving.
OnUserListSelection receives two arguments: a number
indicating the list type, and a string indicating the selected
item text. The other event handlers will not be passed any arguments.

Event handlers return a boolean value to indicate whether SciTE should
continue processing the event. Return a true value to indicate that
the event has been fully handled, and that no further handlers should
be called. Return a false value to give other extensions a chance to
process the same event. In many but not all cases, a well behaved
event handler will return false. Remember that, in Lua, the only
non-true values are false and nil . Unlike in C++, Python and many
other languages, 0 evaluates to true .

There is one additional event handler, OnClear , that is not
expressly defined in the Extension interface, but is exposed to Lua.
Whenever SciTE re-reads the properties (which occurs every time you
switch buffers or open a new file, but can also occur at other times),
the Lua Extension removes any globals that were created since the last
time properties were read, and restores any globals that were
overwritten. Then, if the startup script defines a function
OnClear , that function will be called so that scripts have a
chance to clean up other changes they might have made outside of the
Lua global scope (e.g. dynamic properties modified through the props
object; see below) and/or to tailor the Lua environment according to
local properties for the current buffer.

After this, SciTE reads the properties and ultimately loads the
extension script, if one is defined. However, at the time when the
OnClear event fires, the extension script is not yet loaded.
Thus, OnClear can only be defined in the startup script,
not in an extension script.

In addition to event handlers, you can also use define new commands
that are available through the Tools menu or through keyboard shortcuts.
To specify that a command that will be handled by Lua, specify
subsystem 3 for the command. Then, to implement the command using Lua,
just define a global function. The command name is the function name.

You can also use predefined functions like dofile and dostring as tool
commands.

Anything specified after the command name is passed to the Lua function
as a single string argument. An example of a command, using the
built-in dofile command, is shown below.


command.name.1.*=Run My Script
command.subsystem.1.*=3
command.1.*=dofile $(SciteDefaultHome)/My Script.lua


Note that the command line is &amp; quot;not &amp; quot; evaluated directly
as a Lua script.

If there is no function matching the command name, no error will be
displayed. This is because Lua assumes in this case that the command
is meant for some other extension, such as the SciTE Director
Extension . However, if the command function is found, but fails
to execute, an error is reported.

Multiple handlers

Scite Ext Man can help in
more complex applications where you have
multiple scripts needing to handle an event.


Predefined Lua Functions and Objects:

Within Lua scripts you can use the following functions / objects:
trace(s) - writes s to the output pane (no prefix, no newlines)
dostring(s) - executes s as a Lua string, like Lua 4 &amp; #39;s dostring
editor - the editor pane
output - the output pane
props - a pseudo-table representing the SciTE properties
buffer - a table associated with the current buffer or document
scite - a namespace for functions which control SciTE.

In addition, all constants defined in Scintilla.iface are exposed as
Lua globals variables. Function names are exposed as their block
capital equivalents, with the SCI_ prefix.

All functions and objects defined in the Lua standard library are also
available. Although dostring was deprecated in Lua 5, it is restored
since some have said it would be useful in tool commands.

A function _ALERT() is also defined to be an alias for the built-in
print() , which prints the alert message (plus a newline) to the window.
This provides a reasonable way for Lua to present error messages to
the user. You are free to override _ALERT with a different definition
if you prefer.

The props pseudo-table allows you to read or write properties by name
using normal Lua table-access semantics, e.g. props[ &quot; property.name &quot; ] .
As with Lua tables, you can also un-set a property by assigning nil to its key.

When you assign a value to a property from Lua, this overrides any values
specified in the configuration files for that setting. The underlying file
properties are not changed. If you later assign nil to the same property
from Lua, this removes the run-time setting, allowing any file-based
property setting to show through once again.

The editor and output panes support the following properties and
methods:
textrange(startPos, endPos) - gets the text in the specified range

findtext(text, [flags], [startPos, [endPos]])
- returns the start and end of the first match, or nil if no match
- flags can be 0 (the default), or a combination of SCFIND constants
such as SCFIND_WHOLEWORD, SCFIND_MATCHCASE, and SCFIND_REGEXP

match(text, [flags], [startPos])
- returns a generator that allows you to loop over the matches
i.e. for m in editor:match(text, flags) do ... end
- the match object (i.e. the loop counter m in the above
example) supports read-only properties pos, len, and text;
and also supports a function replace(replaceText) to
support search and replace.
- while looping through matches, if the document is modified
by any method other than the loop counter's replace method,
this may cause the match generator to lose its place.
- also, do not attempt to store the match object for later
access outside the loop; it will not be useable.

append(text) - appends text to the end of the document
insert(pos, text) - inserts text at the specified position
remove(startPos, endPos) - removes the text in the range

Most of the functions defined in Scintilla.iface are also be exposed
as pane methods. Those functions having simple parameters (string,
boolean, and numeric types) are fully supported. For example,
editor:InsertText(pos, text) does practically the same thing as
editor:insert(pos, text) . Functions having a stringresult parameter
will include a string in the return value. For both strings and
stringresults, if the function is documented as expecting a length
as its first parameter, you do not pass the length from Lua. Instead,
it is inferred from the context.

The keymod parameter type has partial support. When an iface function
is declared as taking a keymod, the Lua equivalent expects two
numbers: first the key code (e.g. SCK_LEFT or string.byte( &quot; ' &quot; ) , and
second the modifiers (e.g. SCMOD_CTRL ).

Functions that have more complex parameters are not supported.

Functions that are declared to return a numeric type have the result
added to their return value. If the function also has a stringresult,
that comes first, followed by the numeric return value.

Some functions are declared as 'get' or 'set' rather than 'fun' in
the iface file. These are generally exposed to Lua as properties,
e.g. editor.TabSize = 8 . Some of the getters and setters also have
a parameter. Where possible, these are exposed to Lua as indexed
properties, e.g. editor.StyleBold[SCE_PROPS_DEFAULT] = true .
However, if an iface function is declared as get / set but cannot be
mapped to a Lua property, it is exposed as a Lua function instead.

The possible Scintilla calls are listed in API file format.
The Scintilla API is described in
ScintillaDoc .

The scite namespace includes the following functions:
scite.Open(filename)
- opens a file in a new buffer
- activates the file's buffer if it is already opened.

scite.SendEditor(SCI_constant, ...)
- sends a message to the editor pane
- equivalent to the corresponding iface function or property

scite.SendOutput(SCI_constant, ...)
- sends a message to the output pane

scite.ConstantName(number)
- returns the symbolic name of a Scintilla / SciTE constant

scite.MenuCommand(IDM_constant)
- equivalent to the corresponding IDM_ command defined in SciTE.h

Open requires special care. When the buffer changes in SciTE, the
Lua global namespace is reset to its initial state, and any extension
script associated with the new buffer is loaded. Thus, when you call
Open, this may change the environment in which your current script is
running. When possible, you can avoid confusion by simply returning
after scite.Open, but when that is not possible, just bear in mind
that there are side effects. Local variables, unlike globals, will
be retained after the buffer change until your script returns.

The SendEditor and SendOuput functions duplicate the
functionality of the editor and output objects, providing access to these
through an interface that is more familiar to Scintilla C++ developers.
This may be useful for prototyping C++ code using Lua. Internally,
SendEditor and SendOutput are translated to the
corresponding iface function or property, so their arguments and
return types are identical. (Although the calling convention for
properties is obviously different.)

The ConstantName function may be useful when generating debug messages,
or if extending the SciTE LuaExtension to support macro recording.

The MenuCommand function enables usage of SciTE's menu commands
as defined in SciTE.h.


Lua 5.1

Despite some of the big changes in Lua 5.1 dealing with changes
in the language, most of the compatibility options have been
turned on.
Compatibilities:
- table.getn still works, but the '#' operator should be used
- Lua 5.0's varargs are still available
- Lua 5.0's math.mod is still available, as well as 5.1's
math.fmod
- Lua 5.0's string.gfind is still available, as well as 5.1's
string.gmatch
- [C API] Lua 5.0's luaL_openlib behavior is still available
Changes:
- table.setn was deprecated
- loadlib was moved into the package table (package.loadlib)
- Lua 5.0's long string nesting throws an error




Disabling Lua

Lua is currently loaded just-in-time, before it is first used. The
ways that Lua can become are through the ext.lua.startup.script
property, by naming a lua file named in the extension. filepattern
property, or by using the extension mechanism to define tool commands
(i.e. subsystem 3). If you do not do any of these things, the Lua
scripting engine is not loaded, and for all practical purposes, SciTE
should behave as it did before Lua was added.

Nevertheless, it is still possible to build SciTE without the Lua
support. To do this, simply define the variable NO_LUA when you build
it, e.g. for MSVC, nmake -f scite.mak -DNO_LUA ; or with GNU tools,
make NO_LUA=1 .


scite228.zip > SciTEExtras.html

SciTE Extras


table {
border: 1px solid black;
border-collapse: collapse;
}
td {
border: 1px solid black;
padding: 1px 5px 1px 5px;
}
th {
border: 1px solid black;
padding: 1px 5px 1px 5px;
}










API files and property files for SciTE




This page contains various contributed files that can be used with SciTE.


Shells


Filerx
provides project management and macro features on Windows.
scitecmd
is a simple utility for opening files as tabs in SciTE from the command line on Windows.


APDL


APDL properties and API


ASP


ASP API methods


AutoHotkey


AutoHotkey properties



AutoIt3


SciTE4AutoIt3 Website containing AutoIt3 related properties and API files.


C


C standard library


C++


Windows API
OpenGL API
Glut API


C#


C# API file and generator program.


CIL


Properties for CIL/MSIL


CMake


CMake API


FORTRAN


Standard FORTRAN API functions


Java


Java API and Java Help


Lua


Lua 5 C API and Lua functions


Microsoft SQL


Replaces sql.properties


MySQL


Keywords



nncron


nncron.api


Oracle


Extended properties file
with additional keywords and standard package names.


osCommerce



API. German language site.


Perl


Perl API


PHP


html.properties
php.api for PHP 4.3.3
PHP properties
PHP functions

Utilities for making PHP support files.
A script for creating api file
out of your own php source code


POV-Ray


POV-Ray API


TADS3



TADS3 property file

Explanation


Windows Scripting



Properties files and scripts.


scite228.zip > SciTEDownload.html

Download Scintilla and SciTE


h3 {
background-color: #CCCCFF;
}









Download
Scintilla and SciTE







Windows &amp; nbsp; &amp; nbsp;

GTK+/Linux &amp; nbsp; &amp; nbsp;




Download


The license for using Scintilla or SciTE is similar to that of Python
containing very few restrictions.


Release 2.28


Source Code

The source code package contains all of the source code for Scintilla and SciTE but no binary
executable code and is available in

zip format (2100K) commonly used on Windows
tgz format (1880K) commonly used on Linux and compatible operating systems

Instructions for building on both Windows and Linux are included in the readme file.

Windows


Windows Executables


Windows executables only support Windows XP and later. It may be possible to build with older compilers for Windows 2000 but that
is no longer tested.


A full download (1000K) includes the SciTE executable, any required DLLs,
configuration files and documentation. After downloading the file, unzip it, and run
SciTE.EXE. The files required to run SciTE are SciTE.EXE, SciLexer.DLL, and
SciTEGlobal.properties.


A single file executable called Sc1 (640K) does not need any DLL or
properties files as these are linked into the executable. You may still create properties
files if you wish.
Sc1.exe has been compressed with the
UPX compressor
so that it is a fast download. It does not need to be decompressed to be used.


Windows Installer


An installer
created by Troy Simpson.


GTK+ / Linux


Linux executable for 32-bit Intel compatible processors


This binary release requires GTK+ 2.8 or later and was tested on Ubuntu 10.4.
If you are using a Linux distribution more than a year old you may
need to rebuild SciTE to use your installed version of GTK+.
If the target system is 64-bit, you may also need to build SciTE from source.


A full download (920K) includes the 32-bit SciTE executable,
configuration files and documentation.
After downloading the file, gunzip and untar it, and run
SciTE. The files required to run SciTE are SciTE which is best located on the path
(I put it in /usr/local/bin) 40 properties files which should be located in the
/usr/share/scite directory, and Sci48M.png which should be copied to /usr/share/pixmaps.


Debian Packages


Official Debian Packages are available from Apt.
There is a
package page .


Contributed by Aubin Paul.


SciTE localised for other languages


SciTE can be and has been translated into other languages .


Previous versions can be downloaded from the history
page .


scite228.zip > SciTEDirector.html

SciTE Director Interface


table {
border: 1px solid black;
border-collapse: collapse;
}
td {
border: 1px solid black;
padding: 1px 5px 1px 5px;
}
.S0 {
color: #808080;
}
.S1 {
font-family: Comic Sans MS;
color: #007F00;
font-size: 9pt;
}
.S2 {
font-family: Comic Sans MS;
color: #007F00;
font-size: 9pt;
}
.S3 {
font-family: Comic Sans MS;
color: #3F703F;
font-size: 9pt;
}
.S4 {
color: #007F7F;
}
.S5 {
font-weight: bold;
color: #00007F;
}
.S6 {
color: #7F007F;
}
.S7 {
color: #7F007F;
}
.S8 {
color: #804080;
}
.S9 {
color: #7F7F00;
}
.S10 {
font-weight: bold;
color: #000000;
}
.S12 {
font-family: Courier New;
color: #000000;
background: #E0C0E0;
font-size: 10pt;
}
.S13 {
font-family: Courier New;
color: #007F00;
background: #E0FFE0;
font-size: 10pt;
}
.S14 {
font-family: Courier New;
color: #3F7F3F;
background: #E0F0FF;
font-size: 10pt;
}
.S15 {
font-family: Comic Sans MS;
color: #3F703F;
font-size: 9pt;
}
SPAN {
font-family: Verdana;
font-size: 10pt;
}
.example {
color: #00A000;
font-weight: bold;
}
DIV.example {
background: #F7FCF7;
border: 1px solid #C0D7C0;
margin: 0.3em 3em;
padding: 0.3em 0.6em;
font-size: 80%;
}
DIV.highlighted {
background: #F7FCF7;
border: 1px solid #C0D7C0;
margin: 0.3em 3em;
padding: 0.3em 0.6em;
font-size: 80%;
}










SciTE Director Interface




Purpose.

Software development does not occur only at the single file level handled by SciTE.
A developer will generally work on a group of related files together in the context of one
project. Project manager functionality could be added to SciTE as it has to other editors
but this would impose a particular view of how projects are to be managed including the
format of project files. Instead, SciTE has an interface that can be used by project
managers or similar applications to control SciTE. Any application that controls SciTE is
referred to as a &quot; Director &quot; .
The current Director interface only works on Windows. In the future, it should be
possible to replace the low level interface and so make this interface available on other
platforms.
There is currently one director application,
Filerx , available.
This interface is implemented on top of the
SciTE Extension Interface , in the
file scite\win32\DirectorExtension.cxx.

Direct connection, broadcasting and explicit return addresses.

One application at a time is the director of SciTE,
controlling SciTE as it wishes. To support other communications techniques
applications may broadcast to all active director interfaces. When doing so,
each message should contain an explicit return address where replies to the
broadcast message will be sent.


Low level interface on Windows.

The Windows WM_COPYDATA message is used to transfer data between
SciTE and a Director. The messages are sent between windows created by the two
applications. SciTE uses a window that has no other purpose than to receive these
messages.
The lpData and cbData fields of the COPYDATASTRUCT
are used to transfer a string between the two processes, with cbData holding the length
of the string pointed to by lpData. The string does not have to be terminated with '\0'.
The dwData should be 0.
Before messages can be sent from one application to the other, the window handle
of the window to receive the message must be found. This is normally transferred when
starting the other application as a command line parameter. Either application may
start the other. SciTE makes its window handle available in the WindowID
property and accepts a director.hwnd property as the window handle to which it
sends data.
As an example of communicating the window handle, to install Filerx in the Tools
menu of SciTE these properties could be used:

command.name.0.*=Project Editor
command.0.*= &quot; C:\os\scite\bin\filerx.exe &quot; &quot; $(FileDir) &quot; &quot; $(WindowID) &quot;
command.subsystem.0.*=2

In the opposite direction, Filerx can start up SciTE with a command line that
specifies its window handle as well as the file it wants edited:

SciTE -director.hwnd=937846 c:\os\scite\src\SciTEBase.cxx

Once one application has the window handle of the other application, it should send
its window handle to the other application using an identity message as described later.
Then both sides are able to send messages.
To broadcast a message on Windows, the set of active director
interfaces can be found by broadcasting the &quot; SciTEDirectorInterface &quot;
message and seeing which windows reply with the same value as that message.
Example broadcast code:

unsigned &amp; nbsp; int &amp; nbsp; SDI &amp; nbsp; = &amp; nbsp; :: RegisterWindowMessage ( &quot; SciTEDirectorInterface &quot; );
HWND &amp; nbsp; w &amp; nbsp; = &amp; nbsp; :: GetWindow (:: GetDesktopWindow (), GW_CHILD );
while &amp; nbsp; ( w ) &amp; nbsp; {
&amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; DWORD &amp; nbsp; res &amp; nbsp; = &amp; nbsp; 0 ;
&amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; // &amp; nbsp;Need &amp; nbsp;time &amp; nbsp;out &amp; nbsp;to &amp; nbsp;avoid &amp; nbsp;hung &amp; nbsp;applications
&amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; :: SendMessageTimeout ( w , &amp; nbsp; SDI , &amp; nbsp; 0 , &amp; nbsp; 0 ,
&amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; SMTO_NORMAL , &amp; nbsp; 1000 , &amp; nbsp; &amp; amp; res );
&amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; if &amp; nbsp; ( res &amp; nbsp; == &amp; nbsp; static_cast &amp; lt; DWORD &amp; gt;( SDI )) &amp; nbsp; {
&amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; // &amp; nbsp;Replied &amp; nbsp;with &amp; nbsp;same &amp; nbsp;SDI &amp; nbsp;code &amp; nbsp;so &amp; nbsp;should
&amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; // &amp; nbsp;understand &amp; nbsp;SDI's &amp; nbsp;version &amp; nbsp;of &amp; nbsp;WM_COPYDATA
&amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; :: SendMessage ( w , WM_COPYDATA ,
&amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; ( UINT ) m_hWnd ,( long ) &amp; amp; cds );
&amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; }
&amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; w &amp; nbsp; = &amp; nbsp; :: GetWindow ( w , &amp; nbsp; GW_HWNDNEXT );
}


To advertise that a top level window supports the Director interface:

LRESULT &amp; nbsp; PASCAL &amp; nbsp; DirectorExtension_WndProc ( HWND &amp; nbsp; hWnd , &amp; nbsp;
&amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; UINT &amp; nbsp; iMessage , &amp; nbsp; WPARAM &amp; nbsp; wParam , &amp; nbsp; LPARAM &amp; nbsp; lParam ) &amp; nbsp; {
&amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; unsigned &amp; nbsp; int &amp; nbsp; SDI &amp; nbsp; = &amp; nbsp; :: RegisterWindowMessage ( &quot; SciTEDirectorInterface &quot; );
&amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; if &amp; nbsp; ( iMessage &amp; nbsp; == &amp; nbsp; SDI ) &amp; nbsp; {
&amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; return &amp; nbsp; SDI ;
&amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; }
&amp; nbsp; &amp; nbsp; &amp; nbsp; &amp; nbsp; return &amp; nbsp; :: DefWindowProc ( hWnd , &amp; nbsp; iMessage , &amp; nbsp; wParam , lParam );
}


Low level interface on GTK+.

This is not yet implemented.
The proposed design uses an input fifo for each application supporting the director
interface located in /tmp with a name using a pattern such as
&quot; /tmp/SciTE &amp; lt;PID &amp; gt;.director &quot; .
This allows enumerating all active director interfaces and also opening
a specific interface when the fifo name has been communicated through some
other means such as a command line argument or an identity: command.

High level interface.

Messages use C style escapes to represent control characters and
ensure that only visible characters are transmitted apart from the use
of '\n' to separate messages.
The string transmitted by the low level interface contains an optional
return address surrounded by ':' characters, an action, a ':' character and
an optional argument. The argument is often a file path. The ':' must be present even if there
is no argument. For example, SciTE understands the message

open:c:\\os\\scintilla\\include\\Scintilla.iface

as a command to open the file &quot; c:\os\scintilla\include\Scintilla.iface &quot; just as if the user
had performed this operation.
If the first character of the message is a ':' then up to the next ':' is a return
address, so SciTE will reply to the message

:73658:askfilename:

by sending the filename being edited to the return address 73658
rather than to its director.
The actions understood by SciTE are:


askfilename:
Return the name of the file being edited.


askproperty: &amp; lt;key &amp; gt;
Return the value of a property.


close:
Close the current file.


closing:
Director is closing - SciTE closes if it was started by the director.


currentmacro: &amp; lt;string &amp; gt;
Set the current macro to name.


cwd:
Change the working directory.


enumproperties:dyn|local|user|base|embed
Enumerate all the properties in the argument set.


exportashtml: &amp; lt;path &amp; gt;
Save the document in HTML format as the indicated file.


exportasrtf: &amp; lt;path &amp; gt;
Save the document in RTF format as the indicated file.


exportaspdf: &amp; lt;path &amp; gt;
Save the document in PDF format as the indicated file.


exportaslatex: &amp; lt;path &amp; gt;
Save the document in LaTeX format as the indicated file.


exportasxml: &amp; lt;path &amp; gt;
Save the document in XML format as the indicated file.


extender: &amp; lt;command &amp; gt;
Call the extension interface with the given command.


find: &amp; lt;string &amp; gt;
Search for a string, select and show it.


focus: &amp; lt;timeStamp &amp; gt;
On GTK+ bring this SciTE window to the front.
The timeStamp is from the window manager and ensures that windows are only
activated because of a user command.
Has no effect on Windows as applications on Windows can only donate focus, not take focus.


goto: &amp; lt;lineNumber &amp; gt;[, &amp; lt;columnNumber &amp; gt;]
Move caret to a particular line and make it visible.
If there is a column number then select the word at that column number
or move the caret there if no word is present.


identity: &amp; lt;hwndDirector &amp; gt;
Sets the director window handle to which SciTE sends messages.
The argument is in decimal.


insert: &amp; lt;value &amp; gt;
Display the value in the editor pane replacing the selection.


loadsession: &amp; lt;path &amp; gt;
Load a session as given by the indicated file.


macrocommand: &amp; lt;command &amp; gt;
Execute a macro command.
See the SciTE source code for the syntax of the
command argument.


macroenable: &amp; lt;enable &amp; gt;
If enable, display menu commands in SciTE for recording
and playing macros.


macrolist: &amp; lt;list &amp; gt;
Display a list for the user to choose from.


menucommand: &amp; lt;cmd &amp; gt;
Execute a menu command based on numeric ID.


open: &amp; lt;path &amp; gt;
Open the indicated file.


output: &amp; lt;value &amp; gt;
Display the value in the output pane replacing the selection.


property: &amp; lt;key &amp; gt;= &amp; lt;value &amp; gt;
Set a property to a value.


quit:
Shut down SciTE.


reloadproperties:
Reload properties from files.


replaceall: &amp; lt;search &amp; gt;\000 &amp; lt;replace &amp; gt;
Replace all instances of he search string in the
document with the replace string.


saveas: &amp; lt;path &amp; gt;
Save the document as the indicated file.


savesession: &amp; lt;path &amp; gt;
Save a session as given by the indicated file.


The actions sent by SciTE are:


closed: &amp; lt;path &amp; gt;
SciTE has closed the indicated file.


closing:
SciTE is closing.


dyn|local|user|base|embed: &amp; lt;key &amp; gt;= &amp; lt;value &amp; gt;
Set a property in a set to a value.


filename: &amp; lt;path &amp; gt;
The file being edited is path.
This is the reply to the askfilename: command.


identity: &amp; lt;hwndSciTEReceiving &amp; gt;
SciTE indicates to the director the window handle to which it should send
messages. The argument is in decimal.


macro:getlist
Retrieve the list of available macros which will be
returned by the macrolist command.


macro:record: &amp; lt;details &amp; gt;
Start recording a macro.
See the SciTE source code for the syntax of the
details argument.


macro:run: &amp; lt;macroName &amp; gt;
Run the named macro.


macro:stoprecord
Stop recording a macro.


opened: &amp; lt;path &amp; gt;
SciTE has opened the indicated file.


switched: &amp; lt;path &amp; gt;
SciTE has switched buffers to the indicated file.


saved: &amp; lt;path &amp; gt;
SciTE has saved the indicated file.


In the future, more actions will be defined. Applications should ignore any
actions that they do not understand.


scite228.zip > SciTERegEx.html

SciTE Regular Expressions


h3 {
background-color: #FEC;
}
.ref {
color: #80C;
}
code {
font-weight: bold;
}
dt {
margin-top: 15px;
}










Regular Expressions




Regular Expressions in SciTE

Purpose

Regular expressions can be used for searching for patterns
rather than literals. For example, it is possible to
search for variables in SciTE property files,
which look like $(name.subname) with the regular expression:
\$([a-z.]+) (or \$\([a-z.]+\) in posix mode).


Replacement with regular expressions allows complex
transformations with the use of tagged expressions.
For example, pairs of numbers separated by a ',' could
be reordered by replacing the regular expression:
\([0-9]+\),\([0-9]+\) (or ([0-9]+),([0-9]+)
in posix mode, or even (\d+),(\d+) )
with:
\2,\1

Syntax

Regular expression syntax depends on a parameter: find.replace.regexp.posix
If set to 0, syntax uses the old Unix style where \( and \)
mark capturing sections while ( and ) are themselves.
If set to 1, syntax uses the more common style where ( and )
mark capturing sections while \( and \) are plain parentheses.

[1] char
matches itself, unless it is a special character
(metachar): . \ [ ] * + ? ^ $ and ( ) in posix mode.
[2] .
matches any character.
[3] \
matches the character following it, except:
\a , \b , \f ,
\n , \r , \t , \v
match the corresponding C escape char,
respectively BEL, BS, FF, LF, CR, TAB and VT;
Note that \r and \n are never matched because in Scintilla,
regular expression searches are made line per line (stripped of end-of-line chars).
if not in posix mode, when followed by a left or right round bracket (see [8] );
when followed by a digit 1 to 9 (see [9] );
when followed by a left or right angle bracket (see [10] );
when followed by d, D, s, S, w or W (see [11] );
when followed by x and two hexa digits (see [12] );

Backslash is used as an escape character for all other meta-characters, and itself.
[4] [ set ]
matches one of the characters in the set.
If the first character in the set is ^ , it matches the characters NOT in the set,
i.e. complements the set. A shorthand S-E (start dash end) is
used to specify a set of characters S up to E, inclusive. The special characters ] and
- have no special meaning if they appear as the first chars in the set. To include both,
put - first: [-]A-Z] (or just backslash them).
example match
[-]|] matches these 3 chars,
[]-|] matches from ] to | chars
[a-z] any lowercase alpha
[^-]] any char except - and ]
[^A-Z] any char except uppercase alpha
[a-zA-Z] any alpha

[5] *
any regular expression form [1] to [4]
(except [8] , [9] and [10]
forms of [3] ),
followed by closure char ( * ) matches zero or more matches of that form.
[6] +
same as [5] , except it matches one or more.
[5-6]
Both [5] and [6] are greedy (they match as much as possible)
unless they are followed by the 'lazy' quantifier ( ? )
in which case both [5] and [6] try to match as little as possible.
[7] ?
same as [5] , except it matches zero or one.
[8]
a regular expression in the form [1] to [13] , enclosed
as \( form \) (or ( form ) with posix flag) matches
what form matches.
The enclosure creates a set of tags, used for [9] and for
pattern substitution. The tagged forms are numbered starting from 1.
[9]
a \ followed by a digit 1 to 9 matches whatever a
previously tagged regular expression ( [8] ) matched.
[10] \ &amp; lt; \ &amp; gt;
a regular expression starting with a \ &amp; lt; construct
and/or ending with a \ &amp; gt; construct, restricts the
pattern matching to the beginning of a word, and/or
the end of a word. A word is defined to be a character
string beginning and/or ending with the characters
A-Z a-z 0-9 and _. Scintilla extends this definition
by user setting. The word must also be preceded and/or
followed by any character outside those mentioned.
[11] \l
a backslash followed by d, D, s, S, w or W,
becomes a character class (both inside and outside sets []).
d: decimal digits
D: any char except decimal digits
s: whitespace (space, \t \n \r \f \v)
S: any char except whitespace (see above)
w: alphanumeric &amp; amp; underscore (changed by user setting)
W: any char except alphanumeric &amp; amp; underscore (see above)

[12] \xHH
a backslash followed by x and two hexa digits,
becomes the character whose Ascii code is equal
to these digits. If not followed by two digits,
it is 'x' char itself.
[13]
a composite regular expression xy where x and y
are in the form [1] to [12] matches the longest
match of x followed by a match for y.
[14] ^ $
a regular expression starting with a ^ character
and/or ending with a $ character, restricts the
pattern matching to the beginning of the line,
or the end of line. [anchors] Elsewhere in the
pattern, ^ and $ are treated as ordinary characters.

Acknowledgments

Most of this documentation was originally written by Ozan S. Yigit.
Additions by Neil Hodgson and Philippe Lhoste.
All of this document is in the public domain.


scite228.zip > SciTELexer.html

Download Scintilla and SciTE










Add a lexer to Scintilla and SciTE




Lexer addition.

The process of adding a new lexer to both Scintilla and SciTE
is fairly long. Here is my response when asked how to add a lexer for
Apache CONF files to SciTE. There is more information on writing the
lexer code (steps 4 and 5, here) in the documentation for Scintilla.

Don't bother about steps which are for configurations you don't
use all 6 makefiles - I'll patch them up later if you want to
contribute the lexer.


In scintilla/include/Scintilla.iface, add a lexer ID value:
val SCLEX_CONF=17


And any lexical class IDs:
val SCE_CONF_DEFAULT=0
val SCE_CONF_COMMENT=1


In the scintilla/include directory run HFacer.py to regenerate the
SciLexer.h file. Alternatively (if you don't want to run a Python script)
just add these values to SciLexer.h as #defines and I'll put them in
Scintilla.iface.


In the scintilla/src/LexOthers.cxx write a ColouriseConfDoc function
similar to one of the other functions such as ColouriseLatexDoc.
static void ColouriseConfDoc (unsigned int startPos, int length, int
initStyle, WordList *[], Accessor &amp; amp;styler) {


At the end of the file associate the lexer ID and name with the function:
LexerModule lmConf(SCLEX_CONF, ColouriseConfDoc, &quot; conf &quot; );


If this is a complex lexer then it may be better off in its own file, in
which case clone one of the current files and then add the file to all of
the make files where LexOthers is currently referenced -
scintilla/win32/makefile, scintilla/win32/scintilla.mak,
scintilla/gtk/makefile, scite/win32/makefile, and scite/win32/scite.mak.


To the scite/src/others.properties add an entry to associate the file
extension with the lexer:
lexer.*.conf=conf
If a new lexer file was created instead of adding to LexOthers, then a
new properties file should be created by cloning scite/src/others.properties
and modifying that file in the following steps.


Set up the styles:
# Default
style.conf.0=fore:#FF0000,bold
# Comment
style.conf.1=fore:#007F7F,$(font.comment)


If on Windows (someday this may work on GTK+ too), a filter should be
added for conf files in scite/src/others.properties:
filter.conf=Configuration (.conf)|*.conf|


In scite/src/SciTEGlobal.properties add $(filter.conf) to the definition
of open.filter.


To add this language to the Language menu of SciTE, add an entry to the menu.language
property including the name of the language and the file extension used most commonly
for it.


Build both Scintilla and SciTE.


Share and enjoy



For more extensive information on building lexers, see the

instructions in the Scintilla documentation .


scite228.zip > lparser.h

/*
** $Id$
** Lua Parser
** See Copyright Notice in lua.h
*/

#ifndef lparser_h
#define lparser_h

#include &quot; llimits.h &quot;
#include &quot; lobject.h &quot;
#include &quot; lzio.h &quot;


/*
** Expression descriptor
*/

typedef enum {
VVOID, /* no value */
VNIL,
VTRUE,
VFALSE,
VK, /* info = index of constant in `k' */
VKNUM, /* nval = numerical value */
VLOCAL, /* info = local register */
VUPVAL, /* info = index of upvalue in `upvalues' */
VGLOBAL, /* info = index of table; aux = index of global name in `k' */
VINDEXED, /* info = table register; aux = index register (or `k') */
VJMP, /* info = instruction pc */
VRELOCABLE, /* info = instruction pc */
VNONRELOC, /* info = result register */
VCALL, /* info = instruction pc */
VVARARG /* info = instruction pc */
} expkind;

typedef struct expdesc {
expkind k;
union {
struct { int info, aux; } s;
lua_Number nval;
} u;
int t; /* patch list of `exit when true' */
int f; /* patch list of `exit when false' */
} expdesc;


typedef struct upvaldesc {
lu_byte k;
lu_byte info;
} upvaldesc;


struct BlockCnt; /* defined in lparser.c */


/* state needed to generate code for a given function */
typedef struct FuncState {
Proto *f; /* current function header */
Table *h; /* table to find (and reuse) elements in `k' */
struct FuncState *prev; /* enclosing function */
struct LexState *ls; /* lexical state */
struct lua_State *L; /* copy of the Lua state */
struct BlockCnt *bl; /* chain of current blocks */
int pc; /* next position to code (equivalent to `ncode') */
int lasttarget; /* `pc' of last `jump target' */
int jpc; /* list of pending jumps to `pc' */
int freereg; /* first free register */
int nk; /* number of elements in `k' */
int np; /* number of elements in `p' */
short nlocvars; /* number of elements in `locvars' */
lu_byte nactvar; /* number of active local variables */
upvaldesc upvalues[LUAI_MAXUPVALUES]; /* upvalues */
unsigned short actvar[LUAI_MAXVARS]; /* declared-variable stack */
} FuncState;


LUAI_FUNC Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff,
const char *name);


#endif


scite228.zip > lundump.h

/*
** $Id$
** load precompiled Lua chunks
** See Copyright Notice in lua.h
*/

#ifndef lundump_h
#define lundump_h

#include &quot; lobject.h &quot;
#include &quot; lzio.h &quot;

/* load one chunk; from lundump.c */
LUAI_FUNC Proto* luaU_undump (lua_State* L, ZIO* Z, Mbuffer* buff, const char* name);

/* make header; from lundump.c */
LUAI_FUNC void luaU_header (char* h);

/* dump one chunk; from ldump.c */
LUAI_FUNC int luaU_dump (lua_State* L, const Proto* f, lua_Writer w, void* data, int strip);

#ifdef luac_c
/* print one chunk; from print.c */
LUAI_FUNC void luaU_print (const Proto* f, int full);
#endif

/* for header of binary files -- this is Lua 5.1 */
#define LUAC_VERSION 0x51

/* for header of binary files -- this is the official format */
#define LUAC_FORMAT 0

/* size of header of binary files */
#define LUAC_HEADERSIZE 12

#endif


scite228.zip > lstate.h

/*
** $Id$
** Global State
** See Copyright Notice in lua.h
*/

#ifndef lstate_h
#define lstate_h

#include &quot; lua.h &quot;

#include &quot; lobject.h &quot;
#include &quot; ltm.h &quot;
#include &quot; lzio.h &quot;



struct lua_longjmp; /* defined in ldo.c */


/* table of globals */
#define gt(L) ( &amp; L- &amp; gt; l_gt)

/* registry */
#define registry(L) ( &amp; G(L)- &amp; gt; l_registry)


/* extra stack space to handle TM calls and some other extras */
#define EXTRA_STACK 5


#define BASIC_CI_SIZE 8

#define BASIC_STACK_SIZE (2*LUA_MINSTACK)



typedef struct stringtable {
GCObject **hash;
lu_int32 nuse; /* number of elements */
int size;
} stringtable;


/*
** informations about a call
*/
typedef struct CallInfo {
StkId base; /* base for this function */
StkId func; /* function index in the stack */
StkId top; /* top for this function */
const Instruction *savedpc;
int nresults; /* expected number of results from this function */
int tailcalls; /* number of tail calls lost under this entry */
} CallInfo;



#define curr_func(L) (clvalue(L- &amp; gt; ci- &amp; gt; func))
#define ci_func(ci) (clvalue((ci)- &amp; gt; func))
#define f_isLua(ci) (!ci_func(ci)- &amp; gt; c.isC)
#define isLua(ci) (ttisfunction((ci)- &amp; gt; func) &amp; &amp; f_isLua(ci))


/*
** `global state', shared by all threads of this state
*/
typedef struct global_State {
stringtable strt; /* hash table for strings */
lua_Alloc frealloc; /* function to reallocate memory */
void *ud; /* auxiliary data to `frealloc' */
lu_byte currentwhite;
lu_byte gcstate; /* state of garbage collector */
int sweepstrgc; /* position of sweep in `strt' */
GCObject *rootgc; /* list of all collectable objects */
GCObject **sweepgc; /* position of sweep in `rootgc' */
GCObject *gray; /* list of gray objects */
GCObject *grayagain; /* list of objects to be traversed atomically */
GCObject *weak; /* list of weak tables (to be cleared) */
GCObject *tmudata; /* last element of list of userdata to be GC */
Mbuffer buff; /* temporary buffer for string concatentation */
lu_mem GCthreshold;
lu_mem totalbytes; /* number of bytes currently allocated */
lu_mem estimate; /* an estimate of number of bytes actually in use */
lu_mem gcdept; /* how much GC is `behind schedule' */
int gcpause; /* size of pause between successive GCs */
int gcstepmul; /* GC `granularity' */
lua_CFunction panic; /* to be called in unprotected errors */
TValue l_registry;
struct lua_State *mainthread;
UpVal uvhead; /* head of double-linked list of all open upvalues */
struct Table *mt[NUM_TAGS]; /* metatables for basic types */
TString *tmname[TM_N]; /* array with tag-method names */
} global_State;


/*
** `per thread' state
*/
struct lua_State {
CommonHeader;
lu_byte status;
StkId top; /* first free slot in the stack */
StkId base; /* base of current function */
global_State *l_G;
CallInfo *ci; /* call info for current function */
const Instruction *savedpc; /* `savedpc' of current function */
StkId stack_last; /* last free slot in the stack */
StkId stack; /* stack base */
CallInfo *end_ci; /* points after end of ci array*/
CallInfo *base_ci; /* array of CallInfo's */
int stacksize;
int size_ci; /* size of array `base_ci' */
unsigned short nCcalls; /* number of nested C calls */
unsigned short baseCcalls; /* nested C calls when resuming coroutine */
lu_byte hookmask;
lu_byte allowhook;
int basehookcount;
int hookcount;
lua_Hook hook;
TValue l_gt; /* table of globals */
TValue env; /* temporary place for environments */
GCObject *openupval; /* list of open upvalues in this stack */
GCObject *gclist;
struct lua_longjmp *errorJmp; /* current error recover point */
ptrdiff_t errfunc; /* current error handling function (stack index) */
};


#define G(L) (L- &amp; gt; l_G)


/*
** Union of all collectable objects
*/
union GCObject {
GCheader gch;
union TString ts;
union Udata u;
union Closure cl;
struct Table h;
struct Proto p;
struct UpVal uv;
struct lua_State th; /* thread */
};


/* macros to convert a GCObject into a specific value */
#define rawgco2ts(o) check_exp((o)- &amp; gt; gch.tt == LUA_TSTRING, &amp; ((o)- &amp; gt; ts))
#define gco2ts(o) ( &amp; rawgco2ts(o)- &amp; gt; tsv)
#define rawgco2u(o) check_exp((o)- &amp; gt; gch.tt == LUA_TUSERDATA, &amp; ((o)- &amp; gt; u))
#define gco2u(o) ( &amp; rawgco2u(o)- &amp; gt; uv)
#define gco2cl(o) check_exp((o)- &amp; gt; gch.tt == LUA_TFUNCTION, &amp; ((o)- &amp; gt; cl))
#define gco2h(o) check_exp((o)- &amp; gt; gch.tt == LUA_TTABLE, &amp; ((o)- &amp; gt; h))
#define gco2p(o) check_exp((o)- &amp; gt; gch.tt == LUA_TPROTO, &amp; ((o)- &amp; gt; p))
#define gco2uv(o) check_exp((o)- &amp; gt; gch.tt == LUA_TUPVAL, &amp; ((o)- &amp; gt; uv))
#define ngcotouv(o) \
check_exp((o) == NULL || (o)- &amp; gt; gch.tt == LUA_TUPVAL, &amp; ((o)- &amp; gt; uv))
#define gco2th(o) check_exp((o)- &amp; gt; gch.tt == LUA_TTHREAD, &amp; ((o)- &amp; gt; th))

/* macro to convert any Lua object into a GCObject */
#define obj2gco(v) (cast(GCObject *, (v)))


LUAI_FUNC lua_State *luaE_newthread (lua_State *L);
LUAI_FUNC void luaE_freethread (lua_State *L, lua_State *L1);

#endif


scite228.zip > lfunc.c

/*
** $Id$
** Auxiliary functions to manipulate prototypes and closures
** See Copyright Notice in lua.h
*/


#include &amp; lt; stddef.h &amp; gt;

#define lfunc_c
#define LUA_CORE

#include &quot; lua.h &quot;

#include &quot; lfunc.h &quot;
#include &quot; lgc.h &quot;
#include &quot; lmem.h &quot;
#include &quot; lobject.h &quot;
#include &quot; lstate.h &quot;



Closure *luaF_newCclosure (lua_State *L, int nelems, Table *e) {
Closure *c = cast(Closure *, luaM_malloc(L, sizeCclosure(nelems)));
luaC_link(L, obj2gco(c), LUA_TFUNCTION);
c- &amp; gt; c.isC = 1;
c- &amp; gt; c.env = e;
c- &amp; gt; c.nupvalues = cast_byte(nelems);
return c;
}


Closure *luaF_newLclosure (lua_State *L, int nelems, Table *e) {
Closure *c = cast(Closure *, luaM_malloc(L, sizeLclosure(nelems)));
luaC_link(L, obj2gco(c), LUA_TFUNCTION);
c- &amp; gt; l.isC = 0;
c- &amp; gt; l.env = e;
c- &amp; gt; l.nupvalues = cast_byte(nelems);
while (nelems--) c- &amp; gt; l.upvals[nelems] = NULL;
return c;
}


UpVal *luaF_newupval (lua_State *L) {
UpVal *uv = luaM_new(L, UpVal);
luaC_link(L, obj2gco(uv), LUA_TUPVAL);
uv- &amp; gt; v = &amp; uv- &amp; gt; u.value;
setnilvalue(uv- &amp; gt; v);
return uv;
}


UpVal *luaF_findupval (lua_State *L, StkId level) {
global_State *g = G(L);
GCObject **pp = &amp; L- &amp; gt; openupval;
UpVal *p;
UpVal *uv;
while (*pp != NULL &amp; &amp; (p = ngcotouv(*pp))- &amp; gt; v &amp; gt; = level) {
lua_assert(p- &amp; gt; v != &amp; p- &amp; gt; u.value);
if (p- &amp; gt; v == level) { /* found a corresponding upvalue? */
if (isdead(g, obj2gco(p))) /* is it dead? */
changewhite(obj2gco(p)); /* ressurect it */
return p;
}
pp = &amp; p- &amp; gt; next;
}
uv = luaM_new(L, UpVal); /* not found: create a new one */
uv- &amp; gt; tt = LUA_TUPVAL;
uv- &amp; gt; marked = luaC_white(g);
uv- &amp; gt; v = level; /* current value lives in the stack */
uv- &amp; gt; next = *pp; /* chain it in the proper position */
*pp = obj2gco(uv);
uv- &amp; gt; u.l.prev = &amp; g- &amp; gt; uvhead; /* double link it in `uvhead' list */
uv- &amp; gt; u.l.next = g- &amp; gt; uvhead.u.l.next;
uv- &amp; gt; u.l.next- &amp; gt; u.l.prev = uv;
g- &amp; gt; uvhead.u.l.next = uv;
lua_assert(uv- &amp; gt; u.l.next- &amp; gt; u.l.prev == uv &amp; &amp; uv- &amp; gt; u.l.prev- &amp; gt; u.l.next == uv);
return uv;
}


static void unlinkupval (UpVal *uv) {
lua_assert(uv- &amp; gt; u.l.next- &amp; gt; u.l.prev == uv &amp; &amp; uv- &amp; gt; u.l.prev- &amp; gt; u.l.next == uv);
uv- &amp; gt; u.l.next- &amp; gt; u.l.prev = uv- &amp; gt; u.l.prev; /* remove from `uvhead' list */
uv- &amp; gt; u.l.prev- &amp; gt; u.l.next = uv- &amp; gt; u.l.next;
}


void luaF_freeupval (lua_State *L, UpVal *uv) {
if (uv- &amp; gt; v != &amp; uv- &amp; gt; u.value) /* is it open? */
unlinkupval(uv); /* remove from open list */
luaM_free(L, uv); /* free upvalue */
}


void luaF_close (lua_State *L, StkId level) {
UpVal *uv;
global_State *g = G(L);
while (L- &amp; gt; openupval != NULL &amp; &amp; (uv = ngcotouv(L- &amp; gt; openupval))- &amp; gt; v &amp; gt; = level) {
GCObject *o = obj2gco(uv);
lua_assert(!isblack(o) &amp; &amp; uv- &amp; gt; v != &amp; uv- &amp; gt; u.value);
L- &amp; gt; openupval = uv- &amp; gt; next; /* remove from `open' list */
if (isdead(g, o))
luaF_freeupval(L, uv); /* free upvalue */
else {
unlinkupval(uv);
setobj(L, &amp; uv- &amp; gt; u.value, uv- &amp; gt; v);
uv- &amp; gt; v = &amp; uv- &amp; gt; u.value; /* now current value lives here */
luaC_linkupval(L, uv); /* link upvalue into `gcroot' list */
}
}
}


Proto *luaF_newproto (lua_State *L) {
Proto *f = luaM_new(L, Proto);
luaC_link(L, obj2gco(f), LUA_TPROTO);
f- &amp; gt; k = NULL;
f- &amp; gt; sizek = 0;
f- &amp; gt; p = NULL;
f- &amp; gt; sizep = 0;
f- &amp; gt; code = NULL;
f- &amp; gt; sizecode = 0;
f- &amp; gt; sizelineinfo = 0;
f- &amp; gt; sizeupvalues = 0;
f- &amp; gt; nups = 0;
f- &amp; gt; upvalues = NULL;
f- &amp; gt; numparams = 0;
f- &amp; gt; is_vararg = 0;
f- &amp; gt; maxstacksize = 0;
f- &amp; gt; lineinfo = NULL;
f- &amp; gt; sizelocvars = 0;
f- &amp; gt; locvars = NULL;
f- &amp; gt; linedefined = 0;
f- &amp; gt; lastlinedefined = 0;
f- &amp; gt; source = NULL;
return f;
}


void luaF_freeproto (lua_State *L, Proto *f) {
luaM_freearray(L, f- &amp; gt; code, f- &amp; gt; sizecode, Instruction);
luaM_freearray(L, f- &amp; gt; p, f- &amp; gt; sizep, Proto *);
luaM_freearray(L, f- &amp; gt; k, f- &amp; gt; sizek, TValue);
luaM_freearray(L, f- &amp; gt; lineinfo, f- &amp; gt; sizelineinfo, int);
luaM_freearray(L, f- &amp; gt; locvars, f- &amp; gt; sizelocvars, struct LocVar);
luaM_freearray(L, f- &amp; gt; upvalues, f- &amp; gt; sizeupvalues, TString *);
luaM_free(L, f);
}


void luaF_freeclosure (lua_State *L, Closure *c) {
int size = (c- &amp; gt; c.isC) ? sizeCclosure(c- &amp; gt; c.nupvalues) :
sizeLclosure(c- &amp; gt; l.nupvalues);
luaM_freemem(L, c, size);
}


/*
** Look for n-th local variable at line `line' in function `func'.
** Returns NULL if not found.
*/
const char *luaF_getlocalname (const Proto *f, int local_number, int pc) {
int i;
for (i = 0; i &amp; lt; f- &amp; gt; sizelocvars &amp; &amp; f- &amp; gt; locvars[i].startpc &amp; lt; = pc; i++) {
if (pc &amp; lt; f- &amp; gt; locvars[i].endpc) { /* is variable active? */
local_number--;
if (local_number == 0)
return getstr(f- &amp; gt; locvars[i].varname);
}
}
return NULL; /* not found */
}


scite228.zip > ldebug.c

/*
** $Id$
** Debug Interface
** See Copyright Notice in lua.h
*/


#include &amp; lt; stdarg.h &amp; gt;
#include &amp; lt; stddef.h &amp; gt;
#include &amp; lt; string.h &amp; gt;


#define ldebug_c
#define LUA_CORE

#include &quot; lua.h &quot;

#include &quot; lapi.h &quot;
#include &quot; lcode.h &quot;
#include &quot; ldebug.h &quot;
#include &quot; ldo.h &quot;
#include &quot; lfunc.h &quot;
#include &quot; lobject.h &quot;
#include &quot; lopcodes.h &quot;
#include &quot; lstate.h &quot;
#include &quot; lstring.h &quot;
#include &quot; ltable.h &quot;
#include &quot; ltm.h &quot;
#include &quot; lvm.h &quot;



static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name);


static int currentpc (lua_State *L, CallInfo *ci) {
if (!isLua(ci)) return -1; /* function is not a Lua function? */
if (ci == L- &amp; gt; ci)
ci- &amp; gt; savedpc = L- &amp; gt; savedpc;
return pcRel(ci- &amp; gt; savedpc, ci_func(ci)- &amp; gt; l.p);
}


static int currentline (lua_State *L, CallInfo *ci) {
int pc = currentpc(L, ci);
if (pc &amp; lt; 0)
return -1; /* only active lua functions have current-line information */
else
return getline(ci_func(ci)- &amp; gt; l.p, pc);
}


/*
** this function can be called asynchronous (e.g. during a signal)
*/
LUA_API int lua_sethook (lua_State *L, lua_Hook func, int mask, int count) {
if (func == NULL || mask == 0) { /* turn off hooks? */
mask = 0;
func = NULL;
}
L- &amp; gt; hook = func;
L- &amp; gt; basehookcount = count;
resethookcount(L);
L- &amp; gt; hookmask = cast_byte(mask);
return 1;
}


LUA_API lua_Hook lua_gethook (lua_State *L) {
return L- &amp; gt; hook;
}


LUA_API int lua_gethookmask (lua_State *L) {
return L- &amp; gt; hookmask;
}


LUA_API int lua_gethookcount (lua_State *L) {
return L- &amp; gt; basehookcount;
}


LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar) {
int status;
CallInfo *ci;
lua_lock(L);
for (ci = L- &amp; gt; ci; level &amp; gt; 0 &amp; &amp; ci &amp; gt; L- &amp; gt; base_ci; ci--) {
level--;
if (f_isLua(ci)) /* Lua function? */
level -= ci- &amp; gt; tailcalls; /* skip lost tail calls */
}
if (level == 0 &amp; &amp; ci &amp; gt; L- &amp; gt; base_ci) { /* level found? */
status = 1;
ar- &amp; gt; i_ci = cast_int(ci - L- &amp; gt; base_ci);
}
else if (level &amp; lt; 0) { /* level is of a lost tail call? */
status = 1;
ar- &amp; gt; i_ci = 0;
}
else status = 0; /* no such level */
lua_unlock(L);
return status;
}


static Proto *getluaproto (CallInfo *ci) {
return (isLua(ci) ? ci_func(ci)- &amp; gt; l.p : NULL);
}


static const char *findlocal (lua_State *L, CallInfo *ci, int n) {
const char *name;
Proto *fp = getluaproto(ci);
if (fp &amp; &amp; (name = luaF_getlocalname(fp, n, currentpc(L, ci))) != NULL)
return name; /* is a local variable in a Lua function */
else {
StkId limit = (ci == L- &amp; gt; ci) ? L- &amp; gt; top : (ci+1)- &amp; gt; func;
if (limit - ci- &amp; gt; base &amp; gt; = n &amp; &amp; n &amp; gt; 0) /* is 'n' inside 'ci' stack? */
return &quot; (*temporary) &quot; ;
else
return NULL;
}
}


LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n) {
CallInfo *ci = L- &amp; gt; base_ci + ar- &amp; gt; i_ci;
const char *name = findlocal(L, ci, n);
lua_lock(L);
if (name)
luaA_pushobject(L, ci- &amp; gt; base + (n - 1));
lua_unlock(L);
return name;
}


LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n) {
CallInfo *ci = L- &amp; gt; base_ci + ar- &amp; gt; i_ci;
const char *name = findlocal(L, ci, n);
lua_lock(L);
if (name)
setobjs2s(L, ci- &amp; gt; base + (n - 1), L- &amp; gt; top - 1);
L- &amp; gt; top--; /* pop value */
lua_unlock(L);
return name;
}


static void funcinfo (lua_Debug *ar, Closure *cl) {
if (cl- &amp; gt; c.isC) {
ar- &amp; gt; source = &quot; =[C] &quot; ;
ar- &amp; gt; linedefined = -1;
ar- &amp; gt; lastlinedefined = -1;
ar- &amp; gt; what = &quot; C &quot; ;
}
else {
ar- &amp; gt; source = getstr(cl- &amp; gt; l.p- &amp; gt; source);
ar- &amp; gt; linedefined = cl- &amp; gt; l.p- &amp; gt; linedefined;
ar- &amp; gt; lastlinedefined = cl- &amp; gt; l.p- &amp; gt; lastlinedefined;
ar- &amp; gt; what = (ar- &amp; gt; linedefined == 0) ? &quot; main &quot; : &quot; Lua &quot; ;
}
luaO_chunkid(ar- &amp; gt; short_src, ar- &amp; gt; source, LUA_IDSIZE);
}


static void info_tailcall (lua_Debug *ar) {
ar- &amp; gt; name = ar- &amp; gt; namewhat = &quot; &quot; ;
ar- &amp; gt; what = &quot; tail &quot; ;
ar- &amp; gt; lastlinedefined = ar- &amp; gt; linedefined = ar- &amp; gt; currentline = -1;
ar- &amp; gt; source = &quot; =(tail call) &quot; ;
luaO_chunkid(ar- &amp; gt; short_src, ar- &amp; gt; source, LUA_IDSIZE);
ar- &amp; gt; nups = 0;
}


static void collectvalidlines (lua_State *L, Closure *f) {
if (f == NULL || f- &amp; gt; c.isC) {
setnilvalue(L- &amp; gt; top);
}
else {
Table *t = luaH_new(L, 0, 0);
int *lineinfo = f- &amp; gt; l.p- &amp; gt; lineinfo;
int i;
for (i=0; i &amp; lt; f- &amp; gt; l.p- &amp; gt; sizelineinfo; i++)
setbvalue(luaH_setnum(L, t, lineinfo[i]), 1);
sethvalue(L, L- &amp; gt; top, t);
}
incr_top(L);
}


static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar,
Closure *f, CallInfo *ci) {
int status = 1;
if (f == NULL) {
info_tailcall(ar);
return status;
}
for (; *what; what++) {
switch (*what) {
case 'S': {
funcinfo(ar, f);
break;
}
case 'l': {
ar- &amp; gt; currentline = (ci) ? currentline(L, ci) : -1;
break;
}
case 'u': {
ar- &amp; gt; nups = f- &amp; gt; c.nupvalues;
break;
}
case 'n': {
ar- &amp; gt; namewhat = (ci) ? getfuncname(L, ci, &amp; ar- &amp; gt; name) : NULL;
if (ar- &amp; gt; namewhat == NULL) {
ar- &amp; gt; namewhat = &quot; &quot; ; /* not found */
ar- &amp; gt; name = NULL;
}
break;
}
case 'L':
case 'f': /* handled by lua_getinfo */
break;
default: status = 0; /* invalid option */
}
}
return status;
}


LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) {
int status;
Closure *f = NULL;
CallInfo *ci = NULL;
lua_lock(L);
if (*what == ' &amp; gt; ') {
StkId func = L- &amp; gt; top - 1;
luai_apicheck(L, ttisfunction(func));
what++; /* skip the ' &amp; gt; ' */
f = clvalue(func);
L- &amp; gt; top--; /* pop function */
}
else if (ar- &amp; gt; i_ci != 0) { /* no tail call? */
ci = L- &amp; gt; base_ci + ar- &amp; gt; i_ci;
lua_assert(ttisfunction(ci- &amp; gt; func));
f = clvalue(ci- &amp; gt; func);
}
status = auxgetinfo(L, what, ar, f, ci);
if (strchr(what, 'f')) {
if (f == NULL) setnilvalue(L- &amp; gt; top);
else setclvalue(L, L- &amp; gt; top, f);
incr_top(L);
}
if (strchr(what, 'L'))
collectvalidlines(L, f);
lua_unlock(L);
return status;
}


/*
** {======================================================
** Symbolic Execution and code checker
** =======================================================
*/

#define check(x) if (!(x)) return 0;

#define checkjump(pt,pc) check(0 &amp; lt; = pc &amp; &amp; pc &amp; lt; pt- &amp; gt; sizecode)

#define checkreg(pt,reg) check((reg) &amp; lt; (pt)- &amp; gt; maxstacksize)



static int precheck (const Proto *pt) {
check(pt- &amp; gt; maxstacksize &amp; lt; = MAXSTACK);
check(pt- &amp; gt; numparams+(pt- &amp; gt; is_vararg &amp; VARARG_HASARG) &amp; lt; = pt- &amp; gt; maxstacksize);
check(!(pt- &amp; gt; is_vararg &amp; VARARG_NEEDSARG) ||
(pt- &amp; gt; is_vararg &amp; VARARG_HASARG));
check(pt- &amp; gt; sizeupvalues &amp; lt; = pt- &amp; gt; nups);
check(pt- &amp; gt; sizelineinfo == pt- &amp; gt; sizecode || pt- &amp; gt; sizelineinfo == 0);
check(pt- &amp; gt; sizecode &amp; gt; 0 &amp; &amp; GET_OPCODE(pt- &amp; gt; code[pt- &amp; gt; sizecode-1]) == OP_RETURN);
return 1;
}


#define checkopenop(pt,pc) luaG_checkopenop((pt)- &amp; gt; code[(pc)+1])

int luaG_checkopenop (Instruction i) {
switch (GET_OPCODE(i)) {
case OP_CALL:
case OP_TAILCALL:
case OP_RETURN:
case OP_SETLIST: {
check(GETARG_B(i) == 0);
return 1;
}
default: return 0; /* invalid instruction after an open call */
}
}


static int checkArgMode (const Proto *pt, int r, enum OpArgMask mode) {
switch (mode) {
case OpArgN: check(r == 0); break;
case OpArgU: break;
case OpArgR: checkreg(pt, r); break;
case OpArgK:
check(ISK(r) ? INDEXK(r) &amp; lt; pt- &amp; gt; sizek : r &amp; lt; pt- &amp; gt; maxstacksize);
break;
}
return 1;
}


static Instruction symbexec (const Proto *pt, int lastpc, int reg) {
int pc;
int last; /* stores position of last instruction that changed `reg' */
last = pt- &amp; gt; sizecode-1; /* points to final return (a `neutral' instruction) */
check(precheck(pt));
for (pc = 0; pc &amp; lt; lastpc; pc++) {
Instruction i = pt- &amp; gt; code[pc];
OpCode op = GET_OPCODE(i);
int a = GETARG_A(i);
int b = 0;
int c = 0;
check(op &amp; lt; NUM_OPCODES);
checkreg(pt, a);
switch (getOpMode(op)) {
case iABC: {
b = GETARG_B(i);
c = GETARG_C(i);
check(checkArgMode(pt, b, getBMode(op)));
check(checkArgMode(pt, c, getCMode(op)));
break;
}
case iABx: {
b = GETARG_Bx(i);
if (getBMode(op) == OpArgK) check(b &amp; lt; pt- &amp; gt; sizek);
break;
}
case iAsBx: {
b = GETARG_sBx(i);
if (getBMode(op) == OpArgR) {
int dest = pc+1+b;
check(0 &amp; lt; = dest &amp; &amp; dest &amp; lt; pt- &amp; gt; sizecode);
if (dest &amp; gt; 0) {
int j;
/* check that it does not jump to a setlist count; this
is tricky, because the count from a previous setlist may
have the same value of an invalid setlist; so, we must
go all the way back to the first of them (if any) */
for (j = 0; j &amp; lt; dest; j++) {
Instruction d = pt- &amp; gt; code[dest-1-j];
if (!(GET_OPCODE(d) == OP_SETLIST &amp; &amp; GETARG_C(d) == 0)) break;
}
/* if 'j' is even, previous value is not a setlist (even if
it looks like one) */
check((j &amp; 1) == 0);
}
}
break;
}
}
if (testAMode(op)) {
if (a == reg) last = pc; /* change register `a' */
}
if (testTMode(op)) {
check(pc+2 &amp; lt; pt- &amp; gt; sizecode); /* check skip */
check(GET_OPCODE(pt- &amp; gt; code[pc+1]) == OP_JMP);
}
switch (op) {
case OP_LOADBOOL: {
if (c == 1) { /* does it jump? */
check(pc+2 &amp; lt; pt- &amp; gt; sizecode); /* check its jump */
check(GET_OPCODE(pt- &amp; gt; code[pc+1]) != OP_SETLIST ||
GETARG_C(pt- &amp; gt; code[pc+1]) != 0);
}
break;
}
case OP_LOADNIL: {
if (a &amp; lt; = reg &amp; &amp; reg &amp; lt; = b)
last = pc; /* set registers from `a' to `b' */
break;
}
case OP_GETUPVAL:
case OP_SETUPVAL: {
check(b &amp; lt; pt- &amp; gt; nups);
break;
}
case OP_GETGLOBAL:
case OP_SETGLOBAL: {
check(ttisstring( &amp; pt- &amp; gt; k[b]));
break;
}
case OP_SELF: {
checkreg(pt, a+1);
if (reg == a+1) last = pc;
break;
}
case OP_CONCAT: {
check(b &amp; lt; c); /* at least two operands */
break;
}
case OP_TFORLOOP: {
check(c &amp; gt; = 1); /* at least one result (control variable) */
checkreg(pt, a+2+c); /* space for results */
if (reg &amp; gt; = a+2) last = pc; /* affect all regs above its base */
break;
}
case OP_FORLOOP:
case OP_FORPREP:
checkreg(pt, a+3);
/* go through */
case OP_JMP: {
int dest = pc+1+b;
/* not full check and jump is forward and do not skip `lastpc'? */
if (reg != NO_REG &amp; &amp; pc &amp; lt; dest &amp; &amp; dest &amp; lt; = lastpc)
pc += b; /* do the jump */
break;
}
case OP_CALL:
case OP_TAILCALL: {
if (b != 0) {
checkreg(pt, a+b-1);
}
c--; /* c = num. returns */
if (c == LUA_MULTRET) {
check(checkopenop(pt, pc));
}
else if (c != 0)
checkreg(pt, a+c-1);
if (reg &amp; gt; = a) last = pc; /* affect all registers above base */
break;
}
case OP_RETURN: {
b--; /* b = num. returns */
if (b &amp; gt; 0) checkreg(pt, a+b-1);
break;
}
case OP_SETLIST: {
if (b &amp; gt; 0) checkreg(pt, a + b);
if (c == 0) {
pc++;
check(pc &amp; lt; pt- &amp; gt; sizecode - 1);
}
break;
}
case OP_CLOSURE: {
int nup, j;
check(b &amp; lt; pt- &amp; gt; sizep);
nup = pt- &amp; gt; p[b]- &amp; gt; nups;
check(pc + nup &amp; lt; pt- &amp; gt; sizecode);
for (j = 1; j &amp; lt; = nup; j++) {
OpCode op1 = GET_OPCODE(pt- &amp; gt; code[pc + j]);
check(op1 == OP_GETUPVAL || op1 == OP_MOVE);
}
if (reg != NO_REG) /* tracing? */
pc += nup; /* do not 'execute' these pseudo-instructions */
break;
}
case OP_VARARG: {
check((pt- &amp; gt; is_vararg &amp; VARARG_ISVARARG) &amp; &amp;
!(pt- &amp; gt; is_vararg &amp; VARARG_NEEDSARG));
b--;
if (b == LUA_MULTRET) check(checkopenop(pt, pc));
checkreg(pt, a+b-1);
break;
}
default: break;
}
}
return pt- &amp; gt; code[last];
}

#undef check
#undef checkjump
#undef checkreg

/* }====================================================== */


int luaG_checkcode (const Proto *pt) {
return (symbexec(pt, pt- &amp; gt; sizecode, NO_REG) != 0);
}


static const char *kname (Proto *p, int c) {
if (ISK(c) &amp; &amp; ttisstring( &amp; p- &amp; gt; k[INDEXK(c)]))
return svalue( &amp; p- &amp; gt; k[INDEXK(c)]);
else
return &quot; ? &quot; ;
}


static const char *getobjname (lua_State *L, CallInfo *ci, int stackpos,
const char **name) {
if (isLua(ci)) { /* a Lua function? */
Proto *p = ci_func(ci)- &amp; gt; l.p;
int pc = currentpc(L, ci);
Instruction i;
*name = luaF_getlocalname(p, stackpos+1, pc);
if (*name) /* is a local? */
return &quot; local &quot; ;
i = symbexec(p, pc, stackpos); /* try symbolic execution */
lua_assert(pc != -1);
switch (GET_OPCODE(i)) {
case OP_GETGLOBAL: {
int g = GETARG_Bx(i); /* global index */
lua_assert(ttisstring( &amp; p- &amp; gt; k[g]));
*name = svalue( &amp; p- &amp; gt; k[g]);
return &quot; global &quot; ;
}
case OP_MOVE: {
int a = GETARG_A(i);
int b = GETARG_B(i); /* move from `b' to `a' */
if (b &amp; lt; a)
return getobjname(L, ci, b, name); /* get name for `b' */
break;
}
case OP_GETTABLE: {
int k = GETARG_C(i); /* key index */
*name = kname(p, k);
return &quot; field &quot; ;
}
case OP_GETUPVAL: {
int u = GETARG_B(i); /* upvalue index */
*name = p- &amp; gt; upvalues ? getstr(p- &amp; gt; upvalues[u]) : &quot; ? &quot; ;
return &quot; upvalue &quot; ;
}
case OP_SELF: {
int k = GETARG_C(i); /* key index */
*name = kname(p, k);
return &quot; method &quot; ;
}
default: break;
}
}
return NULL; /* no useful name found */
}


static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name) {
Instruction i;
if ((isLua(ci) &amp; &amp; ci- &amp; gt; tailcalls &amp; gt; 0) || !isLua(ci - 1))
return NULL; /* calling function is not Lua (or is unknown) */
ci--; /* calling function */
i = ci_func(ci)- &amp; gt; l.p- &amp; gt; code[currentpc(L, ci)];
if (GET_OPCODE(i) == OP_CALL || GET_OPCODE(i) == OP_TAILCALL ||
GET_OPCODE(i) == OP_TFORLOOP)
return getobjname(L, ci, GETARG_A(i), name);
else
return NULL; /* no useful name can be found */
}


/* only ANSI way to check whether a pointer points to an array */
static int isinstack (CallInfo *ci, const TValue *o) {
StkId p;
for (p = ci- &amp; gt; base; p &amp; lt; ci- &amp; gt; top; p++)
if (o == p) return 1;
return 0;
}


void luaG_typeerror (lua_State *L, const TValue *o, const char *op) {
const char *name = NULL;
const char *t = luaT_typenames[ttype(o)];
const char *kind = (isinstack(L- &amp; gt; ci, o)) ?
getobjname(L, L- &amp; gt; ci, cast_int(o - L- &amp; gt; base), &amp; name) :
NULL;
if (kind)
luaG_runerror(L, &quot; attempt to %s %s &quot; LUA_QS &quot; (a %s value) &quot; ,
op, kind, name, t);
else
luaG_runerror(L, &quot; attempt to %s a %s value &quot; , op, t);
}


void luaG_concaterror (lua_State *L, StkId p1, StkId p2) {
if (ttisstring(p1) || ttisnumber(p1)) p1 = p2;
lua_assert(!ttisstring(p1) &amp; &amp; !ttisnumber(p1));
luaG_typeerror(L, p1, &quot; concatenate &quot; );
}


void luaG_aritherror (lua_State *L, const TValue *p1, const TValue *p2) {
TValue temp;
if (luaV_tonumber(p1, &amp; temp) == NULL)
p2 = p1; /* first operand is wrong */
luaG_typeerror(L, p2, &quot; perform arithmetic on &quot; );
}


int luaG_ordererror (lua_State *L, const TValue *p1, const TValue *p2) {
const char *t1 = luaT_typenames[ttype(p1)];
const char *t2 = luaT_typenames[ttype(p2)];
if (t1[2] == t2[2])
luaG_runerror(L, &quot; attempt to compare two %s values &quot; , t1);
else
luaG_runerror(L, &quot; attempt to compare %s with %s &quot; , t1, t2);
return 0;
}


static void addinfo (lua_State *L, const char *msg) {
CallInfo *ci = L- &amp; gt; ci;
if (isLua(ci)) { /* is Lua code? */
char buff[LUA_IDSIZE]; /* add file:line information */
int line = currentline(L, ci);
luaO_chunkid(buff, getstr(getluaproto(ci)- &amp; gt; source), LUA_IDSIZE);
luaO_pushfstring(L, &quot; %s:%d: %s &quot; , buff, line, msg);
}
}


void luaG_errormsg (lua_State *L) {
if (L- &amp; gt; errfunc != 0) { /* is there an error handling function? */
StkId errfunc = restorestack(L, L- &amp; gt; errfunc);
if (!ttisfunction(errfunc)) luaD_throw(L, LUA_ERRERR);
setobjs2s(L, L- &amp; gt; top, L- &amp; gt; top - 1); /* move argument */
setobjs2s(L, L- &amp; gt; top - 1, errfunc); /* push function */
incr_top(L);
luaD_call(L, L- &amp; gt; top - 2, 1); /* call it */
}
luaD_throw(L, LUA_ERRRUN);
}


void luaG_runerror (lua_State *L, const char *fmt, ...) {
va_list argp;
va_start(argp, fmt);
addinfo(L, luaO_pushvfstring(L, fmt, argp));
va_end(argp);
luaG_errormsg(L);
}


scite228.zip > ltm.h

/*
** $Id$
** Tag methods
** See Copyright Notice in lua.h
*/

#ifndef ltm_h
#define ltm_h


#include &quot; lobject.h &quot;


/*
* WARNING: if you change the order of this enumeration,
* grep &quot; ORDER TM &quot;
*/
typedef enum {
TM_INDEX,
TM_NEWINDEX,
TM_GC,
TM_MODE,
TM_EQ, /* last tag method with `fast' access */
TM_ADD,
TM_SUB,
TM_MUL,
TM_DIV,
TM_MOD,
TM_POW,
TM_UNM,
TM_LEN,
TM_LT,
TM_LE,
TM_CONCAT,
TM_CALL,
TM_N /* number of elements in the enum */
} TMS;



#define gfasttm(g,et,e) ((et) == NULL ? NULL : \
((et)- &amp; gt; flags &amp; (1u &amp; lt; &amp; lt; (e))) ? NULL : luaT_gettm(et, e, (g)- &amp; gt; tmname[e]))

#define fasttm(l,et,e) gfasttm(G(l), et, e)

LUAI_DATA const char *const luaT_typenames[];


LUAI_FUNC const TValue *luaT_gettm (Table *events, TMS event, TString *ename);
LUAI_FUNC const TValue *luaT_gettmbyobj (lua_State *L, const TValue *o,
TMS event);
LUAI_FUNC void luaT_init (lua_State *L);

#endif


scite228.zip > llex.h

/*
** $Id$
** Lexical Analyzer
** See Copyright Notice in lua.h
*/

#ifndef llex_h
#define llex_h

#include &quot; lobject.h &quot;
#include &quot; lzio.h &quot;


#define FIRST_RESERVED 257

/* maximum length of a reserved word */
#define TOKEN_LEN (sizeof( &quot; function &quot; )/sizeof(char))


/*
* WARNING: if you change the order of this enumeration,
* grep &quot; ORDER RESERVED &quot;
*/
enum RESERVED {
/* terminal symbols denoted by reserved words */
TK_AND = FIRST_RESERVED, TK_BREAK,
TK_DO, TK_ELSE, TK_ELSEIF, TK_END, TK_FALSE, TK_FOR, TK_FUNCTION,
TK_IF, TK_IN, TK_LOCAL, TK_NIL, TK_NOT, TK_OR, TK_REPEAT,
TK_RETURN, TK_THEN, TK_TRUE, TK_UNTIL, TK_WHILE,
/* other terminal symbols */
TK_CONCAT, TK_DOTS, TK_EQ, TK_GE, TK_LE, TK_NE, TK_NUMBER,
TK_NAME, TK_STRING, TK_EOS
};

/* number of reserved words */
#define NUM_RESERVED (cast(int, TK_WHILE-FIRST_RESERVED+1))


/* array with token `names' */
LUAI_DATA const char *const luaX_tokens [];


typedef union {
lua_Number r;
TString *ts;
} SemInfo; /* semantics information */


typedef struct Token {
int token;
SemInfo seminfo;
} Token;


typedef struct LexState {
int current; /* current character (charint) */
int linenumber; /* input line counter */
int lastline; /* line of last token `consumed' */
Token t; /* current token */
Token lookahead; /* look ahead token */
struct FuncState *fs; /* `FuncState' is private to the parser */
struct lua_State *L;
ZIO *z; /* input stream */
Mbuffer *buff; /* buffer for tokens */
TString *source; /* current source name */
char decpoint; /* locale decimal point */
} LexState;


LUAI_FUNC void luaX_init (lua_State *L);
LUAI_FUNC void luaX_setinput (lua_State *L, LexState *ls, ZIO *z,
TString *source);
LUAI_FUNC TString *luaX_newstring (LexState *ls, const char *str, size_t l);
LUAI_FUNC void luaX_next (LexState *ls);
LUAI_FUNC void luaX_lookahead (LexState *ls);
LUAI_FUNC void luaX_lexerror (LexState *ls, const char *msg, int token);
LUAI_FUNC void luaX_syntaxerror (LexState *ls, const char *s);
LUAI_FUNC const char *luaX_token2str (LexState *ls, int token);


#endif


scite228.zip > ldo.c

/*
** $Id$
** Stack and Call structure of Lua
** See Copyright Notice in lua.h
*/


#include &amp; lt; setjmp.h &amp; gt;
#include &amp; lt; stdlib.h &amp; gt;
#include &amp; lt; string.h &amp; gt;

#define ldo_c
#define LUA_CORE

#include &quot; lua.h &quot;

#include &quot; ldebug.h &quot;
#include &quot; ldo.h &quot;
#include &quot; lfunc.h &quot;
#include &quot; lgc.h &quot;
#include &quot; lmem.h &quot;
#include &quot; lobject.h &quot;
#include &quot; lopcodes.h &quot;
#include &quot; lparser.h &quot;
#include &quot; lstate.h &quot;
#include &quot; lstring.h &quot;
#include &quot; ltable.h &quot;
#include &quot; ltm.h &quot;
#include &quot; lundump.h &quot;
#include &quot; lvm.h &quot;
#include &quot; lzio.h &quot;




/*
** {======================================================
** Error-recovery functions
** =======================================================
*/


/* chain list of long jump buffers */
struct lua_longjmp {
struct lua_longjmp *previous;
luai_jmpbuf b;
volatile int status; /* error code */
};


void luaD_seterrorobj (lua_State *L, int errcode, StkId oldtop) {
switch (errcode) {
case LUA_ERRMEM: {
setsvalue2s(L, oldtop, luaS_newliteral(L, MEMERRMSG));
break;
}
case LUA_ERRERR: {
setsvalue2s(L, oldtop, luaS_newliteral(L, &quot; error in error handling &quot; ));
break;
}
case LUA_ERRSYNTAX:
case LUA_ERRRUN: {
setobjs2s(L, oldtop, L- &amp; gt; top - 1); /* error message on current top */
break;
}
}
L- &amp; gt; top = oldtop + 1;
}


static void restore_stack_limit (lua_State *L) {
lua_assert(L- &amp; gt; stack_last - L- &amp; gt; stack == L- &amp; gt; stacksize - EXTRA_STACK - 1);
if (L- &amp; gt; size_ci &amp; gt; LUAI_MAXCALLS) { /* there was an overflow? */
int inuse = cast_int(L- &amp; gt; ci - L- &amp; gt; base_ci);
if (inuse + 1 &amp; lt; LUAI_MAXCALLS) /* can `undo' overflow? */
luaD_reallocCI(L, LUAI_MAXCALLS);
}
}


static void resetstack (lua_State *L, int status) {
L- &amp; gt; ci = L- &amp; gt; base_ci;
L- &amp; gt; base = L- &amp; gt; ci- &amp; gt; base;
luaF_close(L, L- &amp; gt; base); /* close eventual pending closures */
luaD_seterrorobj(L, status, L- &amp; gt; base);
L- &amp; gt; nCcalls = L- &amp; gt; baseCcalls;
L- &amp; gt; allowhook = 1;
restore_stack_limit(L);
L- &amp; gt; errfunc = 0;
L- &amp; gt; errorJmp = NULL;
}


void luaD_throw (lua_State *L, int errcode) {
if (L- &amp; gt; errorJmp) {
L- &amp; gt; errorJmp- &amp; gt; status = errcode;
LUAI_THROW(L, L- &amp; gt; errorJmp);
}
else {
L- &amp; gt; status = cast_byte(errcode);
if (G(L)- &amp; gt; panic) {
resetstack(L, errcode);
lua_unlock(L);
G(L)- &amp; gt; panic(L);
}
exit(EXIT_FAILURE);
}
}


int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud) {
struct lua_longjmp lj;
lj.status = 0;
lj.previous = L- &amp; gt; errorJmp; /* chain new error handler */
L- &amp; gt; errorJmp = &amp; lj;
LUAI_TRY(L, &amp; lj,
(*f)(L, ud);
);
L- &amp; gt; errorJmp = lj.previous; /* restore old error handler */
return lj.status;
}

/* }====================================================== */


static void correctstack (lua_State *L, TValue *oldstack) {
CallInfo *ci;
GCObject *up;
L- &amp; gt; top = (L- &amp; gt; top - oldstack) + L- &amp; gt; stack;
for (up = L- &amp; gt; openupval; up != NULL; up = up- &amp; gt; gch.next)
gco2uv(up)- &amp; gt; v = (gco2uv(up)- &amp; gt; v - oldstack) + L- &amp; gt; stack;
for (ci = L- &amp; gt; base_ci; ci &amp; lt; = L- &amp; gt; ci; ci++) {
ci- &amp; gt; top = (ci- &amp; gt; top - oldstack) + L- &amp; gt; stack;
ci- &amp; gt; base = (ci- &amp; gt; base - oldstack) + L- &amp; gt; stack;
ci- &amp; gt; func = (ci- &amp; gt; func - oldstack) + L- &amp; gt; stack;
}
L- &amp; gt; base = (L- &amp; gt; base - oldstack) + L- &amp; gt; stack;
}


void luaD_reallocstack (lua_State *L, int newsize) {
TValue *oldstack = L- &amp; gt; stack;
int realsize = newsize + 1 + EXTRA_STACK;
lua_assert(L- &amp; gt; stack_last - L- &amp; gt; stack == L- &amp; gt; stacksize - EXTRA_STACK - 1);
luaM_reallocvector(L, L- &amp; gt; stack, L- &amp; gt; stacksize, realsize, TValue);
L- &amp; gt; stacksize = realsize;
L- &amp; gt; stack_last = L- &amp; gt; stack+newsize;
correctstack(L, oldstack);
}


void luaD_reallocCI (lua_State *L, int newsize) {
CallInfo *oldci = L- &amp; gt; base_ci;
luaM_reallocvector(L, L- &amp; gt; base_ci, L- &amp; gt; size_ci, newsize, CallInfo);
L- &amp; gt; size_ci = newsize;
L- &amp; gt; ci = (L- &amp; gt; ci - oldci) + L- &amp; gt; base_ci;
L- &amp; gt; end_ci = L- &amp; gt; base_ci + L- &amp; gt; size_ci - 1;
}


void luaD_growstack (lua_State *L, int n) {
if (n &amp; lt; = L- &amp; gt; stacksize) /* double size is enough? */
luaD_reallocstack(L, 2*L- &amp; gt; stacksize);
else
luaD_reallocstack(L, L- &amp; gt; stacksize + n);
}


static CallInfo *growCI (lua_State *L) {
if (L- &amp; gt; size_ci &amp; gt; LUAI_MAXCALLS) /* overflow while handling overflow? */
luaD_throw(L, LUA_ERRERR);
else {
luaD_reallocCI(L, 2*L- &amp; gt; size_ci);
if (L- &amp; gt; size_ci &amp; gt; LUAI_MAXCALLS)
luaG_runerror(L, &quot; stack overflow &quot; );
}
return ++L- &amp; gt; ci;
}


void luaD_callhook (lua_State *L, int event, int line) {
lua_Hook hook = L- &amp; gt; hook;
if (hook &amp; &amp; L- &amp; gt; allowhook) {
ptrdiff_t top = savestack(L, L- &amp; gt; top);
ptrdiff_t ci_top = savestack(L, L- &amp; gt; ci- &amp; gt; top);
lua_Debug ar;
ar.event = event;
ar.currentline = line;
if (event == LUA_HOOKTAILRET)
ar.i_ci = 0; /* tail call; no debug information about it */
else
ar.i_ci = cast_int(L- &amp; gt; ci - L- &amp; gt; base_ci);
luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */
L- &amp; gt; ci- &amp; gt; top = L- &amp; gt; top + LUA_MINSTACK;
lua_assert(L- &amp; gt; ci- &amp; gt; top &amp; lt; = L- &amp; gt; stack_last);
L- &amp; gt; allowhook = 0; /* cannot call hooks inside a hook */
lua_unlock(L);
(*hook)(L, &amp; ar);
lua_lock(L);
lua_assert(!L- &amp; gt; allowhook);
L- &amp; gt; allowhook = 1;
L- &amp; gt; ci- &amp; gt; top = restorestack(L, ci_top);
L- &amp; gt; top = restorestack(L, top);
}
}


static StkId adjust_varargs (lua_State *L, Proto *p, int actual) {
int i;
int nfixargs = p- &amp; gt; numparams;
Table *htab = NULL;
StkId base, fixed;
for (; actual &amp; lt; nfixargs; ++actual)
setnilvalue(L- &amp; gt; top++);
#if defined(LUA_COMPAT_VARARG)
if (p- &amp; gt; is_vararg &amp; VARARG_NEEDSARG) { /* compat. with old-style vararg? */
int nvar = actual - nfixargs; /* number of extra arguments */
lua_assert(p- &amp; gt; is_vararg &amp; VARARG_HASARG);
luaC_checkGC(L);
htab = luaH_new(L, nvar, 1); /* create `arg' table */
for (i=0; i &amp; lt; nvar; i++) /* put extra arguments into `arg' table */
setobj2n(L, luaH_setnum(L, htab, i+1), L- &amp; gt; top - nvar + i);
/* store counter in field `n' */
setnvalue(luaH_setstr(L, htab, luaS_newliteral(L, &quot; n &quot; )), cast_num(nvar));
}
#endif
/* move fixed parameters to final position */
fixed = L- &amp; gt; top - actual; /* first fixed argument */
base = L- &amp; gt; top; /* final position of first argument */
for (i=0; i &amp; lt; nfixargs; i++) {
setobjs2s(L, L- &amp; gt; top++, fixed+i);
setnilvalue(fixed+i);
}
/* add `arg' parameter */
if (htab) {
sethvalue(L, L- &amp; gt; top++, htab);
lua_assert(iswhite(obj2gco(htab)));
}
return base;
}


static StkId tryfuncTM (lua_State *L, StkId func) {
const TValue *tm = luaT_gettmbyobj(L, func, TM_CALL);
StkId p;
ptrdiff_t funcr = savestack(L, func);
if (!ttisfunction(tm))
luaG_typeerror(L, func, &quot; call &quot; );
/* Open a hole inside the stack at `func' */
for (p = L- &amp; gt; top; p &amp; gt; func; p--) setobjs2s(L, p, p-1);
incr_top(L);
func = restorestack(L, funcr); /* previous call may change stack */
setobj2s(L, func, tm); /* tag method is the new function to be called */
return func;
}



#define inc_ci(L) \
((L- &amp; gt; ci == L- &amp; gt; end_ci) ? growCI(L) : \
(condhardstacktests(luaD_reallocCI(L, L- &amp; gt; size_ci)), ++L- &amp; gt; ci))


int luaD_precall (lua_State *L, StkId func, int nresults) {
LClosure *cl;
ptrdiff_t funcr;
if (!ttisfunction(func)) /* `func' is not a function? */
func = tryfuncTM(L, func); /* check the `function' tag method */
funcr = savestack(L, func);
cl = &amp; clvalue(func)- &amp; gt; l;
L- &amp; gt; ci- &amp; gt; savedpc = L- &amp; gt; savedpc;
if (!cl- &amp; gt; isC) { /* Lua function? prepare its call */
CallInfo *ci;
StkId st, base;
Proto *p = cl- &amp; gt; p;
luaD_checkstack(L, p- &amp; gt; maxstacksize);
func = restorestack(L, funcr);
if (!p- &amp; gt; is_vararg) { /* no varargs? */
base = func + 1;
if (L- &amp; gt; top &amp; gt; base + p- &amp; gt; numparams)
L- &amp; gt; top = base + p- &amp; gt; numparams;
}
else { /* vararg function */
int nargs = cast_int(L- &amp; gt; top - func) - 1;
base = adjust_varargs(L, p, nargs);
func = restorestack(L, funcr); /* previous call may change the stack */
}
ci = inc_ci(L); /* now `enter' new function */
ci- &amp; gt; func = func;
L- &amp; gt; base = ci- &amp; gt; base = base;
ci- &amp; gt; top = L- &amp; gt; base + p- &amp; gt; maxstacksize;
lua_assert(ci- &amp; gt; top &amp; lt; = L- &amp; gt; stack_last);
L- &amp; gt; savedpc = p- &amp; gt; code; /* starting point */
ci- &amp; gt; tailcalls = 0;
ci- &amp; gt; nresults = nresults;
for (st = L- &amp; gt; top; st &amp; lt; ci- &amp; gt; top; st++)
setnilvalue(st);
L- &amp; gt; top = ci- &amp; gt; top;
if (L- &amp; gt; hookmask &amp; LUA_MASKCALL) {
L- &amp; gt; savedpc++; /* hooks assume 'pc' is already incremented */
luaD_callhook(L, LUA_HOOKCALL, -1);
L- &amp; gt; savedpc--; /* correct 'pc' */
}
return PCRLUA;
}
else { /* if is a C function, call it */
CallInfo *ci;
int n;
luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */
ci = inc_ci(L); /* now `enter' new function */
ci- &amp; gt; func = restorestack(L, funcr);
L- &amp; gt; base = ci- &amp; gt; base = ci- &amp; gt; func + 1;
ci- &amp; gt; top = L- &amp; gt; top + LUA_MINSTACK;
lua_assert(ci- &amp; gt; top &amp; lt; = L- &amp; gt; stack_last);
ci- &amp; gt; nresults = nresults;
if (L- &amp; gt; hookmask &amp; LUA_MASKCALL)
luaD_callhook(L, LUA_HOOKCALL, -1);
lua_unlock(L);
n = (*curr_func(L)- &amp; gt; c.f)(L); /* do the actual call */
lua_lock(L);
if (n &amp; lt; 0) /* yielding? */
return PCRYIELD;
else {
luaD_poscall(L, L- &amp; gt; top - n);
return PCRC;
}
}
}


static StkId callrethooks (lua_State *L, StkId firstResult) {
ptrdiff_t fr = savestack(L, firstResult); /* next call may change stack */
luaD_callhook(L, LUA_HOOKRET, -1);
if (f_isLua(L- &amp; gt; ci)) { /* Lua function? */
while ((L- &amp; gt; hookmask &amp; LUA_MASKRET) &amp; &amp; L- &amp; gt; ci- &amp; gt; tailcalls--) /* tail calls */
luaD_callhook(L, LUA_HOOKTAILRET, -1);
}
return restorestack(L, fr);
}


int luaD_poscall (lua_State *L, StkId firstResult) {
StkId res;
int wanted, i;
CallInfo *ci;
if (L- &amp; gt; hookmask &amp; LUA_MASKRET)
firstResult = callrethooks(L, firstResult);
ci = L- &amp; gt; ci--;
res = ci- &amp; gt; func; /* res == final position of 1st result */
wanted = ci- &amp; gt; nresults;
L- &amp; gt; base = (ci - 1)- &amp; gt; base; /* restore base */
L- &amp; gt; savedpc = (ci - 1)- &amp; gt; savedpc; /* restore savedpc */
/* move results to correct place */
for (i = wanted; i != 0 &amp; &amp; firstResult &amp; lt; L- &amp; gt; top; i--)
setobjs2s(L, res++, firstResult++);
while (i-- &amp; gt; 0)
setnilvalue(res++);
L- &amp; gt; top = res;
return (wanted - LUA_MULTRET); /* 0 iff wanted == LUA_MULTRET */
}


/*
** Call a function (C or Lua). The function to be called is at *func.
** The arguments are on the stack, right after the function.
** When returns, all the results are on the stack, starting at the original
** function position.
*/
void luaD_call (lua_State *L, StkId func, int nResults) {
if (++L- &amp; gt; nCcalls &amp; gt; = LUAI_MAXCCALLS) {
if (L- &amp; gt; nCcalls == LUAI_MAXCCALLS)
luaG_runerror(L, &quot; C stack overflow &quot; );
else if (L- &amp; gt; nCcalls &amp; gt; = (LUAI_MAXCCALLS + (LUAI_MAXCCALLS &amp; gt; &amp; gt; 3)))
luaD_throw(L, LUA_ERRERR); /* error while handing stack error */
}
if (luaD_precall(L, func, nResults) == PCRLUA) /* is a Lua function? */
luaV_execute(L, 1); /* call it */
L- &amp; gt; nCcalls--;
luaC_checkGC(L);
}


static void resume (lua_State *L, void *ud) {
StkId firstArg = cast(StkId, ud);
CallInfo *ci = L- &amp; gt; ci;
if (L- &amp; gt; status == 0) { /* start coroutine? */
lua_assert(ci == L- &amp; gt; base_ci &amp; &amp; firstArg &amp; gt; L- &amp; gt; base);
if (luaD_precall(L, firstArg - 1, LUA_MULTRET) != PCRLUA)
return;
}
else { /* resuming from previous yield */
lua_assert(L- &amp; gt; status == LUA_YIELD);
L- &amp; gt; status = 0;
if (!f_isLua(ci)) { /* `common' yield? */
/* finish interrupted execution of `OP_CALL' */
lua_assert(GET_OPCODE(*((ci-1)- &amp; gt; savedpc - 1)) == OP_CALL ||
GET_OPCODE(*((ci-1)- &amp; gt; savedpc - 1)) == OP_TAILCALL);
if (luaD_poscall(L, firstArg)) /* complete it... */
L- &amp; gt; top = L- &amp; gt; ci- &amp; gt; top; /* and correct top if not multiple results */
}
else /* yielded inside a hook: just continue its execution */
L- &amp; gt; base = L- &amp; gt; ci- &amp; gt; base;
}
luaV_execute(L, cast_int(L- &amp; gt; ci - L- &amp; gt; base_ci));
}


static int resume_error (lua_State *L, const char *msg) {
L- &amp; gt; top = L- &amp; gt; ci- &amp; gt; base;
setsvalue2s(L, L- &amp; gt; top, luaS_new(L, msg));
incr_top(L);
lua_unlock(L);
return LUA_ERRRUN;
}


LUA_API int lua_resume (lua_State *L, int nargs) {
int status;
lua_lock(L);
if (L- &amp; gt; status != LUA_YIELD &amp; &amp; (L- &amp; gt; status != 0 || L- &amp; gt; ci != L- &amp; gt; base_ci))
return resume_error(L, &quot; cannot resume non-suspended coroutine &quot; );
if (L- &amp; gt; nCcalls &amp; gt; = LUAI_MAXCCALLS)
return resume_error(L, &quot; C stack overflow &quot; );
luai_userstateresume(L, nargs);
lua_assert(L- &amp; gt; errfunc == 0);
L- &amp; gt; baseCcalls = ++L- &amp; gt; nCcalls;
status = luaD_rawrunprotected(L, resume, L- &amp; gt; top - nargs);
if (status != 0) { /* error? */
L- &amp; gt; status = cast_byte(status); /* mark thread as `dead' */
luaD_seterrorobj(L, status, L- &amp; gt; top);
L- &amp; gt; ci- &amp; gt; top = L- &amp; gt; top;
}
else {
lua_assert(L- &amp; gt; nCcalls == L- &amp; gt; baseCcalls);
status = L- &amp; gt; status;
}
--L- &amp; gt; nCcalls;
lua_unlock(L);
return status;
}


LUA_API int lua_yield (lua_State *L, int nresults) {
luai_userstateyield(L, nresults);
lua_lock(L);
if (L- &amp; gt; nCcalls &amp; gt; L- &amp; gt; baseCcalls)
luaG_runerror(L, &quot; attempt to yield across metamethod/C-call boundary &quot; );
L- &amp; gt; base = L- &amp; gt; top - nresults; /* protect stack slots below */
L- &amp; gt; status = LUA_YIELD;
lua_unlock(L);
return -1;
}


int luaD_pcall (lua_State *L, Pfunc func, void *u,
ptrdiff_t old_top, ptrdiff_t ef) {
int status;
unsigned short oldnCcalls = L- &amp; gt; nCcalls;
ptrdiff_t old_ci = saveci(L, L- &amp; gt; ci);
lu_byte old_allowhooks = L- &amp; gt; allowhook;
ptrdiff_t old_errfunc = L- &amp; gt; errfunc;
L- &amp; gt; errfunc = ef;
status = luaD_rawrunprotected(L, func, u);
if (status != 0) { /* an error occurred? */
StkId oldtop = restorestack(L, old_top);
luaF_close(L, oldtop); /* close eventual pending closures */
luaD_seterrorobj(L, status, oldtop);
L- &amp; gt; nCcalls = oldnCcalls;
L- &amp; gt; ci = restoreci(L, old_ci);
L- &amp; gt; base = L- &amp; gt; ci- &amp; gt; base;
L- &amp; gt; savedpc = L- &amp; gt; ci- &amp; gt; savedpc;
L- &amp; gt; allowhook = old_allowhooks;
restore_stack_limit(L);
}
L- &amp; gt; errfunc = old_errfunc;
return status;
}



/*
** Execute a protected parser.
*/
struct SParser { /* data to `f_parser' */
ZIO *z;
Mbuffer buff; /* buffer to be used by the scanner */
const char *name;
};

static void f_parser (lua_State *L, void *ud) {
int i;
Proto *tf;
Closure *cl;
struct SParser *p = cast(struct SParser *, ud);
int c = luaZ_lookahead(p- &amp; gt; z);
luaC_checkGC(L);
tf = ((c == LUA_SIGNATURE[0]) ? luaU_undump : luaY_parser)(L, p- &amp; gt; z,
&amp; p- &amp; gt; buff, p- &amp; gt; name);
cl = luaF_newLclosure(L, tf- &amp; gt; nups, hvalue(gt(L)));
cl- &amp; gt; l.p = tf;
for (i = 0; i &amp; lt; tf- &amp; gt; nups; i++) /* initialize eventual upvalues */
cl- &amp; gt; l.upvals[i] = luaF_newupval(L);
setclvalue(L, L- &amp; gt; top, cl);
incr_top(L);
}


int luaD_protectedparser (lua_State *L, ZIO *z, const char *name) {
struct SParser p;
int status;
p.z = z; p.name = name;
luaZ_initbuffer(L, &amp; p.buff);
status = luaD_pcall(L, f_parser, &amp; p, savestack(L, L- &amp; gt; top), L- &amp; gt; errfunc);
luaZ_freebuffer(L, &amp; p.buff);
return status;
}


scite228.zip > lapi.c

/*
** $Id$
** Lua API
** See Copyright Notice in lua.h
*/


#include &amp; lt; assert.h &amp; gt;
#include &amp; lt; math.h &amp; gt;
#include &amp; lt; stdarg.h &amp; gt;
#include &amp; lt; string.h &amp; gt;

#define lapi_c
#define LUA_CORE

#include &quot; lua.h &quot;

#include &quot; lapi.h &quot;
#include &quot; ldebug.h &quot;
#include &quot; ldo.h &quot;
#include &quot; lfunc.h &quot;
#include &quot; lgc.h &quot;
#include &quot; lmem.h &quot;
#include &quot; lobject.h &quot;
#include &quot; lstate.h &quot;
#include &quot; lstring.h &quot;
#include &quot; ltable.h &quot;
#include &quot; ltm.h &quot;
#include &quot; lundump.h &quot;
#include &quot; lvm.h &quot;



const char lua_ident[] =
&quot; $Lua: &quot; LUA_RELEASE &quot; &quot; LUA_COPYRIGHT &quot; $\n &quot;
&quot; $Authors: &quot; LUA_AUTHORS &quot; $\n &quot;
&quot; $URL: www.lua.org $\n &quot; ;



#define api_checknelems(L, n) api_check(L, (n) &amp; lt; = (L- &amp; gt; top - L- &amp; gt; base))

#define api_checkvalidindex(L, i) api_check(L, (i) != luaO_nilobject)

#define api_incr_top(L) {api_check(L, L- &amp; gt; top &amp; lt; L- &amp; gt; ci- &amp; gt; top); L- &amp; gt; top++;}



static TValue *index2adr (lua_State *L, int idx) {
if (idx &amp; gt; 0) {
TValue *o = L- &amp; gt; base + (idx - 1);
api_check(L, idx &amp; lt; = L- &amp; gt; ci- &amp; gt; top - L- &amp; gt; base);
if (o &amp; gt; = L- &amp; gt; top) return cast(TValue *, luaO_nilobject);
else return o;
}
else if (idx &amp; gt; LUA_REGISTRYINDEX) {
api_check(L, idx != 0 &amp; &amp; -idx &amp; lt; = L- &amp; gt; top - L- &amp; gt; base);
return L- &amp; gt; top + idx;
}
else switch (idx) { /* pseudo-indices */
case LUA_REGISTRYINDEX: return registry(L);
case LUA_ENVIRONINDEX: {
Closure *func = curr_func(L);
sethvalue(L, &amp; L- &amp; gt; env, func- &amp; gt; c.env);
return &amp; L- &amp; gt; env;
}
case LUA_GLOBALSINDEX: return gt(L);
default: {
Closure *func = curr_func(L);
idx = LUA_GLOBALSINDEX - idx;
return (idx &amp; lt; = func- &amp; gt; c.nupvalues)
? &amp; func- &amp; gt; c.upvalue[idx-1]
: cast(TValue *, luaO_nilobject);
}
}
}


static Table *getcurrenv (lua_State *L) {
if (L- &amp; gt; ci == L- &amp; gt; base_ci) /* no enclosing function? */
return hvalue(gt(L)); /* use global table as environment */
else {
Closure *func = curr_func(L);
return func- &amp; gt; c.env;
}
}


void luaA_pushobject (lua_State *L, const TValue *o) {
setobj2s(L, L- &amp; gt; top, o);
api_incr_top(L);
}


LUA_API int lua_checkstack (lua_State *L, int size) {
int res = 1;
lua_lock(L);
if (size &amp; gt; LUAI_MAXCSTACK || (L- &amp; gt; top - L- &amp; gt; base + size) &amp; gt; LUAI_MAXCSTACK)
res = 0; /* stack overflow */
else if (size &amp; gt; 0) {
luaD_checkstack(L, size);
if (L- &amp; gt; ci- &amp; gt; top &amp; lt; L- &amp; gt; top + size)
L- &amp; gt; ci- &amp; gt; top = L- &amp; gt; top + size;
}
lua_unlock(L);
return res;
}


LUA_API void lua_xmove (lua_State *from, lua_State *to, int n) {
int i;
if (from == to) return;
lua_lock(to);
api_checknelems(from, n);
api_check(from, G(from) == G(to));
api_check(from, to- &amp; gt; ci- &amp; gt; top - to- &amp; gt; top &amp; gt; = n);
from- &amp; gt; top -= n;
for (i = 0; i &amp; lt; n; i++) {
setobj2s(to, to- &amp; gt; top++, from- &amp; gt; top + i);
}
lua_unlock(to);
}


LUA_API void lua_setlevel (lua_State *from, lua_State *to) {
to- &amp; gt; nCcalls = from- &amp; gt; nCcalls;
}


LUA_API lua_CFunction lua_atpanic (lua_State *L, lua_CFunction panicf) {
lua_CFunction old;
lua_lock(L);
old = G(L)- &amp; gt; panic;
G(L)- &amp; gt; panic = panicf;
lua_unlock(L);
return old;
}


LUA_API lua_State *lua_newthread (lua_State *L) {
lua_State *L1;
lua_lock(L);
luaC_checkGC(L);
L1 = luaE_newthread(L);
setthvalue(L, L- &amp; gt; top, L1);
api_incr_top(L);
lua_unlock(L);
luai_userstatethread(L, L1);
return L1;
}



/*
** basic stack manipulation
*/


LUA_API int lua_gettop (lua_State *L) {
return cast_int(L- &amp; gt; top - L- &amp; gt; base);
}


LUA_API void lua_settop (lua_State *L, int idx) {
lua_lock(L);
if (idx &amp; gt; = 0) {
api_check(L, idx &amp; lt; = L- &amp; gt; stack_last - L- &amp; gt; base);
while (L- &amp; gt; top &amp; lt; L- &amp; gt; base + idx)
setnilvalue(L- &amp; gt; top++);
L- &amp; gt; top = L- &amp; gt; base + idx;
}
else {
api_check(L, -(idx+1) &amp; lt; = (L- &amp; gt; top - L- &amp; gt; base));
L- &amp; gt; top += idx+1; /* `subtract' index (index is negative) */
}
lua_unlock(L);
}


LUA_API void lua_remove (lua_State *L, int idx) {
StkId p;
lua_lock(L);
p = index2adr(L, idx);
api_checkvalidindex(L, p);
while (++p &amp; lt; L- &amp; gt; top) setobjs2s(L, p-1, p);
L- &amp; gt; top--;
lua_unlock(L);
}


LUA_API void lua_insert (lua_State *L, int idx) {
StkId p;
StkId q;
lua_lock(L);
p = index2adr(L, idx);
api_checkvalidindex(L, p);
for (q = L- &amp; gt; top; q &amp; gt; p; q--) setobjs2s(L, q, q-1);
setobjs2s(L, p, L- &amp; gt; top);
lua_unlock(L);
}


LUA_API void lua_replace (lua_State *L, int idx) {
StkId o;
lua_lock(L);
/* explicit test for incompatible code */
if (idx == LUA_ENVIRONINDEX &amp; &amp; L- &amp; gt; ci == L- &amp; gt; base_ci)
luaG_runerror(L, &quot; no calling environment &quot; );
api_checknelems(L, 1);
o = index2adr(L, idx);
api_checkvalidindex(L, o);
if (idx == LUA_ENVIRONINDEX) {
Closure *func = curr_func(L);
api_check(L, ttistable(L- &amp; gt; top - 1));
func- &amp; gt; c.env = hvalue(L- &amp; gt; top - 1);
luaC_barrier(L, func, L- &amp; gt; top - 1);
}
else {
setobj(L, o, L- &amp; gt; top - 1);
if (idx &amp; lt; LUA_GLOBALSINDEX) /* function upvalue? */
luaC_barrier(L, curr_func(L), L- &amp; gt; top - 1);
}
L- &amp; gt; top--;
lua_unlock(L);
}


LUA_API void lua_pushvalue (lua_State *L, int idx) {
lua_lock(L);
setobj2s(L, L- &amp; gt; top, index2adr(L, idx));
api_incr_top(L);
lua_unlock(L);
}



/*
** access functions (stack - &amp; gt; C)
*/


LUA_API int lua_type (lua_State *L, int idx) {
StkId o = index2adr(L, idx);
return (o == luaO_nilobject) ? LUA_TNONE : ttype(o);
}


LUA_API const char *lua_typename (lua_State *L, int t) {
UNUSED(L);
return (t == LUA_TNONE) ? &quot; no value &quot; : luaT_typenames[t];
}


LUA_API int lua_iscfunction (lua_State *L, int idx) {
StkId o = index2adr(L, idx);
return iscfunction(o);
}


LUA_API int lua_isnumber (lua_State *L, int idx) {
TValue n;
const TValue *o = index2adr(L, idx);
return tonumber(o, &amp; n);
}


LUA_API int lua_isstring (lua_State *L, int idx) {
int t = lua_type(L, idx);
return (t == LUA_TSTRING || t == LUA_TNUMBER);
}


LUA_API int lua_isuserdata (lua_State *L, int idx) {
const TValue *o = index2adr(L, idx);
return (ttisuserdata(o) || ttislightuserdata(o));
}


LUA_API int lua_rawequal (lua_State *L, int index1, int index2) {
StkId o1 = index2adr(L, index1);
StkId o2 = index2adr(L, index2);
return (o1 == luaO_nilobject || o2 == luaO_nilobject) ? 0
: luaO_rawequalObj(o1, o2);
}


LUA_API int lua_equal (lua_State *L, int index1, int index2) {
StkId o1, o2;
int i;
lua_lock(L); /* may call tag method */
o1 = index2adr(L, index1);
o2 = index2adr(L, index2);
i = (o1 == luaO_nilobject || o2 == luaO_nilobject) ? 0 : equalobj(L, o1, o2);
lua_unlock(L);
return i;
}


LUA_API int lua_lessthan (lua_State *L, int index1, int index2) {
StkId o1, o2;
int i;
lua_lock(L); /* may call tag method */
o1 = index2adr(L, index1);
o2 = index2adr(L, index2);
i = (o1 == luaO_nilobject || o2 == luaO_nilobject) ? 0
: luaV_lessthan(L, o1, o2);
lua_unlock(L);
return i;
}



LUA_API lua_Number lua_tonumber (lua_State *L, int idx) {
TValue n;
const TValue *o = index2adr(L, idx);
if (tonumber(o, &amp; n))
return nvalue(o);
else
return 0;
}


LUA_API lua_Integer lua_tointeger (lua_State *L, int idx) {
TValue n;
const TValue *o = index2adr(L, idx);
if (tonumber(o, &amp; n)) {
lua_Integer res;
lua_Number num = nvalue(o);
lua_number2integer(res, num);
return res;
}
else
return 0;
}


LUA_API int lua_toboolean (lua_State *L, int idx) {
const TValue *o = index2adr(L, idx);
return !l_isfalse(o);
}


LUA_API const char *lua_tolstring (lua_State *L, int idx, size_t *len) {
StkId o = index2adr(L, idx);
if (!ttisstring(o)) {
lua_lock(L); /* `luaV_tostring' may create a new string */
if (!luaV_tostring(L, o)) { /* conversion failed? */
if (len != NULL) *len = 0;
lua_unlock(L);
return NULL;
}
luaC_checkGC(L);
o = index2adr(L, idx); /* previous call may reallocate the stack */
lua_unlock(L);
}
if (len != NULL) *len = tsvalue(o)- &amp; gt; len;
return svalue(o);
}


LUA_API size_t lua_objlen (lua_State *L, int idx) {
StkId o = index2adr(L, idx);
switch (ttype(o)) {
case LUA_TSTRING: return tsvalue(o)- &amp; gt; len;
case LUA_TUSERDATA: return uvalue(o)- &amp; gt; len;
case LUA_TTABLE: return luaH_getn(hvalue(o));
case LUA_TNUMBER: {
size_t l;
lua_lock(L); /* `luaV_tostring' may create a new string */
l = (luaV_tostring(L, o) ? tsvalue(o)- &amp; gt; len : 0);
lua_unlock(L);
return l;
}
default: return 0;
}
}


LUA_API lua_CFunction lua_tocfunction (lua_State *L, int idx) {
StkId o = index2adr(L, idx);
return (!iscfunction(o)) ? NULL : clvalue(o)- &amp; gt; c.f;
}


LUA_API void *lua_touserdata (lua_State *L, int idx) {
StkId o = index2adr(L, idx);
switch (ttype(o)) {
case LUA_TUSERDATA: return (rawuvalue(o) + 1);
case LUA_TLIGHTUSERDATA: return pvalue(o);
default: return NULL;
}
}


LUA_API lua_State *lua_tothread (lua_State *L, int idx) {
StkId o = index2adr(L, idx);
return (!ttisthread(o)) ? NULL : thvalue(o);
}


LUA_API const void *lua_topointer (lua_State *L, int idx) {
StkId o = index2adr(L, idx);
switch (ttype(o)) {
case LUA_TTABLE: return hvalue(o);
case LUA_TFUNCTION: return clvalue(o);
case LUA_TTHREAD: return thvalue(o);
case LUA_TUSERDATA:
case LUA_TLIGHTUSERDATA:
return lua_touserdata(L, idx);
default: return NULL;
}
}



/*
** push functions (C - &amp; gt; stack)
*/


LUA_API void lua_pushnil (lua_State *L) {
lua_lock(L);
setnilvalue(L- &amp; gt; top);
api_incr_top(L);
lua_unlock(L);
}


LUA_API void lua_pushnumber (lua_State *L, lua_Number n) {
lua_lock(L);
setnvalue(L- &amp; gt; top, n);
api_incr_top(L);
lua_unlock(L);
}


LUA_API void lua_pushinteger (lua_State *L, lua_Integer n) {
lua_lock(L);
setnvalue(L- &amp; gt; top, cast_num(n));
api_incr_top(L);
lua_unlock(L);
}


LUA_API void lua_pushlstring (lua_State *L, const char *s, size_t len) {
lua_lock(L);
luaC_checkGC(L);
setsvalue2s(L, L- &amp; gt; top, luaS_newlstr(L, s, len));
api_incr_top(L);
lua_unlock(L);
}


LUA_API void lua_pushstring (lua_State *L, const char *s) {
if (s == NULL)
lua_pushnil(L);
else
lua_pushlstring(L, s, strlen(s));
}


LUA_API const char *lua_pushvfstring (lua_State *L, const char *fmt,
va_list argp) {
const char *ret;
lua_lock(L);
luaC_checkGC(L);
ret = luaO_pushvfstring(L, fmt, argp);
lua_unlock(L);
return ret;
}


LUA_API const char *lua_pushfstring (lua_State *L, const char *fmt, ...) {
const char *ret;
va_list argp;
lua_lock(L);
luaC_checkGC(L);
va_start(argp, fmt);
ret = luaO_pushvfstring(L, fmt, argp);
va_end(argp);
lua_unlock(L);
return ret;
}


LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) {
Closure *cl;
lua_lock(L);
luaC_checkGC(L);
api_checknelems(L, n);
cl = luaF_newCclosure(L, n, getcurrenv(L));
cl- &amp; gt; c.f = fn;
L- &amp; gt; top -= n;
while (n--)
setobj2n(L, &amp; cl- &amp; gt; c.upvalue[n], L- &amp; gt; top+n);
setclvalue(L, L- &amp; gt; top, cl);
lua_assert(iswhite(obj2gco(cl)));
api_incr_top(L);
lua_unlock(L);
}


LUA_API void lua_pushboolean (lua_State *L, int b) {
lua_lock(L);
setbvalue(L- &amp; gt; top, (b != 0)); /* ensure that true is 1 */
api_incr_top(L);
lua_unlock(L);
}


LUA_API void lua_pushlightuserdata (lua_State *L, void *p) {
lua_lock(L);
setpvalue(L- &amp; gt; top, p);
api_incr_top(L);
lua_unlock(L);
}


LUA_API int lua_pushthread (lua_State *L) {
lua_lock(L);
setthvalue(L, L- &amp; gt; top, L);
api_incr_top(L);
lua_unlock(L);
return (G(L)- &amp; gt; mainthread == L);
}



/*
** get functions (Lua - &amp; gt; stack)
*/


LUA_API void lua_gettable (lua_State *L, int idx) {
StkId t;
lua_lock(L);
t = index2adr(L, idx);
api_checkvalidindex(L, t);
luaV_gettable(L, t, L- &amp; gt; top - 1, L- &amp; gt; top - 1);
lua_unlock(L);
}


LUA_API void lua_getfield (lua_State *L, int idx, const char *k) {
StkId t;
TValue key;
lua_lock(L);
t = index2adr(L, idx);
api_checkvalidindex(L, t);
setsvalue(L, &amp; key, luaS_new(L, k));
luaV_gettable(L, t, &amp; key, L- &amp; gt; top);
api_incr_top(L);
lua_unlock(L);
}


LUA_API void lua_rawget (lua_State *L, int idx) {
StkId t;
lua_lock(L);
t = index2adr(L, idx);
api_check(L, ttistable(t));
setobj2s(L, L- &amp; gt; top - 1, luaH_get(hvalue(t), L- &amp; gt; top - 1));
lua_unlock(L);
}


LUA_API void lua_rawgeti (lua_State *L, int idx, int n) {
StkId o;
lua_lock(L);
o = index2adr(L, idx);
api_check(L, ttistable(o));
setobj2s(L, L- &amp; gt; top, luaH_getnum(hvalue(o), n));
api_incr_top(L);
lua_unlock(L);
}


LUA_API void lua_createtable (lua_State *L, int narray, int nrec) {
lua_lock(L);
luaC_checkGC(L);
sethvalue(L, L- &amp; gt; top, luaH_new(L, narray, nrec));
api_incr_top(L);
lua_unlock(L);
}


LUA_API int lua_getmetatable (lua_State *L, int objindex) {
const TValue *obj;
Table *mt = NULL;
int res;
lua_lock(L);
obj = index2adr(L, objindex);
switch (ttype(obj)) {
case LUA_TTABLE:
mt = hvalue(obj)- &amp; gt; metatable;
break;
case LUA_TUSERDATA:
mt = uvalue(obj)- &amp; gt; metatable;
break;
default:
mt = G(L)- &amp; gt; mt[ttype(obj)];
break;
}
if (mt == NULL)
res = 0;
else {
sethvalue(L, L- &amp; gt; top, mt);
api_incr_top(L);
res = 1;
}
lua_unlock(L);
return res;
}


LUA_API void lua_getfenv (lua_State *L, int idx) {
StkId o;
lua_lock(L);
o = index2adr(L, idx);
api_checkvalidindex(L, o);
switch (ttype(o)) {
case LUA_TFUNCTION:
sethvalue(L, L- &amp; gt; top, clvalue(o)- &amp; gt; c.env);
break;
case LUA_TUSERDATA:
sethvalue(L, L- &amp; gt; top, uvalue(o)- &amp; gt; env);
break;
case LUA_TTHREAD:
setobj2s(L, L- &amp; gt; top, gt(thvalue(o)));
break;
default:
setnilvalue(L- &amp; gt; top);
break;
}
api_incr_top(L);
lua_unlock(L);
}


/*
** set functions (stack - &amp; gt; Lua)
*/


LUA_API void lua_settable (lua_State *L, int idx) {
StkId t;
lua_lock(L);
api_checknelems(L, 2);
t = index2adr(L, idx);
api_checkvalidindex(L, t);
luaV_settable(L, t, L- &amp; gt; top - 2, L- &amp; gt; top - 1);
L- &amp; gt; top -= 2; /* pop index and value */
lua_unlock(L);
}


LUA_API void lua_setfield (lua_State *L, int idx, const char *k) {
StkId t;
TValue key;
lua_lock(L);
api_checknelems(L, 1);
t = index2adr(L, idx);
api_checkvalidindex(L, t);
setsvalue(L, &amp; key, luaS_new(L, k));
luaV_settable(L, t, &amp; key, L- &amp; gt; top - 1);
L- &amp; gt; top--; /* pop value */
lua_unlock(L);
}


LUA_API void lua_rawset (lua_State *L, int idx) {
StkId t;
lua_lock(L);
api_checknelems(L, 2);
t = index2adr(L, idx);
api_check(L, ttistable(t));
setobj2t(L, luaH_set(L, hvalue(t), L- &amp; gt; top-2), L- &amp; gt; top-1);
luaC_barriert(L, hvalue(t), L- &amp; gt; top-1);
L- &amp; gt; top -= 2;
lua_unlock(L);
}


LUA_API void lua_rawseti (lua_State *L, int idx, int n) {
StkId o;
lua_lock(L);
api_checknelems(L, 1);
o = index2adr(L, idx);
api_check(L, ttistable(o));
setobj2t(L, luaH_setnum(L, hvalue(o), n), L- &amp; gt; top-1);
luaC_barriert(L, hvalue(o), L- &amp; gt; top-1);
L- &amp; gt; top--;
lua_unlock(L);
}


LUA_API int lua_setmetatable (lua_State *L, int objindex) {
TValue *obj;
Table *mt;
lua_lock(L);
api_checknelems(L, 1);
obj = index2adr(L, objindex);
api_checkvalidindex(L, obj);
if (ttisnil(L- &amp; gt; top - 1))
mt = NULL;
else {
api_check(L, ttistable(L- &amp; gt; top - 1));
mt = hvalue(L- &amp; gt; top - 1);
}
switch (ttype(obj)) {
case LUA_TTABLE: {
hvalue(obj)- &amp; gt; metatable = mt;
if (mt)
luaC_objbarriert(L, hvalue(obj), mt);
break;
}
case LUA_TUSERDATA: {
uvalue(obj)- &amp; gt; metatable = mt;
if (mt)
luaC_objbarrier(L, rawuvalue(obj), mt);
break;
}
default: {
G(L)- &amp; gt; mt[ttype(obj)] = mt;
break;
}
}
L- &amp; gt; top--;
lua_unlock(L);
return 1;
}


LUA_API int lua_setfenv (lua_State *L, int idx) {
StkId o;
int res = 1;
lua_lock(L);
api_checknelems(L, 1);
o = index2adr(L, idx);
api_checkvalidindex(L, o);
api_check(L, ttistable(L- &amp; gt; top - 1));
switch (ttype(o)) {
case LUA_TFUNCTION:
clvalue(o)- &amp; gt; c.env = hvalue(L- &amp; gt; top - 1);
break;
case LUA_TUSERDATA:
uvalue(o)- &amp; gt; env = hvalue(L- &amp; gt; top - 1);
break;
case LUA_TTHREAD:
sethvalue(L, gt(thvalue(o)), hvalue(L- &amp; gt; top - 1));
break;
default:
res = 0;
break;
}
if (res) luaC_objbarrier(L, gcvalue(o), hvalue(L- &amp; gt; top - 1));
L- &amp; gt; top--;
lua_unlock(L);
return res;
}


/*
** `load' and `call' functions (run Lua code)
*/


#define adjustresults(L,nres) \
{ if (nres == LUA_MULTRET &amp; &amp; L- &amp; gt; top &amp; gt; = L- &amp; gt; ci- &amp; gt; top) L- &amp; gt; ci- &amp; gt; top = L- &amp; gt; top; }


#define checkresults(L,na,nr) \
api_check(L, (nr) == LUA_MULTRET || (L- &amp; gt; ci- &amp; gt; top - L- &amp; gt; top &amp; gt; = (nr) - (na)))


LUA_API void lua_call (lua_State *L, int nargs, int nresults) {
StkId func;
lua_lock(L);
api_checknelems(L, nargs+1);
checkresults(L, nargs, nresults);
func = L- &amp; gt; top - (nargs+1);
luaD_call(L, func, nresults);
adjustresults(L, nresults);
lua_unlock(L);
}



/*
** Execute a protected call.
*/
struct CallS { /* data to `f_call' */
StkId func;
int nresults;
};


static void f_call (lua_State *L, void *ud) {
struct CallS *c = cast(struct CallS *, ud);
luaD_call(L, c- &amp; gt; func, c- &amp; gt; nresults);
}



LUA_API int lua_pcall (lua_State *L, int nargs, int nresults, int errfunc) {
struct CallS c;
int status;
ptrdiff_t func;
lua_lock(L);
api_checknelems(L, nargs+1);
checkresults(L, nargs, nresults);
if (errfunc == 0)
func = 0;
else {
StkId o = index2adr(L, errfunc);
api_checkvalidindex(L, o);
func = savestack(L, o);
}
c.func = L- &amp; gt; top - (nargs+1); /* function to be called */
c.nresults = nresults;
status = luaD_pcall(L, f_call, &amp; c, savestack(L, c.func), func);
adjustresults(L, nresults);
lua_unlock(L);
return status;
}


/*
** Execute a protected C call.
*/
struct CCallS { /* data to `f_Ccall' */
lua_CFunction func;
void *ud;
};


static void f_Ccall (lua_State *L, void *ud) {
struct CCallS *c = cast(struct CCallS *, ud);
Closure *cl;
cl = luaF_newCclosure(L, 0, getcurrenv(L));
cl- &amp; gt; c.f = c- &amp; gt; func;
setclvalue(L, L- &amp; gt; top, cl); /* push function */
api_incr_top(L);
setpvalue(L- &amp; gt; top, c- &amp; gt; ud); /* push only argument */
api_incr_top(L);
luaD_call(L, L- &amp; gt; top - 2, 0);
}


LUA_API int lua_cpcall (lua_State *L, lua_CFunction func, void *ud) {
struct CCallS c;
int status;
lua_lock(L);
c.func = func;
c.ud = ud;
status = luaD_pcall(L, f_Ccall, &amp; c, savestack(L, L- &amp; gt; top), 0);
lua_unlock(L);
return status;
}


LUA_API int lua_load (lua_State *L, lua_Reader reader, void *data,
const char *chunkname) {
ZIO z;
int status;
lua_lock(L);
if (!chunkname) chunkname = &quot; ? &quot; ;
luaZ_init(L, &amp; z, reader, data);
status = luaD_protectedparser(L, &amp; z, chunkname);
lua_unlock(L);
return status;
}


LUA_API int lua_dump (lua_State *L, lua_Writer writer, void *data) {
int status;
TValue *o;
lua_lock(L);
api_checknelems(L, 1);
o = L- &amp; gt; top - 1;
if (isLfunction(o))
status = luaU_dump(L, clvalue(o)- &amp; gt; l.p, writer, data, 0);
else
status = 1;
lua_unlock(L);
return status;
}


LUA_API int lua_status (lua_State *L) {
return L- &amp; gt; status;
}


/*
** Garbage-collection function
*/

LUA_API int lua_gc (lua_State *L, int what, int data) {
int res = 0;
global_State *g;
lua_lock(L);
g = G(L);
switch (what) {
case LUA_GCSTOP: {
g- &amp; gt; GCthreshold = MAX_LUMEM;
break;
}
case LUA_GCRESTART: {
g- &amp; gt; GCthreshold = g- &amp; gt; totalbytes;
break;
}
case LUA_GCCOLLECT: {
luaC_fullgc(L);
break;
}
case LUA_GCCOUNT: {
/* GC values are expressed in Kbytes: #bytes/2^10 */
res = cast_int(g- &amp; gt; totalbytes &amp; gt; &amp; gt; 10);
break;
}
case LUA_GCCOUNTB: {
res = cast_int(g- &amp; gt; totalbytes &amp; 0x3ff);
break;
}
case LUA_GCSTEP: {
lu_mem a = (cast(lu_mem, data) &amp; lt; &amp; lt; 10);
if (a &amp; lt; = g- &amp; gt; totalbytes)
g- &amp; gt; GCthreshold = g- &amp; gt; totalbytes - a;
else
g- &amp; gt; GCthreshold = 0;
while (g- &amp; gt; GCthreshold &amp; lt; = g- &amp; gt; totalbytes) {
luaC_step(L);
if (g- &amp; gt; gcstate == GCSpause) { /* end of cycle? */
res = 1; /* signal it */
break;
}
}
break;
}
case LUA_GCSETPAUSE: {
res = g- &amp; gt; gcpause;
g- &amp; gt; gcpause = data;
break;
}
case LUA_GCSETSTEPMUL: {
res = g- &amp; gt; gcstepmul;
g- &amp; gt; gcstepmul = data;
break;
}
default: res = -1; /* invalid option */
}
lua_unlock(L);
return res;
}



/*
** miscellaneous functions
*/


LUA_API int lua_error (lua_State *L) {
lua_lock(L);
api_checknelems(L, 1);
luaG_errormsg(L);
lua_unlock(L);
return 0; /* to avoid warnings */
}


LUA_API int lua_next (lua_State *L, int idx) {
StkId t;
int more;
lua_lock(L);
t = index2adr(L, idx);
api_check(L, ttistable(t));
more = luaH_next(L, hvalue(t), L- &amp; gt; top - 1);
if (more) {
api_incr_top(L);
}
else /* no more elements */
L- &amp; gt; top -= 1; /* remove key */
lua_unlock(L);
return more;
}


LUA_API void lua_concat (lua_State *L, int n) {
lua_lock(L);
api_checknelems(L, n);
if (n &amp; gt; = 2) {
luaC_checkGC(L);
luaV_concat(L, n, cast_int(L- &amp; gt; top - L- &amp; gt; base) - 1);
L- &amp; gt; top -= (n-1);
}
else if (n == 0) { /* push empty string */
setsvalue2s(L, L- &amp; gt; top, luaS_newlstr(L, &quot; &quot; , 0));
api_incr_top(L);
}
/* else n == 1; nothing to do */
lua_unlock(L);
}


LUA_API lua_Alloc lua_getallocf (lua_State *L, void **ud) {
lua_Alloc f;
lua_lock(L);
if (ud) *ud = G(L)- &amp; gt; ud;
f = G(L)- &amp; gt; frealloc;
lua_unlock(L);
return f;
}


LUA_API void lua_setallocf (lua_State *L, lua_Alloc f, void *ud) {
lua_lock(L);
G(L)- &amp; gt; ud = ud;
G(L)- &amp; gt; frealloc = f;
lua_unlock(L);
}


LUA_API void *lua_newuserdata (lua_State *L, size_t size) {
Udata *u;
lua_lock(L);
luaC_checkGC(L);
u = luaS_newudata(L, size, getcurrenv(L));
setuvalue(L, L- &amp; gt; top, u);
api_incr_top(L);
lua_unlock(L);
return u + 1;
}




static const char *aux_upvalue (StkId fi, int n, TValue **val) {
Closure *f;
if (!ttisfunction(fi)) return NULL;
f = clvalue(fi);
if (f- &amp; gt; c.isC) {
if (!(1 &amp; lt; = n &amp; &amp; n &amp; lt; = f- &amp; gt; c.nupvalues)) return NULL;
*val = &amp; f- &amp; gt; c.upvalue[n-1];
return &quot; &quot; ;
}
else {
Proto *p = f- &amp; gt; l.p;
if (!(1 &amp; lt; = n &amp; &amp; n &amp; lt; = p- &amp; gt; sizeupvalues)) return NULL;
*val = f- &amp; gt; l.upvals[n-1]- &amp; gt; v;
return getstr(p- &amp; gt; upvalues[n-1]);
}
}


LUA_API const char *lua_getupvalue (lua_State *L, int funcindex, int n) {
const char *name;
TValue *val;
lua_lock(L);
name = aux_upvalue(index2adr(L, funcindex), n, &amp; val);
if (name) {
setobj2s(L, L- &amp; gt; top, val);
api_incr_top(L);
}
lua_unlock(L);
return name;
}


LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n) {
const char *name;
TValue *val;
StkId fi;
lua_lock(L);
fi = index2adr(L, funcindex);
api_checknelems(L, 1);
name = aux_upvalue(fi, n, &amp; val);
if (name) {
L- &amp; gt; top--;
setobj(L, val, L- &amp; gt; top);
luaC_barrier(L, clvalue(fi), L- &amp; gt; top);
}
lua_unlock(L);
return name;
}


scite228.zip > ltable.h

/*
** $Id$
** Lua tables (hash)
** See Copyright Notice in lua.h
*/

#ifndef ltable_h
#define ltable_h

#include &quot; lobject.h &quot;


#define gnode(t,i) ( &amp; (t)- &amp; gt; node[i])
#define gkey(n) ( &amp; (n)- &amp; gt; i_key.nk)
#define gval(n) ( &amp; (n)- &amp; gt; i_val)
#define gnext(n) ((n)- &amp; gt; i_key.nk.next)

#define key2tval(n) ( &amp; (n)- &amp; gt; i_key.tvk)


LUAI_FUNC const TValue *luaH_getnum (Table *t, int key);
LUAI_FUNC TValue *luaH_setnum (lua_State *L, Table *t, int key);
LUAI_FUNC const TValue *luaH_getstr (Table *t, TString *key);
LUAI_FUNC TValue *luaH_setstr (lua_State *L, Table *t, TString *key);
LUAI_FUNC const TValue *luaH_get (Table *t, const TValue *key);
LUAI_FUNC TValue *luaH_set (lua_State *L, Table *t, const TValue *key);
LUAI_FUNC Table *luaH_new (lua_State *L, int narray, int lnhash);
LUAI_FUNC void luaH_resizearray (lua_State *L, Table *t, int nasize);
LUAI_FUNC void luaH_free (lua_State *L, Table *t);
LUAI_FUNC int luaH_next (lua_State *L, Table *t, StkId key);
LUAI_FUNC int luaH_getn (Table *t);


#if defined(LUA_DEBUG)
LUAI_FUNC Node *luaH_mainposition (const Table *t, const TValue *key);
LUAI_FUNC int luaH_isdummy (Node *n);
#endif


#endif


scite228.zip > lapi.h

/*
** $Id$
** Auxiliary functions from Lua API
** See Copyright Notice in lua.h
*/

#ifndef lapi_h
#define lapi_h


#include &quot; lobject.h &quot;


LUAI_FUNC void luaA_pushobject (lua_State *L, const TValue *o);

#endif


scite228.zip > lcode.c

/*
** $Id$
** Code generator for Lua
** See Copyright Notice in lua.h
*/


#include &amp; lt; stdlib.h &amp; gt;

#define lcode_c
#define LUA_CORE

#include &quot; lua.h &quot;

#include &quot; lcode.h &quot;
#include &quot; ldebug.h &quot;
#include &quot; ldo.h &quot;
#include &quot; lgc.h &quot;
#include &quot; llex.h &quot;
#include &quot; lmem.h &quot;
#include &quot; lobject.h &quot;
#include &quot; lopcodes.h &quot;
#include &quot; lparser.h &quot;
#include &quot; ltable.h &quot;


#define hasjumps(e) ((e)- &amp; gt; t != (e)- &amp; gt; f)


static int isnumeral(expdesc *e) {
return (e- &amp; gt; k == VKNUM &amp; &amp; e- &amp; gt; t == NO_JUMP &amp; &amp; e- &amp; gt; f == NO_JUMP);
}


void luaK_nil (FuncState *fs, int from, int n) {
Instruction *previous;
if (fs- &amp; gt; pc &amp; gt; fs- &amp; gt; lasttarget) { /* no jumps to current position? */
if (fs- &amp; gt; pc == 0) { /* function start? */
if (from &amp; gt; = fs- &amp; gt; nactvar)
return; /* positions are already clean */
}
else {
previous = &amp; fs- &amp; gt; f- &amp; gt; code[fs- &amp; gt; pc-1];
if (GET_OPCODE(*previous) == OP_LOADNIL) {
int pfrom = GETARG_A(*previous);
int pto = GETARG_B(*previous);
if (pfrom &amp; lt; = from &amp; &amp; from &amp; lt; = pto+1) { /* can connect both? */
if (from+n-1 &amp; gt; pto)
SETARG_B(*previous, from+n-1);
return;
}
}
}
}
luaK_codeABC(fs, OP_LOADNIL, from, from+n-1, 0); /* else no optimization */
}


int luaK_jump (FuncState *fs) {
int jpc = fs- &amp; gt; jpc; /* save list of jumps to here */
int j;
fs- &amp; gt; jpc = NO_JUMP;
j = luaK_codeAsBx(fs, OP_JMP, 0, NO_JUMP);
luaK_concat(fs, &amp; j, jpc); /* keep them on hold */
return j;
}


void luaK_ret (FuncState *fs, int first, int nret) {
luaK_codeABC(fs, OP_RETURN, first, nret+1, 0);
}


static int condjump (FuncState *fs, OpCode op, int A, int B, int C) {
luaK_codeABC(fs, op, A, B, C);
return luaK_jump(fs);
}


static void fixjump (FuncState *fs, int pc, int dest) {
Instruction *jmp = &amp; fs- &amp; gt; f- &amp; gt; code[pc];
int offset = dest-(pc+1);
lua_assert(dest != NO_JUMP);
if (abs(offset) &amp; gt; MAXARG_sBx)
luaX_syntaxerror(fs- &amp; gt; ls, &quot; control structure too long &quot; );
SETARG_sBx(*jmp, offset);
}


/*
** returns current `pc' and marks it as a jump target (to avoid wrong
** optimizations with consecutive instructions not in the same basic block).
*/
int luaK_getlabel (FuncState *fs) {
fs- &amp; gt; lasttarget = fs- &amp; gt; pc;
return fs- &amp; gt; pc;
}


static int getjump (FuncState *fs, int pc) {
int offset = GETARG_sBx(fs- &amp; gt; f- &amp; gt; code[pc]);
if (offset == NO_JUMP) /* point to itself represents end of list */
return NO_JUMP; /* end of list */
else
return (pc+1)+offset; /* turn offset into absolute position */
}


static Instruction *getjumpcontrol (FuncState *fs, int pc) {
Instruction *pi = &amp; fs- &amp; gt; f- &amp; gt; code[pc];
if (pc &amp; gt; = 1 &amp; &amp; testTMode(GET_OPCODE(*(pi-1))))
return pi-1;
else
return pi;
}


/*
** check whether list has any jump that do not produce a value
** (or produce an inverted value)
*/
static int need_value (FuncState *fs, int list) {
for (; list != NO_JUMP; list = getjump(fs, list)) {
Instruction i = *getjumpcontrol(fs, list);
if (GET_OPCODE(i) != OP_TESTSET) return 1;
}
return 0; /* not found */
}


static int patchtestreg (FuncState *fs, int node, int reg) {
Instruction *i = getjumpcontrol(fs, node);
if (GET_OPCODE(*i) != OP_TESTSET)
return 0; /* cannot patch other instructions */
if (reg != NO_REG &amp; &amp; reg != GETARG_B(*i))
SETARG_A(*i, reg);
else /* no register to put value or register already has the value */
*i = CREATE_ABC(OP_TEST, GETARG_B(*i), 0, GETARG_C(*i));

return 1;
}


static void removevalues (FuncState *fs, int list) {
for (; list != NO_JUMP; list = getjump(fs, list))
patchtestreg(fs, list, NO_REG);
}


static void patchlistaux (FuncState *fs, int list, int vtarget, int reg,
int dtarget) {
while (list != NO_JUMP) {
int next = getjump(fs, list);
if (patchtestreg(fs, list, reg))
fixjump(fs, list, vtarget);
else
fixjump(fs, list, dtarget); /* jump to default target */
list = next;
}
}


static void dischargejpc (FuncState *fs) {
patchlistaux(fs, fs- &amp; gt; jpc, fs- &amp; gt; pc, NO_REG, fs- &amp; gt; pc);
fs- &amp; gt; jpc = NO_JUMP;
}


void luaK_patchlist (FuncState *fs, int list, int target) {
if (target == fs- &amp; gt; pc)
luaK_patchtohere(fs, list);
else {
lua_assert(target &amp; lt; fs- &amp; gt; pc);
patchlistaux(fs, list, target, NO_REG, target);
}
}


void luaK_patchtohere (FuncState *fs, int list) {
luaK_getlabel(fs);
luaK_concat(fs, &amp; fs- &amp; gt; jpc, list);
}


void luaK_concat (FuncState *fs, int *l1, int l2) {
if (l2 == NO_JUMP) return;
else if (*l1 == NO_JUMP)
*l1 = l2;
else {
int list = *l1;
int next;
while ((next = getjump(fs, list)) != NO_JUMP) /* find last element */
list = next;
fixjump(fs, list, l2);
}
}


void luaK_checkstack (FuncState *fs, int n) {
int newstack = fs- &amp; gt; freereg + n;
if (newstack &amp; gt; fs- &amp; gt; f- &amp; gt; maxstacksize) {
if (newstack &amp; gt; = MAXSTACK)
luaX_syntaxerror(fs- &amp; gt; ls, &quot; function or expression too complex &quot; );
fs- &amp; gt; f- &amp; gt; maxstacksize = cast_byte(newstack);
}
}


void luaK_reserveregs (FuncState *fs, int n) {
luaK_checkstack(fs, n);
fs- &amp; gt; freereg += n;
}


static void freereg (FuncState *fs, int reg) {
if (!ISK(reg) &amp; &amp; reg &amp; gt; = fs- &amp; gt; nactvar) {
fs- &amp; gt; freereg--;
lua_assert(reg == fs- &amp; gt; freereg);
}
}


static void freeexp (FuncState *fs, expdesc *e) {
if (e- &amp; gt; k == VNONRELOC)
freereg(fs, e- &amp; gt; u.s.info);
}


static int addk (FuncState *fs, TValue *k, TValue *v) {
lua_State *L = fs- &amp; gt; L;
TValue *idx = luaH_set(L, fs- &amp; gt; h, k);
Proto *f = fs- &amp; gt; f;
int oldsize = f- &amp; gt; sizek;
if (ttisnumber(idx)) {
lua_assert(luaO_rawequalObj( &amp; fs- &amp; gt; f- &amp; gt; k[cast_int(nvalue(idx))], v));
return cast_int(nvalue(idx));
}
else { /* constant not found; create a new entry */
setnvalue(idx, cast_num(fs- &amp; gt; nk));
luaM_growvector(L, f- &amp; gt; k, fs- &amp; gt; nk, f- &amp; gt; sizek, TValue,
MAXARG_Bx, &quot; constant table overflow &quot; );
while (oldsize &amp; lt; f- &amp; gt; sizek) setnilvalue( &amp; f- &amp; gt; k[oldsize++]);
setobj(L, &amp; f- &amp; gt; k[fs- &amp; gt; nk], v);
luaC_barrier(L, f, v);
return fs- &amp; gt; nk++;
}
}


int luaK_stringK (FuncState *fs, TString *s) {
TValue o;
setsvalue(fs- &amp; gt; L, &amp; o, s);
return addk(fs, &amp; o, &amp; o);
}


int luaK_numberK (FuncState *fs, lua_Number r) {
TValue o;
setnvalue( &amp; o, r);
return addk(fs, &amp; o, &amp; o);
}


static int boolK (FuncState *fs, int b) {
TValue o;
setbvalue( &amp; o, b);
return addk(fs, &amp; o, &amp; o);
}


static int nilK (FuncState *fs) {
TValue k, v;
setnilvalue( &amp; v);
/* cannot use nil as key; instead use table itself to represent nil */
sethvalue(fs- &amp; gt; L, &amp; k, fs- &amp; gt; h);
return addk(fs, &amp; k, &amp; v);
}


void luaK_setreturns (FuncState *fs, expdesc *e, int nresults) {
if (e- &amp; gt; k == VCALL) { /* expression is an open function call? */
SETARG_C(getcode(fs, e), nresults+1);
}
else if (e- &amp; gt; k == VVARARG) {
SETARG_B(getcode(fs, e), nresults+1);
SETARG_A(getcode(fs, e), fs- &amp; gt; freereg);
luaK_reserveregs(fs, 1);
}
}


void luaK_setoneret (FuncState *fs, expdesc *e) {
if (e- &amp; gt; k == VCALL) { /* expression is an open function call? */
e- &amp; gt; k = VNONRELOC;
e- &amp; gt; u.s.info = GETARG_A(getcode(fs, e));
}
else if (e- &amp; gt; k == VVARARG) {
SETARG_B(getcode(fs, e), 2);
e- &amp; gt; k = VRELOCABLE; /* can relocate its simple result */
}
}


void luaK_dischargevars (FuncState *fs, expdesc *e) {
switch (e- &amp; gt; k) {
case VLOCAL: {
e- &amp; gt; k = VNONRELOC;
break;
}
case VUPVAL: {
e- &amp; gt; u.s.info = luaK_codeABC(fs, OP_GETUPVAL, 0, e- &amp; gt; u.s.info, 0);
e- &amp; gt; k = VRELOCABLE;
break;
}
case VGLOBAL: {
e- &amp; gt; u.s.info = luaK_codeABx(fs, OP_GETGLOBAL, 0, e- &amp; gt; u.s.info);
e- &amp; gt; k = VRELOCABLE;
break;
}
case VINDEXED: {
freereg(fs, e- &amp; gt; u.s.aux);
freereg(fs, e- &amp; gt; u.s.info);
e- &amp; gt; u.s.info = luaK_codeABC(fs, OP_GETTABLE, 0, e- &amp; gt; u.s.info, e- &amp; gt; u.s.aux);
e- &amp; gt; k = VRELOCABLE;
break;
}
case VVARARG:
case VCALL: {
luaK_setoneret(fs, e);
break;
}
default: break; /* there is one value available (somewhere) */
}
}


static int code_label (FuncState *fs, int A, int b, int jump) {
luaK_getlabel(fs); /* those instructions may be jump targets */
return luaK_codeABC(fs, OP_LOADBOOL, A, b, jump);
}


static void discharge2reg (FuncState *fs, expdesc *e, int reg) {
luaK_dischargevars(fs, e);
switch (e- &amp; gt; k) {
case VNIL: {
luaK_nil(fs, reg, 1);
break;
}
case VFALSE: case VTRUE: {
luaK_codeABC(fs, OP_LOADBOOL, reg, e- &amp; gt; k == VTRUE, 0);
break;
}
case VK: {
luaK_codeABx(fs, OP_LOADK, reg, e- &amp; gt; u.s.info);
break;
}
case VKNUM: {
luaK_codeABx(fs, OP_LOADK, reg, luaK_numberK(fs, e- &amp; gt; u.nval));
break;
}
case VRELOCABLE: {
Instruction *pc = &amp; getcode(fs, e);
SETARG_A(*pc, reg);
break;
}
case VNONRELOC: {
if (reg != e- &amp; gt; u.s.info)
luaK_codeABC(fs, OP_MOVE, reg, e- &amp; gt; u.s.info, 0);
break;
}
default: {
lua_assert(e- &amp; gt; k == VVOID || e- &amp; gt; k == VJMP);
return; /* nothing to do... */
}
}
e- &amp; gt; u.s.info = reg;
e- &amp; gt; k = VNONRELOC;
}


static void discharge2anyreg (FuncState *fs, expdesc *e) {
if (e- &amp; gt; k != VNONRELOC) {
luaK_reserveregs(fs, 1);
discharge2reg(fs, e, fs- &amp; gt; freereg-1);
}
}


static void exp2reg (FuncState *fs, expdesc *e, int reg) {
discharge2reg(fs, e, reg);
if (e- &amp; gt; k == VJMP)
luaK_concat(fs, &amp; e- &amp; gt; t, e- &amp; gt; u.s.info); /* put this jump in `t' list */
if (hasjumps(e)) {
int final; /* position after whole expression */
int p_f = NO_JUMP; /* position of an eventual LOAD false */
int p_t = NO_JUMP; /* position of an eventual LOAD true */
if (need_value(fs, e- &amp; gt; t) || need_value(fs, e- &amp; gt; f)) {
int fj = (e- &amp; gt; k == VJMP) ? NO_JUMP : luaK_jump(fs);
p_f = code_label(fs, reg, 0, 1);
p_t = code_label(fs, reg, 1, 0);
luaK_patchtohere(fs, fj);
}
final = luaK_getlabel(fs);
patchlistaux(fs, e- &amp; gt; f, final, reg, p_f);
patchlistaux(fs, e- &amp; gt; t, final, reg, p_t);
}
e- &amp; gt; f = e- &amp; gt; t = NO_JUMP;
e- &amp; gt; u.s.info = reg;
e- &amp; gt; k = VNONRELOC;
}


void luaK_exp2nextreg (FuncState *fs, expdesc *e) {
luaK_dischargevars(fs, e);
freeexp(fs, e);
luaK_reserveregs(fs, 1);
exp2reg(fs, e, fs- &amp; gt; freereg - 1);
}


int luaK_exp2anyreg (FuncState *fs, expdesc *e) {
luaK_dischargevars(fs, e);
if (e- &amp; gt; k == VNONRELOC) {
if (!hasjumps(e)) return e- &amp; gt; u.s.info; /* exp is already in a register */
if (e- &amp; gt; u.s.info &amp; gt; = fs- &amp; gt; nactvar) { /* reg. is not a local? */
exp2reg(fs, e, e- &amp; gt; u.s.info); /* put value on it */
return e- &amp; gt; u.s.info;
}
}
luaK_exp2nextreg(fs, e); /* default */
return e- &amp; gt; u.s.info;
}


void luaK_exp2val (FuncState *fs, expdesc *e) {
if (hasjumps(e))
luaK_exp2anyreg(fs, e);
else
luaK_dischargevars(fs, e);
}


int luaK_exp2RK (FuncState *fs, expdesc *e) {
luaK_exp2val(fs, e);
switch (e- &amp; gt; k) {
case VKNUM:
case VTRUE:
case VFALSE:
case VNIL: {
if (fs- &amp; gt; nk &amp; lt; = MAXINDEXRK) { /* constant fit in RK operand? */
e- &amp; gt; u.s.info = (e- &amp; gt; k == VNIL) ? nilK(fs) :
(e- &amp; gt; k == VKNUM) ? luaK_numberK(fs, e- &amp; gt; u.nval) :
boolK(fs, (e- &amp; gt; k == VTRUE));
e- &amp; gt; k = VK;
return RKASK(e- &amp; gt; u.s.info);
}
else break;
}
case VK: {
if (e- &amp; gt; u.s.info &amp; lt; = MAXINDEXRK) /* constant fit in argC? */
return RKASK(e- &amp; gt; u.s.info);
else break;
}
default: break;
}
/* not a constant in the right range: put it in a register */
return luaK_exp2anyreg(fs, e);
}


void luaK_storevar (FuncState *fs, expdesc *var, expdesc *ex) {
switch (var- &amp; gt; k) {
case VLOCAL: {
freeexp(fs, ex);
exp2reg(fs, ex, var- &amp; gt; u.s.info);
return;
}
case VUPVAL: {
int e = luaK_exp2anyreg(fs, ex);
luaK_codeABC(fs, OP_SETUPVAL, e, var- &amp; gt; u.s.info, 0);
break;
}
case VGLOBAL: {
int e = luaK_exp2anyreg(fs, ex);
luaK_codeABx(fs, OP_SETGLOBAL, e, var- &amp; gt; u.s.info);
break;
}
case VINDEXED: {
int e = luaK_exp2RK(fs, ex);
luaK_codeABC(fs, OP_SETTABLE, var- &amp; gt; u.s.info, var- &amp; gt; u.s.aux, e);
break;
}
default: {
lua_assert(0); /* invalid var kind to store */
break;
}
}
freeexp(fs, ex);
}


void luaK_self (FuncState *fs, expdesc *e, expdesc *key) {
int func;
luaK_exp2anyreg(fs, e);
freeexp(fs, e);
func = fs- &amp; gt; freereg;
luaK_reserveregs(fs, 2);
luaK_codeABC(fs, OP_SELF, func, e- &amp; gt; u.s.info, luaK_exp2RK(fs, key));
freeexp(fs, key);
e- &amp; gt; u.s.info = func;
e- &amp; gt; k = VNONRELOC;
}


static void invertjump (FuncState *fs, expdesc *e) {
Instruction *pc = getjumpcontrol(fs, e- &amp; gt; u.s.info);
lua_assert(testTMode(GET_OPCODE(*pc)) &amp; &amp; GET_OPCODE(*pc) != OP_TESTSET &amp; &amp;
GET_OPCODE(*pc) != OP_TEST);
SETARG_A(*pc, !(GETARG_A(*pc)));
}


static int jumponcond (FuncState *fs, expdesc *e, int cond) {
if (e- &amp; gt; k == VRELOCABLE) {
Instruction ie = getcode(fs, e);
if (GET_OPCODE(ie) == OP_NOT) {
fs- &amp; gt; pc--; /* remove previous OP_NOT */
return condjump(fs, OP_TEST, GETARG_B(ie), 0, !cond);
}
/* else go through */
}
discharge2anyreg(fs, e);
freeexp(fs, e);
return condjump(fs, OP_TESTSET, NO_REG, e- &amp; gt; u.s.info, cond);
}


void luaK_goiftrue (FuncState *fs, expdesc *e) {
int pc; /* pc of last jump */
luaK_dischargevars(fs, e);
switch (e- &amp; gt; k) {
case VK: case VKNUM: case VTRUE: {
pc = NO_JUMP; /* always true; do nothing */
break;
}
case VFALSE: {
pc = luaK_jump(fs); /* always jump */
break;
}
case VJMP: {
invertjump(fs, e);
pc = e- &amp; gt; u.s.info;
break;
}
default: {
pc = jumponcond(fs, e, 0);
break;
}
}
luaK_concat(fs, &amp; e- &amp; gt; f, pc); /* insert last jump in `f' list */
luaK_patchtohere(fs, e- &amp; gt; t);
e- &amp; gt; t = NO_JUMP;
}


static void luaK_goiffalse (FuncState *fs, expdesc *e) {
int pc; /* pc of last jump */
luaK_dischargevars(fs, e);
switch (e- &amp; gt; k) {
case VNIL: case VFALSE: {
pc = NO_JUMP; /* always false; do nothing */
break;
}
case VTRUE: {
pc = luaK_jump(fs); /* always jump */
break;
}
case VJMP: {
pc = e- &amp; gt; u.s.info;
break;
}
default: {
pc = jumponcond(fs, e, 1);
break;
}
}
luaK_concat(fs, &amp; e- &amp; gt; t, pc); /* insert last jump in `t' list */
luaK_patchtohere(fs, e- &amp; gt; f);
e- &amp; gt; f = NO_JUMP;
}


static void codenot (FuncState *fs, expdesc *e) {
luaK_dischargevars(fs, e);
switch (e- &amp; gt; k) {
case VNIL: case VFALSE: {
e- &amp; gt; k = VTRUE;
break;
}
case VK: case VKNUM: case VTRUE: {
e- &amp; gt; k = VFALSE;
break;
}
case VJMP: {
invertjump(fs, e);
break;
}
case VRELOCABLE:
case VNONRELOC: {
discharge2anyreg(fs, e);
freeexp(fs, e);
e- &amp; gt; u.s.info = luaK_codeABC(fs, OP_NOT, 0, e- &amp; gt; u.s.info, 0);
e- &amp; gt; k = VRELOCABLE;
break;
}
default: {
lua_assert(0); /* cannot happen */
break;
}
}
/* interchange true and false lists */
{ int temp = e- &amp; gt; f; e- &amp; gt; f = e- &amp; gt; t; e- &amp; gt; t = temp; }
removevalues(fs, e- &amp; gt; f);
removevalues(fs, e- &amp; gt; t);
}


void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k) {
t- &amp; gt; u.s.aux = luaK_exp2RK(fs, k);
t- &amp; gt; k = VINDEXED;
}


static int constfolding (OpCode op, expdesc *e1, expdesc *e2) {
lua_Number v1, v2, r;
if (!isnumeral(e1) || !isnumeral(e2)) return 0;
v1 = e1- &amp; gt; u.nval;
v2 = e2- &amp; gt; u.nval;
switch (op) {
case OP_ADD: r = luai_numadd(v1, v2); break;
case OP_SUB: r = luai_numsub(v1, v2); break;
case OP_MUL: r = luai_nummul(v1, v2); break;
case OP_DIV:
if (v2 == 0) return 0; /* do not attempt to divide by 0 */
r = luai_numdiv(v1, v2); break;
case OP_MOD:
if (v2 == 0) return 0; /* do not attempt to divide by 0 */
r = luai_nummod(v1, v2); break;
case OP_POW: r = luai_numpow(v1, v2); break;
case OP_UNM: r = luai_numunm(v1); break;
case OP_LEN: return 0; /* no constant folding for 'len' */
default: lua_assert(0); r = 0; break;
}
if (luai_numisnan(r)) return 0; /* do not attempt to produce NaN */
e1- &amp; gt; u.nval = r;
return 1;
}


static void codearith (FuncState *fs, OpCode op, expdesc *e1, expdesc *e2) {
if (constfolding(op, e1, e2))
return;
else {
int o2 = (op != OP_UNM &amp; &amp; op != OP_LEN) ? luaK_exp2RK(fs, e2) : 0;
int o1 = luaK_exp2RK(fs, e1);
if (o1 &amp; gt; o2) {
freeexp(fs, e1);
freeexp(fs, e2);
}
else {
freeexp(fs, e2);
freeexp(fs, e1);
}
e1- &amp; gt; u.s.info = luaK_codeABC(fs, op, 0, o1, o2);
e1- &amp; gt; k = VRELOCABLE;
}
}


static void codecomp (FuncState *fs, OpCode op, int cond, expdesc *e1,
expdesc *e2) {
int o1 = luaK_exp2RK(fs, e1);
int o2 = luaK_exp2RK(fs, e2);
freeexp(fs, e2);
freeexp(fs, e1);
if (cond == 0 &amp; &amp; op != OP_EQ) {
int temp; /* exchange args to replace by ` &amp; lt; ' or ` &amp; lt; =' */
temp = o1; o1 = o2; o2 = temp; /* o1 &amp; lt; == &amp; gt; o2 */
cond = 1;
}
e1- &amp; gt; u.s.info = condjump(fs, op, cond, o1, o2);
e1- &amp; gt; k = VJMP;
}


void luaK_prefix (FuncState *fs, UnOpr op, expdesc *e) {
expdesc e2;
e2.t = e2.f = NO_JUMP; e2.k = VKNUM; e2.u.nval = 0;
switch (op) {
case OPR_MINUS: {
if (!isnumeral(e))
luaK_exp2anyreg(fs, e); /* cannot operate on non-numeric constants */
codearith(fs, OP_UNM, e, &amp; e2);
break;
}
case OPR_NOT: codenot(fs, e); break;
case OPR_LEN: {
luaK_exp2anyreg(fs, e); /* cannot operate on constants */
codearith(fs, OP_LEN, e, &amp; e2);
break;
}
default: lua_assert(0);
}
}


void luaK_infix (FuncState *fs, BinOpr op, expdesc *v) {
switch (op) {
case OPR_AND: {
luaK_goiftrue(fs, v);
break;
}
case OPR_OR: {
luaK_goiffalse(fs, v);
break;
}
case OPR_CONCAT: {
luaK_exp2nextreg(fs, v); /* operand must be on the `stack' */
break;
}
case OPR_ADD: case OPR_SUB: case OPR_MUL: case OPR_DIV:
case OPR_MOD: case OPR_POW: {
if (!isnumeral(v)) luaK_exp2RK(fs, v);
break;
}
default: {
luaK_exp2RK(fs, v);
break;
}
}
}


void luaK_posfix (FuncState *fs, BinOpr op, expdesc *e1, expdesc *e2) {
switch (op) {
case OPR_AND: {
lua_assert(e1- &amp; gt; t == NO_JUMP); /* list must be closed */
luaK_dischargevars(fs, e2);
luaK_concat(fs, &amp; e2- &amp; gt; f, e1- &amp; gt; f);
*e1 = *e2;
break;
}
case OPR_OR: {
lua_assert(e1- &amp; gt; f == NO_JUMP); /* list must be closed */
luaK_dischargevars(fs, e2);
luaK_concat(fs, &amp; e2- &amp; gt; t, e1- &amp; gt; t);
*e1 = *e2;
break;
}
case OPR_CONCAT: {
luaK_exp2val(fs, e2);
if (e2- &amp; gt; k == VRELOCABLE &amp; &amp; GET_OPCODE(getcode(fs, e2)) == OP_CONCAT) {
lua_assert(e1- &amp; gt; u.s.info == GETARG_B(getcode(fs, e2))-1);
freeexp(fs, e1);
SETARG_B(getcode(fs, e2), e1- &amp; gt; u.s.info);
e1- &amp; gt; k = VRELOCABLE; e1- &amp; gt; u.s.info = e2- &amp; gt; u.s.info;
}
else {
luaK_exp2nextreg(fs, e2); /* operand must be on the 'stack' */
codearith(fs, OP_CONCAT, e1, e2);
}
break;
}
case OPR_ADD: codearith(fs, OP_ADD, e1, e2); break;
case OPR_SUB: codearith(fs, OP_SUB, e1, e2); break;
case OPR_MUL: codearith(fs, OP_MUL, e1, e2); break;
case OPR_DIV: codearith(fs, OP_DIV, e1, e2); break;
case OPR_MOD: codearith(fs, OP_MOD, e1, e2); break;
case OPR_POW: codearith(fs, OP_POW, e1, e2); break;
case OPR_EQ: codecomp(fs, OP_EQ, 1, e1, e2); break;
case OPR_NE: codecomp(fs, OP_EQ, 0, e1, e2); break;
case OPR_LT: codecomp(fs, OP_LT, 1, e1, e2); break;
case OPR_LE: codecomp(fs, OP_LE, 1, e1, e2); break;
case OPR_GT: codecomp(fs, OP_LT, 0, e1, e2); break;
case OPR_GE: codecomp(fs, OP_LE, 0, e1, e2); break;
default: lua_assert(0);
}
}


void luaK_fixline (FuncState *fs, int line) {
fs- &amp; gt; f- &amp; gt; lineinfo[fs- &amp; gt; pc - 1] = line;
}


static int luaK_code (FuncState *fs, Instruction i, int line) {
Proto *f = fs- &amp; gt; f;
dischargejpc(fs); /* `pc' will change */
/* put new instruction in code array */
luaM_growvector(fs- &amp; gt; L, f- &amp; gt; code, fs- &amp; gt; pc, f- &amp; gt; sizecode, Instruction,
MAX_INT, &quot; code size overflow &quot; );
f- &amp; gt; code[fs- &amp; gt; pc] = i;
/* save corresponding line information */
luaM_growvector(fs- &amp; gt; L, f- &amp; gt; lineinfo, fs- &amp; gt; pc, f- &amp; gt; sizelineinfo, int,
MAX_INT, &quot; code size overflow &quot; );
f- &amp; gt; lineinfo[fs- &amp; gt; pc] = line;
return fs- &amp; gt; pc++;
}


int luaK_codeABC (FuncState *fs, OpCode o, int a, int b, int c) {
lua_assert(getOpMode(o) == iABC);
lua_assert(getBMode(o) != OpArgN || b == 0);
lua_assert(getCMode(o) != OpArgN || c == 0);
return luaK_code(fs, CREATE_ABC(o, a, b, c), fs- &amp; gt; ls- &amp; gt; lastline);
}


int luaK_codeABx (FuncState *fs, OpCode o, int a, unsigned int bc) {
lua_assert(getOpMode(o) == iABx || getOpMode(o) == iAsBx);
lua_assert(getCMode(o) == OpArgN);
return luaK_code(fs, CREATE_ABx(o, a, bc), fs- &amp; gt; ls- &amp; gt; lastline);
}


void luaK_setlist (FuncState *fs, int base, int nelems, int tostore) {
int c = (nelems - 1)/LFIELDS_PER_FLUSH + 1;
int b = (tostore == LUA_MULTRET) ? 0 : tostore;
lua_assert(tostore != 0);
if (c &amp; lt; = MAXARG_C)
luaK_codeABC(fs, OP_SETLIST, base, b, c);
else {
luaK_codeABC(fs, OP_SETLIST, base, b, 0);
luaK_code(fs, cast(Instruction, c), fs- &amp; gt; ls- &amp; gt; lastline);
}
fs- &amp; gt; freereg = base + 1; /* free registers with list values */
}


scite228.zip > lmem.h

/*
** $Id$
** Interface to Memory Manager
** See Copyright Notice in lua.h
*/

#ifndef lmem_h
#define lmem_h


#include &amp; lt; stddef.h &amp; gt;

#include &quot; llimits.h &quot;
#include &quot; lua.h &quot;

#define MEMERRMSG &quot; not enough memory &quot;


#define luaM_reallocv(L,b,on,n,e) \
((cast(size_t, (n)+1) &amp; lt; = MAX_SIZET/(e)) ? /* +1 to avoid warnings */ \
luaM_realloc_(L, (b), (on)*(e), (n)*(e)) : \
luaM_toobig(L))

#define luaM_freemem(L, b, s) luaM_realloc_(L, (b), (s), 0)
#define luaM_free(L, b) luaM_realloc_(L, (b), sizeof(*(b)), 0)
#define luaM_freearray(L, b, n, t) luaM_reallocv(L, (b), n, 0, sizeof(t))

#define luaM_malloc(L,t) luaM_realloc_(L, NULL, 0, (t))
#define luaM_new(L,t) cast(t *, luaM_malloc(L, sizeof(t)))
#define luaM_newvector(L,n,t) \
cast(t *, luaM_reallocv(L, NULL, 0, n, sizeof(t)))

#define luaM_growvector(L,v,nelems,size,t,limit,e) \
if ((nelems)+1 &amp; gt; (size)) \
((v)=cast(t *, luaM_growaux_(L,v, &amp; (size),sizeof(t),limit,e)))

#define luaM_reallocvector(L, v,oldn,n,t) \
((v)=cast(t *, luaM_reallocv(L, v, oldn, n, sizeof(t))))


LUAI_FUNC void *luaM_realloc_ (lua_State *L, void *block, size_t oldsize,
size_t size);
LUAI_FUNC void *luaM_toobig (lua_State *L);
LUAI_FUNC void *luaM_growaux_ (lua_State *L, void *block, int *size,
size_t size_elem, int limit,
const char *errormsg);

#endif


scite228.zip > ltm.c

/*
** $Id$
** Tag methods
** See Copyright Notice in lua.h
*/


#include &amp; lt; string.h &amp; gt;

#define ltm_c
#define LUA_CORE

#include &quot; lua.h &quot;

#include &quot; lobject.h &quot;
#include &quot; lstate.h &quot;
#include &quot; lstring.h &quot;
#include &quot; ltable.h &quot;
#include &quot; ltm.h &quot;



const char *const luaT_typenames[] = {
&quot; nil &quot; , &quot; boolean &quot; , &quot; userdata &quot; , &quot; number &quot; ,
&quot; string &quot; , &quot; table &quot; , &quot; function &quot; , &quot; userdata &quot; , &quot; thread &quot; ,
&quot; proto &quot; , &quot; upval &quot;
};


void luaT_init (lua_State *L) {
static const char *const luaT_eventname[] = { /* ORDER TM */
&quot; __index &quot; , &quot; __newindex &quot; ,
&quot; __gc &quot; , &quot; __mode &quot; , &quot; __eq &quot; ,
&quot; __add &quot; , &quot; __sub &quot; , &quot; __mul &quot; , &quot; __div &quot; , &quot; __mod &quot; ,
&quot; __pow &quot; , &quot; __unm &quot; , &quot; __len &quot; , &quot; __lt &quot; , &quot; __le &quot; ,
&quot; __concat &quot; , &quot; __call &quot;
};
int i;
for (i=0; i &amp; lt; TM_N; i++) {
G(L)- &amp; gt; tmname[i] = luaS_new(L, luaT_eventname[i]);
luaS_fix(G(L)- &amp; gt; tmname[i]); /* never collect these names */
}
}


/*
** function to be used with macro &quot; fasttm &quot; : optimized for absence of
** tag methods
*/
const TValue *luaT_gettm (Table *events, TMS event, TString *ename) {
const TValue *tm = luaH_getstr(events, ename);
lua_assert(event &amp; lt; = TM_EQ);
if (ttisnil(tm)) { /* no tag method? */
events- &amp; gt; flags |= cast_byte(1u &amp; lt; &amp; lt; event); /* cache this fact */
return NULL;
}
else return tm;
}


const TValue *luaT_gettmbyobj (lua_State *L, const TValue *o, TMS event) {
Table *mt;
switch (ttype(o)) {
case LUA_TTABLE:
mt = hvalue(o)- &amp; gt; metatable;
break;
case LUA_TUSERDATA:
mt = uvalue(o)- &amp; gt; metatable;
break;
default:
mt = G(L)- &amp; gt; mt[ttype(o)];
}
return (mt ? luaH_getstr(mt, G(L)- &amp; gt; tmname[event]) : luaO_nilobject);
}


scite228.zip > lgc.c

/*
** $Id$
** Garbage Collector
** See Copyright Notice in lua.h
*/

#include &amp; lt; string.h &amp; gt;

#define lgc_c
#define LUA_CORE

#include &quot; lua.h &quot;

#include &quot; ldebug.h &quot;
#include &quot; ldo.h &quot;
#include &quot; lfunc.h &quot;
#include &quot; lgc.h &quot;
#include &quot; lmem.h &quot;
#include &quot; lobject.h &quot;
#include &quot; lstate.h &quot;
#include &quot; lstring.h &quot;
#include &quot; ltable.h &quot;
#include &quot; ltm.h &quot;


#define GCSTEPSIZE 1024u
#define GCSWEEPMAX 40
#define GCSWEEPCOST 10
#define GCFINALIZECOST 100


#define maskmarks cast_byte(~(bitmask(BLACKBIT)|WHITEBITS))

#define makewhite(g,x) \
((x)- &amp; gt; gch.marked = cast_byte(((x)- &amp; gt; gch.marked &amp; maskmarks) | luaC_white(g)))

#define white2gray(x) reset2bits((x)- &amp; gt; gch.marked, WHITE0BIT, WHITE1BIT)
#define black2gray(x) resetbit((x)- &amp; gt; gch.marked, BLACKBIT)

#define stringmark(s) reset2bits((s)- &amp; gt; tsv.marked, WHITE0BIT, WHITE1BIT)


#define isfinalized(u) testbit((u)- &amp; gt; marked, FINALIZEDBIT)
#define markfinalized(u) l_setbit((u)- &amp; gt; marked, FINALIZEDBIT)


#define KEYWEAK bitmask(KEYWEAKBIT)
#define VALUEWEAK bitmask(VALUEWEAKBIT)



#define markvalue(g,o) { checkconsistency(o); \
if (iscollectable(o) &amp; &amp; iswhite(gcvalue(o))) reallymarkobject(g,gcvalue(o)); }

#define markobject(g,t) { if (iswhite(obj2gco(t))) \
reallymarkobject(g, obj2gco(t)); }


#define setthreshold(g) (g- &amp; gt; GCthreshold = (g- &amp; gt; estimate/100) * g- &amp; gt; gcpause)


static void removeentry (Node *n) {
lua_assert(ttisnil(gval(n)));
if (iscollectable(gkey(n)))
setttype(gkey(n), LUA_TDEADKEY); /* dead key; remove it */
}


static void reallymarkobject (global_State *g, GCObject *o) {
lua_assert(iswhite(o) &amp; &amp; !isdead(g, o));
white2gray(o);
switch (o- &amp; gt; gch.tt) {
case LUA_TSTRING: {
return;
}
case LUA_TUSERDATA: {
Table *mt = gco2u(o)- &amp; gt; metatable;
gray2black(o); /* udata are never gray */
if (mt) markobject(g, mt);
markobject(g, gco2u(o)- &amp; gt; env);
return;
}
case LUA_TUPVAL: {
UpVal *uv = gco2uv(o);
markvalue(g, uv- &amp; gt; v);
if (uv- &amp; gt; v == &amp; uv- &amp; gt; u.value) /* closed? */
gray2black(o); /* open upvalues are never black */
return;
}
case LUA_TFUNCTION: {
gco2cl(o)- &amp; gt; c.gclist = g- &amp; gt; gray;
g- &amp; gt; gray = o;
break;
}
case LUA_TTABLE: {
gco2h(o)- &amp; gt; gclist = g- &amp; gt; gray;
g- &amp; gt; gray = o;
break;
}
case LUA_TTHREAD: {
gco2th(o)- &amp; gt; gclist = g- &amp; gt; gray;
g- &amp; gt; gray = o;
break;
}
case LUA_TPROTO: {
gco2p(o)- &amp; gt; gclist = g- &amp; gt; gray;
g- &amp; gt; gray = o;
break;
}
default: lua_assert(0);
}
}


static void marktmu (global_State *g) {
GCObject *u = g- &amp; gt; tmudata;
if (u) {
do {
u = u- &amp; gt; gch.next;
makewhite(g, u); /* may be marked, if left from previous GC */
reallymarkobject(g, u);
} while (u != g- &amp; gt; tmudata);
}
}


/* move `dead' udata that need finalization to list `tmudata' */
size_t luaC_separateudata (lua_State *L, int all) {
global_State *g = G(L);
size_t deadmem = 0;
GCObject **p = &amp; g- &amp; gt; mainthread- &amp; gt; next;
GCObject *curr;
while ((curr = *p) != NULL) {
if (!(iswhite(curr) || all) || isfinalized(gco2u(curr)))
p = &amp; curr- &amp; gt; gch.next; /* don't bother with them */
else if (fasttm(L, gco2u(curr)- &amp; gt; metatable, TM_GC) == NULL) {
markfinalized(gco2u(curr)); /* don't need finalization */
p = &amp; curr- &amp; gt; gch.next;
}
else { /* must call its gc method */
deadmem += sizeudata(gco2u(curr));
markfinalized(gco2u(curr));
*p = curr- &amp; gt; gch.next;
/* link `curr' at the end of `tmudata' list */
if (g- &amp; gt; tmudata == NULL) /* list is empty? */
g- &amp; gt; tmudata = curr- &amp; gt; gch.next = curr; /* creates a circular list */
else {
curr- &amp; gt; gch.next = g- &amp; gt; tmudata- &amp; gt; gch.next;
g- &amp; gt; tmudata- &amp; gt; gch.next = curr;
g- &amp; gt; tmudata = curr;
}
}
}
return deadmem;
}


static int traversetable (global_State *g, Table *h) {
int i;
int weakkey = 0;
int weakvalue = 0;
const TValue *mode;
if (h- &amp; gt; metatable)
markobject(g, h- &amp; gt; metatable);
mode = gfasttm(g, h- &amp; gt; metatable, TM_MODE);
if (mode &amp; &amp; ttisstring(mode)) { /* is there a weak mode? */
weakkey = (strchr(svalue(mode), 'k') != NULL);
weakvalue = (strchr(svalue(mode), 'v') != NULL);
if (weakkey || weakvalue) { /* is really weak? */
h- &amp; gt; marked &amp; = ~(KEYWEAK | VALUEWEAK); /* clear bits */
h- &amp; gt; marked |= cast_byte((weakkey &amp; lt; &amp; lt; KEYWEAKBIT) |
(weakvalue &amp; lt; &amp; lt; VALUEWEAKBIT));
h- &amp; gt; gclist = g- &amp; gt; weak; /* must be cleared after GC, ... */
g- &amp; gt; weak = obj2gco(h); /* ... so put in the appropriate list */
}
}
if (weakkey &amp; &amp; weakvalue) return 1;
if (!weakvalue) {
i = h- &amp; gt; sizearray;
while (i--)
markvalue(g, &amp; h- &amp; gt; array[i]);
}
i = sizenode(h);
while (i--) {
Node *n = gnode(h, i);
lua_assert(ttype(gkey(n)) != LUA_TDEADKEY || ttisnil(gval(n)));
if (ttisnil(gval(n)))
removeentry(n); /* remove empty entries */
else {
lua_assert(!ttisnil(gkey(n)));
if (!weakkey) markvalue(g, gkey(n));
if (!weakvalue) markvalue(g, gval(n));
}
}
return weakkey || weakvalue;
}


/*
** All marks are conditional because a GC may happen while the
** prototype is still being created
*/
static void traverseproto (global_State *g, Proto *f) {
int i;
if (f- &amp; gt; source) stringmark(f- &amp; gt; source);
for (i=0; i &amp; lt; f- &amp; gt; sizek; i++) /* mark literals */
markvalue(g, &amp; f- &amp; gt; k[i]);
for (i=0; i &amp; lt; f- &amp; gt; sizeupvalues; i++) { /* mark upvalue names */
if (f- &amp; gt; upvalues[i])
stringmark(f- &amp; gt; upvalues[i]);
}
for (i=0; i &amp; lt; f- &amp; gt; sizep; i++) { /* mark nested protos */
if (f- &amp; gt; p[i])
markobject(g, f- &amp; gt; p[i]);
}
for (i=0; i &amp; lt; f- &amp; gt; sizelocvars; i++) { /* mark local-variable names */
if (f- &amp; gt; locvars[i].varname)
stringmark(f- &amp; gt; locvars[i].varname);
}
}



static void traverseclosure (global_State *g, Closure *cl) {
markobject(g, cl- &amp; gt; c.env);
if (cl- &amp; gt; c.isC) {
int i;
for (i=0; i &amp; lt; cl- &amp; gt; c.nupvalues; i++) /* mark its upvalues */
markvalue(g, &amp; cl- &amp; gt; c.upvalue[i]);
}
else {
int i;
lua_assert(cl- &amp; gt; l.nupvalues == cl- &amp; gt; l.p- &amp; gt; nups);
markobject(g, cl- &amp; gt; l.p);
for (i=0; i &amp; lt; cl- &amp; gt; l.nupvalues; i++) /* mark its upvalues */
markobject(g, cl- &amp; gt; l.upvals[i]);
}
}


static void checkstacksizes (lua_State *L, StkId max) {
int ci_used = cast_int(L- &amp; gt; ci - L- &amp; gt; base_ci); /* number of `ci' in use */
int s_used = cast_int(max - L- &amp; gt; stack); /* part of stack in use */
if (L- &amp; gt; size_ci &amp; gt; LUAI_MAXCALLS) /* handling overflow? */
return; /* do not touch the stacks */
if (4*ci_used &amp; lt; L- &amp; gt; size_ci &amp; &amp; 2*BASIC_CI_SIZE &amp; lt; L- &amp; gt; size_ci)
luaD_reallocCI(L, L- &amp; gt; size_ci/2); /* still big enough... */
condhardstacktests(luaD_reallocCI(L, ci_used + 1));
if (4*s_used &amp; lt; L- &amp; gt; stacksize &amp; &amp;
2*(BASIC_STACK_SIZE+EXTRA_STACK) &amp; lt; L- &amp; gt; stacksize)
luaD_reallocstack(L, L- &amp; gt; stacksize/2); /* still big enough... */
condhardstacktests(luaD_reallocstack(L, s_used));
}


static void traversestack (global_State *g, lua_State *l) {
StkId o, lim;
CallInfo *ci;
markvalue(g, gt(l));
lim = l- &amp; gt; top;
for (ci = l- &amp; gt; base_ci; ci &amp; lt; = l- &amp; gt; ci; ci++) {
lua_assert(ci- &amp; gt; top &amp; lt; = l- &amp; gt; stack_last);
if (lim &amp; lt; ci- &amp; gt; top) lim = ci- &amp; gt; top;
}
for (o = l- &amp; gt; stack; o &amp; lt; l- &amp; gt; top; o++)
markvalue(g, o);
for (; o &amp; lt; = lim; o++)
setnilvalue(o);
checkstacksizes(l, lim);
}


/*
** traverse one gray object, turning it to black.
** Returns `quantity' traversed.
*/
static l_mem propagatemark (global_State *g) {
GCObject *o = g- &amp; gt; gray;
lua_assert(isgray(o));
gray2black(o);
switch (o- &amp; gt; gch.tt) {
case LUA_TTABLE: {
Table *h = gco2h(o);
g- &amp; gt; gray = h- &amp; gt; gclist;
if (traversetable(g, h)) /* table is weak? */
black2gray(o); /* keep it gray */
return sizeof(Table) + sizeof(TValue) * h- &amp; gt; sizearray +
sizeof(Node) * sizenode(h);
}
case LUA_TFUNCTION: {
Closure *cl = gco2cl(o);
g- &amp; gt; gray = cl- &amp; gt; c.gclist;
traverseclosure(g, cl);
return (cl- &amp; gt; c.isC) ? sizeCclosure(cl- &amp; gt; c.nupvalues) :
sizeLclosure(cl- &amp; gt; l.nupvalues);
}
case LUA_TTHREAD: {
lua_State *th = gco2th(o);
g- &amp; gt; gray = th- &amp; gt; gclist;
th- &amp; gt; gclist = g- &amp; gt; grayagain;
g- &amp; gt; grayagain = o;
black2gray(o);
traversestack(g, th);
return sizeof(lua_State) + sizeof(TValue) * th- &amp; gt; stacksize +
sizeof(CallInfo) * th- &amp; gt; size_ci;
}
case LUA_TPROTO: {
Proto *p = gco2p(o);
g- &amp; gt; gray = p- &amp; gt; gclist;
traverseproto(g, p);
return sizeof(Proto) + sizeof(Instruction) * p- &amp; gt; sizecode +
sizeof(Proto *) * p- &amp; gt; sizep +
sizeof(TValue) * p- &amp; gt; sizek +
sizeof(int) * p- &amp; gt; sizelineinfo +
sizeof(LocVar) * p- &amp; gt; sizelocvars +
sizeof(TString *) * p- &amp; gt; sizeupvalues;
}
default: lua_assert(0); return 0;
}
}


static size_t propagateall (global_State *g) {
size_t m = 0;
while (g- &amp; gt; gray) m += propagatemark(g);
return m;
}


/*
** The next function tells whether a key or value can be cleared from
** a weak table. Non-collectable objects are never removed from weak
** tables. Strings behave as `values', so are never removed too. for
** other objects: if really collected, cannot keep them; for userdata
** being finalized, keep them in keys, but not in values
*/
static int iscleared (const TValue *o, int iskey) {
if (!iscollectable(o)) return 0;
if (ttisstring(o)) {
stringmark(rawtsvalue(o)); /* strings are `values', so are never weak */
return 0;
}
return iswhite(gcvalue(o)) ||
(ttisuserdata(o) &amp; &amp; (!iskey &amp; &amp; isfinalized(uvalue(o))));
}


/*
** clear collected entries from weaktables
*/
static void cleartable (GCObject *l) {
while (l) {
Table *h = gco2h(l);
int i = h- &amp; gt; sizearray;
lua_assert(testbit(h- &amp; gt; marked, VALUEWEAKBIT) ||
testbit(h- &amp; gt; marked, KEYWEAKBIT));
if (testbit(h- &amp; gt; marked, VALUEWEAKBIT)) {
while (i--) {
TValue *o = &amp; h- &amp; gt; array[i];
if (iscleared(o, 0)) /* value was collected? */
setnilvalue(o); /* remove value */
}
}
i = sizenode(h);
while (i--) {
Node *n = gnode(h, i);
if (!ttisnil(gval(n)) &amp; &amp; /* non-empty entry? */
(iscleared(key2tval(n), 1) || iscleared(gval(n), 0))) {
setnilvalue(gval(n)); /* remove value ... */
removeentry(n); /* remove entry from table */
}
}
l = h- &amp; gt; gclist;
}
}


static void freeobj (lua_State *L, GCObject *o) {
switch (o- &amp; gt; gch.tt) {
case LUA_TPROTO: luaF_freeproto(L, gco2p(o)); break;
case LUA_TFUNCTION: luaF_freeclosure(L, gco2cl(o)); break;
case LUA_TUPVAL: luaF_freeupval(L, gco2uv(o)); break;
case LUA_TTABLE: luaH_free(L, gco2h(o)); break;
case LUA_TTHREAD: {
lua_assert(gco2th(o) != L &amp; &amp; gco2th(o) != G(L)- &amp; gt; mainthread);
luaE_freethread(L, gco2th(o));
break;
}
case LUA_TSTRING: {
G(L)- &amp; gt; strt.nuse--;
luaM_freemem(L, o, sizestring(gco2ts(o)));
break;
}
case LUA_TUSERDATA: {
luaM_freemem(L, o, sizeudata(gco2u(o)));
break;
}
default: lua_assert(0);
}
}



#define sweepwholelist(L,p) sweeplist(L,p,MAX_LUMEM)


static GCObject **sweeplist (lua_State *L, GCObject **p, lu_mem count) {
GCObject *curr;
global_State *g = G(L);
int deadmask = otherwhite(g);
while ((curr = *p) != NULL &amp; &amp; count-- &amp; gt; 0) {
if (curr- &amp; gt; gch.tt == LUA_TTHREAD) /* sweep open upvalues of each thread */
sweepwholelist(L, &amp; gco2th(curr)- &amp; gt; openupval);
if ((curr- &amp; gt; gch.marked ^ WHITEBITS) &amp; deadmask) { /* not dead? */
lua_assert(!isdead(g, curr) || testbit(curr- &amp; gt; gch.marked, FIXEDBIT));
makewhite(g, curr); /* make it white (for next cycle) */
p = &amp; curr- &amp; gt; gch.next;
}
else { /* must erase `curr' */
lua_assert(isdead(g, curr) || deadmask == bitmask(SFIXEDBIT));
*p = curr- &amp; gt; gch.next;
if (curr == g- &amp; gt; rootgc) /* is the first element of the list? */
g- &amp; gt; rootgc = curr- &amp; gt; gch.next; /* adjust first */
freeobj(L, curr);
}
}
return p;
}


static void checkSizes (lua_State *L) {
global_State *g = G(L);
/* check size of string hash */
if (g- &amp; gt; strt.nuse &amp; lt; cast(lu_int32, g- &amp; gt; strt.size/4) &amp; &amp;
g- &amp; gt; strt.size &amp; gt; MINSTRTABSIZE*2)
luaS_resize(L, g- &amp; gt; strt.size/2); /* table is too big */
/* check size of buffer */
if (luaZ_sizebuffer( &amp; g- &amp; gt; buff) &amp; gt; LUA_MINBUFFER*2) { /* buffer too big? */
size_t newsize = luaZ_sizebuffer( &amp; g- &amp; gt; buff) / 2;
luaZ_resizebuffer(L, &amp; g- &amp; gt; buff, newsize);
}
}


static void GCTM (lua_State *L) {
global_State *g = G(L);
GCObject *o = g- &amp; gt; tmudata- &amp; gt; gch.next; /* get first element */
Udata *udata = rawgco2u(o);
const TValue *tm;
/* remove udata from `tmudata' */
if (o == g- &amp; gt; tmudata) /* last element? */
g- &amp; gt; tmudata = NULL;
else
g- &amp; gt; tmudata- &amp; gt; gch.next = udata- &amp; gt; uv.next;
udata- &amp; gt; uv.next = g- &amp; gt; mainthread- &amp; gt; next; /* return it to `root' list */
g- &amp; gt; mainthread- &amp; gt; next = o;
makewhite(g, o);
tm = fasttm(L, udata- &amp; gt; uv.metatable, TM_GC);
if (tm != NULL) {
lu_byte oldah = L- &amp; gt; allowhook;
lu_mem oldt = g- &amp; gt; GCthreshold;
L- &amp; gt; allowhook = 0; /* stop debug hooks during GC tag method */
g- &amp; gt; GCthreshold = 2*g- &amp; gt; totalbytes; /* avoid GC steps */
setobj2s(L, L- &amp; gt; top, tm);
setuvalue(L, L- &amp; gt; top+1, udata);
L- &amp; gt; top += 2;
luaD_call(L, L- &amp; gt; top - 2, 0);
L- &amp; gt; allowhook = oldah; /* restore hooks */
g- &amp; gt; GCthreshold = oldt; /* restore threshold */
}
}


/*
** Call all GC tag methods
*/
void luaC_callGCTM (lua_State *L) {
while (G(L)- &amp; gt; tmudata)
GCTM(L);
}


void luaC_freeall (lua_State *L) {
global_State *g = G(L);
int i;
g- &amp; gt; currentwhite = WHITEBITS | bitmask(SFIXEDBIT); /* mask to collect all elements */
sweepwholelist(L, &amp; g- &amp; gt; rootgc);
for (i = 0; i &amp; lt; g- &amp; gt; strt.size; i++) /* free all string lists */
sweepwholelist(L, &amp; g- &amp; gt; strt.hash[i]);
}


static void markmt (global_State *g) {
int i;
for (i=0; i &amp; lt; NUM_TAGS; i++)
if (g- &amp; gt; mt[i]) markobject(g, g- &amp; gt; mt[i]);
}


/* mark root set */
static void markroot (lua_State *L) {
global_State *g = G(L);
g- &amp; gt; gray = NULL;
g- &amp; gt; grayagain = NULL;
g- &amp; gt; weak = NULL;
markobject(g, g- &amp; gt; mainthread);
/* make global table be traversed before main stack */
markvalue(g, gt(g- &amp; gt; mainthread));
markvalue(g, registry(L));
markmt(g);
g- &amp; gt; gcstate = GCSpropagate;
}


static void remarkupvals (global_State *g) {
UpVal *uv;
for (uv = g- &amp; gt; uvhead.u.l.next; uv != &amp; g- &amp; gt; uvhead; uv = uv- &amp; gt; u.l.next) {
lua_assert(uv- &amp; gt; u.l.next- &amp; gt; u.l.prev == uv &amp; &amp; uv- &amp; gt; u.l.prev- &amp; gt; u.l.next == uv);
if (isgray(obj2gco(uv)))
markvalue(g, uv- &amp; gt; v);
}
}


static void atomic (lua_State *L) {
global_State *g = G(L);
size_t udsize; /* total size of userdata to be finalized */
/* remark occasional upvalues of (maybe) dead threads */
remarkupvals(g);
/* traverse objects cautch by write barrier and by 'remarkupvals' */
propagateall(g);
/* remark weak tables */
g- &amp; gt; gray = g- &amp; gt; weak;
g- &amp; gt; weak = NULL;
lua_assert(!iswhite(obj2gco(g- &amp; gt; mainthread)));
markobject(g, L); /* mark running thread */
markmt(g); /* mark basic metatables (again) */
propagateall(g);
/* remark gray again */
g- &amp; gt; gray = g- &amp; gt; grayagain;
g- &amp; gt; grayagain = NULL;
propagateall(g);
udsize = luaC_separateudata(L, 0); /* separate userdata to be finalized */
marktmu(g); /* mark `preserved' userdata */
udsize += propagateall(g); /* remark, to propagate `preserveness' */
cleartable(g- &amp; gt; weak); /* remove collected objects from weak tables */
/* flip current white */
g- &amp; gt; currentwhite = cast_byte(otherwhite(g));
g- &amp; gt; sweepstrgc = 0;
g- &amp; gt; sweepgc = &amp; g- &amp; gt; rootgc;
g- &amp; gt; gcstate = GCSsweepstring;
g- &amp; gt; estimate = g- &amp; gt; totalbytes - udsize; /* first estimate */
}


static l_mem singlestep (lua_State *L) {
global_State *g = G(L);
/*lua_checkmemory(L);*/
switch (g- &amp; gt; gcstate) {
case GCSpause: {
markroot(L); /* start a new collection */
return 0;
}
case GCSpropagate: {
if (g- &amp; gt; gray)
return propagatemark(g);
else { /* no more `gray' objects */
atomic(L); /* finish mark phase */
return 0;
}
}
case GCSsweepstring: {
lu_mem old = g- &amp; gt; totalbytes;
sweepwholelist(L, &amp; g- &amp; gt; strt.hash[g- &amp; gt; sweepstrgc++]);
if (g- &amp; gt; sweepstrgc &amp; gt; = g- &amp; gt; strt.size) /* nothing more to sweep? */
g- &amp; gt; gcstate = GCSsweep; /* end sweep-string phase */
lua_assert(old &amp; gt; = g- &amp; gt; totalbytes);
g- &amp; gt; estimate -= old - g- &amp; gt; totalbytes;
return GCSWEEPCOST;
}
case GCSsweep: {
lu_mem old = g- &amp; gt; totalbytes;
g- &amp; gt; sweepgc = sweeplist(L, g- &amp; gt; sweepgc, GCSWEEPMAX);
if (*g- &amp; gt; sweepgc == NULL) { /* nothing more to sweep? */
checkSizes(L);
g- &amp; gt; gcstate = GCSfinalize; /* end sweep phase */
}
lua_assert(old &amp; gt; = g- &amp; gt; totalbytes);
g- &amp; gt; estimate -= old - g- &amp; gt; totalbytes;
return GCSWEEPMAX*GCSWEEPCOST;
}
case GCSfinalize: {
if (g- &amp; gt; tmudata) {
GCTM(L);
if (g- &amp; gt; estimate &amp; gt; GCFINALIZECOST)
g- &amp; gt; estimate -= GCFINALIZECOST;
return GCFINALIZECOST;
}
else {
g- &amp; gt; gcstate = GCSpause; /* end collection */
g- &amp; gt; gcdept = 0;
return 0;
}
}
default: lua_assert(0); return 0;
}
}


void luaC_step (lua_State *L) {
global_State *g = G(L);
l_mem lim = (GCSTEPSIZE/100) * g- &amp; gt; gcstepmul;
if (lim == 0)
lim = (MAX_LUMEM-1)/2; /* no limit */
g- &amp; gt; gcdept += g- &amp; gt; totalbytes - g- &amp; gt; GCthreshold;
do {
lim -= singlestep(L);
if (g- &amp; gt; gcstate == GCSpause)
break;
} while (lim &amp; gt; 0);
if (g- &amp; gt; gcstate != GCSpause) {
if (g- &amp; gt; gcdept &amp; lt; GCSTEPSIZE)
g- &amp; gt; GCthreshold = g- &amp; gt; totalbytes + GCSTEPSIZE; /* - lim/g- &amp; gt; gcstepmul;*/
else {
g- &amp; gt; gcdept -= GCSTEPSIZE;
g- &amp; gt; GCthreshold = g- &amp; gt; totalbytes;
}
}
else {
lua_assert(g- &amp; gt; totalbytes &amp; gt; = g- &amp; gt; estimate);
setthreshold(g);
}
}


void luaC_fullgc (lua_State *L) {
global_State *g = G(L);
if (g- &amp; gt; gcstate &amp; lt; = GCSpropagate) {
/* reset sweep marks to sweep all elements (returning them to white) */
g- &amp; gt; sweepstrgc = 0;
g- &amp; gt; sweepgc = &amp; g- &amp; gt; rootgc;
/* reset other collector lists */
g- &amp; gt; gray = NULL;
g- &amp; gt; grayagain = NULL;
g- &amp; gt; weak = NULL;
g- &amp; gt; gcstate = GCSsweepstring;
}
lua_assert(g- &amp; gt; gcstate != GCSpause &amp; &amp; g- &amp; gt; gcstate != GCSpropagate);
/* finish any pending sweep phase */
while (g- &amp; gt; gcstate != GCSfinalize) {
lua_assert(g- &amp; gt; gcstate == GCSsweepstring || g- &amp; gt; gcstate == GCSsweep);
singlestep(L);
}
markroot(L);
while (g- &amp; gt; gcstate != GCSpause) {
singlestep(L);
}
setthreshold(g);
}


void luaC_barrierf (lua_State *L, GCObject *o, GCObject *v) {
global_State *g = G(L);
lua_assert(isblack(o) &amp; &amp; iswhite(v) &amp; &amp; !isdead(g, v) &amp; &amp; !isdead(g, o));
lua_assert(g- &amp; gt; gcstate != GCSfinalize &amp; &amp; g- &amp; gt; gcstate != GCSpause);
lua_assert(ttype( &amp; o- &amp; gt; gch) != LUA_TTABLE);
/* must keep invariant? */
if (g- &amp; gt; gcstate == GCSpropagate)
reallymarkobject(g, v); /* restore invariant */
else /* don't mind */
makewhite(g, o); /* mark as white just to avoid other barriers */
}


void luaC_barrierback (lua_State *L, Table *t) {
global_State *g = G(L);
GCObject *o = obj2gco(t);
lua_assert(isblack(o) &amp; &amp; !isdead(g, o));
lua_assert(g- &amp; gt; gcstate != GCSfinalize &amp; &amp; g- &amp; gt; gcstate != GCSpause);
black2gray(o); /* make table gray (again) */
t- &amp; gt; gclist = g- &amp; gt; grayagain;
g- &amp; gt; grayagain = o;
}


void luaC_link (lua_State *L, GCObject *o, lu_byte tt) {
global_State *g = G(L);
o- &amp; gt; gch.next = g- &amp; gt; rootgc;
g- &amp; gt; rootgc = o;
o- &amp; gt; gch.marked = luaC_white(g);
o- &amp; gt; gch.tt = tt;
}


void luaC_linkupval (lua_State *L, UpVal *uv) {
global_State *g = G(L);
GCObject *o = obj2gco(uv);
o- &amp; gt; gch.next = g- &amp; gt; rootgc; /* link upvalue into `rootgc' list */
g- &amp; gt; rootgc = o;
if (isgray(o)) {
if (g- &amp; gt; gcstate == GCSpropagate) {
gray2black(o); /* closed upvalues need barrier */
luaC_barrier(L, uv, uv- &amp; gt; v);
}
else { /* sweep phase: sweep it (turning it into white) */
makewhite(g, o);
lua_assert(g- &amp; gt; gcstate != GCSfinalize &amp; &amp; g- &amp; gt; gcstate != GCSpause);
}
}
}


scite228.zip > lvm.h

/*
** $Id$
** Lua virtual machine
** See Copyright Notice in lua.h
*/

#ifndef lvm_h
#define lvm_h


#include &quot; ldo.h &quot;
#include &quot; lobject.h &quot;
#include &quot; ltm.h &quot;


#define tostring(L,o) ((ttype(o) == LUA_TSTRING) || (luaV_tostring(L, o)))

#define tonumber(o,n) (ttype(o) == LUA_TNUMBER || \
(((o) = luaV_tonumber(o,n)) != NULL))

#define equalobj(L,o1,o2) \
(ttype(o1) == ttype(o2) &amp; &amp; luaV_equalval(L, o1, o2))


LUAI_FUNC int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r);
LUAI_FUNC int luaV_equalval (lua_State *L, const TValue *t1, const TValue *t2);
LUAI_FUNC const TValue *luaV_tonumber (const TValue *obj, TValue *n);
LUAI_FUNC int luaV_tostring (lua_State *L, StkId obj);
LUAI_FUNC void luaV_gettable (lua_State *L, const TValue *t, TValue *key,
StkId val);
LUAI_FUNC void luaV_settable (lua_State *L, const TValue *t, TValue *key,
StkId val);
LUAI_FUNC void luaV_execute (lua_State *L, int nexeccalls);
LUAI_FUNC void luaV_concat (lua_State *L, int total, int last);

#endif


scite228.zip > ldump.c

/*
** $Id$
** save precompiled Lua chunks
** See Copyright Notice in lua.h
*/

#include &amp; lt; stddef.h &amp; gt;

#define ldump_c
#define LUA_CORE

#include &quot; lua.h &quot;

#include &quot; lobject.h &quot;
#include &quot; lstate.h &quot;
#include &quot; lundump.h &quot;

typedef struct {
lua_State* L;
lua_Writer writer;
void* data;
int strip;
int status;
} DumpState;

#define DumpMem(b,n,size,D) DumpBlock(b,(n)*(size),D)
#define DumpVar(x,D) DumpMem( &amp; x,1,sizeof(x),D)

static void DumpBlock(const void* b, size_t size, DumpState* D)
{
if (D- &amp; gt; status==0)
{
lua_unlock(D- &amp; gt; L);
D- &amp; gt; status=(*D- &amp; gt; writer)(D- &amp; gt; L,b,size,D- &amp; gt; data);
lua_lock(D- &amp; gt; L);
}
}

static void DumpChar(int y, DumpState* D)
{
char x=(char)y;
DumpVar(x,D);
}

static void DumpInt(int x, DumpState* D)
{
DumpVar(x,D);
}

static void DumpNumber(lua_Number x, DumpState* D)
{
DumpVar(x,D);
}

static void DumpVector(const void* b, int n, size_t size, DumpState* D)
{
DumpInt(n,D);
DumpMem(b,n,size,D);
}

static void DumpString(const TString* s, DumpState* D)
{
if (s==NULL || getstr(s)==NULL)
{
size_t size=0;
DumpVar(size,D);
}
else
{
size_t size=s- &amp; gt; tsv.len+1; /* include trailing '\0' */
DumpVar(size,D);
DumpBlock(getstr(s),size,D);
}
}

#define DumpCode(f,D) DumpVector(f- &amp; gt; code,f- &amp; gt; sizecode,sizeof(Instruction),D)

static void DumpFunction(const Proto* f, const TString* p, DumpState* D);

static void DumpConstants(const Proto* f, DumpState* D)
{
int i,n=f- &amp; gt; sizek;
DumpInt(n,D);
for (i=0; i &amp; lt; n; i++)
{
const TValue* o= &amp; f- &amp; gt; k[i];
DumpChar(ttype(o),D);
switch (ttype(o))
{
case LUA_TNIL:
break;
case LUA_TBOOLEAN:
DumpChar(bvalue(o),D);
break;
case LUA_TNUMBER:
DumpNumber(nvalue(o),D);
break;
case LUA_TSTRING:
DumpString(rawtsvalue(o),D);
break;
default:
lua_assert(0); /* cannot happen */
break;
}
}
n=f- &amp; gt; sizep;
DumpInt(n,D);
for (i=0; i &amp; lt; n; i++) DumpFunction(f- &amp; gt; p[i],f- &amp; gt; source,D);
}

static void DumpDebug(const Proto* f, DumpState* D)
{
int i,n;
n= (D- &amp; gt; strip) ? 0 : f- &amp; gt; sizelineinfo;
DumpVector(f- &amp; gt; lineinfo,n,sizeof(int),D);
n= (D- &amp; gt; strip) ? 0 : f- &amp; gt; sizelocvars;
DumpInt(n,D);
for (i=0; i &amp; lt; n; i++)
{
DumpString(f- &amp; gt; locvars[i].varname,D);
DumpInt(f- &amp; gt; locvars[i].startpc,D);
DumpInt(f- &amp; gt; locvars[i].endpc,D);
}
n= (D- &amp; gt; strip) ? 0 : f- &amp; gt; sizeupvalues;
DumpInt(n,D);
for (i=0; i &amp; lt; n; i++) DumpString(f- &amp; gt; upvalues[i],D);
}

static void DumpFunction(const Proto* f, const TString* p, DumpState* D)
{
DumpString((f- &amp; gt; source==p || D- &amp; gt; strip) ? NULL : f- &amp; gt; source,D);
DumpInt(f- &amp; gt; linedefined,D);
DumpInt(f- &amp; gt; lastlinedefined,D);
DumpChar(f- &amp; gt; nups,D);
DumpChar(f- &amp; gt; numparams,D);
DumpChar(f- &amp; gt; is_vararg,D);
DumpChar(f- &amp; gt; maxstacksize,D);
DumpCode(f,D);
DumpConstants(f,D);
DumpDebug(f,D);
}

static void DumpHeader(DumpState* D)
{
char h[LUAC_HEADERSIZE];
luaU_header(h);
DumpBlock(h,LUAC_HEADERSIZE,D);
}

/*
** dump Lua function as precompiled chunk
*/
int luaU_dump (lua_State* L, const Proto* f, lua_Writer w, void* data, int strip)
{
DumpState D;
D.L=L;
D.writer=w;
D.data=data;
D.strip=strip;
D.status=0;
DumpHeader( &amp; D);
DumpFunction(f,NULL, &amp; D);
return D.status;
}


scite228.zip > ldebug.h

/*
** $Id$
** Auxiliary functions from Debug Interface module
** See Copyright Notice in lua.h
*/

#ifndef ldebug_h
#define ldebug_h


#include &quot; lstate.h &quot;


#define pcRel(pc, p) (cast(int, (pc) - (p)- &amp; gt; code) - 1)

#define getline(f,pc) (((f)- &amp; gt; lineinfo) ? (f)- &amp; gt; lineinfo[pc] : 0)

#define resethookcount(L) (L- &amp; gt; hookcount = L- &amp; gt; basehookcount)


LUAI_FUNC void luaG_typeerror (lua_State *L, const TValue *o,
const char *opname);
LUAI_FUNC void luaG_concaterror (lua_State *L, StkId p1, StkId p2);
LUAI_FUNC void luaG_aritherror (lua_State *L, const TValue *p1,
const TValue *p2);
LUAI_FUNC int luaG_ordererror (lua_State *L, const TValue *p1,
const TValue *p2);
LUAI_FUNC void luaG_runerror (lua_State *L, const char *fmt, ...);
LUAI_FUNC void luaG_errormsg (lua_State *L);
LUAI_FUNC int luaG_checkcode (const Proto *pt);
LUAI_FUNC int luaG_checkopenop (Instruction i);

#endif


scite228.zip > ltable.c

/*
** $Id$
** Lua tables (hash)
** See Copyright Notice in lua.h
*/


/*
** Implementation of tables (aka arrays, objects, or hash tables).
** Tables keep its elements in two parts: an array part and a hash part.
** Non-negative integer keys are all candidates to be kept in the array
** part. The actual size of the array is the largest `n' such that at
** least half the slots between 0 and n are in use.
** Hash uses a mix of chained scatter table with Brent's variation.
** A main invariant of these tables is that, if an element is not
** in its main position (i.e. the `original' position that its hash gives
** to it), then the colliding element is in its own main position.
** Hence even when the load factor reaches 100%, performance remains good.
*/

#include &amp; lt; math.h &amp; gt;
#include &amp; lt; string.h &amp; gt;

#define ltable_c
#define LUA_CORE

#include &quot; lua.h &quot;

#include &quot; ldebug.h &quot;
#include &quot; ldo.h &quot;
#include &quot; lgc.h &quot;
#include &quot; lmem.h &quot;
#include &quot; lobject.h &quot;
#include &quot; lstate.h &quot;
#include &quot; ltable.h &quot;


/*
** max size of array part is 2^MAXBITS
*/
#if LUAI_BITSINT &amp; gt; 26
#define MAXBITS 26
#else
#define MAXBITS (LUAI_BITSINT-2)
#endif

#define MAXASIZE (1 &amp; lt; &amp; lt; MAXBITS)


#define hashpow2(t,n) (gnode(t, lmod((n), sizenode(t))))

#define hashstr(t,str) hashpow2(t, (str)- &amp; gt; tsv.hash)
#define hashboolean(t,p) hashpow2(t, p)


/*
** for some types, it is better to avoid modulus by power of 2, as
** they tend to have many 2 factors.
*/
#define hashmod(t,n) (gnode(t, ((n) % ((sizenode(t)-1)|1))))


#define hashpointer(t,p) hashmod(t, IntPoint(p))


/*
** number of ints inside a lua_Number
*/
#define numints cast_int(sizeof(lua_Number)/sizeof(int))



#define dummynode ( &amp; dummynode_)

static const Node dummynode_ = {
{{NULL}, LUA_TNIL}, /* value */
{{{NULL}, LUA_TNIL, NULL}} /* key */
};


/*
** hash for lua_Numbers
*/
static Node *hashnum (const Table *t, lua_Number n) {
unsigned int a[numints];
int i;
if (luai_numeq(n, 0)) /* avoid problems with -0 */
return gnode(t, 0);
memcpy(a, &amp; n, sizeof(a));
for (i = 1; i &amp; lt; numints; i++) a[0] += a[i];
return hashmod(t, a[0]);
}



/*
** returns the `main' position of an element in a table (that is, the index
** of its hash value)
*/
static Node *mainposition (const Table *t, const TValue *key) {
switch (ttype(key)) {
case LUA_TNUMBER:
return hashnum(t, nvalue(key));
case LUA_TSTRING:
return hashstr(t, rawtsvalue(key));
case LUA_TBOOLEAN:
return hashboolean(t, bvalue(key));
case LUA_TLIGHTUSERDATA:
return hashpointer(t, pvalue(key));
default:
return hashpointer(t, gcvalue(key));
}
}


/*
** returns the index for `key' if `key' is an appropriate key to live in
** the array part of the table, -1 otherwise.
*/
static int arrayindex (const TValue *key) {
if (ttisnumber(key)) {
lua_Number n = nvalue(key);
int k;
lua_number2int(k, n);
if (luai_numeq(cast_num(k), n))
return k;
}
return -1; /* `key' did not match some condition */
}


/*
** returns the index of a `key' for table traversals. First goes all
** elements in the array part, then elements in the hash part. The
** beginning of a traversal is signalled by -1.
*/
static int findindex (lua_State *L, Table *t, StkId key) {
int i;
if (ttisnil(key)) return -1; /* first iteration */
i = arrayindex(key);
if (0 &amp; lt; i &amp; &amp; i &amp; lt; = t- &amp; gt; sizearray) /* is `key' inside array part? */
return i-1; /* yes; that's the index (corrected to C) */
else {
Node *n = mainposition(t, key);
do { /* check whether `key' is somewhere in the chain */
/* key may be dead already, but it is ok to use it in `next' */
if (luaO_rawequalObj(key2tval(n), key) ||
(ttype(gkey(n)) == LUA_TDEADKEY &amp; &amp; iscollectable(key) &amp; &amp;
gcvalue(gkey(n)) == gcvalue(key))) {
i = cast_int(n - gnode(t, 0)); /* key index in hash table */
/* hash elements are numbered after array ones */
return i + t- &amp; gt; sizearray;
}
else n = gnext(n);
} while (n);
luaG_runerror(L, &quot; invalid key to &quot; LUA_QL( &quot; next &quot; )); /* key not found */
return 0; /* to avoid warnings */
}
}


int luaH_next (lua_State *L, Table *t, StkId key) {
int i = findindex(L, t, key); /* find original element */
for (i++; i &amp; lt; t- &amp; gt; sizearray; i++) { /* try first array part */
if (!ttisnil( &amp; t- &amp; gt; array[i])) { /* a non-nil value? */
setnvalue(key, cast_num(i+1));
setobj2s(L, key+1, &amp; t- &amp; gt; array[i]);
return 1;
}
}
for (i -= t- &amp; gt; sizearray; i &amp; lt; sizenode(t); i++) { /* then hash part */
if (!ttisnil(gval(gnode(t, i)))) { /* a non-nil value? */
setobj2s(L, key, key2tval(gnode(t, i)));
setobj2s(L, key+1, gval(gnode(t, i)));
return 1;
}
}
return 0; /* no more elements */
}


/*
** {=============================================================
** Rehash
** ==============================================================
*/


static int computesizes (int nums[], int *narray) {
int i;
int twotoi; /* 2^i */
int a = 0; /* number of elements smaller than 2^i */
int na = 0; /* number of elements to go to array part */
int n = 0; /* optimal size for array part */
for (i = 0, twotoi = 1; twotoi/2 &amp; lt; *narray; i++, twotoi *= 2) {
if (nums[i] &amp; gt; 0) {
a += nums[i];
if (a &amp; gt; twotoi/2) { /* more than half elements present? */
n = twotoi; /* optimal size (till now) */
na = a; /* all elements smaller than n will go to array part */
}
}
if (a == *narray) break; /* all elements already counted */
}
*narray = n;
lua_assert(*narray/2 &amp; lt; = na &amp; &amp; na &amp; lt; = *narray);
return na;
}


static int countint (const TValue *key, int *nums) {
int k = arrayindex(key);
if (0 &amp; lt; k &amp; &amp; k &amp; lt; = MAXASIZE) { /* is `key' an appropriate array index? */
nums[ceillog2(k)]++; /* count as such */
return 1;
}
else
return 0;
}


static int numusearray (const Table *t, int *nums) {
int lg;
int ttlg; /* 2^lg */
int ause = 0; /* summation of `nums' */
int i = 1; /* count to traverse all array keys */
for (lg=0, ttlg=1; lg &amp; lt; =MAXBITS; lg++, ttlg*=2) { /* for each slice */
int lc = 0; /* counter */
int lim = ttlg;
if (lim &amp; gt; t- &amp; gt; sizearray) {
lim = t- &amp; gt; sizearray; /* adjust upper limit */
if (i &amp; gt; lim)
break; /* no more elements to count */
}
/* count elements in range (2^(lg-1), 2^lg] */
for (; i &amp; lt; = lim; i++) {
if (!ttisnil( &amp; t- &amp; gt; array[i-1]))
lc++;
}
nums[lg] += lc;
ause += lc;
}
return ause;
}


static int numusehash (const Table *t, int *nums, int *pnasize) {
int totaluse = 0; /* total number of elements */
int ause = 0; /* summation of `nums' */
int i = sizenode(t);
while (i--) {
Node *n = &amp; t- &amp; gt; node[i];
if (!ttisnil(gval(n))) {
ause += countint(key2tval(n), nums);
totaluse++;
}
}
*pnasize += ause;
return totaluse;
}


static void setarrayvector (lua_State *L, Table *t, int size) {
int i;
luaM_reallocvector(L, t- &amp; gt; array, t- &amp; gt; sizearray, size, TValue);
for (i=t- &amp; gt; sizearray; i &amp; lt; size; i++)
setnilvalue( &amp; t- &amp; gt; array[i]);
t- &amp; gt; sizearray = size;
}


static void setnodevector (lua_State *L, Table *t, int size) {
int lsize;
if (size == 0) { /* no elements to hash part? */
t- &amp; gt; node = cast(Node *, dummynode); /* use common `dummynode' */
lsize = 0;
}
else {
int i;
lsize = ceillog2(size);
if (lsize &amp; gt; MAXBITS)
luaG_runerror(L, &quot; table overflow &quot; );
size = twoto(lsize);
t- &amp; gt; node = luaM_newvector(L, size, Node);
for (i=0; i &amp; lt; size; i++) {
Node *n = gnode(t, i);
gnext(n) = NULL;
setnilvalue(gkey(n));
setnilvalue(gval(n));
}
}
t- &amp; gt; lsizenode = cast_byte(lsize);
t- &amp; gt; lastfree = gnode(t, size); /* all positions are free */
}


static void resize (lua_State *L, Table *t, int nasize, int nhsize) {
int i;
int oldasize = t- &amp; gt; sizearray;
int oldhsize = t- &amp; gt; lsizenode;
Node *nold = t- &amp; gt; node; /* save old hash ... */
if (nasize &amp; gt; oldasize) /* array part must grow? */
setarrayvector(L, t, nasize);
/* create new hash part with appropriate size */
setnodevector(L, t, nhsize);
if (nasize &amp; lt; oldasize) { /* array part must shrink? */
t- &amp; gt; sizearray = nasize;
/* re-insert elements from vanishing slice */
for (i=nasize; i &amp; lt; oldasize; i++) {
if (!ttisnil( &amp; t- &amp; gt; array[i]))
setobjt2t(L, luaH_setnum(L, t, i+1), &amp; t- &amp; gt; array[i]);
}
/* shrink array */
luaM_reallocvector(L, t- &amp; gt; array, oldasize, nasize, TValue);
}
/* re-insert elements from hash part */
for (i = twoto(oldhsize) - 1; i &amp; gt; = 0; i--) {
Node *old = nold+i;
if (!ttisnil(gval(old)))
setobjt2t(L, luaH_set(L, t, key2tval(old)), gval(old));
}
if (nold != dummynode)
luaM_freearray(L, nold, twoto(oldhsize), Node); /* free old array */
}


void luaH_resizearray (lua_State *L, Table *t, int nasize) {
int nsize = (t- &amp; gt; node == dummynode) ? 0 : sizenode(t);
resize(L, t, nasize, nsize);
}


static void rehash (lua_State *L, Table *t, const TValue *ek) {
int nasize, na;
int nums[MAXBITS+1]; /* nums[i] = number of keys between 2^(i-1) and 2^i */
int i;
int totaluse;
for (i=0; i &amp; lt; =MAXBITS; i++) nums[i] = 0; /* reset counts */
nasize = numusearray(t, nums); /* count keys in array part */
totaluse = nasize; /* all those keys are integer keys */
totaluse += numusehash(t, nums, &amp; nasize); /* count keys in hash part */
/* count extra key */
nasize += countint(ek, nums);
totaluse++;
/* compute new size for array part */
na = computesizes(nums, &amp; nasize);
/* resize the table to new computed sizes */
resize(L, t, nasize, totaluse - na);
}



/*
** }=============================================================
*/


Table *luaH_new (lua_State *L, int narray, int nhash) {
Table *t = luaM_new(L, Table);
luaC_link(L, obj2gco(t), LUA_TTABLE);
t- &amp; gt; metatable = NULL;
t- &amp; gt; flags = cast_byte(~0);
/* temporary values (kept only if some malloc fails) */
t- &amp; gt; array = NULL;
t- &amp; gt; sizearray = 0;
t- &amp; gt; lsizenode = 0;
t- &amp; gt; node = cast(Node *, dummynode);
setarrayvector(L, t, narray);
setnodevector(L, t, nhash);
return t;
}


void luaH_free (lua_State *L, Table *t) {
if (t- &amp; gt; node != dummynode)
luaM_freearray(L, t- &amp; gt; node, sizenode(t), Node);
luaM_freearray(L, t- &amp; gt; array, t- &amp; gt; sizearray, TValue);
luaM_free(L, t);
}


static Node *getfreepos (Table *t) {
while (t- &amp; gt; lastfree-- &amp; gt; t- &amp; gt; node) {
if (ttisnil(gkey(t- &amp; gt; lastfree)))
return t- &amp; gt; lastfree;
}
return NULL; /* could not find a free place */
}



/*
** inserts a new key into a hash table; first, check whether key's main
** position is free. If not, check whether colliding node is in its main
** position or not: if it is not, move colliding node to an empty place and
** put new key in its main position; otherwise (colliding node is in its main
** position), new key goes to an empty position.
*/
static TValue *newkey (lua_State *L, Table *t, const TValue *key) {
Node *mp = mainposition(t, key);
if (!ttisnil(gval(mp)) || mp == dummynode) {
Node *othern;
Node *n = getfreepos(t); /* get a free place */
if (n == NULL) { /* cannot find a free place? */
rehash(L, t, key); /* grow table */
return luaH_set(L, t, key); /* re-insert key into grown table */
}
lua_assert(n != dummynode);
othern = mainposition(t, key2tval(mp));
if (othern != mp) { /* is colliding node out of its main position? */
/* yes; move colliding node into free position */
while (gnext(othern) != mp) othern = gnext(othern); /* find previous */
gnext(othern) = n; /* redo the chain with `n' in place of `mp' */
*n = *mp; /* copy colliding node into free pos. (mp- &amp; gt; next also goes) */
gnext(mp) = NULL; /* now `mp' is free */
setnilvalue(gval(mp));
}
else { /* colliding node is in its own main position */
/* new node will go into free position */
gnext(n) = gnext(mp); /* chain new position */
gnext(mp) = n;
mp = n;
}
}
gkey(mp)- &amp; gt; value = key- &amp; gt; value; gkey(mp)- &amp; gt; tt = key- &amp; gt; tt;
luaC_barriert(L, t, key);
lua_assert(ttisnil(gval(mp)));
return gval(mp);
}


/*
** search function for integers
*/
const TValue *luaH_getnum (Table *t, int key) {
/* (1 &amp; lt; = key &amp; &amp; key &amp; lt; = t- &amp; gt; sizearray) */
if (cast(unsigned int, key-1) &amp; lt; cast(unsigned int, t- &amp; gt; sizearray))
return &amp; t- &amp; gt; array[key-1];
else {
lua_Number nk = cast_num(key);
Node *n = hashnum(t, nk);
do { /* check whether `key' is somewhere in the chain */
if (ttisnumber(gkey(n)) &amp; &amp; luai_numeq(nvalue(gkey(n)), nk))
return gval(n); /* that's it */
else n = gnext(n);
} while (n);
return luaO_nilobject;
}
}


/*
** search function for strings
*/
const TValue *luaH_getstr (Table *t, TString *key) {
Node *n = hashstr(t, key);
do { /* check whether `key' is somewhere in the chain */
if (ttisstring(gkey(n)) &amp; &amp; rawtsvalue(gkey(n)) == key)
return gval(n); /* that's it */
else n = gnext(n);
} while (n);
return luaO_nilobject;
}


/*
** main search function
*/
const TValue *luaH_get (Table *t, const TValue *key) {
switch (ttype(key)) {
case LUA_TNIL: return luaO_nilobject;
case LUA_TSTRING: return luaH_getstr(t, rawtsvalue(key));
case LUA_TNUMBER: {
int k;
lua_Number n = nvalue(key);
lua_number2int(k, n);
if (luai_numeq(cast_num(k), nvalue(key))) /* index is int? */
return luaH_getnum(t, k); /* use specialized version */
/* else go through */
}
default: {
Node *n = mainposition(t, key);
do { /* check whether `key' is somewhere in the chain */
if (luaO_rawequalObj(key2tval(n), key))
return gval(n); /* that's it */
else n = gnext(n);
} while (n);
return luaO_nilobject;
}
}
}


TValue *luaH_set (lua_State *L, Table *t, const TValue *key) {
const TValue *p = luaH_get(t, key);
t- &amp; gt; flags = 0;
if (p != luaO_nilobject)
return cast(TValue *, p);
else {
if (ttisnil(key)) luaG_runerror(L, &quot; table index is nil &quot; );
else if (ttisnumber(key) &amp; &amp; luai_numisnan(nvalue(key)))
luaG_runerror(L, &quot; table index is NaN &quot; );
return newkey(L, t, key);
}
}


TValue *luaH_setnum (lua_State *L, Table *t, int key) {
const TValue *p = luaH_getnum(t, key);
if (p != luaO_nilobject)
return cast(TValue *, p);
else {
TValue k;
setnvalue( &amp; k, cast_num(key));
return newkey(L, t, &amp; k);
}
}


TValue *luaH_setstr (lua_State *L, Table *t, TString *key) {
const TValue *p = luaH_getstr(t, key);
if (p != luaO_nilobject)
return cast(TValue *, p);
else {
TValue k;
setsvalue(L, &amp; k, key);
return newkey(L, t, &amp; k);
}
}


static int unbound_search (Table *t, unsigned int j) {
unsigned int i = j; /* i is zero or a present index */
j++;
/* find `i' and `j' such that i is present and j is not */
while (!ttisnil(luaH_getnum(t, j))) {
i = j;
j *= 2;
if (j &amp; gt; cast(unsigned int, MAX_INT)) { /* overflow? */
/* table was built with bad purposes: resort to linear search */
i = 1;
while (!ttisnil(luaH_getnum(t, i))) i++;
return i - 1;
}
}
/* now do a binary search between them */
while (j - i &amp; gt; 1) {
unsigned int m = (i+j)/2;
if (ttisnil(luaH_getnum(t, m))) j = m;
else i = m;
}
return i;
}


/*
** Try to find a boundary in table `t'. A `boundary' is an integer index
** such that t[i] is non-nil and t[i+1] is nil (and 0 if t[1] is nil).
*/
int luaH_getn (Table *t) {
unsigned int j = t- &amp; gt; sizearray;
if (j &amp; gt; 0 &amp; &amp; ttisnil( &amp; t- &amp; gt; array[j - 1])) {
/* there is a boundary in the array part: (binary) search for it */
unsigned int i = 0;
while (j - i &amp; gt; 1) {
unsigned int m = (i+j)/2;
if (ttisnil( &amp; t- &amp; gt; array[m - 1])) j = m;
else i = m;
}
return i;
}
/* else must find a boundary in hash part */
else if (t- &amp; gt; node == dummynode) /* hash part is empty? */
return j; /* that is easy... */
else return unbound_search(t, j);
}



#if defined(LUA_DEBUG)

Node *luaH_mainposition (const Table *t, const TValue *key) {
return mainposition(t, key);
}

int luaH_isdummy (Node *n) { return n == dummynode; }

#endif


scite228.zip > lfunc.h

/*
** $Id$
** Auxiliary functions to manipulate prototypes and closures
** See Copyright Notice in lua.h
*/

#ifndef lfunc_h
#define lfunc_h


#include &quot; lobject.h &quot;


#define sizeCclosure(n) (cast(int, sizeof(CClosure)) + \
cast(int, sizeof(TValue)*((n)-1)))

#define sizeLclosure(n) (cast(int, sizeof(LClosure)) + \
cast(int, sizeof(TValue *)*((n)-1)))


LUAI_FUNC Proto *luaF_newproto (lua_State *L);
LUAI_FUNC Closure *luaF_newCclosure (lua_State *L, int nelems, Table *e);
LUAI_FUNC Closure *luaF_newLclosure (lua_State *L, int nelems, Table *e);
LUAI_FUNC UpVal *luaF_newupval (lua_State *L);
LUAI_FUNC UpVal *luaF_findupval (lua_State *L, StkId level);
LUAI_FUNC void luaF_close (lua_State *L, StkId level);
LUAI_FUNC void luaF_freeproto (lua_State *L, Proto *f);
LUAI_FUNC void luaF_freeclosure (lua_State *L, Closure *c);
LUAI_FUNC void luaF_freeupval (lua_State *L, UpVal *uv);
LUAI_FUNC const char *luaF_getlocalname (const Proto *func, int local_number,
int pc);


#endif


scite228.zip > lzio.h

/*
** $Id$
** Buffered streams
** See Copyright Notice in lua.h
*/


#ifndef lzio_h
#define lzio_h

#include &quot; lua.h &quot;

#include &quot; lmem.h &quot;


#define EOZ (-1) /* end of stream */

typedef struct Zio ZIO;

#define char2int(c) cast(int, cast(unsigned char, (c)))

#define zgetc(z) (((z)- &amp; gt; n--) &amp; gt; 0 ? char2int(*(z)- &amp; gt; p++) : luaZ_fill(z))

typedef struct Mbuffer {
char *buffer;
size_t n;
size_t buffsize;
} Mbuffer;

#define luaZ_initbuffer(L, buff) ((buff)- &amp; gt; buffer = NULL, (buff)- &amp; gt; buffsize = 0)

#define luaZ_buffer(buff) ((buff)- &amp; gt; buffer)
#define luaZ_sizebuffer(buff) ((buff)- &amp; gt; buffsize)
#define luaZ_bufflen(buff) ((buff)- &amp; gt; n)

#define luaZ_resetbuffer(buff) ((buff)- &amp; gt; n = 0)


#define luaZ_resizebuffer(L, buff, size) \
(luaM_reallocvector(L, (buff)- &amp; gt; buffer, (buff)- &amp; gt; buffsize, size, char), \
(buff)- &amp; gt; buffsize = size)

#define luaZ_freebuffer(L, buff) luaZ_resizebuffer(L, buff, 0)


LUAI_FUNC char *luaZ_openspace (lua_State *L, Mbuffer *buff, size_t n);
LUAI_FUNC void luaZ_init (lua_State *L, ZIO *z, lua_Reader reader,
void *data);
LUAI_FUNC size_t luaZ_read (ZIO* z, void* b, size_t n); /* read next n bytes */
LUAI_FUNC int luaZ_lookahead (ZIO *z);



/* --------- Private Part ------------------ */

struct Zio {
size_t n; /* bytes still unread */
const char *p; /* current position in buffer */
lua_Reader reader;
void* data; /* additional data */
lua_State *L; /* Lua state (for reader) */
};


LUAI_FUNC int luaZ_fill (ZIO *z);

#endif


scite228.zip > lgc.h

/*
** $Id$
** Garbage Collector
** See Copyright Notice in lua.h
*/

#ifndef lgc_h
#define lgc_h


#include &quot; lobject.h &quot;


/*
** Possible states of the Garbage Collector
*/
#define GCSpause 0
#define GCSpropagate 1
#define GCSsweepstring 2
#define GCSsweep 3
#define GCSfinalize 4


/*
** some userful bit tricks
*/
#define resetbits(x,m) ((x) &amp; = cast(lu_byte, ~(m)))
#define setbits(x,m) ((x) |= (m))
#define testbits(x,m) ((x) &amp; (m))
#define bitmask(b) (1 &amp; lt; &amp; lt; (b))
#define bit2mask(b1,b2) (bitmask(b1) | bitmask(b2))
#define l_setbit(x,b) setbits(x, bitmask(b))
#define resetbit(x,b) resetbits(x, bitmask(b))
#define testbit(x,b) testbits(x, bitmask(b))
#define set2bits(x,b1,b2) setbits(x, (bit2mask(b1, b2)))
#define reset2bits(x,b1,b2) resetbits(x, (bit2mask(b1, b2)))
#define test2bits(x,b1,b2) testbits(x, (bit2mask(b1, b2)))



/*
** Layout for bit use in `marked' field:
** bit 0 - object is white (type 0)
** bit 1 - object is white (type 1)
** bit 2 - object is black
** bit 3 - for userdata: has been finalized
** bit 3 - for tables: has weak keys
** bit 4 - for tables: has weak values
** bit 5 - object is fixed (should not be collected)
** bit 6 - object is &quot; super &quot; fixed (only the main thread)
*/


#define WHITE0BIT 0
#define WHITE1BIT 1
#define BLACKBIT 2
#define FINALIZEDBIT 3
#define KEYWEAKBIT 3
#define VALUEWEAKBIT 4
#define FIXEDBIT 5
#define SFIXEDBIT 6
#define WHITEBITS bit2mask(WHITE0BIT, WHITE1BIT)


#define iswhite(x) test2bits((x)- &amp; gt; gch.marked, WHITE0BIT, WHITE1BIT)
#define isblack(x) testbit((x)- &amp; gt; gch.marked, BLACKBIT)
#define isgray(x) (!isblack(x) &amp; &amp; !iswhite(x))

#define otherwhite(g) (g- &amp; gt; currentwhite ^ WHITEBITS)
#define isdead(g,v) ((v)- &amp; gt; gch.marked &amp; otherwhite(g) &amp; WHITEBITS)

#define changewhite(x) ((x)- &amp; gt; gch.marked ^= WHITEBITS)
#define gray2black(x) l_setbit((x)- &amp; gt; gch.marked, BLACKBIT)

#define valiswhite(x) (iscollectable(x) &amp; &amp; iswhite(gcvalue(x)))

#define luaC_white(g) cast(lu_byte, (g)- &amp; gt; currentwhite &amp; WHITEBITS)


#define luaC_checkGC(L) { \
condhardstacktests(luaD_reallocstack(L, L- &amp; gt; stacksize - EXTRA_STACK - 1)); \
if (G(L)- &amp; gt; totalbytes &amp; gt; = G(L)- &amp; gt; GCthreshold) \
luaC_step(L); }


#define luaC_barrier(L,p,v) { if (valiswhite(v) &amp; &amp; isblack(obj2gco(p))) \
luaC_barrierf(L,obj2gco(p),gcvalue(v)); }

#define luaC_barriert(L,t,v) { if (valiswhite(v) &amp; &amp; isblack(obj2gco(t))) \
luaC_barrierback(L,t); }

#define luaC_objbarrier(L,p,o) \
{ if (iswhite(obj2gco(o)) &amp; &amp; isblack(obj2gco(p))) \
luaC_barrierf(L,obj2gco(p),obj2gco(o)); }

#define luaC_objbarriert(L,t,o) \
{ if (iswhite(obj2gco(o)) &amp; &amp; isblack(obj2gco(t))) luaC_barrierback(L,t); }

LUAI_FUNC size_t luaC_separateudata (lua_State *L, int all);
LUAI_FUNC void luaC_callGCTM (lua_State *L);
LUAI_FUNC void luaC_freeall (lua_State *L);
LUAI_FUNC void luaC_step (lua_State *L);
LUAI_FUNC void luaC_fullgc (lua_State *L);
LUAI_FUNC void luaC_link (lua_State *L, GCObject *o, lu_byte tt);
LUAI_FUNC void luaC_linkupval (lua_State *L, UpVal *uv);
LUAI_FUNC void luaC_barrierf (lua_State *L, GCObject *o, GCObject *v);
LUAI_FUNC void luaC_barrierback (lua_State *L, Table *t);


#endif


scite228.zip > llex.c

/*
** $Id$
** Lexical Analyzer
** See Copyright Notice in lua.h
*/


#include &amp; lt; ctype.h &amp; gt;
#include &amp; lt; locale.h &amp; gt;
#include &amp; lt; string.h &amp; gt;

#define llex_c
#define LUA_CORE

#include &quot; lua.h &quot;

#include &quot; ldo.h &quot;
#include &quot; llex.h &quot;
#include &quot; lobject.h &quot;
#include &quot; lparser.h &quot;
#include &quot; lstate.h &quot;
#include &quot; lstring.h &quot;
#include &quot; ltable.h &quot;
#include &quot; lzio.h &quot;



#define next(ls) (ls- &amp; gt; current = zgetc(ls- &amp; gt; z))




#define currIsNewline(ls) (ls- &amp; gt; current == '\n' || ls- &amp; gt; current == '\r')


/* ORDER RESERVED */
const char *const luaX_tokens [] = {
&quot; and &quot; , &quot; break &quot; , &quot; do &quot; , &quot; else &quot; , &quot; elseif &quot; ,
&quot; end &quot; , &quot; false &quot; , &quot; for &quot; , &quot; function &quot; , &quot; if &quot; ,
&quot; in &quot; , &quot; local &quot; , &quot; nil &quot; , &quot; not &quot; , &quot; or &quot; , &quot; repeat &quot; ,
&quot; return &quot; , &quot; then &quot; , &quot; true &quot; , &quot; until &quot; , &quot; while &quot; ,
&quot; .. &quot; , &quot; ... &quot; , &quot; == &quot; , &quot; &amp; gt; = &quot; , &quot; &amp; lt; = &quot; , &quot; ~= &quot; ,
&quot; &amp; lt; number &amp; gt; &quot; , &quot; &amp; lt; name &amp; gt; &quot; , &quot; &amp; lt; string &amp; gt; &quot; , &quot; &amp; lt; eof &amp; gt; &quot; ,
NULL
};


#define save_and_next(ls) (save(ls, ls- &amp; gt; current), next(ls))


static void save (LexState *ls, int c) {
Mbuffer *b = ls- &amp; gt; buff;
if (b- &amp; gt; n + 1 &amp; gt; b- &amp; gt; buffsize) {
size_t newsize;
if (b- &amp; gt; buffsize &amp; gt; = MAX_SIZET/2)
luaX_lexerror(ls, &quot; lexical element too long &quot; , 0);
newsize = b- &amp; gt; buffsize * 2;
luaZ_resizebuffer(ls- &amp; gt; L, b, newsize);
}
b- &amp; gt; buffer[b- &amp; gt; n++] = cast(char, c);
}


void luaX_init (lua_State *L) {
int i;
for (i=0; i &amp; lt; NUM_RESERVED; i++) {
TString *ts = luaS_new(L, luaX_tokens[i]);
luaS_fix(ts); /* reserved words are never collected */
lua_assert(strlen(luaX_tokens[i])+1 &amp; lt; = TOKEN_LEN);
ts- &amp; gt; tsv.reserved = cast_byte(i+1); /* reserved word */
}
}


#define MAXSRC 80


const char *luaX_token2str (LexState *ls, int token) {
if (token &amp; lt; FIRST_RESERVED) {
lua_assert(token == cast(unsigned char, token));
return (iscntrl(token)) ? luaO_pushfstring(ls- &amp; gt; L, &quot; char(%d) &quot; , token) :
luaO_pushfstring(ls- &amp; gt; L, &quot; %c &quot; , token);
}
else
return luaX_tokens[token-FIRST_RESERVED];
}


static const char *txtToken (LexState *ls, int token) {
switch (token) {
case TK_NAME:
case TK_STRING:
case TK_NUMBER:
save(ls, '\0');
return luaZ_buffer(ls- &amp; gt; buff);
default:
return luaX_token2str(ls, token);
}
}


void luaX_lexerror (LexState *ls, const char *msg, int token) {
char buff[MAXSRC];
luaO_chunkid(buff, getstr(ls- &amp; gt; source), MAXSRC);
msg = luaO_pushfstring(ls- &amp; gt; L, &quot; %s:%d: %s &quot; , buff, ls- &amp; gt; linenumber, msg);
if (token)
luaO_pushfstring(ls- &amp; gt; L, &quot; %s near &quot; LUA_QS, msg, txtToken(ls, token));
luaD_throw(ls- &amp; gt; L, LUA_ERRSYNTAX);
}


void luaX_syntaxerror (LexState *ls, const char *msg) {
luaX_lexerror(ls, msg, ls- &amp; gt; t.token);
}


TString *luaX_newstring (LexState *ls, const char *str, size_t l) {
lua_State *L = ls- &amp; gt; L;
TString *ts = luaS_newlstr(L, str, l);
TValue *o = luaH_setstr(L, ls- &amp; gt; fs- &amp; gt; h, ts); /* entry for `str' */
if (ttisnil(o))
setbvalue(o, 1); /* make sure `str' will not be collected */
return ts;
}


static void inclinenumber (LexState *ls) {
int old = ls- &amp; gt; current;
lua_assert(currIsNewline(ls));
next(ls); /* skip `\n' or `\r' */
if (currIsNewline(ls) &amp; &amp; ls- &amp; gt; current != old)
next(ls); /* skip `\n\r' or `\r\n' */
if (++ls- &amp; gt; linenumber &amp; gt; = MAX_INT)
luaX_syntaxerror(ls, &quot; chunk has too many lines &quot; );
}


void luaX_setinput (lua_State *L, LexState *ls, ZIO *z, TString *source) {
ls- &amp; gt; decpoint = '.';
ls- &amp; gt; L = L;
ls- &amp; gt; lookahead.token = TK_EOS; /* no look-ahead token */
ls- &amp; gt; z = z;
ls- &amp; gt; fs = NULL;
ls- &amp; gt; linenumber = 1;
ls- &amp; gt; lastline = 1;
ls- &amp; gt; source = source;
luaZ_resizebuffer(ls- &amp; gt; L, ls- &amp; gt; buff, LUA_MINBUFFER); /* initialize buffer */
next(ls); /* read first char */
}



/*
** =======================================================
** LEXICAL ANALYZER
** =======================================================
*/



static int check_next (LexState *ls, const char *set) {
if (!strchr(set, ls- &amp; gt; current))
return 0;
save_and_next(ls);
return 1;
}


static void buffreplace (LexState *ls, char from, char to) {
size_t n = luaZ_bufflen(ls- &amp; gt; buff);
char *p = luaZ_buffer(ls- &amp; gt; buff);
while (n--)
if (p[n] == from) p[n] = to;
}


static void trydecpoint (LexState *ls, SemInfo *seminfo) {
/* format error: try to update decimal point separator */
struct lconv *cv = localeconv();
char old = ls- &amp; gt; decpoint;
ls- &amp; gt; decpoint = (cv ? cv- &amp; gt; decimal_point[0] : '.');
buffreplace(ls, old, ls- &amp; gt; decpoint); /* try updated decimal separator */
if (!luaO_str2d(luaZ_buffer(ls- &amp; gt; buff), &amp; seminfo- &amp; gt; r)) {
/* format error with correct decimal point: no more options */
buffreplace(ls, ls- &amp; gt; decpoint, '.'); /* undo change (for error message) */
luaX_lexerror(ls, &quot; malformed number &quot; , TK_NUMBER);
}
}


/* LUA_NUMBER */
static void read_numeral (LexState *ls, SemInfo *seminfo) {
lua_assert(isdigit(ls- &amp; gt; current));
do {
save_and_next(ls);
} while (isdigit(ls- &amp; gt; current) || ls- &amp; gt; current == '.');
if (check_next(ls, &quot; Ee &quot; )) /* `E'? */
check_next(ls, &quot; +- &quot; ); /* optional exponent sign */
while (isalnum(ls- &amp; gt; current) || ls- &amp; gt; current == '_')
save_and_next(ls);
save(ls, '\0');
buffreplace(ls, '.', ls- &amp; gt; decpoint); /* follow locale for decimal point */
if (!luaO_str2d(luaZ_buffer(ls- &amp; gt; buff), &amp; seminfo- &amp; gt; r)) /* format error? */
trydecpoint(ls, seminfo); /* try to update decimal point separator */
}


static int skip_sep (LexState *ls) {
int count = 0;
int s = ls- &amp; gt; current;
lua_assert(s == '[' || s == ']');
save_and_next(ls);
while (ls- &amp; gt; current == '=') {
save_and_next(ls);
count++;
}
return (ls- &amp; gt; current == s) ? count : (-count) - 1;
}


static void read_long_string (LexState *ls, SemInfo *seminfo, int sep) {
int cont = 0;
(void)(cont); /* avoid warnings when `cont' is not used */
save_and_next(ls); /* skip 2nd `[' */
if (currIsNewline(ls)) /* string starts with a newline? */
inclinenumber(ls); /* skip it */
for (;;) {
switch (ls- &amp; gt; current) {
case EOZ:
luaX_lexerror(ls, (seminfo) ? &quot; unfinished long string &quot; :
&quot; unfinished long comment &quot; , TK_EOS);
break; /* to avoid warnings */
#if defined(LUA_COMPAT_LSTR)
case '[': {
if (skip_sep(ls) == sep) {
save_and_next(ls); /* skip 2nd `[' */
cont++;
#if LUA_COMPAT_LSTR == 1
if (sep == 0)
luaX_lexerror(ls, &quot; nesting of [[...]] is deprecated &quot; , '[');
#endif
}
break;
}
#endif
case ']': {
if (skip_sep(ls) == sep) {
save_and_next(ls); /* skip 2nd `]' */
#if defined(LUA_COMPAT_LSTR) &amp; &amp; LUA_COMPAT_LSTR == 2
cont--;
if (sep == 0 &amp; &amp; cont &amp; gt; = 0) break;
#endif
goto endloop;
}
break;
}
case '\n':
case '\r': {
save(ls, '\n');
inclinenumber(ls);
if (!seminfo) luaZ_resetbuffer(ls- &amp; gt; buff); /* avoid wasting space */
break;
}
default: {
if (seminfo) save_and_next(ls);
else next(ls);
}
}
} endloop:
if (seminfo)
seminfo- &amp; gt; ts = luaX_newstring(ls, luaZ_buffer(ls- &amp; gt; buff) + (2 + sep),
luaZ_bufflen(ls- &amp; gt; buff) - 2*(2 + sep));
}


static void read_string (LexState *ls, int del, SemInfo *seminfo) {
save_and_next(ls);
while (ls- &amp; gt; current != del) {
switch (ls- &amp; gt; current) {
case EOZ:
luaX_lexerror(ls, &quot; unfinished string &quot; , TK_EOS);
continue; /* to avoid warnings */
case '\n':
case '\r':
luaX_lexerror(ls, &quot; unfinished string &quot; , TK_STRING);
continue; /* to avoid warnings */
case '\\': {
int c;
next(ls); /* do not save the `\' */
switch (ls- &amp; gt; current) {
case 'a': c = '\a'; break;
case 'b': c = '\b'; break;
case 'f': c = '\f'; break;
case 'n': c = '\n'; break;
case 'r': c = '\r'; break;
case 't': c = '\t'; break;
case 'v': c = '\v'; break;
case '\n': /* go through */
case '\r': save(ls, '\n'); inclinenumber(ls); continue;
case EOZ: continue; /* will raise an error next loop */
default: {
if (!isdigit(ls- &amp; gt; current))
save_and_next(ls); /* handles \\, \ &quot; , \', and \? */
else { /* \xxx */
int i = 0;
c = 0;
do {
c = 10*c + (ls- &amp; gt; current-'0');
next(ls);
} while (++i &amp; lt; 3 &amp; &amp; isdigit(ls- &amp; gt; current));
if (c &amp; gt; UCHAR_MAX)
luaX_lexerror(ls, &quot; escape sequence too large &quot; , TK_STRING);
save(ls, c);
}
continue;
}
}
save(ls, c);
next(ls);
continue;
}
default:
save_and_next(ls);
}
}
save_and_next(ls); /* skip delimiter */
seminfo- &amp; gt; ts = luaX_newstring(ls, luaZ_buffer(ls- &amp; gt; buff) + 1,
luaZ_bufflen(ls- &amp; gt; buff) - 2);
}


static int llex (LexState *ls, SemInfo *seminfo) {
luaZ_resetbuffer(ls- &amp; gt; buff);
for (;;) {
switch (ls- &amp; gt; current) {
case '\n':
case '\r': {
inclinenumber(ls);
continue;
}
case '-': {
next(ls);
if (ls- &amp; gt; current != '-') return '-';
/* else is a comment */
next(ls);
if (ls- &amp; gt; current == '[') {
int sep = skip_sep(ls);
luaZ_resetbuffer(ls- &amp; gt; buff); /* `skip_sep' may dirty the buffer */
if (sep &amp; gt; = 0) {
read_long_string(ls, NULL, sep); /* long comment */
luaZ_resetbuffer(ls- &amp; gt; buff);
continue;
}
}
/* else short comment */
while (!currIsNewline(ls) &amp; &amp; ls- &amp; gt; current != EOZ)
next(ls);
continue;
}
case '[': {
int sep = skip_sep(ls);
if (sep &amp; gt; = 0) {
read_long_string(ls, seminfo, sep);
return TK_STRING;
}
else if (sep == -1) return '[';
else luaX_lexerror(ls, &quot; invalid long string delimiter &quot; , TK_STRING);
}
case '=': {
next(ls);
if (ls- &amp; gt; current != '=') return '=';
else { next(ls); return TK_EQ; }
}
case ' &amp; lt; ': {
next(ls);
if (ls- &amp; gt; current != '=') return ' &amp; lt; ';
else { next(ls); return TK_LE; }
}
case ' &amp; gt; ': {
next(ls);
if (ls- &amp; gt; current != '=') return ' &amp; gt; ';
else { next(ls); return TK_GE; }
}
case '~': {
next(ls);
if (ls- &amp; gt; current != '=') return '~';
else { next(ls); return TK_NE; }
}
case ' &quot; ':
case '\'': {
read_string(ls, ls- &amp; gt; current, seminfo);
return TK_STRING;
}
case '.': {
save_and_next(ls);
if (check_next(ls, &quot; . &quot; )) {
if (check_next(ls, &quot; . &quot; ))
return TK_DOTS; /* ... */
else return TK_CONCAT; /* .. */
}
else if (!isdigit(ls- &amp; gt; current)) return '.';
else {
read_numeral(ls, seminfo);
return TK_NUMBER;
}
}
case EOZ: {
return TK_EOS;
}
default: {
if (isspace(ls- &amp; gt; current)) {
lua_assert(!currIsNewline(ls));
next(ls);
continue;
}
else if (isdigit(ls- &amp; gt; current)) {
read_numeral(ls, seminfo);
return TK_NUMBER;
}
else if (isalpha(ls- &amp; gt; current) || ls- &amp; gt; current == '_') {
/* identifier or reserved word */
TString *ts;
do {
save_and_next(ls);
} while (isalnum(ls- &amp; gt; current) || ls- &amp; gt; current == '_');
ts = luaX_newstring(ls, luaZ_buffer(ls- &amp; gt; buff),
luaZ_bufflen(ls- &amp; gt; buff));
if (ts- &amp; gt; tsv.reserved &amp; gt; 0) /* reserved word? */
return ts- &amp; gt; tsv.reserved - 1 + FIRST_RESERVED;
else {
seminfo- &amp; gt; ts = ts;
return TK_NAME;
}
}
else {
int c = ls- &amp; gt; current;
next(ls);
return c; /* single-char tokens (+ - / ...) */
}
}
}
}
}


void luaX_next (LexState *ls) {
ls- &amp; gt; lastline = ls- &amp; gt; linenumber;
if (ls- &amp; gt; lookahead.token != TK_EOS) { /* is there a look-ahead token? */
ls- &amp; gt; t = ls- &amp; gt; lookahead; /* use this one */
ls- &amp; gt; lookahead.token = TK_EOS; /* and discharge it */
}
else
ls- &amp; gt; t.token = llex(ls, &amp; ls- &amp; gt; t.seminfo); /* read next token */
}


void luaX_lookahead (LexState *ls) {
lua_assert(ls- &amp; gt; lookahead.token == TK_EOS);
ls- &amp; gt; lookahead.token = llex(ls, &amp; ls- &amp; gt; lookahead.seminfo);
}


scite228.zip > ldo.h

/*
** $Id$
** Stack and Call structure of Lua
** See Copyright Notice in lua.h
*/

#ifndef ldo_h
#define ldo_h


#include &quot; lobject.h &quot;
#include &quot; lstate.h &quot;
#include &quot; lzio.h &quot;


#define luaD_checkstack(L,n) \
if ((char *)L- &amp; gt; stack_last - (char *)L- &amp; gt; top &amp; lt; = (n)*(int)sizeof(TValue)) \
luaD_growstack(L, n); \
else condhardstacktests(luaD_reallocstack(L, L- &amp; gt; stacksize - EXTRA_STACK - 1));


#define incr_top(L) {luaD_checkstack(L,1); L- &amp; gt; top++;}

#define savestack(L,p) ((char *)(p) - (char *)L- &amp; gt; stack)
#define restorestack(L,n) ((TValue *)((char *)L- &amp; gt; stack + (n)))

#define saveci(L,p) ((char *)(p) - (char *)L- &amp; gt; base_ci)
#define restoreci(L,n) ((CallInfo *)((char *)L- &amp; gt; base_ci + (n)))


/* results from luaD_precall */
#define PCRLUA 0 /* initiated a call to a Lua function */
#define PCRC 1 /* did a call to a C function */
#define PCRYIELD 2 /* C funtion yielded */


/* type of protected functions, to be ran by `runprotected' */
typedef void (*Pfunc) (lua_State *L, void *ud);

LUAI_FUNC int luaD_protectedparser (lua_State *L, ZIO *z, const char *name);
LUAI_FUNC void luaD_callhook (lua_State *L, int event, int line);
LUAI_FUNC int luaD_precall (lua_State *L, StkId func, int nresults);
LUAI_FUNC void luaD_call (lua_State *L, StkId func, int nResults);
LUAI_FUNC int luaD_pcall (lua_State *L, Pfunc func, void *u,
ptrdiff_t oldtop, ptrdiff_t ef);
LUAI_FUNC int luaD_poscall (lua_State *L, StkId firstResult);
LUAI_FUNC void luaD_reallocCI (lua_State *L, int newsize);
LUAI_FUNC void luaD_reallocstack (lua_State *L, int newsize);
LUAI_FUNC void luaD_growstack (lua_State *L, int n);

LUAI_FUNC void luaD_throw (lua_State *L, int errcode);
LUAI_FUNC int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud);

LUAI_FUNC void luaD_seterrorobj (lua_State *L, int errcode, StkId oldtop);

#endif


scite228.zip > liolib.c

/*
** $Id$
** Standard I/O (and system) library
** See Copyright Notice in lua.h
*/


#include &amp; lt; errno.h &amp; gt;
#include &amp; lt; stdio.h &amp; gt;
#include &amp; lt; stdlib.h &amp; gt;
#include &amp; lt; string.h &amp; gt;

#define liolib_c
#define LUA_LIB

#include &quot; lua.h &quot;

#include &quot; lauxlib.h &quot;
#include &quot; lualib.h &quot;



#define IO_INPUT 1
#define IO_OUTPUT 2


static const char *const fnames[] = { &quot; input &quot; , &quot; output &quot; };


static int pushresult (lua_State *L, int i, const char *filename) {
int en = errno; /* calls to Lua API may change this value */
if (i) {
lua_pushboolean(L, 1);
return 1;
}
else {
lua_pushnil(L);
if (filename)
lua_pushfstring(L, &quot; %s: %s &quot; , filename, strerror(en));
else
lua_pushfstring(L, &quot; %s &quot; , strerror(en));
lua_pushinteger(L, en);
return 3;
}
}


static void fileerror (lua_State *L, int arg, const char *filename) {
lua_pushfstring(L, &quot; %s: %s &quot; , filename, strerror(errno));
luaL_argerror(L, arg, lua_tostring(L, -1));
}


#define tofilep(L) ((FILE **)luaL_checkudata(L, 1, LUA_FILEHANDLE))


static int io_type (lua_State *L) {
void *ud;
luaL_checkany(L, 1);
ud = lua_touserdata(L, 1);
lua_getfield(L, LUA_REGISTRYINDEX, LUA_FILEHANDLE);
if (ud == NULL || !lua_getmetatable(L, 1) || !lua_rawequal(L, -2, -1))
lua_pushnil(L); /* not a file */
else if (*((FILE **)ud) == NULL)
lua_pushliteral(L, &quot; closed file &quot; );
else
lua_pushliteral(L, &quot; file &quot; );
return 1;
}


static FILE *tofile (lua_State *L) {
FILE **f = tofilep(L);
if (*f == NULL)
luaL_error(L, &quot; attempt to use a closed file &quot; );
return *f;
}



/*
** When creating file handles, always creates a `closed' file handle
** before opening the actual file; so, if there is a memory error, the
** file is not left opened.
*/
static FILE **newfile (lua_State *L) {
FILE **pf = (FILE **)lua_newuserdata(L, sizeof(FILE *));
*pf = NULL; /* file handle is currently `closed' */
luaL_getmetatable(L, LUA_FILEHANDLE);
lua_setmetatable(L, -2);
return pf;
}


/*
** function to (not) close the standard files stdin, stdout, and stderr
*/
static int io_noclose (lua_State *L) {
lua_pushnil(L);
lua_pushliteral(L, &quot; cannot close standard file &quot; );
return 2;
}


/*
** function to close 'popen' files
*/
static int io_pclose (lua_State *L) {
FILE **p = tofilep(L);
int ok = lua_pclose(L, *p);
*p = NULL;
return pushresult(L, ok, NULL);
}


/*
** function to close regular files
*/
static int io_fclose (lua_State *L) {
FILE **p = tofilep(L);
int ok = (fclose(*p) == 0);
*p = NULL;
return pushresult(L, ok, NULL);
}


static int aux_close (lua_State *L) {
lua_getfenv(L, 1);
lua_getfield(L, -1, &quot; __close &quot; );
return (lua_tocfunction(L, -1))(L);
}


static int io_close (lua_State *L) {
if (lua_isnone(L, 1))
lua_rawgeti(L, LUA_ENVIRONINDEX, IO_OUTPUT);
tofile(L); /* make sure argument is a file */
return aux_close(L);
}


static int io_gc (lua_State *L) {
FILE *f = *tofilep(L);
/* ignore closed files */
if (f != NULL)
aux_close(L);
return 0;
}


static int io_tostring (lua_State *L) {
FILE *f = *tofilep(L);
if (f == NULL)
lua_pushliteral(L, &quot; file (closed) &quot; );
else
lua_pushfstring(L, &quot; file (%p) &quot; , f);
return 1;
}


static int io_open (lua_State *L) {
const char *filename = luaL_checkstring(L, 1);
const char *mode = luaL_optstring(L, 2, &quot; r &quot; );
FILE **pf = newfile(L);
*pf = fopen(filename, mode);
return (*pf == NULL) ? pushresult(L, 0, filename) : 1;
}


/*
** this function has a separated environment, which defines the
** correct __close for 'popen' files
*/
static int io_popen (lua_State *L) {
const char *filename = luaL_checkstring(L, 1);
const char *mode = luaL_optstring(L, 2, &quot; r &quot; );
FILE **pf = newfile(L);
*pf = lua_popen(L, filename, mode);
return (*pf == NULL) ? pushresult(L, 0, filename) : 1;
}


static int io_tmpfile (lua_State *L) {
FILE **pf = newfile(L);
*pf = tmpfile();
return (*pf == NULL) ? pushresult(L, 0, NULL) : 1;
}


static FILE *getiofile (lua_State *L, int findex) {
FILE *f;
lua_rawgeti(L, LUA_ENVIRONINDEX, findex);
f = *(FILE **)lua_touserdata(L, -1);
if (f == NULL)
luaL_error(L, &quot; standard %s file is closed &quot; , fnames[findex - 1]);
return f;
}


static int g_iofile (lua_State *L, int f, const char *mode) {
if (!lua_isnoneornil(L, 1)) {
const char *filename = lua_tostring(L, 1);
if (filename) {
FILE **pf = newfile(L);
*pf = fopen(filename, mode);
if (*pf == NULL)
fileerror(L, 1, filename);
}
else {
tofile(L); /* check that it's a valid file handle */
lua_pushvalue(L, 1);
}
lua_rawseti(L, LUA_ENVIRONINDEX, f);
}
/* return current value */
lua_rawgeti(L, LUA_ENVIRONINDEX, f);
return 1;
}


static int io_input (lua_State *L) {
return g_iofile(L, IO_INPUT, &quot; r &quot; );
}


static int io_output (lua_State *L) {
return g_iofile(L, IO_OUTPUT, &quot; w &quot; );
}


static int io_readline (lua_State *L);


static void aux_lines (lua_State *L, int idx, int toclose) {
lua_pushvalue(L, idx);
lua_pushboolean(L, toclose); /* close/not close file when finished */
lua_pushcclosure(L, io_readline, 2);
}


static int f_lines (lua_State *L) {
tofile(L); /* check that it's a valid file handle */
aux_lines(L, 1, 0);
return 1;
}


static int io_lines (lua_State *L) {
if (lua_isnoneornil(L, 1)) { /* no arguments? */
/* will iterate over default input */
lua_rawgeti(L, LUA_ENVIRONINDEX, IO_INPUT);
return f_lines(L);
}
else {
const char *filename = luaL_checkstring(L, 1);
FILE **pf = newfile(L);
*pf = fopen(filename, &quot; r &quot; );
if (*pf == NULL)
fileerror(L, 1, filename);
aux_lines(L, lua_gettop(L), 1);
return 1;
}
}


/*
** {======================================================
** READ
** =======================================================
*/


static int read_number (lua_State *L, FILE *f) {
lua_Number d;
if (fscanf(f, LUA_NUMBER_SCAN, &amp; d) == 1) {
lua_pushnumber(L, d);
return 1;
}
else return 0; /* read fails */
}


static int test_eof (lua_State *L, FILE *f) {
int c = getc(f);
ungetc(c, f);
lua_pushlstring(L, NULL, 0);
return (c != EOF);
}


static int read_line (lua_State *L, FILE *f) {
luaL_Buffer b;
luaL_buffinit(L, &amp; b);
for (;;) {
size_t l;
char *p = luaL_prepbuffer( &amp; b);
if (fgets(p, LUAL_BUFFERSIZE, f) == NULL) { /* eof? */
luaL_pushresult( &amp; b); /* close buffer */
return (lua_objlen(L, -1) &amp; gt; 0); /* check whether read something */
}
l = strlen(p);
if (l == 0 || p[l-1] != '\n')
luaL_addsize( &amp; b, l);
else {
luaL_addsize( &amp; b, l - 1); /* do not include `eol' */
luaL_pushresult( &amp; b); /* close buffer */
return 1; /* read at least an `eol' */
}
}
}


static int read_chars (lua_State *L, FILE *f, size_t n) {
size_t rlen; /* how much to read */
size_t nr; /* number of chars actually read */
luaL_Buffer b;
luaL_buffinit(L, &amp; b);
rlen = LUAL_BUFFERSIZE; /* try to read that much each time */
do {
char *p = luaL_prepbuffer( &amp; b);
if (rlen &amp; gt; n) rlen = n; /* cannot read more than asked */
nr = fread(p, sizeof(char), rlen, f);
luaL_addsize( &amp; b, nr);
n -= nr; /* still have to read `n' chars */
} while (n &amp; gt; 0 &amp; &amp; nr == rlen); /* until end of count or eof */
luaL_pushresult( &amp; b); /* close buffer */
return (n == 0 || lua_objlen(L, -1) &amp; gt; 0);
}


static int g_read (lua_State *L, FILE *f, int first) {
int nargs = lua_gettop(L) - 1;
int success;
int n;
clearerr(f);
if (nargs == 0) { /* no arguments? */
success = read_line(L, f);
n = first+1; /* to return 1 result */
}
else { /* ensure stack space for all results and for auxlib's buffer */
luaL_checkstack(L, nargs+LUA_MINSTACK, &quot; too many arguments &quot; );
success = 1;
for (n = first; nargs-- &amp; &amp; success; n++) {
if (lua_type(L, n) == LUA_TNUMBER) {
size_t l = (size_t)lua_tointeger(L, n);
success = (l == 0) ? test_eof(L, f) : read_chars(L, f, l);
}
else {
const char *p = lua_tostring(L, n);
luaL_argcheck(L, p &amp; &amp; p[0] == '*', n, &quot; invalid option &quot; );
switch (p[1]) {
case 'n': /* number */
success = read_number(L, f);
break;
case 'l': /* line */
success = read_line(L, f);
break;
case 'a': /* file */
read_chars(L, f, ~((size_t)0)); /* read MAX_SIZE_T chars */
success = 1; /* always success */
break;
default:
return luaL_argerror(L, n, &quot; invalid format &quot; );
}
}
}
}
if (ferror(f))
return pushresult(L, 0, NULL);
if (!success) {
lua_pop(L, 1); /* remove last result */
lua_pushnil(L); /* push nil instead */
}
return n - first;
}


static int io_read (lua_State *L) {
return g_read(L, getiofile(L, IO_INPUT), 1);
}


static int f_read (lua_State *L) {
return g_read(L, tofile(L), 2);
}


static int io_readline (lua_State *L) {
FILE *f = *(FILE **)lua_touserdata(L, lua_upvalueindex(1));
int sucess;
if (f == NULL) /* file is already closed? */
luaL_error(L, &quot; file is already closed &quot; );
sucess = read_line(L, f);
if (ferror(f))
return luaL_error(L, &quot; %s &quot; , strerror(errno));
if (sucess) return 1;
else { /* EOF */
if (lua_toboolean(L, lua_upvalueindex(2))) { /* generator created file? */
lua_settop(L, 0);
lua_pushvalue(L, lua_upvalueindex(1));
aux_close(L); /* close it */
}
return 0;
}
}

/* }====================================================== */


static int g_write (lua_State *L, FILE *f, int arg) {
int nargs = lua_gettop(L) - 1;
int status = 1;
for (; nargs--; arg++) {
if (lua_type(L, arg) == LUA_TNUMBER) {
/* optimization: could be done exactly as for strings */
status = status &amp; &amp;
fprintf(f, LUA_NUMBER_FMT, lua_tonumber(L, arg)) &amp; gt; 0;
}
else {
size_t l;
const char *s = luaL_checklstring(L, arg, &amp; l);
status = status &amp; &amp; (fwrite(s, sizeof(char), l, f) == l);
}
}
return pushresult(L, status, NULL);
}


static int io_write (lua_State *L) {
return g_write(L, getiofile(L, IO_OUTPUT), 1);
}


static int f_write (lua_State *L) {
return g_write(L, tofile(L), 2);
}


static int f_seek (lua_State *L) {
static const int mode[] = {SEEK_SET, SEEK_CUR, SEEK_END};
static const char *const modenames[] = { &quot; set &quot; , &quot; cur &quot; , &quot; end &quot; , NULL};
FILE *f = tofile(L);
int op = luaL_checkoption(L, 2, &quot; cur &quot; , modenames);
long offset = luaL_optlong(L, 3, 0);
op = fseek(f, offset, mode[op]);
if (op)
return pushresult(L, 0, NULL); /* error */
else {
lua_pushinteger(L, ftell(f));
return 1;
}
}


static int f_setvbuf (lua_State *L) {
static const int mode[] = {_IONBF, _IOFBF, _IOLBF};
static const char *const modenames[] = { &quot; no &quot; , &quot; full &quot; , &quot; line &quot; , NULL};
FILE *f = tofile(L);
int op = luaL_checkoption(L, 2, NULL, modenames);
lua_Integer sz = luaL_optinteger(L, 3, LUAL_BUFFERSIZE);
int res = setvbuf(f, NULL, mode[op], sz);
return pushresult(L, res == 0, NULL);
}



static int io_flush (lua_State *L) {
return pushresult(L, fflush(getiofile(L, IO_OUTPUT)) == 0, NULL);
}


static int f_flush (lua_State *L) {
return pushresult(L, fflush(tofile(L)) == 0, NULL);
}


static const luaL_Reg iolib[] = {
{ &quot; close &quot; , io_close},
{ &quot; flush &quot; , io_flush},
{ &quot; input &quot; , io_input},
{ &quot; lines &quot; , io_lines},
{ &quot; open &quot; , io_open},
{ &quot; output &quot; , io_output},
{ &quot; popen &quot; , io_popen},
{ &quot; read &quot; , io_read},
{ &quot; tmpfile &quot; , io_tmpfile},
{ &quot; type &quot; , io_type},
{ &quot; write &quot; , io_write},
{NULL, NULL}
};


static const luaL_Reg flib[] = {
{ &quot; close &quot; , io_close},
{ &quot; flush &quot; , f_flush},
{ &quot; lines &quot; , f_lines},
{ &quot; read &quot; , f_read},
{ &quot; seek &quot; , f_seek},
{ &quot; setvbuf &quot; , f_setvbuf},
{ &quot; write &quot; , f_write},
{ &quot; __gc &quot; , io_gc},
{ &quot; __tostring &quot; , io_tostring},
{NULL, NULL}
};


static void createmeta (lua_State *L) {
luaL_newmetatable(L, LUA_FILEHANDLE); /* create metatable for file handles */
lua_pushvalue(L, -1); /* push metatable */
lua_setfield(L, -2, &quot; __index &quot; ); /* metatable.__index = metatable */
luaL_register(L, NULL, flib); /* file methods */
}


static void createstdfile (lua_State *L, FILE *f, int k, const char *fname) {
*newfile(L) = f;
if (k &amp; gt; 0) {
lua_pushvalue(L, -1);
lua_rawseti(L, LUA_ENVIRONINDEX, k);
}
lua_pushvalue(L, -2); /* copy environment */
lua_setfenv(L, -2); /* set it */
lua_setfield(L, -3, fname);
}


static void newfenv (lua_State *L, lua_CFunction cls) {
lua_createtable(L, 0, 1);
lua_pushcfunction(L, cls);
lua_setfield(L, -2, &quot; __close &quot; );
}


LUALIB_API int luaopen_io (lua_State *L) {
createmeta(L);
/* create (private) environment (with fields IO_INPUT, IO_OUTPUT, __close) */
newfenv(L, io_fclose);
lua_replace(L, LUA_ENVIRONINDEX);
/* open library */
luaL_register(L, LUA_IOLIBNAME, iolib);
/* create (and set) default files */
newfenv(L, io_noclose); /* close function for default files */
createstdfile(L, stdin, IO_INPUT, &quot; stdin &quot; );
createstdfile(L, stdout, IO_OUTPUT, &quot; stdout &quot; );
createstdfile(L, stderr, 0, &quot; stderr &quot; );
lua_pop(L, 1); /* pop environment for default files */
lua_getfield(L, -1, &quot; popen &quot; );
newfenv(L, io_pclose); /* create environment for 'popen' */
lua_setfenv(L, -2); /* set fenv for 'popen' */
lua_pop(L, 1); /* pop 'popen' */
return 1;
}


scite228.zip > ldblib.c

/*
** $Id$
** Interface from Lua to its debug API
** See Copyright Notice in lua.h
*/


#include &amp; lt; stdio.h &amp; gt;
#include &amp; lt; stdlib.h &amp; gt;
#include &amp; lt; string.h &amp; gt;

#define ldblib_c
#define LUA_LIB

#include &quot; lua.h &quot;

#include &quot; lauxlib.h &quot;
#include &quot; lualib.h &quot;



static int db_getregistry (lua_State *L) {
lua_pushvalue(L, LUA_REGISTRYINDEX);
return 1;
}


static int db_getmetatable (lua_State *L) {
luaL_checkany(L, 1);
if (!lua_getmetatable(L, 1)) {
lua_pushnil(L); /* no metatable */
}
return 1;
}


static int db_setmetatable (lua_State *L) {
int t = lua_type(L, 2);
luaL_argcheck(L, t == LUA_TNIL || t == LUA_TTABLE, 2,
&quot; nil or table expected &quot; );
lua_settop(L, 2);
lua_pushboolean(L, lua_setmetatable(L, 1));
return 1;
}


static int db_getfenv (lua_State *L) {
lua_getfenv(L, 1);
return 1;
}


static int db_setfenv (lua_State *L) {
luaL_checktype(L, 2, LUA_TTABLE);
lua_settop(L, 2);
if (lua_setfenv(L, 1) == 0)
luaL_error(L, LUA_QL( &quot; setfenv &quot; )
&quot; cannot change environment of given object &quot; );
return 1;
}


static void settabss (lua_State *L, const char *i, const char *v) {
lua_pushstring(L, v);
lua_setfield(L, -2, i);
}


static void settabsi (lua_State *L, const char *i, int v) {
lua_pushinteger(L, v);
lua_setfield(L, -2, i);
}


static lua_State *getthread (lua_State *L, int *arg) {
if (lua_isthread(L, 1)) {
*arg = 1;
return lua_tothread(L, 1);
}
else {
*arg = 0;
return L;
}
}


static void treatstackoption (lua_State *L, lua_State *L1, const char *fname) {
if (L == L1) {
lua_pushvalue(L, -2);
lua_remove(L, -3);
}
else
lua_xmove(L1, L, 1);
lua_setfield(L, -2, fname);
}


static int db_getinfo (lua_State *L) {
lua_Debug ar;
int arg;
lua_State *L1 = getthread(L, &amp; arg);
const char *options = luaL_optstring(L, arg+2, &quot; flnSu &quot; );
if (lua_isnumber(L, arg+1)) {
if (!lua_getstack(L1, (int)lua_tointeger(L, arg+1), &amp; ar)) {
lua_pushnil(L); /* level out of range */
return 1;
}
}
else if (lua_isfunction(L, arg+1)) {
lua_pushfstring(L, &quot; &amp; gt; %s &quot; , options);
options = lua_tostring(L, -1);
lua_pushvalue(L, arg+1);
lua_xmove(L, L1, 1);
}
else
return luaL_argerror(L, arg+1, &quot; function or level expected &quot; );
if (!lua_getinfo(L1, options, &amp; ar))
return luaL_argerror(L, arg+2, &quot; invalid option &quot; );
lua_createtable(L, 0, 2);
if (strchr(options, 'S')) {
settabss(L, &quot; source &quot; , ar.source);
settabss(L, &quot; short_src &quot; , ar.short_src);
settabsi(L, &quot; linedefined &quot; , ar.linedefined);
settabsi(L, &quot; lastlinedefined &quot; , ar.lastlinedefined);
settabss(L, &quot; what &quot; , ar.what);
}
if (strchr(options, 'l'))
settabsi(L, &quot; currentline &quot; , ar.currentline);
if (strchr(options, 'u'))
settabsi(L, &quot; nups &quot; , ar.nups);
if (strchr(options, 'n')) {
settabss(L, &quot; name &quot; , ar.name);
settabss(L, &quot; namewhat &quot; , ar.namewhat);
}
if (strchr(options, 'L'))
treatstackoption(L, L1, &quot; activelines &quot; );
if (strchr(options, 'f'))
treatstackoption(L, L1, &quot; func &quot; );
return 1; /* return table */
}


static int db_getlocal (lua_State *L) {
int arg;
lua_State *L1 = getthread(L, &amp; arg);
lua_Debug ar;
const char *name;
if (!lua_getstack(L1, luaL_checkint(L, arg+1), &amp; ar)) /* out of range? */
return luaL_argerror(L, arg+1, &quot; level out of range &quot; );
name = lua_getlocal(L1, &amp; ar, luaL_checkint(L, arg+2));
if (name) {
lua_xmove(L1, L, 1);
lua_pushstring(L, name);
lua_pushvalue(L, -2);
return 2;
}
else {
lua_pushnil(L);
return 1;
}
}


static int db_setlocal (lua_State *L) {
int arg;
lua_State *L1 = getthread(L, &amp; arg);
lua_Debug ar;
if (!lua_getstack(L1, luaL_checkint(L, arg+1), &amp; ar)) /* out of range? */
return luaL_argerror(L, arg+1, &quot; level out of range &quot; );
luaL_checkany(L, arg+3);
lua_settop(L, arg+3);
lua_xmove(L, L1, 1);
lua_pushstring(L, lua_setlocal(L1, &amp; ar, luaL_checkint(L, arg+2)));
return 1;
}


static int auxupvalue (lua_State *L, int get) {
const char *name;
int n = luaL_checkint(L, 2);
luaL_checktype(L, 1, LUA_TFUNCTION);
if (lua_iscfunction(L, 1)) return 0; /* cannot touch C upvalues from Lua */
name = get ? lua_getupvalue(L, 1, n) : lua_setupvalue(L, 1, n);
if (name == NULL) return 0;
lua_pushstring(L, name);
lua_insert(L, -(get+1));
return get + 1;
}


static int db_getupvalue (lua_State *L) {
return auxupvalue(L, 1);
}


static int db_setupvalue (lua_State *L) {
luaL_checkany(L, 3);
return auxupvalue(L, 0);
}



static const char KEY_HOOK = 'h';


static void hookf (lua_State *L, lua_Debug *ar) {
static const char *const hooknames[] =
{ &quot; call &quot; , &quot; return &quot; , &quot; line &quot; , &quot; count &quot; , &quot; tail return &quot; };
lua_pushlightuserdata(L, (void *) &amp; KEY_HOOK);
lua_rawget(L, LUA_REGISTRYINDEX);
lua_pushlightuserdata(L, L);
lua_rawget(L, -2);
if (lua_isfunction(L, -1)) {
lua_pushstring(L, hooknames[(int)ar- &amp; gt; event]);
if (ar- &amp; gt; currentline &amp; gt; = 0)
lua_pushinteger(L, ar- &amp; gt; currentline);
else lua_pushnil(L);
lua_assert(lua_getinfo(L, &quot; lS &quot; , ar));
lua_call(L, 2, 0);
}
}


static int makemask (const char *smask, int count) {
int mask = 0;
if (strchr(smask, 'c')) mask |= LUA_MASKCALL;
if (strchr(smask, 'r')) mask |= LUA_MASKRET;
if (strchr(smask, 'l')) mask |= LUA_MASKLINE;
if (count &amp; gt; 0) mask |= LUA_MASKCOUNT;
return mask;
}


static char *unmakemask (int mask, char *smask) {
int i = 0;
if (mask &amp; LUA_MASKCALL) smask[i++] = 'c';
if (mask &amp; LUA_MASKRET) smask[i++] = 'r';
if (mask &amp; LUA_MASKLINE) smask[i++] = 'l';
smask[i] = '\0';
return smask;
}


static void gethooktable (lua_State *L) {
lua_pushlightuserdata(L, (void *) &amp; KEY_HOOK);
lua_rawget(L, LUA_REGISTRYINDEX);
if (!lua_istable(L, -1)) {
lua_pop(L, 1);
lua_createtable(L, 0, 1);
lua_pushlightuserdata(L, (void *) &amp; KEY_HOOK);
lua_pushvalue(L, -2);
lua_rawset(L, LUA_REGISTRYINDEX);
}
}


static int db_sethook (lua_State *L) {
int arg, mask, count;
lua_Hook func;
lua_State *L1 = getthread(L, &amp; arg);
if (lua_isnoneornil(L, arg+1)) {
lua_settop(L, arg+1);
func = NULL; mask = 0; count = 0; /* turn off hooks */
}
else {
const char *smask = luaL_checkstring(L, arg+2);
luaL_checktype(L, arg+1, LUA_TFUNCTION);
count = luaL_optint(L, arg+3, 0);
func = hookf; mask = makemask(smask, count);
}
gethooktable(L);
lua_pushlightuserdata(L, L1);
lua_pushvalue(L, arg+1);
lua_rawset(L, -3); /* set new hook */
lua_pop(L, 1); /* remove hook table */
lua_sethook(L1, func, mask, count); /* set hooks */
return 0;
}


static int db_gethook (lua_State *L) {
int arg;
lua_State *L1 = getthread(L, &amp; arg);
char buff[5];
int mask = lua_gethookmask(L1);
lua_Hook hook = lua_gethook(L1);
if (hook != NULL &amp; &amp; hook != hookf) /* external hook? */
lua_pushliteral(L, &quot; external hook &quot; );
else {
gethooktable(L);
lua_pushlightuserdata(L, L1);
lua_rawget(L, -2); /* get hook */
lua_remove(L, -2); /* remove hook table */
}
lua_pushstring(L, unmakemask(mask, buff));
lua_pushinteger(L, lua_gethookcount(L1));
return 3;
}


static int db_debug (lua_State *L) {
for (;;) {
char buffer[250];
fputs( &quot; lua_debug &amp; gt; &quot; , stderr);
if (fgets(buffer, sizeof(buffer), stdin) == 0 ||
strcmp(buffer, &quot; cont\n &quot; ) == 0)
return 0;
if (luaL_loadbuffer(L, buffer, strlen(buffer), &quot; =(debug command) &quot; ) ||
lua_pcall(L, 0, 0, 0)) {
fputs(lua_tostring(L, -1), stderr);
fputs( &quot; \n &quot; , stderr);
}
lua_settop(L, 0); /* remove eventual returns */
}
}


#define LEVELS1 12 /* size of the first part of the stack */
#define LEVELS2 10 /* size of the second part of the stack */

static int db_errorfb (lua_State *L) {
int level;
int firstpart = 1; /* still before eventual `...' */
int arg;
lua_State *L1 = getthread(L, &amp; arg);
lua_Debug ar;
if (lua_isnumber(L, arg+2)) {
level = (int)lua_tointeger(L, arg+2);
lua_pop(L, 1);
}
else
level = (L == L1) ? 1 : 0; /* level 0 may be this own function */
if (lua_gettop(L) == arg)
lua_pushliteral(L, &quot; &quot; );
else if (!lua_isstring(L, arg+1)) return 1; /* message is not a string */
else lua_pushliteral(L, &quot; \n &quot; );
lua_pushliteral(L, &quot; stack traceback: &quot; );
while (lua_getstack(L1, level++, &amp; ar)) {
if (level &amp; gt; LEVELS1 &amp; &amp; firstpart) {
/* no more than `LEVELS2' more levels? */
if (!lua_getstack(L1, level+LEVELS2, &amp; ar))
level--; /* keep going */
else {
lua_pushliteral(L, &quot; \n\t... &quot; ); /* too many levels */
while (lua_getstack(L1, level+LEVELS2, &amp; ar)) /* find last levels */
level++;
}
firstpart = 0;
continue;
}
lua_pushliteral(L, &quot; \n\t &quot; );
lua_getinfo(L1, &quot; Snl &quot; , &amp; ar);
lua_pushfstring(L, &quot; %s: &quot; , ar.short_src);
if (ar.currentline &amp; gt; 0)
lua_pushfstring(L, &quot; %d: &quot; , ar.currentline);
if (*ar.namewhat != '\0') /* is there a name? */
lua_pushfstring(L, &quot; in function &quot; LUA_QS, ar.name);
else {
if (*ar.what == 'm') /* main? */
lua_pushfstring(L, &quot; in main chunk &quot; );
else if (*ar.what == 'C' || *ar.what == 't')
lua_pushliteral(L, &quot; ? &quot; ); /* C function or tail call */
else
lua_pushfstring(L, &quot; in function &amp; lt; %s:%d &amp; gt; &quot; ,
ar.short_src, ar.linedefined);
}
lua_concat(L, lua_gettop(L) - arg);
}
lua_concat(L, lua_gettop(L) - arg);
return 1;
}


static const luaL_Reg dblib[] = {
{ &quot; debug &quot; , db_debug},
{ &quot; getfenv &quot; , db_getfenv},
{ &quot; gethook &quot; , db_gethook},
{ &quot; getinfo &quot; , db_getinfo},
{ &quot; getlocal &quot; , db_getlocal},
{ &quot; getregistry &quot; , db_getregistry},
{ &quot; getmetatable &quot; , db_getmetatable},
{ &quot; getupvalue &quot; , db_getupvalue},
{ &quot; setfenv &quot; , db_setfenv},
{ &quot; sethook &quot; , db_sethook},
{ &quot; setlocal &quot; , db_setlocal},
{ &quot; setmetatable &quot; , db_setmetatable},
{ &quot; setupvalue &quot; , db_setupvalue},
{ &quot; traceback &quot; , db_errorfb},
{NULL, NULL}
};


LUALIB_API int luaopen_debug (lua_State *L) {
luaL_register(L, LUA_DBLIBNAME, dblib);
return 1;
}


scite228.zip > lbaselib.c

/*
** $Id$
** Basic library
** See Copyright Notice in lua.h
*/



#include &amp; lt; ctype.h &amp; gt;
#include &amp; lt; stdio.h &amp; gt;
#include &amp; lt; stdlib.h &amp; gt;
#include &amp; lt; string.h &amp; gt;

#define lbaselib_c
#define LUA_LIB

#include &quot; lua.h &quot;

#include &quot; lauxlib.h &quot;
#include &quot; lualib.h &quot;




/*
** If your system does not support `stdout', you can just remove this function.
** If you need, you can define your own `print' function, following this
** model but changing `fputs' to put the strings at a proper place
** (a console window or a log file, for instance).
*/
static int luaB_print (lua_State *L) {
int n = lua_gettop(L); /* number of arguments */
int i;
lua_getglobal(L, &quot; tostring &quot; );
for (i=1; i &amp; lt; =n; i++) {
const char *s;
lua_pushvalue(L, -1); /* function to be called */
lua_pushvalue(L, i); /* value to print */
lua_call(L, 1, 1);
s = lua_tostring(L, -1); /* get result */
if (s == NULL)
return luaL_error(L, LUA_QL( &quot; tostring &quot; ) &quot; must return a string to &quot;
LUA_QL( &quot; print &quot; ));
if (i &amp; gt; 1) fputs( &quot; \t &quot; , stdout);
fputs(s, stdout);
lua_pop(L, 1); /* pop result */
}
fputs( &quot; \n &quot; , stdout);
return 0;
}


static int luaB_tonumber (lua_State *L) {
int base = luaL_optint(L, 2, 10);
if (base == 10) { /* standard conversion */
luaL_checkany(L, 1);
if (lua_isnumber(L, 1)) {
lua_pushnumber(L, lua_tonumber(L, 1));
return 1;
}
}
else {
const char *s1 = luaL_checkstring(L, 1);
char *s2;
unsigned long n;
luaL_argcheck(L, 2 &amp; lt; = base &amp; &amp; base &amp; lt; = 36, 2, &quot; base out of range &quot; );
n = strtoul(s1, &amp; s2, base);
if (s1 != s2) { /* at least one valid digit? */
while (isspace((unsigned char)(*s2))) s2++; /* skip trailing spaces */
if (*s2 == '\0') { /* no invalid trailing characters? */
lua_pushnumber(L, (lua_Number)n);
return 1;
}
}
}
lua_pushnil(L); /* else not a number */
return 1;
}


static int luaB_error (lua_State *L) {
int level = luaL_optint(L, 2, 1);
lua_settop(L, 1);
if (lua_isstring(L, 1) &amp; &amp; level &amp; gt; 0) { /* add extra information? */
luaL_where(L, level);
lua_pushvalue(L, 1);
lua_concat(L, 2);
}
return lua_error(L);
}


static int luaB_getmetatable (lua_State *L) {
luaL_checkany(L, 1);
if (!lua_getmetatable(L, 1)) {
lua_pushnil(L);
return 1; /* no metatable */
}
luaL_getmetafield(L, 1, &quot; __metatable &quot; );
return 1; /* returns either __metatable field (if present) or metatable */
}


static int luaB_setmetatable (lua_State *L) {
int t = lua_type(L, 2);
luaL_checktype(L, 1, LUA_TTABLE);
luaL_argcheck(L, t == LUA_TNIL || t == LUA_TTABLE, 2,
&quot; nil or table expected &quot; );
if (luaL_getmetafield(L, 1, &quot; __metatable &quot; ))
luaL_error(L, &quot; cannot change a protected metatable &quot; );
lua_settop(L, 2);
lua_setmetatable(L, 1);
return 1;
}


static void getfunc (lua_State *L, int opt) {
if (lua_isfunction(L, 1)) lua_pushvalue(L, 1);
else {
lua_Debug ar;
int level = opt ? luaL_optint(L, 1, 1) : luaL_checkint(L, 1);
luaL_argcheck(L, level &amp; gt; = 0, 1, &quot; level must be non-negative &quot; );
if (lua_getstack(L, level, &amp; ar) == 0)
luaL_argerror(L, 1, &quot; invalid level &quot; );
lua_getinfo(L, &quot; f &quot; , &amp; ar);
if (lua_isnil(L, -1))
luaL_error(L, &quot; no function environment for tail call at level %d &quot; ,
level);
}
}


static int luaB_getfenv (lua_State *L) {
getfunc(L, 1);
if (lua_iscfunction(L, -1)) /* is a C function? */
lua_pushvalue(L, LUA_GLOBALSINDEX); /* return the thread's global env. */
else
lua_getfenv(L, -1);
return 1;
}


static int luaB_setfenv (lua_State *L) {
luaL_checktype(L, 2, LUA_TTABLE);
getfunc(L, 0);
lua_pushvalue(L, 2);
if (lua_isnumber(L, 1) &amp; &amp; lua_tonumber(L, 1) == 0) {
/* change environment of current thread */
lua_pushthread(L);
lua_insert(L, -2);
lua_setfenv(L, -2);
return 0;
}
else if (lua_iscfunction(L, -2) || lua_setfenv(L, -2) == 0)
luaL_error(L,
LUA_QL( &quot; setfenv &quot; ) &quot; cannot change environment of given object &quot; );
return 1;
}


static int luaB_rawequal (lua_State *L) {
luaL_checkany(L, 1);
luaL_checkany(L, 2);
lua_pushboolean(L, lua_rawequal(L, 1, 2));
return 1;
}


static int luaB_rawget (lua_State *L) {
luaL_checktype(L, 1, LUA_TTABLE);
luaL_checkany(L, 2);
lua_settop(L, 2);
lua_rawget(L, 1);
return 1;
}

static int luaB_rawset (lua_State *L) {
luaL_checktype(L, 1, LUA_TTABLE);
luaL_checkany(L, 2);
luaL_checkany(L, 3);
lua_settop(L, 3);
lua_rawset(L, 1);
return 1;
}


static int luaB_gcinfo (lua_State *L) {
lua_pushinteger(L, lua_getgccount(L));
return 1;
}


static int luaB_collectgarbage (lua_State *L) {
static const char *const opts[] = { &quot; stop &quot; , &quot; restart &quot; , &quot; collect &quot; ,
&quot; count &quot; , &quot; step &quot; , &quot; setpause &quot; , &quot; setstepmul &quot; , NULL};
static const int optsnum[] = {LUA_GCSTOP, LUA_GCRESTART, LUA_GCCOLLECT,
LUA_GCCOUNT, LUA_GCSTEP, LUA_GCSETPAUSE, LUA_GCSETSTEPMUL};
int o = luaL_checkoption(L, 1, &quot; collect &quot; , opts);
int ex = luaL_optint(L, 2, 0);
int res = lua_gc(L, optsnum[o], ex);
switch (optsnum[o]) {
case LUA_GCCOUNT: {
int b = lua_gc(L, LUA_GCCOUNTB, 0);
lua_pushnumber(L, res + ((lua_Number)b/1024));
return 1;
}
case LUA_GCSTEP: {
lua_pushboolean(L, res);
return 1;
}
default: {
lua_pushnumber(L, res);
return 1;
}
}
}


static int luaB_type (lua_State *L) {
luaL_checkany(L, 1);
lua_pushstring(L, luaL_typename(L, 1));
return 1;
}


static int luaB_next (lua_State *L) {
luaL_checktype(L, 1, LUA_TTABLE);
lua_settop(L, 2); /* create a 2nd argument if there isn't one */
if (lua_next(L, 1))
return 2;
else {
lua_pushnil(L);
return 1;
}
}


static int luaB_pairs (lua_State *L) {
luaL_checktype(L, 1, LUA_TTABLE);
lua_pushvalue(L, lua_upvalueindex(1)); /* return generator, */
lua_pushvalue(L, 1); /* state, */
lua_pushnil(L); /* and initial value */
return 3;
}


static int ipairsaux (lua_State *L) {
int i = luaL_checkint(L, 2);
luaL_checktype(L, 1, LUA_TTABLE);
i++; /* next value */
lua_pushinteger(L, i);
lua_rawgeti(L, 1, i);
return (lua_isnil(L, -1)) ? 0 : 2;
}


static int luaB_ipairs (lua_State *L) {
luaL_checktype(L, 1, LUA_TTABLE);
lua_pushvalue(L, lua_upvalueindex(1)); /* return generator, */
lua_pushvalue(L, 1); /* state, */
lua_pushinteger(L, 0); /* and initial value */
return 3;
}


static int load_aux (lua_State *L, int status) {
if (status == 0) /* OK? */
return 1;
else {
lua_pushnil(L);
lua_insert(L, -2); /* put before error message */
return 2; /* return nil plus error message */
}
}


static int luaB_loadstring (lua_State *L) {
size_t l;
const char *s = luaL_checklstring(L, 1, &amp; l);
const char *chunkname = luaL_optstring(L, 2, s);
return load_aux(L, luaL_loadbuffer(L, s, l, chunkname));
}


static int luaB_loadfile (lua_State *L) {
const char *fname = luaL_optstring(L, 1, NULL);
return load_aux(L, luaL_loadfile(L, fname));
}


/*
** Reader for generic `load' function: `lua_load' uses the
** stack for internal stuff, so the reader cannot change the
** stack top. Instead, it keeps its resulting string in a
** reserved slot inside the stack.
*/
static const char *generic_reader (lua_State *L, void *ud, size_t *size) {
(void)ud; /* to avoid warnings */
luaL_checkstack(L, 2, &quot; too many nested functions &quot; );
lua_pushvalue(L, 1); /* get function */
lua_call(L, 0, 1); /* call it */
if (lua_isnil(L, -1)) {
*size = 0;
return NULL;
}
else if (lua_isstring(L, -1)) {
lua_replace(L, 3); /* save string in a reserved stack slot */
return lua_tolstring(L, 3, size);
}
else luaL_error(L, &quot; reader function must return a string &quot; );
return NULL; /* to avoid warnings */
}


static int luaB_load (lua_State *L) {
int status;
const char *cname = luaL_optstring(L, 2, &quot; =(load) &quot; );
luaL_checktype(L, 1, LUA_TFUNCTION);
lua_settop(L, 3); /* function, eventual name, plus one reserved slot */
status = lua_load(L, generic_reader, NULL, cname);
return load_aux(L, status);
}


static int luaB_dofile (lua_State *L) {
const char *fname = luaL_optstring(L, 1, NULL);
int n = lua_gettop(L);
if (luaL_loadfile(L, fname) != 0) lua_error(L);
lua_call(L, 0, LUA_MULTRET);
return lua_gettop(L) - n;
}


static int luaB_assert (lua_State *L) {
luaL_checkany(L, 1);
if (!lua_toboolean(L, 1))
return luaL_error(L, &quot; %s &quot; , luaL_optstring(L, 2, &quot; assertion failed! &quot; ));
return lua_gettop(L);
}


static int luaB_unpack (lua_State *L) {
int i, e, n;
luaL_checktype(L, 1, LUA_TTABLE);
i = luaL_optint(L, 2, 1);
e = luaL_opt(L, luaL_checkint, 3, luaL_getn(L, 1));
if (i &amp; gt; e) return 0; /* empty range */
n = e - i + 1; /* number of elements */
if (n &amp; lt; = 0 || !lua_checkstack(L, n)) /* n &amp; lt; = 0 means arith. overflow */
return luaL_error(L, &quot; too many results to unpack &quot; );
lua_rawgeti(L, 1, i); /* push arg[i] (avoiding overflow problems) */
while (i++ &amp; lt; e) /* push arg[i + 1...e] */
lua_rawgeti(L, 1, i);
return n;
}


static int luaB_select (lua_State *L) {
int n = lua_gettop(L);
if (lua_type(L, 1) == LUA_TSTRING &amp; &amp; *lua_tostring(L, 1) == '#') {
lua_pushinteger(L, n-1);
return 1;
}
else {
int i = luaL_checkint(L, 1);
if (i &amp; lt; 0) i = n + i;
else if (i &amp; gt; n) i = n;
luaL_argcheck(L, 1 &amp; lt; = i, 1, &quot; index out of range &quot; );
return n - i;
}
}


static int luaB_pcall (lua_State *L) {
int status;
luaL_checkany(L, 1);
status = lua_pcall(L, lua_gettop(L) - 1, LUA_MULTRET, 0);
lua_pushboolean(L, (status == 0));
lua_insert(L, 1);
return lua_gettop(L); /* return status + all results */
}


static int luaB_xpcall (lua_State *L) {
int status;
luaL_checkany(L, 2);
lua_settop(L, 2);
lua_insert(L, 1); /* put error function under function to be called */
status = lua_pcall(L, 0, LUA_MULTRET, 1);
lua_pushboolean(L, (status == 0));
lua_replace(L, 1);
return lua_gettop(L); /* return status + all results */
}


static int luaB_tostring (lua_State *L) {
luaL_checkany(L, 1);
if (luaL_callmeta(L, 1, &quot; __tostring &quot; )) /* is there a metafield? */
return 1; /* use its value */
switch (lua_type(L, 1)) {
case LUA_TNUMBER:
lua_pushstring(L, lua_tostring(L, 1));
break;
case LUA_TSTRING:
lua_pushvalue(L, 1);
break;
case LUA_TBOOLEAN:
lua_pushstring(L, (lua_toboolean(L, 1) ? &quot; true &quot; : &quot; false &quot; ));
break;
case LUA_TNIL:
lua_pushliteral(L, &quot; nil &quot; );
break;
default:
lua_pushfstring(L, &quot; %s: %p &quot; , luaL_typename(L, 1), lua_topointer(L, 1));
break;
}
return 1;
}


static int luaB_newproxy (lua_State *L) {
lua_settop(L, 1);
lua_newuserdata(L, 0); /* create proxy */
if (lua_toboolean(L, 1) == 0)
return 1; /* no metatable */
else if (lua_isboolean(L, 1)) {
lua_newtable(L); /* create a new metatable `m' ... */
lua_pushvalue(L, -1); /* ... and mark `m' as a valid metatable */
lua_pushboolean(L, 1);
lua_rawset(L, lua_upvalueindex(1)); /* weaktable[m] = true */
}
else {
int validproxy = 0; /* to check if weaktable[metatable(u)] == true */
if (lua_getmetatable(L, 1)) {
lua_rawget(L, lua_upvalueindex(1));
validproxy = lua_toboolean(L, -1);
lua_pop(L, 1); /* remove value */
}
luaL_argcheck(L, validproxy, 1, &quot; boolean or proxy expected &quot; );
lua_getmetatable(L, 1); /* metatable is valid; get it */
}
lua_setmetatable(L, 2);
return 1;
}


static const luaL_Reg base_funcs[] = {
{ &quot; assert &quot; , luaB_assert},
{ &quot; collectgarbage &quot; , luaB_collectgarbage},
{ &quot; dofile &quot; , luaB_dofile},
{ &quot; error &quot; , luaB_error},
{ &quot; gcinfo &quot; , luaB_gcinfo},
{ &quot; getfenv &quot; , luaB_getfenv},
{ &quot; getmetatable &quot; , luaB_getmetatable},
{ &quot; loadfile &quot; , luaB_loadfile},
{ &quot; load &quot; , luaB_load},
{ &quot; loadstring &quot; , luaB_loadstring},
{ &quot; next &quot; , luaB_next},
{ &quot; pcall &quot; , luaB_pcall},
{ &quot; print &quot; , luaB_print},
{ &quot; rawequal &quot; , luaB_rawequal},
{ &quot; rawget &quot; , luaB_rawget},
{ &quot; rawset &quot; , luaB_rawset},
{ &quot; select &quot; , luaB_select},
{ &quot; setfenv &quot; , luaB_setfenv},
{ &quot; setmetatable &quot; , luaB_setmetatable},
{ &quot; tonumber &quot; , luaB_tonumber},
{ &quot; tostring &quot; , luaB_tostring},
{ &quot; type &quot; , luaB_type},
{ &quot; unpack &quot; , luaB_unpack},
{ &quot; xpcall &quot; , luaB_xpcall},
{NULL, NULL}
};


/*
** {======================================================
** Coroutine library
** =======================================================
*/

#define CO_RUN 0 /* running */
#define CO_SUS 1 /* suspended */
#define CO_NOR 2 /* 'normal' (it resumed another coroutine) */
#define CO_DEAD 3

static const char *const statnames[] =
{ &quot; running &quot; , &quot; suspended &quot; , &quot; normal &quot; , &quot; dead &quot; };

static int costatus (lua_State *L, lua_State *co) {
if (L == co) return CO_RUN;
switch (lua_status(co)) {
case LUA_YIELD:
return CO_SUS;
case 0: {
lua_Debug ar;
if (lua_getstack(co, 0, &amp; ar) &amp; gt; 0) /* does it have frames? */
return CO_NOR; /* it is running */
else if (lua_gettop(co) == 0)
return CO_DEAD;
else
return CO_SUS; /* initial state */
}
default: /* some error occured */
return CO_DEAD;
}
}


static int luaB_costatus (lua_State *L) {
lua_State *co = lua_tothread(L, 1);
luaL_argcheck(L, co, 1, &quot; coroutine expected &quot; );
lua_pushstring(L, statnames[costatus(L, co)]);
return 1;
}


static int auxresume (lua_State *L, lua_State *co, int narg) {
int status = costatus(L, co);
if (!lua_checkstack(co, narg))
luaL_error(L, &quot; too many arguments to resume &quot; );
if (status != CO_SUS) {
lua_pushfstring(L, &quot; cannot resume %s coroutine &quot; , statnames[status]);
return -1; /* error flag */
}
lua_xmove(L, co, narg);
lua_setlevel(L, co);
status = lua_resume(co, narg);
if (status == 0 || status == LUA_YIELD) {
int nres = lua_gettop(co);
if (!lua_checkstack(L, nres + 1))
luaL_error(L, &quot; too many results to resume &quot; );
lua_xmove(co, L, nres); /* move yielded values */
return nres;
}
else {
lua_xmove(co, L, 1); /* move error message */
return -1; /* error flag */
}
}


static int luaB_coresume (lua_State *L) {
lua_State *co = lua_tothread(L, 1);
int r;
luaL_argcheck(L, co, 1, &quot; coroutine expected &quot; );
r = auxresume(L, co, lua_gettop(L) - 1);
if (r &amp; lt; 0) {
lua_pushboolean(L, 0);
lua_insert(L, -2);
return 2; /* return false + error message */
}
else {
lua_pushboolean(L, 1);
lua_insert(L, -(r + 1));
return r + 1; /* return true + `resume' returns */
}
}


static int luaB_auxwrap (lua_State *L) {
lua_State *co = lua_tothread(L, lua_upvalueindex(1));
int r = auxresume(L, co, lua_gettop(L));
if (r &amp; lt; 0) {
if (lua_isstring(L, -1)) { /* error object is a string? */
luaL_where(L, 1); /* add extra info */
lua_insert(L, -2);
lua_concat(L, 2);
}
lua_error(L); /* propagate error */
}
return r;
}


static int luaB_cocreate (lua_State *L) {
lua_State *NL = lua_newthread(L);
luaL_argcheck(L, lua_isfunction(L, 1) &amp; &amp; !lua_iscfunction(L, 1), 1,
&quot; Lua function expected &quot; );
lua_pushvalue(L, 1); /* move function to top */
lua_xmove(L, NL, 1); /* move function from L to NL */
return 1;
}


static int luaB_cowrap (lua_State *L) {
luaB_cocreate(L);
lua_pushcclosure(L, luaB_auxwrap, 1);
return 1;
}


static int luaB_yield (lua_State *L) {
return lua_yield(L, lua_gettop(L));
}


static int luaB_corunning (lua_State *L) {
if (lua_pushthread(L))
lua_pushnil(L); /* main thread is not a coroutine */
return 1;
}


static const luaL_Reg co_funcs[] = {
{ &quot; create &quot; , luaB_cocreate},
{ &quot; resume &quot; , luaB_coresume},
{ &quot; running &quot; , luaB_corunning},
{ &quot; status &quot; , luaB_costatus},
{ &quot; wrap &quot; , luaB_cowrap},
{ &quot; yield &quot; , luaB_yield},
{NULL, NULL}
};

/* }====================================================== */


static void auxopen (lua_State *L, const char *name,
lua_CFunction f, lua_CFunction u) {
lua_pushcfunction(L, u);
lua_pushcclosure(L, f, 1);
lua_setfield(L, -2, name);
}


static void base_open (lua_State *L) {
/* set global _G */
lua_pushvalue(L, LUA_GLOBALSINDEX);
lua_setglobal(L, &quot; _G &quot; );
/* open lib into global table */
luaL_register(L, &quot; _G &quot; , base_funcs);
lua_pushliteral(L, LUA_VERSION);
lua_setglobal(L, &quot; _VERSION &quot; ); /* set global _VERSION */
/* `ipairs' and `pairs' need auxliliary functions as upvalues */
auxopen(L, &quot; ipairs &quot; , luaB_ipairs, ipairsaux);
auxopen(L, &quot; pairs &quot; , luaB_pairs, luaB_next);
/* `newproxy' needs a weaktable as upvalue */
lua_createtable(L, 0, 1); /* new table `w' */
lua_pushvalue(L, -1); /* `w' will be its own metatable */
lua_setmetatable(L, -2);
lua_pushliteral(L, &quot; kv &quot; );
lua_setfield(L, -2, &quot; __mode &quot; ); /* metatable(w).__mode = &quot; kv &quot; */
lua_pushcclosure(L, luaB_newproxy, 1);
lua_setglobal(L, &quot; newproxy &quot; ); /* set global `newproxy' */
}


LUALIB_API int luaopen_base (lua_State *L) {
base_open(L);
luaL_register(L, LUA_COLIBNAME, co_funcs);
return 2;
}


scite228.zip > lauxlib.c

/*
** $Id$
** Auxiliary functions for building Lua libraries
** See Copyright Notice in lua.h
*/


#include &amp; lt; ctype.h &amp; gt;
#include &amp; lt; errno.h &amp; gt;
#include &amp; lt; stdarg.h &amp; gt;
#include &amp; lt; stdio.h &amp; gt;
#include &amp; lt; stdlib.h &amp; gt;
#include &amp; lt; string.h &amp; gt;


/* This file uses only the official API of Lua.
** Any function declared here could be written as an application function.
*/

#define lauxlib_c
#define LUA_LIB

#include &quot; lua.h &quot;

#include &quot; lauxlib.h &quot;


#define FREELIST_REF 0 /* free list of references */


/* convert a stack index to positive */
#define abs_index(L, i) ((i) &amp; gt; 0 || (i) &amp; lt; = LUA_REGISTRYINDEX ? (i) : \
lua_gettop(L) + (i) + 1)


/*
** {======================================================
** Error-report functions
** =======================================================
*/


LUALIB_API int luaL_argerror (lua_State *L, int narg, const char *extramsg) {
lua_Debug ar;
if (!lua_getstack(L, 0, &amp; ar)) /* no stack frame? */
return luaL_error(L, &quot; bad argument #%d (%s) &quot; , narg, extramsg);
lua_getinfo(L, &quot; n &quot; , &amp; ar);
if (strcmp(ar.namewhat, &quot; method &quot; ) == 0) {
narg--; /* do not count `self' */
if (narg == 0) /* error is in the self argument itself? */
return luaL_error(L, &quot; calling &quot; LUA_QS &quot; on bad self (%s) &quot; ,
ar.name, extramsg);
}
if (ar.name == NULL)
ar.name = &quot; ? &quot; ;
return luaL_error(L, &quot; bad argument #%d to &quot; LUA_QS &quot; (%s) &quot; ,
narg, ar.name, extramsg);
}


LUALIB_API int luaL_typerror (lua_State *L, int narg, const char *tname) {
const char *msg = lua_pushfstring(L, &quot; %s expected, got %s &quot; ,
tname, luaL_typename(L, narg));
return luaL_argerror(L, narg, msg);
}


static void tag_error (lua_State *L, int narg, int tag) {
luaL_typerror(L, narg, lua_typename(L, tag));
}


LUALIB_API void luaL_where (lua_State *L, int level) {
lua_Debug ar;
if (lua_getstack(L, level, &amp; ar)) { /* check function at level */
lua_getinfo(L, &quot; Sl &quot; , &amp; ar); /* get info about it */
if (ar.currentline &amp; gt; 0) { /* is there info? */
lua_pushfstring(L, &quot; %s:%d: &quot; , ar.short_src, ar.currentline);
return;
}
}
lua_pushliteral(L, &quot; &quot; ); /* else, no information available... */
}


LUALIB_API int luaL_error (lua_State *L, const char *fmt, ...) {
va_list argp;
va_start(argp, fmt);
luaL_where(L, 1);
lua_pushvfstring(L, fmt, argp);
va_end(argp);
lua_concat(L, 2);
return lua_error(L);
}

/* }====================================================== */


LUALIB_API int luaL_checkoption (lua_State *L, int narg, const char *def,
const char *const lst[]) {
const char *name = (def) ? luaL_optstring(L, narg, def) :
luaL_checkstring(L, narg);
int i;
for (i=0; lst[i]; i++)
if (strcmp(lst[i], name) == 0)
return i;
return luaL_argerror(L, narg,
lua_pushfstring(L, &quot; invalid option &quot; LUA_QS, name));
}


LUALIB_API int luaL_newmetatable (lua_State *L, const char *tname) {
lua_getfield(L, LUA_REGISTRYINDEX, tname); /* get registry.name */
if (!lua_isnil(L, -1)) /* name already in use? */
return 0; /* leave previous value on top, but return 0 */
lua_pop(L, 1);
lua_newtable(L); /* create metatable */
lua_pushvalue(L, -1);
lua_setfield(L, LUA_REGISTRYINDEX, tname); /* registry.name = metatable */
return 1;
}


LUALIB_API void *luaL_checkudata (lua_State *L, int ud, const char *tname) {
void *p = lua_touserdata(L, ud);
if (p != NULL) { /* value is a userdata? */
if (lua_getmetatable(L, ud)) { /* does it have a metatable? */
lua_getfield(L, LUA_REGISTRYINDEX, tname); /* get correct metatable */
if (lua_rawequal(L, -1, -2)) { /* does it have the correct mt? */
lua_pop(L, 2); /* remove both metatables */
return p;
}
}
}
luaL_typerror(L, ud, tname); /* else error */
return NULL; /* to avoid warnings */
}


LUALIB_API void luaL_checkstack (lua_State *L, int space, const char *mes) {
if (!lua_checkstack(L, space))
luaL_error(L, &quot; stack overflow (%s) &quot; , mes);
}


LUALIB_API void luaL_checktype (lua_State *L, int narg, int t) {
if (lua_type(L, narg) != t)
tag_error(L, narg, t);
}


LUALIB_API void luaL_checkany (lua_State *L, int narg) {
if (lua_type(L, narg) == LUA_TNONE)
luaL_argerror(L, narg, &quot; value expected &quot; );
}


LUALIB_API const char *luaL_checklstring (lua_State *L, int narg, size_t *len) {
const char *s = lua_tolstring(L, narg, len);
if (!s) tag_error(L, narg, LUA_TSTRING);
return s;
}


LUALIB_API const char *luaL_optlstring (lua_State *L, int narg,
const char *def, size_t *len) {
if (lua_isnoneornil(L, narg)) {
if (len)
*len = (def ? strlen(def) : 0);
return def;
}
else return luaL_checklstring(L, narg, len);
}


LUALIB_API lua_Number luaL_checknumber (lua_State *L, int narg) {
lua_Number d = lua_tonumber(L, narg);
if (d == 0 &amp; &amp; !lua_isnumber(L, narg)) /* avoid extra test when d is not 0 */
tag_error(L, narg, LUA_TNUMBER);
return d;
}


LUALIB_API lua_Number luaL_optnumber (lua_State *L, int narg, lua_Number def) {
return luaL_opt(L, luaL_checknumber, narg, def);
}


LUALIB_API lua_Integer luaL_checkinteger (lua_State *L, int narg) {
lua_Integer d = lua_tointeger(L, narg);
if (d == 0 &amp; &amp; !lua_isnumber(L, narg)) /* avoid extra test when d is not 0 */
tag_error(L, narg, LUA_TNUMBER);
return d;
}


LUALIB_API lua_Integer luaL_optinteger (lua_State *L, int narg,
lua_Integer def) {
return luaL_opt(L, luaL_checkinteger, narg, def);
}


LUALIB_API int luaL_getmetafield (lua_State *L, int obj, const char *event) {
if (!lua_getmetatable(L, obj)) /* no metatable? */
return 0;
lua_pushstring(L, event);
lua_rawget(L, -2);
if (lua_isnil(L, -1)) {
lua_pop(L, 2); /* remove metatable and metafield */
return 0;
}
else {
lua_remove(L, -2); /* remove only metatable */
return 1;
}
}


LUALIB_API int luaL_callmeta (lua_State *L, int obj, const char *event) {
obj = abs_index(L, obj);
if (!luaL_getmetafield(L, obj, event)) /* no metafield? */
return 0;
lua_pushvalue(L, obj);
lua_call(L, 1, 1);
return 1;
}


LUALIB_API void (luaL_register) (lua_State *L, const char *libname,
const luaL_Reg *l) {
luaI_openlib(L, libname, l, 0);
}


static int libsize (const luaL_Reg *l) {
int size = 0;
for (; l- &amp; gt; name; l++) size++;
return size;
}


LUALIB_API void luaI_openlib (lua_State *L, const char *libname,
const luaL_Reg *l, int nup) {
if (libname) {
int size = libsize(l);
/* check whether lib already exists */
luaL_findtable(L, LUA_REGISTRYINDEX, &quot; _LOADED &quot; , 1);
lua_getfield(L, -1, libname); /* get _LOADED[libname] */
if (!lua_istable(L, -1)) { /* not found? */
lua_pop(L, 1); /* remove previous result */
/* try global variable (and create one if it does not exist) */
if (luaL_findtable(L, LUA_GLOBALSINDEX, libname, size) != NULL)
luaL_error(L, &quot; name conflict for module &quot; LUA_QS, libname);
lua_pushvalue(L, -1);
lua_setfield(L, -3, libname); /* _LOADED[libname] = new table */
}
lua_remove(L, -2); /* remove _LOADED table */
lua_insert(L, -(nup+1)); /* move library table to below upvalues */
}
for (; l- &amp; gt; name; l++) {
int i;
for (i=0; i &amp; lt; nup; i++) /* copy upvalues to the top */
lua_pushvalue(L, -nup);
lua_pushcclosure(L, l- &amp; gt; func, nup);
lua_setfield(L, -(nup+2), l- &amp; gt; name);
}
lua_pop(L, nup); /* remove upvalues */
}



/*
** {======================================================
** getn-setn: size for arrays
** =======================================================
*/

#if defined(LUA_COMPAT_GETN)

static int checkint (lua_State *L, int topop) {
int n = (lua_type(L, -1) == LUA_TNUMBER) ? lua_tointeger(L, -1) : -1;
lua_pop(L, topop);
return n;
}


static void getsizes (lua_State *L) {
lua_getfield(L, LUA_REGISTRYINDEX, &quot; LUA_SIZES &quot; );
if (lua_isnil(L, -1)) { /* no `size' table? */
lua_pop(L, 1); /* remove nil */
lua_newtable(L); /* create it */
lua_pushvalue(L, -1); /* `size' will be its own metatable */
lua_setmetatable(L, -2);
lua_pushliteral(L, &quot; kv &quot; );
lua_setfield(L, -2, &quot; __mode &quot; ); /* metatable(N).__mode = &quot; kv &quot; */
lua_pushvalue(L, -1);
lua_setfield(L, LUA_REGISTRYINDEX, &quot; LUA_SIZES &quot; ); /* store in register */
}
}


LUALIB_API void luaL_setn (lua_State *L, int t, int n) {
t = abs_index(L, t);
lua_pushliteral(L, &quot; n &quot; );
lua_rawget(L, t);
if (checkint(L, 1) &amp; gt; = 0) { /* is there a numeric field `n'? */
lua_pushliteral(L, &quot; n &quot; ); /* use it */
lua_pushinteger(L, n);
lua_rawset(L, t);
}
else { /* use `sizes' */
getsizes(L);
lua_pushvalue(L, t);
lua_pushinteger(L, n);
lua_rawset(L, -3); /* sizes[t] = n */
lua_pop(L, 1); /* remove `sizes' */
}
}


LUALIB_API int luaL_getn (lua_State *L, int t) {
int n;
t = abs_index(L, t);
lua_pushliteral(L, &quot; n &quot; ); /* try t.n */
lua_rawget(L, t);
if ((n = checkint(L, 1)) &amp; gt; = 0) return n;
getsizes(L); /* else try sizes[t] */
lua_pushvalue(L, t);
lua_rawget(L, -2);
if ((n = checkint(L, 2)) &amp; gt; = 0) return n;
return (int)lua_objlen(L, t);
}

#endif

/* }====================================================== */



LUALIB_API const char *luaL_gsub (lua_State *L, const char *s, const char *p,
const char *r) {
const char *wild;
size_t l = strlen(p);
luaL_Buffer b;
luaL_buffinit(L, &amp; b);
while ((wild = strstr(s, p)) != NULL) {
luaL_addlstring( &amp; b, s, wild - s); /* push prefix */
luaL_addstring( &amp; b, r); /* push replacement in place of pattern */
s = wild + l; /* continue after `p' */
}
luaL_addstring( &amp; b, s); /* push last suffix */
luaL_pushresult( &amp; b);
return lua_tostring(L, -1);
}


LUALIB_API const char *luaL_findtable (lua_State *L, int idx,
const char *fname, int szhint) {
const char *e;
lua_pushvalue(L, idx);
do {
e = strchr(fname, '.');
if (e == NULL) e = fname + strlen(fname);
lua_pushlstring(L, fname, e - fname);
lua_rawget(L, -2);
if (lua_isnil(L, -1)) { /* no such field? */
lua_pop(L, 1); /* remove this nil */
lua_createtable(L, 0, (*e == '.' ? 1 : szhint)); /* new table for field */
lua_pushlstring(L, fname, e - fname);
lua_pushvalue(L, -2);
lua_settable(L, -4); /* set new table into field */
}
else if (!lua_istable(L, -1)) { /* field has a non-table value? */
lua_pop(L, 2); /* remove table and value */
return fname; /* return problematic part of the name */
}
lua_remove(L, -2); /* remove previous table */
fname = e + 1;
} while (*e == '.');
return NULL;
}



/*
** {======================================================
** Generic Buffer manipulation
** =======================================================
*/


#define bufflen(B) ((B)- &amp; gt; p - (B)- &amp; gt; buffer)
#define bufffree(B) ((size_t)(LUAL_BUFFERSIZE - bufflen(B)))

#define LIMIT (LUA_MINSTACK/2)


static int emptybuffer (luaL_Buffer *B) {
size_t l = bufflen(B);
if (l == 0) return 0; /* put nothing on stack */
else {
lua_pushlstring(B- &amp; gt; L, B- &amp; gt; buffer, l);
B- &amp; gt; p = B- &amp; gt; buffer;
B- &amp; gt; lvl++;
return 1;
}
}


static void adjuststack (luaL_Buffer *B) {
if (B- &amp; gt; lvl &amp; gt; 1) {
lua_State *L = B- &amp; gt; L;
int toget = 1; /* number of levels to concat */
size_t toplen = lua_strlen(L, -1);
do {
size_t l = lua_strlen(L, -(toget+1));
if (B- &amp; gt; lvl - toget + 1 &amp; gt; = LIMIT || toplen &amp; gt; l) {
toplen += l;
toget++;
}
else break;
} while (toget &amp; lt; B- &amp; gt; lvl);
lua_concat(L, toget);
B- &amp; gt; lvl = B- &amp; gt; lvl - toget + 1;
}
}


LUALIB_API char *luaL_prepbuffer (luaL_Buffer *B) {
if (emptybuffer(B))
adjuststack(B);
return B- &amp; gt; buffer;
}


LUALIB_API void luaL_addlstring (luaL_Buffer *B, const char *s, size_t l) {
while (l--)
luaL_addchar(B, *s++);
}


LUALIB_API void luaL_addstring (luaL_Buffer *B, const char *s) {
luaL_addlstring(B, s, strlen(s));
}


LUALIB_API void luaL_pushresult (luaL_Buffer *B) {
emptybuffer(B);
lua_concat(B- &amp; gt; L, B- &amp; gt; lvl);
B- &amp; gt; lvl = 1;
}


LUALIB_API void luaL_addvalue (luaL_Buffer *B) {
lua_State *L = B- &amp; gt; L;
size_t vl;
const char *s = lua_tolstring(L, -1, &amp; vl);
if (vl &amp; lt; = bufffree(B)) { /* fit into buffer? */
memcpy(B- &amp; gt; p, s, vl); /* put it there */
B- &amp; gt; p += vl;
lua_pop(L, 1); /* remove from stack */
}
else {
if (emptybuffer(B))
lua_insert(L, -2); /* put buffer before new value */
B- &amp; gt; lvl++; /* add new value into B stack */
adjuststack(B);
}
}


LUALIB_API void luaL_buffinit (lua_State *L, luaL_Buffer *B) {
B- &amp; gt; L = L;
B- &amp; gt; p = B- &amp; gt; buffer;
B- &amp; gt; lvl = 0;
}

/* }====================================================== */


LUALIB_API int luaL_ref (lua_State *L, int t) {
int ref;
t = abs_index(L, t);
if (lua_isnil(L, -1)) {
lua_pop(L, 1); /* remove from stack */
return LUA_REFNIL; /* `nil' has a unique fixed reference */
}
lua_rawgeti(L, t, FREELIST_REF); /* get first free element */
ref = (int)lua_tointeger(L, -1); /* ref = t[FREELIST_REF] */
lua_pop(L, 1); /* remove it from stack */
if (ref != 0) { /* any free element? */
lua_rawgeti(L, t, ref); /* remove it from list */
lua_rawseti(L, t, FREELIST_REF); /* (t[FREELIST_REF] = t[ref]) */
}
else { /* no free elements */
ref = (int)lua_objlen(L, t);
ref++; /* create new reference */
}
lua_rawseti(L, t, ref);
return ref;
}


LUALIB_API void luaL_unref (lua_State *L, int t, int ref) {
if (ref &amp; gt; = 0) {
t = abs_index(L, t);
lua_rawgeti(L, t, FREELIST_REF);
lua_rawseti(L, t, ref); /* t[ref] = t[FREELIST_REF] */
lua_pushinteger(L, ref);
lua_rawseti(L, t, FREELIST_REF); /* t[FREELIST_REF] = ref */
}
}



/*
** {======================================================
** Load functions
** =======================================================
*/

typedef struct LoadF {
int extraline;
FILE *f;
char buff[LUAL_BUFFERSIZE];
} LoadF;


static const char *getF (lua_State *L, void *ud, size_t *size) {
LoadF *lf = (LoadF *)ud;
(void)L;
if (lf- &amp; gt; extraline) {
lf- &amp; gt; extraline = 0;
*size = 1;
return &quot; \n &quot; ;
}
if (feof(lf- &amp; gt; f)) return NULL;
*size = fread(lf- &amp; gt; buff, 1, sizeof(lf- &amp; gt; buff), lf- &amp; gt; f);
return (*size &amp; gt; 0) ? lf- &amp; gt; buff : NULL;
}


static int errfile (lua_State *L, const char *what, int fnameindex) {
const char *serr = strerror(errno);
const char *filename = lua_tostring(L, fnameindex) + 1;
lua_pushfstring(L, &quot; cannot %s %s: %s &quot; , what, filename, serr);
lua_remove(L, fnameindex);
return LUA_ERRFILE;
}


LUALIB_API int luaL_loadfile (lua_State *L, const char *filename) {
LoadF lf;
int status, readstatus;
int c;
int fnameindex = lua_gettop(L) + 1; /* index of filename on the stack */
lf.extraline = 0;
if (filename == NULL) {
lua_pushliteral(L, &quot; =stdin &quot; );
lf.f = stdin;
}
else {
lua_pushfstring(L, &quot; @%s &quot; , filename);
lf.f = fopen(filename, &quot; r &quot; );
if (lf.f == NULL) return errfile(L, &quot; open &quot; , fnameindex);
}
c = getc(lf.f);
if (c == '#') { /* Unix exec. file? */
lf.extraline = 1;
while ((c = getc(lf.f)) != EOF &amp; &amp; c != '\n') ; /* skip first line */
if (c == '\n') c = getc(lf.f);
}
if (c == LUA_SIGNATURE[0] &amp; &amp; filename) { /* binary file? */
lf.f = freopen(filename, &quot; rb &quot; , lf.f); /* reopen in binary mode */
if (lf.f == NULL) return errfile(L, &quot; reopen &quot; , fnameindex);
/* skip eventual `#!...' */
while ((c = getc(lf.f)) != EOF &amp; &amp; c != LUA_SIGNATURE[0]) ;
lf.extraline = 0;
}
ungetc(c, lf.f);
status = lua_load(L, getF, &amp; lf, lua_tostring(L, -1));
readstatus = ferror(lf.f);
if (filename) fclose(lf.f); /* close file (even in case of errors) */
if (readstatus) {
lua_settop(L, fnameindex); /* ignore results from `lua_load' */
return errfile(L, &quot; read &quot; , fnameindex);
}
lua_remove(L, fnameindex);
return status;
}


typedef struct LoadS {
const char *s;
size_t size;
} LoadS;


static const char *getS (lua_State *L, void *ud, size_t *size) {
LoadS *ls = (LoadS *)ud;
(void)L;
if (ls- &amp; gt; size == 0) return NULL;
*size = ls- &amp; gt; size;
ls- &amp; gt; size = 0;
return ls- &amp; gt; s;
}


LUALIB_API int luaL_loadbuffer (lua_State *L, const char *buff, size_t size,
const char *name) {
LoadS ls;
ls.s = buff;
ls.size = size;
return lua_load(L, getS, &amp; ls, name);
}


LUALIB_API int (luaL_loadstring) (lua_State *L, const char *s) {
return luaL_loadbuffer(L, s, strlen(s), s);
}



/* }====================================================== */


static void *l_alloc (void *ud, void *ptr, size_t osize, size_t nsize) {
(void)ud;
(void)osize;
if (nsize == 0) {
free(ptr);
return NULL;
}
else
return realloc(ptr, nsize);
}


static int panic (lua_State *L) {
(void)L; /* to avoid warnings */
fprintf(stderr, &quot; PANIC: unprotected error in call to Lua API (%s)\n &quot; ,
lua_tostring(L, -1));
return 0;
}


LUALIB_API lua_State *luaL_newstate (void) {
lua_State *L = lua_newstate(l_alloc, NULL);
if (L) lua_atpanic(L, panic);
return L;
}


scite228.zip > loadlib.c

/*
** $Id$
** Dynamic library loader for Lua
** See Copyright Notice in lua.h
**
** This module contains an implementation of loadlib for Unix systems
** that have dlfcn, an implementation for Darwin (Mac OS X), an
** implementation for Windows, and a stub for other systems.
*/


#include &amp; lt; stdlib.h &amp; gt;
#include &amp; lt; string.h &amp; gt;


#define loadlib_c
#define LUA_LIB

#include &quot; lua.h &quot;

#include &quot; lauxlib.h &quot;
#include &quot; lualib.h &quot;

#ifndef _WIN32
#define LUA_DL_DLOPEN
#endif

/* prefix for open functions in C libraries */
#define LUA_POF &quot; luaopen_ &quot;

/* separator for open functions in C libraries */
#define LUA_OFSEP &quot; _ &quot;


#define LIBPREFIX &quot; LOADLIB: &quot;

#define POF LUA_POF
#define LIB_FAIL &quot; open &quot;


/* error codes for ll_loadfunc */
#define ERRLIB 1
#define ERRFUNC 2

#define setprogdir(L) ((void)0)


static void ll_unloadlib (void *lib);
static void *ll_load (lua_State *L, const char *path);
static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym);



#if defined(LUA_DL_DLOPEN)
/*
** {========================================================================
** This is an implementation of loadlib based on the dlfcn interface.
** The dlfcn interface is available in Linux, SunOS, Solaris, IRIX, FreeBSD,
** NetBSD, AIX 4.2, HPUX 11, and probably most other Unix flavors, at least
** as an emulation layer on top of native functions.
** =========================================================================
*/

#include &amp; lt; dlfcn.h &amp; gt;

static void ll_unloadlib (void *lib) {
dlclose(lib);
}


static void *ll_load (lua_State *L, const char *path) {
void *lib = dlopen(path, RTLD_NOW);
if (lib == NULL) lua_pushstring(L, dlerror());
return lib;
}


static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) {
lua_CFunction f = (lua_CFunction)(long)dlsym(lib, sym);
if (f == NULL) lua_pushstring(L, dlerror());
return f;
}

/* }====================================================== */



#elif defined(LUA_DL_DLL)
/*
** {======================================================================
** This is an implementation of loadlib for Windows using native functions.
** =======================================================================
*/

#include &amp; lt; windows.h &amp; gt;


#undef setprogdir

static void setprogdir (lua_State *L) {
char buff[MAX_PATH + 1];
char *lb;
DWORD nsize = sizeof(buff)/sizeof(char);
DWORD n = GetModuleFileNameA(NULL, buff, nsize);
if (n == 0 || n == nsize || (lb = strrchr(buff, '\\')) == NULL)
luaL_error(L, &quot; unable to get ModuleFileName &quot; );
else {
*lb = '\0';
luaL_gsub(L, lua_tostring(L, -1), LUA_EXECDIR, buff);
lua_remove(L, -2); /* remove original string */
}
}


static void pusherror (lua_State *L) {
int error = GetLastError();
char buffer[128];
if (FormatMessageA(FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM,
NULL, error, 0, buffer, sizeof(buffer), NULL))
lua_pushstring(L, buffer);
else
lua_pushfstring(L, &quot; system error %d\n &quot; , error);
}

static void ll_unloadlib (void *lib) {
FreeLibrary((HINSTANCE)lib);
}


static void *ll_load (lua_State *L, const char *path) {
HINSTANCE lib = LoadLibraryA(path);
if (lib == NULL) pusherror(L);
return lib;
}


static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) {
lua_CFunction f = (lua_CFunction)GetProcAddress((HINSTANCE)lib, sym);
if (f == NULL) pusherror(L);
return f;
}

/* }====================================================== */



#elif defined(LUA_DL_DYLD)
/*
** {======================================================================
** Native Mac OS X / Darwin Implementation
** =======================================================================
*/

#include &amp; lt; mach-o/dyld.h &amp; gt;


/* Mac appends a `_' before C function names */
#undef POF
#define POF &quot; _ &quot; LUA_POF


static void pusherror (lua_State *L) {
const char *err_str;
const char *err_file;
NSLinkEditErrors err;
int err_num;
NSLinkEditError( &amp; err, &amp; err_num, &amp; err_file, &amp; err_str);
lua_pushstring(L, err_str);
}


static const char *errorfromcode (NSObjectFileImageReturnCode ret) {
switch (ret) {
case NSObjectFileImageInappropriateFile:
return &quot; file is not a bundle &quot; ;
case NSObjectFileImageArch:
return &quot; library is for wrong CPU type &quot; ;
case NSObjectFileImageFormat:
return &quot; bad format &quot; ;
case NSObjectFileImageAccess:
return &quot; cannot access file &quot; ;
case NSObjectFileImageFailure:
default:
return &quot; unable to load library &quot; ;
}
}


static void ll_unloadlib (void *lib) {
NSUnLinkModule((NSModule)lib, NSUNLINKMODULE_OPTION_RESET_LAZY_REFERENCES);
}


static void *ll_load (lua_State *L, const char *path) {
NSObjectFileImage img;
NSObjectFileImageReturnCode ret;
/* this would be a rare case, but prevents crashing if it happens */
if(!_dyld_present()) {
lua_pushliteral(L, &quot; dyld not present &quot; );
return NULL;
}
ret = NSCreateObjectFileImageFromFile(path, &amp; img);
if (ret == NSObjectFileImageSuccess) {
NSModule mod = NSLinkModule(img, path, NSLINKMODULE_OPTION_PRIVATE |
NSLINKMODULE_OPTION_RETURN_ON_ERROR);
NSDestroyObjectFileImage(img);
if (mod == NULL) pusherror(L);
return mod;
}
lua_pushstring(L, errorfromcode(ret));
return NULL;
}


static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) {
NSSymbol nss = NSLookupSymbolInModule((NSModule)lib, sym);
if (nss == NULL) {
lua_pushfstring(L, &quot; symbol &quot; LUA_QS &quot; not found &quot; , sym);
return NULL;
}
return (lua_CFunction)NSAddressOfSymbol(nss);
}

/* }====================================================== */



#else
/*
** {======================================================
** Fallback for other systems
** =======================================================
*/

#undef LIB_FAIL
#define LIB_FAIL &quot; absent &quot;


#define DLMSG &quot; dynamic libraries not enabled; check your Lua installation &quot;


static void ll_unloadlib (void *lib) {
(void)lib; /* to avoid warnings */
}


static void *ll_load (lua_State *L, const char *path) {
(void)path; /* to avoid warnings */
lua_pushliteral(L, DLMSG);
return NULL;
}


static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) {
(void)lib; (void)sym; /* to avoid warnings */
lua_pushliteral(L, DLMSG);
return NULL;
}

/* }====================================================== */
#endif



static void **ll_register (lua_State *L, const char *path) {
void **plib;
lua_pushfstring(L, &quot; %s%s &quot; , LIBPREFIX, path);
lua_gettable(L, LUA_REGISTRYINDEX); /* check library in registry? */
if (!lua_isnil(L, -1)) /* is there an entry? */
plib = (void **)lua_touserdata(L, -1);
else { /* no entry yet; create one */
lua_pop(L, 1);
plib = (void **)lua_newuserdata(L, sizeof(const void *));
*plib = NULL;
luaL_getmetatable(L, &quot; _LOADLIB &quot; );
lua_setmetatable(L, -2);
lua_pushfstring(L, &quot; %s%s &quot; , LIBPREFIX, path);
lua_pushvalue(L, -2);
lua_settable(L, LUA_REGISTRYINDEX);
}
return plib;
}


/*
** __gc tag method: calls library's `ll_unloadlib' function with the lib
** handle
*/
static int gctm (lua_State *L) {
void **lib = (void **)luaL_checkudata(L, 1, &quot; _LOADLIB &quot; );
if (*lib) ll_unloadlib(*lib);
*lib = NULL; /* mark library as closed */
return 0;
}


static int ll_loadfunc (lua_State *L, const char *path, const char *sym) {
void **reg = ll_register(L, path);
if (*reg == NULL) *reg = ll_load(L, path);
if (*reg == NULL)
return ERRLIB; /* unable to load library */
else {
lua_CFunction f = ll_sym(L, *reg, sym);
if (f == NULL)
return ERRFUNC; /* unable to find function */
lua_pushcfunction(L, f);
return 0; /* return function */
}
}


static int ll_loadlib (lua_State *L) {
const char *path = luaL_checkstring(L, 1);
const char *init = luaL_checkstring(L, 2);
int stat = ll_loadfunc(L, path, init);
if (stat == 0) /* no errors? */
return 1; /* return the loaded function */
else { /* error; error message is on stack top */
lua_pushnil(L);
lua_insert(L, -2);
lua_pushstring(L, (stat == ERRLIB) ? LIB_FAIL : &quot; init &quot; );
return 3; /* return nil, error message, and where */
}
}



/*
** {======================================================
** 'require' function
** =======================================================
*/


static int readable (const char *filename) {
FILE *f = fopen(filename, &quot; r &quot; ); /* try to open file */
if (f == NULL) return 0; /* open failed */
fclose(f);
return 1;
}


static const char *pushnexttemplate (lua_State *L, const char *path) {
const char *l;
while (*path == *LUA_PATHSEP) path++; /* skip separators */
if (*path == '\0') return NULL; /* no more templates */
l = strchr(path, *LUA_PATHSEP); /* find next separator */
if (l == NULL) l = path + strlen(path);
lua_pushlstring(L, path, l - path); /* template */
return l;
}


static const char *findfile (lua_State *L, const char *name,
const char *pname) {
const char *path;
name = luaL_gsub(L, name, &quot; . &quot; , LUA_DIRSEP);
lua_getfield(L, LUA_ENVIRONINDEX, pname);
path = lua_tostring(L, -1);
if (path == NULL)
luaL_error(L, LUA_QL( &quot; package.%s &quot; ) &quot; must be a string &quot; , pname);
lua_pushliteral(L, &quot; &quot; ); /* error accumulator */
while ((path = pushnexttemplate(L, path)) != NULL) {
const char *filename;
filename = luaL_gsub(L, lua_tostring(L, -1), LUA_PATH_MARK, name);
lua_remove(L, -2); /* remove path template */
if (readable(filename)) /* does file exist and is readable? */
return filename; /* return that file name */
lua_pushfstring(L, &quot; \n\tno file &quot; LUA_QS, filename);
lua_remove(L, -2); /* remove file name */
lua_concat(L, 2); /* add entry to possible error message */
}
return NULL; /* not found */
}


static void loaderror (lua_State *L, const char *filename) {
luaL_error(L, &quot; error loading module &quot; LUA_QS &quot; from file &quot; LUA_QS &quot; :\n\t%s &quot; ,
lua_tostring(L, 1), filename, lua_tostring(L, -1));
}


static int loader_Lua (lua_State *L) {
const char *filename;
const char *name = luaL_checkstring(L, 1);
filename = findfile(L, name, &quot; path &quot; );
if (filename == NULL) return 1; /* library not found in this path */
if (luaL_loadfile(L, filename) != 0)
loaderror(L, filename);
return 1; /* library loaded successfully */
}


static const char *mkfuncname (lua_State *L, const char *modname) {
const char *funcname;
const char *mark = strchr(modname, *LUA_IGMARK);
if (mark) modname = mark + 1;
funcname = luaL_gsub(L, modname, &quot; . &quot; , LUA_OFSEP);
funcname = lua_pushfstring(L, POF &quot; %s &quot; , funcname);
lua_remove(L, -2); /* remove 'gsub' result */
return funcname;
}


static int loader_C (lua_State *L) {
const char *funcname;
const char *name = luaL_checkstring(L, 1);
const char *filename = findfile(L, name, &quot; cpath &quot; );
if (filename == NULL) return 1; /* library not found in this path */
funcname = mkfuncname(L, name);
if (ll_loadfunc(L, filename, funcname) != 0)
loaderror(L, filename);
return 1; /* library loaded successfully */
}


static int loader_Croot (lua_State *L) {
const char *funcname;
const char *filename;
const char *name = luaL_checkstring(L, 1);
const char *p = strchr(name, '.');
int stat;
if (p == NULL) return 0; /* is root */
lua_pushlstring(L, name, p - name);
filename = findfile(L, lua_tostring(L, -1), &quot; cpath &quot; );
if (filename == NULL) return 1; /* root not found */
funcname = mkfuncname(L, name);
if ((stat = ll_loadfunc(L, filename, funcname)) != 0) {
if (stat != ERRFUNC) loaderror(L, filename); /* real error */
lua_pushfstring(L, &quot; \n\tno module &quot; LUA_QS &quot; in file &quot; LUA_QS,
name, filename);
return 1; /* function not found */
}
return 1;
}


static int loader_preload (lua_State *L) {
const char *name = luaL_checkstring(L, 1);
lua_getfield(L, LUA_ENVIRONINDEX, &quot; preload &quot; );
if (!lua_istable(L, -1))
luaL_error(L, LUA_QL( &quot; package.preload &quot; ) &quot; must be a table &quot; );
lua_getfield(L, -1, name);
if (lua_isnil(L, -1)) /* not found? */
lua_pushfstring(L, &quot; \n\tno field package.preload['%s'] &quot; , name);
return 1;
}


static const int sentinel_ = 0;
#define sentinel ((void *) &amp; sentinel_)


static int ll_require (lua_State *L) {
const char *name = luaL_checkstring(L, 1);
int i;
lua_settop(L, 1); /* _LOADED table will be at index 2 */
lua_getfield(L, LUA_REGISTRYINDEX, &quot; _LOADED &quot; );
lua_getfield(L, 2, name);
if (lua_toboolean(L, -1)) { /* is it there? */
if (lua_touserdata(L, -1) == sentinel) /* check loops */
luaL_error(L, &quot; loop or previous error loading module &quot; LUA_QS, name);
return 1; /* package is already loaded */
}
/* else must load it; iterate over available loaders */
lua_getfield(L, LUA_ENVIRONINDEX, &quot; loaders &quot; );
if (!lua_istable(L, -1))
luaL_error(L, LUA_QL( &quot; package.loaders &quot; ) &quot; must be a table &quot; );
lua_pushliteral(L, &quot; &quot; ); /* error message accumulator */
for (i=1; ; i++) {
lua_rawgeti(L, -2, i); /* get a loader */
if (lua_isnil(L, -1))
luaL_error(L, &quot; module &quot; LUA_QS &quot; not found:%s &quot; ,
name, lua_tostring(L, -2));
lua_pushstring(L, name);
lua_call(L, 1, 1); /* call it */
if (lua_isfunction(L, -1)) /* did it find module? */
break; /* module loaded successfully */
else if (lua_isstring(L, -1)) /* loader returned error message? */
lua_concat(L, 2); /* accumulate it */
else
lua_pop(L, 1);
}
lua_pushlightuserdata(L, sentinel);
lua_setfield(L, 2, name); /* _LOADED[name] = sentinel */
lua_pushstring(L, name); /* pass name as argument to module */
lua_call(L, 1, 1); /* run loaded module */
if (!lua_isnil(L, -1)) /* non-nil return? */
lua_setfield(L, 2, name); /* _LOADED[name] = returned value */
lua_getfield(L, 2, name);
if (lua_touserdata(L, -1) == sentinel) { /* module did not set a value? */
lua_pushboolean(L, 1); /* use true as result */
lua_pushvalue(L, -1); /* extra copy to be returned */
lua_setfield(L, 2, name); /* _LOADED[name] = true */
}
return 1;
}

/* }====================================================== */



/*
** {======================================================
** 'module' function
** =======================================================
*/


static void setfenv (lua_State *L) {
lua_Debug ar;
if (lua_getstack(L, 1, &amp; ar) == 0 ||
lua_getinfo(L, &quot; f &quot; , &amp; ar) == 0 || /* get calling function */
lua_iscfunction(L, -1))
luaL_error(L, LUA_QL( &quot; module &quot; ) &quot; not called from a Lua function &quot; );
lua_pushvalue(L, -2);
lua_setfenv(L, -2);
lua_pop(L, 1);
}


static void dooptions (lua_State *L, int n) {
int i;
for (i = 2; i &amp; lt; = n; i++) {
lua_pushvalue(L, i); /* get option (a function) */
lua_pushvalue(L, -2); /* module */
lua_call(L, 1, 0);
}
}


static void modinit (lua_State *L, const char *modname) {
const char *dot;
lua_pushvalue(L, -1);
lua_setfield(L, -2, &quot; _M &quot; ); /* module._M = module */
lua_pushstring(L, modname);
lua_setfield(L, -2, &quot; _NAME &quot; );
dot = strrchr(modname, '.'); /* look for last dot in module name */
if (dot == NULL) dot = modname;
else dot++;
/* set _PACKAGE as package name (full module name minus last part) */
lua_pushlstring(L, modname, dot - modname);
lua_setfield(L, -2, &quot; _PACKAGE &quot; );
}


static int ll_module (lua_State *L) {
const char *modname = luaL_checkstring(L, 1);
int loaded = lua_gettop(L) + 1; /* index of _LOADED table */
lua_getfield(L, LUA_REGISTRYINDEX, &quot; _LOADED &quot; );
lua_getfield(L, loaded, modname); /* get _LOADED[modname] */
if (!lua_istable(L, -1)) { /* not found? */
lua_pop(L, 1); /* remove previous result */
/* try global variable (and create one if it does not exist) */
if (luaL_findtable(L, LUA_GLOBALSINDEX, modname, 1) != NULL)
return luaL_error(L, &quot; name conflict for module &quot; LUA_QS, modname);
lua_pushvalue(L, -1);
lua_setfield(L, loaded, modname); /* _LOADED[modname] = new table */
}
/* check whether table already has a _NAME field */
lua_getfield(L, -1, &quot; _NAME &quot; );
if (!lua_isnil(L, -1)) /* is table an initialized module? */
lua_pop(L, 1);
else { /* no; initialize it */
lua_pop(L, 1);
modinit(L, modname);
}
lua_pushvalue(L, -1);
setfenv(L);
dooptions(L, loaded - 1);
return 0;
}


static int ll_seeall (lua_State *L) {
luaL_checktype(L, 1, LUA_TTABLE);
if (!lua_getmetatable(L, 1)) {
lua_createtable(L, 0, 1); /* create new metatable */
lua_pushvalue(L, -1);
lua_setmetatable(L, 1);
}
lua_pushvalue(L, LUA_GLOBALSINDEX);
lua_setfield(L, -2, &quot; __index &quot; ); /* mt.__index = _G */
return 0;
}


/* }====================================================== */



/* auxiliary mark (for internal use) */
#define AUXMARK &quot; \1 &quot;

static void setpath (lua_State *L, const char *fieldname, const char *envname,
const char *def) {
const char *path = getenv(envname);
if (path == NULL) /* no environment variable? */
lua_pushstring(L, def); /* use default */
else {
/* replace &quot; ;; &quot; by &quot; ;AUXMARK; &quot; and then AUXMARK by default path */
path = luaL_gsub(L, path, LUA_PATHSEP LUA_PATHSEP,
LUA_PATHSEP AUXMARK LUA_PATHSEP);
luaL_gsub(L, path, AUXMARK, def);
lua_remove(L, -2);
}
setprogdir(L);
lua_setfield(L, -2, fieldname);
}


static const luaL_Reg pk_funcs[] = {
{ &quot; loadlib &quot; , ll_loadlib},
{ &quot; seeall &quot; , ll_seeall},
{NULL, NULL}
};


static const luaL_Reg ll_funcs[] = {
{ &quot; module &quot; , ll_module},
{ &quot; require &quot; , ll_require},
{NULL, NULL}
};


static const lua_CFunction loaders[] =
{loader_preload, loader_Lua, loader_C, loader_Croot, NULL};


LUALIB_API int luaopen_package (lua_State *L) {
int i;
/* create new type _LOADLIB */
luaL_newmetatable(L, &quot; _LOADLIB &quot; );
lua_pushcfunction(L, gctm);
lua_setfield(L, -2, &quot; __gc &quot; );
/* create `package' table */
luaL_register(L, LUA_LOADLIBNAME, pk_funcs);
#if defined(LUA_COMPAT_LOADLIB)
lua_getfield(L, -1, &quot; loadlib &quot; );
lua_setfield(L, LUA_GLOBALSINDEX, &quot; loadlib &quot; );
#endif
lua_pushvalue(L, -1);
lua_replace(L, LUA_ENVIRONINDEX);
/* create `loaders' table */
lua_createtable(L, 0, sizeof(loaders)/sizeof(loaders[0]) - 1);
/* fill it with pre-defined loaders */
for (i=0; loaders[i] != NULL; i++) {
lua_pushcfunction(L, loaders[i]);
lua_rawseti(L, -2, i+1);
}
lua_setfield(L, -2, &quot; loaders &quot; ); /* put it in field `loaders' */
setpath(L, &quot; path &quot; , LUA_PATH, LUA_PATH_DEFAULT); /* set field `path' */
setpath(L, &quot; cpath &quot; , LUA_CPATH, LUA_CPATH_DEFAULT); /* set field `cpath' */
/* store config information */
lua_pushliteral(L, LUA_DIRSEP &quot; \n &quot; LUA_PATHSEP &quot; \n &quot; LUA_PATH_MARK &quot; \n &quot;
LUA_EXECDIR &quot; \n &quot; LUA_IGMARK);
lua_setfield(L, -2, &quot; config &quot; );
/* set field `loaded' */
luaL_findtable(L, LUA_REGISTRYINDEX, &quot; _LOADED &quot; , 2);
lua_setfield(L, -2, &quot; loaded &quot; );
/* set field `preload' */
lua_newtable(L);
lua_setfield(L, -2, &quot; preload &quot; );
lua_pushvalue(L, LUA_GLOBALSINDEX);
luaL_register(L, NULL, ll_funcs); /* open lib into global table */
lua_pop(L, 1);
return 1; /* return 'package' table */
}


scite228.zip > ltablib.c

/*
** $Id$
** Library for Table Manipulation
** See Copyright Notice in lua.h
*/


#include &amp; lt; stddef.h &amp; gt;

#define ltablib_c
#define LUA_LIB

#include &quot; lua.h &quot;

#include &quot; lauxlib.h &quot;
#include &quot; lualib.h &quot;


#define aux_getn(L,n) (luaL_checktype(L, n, LUA_TTABLE), luaL_getn(L, n))


static int foreachi (lua_State *L) {
int i;
int n = aux_getn(L, 1);
luaL_checktype(L, 2, LUA_TFUNCTION);
for (i=1; i &amp; lt; = n; i++) {
lua_pushvalue(L, 2); /* function */
lua_pushinteger(L, i); /* 1st argument */
lua_rawgeti(L, 1, i); /* 2nd argument */
lua_call(L, 2, 1);
if (!lua_isnil(L, -1))
return 1;
lua_pop(L, 1); /* remove nil result */
}
return 0;
}


static int foreach (lua_State *L) {
luaL_checktype(L, 1, LUA_TTABLE);
luaL_checktype(L, 2, LUA_TFUNCTION);
lua_pushnil(L); /* first key */
while (lua_next(L, 1)) {
lua_pushvalue(L, 2); /* function */
lua_pushvalue(L, -3); /* key */
lua_pushvalue(L, -3); /* value */
lua_call(L, 2, 1);
if (!lua_isnil(L, -1))
return 1;
lua_pop(L, 2); /* remove value and result */
}
return 0;
}


static int maxn (lua_State *L) {
lua_Number max = 0;
luaL_checktype(L, 1, LUA_TTABLE);
lua_pushnil(L); /* first key */
while (lua_next(L, 1)) {
lua_pop(L, 1); /* remove value */
if (lua_type(L, -1) == LUA_TNUMBER) {
lua_Number v = lua_tonumber(L, -1);
if (v &amp; gt; max) max = v;
}
}
lua_pushnumber(L, max);
return 1;
}


static int getn (lua_State *L) {
lua_pushinteger(L, aux_getn(L, 1));
return 1;
}


static int setn (lua_State *L) {
luaL_checktype(L, 1, LUA_TTABLE);
#ifndef luaL_setn
luaL_setn(L, 1, luaL_checkint(L, 2));
#else
luaL_error(L, LUA_QL( &quot; setn &quot; ) &quot; is obsolete &quot; );
#endif
lua_pushvalue(L, 1);
return 1;
}


static int tinsert (lua_State *L) {
int e = aux_getn(L, 1) + 1; /* first empty element */
int pos; /* where to insert new element */
switch (lua_gettop(L)) {
case 2: { /* called with only 2 arguments */
pos = e; /* insert new element at the end */
break;
}
case 3: {
int i;
pos = luaL_checkint(L, 2); /* 2nd argument is the position */
if (pos &amp; gt; e) e = pos; /* `grow' array if necessary */
for (i = e; i &amp; gt; pos; i--) { /* move up elements */
lua_rawgeti(L, 1, i-1);
lua_rawseti(L, 1, i); /* t[i] = t[i-1] */
}
break;
}
default: {
return luaL_error(L, &quot; wrong number of arguments to &quot; LUA_QL( &quot; insert &quot; ));
}
}
luaL_setn(L, 1, e); /* new size */
lua_rawseti(L, 1, pos); /* t[pos] = v */
return 0;
}


static int tremove (lua_State *L) {
int e = aux_getn(L, 1);
int pos = luaL_optint(L, 2, e);
if (!(1 &amp; lt; = pos &amp; &amp; pos &amp; lt; = e)) /* position is outside bounds? */
return 0; /* nothing to remove */
luaL_setn(L, 1, e - 1); /* t.n = n-1 */
lua_rawgeti(L, 1, pos); /* result = t[pos] */
for ( ;pos &amp; lt; e; pos++) {
lua_rawgeti(L, 1, pos+1);
lua_rawseti(L, 1, pos); /* t[pos] = t[pos+1] */
}
lua_pushnil(L);
lua_rawseti(L, 1, e); /* t[e] = nil */
return 1;
}


static void addfield (lua_State *L, luaL_Buffer *b, int i) {
lua_rawgeti(L, 1, i);
if (!lua_isstring(L, -1))
luaL_error(L, &quot; invalid value (%s) at index %d in table for &quot;
LUA_QL( &quot; concat &quot; ), luaL_typename(L, -1), i);
luaL_addvalue(b);
}


static int tconcat (lua_State *L) {
luaL_Buffer b;
size_t lsep;
int i, last;
const char *sep = luaL_optlstring(L, 2, &quot; &quot; , &amp; lsep);
luaL_checktype(L, 1, LUA_TTABLE);
i = luaL_optint(L, 3, 1);
last = luaL_opt(L, luaL_checkint, 4, luaL_getn(L, 1));
luaL_buffinit(L, &amp; b);
for (; i &amp; lt; last; i++) {
addfield(L, &amp; b, i);
luaL_addlstring( &amp; b, sep, lsep);
}
if (i == last) /* add last value (if interval was not empty) */
addfield(L, &amp; b, i);
luaL_pushresult( &amp; b);
return 1;
}



/*
** {======================================================
** Quicksort
** (based on `Algorithms in MODULA-3', Robert Sedgewick;
** Addison-Wesley, 1993.)
*/


static void set2 (lua_State *L, int i, int j) {
lua_rawseti(L, 1, i);
lua_rawseti(L, 1, j);
}

static int sort_comp (lua_State *L, int a, int b) {
if (!lua_isnil(L, 2)) { /* function? */
int res;
lua_pushvalue(L, 2);
lua_pushvalue(L, a-1); /* -1 to compensate function */
lua_pushvalue(L, b-2); /* -2 to compensate function and `a' */
lua_call(L, 2, 1);
res = lua_toboolean(L, -1);
lua_pop(L, 1);
return res;
}
else /* a &amp; lt; b? */
return lua_lessthan(L, a, b);
}

static void auxsort (lua_State *L, int l, int u) {
while (l &amp; lt; u) { /* for tail recursion */
int i, j;
/* sort elements a[l], a[(l+u)/2] and a[u] */
lua_rawgeti(L, 1, l);
lua_rawgeti(L, 1, u);
if (sort_comp(L, -1, -2)) /* a[u] &amp; lt; a[l]? */
set2(L, l, u); /* swap a[l] - a[u] */
else
lua_pop(L, 2);
if (u-l == 1) break; /* only 2 elements */
i = (l+u)/2;
lua_rawgeti(L, 1, i);
lua_rawgeti(L, 1, l);
if (sort_comp(L, -2, -1)) /* a[i] &amp; lt; a[l]? */
set2(L, i, l);
else {
lua_pop(L, 1); /* remove a[l] */
lua_rawgeti(L, 1, u);
if (sort_comp(L, -1, -2)) /* a[u] &amp; lt; a[i]? */
set2(L, i, u);
else
lua_pop(L, 2);
}
if (u-l == 2) break; /* only 3 elements */
lua_rawgeti(L, 1, i); /* Pivot */
lua_pushvalue(L, -1);
lua_rawgeti(L, 1, u-1);
set2(L, i, u-1);
/* a[l] &amp; lt; = P == a[u-1] &amp; lt; = a[u], only need to sort from l+1 to u-2 */
i = l; j = u-1;
for (;;) { /* invariant: a[l..i] &amp; lt; = P &amp; lt; = a[j..u] */
/* repeat ++i until a[i] &amp; gt; = P */
while (lua_rawgeti(L, 1, ++i), sort_comp(L, -1, -2)) {
if (i &amp; gt; u) luaL_error(L, &quot; invalid order function for sorting &quot; );
lua_pop(L, 1); /* remove a[i] */
}
/* repeat --j until a[j] &amp; lt; = P */
while (lua_rawgeti(L, 1, --j), sort_comp(L, -3, -1)) {
if (j &amp; lt; l) luaL_error(L, &quot; invalid order function for sorting &quot; );
lua_pop(L, 1); /* remove a[j] */
}
if (j &amp; lt; i) {
lua_pop(L, 3); /* pop pivot, a[i], a[j] */
break;
}
set2(L, i, j);
}
lua_rawgeti(L, 1, u-1);
lua_rawgeti(L, 1, i);
set2(L, u-1, i); /* swap pivot (a[u-1]) with a[i] */
/* a[l..i-1] &amp; lt; = a[i] == P &amp; lt; = a[i+1..u] */
/* adjust so that smaller half is in [j..i] and larger one in [l..u] */
if (i-l &amp; lt; u-i) {
j=l; i=i-1; l=i+2;
}
else {
j=i+1; i=u; u=j-2;
}
auxsort(L, j, i); /* call recursively the smaller one */
} /* repeat the routine for the larger one */
}

static int sort (lua_State *L) {
int n = aux_getn(L, 1);
luaL_checkstack(L, 40, &quot; &quot; ); /* assume array is smaller than 2^40 */
if (!lua_isnoneornil(L, 2)) /* is there a 2nd argument? */
luaL_checktype(L, 2, LUA_TFUNCTION);
lua_settop(L, 2); /* make sure there is two arguments */
auxsort(L, 1, n);
return 0;
}

/* }====================================================== */


static const luaL_Reg tab_funcs[] = {
{ &quot; concat &quot; , tconcat},
{ &quot; foreach &quot; , foreach},
{ &quot; foreachi &quot; , foreachi},
{ &quot; getn &quot; , getn},
{ &quot; maxn &quot; , maxn},
{ &quot; insert &quot; , tinsert},
{ &quot; remove &quot; , tremove},
{ &quot; setn &quot; , setn},
{ &quot; sort &quot; , sort},
{NULL, NULL}
};


LUALIB_API int luaopen_table (lua_State *L) {
luaL_register(L, LUA_TABLIBNAME, tab_funcs);
return 1;
}


scite228.zip > linit.c

/*
** $Id$
** Initialization of libraries for lua.c
** See Copyright Notice in lua.h
*/


#define linit_c
#define LUA_LIB

#include &quot; lua.h &quot;

#include &quot; lualib.h &quot;
#include &quot; lauxlib.h &quot;


static const luaL_Reg lualibs[] = {
{ &quot; &quot; , luaopen_base},
{LUA_LOADLIBNAME, luaopen_package},
{LUA_TABLIBNAME, luaopen_table},
{LUA_IOLIBNAME, luaopen_io},
{LUA_OSLIBNAME, luaopen_os},
{LUA_STRLIBNAME, luaopen_string},
{LUA_MATHLIBNAME, luaopen_math},
{LUA_DBLIBNAME, luaopen_debug},
{NULL, NULL}
};


LUALIB_API void luaL_openlibs (lua_State *L) {
const luaL_Reg *lib = lualibs;
for (; lib- &amp; gt; func; lib++) {
lua_pushcfunction(L, lib- &amp; gt; func);
lua_pushstring(L, lib- &amp; gt; name);
lua_call(L, 1, 0);
}
}


scite228.zip > lmathlib.c

/*
** $Id$
** Standard mathematical library
** See Copyright Notice in lua.h
*/


#include &amp; lt; stdlib.h &amp; gt;
#include &amp; lt; math.h &amp; gt;

#define lmathlib_c
#define LUA_LIB

#include &quot; lua.h &quot;

#include &quot; lauxlib.h &quot;
#include &quot; lualib.h &quot;


#undef PI
#define PI (3.14159265358979323846)
#define RADIANS_PER_DEGREE (PI/180.0)



static int math_abs (lua_State *L) {
lua_pushnumber(L, fabs(luaL_checknumber(L, 1)));
return 1;
}

static int math_sin (lua_State *L) {
lua_pushnumber(L, sin(luaL_checknumber(L, 1)));
return 1;
}

static int math_sinh (lua_State *L) {
lua_pushnumber(L, sinh(luaL_checknumber(L, 1)));
return 1;
}

static int math_cos (lua_State *L) {
lua_pushnumber(L, cos(luaL_checknumber(L, 1)));
return 1;
}

static int math_cosh (lua_State *L) {
lua_pushnumber(L, cosh(luaL_checknumber(L, 1)));
return 1;
}

static int math_tan (lua_State *L) {
lua_pushnumber(L, tan(luaL_checknumber(L, 1)));
return 1;
}

static int math_tanh (lua_State *L) {
lua_pushnumber(L, tanh(luaL_checknumber(L, 1)));
return 1;
}

static int math_asin (lua_State *L) {
lua_pushnumber(L, asin(luaL_checknumber(L, 1)));
return 1;
}

static int math_acos (lua_State *L) {
lua_pushnumber(L, acos(luaL_checknumber(L, 1)));
return 1;
}

static int math_atan (lua_State *L) {
lua_pushnumber(L, atan(luaL_checknumber(L, 1)));
return 1;
}

static int math_atan2 (lua_State *L) {
lua_pushnumber(L, atan2(luaL_checknumber(L, 1), luaL_checknumber(L, 2)));
return 1;
}

static int math_ceil (lua_State *L) {
lua_pushnumber(L, ceil(luaL_checknumber(L, 1)));
return 1;
}

static int math_floor (lua_State *L) {
lua_pushnumber(L, floor(luaL_checknumber(L, 1)));
return 1;
}

static int math_fmod (lua_State *L) {
lua_pushnumber(L, fmod(luaL_checknumber(L, 1), luaL_checknumber(L, 2)));
return 1;
}

static int math_modf (lua_State *L) {
double ip;
double fp = modf(luaL_checknumber(L, 1), &amp; ip);
lua_pushnumber(L, ip);
lua_pushnumber(L, fp);
return 2;
}

static int math_sqrt (lua_State *L) {
lua_pushnumber(L, sqrt(luaL_checknumber(L, 1)));
return 1;
}

static int math_pow (lua_State *L) {
lua_pushnumber(L, pow(luaL_checknumber(L, 1), luaL_checknumber(L, 2)));
return 1;
}

static int math_log (lua_State *L) {
lua_pushnumber(L, log(luaL_checknumber(L, 1)));
return 1;
}

static int math_log10 (lua_State *L) {
lua_pushnumber(L, log10(luaL_checknumber(L, 1)));
return 1;
}

static int math_exp (lua_State *L) {
lua_pushnumber(L, exp(luaL_checknumber(L, 1)));
return 1;
}

static int math_deg (lua_State *L) {
lua_pushnumber(L, luaL_checknumber(L, 1)/RADIANS_PER_DEGREE);
return 1;
}

static int math_rad (lua_State *L) {
lua_pushnumber(L, luaL_checknumber(L, 1)*RADIANS_PER_DEGREE);
return 1;
}

static int math_frexp (lua_State *L) {
int e;
lua_pushnumber(L, frexp(luaL_checknumber(L, 1), &amp; e));
lua_pushinteger(L, e);
return 2;
}

static int math_ldexp (lua_State *L) {
lua_pushnumber(L, ldexp(luaL_checknumber(L, 1), luaL_checkint(L, 2)));
return 1;
}



static int math_min (lua_State *L) {
int n = lua_gettop(L); /* number of arguments */
lua_Number dmin = luaL_checknumber(L, 1);
int i;
for (i=2; i &amp; lt; =n; i++) {
lua_Number d = luaL_checknumber(L, i);
if (d &amp; lt; dmin)
dmin = d;
}
lua_pushnumber(L, dmin);
return 1;
}


static int math_max (lua_State *L) {
int n = lua_gettop(L); /* number of arguments */
lua_Number dmax = luaL_checknumber(L, 1);
int i;
for (i=2; i &amp; lt; =n; i++) {
lua_Number d = luaL_checknumber(L, i);
if (d &amp; gt; dmax)
dmax = d;
}
lua_pushnumber(L, dmax);
return 1;
}


static int math_random (lua_State *L) {
/* the `%' avoids the (rare) case of r==1, and is needed also because on
some systems (SunOS!) `rand()' may return a value larger than RAND_MAX */
lua_Number r = (lua_Number)(rand()%RAND_MAX) / (lua_Number)RAND_MAX;
switch (lua_gettop(L)) { /* check number of arguments */
case 0: { /* no arguments */
lua_pushnumber(L, r); /* Number between 0 and 1 */
break;
}
case 1: { /* only upper limit */
int u = luaL_checkint(L, 1);
luaL_argcheck(L, 1 &amp; lt; =u, 1, &quot; interval is empty &quot; );
lua_pushnumber(L, floor(r*u)+1); /* int between 1 and `u' */
break;
}
case 2: { /* lower and upper limits */
int l = luaL_checkint(L, 1);
int u = luaL_checkint(L, 2);
luaL_argcheck(L, l &amp; lt; =u, 2, &quot; interval is empty &quot; );
lua_pushnumber(L, floor(r*(u-l+1))+l); /* int between `l' and `u' */
break;
}
default: return luaL_error(L, &quot; wrong number of arguments &quot; );
}
return 1;
}


static int math_randomseed (lua_State *L) {
srand(luaL_checkint(L, 1));
return 0;
}


static const luaL_Reg mathlib[] = {
{ &quot; abs &quot; , math_abs},
{ &quot; acos &quot; , math_acos},
{ &quot; asin &quot; , math_asin},
{ &quot; atan2 &quot; , math_atan2},
{ &quot; atan &quot; , math_atan},
{ &quot; ceil &quot; , math_ceil},
{ &quot; cosh &quot; , math_cosh},
{ &quot; cos &quot; , math_cos},
{ &quot; deg &quot; , math_deg},
{ &quot; exp &quot; , math_exp},
{ &quot; floor &quot; , math_floor},
{ &quot; fmod &quot; , math_fmod},
{ &quot; frexp &quot; , math_frexp},
{ &quot; ldexp &quot; , math_ldexp},
{ &quot; log10 &quot; , math_log10},
{ &quot; log &quot; , math_log},
{ &quot; max &quot; , math_max},
{ &quot; min &quot; , math_min},
{ &quot; modf &quot; , math_modf},
{ &quot; pow &quot; , math_pow},
{ &quot; rad &quot; , math_rad},
{ &quot; random &quot; , math_random},
{ &quot; randomseed &quot; , math_randomseed},
{ &quot; sinh &quot; , math_sinh},
{ &quot; sin &quot; , math_sin},
{ &quot; sqrt &quot; , math_sqrt},
{ &quot; tanh &quot; , math_tanh},
{ &quot; tan &quot; , math_tan},
{NULL, NULL}
};


/*
** Open math library
*/
LUALIB_API int luaopen_math (lua_State *L) {
luaL_register(L, LUA_MATHLIBNAME, mathlib);
lua_pushnumber(L, PI);
lua_setfield(L, -2, &quot; pi &quot; );
lua_pushnumber(L, HUGE_VAL);
lua_setfield(L, -2, &quot; huge &quot; );
#if defined(LUA_COMPAT_MOD)
lua_getfield(L, -1, &quot; fmod &quot; );
lua_setfield(L, -2, &quot; mod &quot; );
#endif
return 1;
}


scite228.zip > lstrlib.c

/*
** $Id$
** Standard library for string operations and pattern-matching
** See Copyright Notice in lua.h
*/


#include &amp; lt; ctype.h &amp; gt;
#include &amp; lt; stddef.h &amp; gt;
#include &amp; lt; stdio.h &amp; gt;
#include &amp; lt; stdlib.h &amp; gt;
#include &amp; lt; string.h &amp; gt;

#define lstrlib_c
#define LUA_LIB

#include &quot; lua.h &quot;

#include &quot; lauxlib.h &quot;
#include &quot; lualib.h &quot;


/* macro to `unsign' a character */
#define uchar(c) ((unsigned char)(c))



static int str_len (lua_State *L) {
size_t l;
luaL_checklstring(L, 1, &amp; l);
lua_pushinteger(L, l);
return 1;
}


static ptrdiff_t posrelat (ptrdiff_t pos, size_t len) {
/* relative string position: negative means back from end */
if (pos &amp; lt; 0) pos += (ptrdiff_t)len + 1;
return (pos &amp; gt; = 0) ? pos : 0;
}


static int str_sub (lua_State *L) {
size_t l;
const char *s = luaL_checklstring(L, 1, &amp; l);
ptrdiff_t start = posrelat(luaL_checkinteger(L, 2), l);
ptrdiff_t end = posrelat(luaL_optinteger(L, 3, -1), l);
if (start &amp; lt; 1) start = 1;
if (end &amp; gt; (ptrdiff_t)l) end = (ptrdiff_t)l;
if (start &amp; lt; = end)
lua_pushlstring(L, s+start-1, end-start+1);
else lua_pushliteral(L, &quot; &quot; );
return 1;
}


static int str_reverse (lua_State *L) {
size_t l;
luaL_Buffer b;
const char *s = luaL_checklstring(L, 1, &amp; l);
luaL_buffinit(L, &amp; b);
while (l--) luaL_addchar( &amp; b, s[l]);
luaL_pushresult( &amp; b);
return 1;
}


static int str_lower (lua_State *L) {
size_t l;
size_t i;
luaL_Buffer b;
const char *s = luaL_checklstring(L, 1, &amp; l);
luaL_buffinit(L, &amp; b);
for (i=0; i &amp; lt; l; i++)
luaL_addchar( &amp; b, tolower(uchar(s[i])));
luaL_pushresult( &amp; b);
return 1;
}


static int str_upper (lua_State *L) {
size_t l;
size_t i;
luaL_Buffer b;
const char *s = luaL_checklstring(L, 1, &amp; l);
luaL_buffinit(L, &amp; b);
for (i=0; i &amp; lt; l; i++)
luaL_addchar( &amp; b, toupper(uchar(s[i])));
luaL_pushresult( &amp; b);
return 1;
}

static int str_rep (lua_State *L) {
size_t l;
luaL_Buffer b;
const char *s = luaL_checklstring(L, 1, &amp; l);
int n = luaL_checkint(L, 2);
luaL_buffinit(L, &amp; b);
while (n-- &amp; gt; 0)
luaL_addlstring( &amp; b, s, l);
luaL_pushresult( &amp; b);
return 1;
}


static int str_byte (lua_State *L) {
size_t l;
const char *s = luaL_checklstring(L, 1, &amp; l);
ptrdiff_t posi = posrelat(luaL_optinteger(L, 2, 1), l);
ptrdiff_t pose = posrelat(luaL_optinteger(L, 3, posi), l);
int n, i;
if (posi &amp; lt; = 0) posi = 1;
if ((size_t)pose &amp; gt; l) pose = l;
if (posi &amp; gt; pose) return 0; /* empty interval; return no values */
n = (int)(pose - posi + 1);
if (posi + n &amp; lt; = pose) /* overflow? */
luaL_error(L, &quot; string slice too long &quot; );
luaL_checkstack(L, n, &quot; string slice too long &quot; );
for (i=0; i &amp; lt; n; i++)
lua_pushinteger(L, uchar(s[posi+i-1]));
return n;
}


static int str_char (lua_State *L) {
int n = lua_gettop(L); /* number of arguments */
int i;
luaL_Buffer b;
luaL_buffinit(L, &amp; b);
for (i=1; i &amp; lt; =n; i++) {
int c = luaL_checkint(L, i);
luaL_argcheck(L, uchar(c) == c, i, &quot; invalid value &quot; );
luaL_addchar( &amp; b, uchar(c));
}
luaL_pushresult( &amp; b);
return 1;
}


static int writer (lua_State *L, const void* b, size_t size, void* B) {
(void)L;
luaL_addlstring((luaL_Buffer*) B, (const char *)b, size);
return 0;
}


static int str_dump (lua_State *L) {
luaL_Buffer b;
luaL_checktype(L, 1, LUA_TFUNCTION);
lua_settop(L, 1);
luaL_buffinit(L, &amp; b);
if (lua_dump(L, writer, &amp; b) != 0)
luaL_error(L, &quot; unable to dump given function &quot; );
luaL_pushresult( &amp; b);
return 1;
}



/*
** {======================================================
** PATTERN MATCHING
** =======================================================
*/


#define CAP_UNFINISHED (-1)
#define CAP_POSITION (-2)

typedef struct MatchState {
const char *src_init; /* init of source string */
const char *src_end; /* end (`\0') of source string */
lua_State *L;
int level; /* total number of captures (finished or unfinished) */
struct {
const char *init;
ptrdiff_t len;
} capture[LUA_MAXCAPTURES];
} MatchState;


#define L_ESC '%'
#define SPECIALS &quot; ^$*+?.([%- &quot;


static int check_capture (MatchState *ms, int l) {
l -= '1';
if (l &amp; lt; 0 || l &amp; gt; = ms- &amp; gt; level || ms- &amp; gt; capture[l].len == CAP_UNFINISHED)
return luaL_error(ms- &amp; gt; L, &quot; invalid capture index &quot; );
return l;
}


static int capture_to_close (MatchState *ms) {
int level = ms- &amp; gt; level;
for (level--; level &amp; gt; =0; level--)
if (ms- &amp; gt; capture[level].len == CAP_UNFINISHED) return level;
return luaL_error(ms- &amp; gt; L, &quot; invalid pattern capture &quot; );
}


static const char *classend (MatchState *ms, const char *p) {
switch (*p++) {
case L_ESC: {
if (*p == '\0')
luaL_error(ms- &amp; gt; L, &quot; malformed pattern (ends with &quot; LUA_QL( &quot; %% &quot; ) &quot; ) &quot; );
return p+1;
}
case '[': {
if (*p == '^') p++;
do { /* look for a `]' */
if (*p == '\0')
luaL_error(ms- &amp; gt; L, &quot; malformed pattern (missing &quot; LUA_QL( &quot; ] &quot; ) &quot; ) &quot; );
if (*(p++) == L_ESC &amp; &amp; *p != '\0')
p++; /* skip escapes (e.g. `%]') */
} while (*p != ']');
return p+1;
}
default: {
return p;
}
}
}


static int match_class (int c, int cl) {
int res;
switch (tolower(cl)) {
case 'a' : res = isalpha(c); break;
case 'c' : res = iscntrl(c); break;
case 'd' : res = isdigit(c); break;
case 'l' : res = islower(c); break;
case 'p' : res = ispunct(c); break;
case 's' : res = isspace(c); break;
case 'u' : res = isupper(c); break;
case 'w' : res = isalnum(c); break;
case 'x' : res = isxdigit(c); break;
case 'z' : res = (c == 0); break;
default: return (cl == c);
}
return (islower(cl) ? res : !res);
}


static int matchbracketclass (int c, const char *p, const char *ec) {
int sig = 1;
if (*(p+1) == '^') {
sig = 0;
p++; /* skip the `^' */
}
while (++p &amp; lt; ec) {
if (*p == L_ESC) {
p++;
if (match_class(c, uchar(*p)))
return sig;
}
else if ((*(p+1) == '-') &amp; &amp; (p+2 &amp; lt; ec)) {
p+=2;
if (uchar(*(p-2)) &amp; lt; = c &amp; &amp; c &amp; lt; = uchar(*p))
return sig;
}
else if (uchar(*p) == c) return sig;
}
return !sig;
}


static int singlematch (int c, const char *p, const char *ep) {
switch (*p) {
case '.': return 1; /* matches any char */
case L_ESC: return match_class(c, uchar(*(p+1)));
case '[': return matchbracketclass(c, p, ep-1);
default: return (uchar(*p) == c);
}
}


static const char *match (MatchState *ms, const char *s, const char *p);


static const char *matchbalance (MatchState *ms, const char *s,
const char *p) {
if (*p == 0 || *(p+1) == 0)
luaL_error(ms- &amp; gt; L, &quot; unbalanced pattern &quot; );
if (*s != *p) return NULL;
else {
int b = *p;
int e = *(p+1);
int cont = 1;
while (++s &amp; lt; ms- &amp; gt; src_end) {
if (*s == e) {
if (--cont == 0) return s+1;
}
else if (*s == b) cont++;
}
}
return NULL; /* string ends out of balance */
}


static const char *max_expand (MatchState *ms, const char *s,
const char *p, const char *ep) {
ptrdiff_t i = 0; /* counts maximum expand for item */
while ((s+i) &amp; lt; ms- &amp; gt; src_end &amp; &amp; singlematch(uchar(*(s+i)), p, ep))
i++;
/* keeps trying to match with the maximum repetitions */
while (i &amp; gt; =0) {
const char *res = match(ms, (s+i), ep+1);
if (res) return res;
i--; /* else didn't match; reduce 1 repetition to try again */
}
return NULL;
}


static const char *min_expand (MatchState *ms, const char *s,
const char *p, const char *ep) {
for (;;) {
const char *res = match(ms, s, ep+1);
if (res != NULL)
return res;
else if (s &amp; lt; ms- &amp; gt; src_end &amp; &amp; singlematch(uchar(*s), p, ep))
s++; /* try with one more repetition */
else return NULL;
}
}


static const char *start_capture (MatchState *ms, const char *s,
const char *p, int what) {
const char *res;
int level = ms- &amp; gt; level;
if (level &amp; gt; = LUA_MAXCAPTURES) luaL_error(ms- &amp; gt; L, &quot; too many captures &quot; );
ms- &amp; gt; capture[level].init = s;
ms- &amp; gt; capture[level].len = what;
ms- &amp; gt; level = level+1;
if ((res=match(ms, s, p)) == NULL) /* match failed? */
ms- &amp; gt; level--; /* undo capture */
return res;
}


static const char *end_capture (MatchState *ms, const char *s,
const char *p) {
int l = capture_to_close(ms);
const char *res;
ms- &amp; gt; capture[l].len = s - ms- &amp; gt; capture[l].init; /* close capture */
if ((res = match(ms, s, p)) == NULL) /* match failed? */
ms- &amp; gt; capture[l].len = CAP_UNFINISHED; /* undo capture */
return res;
}


static const char *match_capture (MatchState *ms, const char *s, int l) {
size_t len;
l = check_capture(ms, l);
len = ms- &amp; gt; capture[l].len;
if ((size_t)(ms- &amp; gt; src_end-s) &amp; gt; = len &amp; &amp;
memcmp(ms- &amp; gt; capture[l].init, s, len) == 0)
return s+len;
else return NULL;
}


static const char *match (MatchState *ms, const char *s, const char *p) {
init: /* using goto's to optimize tail recursion */
switch (*p) {
case '(': { /* start capture */
if (*(p+1) == ')') /* position capture? */
return start_capture(ms, s, p+2, CAP_POSITION);
else
return start_capture(ms, s, p+1, CAP_UNFINISHED);
}
case ')': { /* end capture */
return end_capture(ms, s, p+1);
}
case L_ESC: {
switch (*(p+1)) {
case 'b': { /* balanced string? */
s = matchbalance(ms, s, p+2);
if (s == NULL) return NULL;
p+=4; goto init; /* else return match(ms, s, p+4); */
}
case 'f': { /* frontier? */
const char *ep; char previous;
p += 2;
if (*p != '[')
luaL_error(ms- &amp; gt; L, &quot; missing &quot; LUA_QL( &quot; [ &quot; ) &quot; after &quot;
LUA_QL( &quot; %%f &quot; ) &quot; in pattern &quot; );
ep = classend(ms, p); /* points to what is next */
previous = (s == ms- &amp; gt; src_init) ? '\0' : *(s-1);
if (matchbracketclass(uchar(previous), p, ep-1) ||
!matchbracketclass(uchar(*s), p, ep-1)) return NULL;
p=ep; goto init; /* else return match(ms, s, ep); */
}
default: {
if (isdigit(uchar(*(p+1)))) { /* capture results (%0-%9)? */
s = match_capture(ms, s, uchar(*(p+1)));
if (s == NULL) return NULL;
p+=2; goto init; /* else return match(ms, s, p+2) */
}
goto dflt; /* case default */
}
}
}
case '\0': { /* end of pattern */
return s; /* match succeeded */
}
case '$': {
if (*(p+1) == '\0') /* is the `$' the last char in pattern? */
return (s == ms- &amp; gt; src_end) ? s : NULL; /* check end of string */
else goto dflt;
}
default: dflt: { /* it is a pattern item */
const char *ep = classend(ms, p); /* points to what is next */
int m = s &amp; lt; ms- &amp; gt; src_end &amp; &amp; singlematch(uchar(*s), p, ep);
switch (*ep) {
case '?': { /* optional */
const char *res;
if (m &amp; &amp; ((res=match(ms, s+1, ep+1)) != NULL))
return res;
p=ep+1; goto init; /* else return match(ms, s, ep+1); */
}
case '*': { /* 0 or more repetitions */
return max_expand(ms, s, p, ep);
}
case '+': { /* 1 or more repetitions */
return (m ? max_expand(ms, s+1, p, ep) : NULL);
}
case '-': { /* 0 or more repetitions (minimum) */
return min_expand(ms, s, p, ep);
}
default: {
if (!m) return NULL;
s++; p=ep; goto init; /* else return match(ms, s+1, ep); */
}
}
}
}
}



static const char *lmemfind (const char *s1, size_t l1,
const char *s2, size_t l2) {
if (l2 == 0) return s1; /* empty strings are everywhere */
else if (l2 &amp; gt; l1) return NULL; /* avoids a negative `l1' */
else {
const char *init; /* to search for a `*s2' inside `s1' */
l2--; /* 1st char will be checked by `memchr' */
l1 = l1-l2; /* `s2' cannot be found after that */
while (l1 &amp; gt; 0 &amp; &amp; (init = (const char *)memchr(s1, *s2, l1)) != NULL) {
init++; /* 1st char is already checked */
if (memcmp(init, s2+1, l2) == 0)
return init-1;
else { /* correct `l1' and `s1' to try again */
l1 -= init-s1;
s1 = init;
}
}
return NULL; /* not found */
}
}


static void push_onecapture (MatchState *ms, int i, const char *s,
const char *e) {
if (i &amp; gt; = ms- &amp; gt; level) {
if (i == 0) /* ms- &amp; gt; level == 0, too */
lua_pushlstring(ms- &amp; gt; L, s, e - s); /* add whole match */
else
luaL_error(ms- &amp; gt; L, &quot; invalid capture index &quot; );
}
else {
ptrdiff_t l = ms- &amp; gt; capture[i].len;
if (l == CAP_UNFINISHED) luaL_error(ms- &amp; gt; L, &quot; unfinished capture &quot; );
if (l == CAP_POSITION)
lua_pushinteger(ms- &amp; gt; L, ms- &amp; gt; capture[i].init - ms- &amp; gt; src_init + 1);
else
lua_pushlstring(ms- &amp; gt; L, ms- &amp; gt; capture[i].init, l);
}
}


static int push_captures (MatchState *ms, const char *s, const char *e) {
int i;
int nlevels = (ms- &amp; gt; level == 0 &amp; &amp; s) ? 1 : ms- &amp; gt; level;
luaL_checkstack(ms- &amp; gt; L, nlevels, &quot; too many captures &quot; );
for (i = 0; i &amp; lt; nlevels; i++)
push_onecapture(ms, i, s, e);
return nlevels; /* number of strings pushed */
}


static int str_find_aux (lua_State *L, int find) {
size_t l1, l2;
const char *s = luaL_checklstring(L, 1, &amp; l1);
const char *p = luaL_checklstring(L, 2, &amp; l2);
ptrdiff_t init = posrelat(luaL_optinteger(L, 3, 1), l1) - 1;
if (init &amp; lt; 0) init = 0;
else if ((size_t)(init) &amp; gt; l1) init = (ptrdiff_t)l1;
if (find &amp; &amp; (lua_toboolean(L, 4) || /* explicit request? */
strpbrk(p, SPECIALS) == NULL)) { /* or no special characters? */
/* do a plain search */
const char *s2 = lmemfind(s+init, l1-init, p, l2);
if (s2) {
lua_pushinteger(L, s2-s+1);
lua_pushinteger(L, s2-s+l2);
return 2;
}
}
else {
MatchState ms;
int anchor = (*p == '^') ? (p++, 1) : 0;
const char *s1=s+init;
ms.L = L;
ms.src_init = s;
ms.src_end = s+l1;
do {
const char *res;
ms.level = 0;
if ((res=match( &amp; ms, s1, p)) != NULL) {
if (find) {
lua_pushinteger(L, s1-s+1); /* start */
lua_pushinteger(L, res-s); /* end */
return push_captures( &amp; ms, NULL, 0) + 2;
}
else
return push_captures( &amp; ms, s1, res);
}
} while (s1++ &amp; lt; ms.src_end &amp; &amp; !anchor);
}
lua_pushnil(L); /* not found */
return 1;
}


static int str_find (lua_State *L) {
return str_find_aux(L, 1);
}


static int str_match (lua_State *L) {
return str_find_aux(L, 0);
}


static int gmatch_aux (lua_State *L) {
MatchState ms;
size_t ls;
const char *s = lua_tolstring(L, lua_upvalueindex(1), &amp; ls);
const char *p = lua_tostring(L, lua_upvalueindex(2));
const char *src;
ms.L = L;
ms.src_init = s;
ms.src_end = s+ls;
for (src = s + (size_t)lua_tointeger(L, lua_upvalueindex(3));
src &amp; lt; = ms.src_end;
src++) {
const char *e;
ms.level = 0;
if ((e = match( &amp; ms, src, p)) != NULL) {
lua_Integer newstart = e-s;
if (e == src) newstart++; /* empty match? go at least one position */
lua_pushinteger(L, newstart);
lua_replace(L, lua_upvalueindex(3));
return push_captures( &amp; ms, src, e);
}
}
return 0; /* not found */
}


static int gmatch (lua_State *L) {
luaL_checkstring(L, 1);
luaL_checkstring(L, 2);
lua_settop(L, 2);
lua_pushinteger(L, 0);
lua_pushcclosure(L, gmatch_aux, 3);
return 1;
}


static int gfind_nodef (lua_State *L) {
return luaL_error(L, LUA_QL( &quot; string.gfind &quot; ) &quot; was renamed to &quot;
LUA_QL( &quot; string.gmatch &quot; ));
}


static void add_s (MatchState *ms, luaL_Buffer *b, const char *s,
const char *e) {
size_t l, i;
const char *news = lua_tolstring(ms- &amp; gt; L, 3, &amp; l);
for (i = 0; i &amp; lt; l; i++) {
if (news[i] != L_ESC)
luaL_addchar(b, news[i]);
else {
i++; /* skip ESC */
if (!isdigit(uchar(news[i])))
luaL_addchar(b, news[i]);
else if (news[i] == '0')
luaL_addlstring(b, s, e - s);
else {
push_onecapture(ms, news[i] - '1', s, e);
luaL_addvalue(b); /* add capture to accumulated result */
}
}
}
}


static void add_value (MatchState *ms, luaL_Buffer *b, const char *s,
const char *e) {
lua_State *L = ms- &amp; gt; L;
switch (lua_type(L, 3)) {
case LUA_TNUMBER:
case LUA_TSTRING: {
add_s(ms, b, s, e);
return;
}
case LUA_TFUNCTION: {
int n;
lua_pushvalue(L, 3);
n = push_captures(ms, s, e);
lua_call(L, n, 1);
break;
}
case LUA_TTABLE: {
push_onecapture(ms, 0, s, e);
lua_gettable(L, 3);
break;
}
}
if (!lua_toboolean(L, -1)) { /* nil or false? */
lua_pop(L, 1);
lua_pushlstring(L, s, e - s); /* keep original text */
}
else if (!lua_isstring(L, -1))
luaL_error(L, &quot; invalid replacement value (a %s) &quot; , luaL_typename(L, -1));
luaL_addvalue(b); /* add result to accumulator */
}


static int str_gsub (lua_State *L) {
size_t srcl;
const char *src = luaL_checklstring(L, 1, &amp; srcl);
const char *p = luaL_checkstring(L, 2);
int tr = lua_type(L, 3);
int max_s = luaL_optint(L, 4, srcl+1);
int anchor = (*p == '^') ? (p++, 1) : 0;
int n = 0;
MatchState ms;
luaL_Buffer b;
luaL_argcheck(L, tr == LUA_TNUMBER || tr == LUA_TSTRING ||
tr == LUA_TFUNCTION || tr == LUA_TTABLE, 3,
&quot; string/function/table expected &quot; );
luaL_buffinit(L, &amp; b);
ms.L = L;
ms.src_init = src;
ms.src_end = src+srcl;
while (n &amp; lt; max_s) {
const char *e;
ms.level = 0;
e = match( &amp; ms, src, p);
if (e) {
n++;
add_value( &amp; ms, &amp; b, src, e);
}
if (e &amp; &amp; e &amp; gt; src) /* non empty match? */
src = e; /* skip it */
else if (src &amp; lt; ms.src_end)
luaL_addchar( &amp; b, *src++);
else break;
if (anchor) break;
}
luaL_addlstring( &amp; b, src, ms.src_end-src);
luaL_pushresult( &amp; b);
lua_pushinteger(L, n); /* number of substitutions */
return 2;
}

/* }====================================================== */


/* maximum size of each formatted item ( &amp; gt; len(format('%99.99f', -1e308))) */
#define MAX_ITEM 512
/* valid flags in a format specification */
#define FLAGS &quot; -+ #0 &quot;
/*
** maximum size of each format specification (such as '%-099.99d')
** (+10 accounts for %99.99x plus margin of error)
*/
#define MAX_FORMAT (sizeof(FLAGS) + sizeof(LUA_INTFRMLEN) + 10)


static void addquoted (lua_State *L, luaL_Buffer *b, int arg) {
size_t l;
const char *s = luaL_checklstring(L, arg, &amp; l);
luaL_addchar(b, ' &quot; ');
while (l--) {
switch (*s) {
case ' &quot; ': case '\\': case '\n': {
luaL_addchar(b, '\\');
luaL_addchar(b, *s);
break;
}
case '\r': {
luaL_addlstring(b, &quot; \\r &quot; , 2);
break;
}
case '\0': {
luaL_addlstring(b, &quot; \\000 &quot; , 4);
break;
}
default: {
luaL_addchar(b, *s);
break;
}
}
s++;
}
luaL_addchar(b, ' &quot; ');
}

static const char *scanformat (lua_State *L, const char *strfrmt, char *form) {
const char *p = strfrmt;
while (*p != '\0' &amp; &amp; strchr(FLAGS, *p) != NULL) p++; /* skip flags */
if ((size_t)(p - strfrmt) &amp; gt; = sizeof(FLAGS))
luaL_error(L, &quot; invalid format (repeated flags) &quot; );
if (isdigit(uchar(*p))) p++; /* skip width */
if (isdigit(uchar(*p))) p++; /* (2 digits at most) */
if (*p == '.') {
p++;
if (isdigit(uchar(*p))) p++; /* skip precision */
if (isdigit(uchar(*p))) p++; /* (2 digits at most) */
}
if (isdigit(uchar(*p)))
luaL_error(L, &quot; invalid format (width or precision too long) &quot; );
*(form++) = '%';
strncpy(form, strfrmt, p - strfrmt + 1);
form += p - strfrmt + 1;
*form = '\0';
return p;
}


static void addintlen (char *form) {
size_t l = strlen(form);
char spec = form[l - 1];
strcpy(form + l - 1, LUA_INTFRMLEN);
form[l + sizeof(LUA_INTFRMLEN) - 2] = spec;
form[l + sizeof(LUA_INTFRMLEN) - 1] = '\0';
}


static int str_format (lua_State *L) {
int arg = 1;
size_t sfl;
const char *strfrmt = luaL_checklstring(L, arg, &amp; sfl);
const char *strfrmt_end = strfrmt+sfl;
luaL_Buffer b;
luaL_buffinit(L, &amp; b);
while (strfrmt &amp; lt; strfrmt_end) {
if (*strfrmt != L_ESC)
luaL_addchar( &amp; b, *strfrmt++);
else if (*++strfrmt == L_ESC)
luaL_addchar( &amp; b, *strfrmt++); /* %% */
else { /* format item */
char form[MAX_FORMAT]; /* to store the format (`%...') */
char buff[MAX_ITEM]; /* to store the formatted item */
arg++;
strfrmt = scanformat(L, strfrmt, form);
switch (*strfrmt++) {
case 'c': {
sprintf(buff, form, (int)luaL_checknumber(L, arg));
break;
}
case 'd': case 'i': {
addintlen(form);
sprintf(buff, form, (LUA_INTFRM_T)luaL_checknumber(L, arg));
break;
}
case 'o': case 'u': case 'x': case 'X': {
addintlen(form);
sprintf(buff, form, (unsigned LUA_INTFRM_T)luaL_checknumber(L, arg));
break;
}
case 'e': case 'E': case 'f':
case 'g': case 'G': {
sprintf(buff, form, (double)luaL_checknumber(L, arg));
break;
}
case 'q': {
addquoted(L, &amp; b, arg);
continue; /* skip the 'addsize' at the end */
}
case 's': {
size_t l;
const char *s = luaL_checklstring(L, arg, &amp; l);
if (!strchr(form, '.') &amp; &amp; l &amp; gt; = 100) {
/* no precision and string is too long to be formatted;
keep original string */
lua_pushvalue(L, arg);
luaL_addvalue( &amp; b);
continue; /* skip the `addsize' at the end */
}
else {
sprintf(buff, form, s);
break;
}
}
default: { /* also treat cases `pnLlh' */
return luaL_error(L, &quot; invalid option &quot; LUA_QL( &quot; %%%c &quot; ) &quot; to &quot;
LUA_QL( &quot; format &quot; ), *(strfrmt - 1));
}
}
luaL_addlstring( &amp; b, buff, strlen(buff));
}
}
luaL_pushresult( &amp; b);
return 1;
}


static const luaL_Reg strlib[] = {
{ &quot; byte &quot; , str_byte},
{ &quot; char &quot; , str_char},
{ &quot; dump &quot; , str_dump},
{ &quot; find &quot; , str_find},
{ &quot; format &quot; , str_format},
{ &quot; gfind &quot; , gfind_nodef},
{ &quot; gmatch &quot; , gmatch},
{ &quot; gsub &quot; , str_gsub},
{ &quot; len &quot; , str_len},
{ &quot; lower &quot; , str_lower},
{ &quot; match &quot; , str_match},
{ &quot; rep &quot; , str_rep},
{ &quot; reverse &quot; , str_reverse},
{ &quot; sub &quot; , str_sub},
{ &quot; upper &quot; , str_upper},
{NULL, NULL}
};


static void createmetatable (lua_State *L) {
lua_createtable(L, 0, 1); /* create metatable for strings */
lua_pushliteral(L, &quot; &quot; ); /* dummy string */
lua_pushvalue(L, -2);
lua_setmetatable(L, -2); /* set string metatable */
lua_pop(L, 1); /* pop dummy string */
lua_pushvalue(L, -2); /* string library... */
lua_setfield(L, -2, &quot; __index &quot; ); /* ...is the __index metamethod */
lua_pop(L, 1); /* pop metatable */
}


/*
** Open string library
*/
LUALIB_API int luaopen_string (lua_State *L) {
luaL_register(L, LUA_STRLIBNAME, strlib);
#if defined(LUA_COMPAT_GFIND)
lua_getfield(L, -1, &quot; gmatch &quot; );
lua_setfield(L, -2, &quot; gfind &quot; );
#endif
createmetatable(L);
return 1;
}


scite228.zip > loslib.c

/*
** $Id$
** Standard Operating System library
** See Copyright Notice in lua.h
*/


#include &amp; lt; errno.h &amp; gt;
#include &amp; lt; locale.h &amp; gt;
#include &amp; lt; stdlib.h &amp; gt;
#include &amp; lt; string.h &amp; gt;
#include &amp; lt; time.h &amp; gt;

#define loslib_c
#define LUA_LIB

#include &quot; lua.h &quot;

#include &quot; lauxlib.h &quot;
#include &quot; lualib.h &quot;


static int os_pushresult (lua_State *L, int i, const char *filename) {
int en = errno; /* calls to Lua API may change this value */
if (i) {
lua_pushboolean(L, 1);
return 1;
}
else {
lua_pushnil(L);
lua_pushfstring(L, &quot; %s: %s &quot; , filename, strerror(en));
lua_pushinteger(L, en);
return 3;
}
}


static int os_execute (lua_State *L) {
lua_pushinteger(L, system(luaL_optstring(L, 1, NULL)));
return 1;
}


static int os_remove (lua_State *L) {
const char *filename = luaL_checkstring(L, 1);
return os_pushresult(L, remove(filename) == 0, filename);
}


static int os_rename (lua_State *L) {
const char *fromname = luaL_checkstring(L, 1);
const char *toname = luaL_checkstring(L, 2);
return os_pushresult(L, rename(fromname, toname) == 0, fromname);
}


static int os_tmpname (lua_State *L) {
char buff[LUA_TMPNAMBUFSIZE];
int err;
lua_tmpnam(buff, err);
if (err)
return luaL_error(L, &quot; unable to generate a unique filename &quot; );
lua_pushstring(L, buff);
return 1;
}


static int os_getenv (lua_State *L) {
lua_pushstring(L, getenv(luaL_checkstring(L, 1))); /* if NULL push nil */
return 1;
}


static int os_clock (lua_State *L) {
lua_pushnumber(L, ((lua_Number)clock())/(lua_Number)CLOCKS_PER_SEC);
return 1;
}


/*
** {======================================================
** Time/Date operations
** { year=%Y, month=%m, day=%d, hour=%H, min=%M, sec=%S,
** wday=%w+1, yday=%j, isdst=? }
** =======================================================
*/

static void setfield (lua_State *L, const char *key, int value) {
lua_pushinteger(L, value);
lua_setfield(L, -2, key);
}

static void setboolfield (lua_State *L, const char *key, int value) {
if (value &amp; lt; 0) /* undefined? */
return; /* does not set field */
lua_pushboolean(L, value);
lua_setfield(L, -2, key);
}

static int getboolfield (lua_State *L, const char *key) {
int res;
lua_getfield(L, -1, key);
res = lua_isnil(L, -1) ? -1 : lua_toboolean(L, -1);
lua_pop(L, 1);
return res;
}


static int getfield (lua_State *L, const char *key, int d) {
int res;
lua_getfield(L, -1, key);
if (lua_isnumber(L, -1))
res = (int)lua_tointeger(L, -1);
else {
if (d &amp; lt; 0)
return luaL_error(L, &quot; field &quot; LUA_QS &quot; missing in date table &quot; , key);
res = d;
}
lua_pop(L, 1);
return res;
}


static int os_date (lua_State *L) {
const char *s = luaL_optstring(L, 1, &quot; %c &quot; );
time_t t = luaL_opt(L, (time_t)luaL_checknumber, 2, time(NULL));
struct tm *stm;
if (*s == '!') { /* UTC? */
stm = gmtime( &amp; t);
s++; /* skip `!' */
}
else
stm = localtime( &amp; t);
if (stm == NULL) /* invalid date? */
lua_pushnil(L);
else if (strcmp(s, &quot; *t &quot; ) == 0) {
lua_createtable(L, 0, 9); /* 9 = number of fields */
setfield(L, &quot; sec &quot; , stm- &amp; gt; tm_sec);
setfield(L, &quot; min &quot; , stm- &amp; gt; tm_min);
setfield(L, &quot; hour &quot; , stm- &amp; gt; tm_hour);
setfield(L, &quot; day &quot; , stm- &amp; gt; tm_mday);
setfield(L, &quot; month &quot; , stm- &amp; gt; tm_mon+1);
setfield(L, &quot; year &quot; , stm- &amp; gt; tm_year+1900);
setfield(L, &quot; wday &quot; , stm- &amp; gt; tm_wday+1);
setfield(L, &quot; yday &quot; , stm- &amp; gt; tm_yday+1);
setboolfield(L, &quot; isdst &quot; , stm- &amp; gt; tm_isdst);
}
else {
char cc[3];
luaL_Buffer b;
cc[0] = '%'; cc[2] = '\0';
luaL_buffinit(L, &amp; b);
for (; *s; s++) {
if (*s != '%' || *(s + 1) == '\0') /* no conversion specifier? */
luaL_addchar( &amp; b, *s);
else {
size_t reslen;
char buff[200]; /* should be big enough for any conversion result */
cc[1] = *(++s);
reslen = strftime(buff, sizeof(buff), cc, stm);
luaL_addlstring( &amp; b, buff, reslen);
}
}
luaL_pushresult( &amp; b);
}
return 1;
}


static int os_time (lua_State *L) {
time_t t;
if (lua_isnoneornil(L, 1)) /* called without args? */
t = time(NULL); /* get current time */
else {
struct tm ts;
luaL_checktype(L, 1, LUA_TTABLE);
lua_settop(L, 1); /* make sure table is at the top */
ts.tm_sec = getfield(L, &quot; sec &quot; , 0);
ts.tm_min = getfield(L, &quot; min &quot; , 0);
ts.tm_hour = getfield(L, &quot; hour &quot; , 12);
ts.tm_mday = getfield(L, &quot; day &quot; , -1);
ts.tm_mon = getfield(L, &quot; month &quot; , -1) - 1;
ts.tm_year = getfield(L, &quot; year &quot; , -1) - 1900;
ts.tm_isdst = getboolfield(L, &quot; isdst &quot; );
t = mktime( &amp; ts);
}
if (t == (time_t)(-1))
lua_pushnil(L);
else
lua_pushnumber(L, (lua_Number)t);
return 1;
}


static int os_difftime (lua_State *L) {
lua_pushnumber(L, difftime((time_t)(luaL_checknumber(L, 1)),
(time_t)(luaL_optnumber(L, 2, 0))));
return 1;
}

/* }====================================================== */


static int os_setlocale (lua_State *L) {
static const int cat[] = {LC_ALL, LC_COLLATE, LC_CTYPE, LC_MONETARY,
LC_NUMERIC, LC_TIME};
static const char *const catnames[] = { &quot; all &quot; , &quot; collate &quot; , &quot; ctype &quot; , &quot; monetary &quot; ,
&quot; numeric &quot; , &quot; time &quot; , NULL};
const char *l = luaL_optstring(L, 1, NULL);
int op = luaL_checkoption(L, 2, &quot; all &quot; , catnames);
lua_pushstring(L, setlocale(cat[op], l));
return 1;
}


static int os_exit (lua_State *L) {
exit(luaL_optint(L, 1, EXIT_SUCCESS));
return 0;
}

static const luaL_Reg syslib[] = {
{ &quot; clock &quot; , os_clock},
{ &quot; date &quot; , os_date},
{ &quot; difftime &quot; , os_difftime},
{ &quot; execute &quot; , os_execute},
{ &quot; exit &quot; , os_exit},
{ &quot; getenv &quot; , os_getenv},
{ &quot; remove &quot; , os_remove},
{ &quot; rename &quot; , os_rename},
{ &quot; setlocale &quot; , os_setlocale},
{ &quot; time &quot; , os_time},
{ &quot; tmpname &quot; , os_tmpname},
{NULL, NULL}
};

/* }====================================================== */



LUALIB_API int luaopen_os (lua_State *L) {
luaL_register(L, LUA_OSLIBNAME, syslib);
return 1;
}


scite228.zip > lparser.c

/*
** $Id$
** Lua Parser
** See Copyright Notice in lua.h
*/


#include &amp; lt; string.h &amp; gt;

#define lparser_c
#define LUA_CORE

#include &quot; lua.h &quot;

#include &quot; lcode.h &quot;
#include &quot; ldebug.h &quot;
#include &quot; ldo.h &quot;
#include &quot; lfunc.h &quot;
#include &quot; llex.h &quot;
#include &quot; lmem.h &quot;
#include &quot; lobject.h &quot;
#include &quot; lopcodes.h &quot;
#include &quot; lparser.h &quot;
#include &quot; lstate.h &quot;
#include &quot; lstring.h &quot;
#include &quot; ltable.h &quot;



#define hasmultret(k) ((k) == VCALL || (k) == VVARARG)

#define getlocvar(fs, i) ((fs)- &amp; gt; f- &amp; gt; locvars[(fs)- &amp; gt; actvar[i]])

#define luaY_checklimit(fs,v,l,m) if ((v) &amp; gt; (l)) errorlimit(fs,l,m)


/*
** nodes for block list (list of active blocks)
*/
typedef struct BlockCnt {
struct BlockCnt *previous; /* chain */
int breaklist; /* list of jumps out of this loop */
lu_byte nactvar; /* # active locals outside the breakable structure */
lu_byte upval; /* true if some variable in the block is an upvalue */
lu_byte isbreakable; /* true if `block' is a loop */
} BlockCnt;



/*
** prototypes for recursive non-terminal functions
*/
static void chunk (LexState *ls);
static void expr (LexState *ls, expdesc *v);


static void anchor_token (LexState *ls) {
if (ls- &amp; gt; t.token == TK_NAME || ls- &amp; gt; t.token == TK_STRING) {
TString *ts = ls- &amp; gt; t.seminfo.ts;
luaX_newstring(ls, getstr(ts), ts- &amp; gt; tsv.len);
}
}


static void error_expected (LexState *ls, int token) {
luaX_syntaxerror(ls,
luaO_pushfstring(ls- &amp; gt; L, LUA_QS &quot; expected &quot; , luaX_token2str(ls, token)));
}


static void errorlimit (FuncState *fs, int limit, const char *what) {
const char *msg = (fs- &amp; gt; f- &amp; gt; linedefined == 0) ?
luaO_pushfstring(fs- &amp; gt; L, &quot; main function has more than %d %s &quot; , limit, what) :
luaO_pushfstring(fs- &amp; gt; L, &quot; function at line %d has more than %d %s &quot; ,
fs- &amp; gt; f- &amp; gt; linedefined, limit, what);
luaX_lexerror(fs- &amp; gt; ls, msg, 0);
}


static int testnext (LexState *ls, int c) {
if (ls- &amp; gt; t.token == c) {
luaX_next(ls);
return 1;
}
else return 0;
}


static void check (LexState *ls, int c) {
if (ls- &amp; gt; t.token != c)
error_expected(ls, c);
}

static void checknext (LexState *ls, int c) {
check(ls, c);
luaX_next(ls);
}


#define check_condition(ls,c,msg) { if (!(c)) luaX_syntaxerror(ls, msg); }



static void check_match (LexState *ls, int what, int who, int where) {
if (!testnext(ls, what)) {
if (where == ls- &amp; gt; linenumber)
error_expected(ls, what);
else {
luaX_syntaxerror(ls, luaO_pushfstring(ls- &amp; gt; L,
LUA_QS &quot; expected (to close &quot; LUA_QS &quot; at line %d) &quot; ,
luaX_token2str(ls, what), luaX_token2str(ls, who), where));
}
}
}


static TString *str_checkname (LexState *ls) {
TString *ts;
check(ls, TK_NAME);
ts = ls- &amp; gt; t.seminfo.ts;
luaX_next(ls);
return ts;
}


static void init_exp (expdesc *e, expkind k, int i) {
e- &amp; gt; f = e- &amp; gt; t = NO_JUMP;
e- &amp; gt; k = k;
e- &amp; gt; u.s.info = i;
}


static void codestring (LexState *ls, expdesc *e, TString *s) {
init_exp(e, VK, luaK_stringK(ls- &amp; gt; fs, s));
}


static void checkname(LexState *ls, expdesc *e) {
codestring(ls, e, str_checkname(ls));
}


static int registerlocalvar (LexState *ls, TString *varname) {
FuncState *fs = ls- &amp; gt; fs;
Proto *f = fs- &amp; gt; f;
int oldsize = f- &amp; gt; sizelocvars;
luaM_growvector(ls- &amp; gt; L, f- &amp; gt; locvars, fs- &amp; gt; nlocvars, f- &amp; gt; sizelocvars,
LocVar, SHRT_MAX, &quot; too many local variables &quot; );
while (oldsize &amp; lt; f- &amp; gt; sizelocvars) f- &amp; gt; locvars[oldsize++].varname = NULL;
f- &amp; gt; locvars[fs- &amp; gt; nlocvars].varname = varname;
luaC_objbarrier(ls- &amp; gt; L, f, varname);
return fs- &amp; gt; nlocvars++;
}


#define new_localvarliteral(ls,v,n) \
new_localvar(ls, luaX_newstring(ls, &quot; &quot; v, (sizeof(v)/sizeof(char))-1), n)


static void new_localvar (LexState *ls, TString *name, int n) {
FuncState *fs = ls- &amp; gt; fs;
luaY_checklimit(fs, fs- &amp; gt; nactvar+n+1, LUAI_MAXVARS, &quot; local variables &quot; );
fs- &amp; gt; actvar[fs- &amp; gt; nactvar+n] = cast(unsigned short, registerlocalvar(ls, name));
}


static void adjustlocalvars (LexState *ls, int nvars) {
FuncState *fs = ls- &amp; gt; fs;
fs- &amp; gt; nactvar = cast_byte(fs- &amp; gt; nactvar + nvars);
for (; nvars; nvars--) {
getlocvar(fs, fs- &amp; gt; nactvar - nvars).startpc = fs- &amp; gt; pc;
}
}


static void removevars (LexState *ls, int tolevel) {
FuncState *fs = ls- &amp; gt; fs;
while (fs- &amp; gt; nactvar &amp; gt; tolevel)
getlocvar(fs, --fs- &amp; gt; nactvar).endpc = fs- &amp; gt; pc;
}


static int indexupvalue (FuncState *fs, TString *name, expdesc *v) {
int i;
Proto *f = fs- &amp; gt; f;
int oldsize = f- &amp; gt; sizeupvalues;
for (i=0; i &amp; lt; f- &amp; gt; nups; i++) {
if (fs- &amp; gt; upvalues[i].k == v- &amp; gt; k &amp; &amp; fs- &amp; gt; upvalues[i].info == v- &amp; gt; u.s.info) {
lua_assert(f- &amp; gt; upvalues[i] == name);
return i;
}
}
/* new one */
luaY_checklimit(fs, f- &amp; gt; nups + 1, LUAI_MAXUPVALUES, &quot; upvalues &quot; );
luaM_growvector(fs- &amp; gt; L, f- &amp; gt; upvalues, f- &amp; gt; nups, f- &amp; gt; sizeupvalues,
TString *, MAX_INT, &quot; &quot; );
while (oldsize &amp; lt; f- &amp; gt; sizeupvalues) f- &amp; gt; upvalues[oldsize++] = NULL;
f- &amp; gt; upvalues[f- &amp; gt; nups] = name;
luaC_objbarrier(fs- &amp; gt; L, f, name);
lua_assert(v- &amp; gt; k == VLOCAL || v- &amp; gt; k == VUPVAL);
fs- &amp; gt; upvalues[f- &amp; gt; nups].k = cast_byte(v- &amp; gt; k);
fs- &amp; gt; upvalues[f- &amp; gt; nups].info = cast_byte(v- &amp; gt; u.s.info);
return f- &amp; gt; nups++;
}


static int searchvar (FuncState *fs, TString *n) {
int i;
for (i=fs- &amp; gt; nactvar-1; i &amp; gt; = 0; i--) {
if (n == getlocvar(fs, i).varname)
return i;
}
return -1; /* not found */
}


static void markupval (FuncState *fs, int level) {
BlockCnt *bl = fs- &amp; gt; bl;
while (bl &amp; &amp; bl- &amp; gt; nactvar &amp; gt; level) bl = bl- &amp; gt; previous;
if (bl) bl- &amp; gt; upval = 1;
}


static int singlevaraux (FuncState *fs, TString *n, expdesc *var, int base) {
if (fs == NULL) { /* no more levels? */
init_exp(var, VGLOBAL, NO_REG); /* default is global variable */
return VGLOBAL;
}
else {
int v = searchvar(fs, n); /* look up at current level */
if (v &amp; gt; = 0) {
init_exp(var, VLOCAL, v);
if (!base)
markupval(fs, v); /* local will be used as an upval */
return VLOCAL;
}
else { /* not found at current level; try upper one */
if (singlevaraux(fs- &amp; gt; prev, n, var, 0) == VGLOBAL)
return VGLOBAL;
var- &amp; gt; u.s.info = indexupvalue(fs, n, var); /* else was LOCAL or UPVAL */
var- &amp; gt; k = VUPVAL; /* upvalue in this level */
return VUPVAL;
}
}
}


static void singlevar (LexState *ls, expdesc *var) {
TString *varname = str_checkname(ls);
FuncState *fs = ls- &amp; gt; fs;
if (singlevaraux(fs, varname, var, 1) == VGLOBAL)
var- &amp; gt; u.s.info = luaK_stringK(fs, varname); /* info points to global name */
}


static void adjust_assign (LexState *ls, int nvars, int nexps, expdesc *e) {
FuncState *fs = ls- &amp; gt; fs;
int extra = nvars - nexps;
if (hasmultret(e- &amp; gt; k)) {
extra++; /* includes call itself */
if (extra &amp; lt; 0) extra = 0;
luaK_setreturns(fs, e, extra); /* last exp. provides the difference */
if (extra &amp; gt; 1) luaK_reserveregs(fs, extra-1);
}
else {
if (e- &amp; gt; k != VVOID) luaK_exp2nextreg(fs, e); /* close last expression */
if (extra &amp; gt; 0) {
int reg = fs- &amp; gt; freereg;
luaK_reserveregs(fs, extra);
luaK_nil(fs, reg, extra);
}
}
}


static void enterlevel (LexState *ls) {
if (++ls- &amp; gt; L- &amp; gt; nCcalls &amp; gt; LUAI_MAXCCALLS)
luaX_lexerror(ls, &quot; chunk has too many syntax levels &quot; , 0);
}


#define leavelevel(ls) ((ls)- &amp; gt; L- &amp; gt; nCcalls--)


static void enterblock (FuncState *fs, BlockCnt *bl, lu_byte isbreakable) {
bl- &amp; gt; breaklist = NO_JUMP;
bl- &amp; gt; isbreakable = isbreakable;
bl- &amp; gt; nactvar = fs- &amp; gt; nactvar;
bl- &amp; gt; upval = 0;
bl- &amp; gt; previous = fs- &amp; gt; bl;
fs- &amp; gt; bl = bl;
lua_assert(fs- &amp; gt; freereg == fs- &amp; gt; nactvar);
}


static void leaveblock (FuncState *fs) {
BlockCnt *bl = fs- &amp; gt; bl;
fs- &amp; gt; bl = bl- &amp; gt; previous;
removevars(fs- &amp; gt; ls, bl- &amp; gt; nactvar);
if (bl- &amp; gt; upval)
luaK_codeABC(fs, OP_CLOSE, bl- &amp; gt; nactvar, 0, 0);
/* a block either controls scope or breaks (never both) */
lua_assert(!bl- &amp; gt; isbreakable || !bl- &amp; gt; upval);
lua_assert(bl- &amp; gt; nactvar == fs- &amp; gt; nactvar);
fs- &amp; gt; freereg = fs- &amp; gt; nactvar; /* free registers */
luaK_patchtohere(fs, bl- &amp; gt; breaklist);
}


static void pushclosure (LexState *ls, FuncState *func, expdesc *v) {
FuncState *fs = ls- &amp; gt; fs;
Proto *f = fs- &amp; gt; f;
int oldsize = f- &amp; gt; sizep;
int i;
luaM_growvector(ls- &amp; gt; L, f- &amp; gt; p, fs- &amp; gt; np, f- &amp; gt; sizep, Proto *,
MAXARG_Bx, &quot; constant table overflow &quot; );
while (oldsize &amp; lt; f- &amp; gt; sizep) f- &amp; gt; p[oldsize++] = NULL;
f- &amp; gt; p[fs- &amp; gt; np++] = func- &amp; gt; f;
luaC_objbarrier(ls- &amp; gt; L, f, func- &amp; gt; f);
init_exp(v, VRELOCABLE, luaK_codeABx(fs, OP_CLOSURE, 0, fs- &amp; gt; np-1));
for (i=0; i &amp; lt; func- &amp; gt; f- &amp; gt; nups; i++) {
OpCode o = (func- &amp; gt; upvalues[i].k == VLOCAL) ? OP_MOVE : OP_GETUPVAL;
luaK_codeABC(fs, o, 0, func- &amp; gt; upvalues[i].info, 0);
}
}


static void open_func (LexState *ls, FuncState *fs) {
lua_State *L = ls- &amp; gt; L;
Proto *f = luaF_newproto(L);
fs- &amp; gt; f = f;
fs- &amp; gt; prev = ls- &amp; gt; fs; /* linked list of funcstates */
fs- &amp; gt; ls = ls;
fs- &amp; gt; L = L;
ls- &amp; gt; fs = fs;
fs- &amp; gt; pc = 0;
fs- &amp; gt; lasttarget = -1;
fs- &amp; gt; jpc = NO_JUMP;
fs- &amp; gt; freereg = 0;
fs- &amp; gt; nk = 0;
fs- &amp; gt; np = 0;
fs- &amp; gt; nlocvars = 0;
fs- &amp; gt; nactvar = 0;
fs- &amp; gt; bl = NULL;
f- &amp; gt; source = ls- &amp; gt; source;
f- &amp; gt; maxstacksize = 2; /* registers 0/1 are always valid */
fs- &amp; gt; h = luaH_new(L, 0, 0);
/* anchor table of constants and prototype (to avoid being collected) */
sethvalue2s(L, L- &amp; gt; top, fs- &amp; gt; h);
incr_top(L);
setptvalue2s(L, L- &amp; gt; top, f);
incr_top(L);
}


static void close_func (LexState *ls) {
lua_State *L = ls- &amp; gt; L;
FuncState *fs = ls- &amp; gt; fs;
Proto *f = fs- &amp; gt; f;
removevars(ls, 0);
luaK_ret(fs, 0, 0); /* final return */
luaM_reallocvector(L, f- &amp; gt; code, f- &amp; gt; sizecode, fs- &amp; gt; pc, Instruction);
f- &amp; gt; sizecode = fs- &amp; gt; pc;
luaM_reallocvector(L, f- &amp; gt; lineinfo, f- &amp; gt; sizelineinfo, fs- &amp; gt; pc, int);
f- &amp; gt; sizelineinfo = fs- &amp; gt; pc;
luaM_reallocvector(L, f- &amp; gt; k, f- &amp; gt; sizek, fs- &amp; gt; nk, TValue);
f- &amp; gt; sizek = fs- &amp; gt; nk;
luaM_reallocvector(L, f- &amp; gt; p, f- &amp; gt; sizep, fs- &amp; gt; np, Proto *);
f- &amp; gt; sizep = fs- &amp; gt; np;
luaM_reallocvector(L, f- &amp; gt; locvars, f- &amp; gt; sizelocvars, fs- &amp; gt; nlocvars, LocVar);
f- &amp; gt; sizelocvars = fs- &amp; gt; nlocvars;
luaM_reallocvector(L, f- &amp; gt; upvalues, f- &amp; gt; sizeupvalues, f- &amp; gt; nups, TString *);
f- &amp; gt; sizeupvalues = f- &amp; gt; nups;
lua_assert(luaG_checkcode(f));
lua_assert(fs- &amp; gt; bl == NULL);
ls- &amp; gt; fs = fs- &amp; gt; prev;
L- &amp; gt; top -= 2; /* remove table and prototype from the stack */
/* last token read was anchored in defunct function; must reanchor it */
if (fs) anchor_token(ls);
}


Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, const char *name) {
struct LexState lexstate;
struct FuncState funcstate;
lexstate.buff = buff;
luaX_setinput(L, &amp; lexstate, z, luaS_new(L, name));
open_func( &amp; lexstate, &amp; funcstate);
funcstate.f- &amp; gt; is_vararg = VARARG_ISVARARG; /* main func. is always vararg */
luaX_next( &amp; lexstate); /* read first token */
chunk( &amp; lexstate);
check( &amp; lexstate, TK_EOS);
close_func( &amp; lexstate);
lua_assert(funcstate.prev == NULL);
lua_assert(funcstate.f- &amp; gt; nups == 0);
lua_assert(lexstate.fs == NULL);
return funcstate.f;
}



/*============================================================*/
/* GRAMMAR RULES */
/*============================================================*/


static void field (LexState *ls, expdesc *v) {
/* field - &amp; gt; ['.' | ':'] NAME */
FuncState *fs = ls- &amp; gt; fs;
expdesc key;
luaK_exp2anyreg(fs, v);
luaX_next(ls); /* skip the dot or colon */
checkname(ls, &amp; key);
luaK_indexed(fs, v, &amp; key);
}


static void yindex (LexState *ls, expdesc *v) {
/* index - &amp; gt; '[' expr ']' */
luaX_next(ls); /* skip the '[' */
expr(ls, v);
luaK_exp2val(ls- &amp; gt; fs, v);
checknext(ls, ']');
}


/*
** {======================================================================
** Rules for Constructors
** =======================================================================
*/


struct ConsControl {
expdesc v; /* last list item read */
expdesc *t; /* table descriptor */
int nh; /* total number of `record' elements */
int na; /* total number of array elements */
int tostore; /* number of array elements pending to be stored */
};


static void recfield (LexState *ls, struct ConsControl *cc) {
/* recfield - &amp; gt; (NAME | `['exp1`]') = exp1 */
FuncState *fs = ls- &amp; gt; fs;
int reg = ls- &amp; gt; fs- &amp; gt; freereg;
expdesc key, val;
int rkkey;
if (ls- &amp; gt; t.token == TK_NAME) {
luaY_checklimit(fs, cc- &amp; gt; nh, MAX_INT, &quot; items in a constructor &quot; );
checkname(ls, &amp; key);
}
else /* ls- &amp; gt; t.token == '[' */
yindex(ls, &amp; key);
cc- &amp; gt; nh++;
checknext(ls, '=');
rkkey = luaK_exp2RK(fs, &amp; key);
expr(ls, &amp; val);
luaK_codeABC(fs, OP_SETTABLE, cc- &amp; gt; t- &amp; gt; u.s.info, rkkey, luaK_exp2RK(fs, &amp; val));
fs- &amp; gt; freereg = reg; /* free registers */
}


static void closelistfield (FuncState *fs, struct ConsControl *cc) {
if (cc- &amp; gt; v.k == VVOID) return; /* there is no list item */
luaK_exp2nextreg(fs, &amp; cc- &amp; gt; v);
cc- &amp; gt; v.k = VVOID;
if (cc- &amp; gt; tostore == LFIELDS_PER_FLUSH) {
luaK_setlist(fs, cc- &amp; gt; t- &amp; gt; u.s.info, cc- &amp; gt; na, cc- &amp; gt; tostore); /* flush */
cc- &amp; gt; tostore = 0; /* no more items pending */
}
}


static void lastlistfield (FuncState *fs, struct ConsControl *cc) {
if (cc- &amp; gt; tostore == 0) return;
if (hasmultret(cc- &amp; gt; v.k)) {
luaK_setmultret(fs, &amp; cc- &amp; gt; v);
luaK_setlist(fs, cc- &amp; gt; t- &amp; gt; u.s.info, cc- &amp; gt; na, LUA_MULTRET);
cc- &amp; gt; na--; /* do not count last expression (unknown number of elements) */
}
else {
if (cc- &amp; gt; v.k != VVOID)
luaK_exp2nextreg(fs, &amp; cc- &amp; gt; v);
luaK_setlist(fs, cc- &amp; gt; t- &amp; gt; u.s.info, cc- &amp; gt; na, cc- &amp; gt; tostore);
}
}


static void listfield (LexState *ls, struct ConsControl *cc) {
expr(ls, &amp; cc- &amp; gt; v);
luaY_checklimit(ls- &amp; gt; fs, cc- &amp; gt; na, MAX_INT, &quot; items in a constructor &quot; );
cc- &amp; gt; na++;
cc- &amp; gt; tostore++;
}


static void constructor (LexState *ls, expdesc *t) {
/* constructor - &amp; gt; ?? */
FuncState *fs = ls- &amp; gt; fs;
int line = ls- &amp; gt; linenumber;
int pc = luaK_codeABC(fs, OP_NEWTABLE, 0, 0, 0);
struct ConsControl cc;
cc.na = cc.nh = cc.tostore = 0;
cc.t = t;
init_exp(t, VRELOCABLE, pc);
init_exp( &amp; cc.v, VVOID, 0); /* no value (yet) */
luaK_exp2nextreg(ls- &amp; gt; fs, t); /* fix it at stack top (for gc) */
checknext(ls, '{');
do {
lua_assert(cc.v.k == VVOID || cc.tostore &amp; gt; 0);
if (ls- &amp; gt; t.token == '}') break;
closelistfield(fs, &amp; cc);
switch(ls- &amp; gt; t.token) {
case TK_NAME: { /* may be listfields or recfields */
luaX_lookahead(ls);
if (ls- &amp; gt; lookahead.token != '=') /* expression? */
listfield(ls, &amp; cc);
else
recfield(ls, &amp; cc);
break;
}
case '[': { /* constructor_item - &amp; gt; recfield */
recfield(ls, &amp; cc);
break;
}
default: { /* constructor_part - &amp; gt; listfield */
listfield(ls, &amp; cc);
break;
}
}
} while (testnext(ls, ',') || testnext(ls, ';'));
check_match(ls, '}', '{', line);
lastlistfield(fs, &amp; cc);
SETARG_B(fs- &amp; gt; f- &amp; gt; code[pc], luaO_int2fb(cc.na)); /* set initial array size */
SETARG_C(fs- &amp; gt; f- &amp; gt; code[pc], luaO_int2fb(cc.nh)); /* set initial table size */
}

/* }====================================================================== */



static void parlist (LexState *ls) {
/* parlist - &amp; gt; [ param { `,' param } ] */
FuncState *fs = ls- &amp; gt; fs;
Proto *f = fs- &amp; gt; f;
int nparams = 0;
f- &amp; gt; is_vararg = 0;
if (ls- &amp; gt; t.token != ')') { /* is `parlist' not empty? */
do {
switch (ls- &amp; gt; t.token) {
case TK_NAME: { /* param - &amp; gt; NAME */
new_localvar(ls, str_checkname(ls), nparams++);
break;
}
case TK_DOTS: { /* param - &amp; gt; `...' */
luaX_next(ls);
#if defined(LUA_COMPAT_VARARG)
/* use `arg' as default name */
new_localvarliteral(ls, &quot; arg &quot; , nparams++);
f- &amp; gt; is_vararg = VARARG_HASARG | VARARG_NEEDSARG;
#endif
f- &amp; gt; is_vararg |= VARARG_ISVARARG;
break;
}
default: luaX_syntaxerror(ls, &quot; &amp; lt; name &amp; gt; or &quot; LUA_QL( &quot; ... &quot; ) &quot; expected &quot; );
}
} while (!f- &amp; gt; is_vararg &amp; &amp; testnext(ls, ','));
}
adjustlocalvars(ls, nparams);
f- &amp; gt; numparams = cast_byte(fs- &amp; gt; nactvar - (f- &amp; gt; is_vararg &amp; VARARG_HASARG));
luaK_reserveregs(fs, fs- &amp; gt; nactvar); /* reserve register for parameters */
}


static void body (LexState *ls, expdesc *e, int needself, int line) {
/* body - &amp; gt; `(' parlist `)' chunk END */
FuncState new_fs;
open_func(ls, &amp; new_fs);
new_fs.f- &amp; gt; linedefined = line;
checknext(ls, '(');
if (needself) {
new_localvarliteral(ls, &quot; self &quot; , 0);
adjustlocalvars(ls, 1);
}
parlist(ls);
checknext(ls, ')');
chunk(ls);
new_fs.f- &amp; gt; lastlinedefined = ls- &amp; gt; linenumber;
check_match(ls, TK_END, TK_FUNCTION, line);
close_func(ls);
pushclosure(ls, &amp; new_fs, e);
}


static int explist1 (LexState *ls, expdesc *v) {
/* explist1 - &amp; gt; expr { `,' expr } */
int n = 1; /* at least one expression */
expr(ls, v);
while (testnext(ls, ',')) {
luaK_exp2nextreg(ls- &amp; gt; fs, v);
expr(ls, v);
n++;
}
return n;
}


static void funcargs (LexState *ls, expdesc *f) {
FuncState *fs = ls- &amp; gt; fs;
expdesc args;
int base, nparams;
int line = ls- &amp; gt; linenumber;
switch (ls- &amp; gt; t.token) {
case '(': { /* funcargs - &amp; gt; `(' [ explist1 ] `)' */
if (line != ls- &amp; gt; lastline)
luaX_syntaxerror(ls, &quot; ambiguous syntax (function call x new statement) &quot; );
luaX_next(ls);
if (ls- &amp; gt; t.token == ')') /* arg list is empty? */
args.k = VVOID;
else {
explist1(ls, &amp; args);
luaK_setmultret(fs, &amp; args);
}
check_match(ls, ')', '(', line);
break;
}
case '{': { /* funcargs - &amp; gt; constructor */
constructor(ls, &amp; args);
break;
}
case TK_STRING: { /* funcargs - &amp; gt; STRING */
codestring(ls, &amp; args, ls- &amp; gt; t.seminfo.ts);
luaX_next(ls); /* must use `seminfo' before `next' */
break;
}
default: {
luaX_syntaxerror(ls, &quot; function arguments expected &quot; );
return;
}
}
lua_assert(f- &amp; gt; k == VNONRELOC);
base = f- &amp; gt; u.s.info; /* base register for call */
if (hasmultret(args.k))
nparams = LUA_MULTRET; /* open call */
else {
if (args.k != VVOID)
luaK_exp2nextreg(fs, &amp; args); /* close last argument */
nparams = fs- &amp; gt; freereg - (base+1);
}
init_exp(f, VCALL, luaK_codeABC(fs, OP_CALL, base, nparams+1, 2));
luaK_fixline(fs, line);
fs- &amp; gt; freereg = base+1; /* call remove function and arguments and leaves
(unless changed) one result */
}




/*
** {======================================================================
** Expression parsing
** =======================================================================
*/


static void prefixexp (LexState *ls, expdesc *v) {
/* prefixexp - &amp; gt; NAME | '(' expr ')' */
switch (ls- &amp; gt; t.token) {
case '(': {
int line = ls- &amp; gt; linenumber;
luaX_next(ls);
expr(ls, v);
check_match(ls, ')', '(', line);
luaK_dischargevars(ls- &amp; gt; fs, v);
return;
}
case TK_NAME: {
singlevar(ls, v);
return;
}
default: {
luaX_syntaxerror(ls, &quot; unexpected symbol &quot; );
return;
}
}
}


static void primaryexp (LexState *ls, expdesc *v) {
/* primaryexp - &amp; gt;
prefixexp { `.' NAME | `[' exp `]' | `:' NAME funcargs | funcargs } */
FuncState *fs = ls- &amp; gt; fs;
prefixexp(ls, v);
for (;;) {
switch (ls- &amp; gt; t.token) {
case '.': { /* field */
field(ls, v);
break;
}
case '[': { /* `[' exp1 `]' */
expdesc key;
luaK_exp2anyreg(fs, v);
yindex(ls, &amp; key);
luaK_indexed(fs, v, &amp; key);
break;
}
case ':': { /* `:' NAME funcargs */
expdesc key;
luaX_next(ls);
checkname(ls, &amp; key);
luaK_self(fs, v, &amp; key);
funcargs(ls, v);
break;
}
case '(': case TK_STRING: case '{': { /* funcargs */
luaK_exp2nextreg(fs, v);
funcargs(ls, v);
break;
}
default: return;
}
}
}


static void simpleexp (LexState *ls, expdesc *v) {
/* simpleexp - &amp; gt; NUMBER | STRING | NIL | true | false | ... |
constructor | FUNCTION body | primaryexp */
switch (ls- &amp; gt; t.token) {
case TK_NUMBER: {
init_exp(v, VKNUM, 0);
v- &amp; gt; u.nval = ls- &amp; gt; t.seminfo.r;
break;
}
case TK_STRING: {
codestring(ls, v, ls- &amp; gt; t.seminfo.ts);
break;
}
case TK_NIL: {
init_exp(v, VNIL, 0);
break;
}
case TK_TRUE: {
init_exp(v, VTRUE, 0);
break;
}
case TK_FALSE: {
init_exp(v, VFALSE, 0);
break;
}
case TK_DOTS: { /* vararg */
FuncState *fs = ls- &amp; gt; fs;
check_condition(ls, fs- &amp; gt; f- &amp; gt; is_vararg,
&quot; cannot use &quot; LUA_QL( &quot; ... &quot; ) &quot; outside a vararg function &quot; );
fs- &amp; gt; f- &amp; gt; is_vararg &amp; = ~VARARG_NEEDSARG; /* don't need 'arg' */
init_exp(v, VVARARG, luaK_codeABC(fs, OP_VARARG, 0, 1, 0));
break;
}
case '{': { /* constructor */
constructor(ls, v);
return;
}
case TK_FUNCTION: {
luaX_next(ls);
body(ls, v, 0, ls- &amp; gt; linenumber);
return;
}
default: {
primaryexp(ls, v);
return;
}
}
luaX_next(ls);
}


static UnOpr getunopr (int op) {
switch (op) {
case TK_NOT: return OPR_NOT;
case '-': return OPR_MINUS;
case '#': return OPR_LEN;
default: return OPR_NOUNOPR;
}
}


static BinOpr getbinopr (int op) {
switch (op) {
case '+': return OPR_ADD;
case '-': return OPR_SUB;
case '*': return OPR_MUL;
case '/': return OPR_DIV;
case '%': return OPR_MOD;
case '^': return OPR_POW;
case TK_CONCAT: return OPR_CONCAT;
case TK_NE: return OPR_NE;
case TK_EQ: return OPR_EQ;
case ' &amp; lt; ': return OPR_LT;
case TK_LE: return OPR_LE;
case ' &amp; gt; ': return OPR_GT;
case TK_GE: return OPR_GE;
case TK_AND: return OPR_AND;
case TK_OR: return OPR_OR;
default: return OPR_NOBINOPR;
}
}


static const struct {
lu_byte left; /* left priority for each binary operator */
lu_byte right; /* right priority */
} priority[] = { /* ORDER OPR */
{6, 6}, {6, 6}, {7, 7}, {7, 7}, {7, 7}, /* `+' `-' `/' `%' */
{10, 9}, {5, 4}, /* power and concat (right associative) */
{3, 3}, {3, 3}, /* equality and inequality */
{3, 3}, {3, 3}, {3, 3}, {3, 3}, /* order */
{2, 2}, {1, 1} /* logical (and/or) */
};

#define UNARY_PRIORITY 8 /* priority for unary operators */


/*
** subexpr - &amp; gt; (simpleexp | unop subexpr) { binop subexpr }
** where `binop' is any binary operator with a priority higher than `limit'
*/
static BinOpr subexpr (LexState *ls, expdesc *v, unsigned int limit) {
BinOpr op;
UnOpr uop;
enterlevel(ls);
uop = getunopr(ls- &amp; gt; t.token);
if (uop != OPR_NOUNOPR) {
luaX_next(ls);
subexpr(ls, v, UNARY_PRIORITY);
luaK_prefix(ls- &amp; gt; fs, uop, v);
}
else simpleexp(ls, v);
/* expand while operators have priorities higher than `limit' */
op = getbinopr(ls- &amp; gt; t.token);
while (op != OPR_NOBINOPR &amp; &amp; priority[op].left &amp; gt; (int)limit) {
expdesc v2;
BinOpr nextop;
luaX_next(ls);
luaK_infix(ls- &amp; gt; fs, op, v);
/* read sub-expression with higher priority */
nextop = subexpr(ls, &amp; v2, priority[op].right);
luaK_posfix(ls- &amp; gt; fs, op, v, &amp; v2);
op = nextop;
}
leavelevel(ls);
return op; /* return first untreated operator */
}


static void expr (LexState *ls, expdesc *v) {
subexpr(ls, v, 0);
}

/* }==================================================================== */



/*
** {======================================================================
** Rules for Statements
** =======================================================================
*/


static int block_follow (int token) {
switch (token) {
case TK_ELSE: case TK_ELSEIF: case TK_END:
case TK_UNTIL: case TK_EOS:
return 1;
default: return 0;
}
}


static void block (LexState *ls) {
/* block - &amp; gt; chunk */
FuncState *fs = ls- &amp; gt; fs;
BlockCnt bl;
enterblock(fs, &amp; bl, 0);
chunk(ls);
lua_assert(bl.breaklist == NO_JUMP);
leaveblock(fs);
}


/*
** structure to chain all variables in the left-hand side of an
** assignment
*/
struct LHS_assign {
struct LHS_assign *prev;
expdesc v; /* variable (global, local, upvalue, or indexed) */
};


/*
** check whether, in an assignment to a local variable, the local variable
** is needed in a previous assignment (to a table). If so, save original
** local value in a safe place and use this safe copy in the previous
** assignment.
*/
static void check_conflict (LexState *ls, struct LHS_assign *lh, expdesc *v) {
FuncState *fs = ls- &amp; gt; fs;
int extra = fs- &amp; gt; freereg; /* eventual position to save local variable */
int conflict = 0;
for (; lh; lh = lh- &amp; gt; prev) {
if (lh- &amp; gt; v.k == VINDEXED) {
if (lh- &amp; gt; v.u.s.info == v- &amp; gt; u.s.info) { /* conflict? */
conflict = 1;
lh- &amp; gt; v.u.s.info = extra; /* previous assignment will use safe copy */
}
if (lh- &amp; gt; v.u.s.aux == v- &amp; gt; u.s.info) { /* conflict? */
conflict = 1;
lh- &amp; gt; v.u.s.aux = extra; /* previous assignment will use safe copy */
}
}
}
if (conflict) {
luaK_codeABC(fs, OP_MOVE, fs- &amp; gt; freereg, v- &amp; gt; u.s.info, 0); /* make copy */
luaK_reserveregs(fs, 1);
}
}


static void assignment (LexState *ls, struct LHS_assign *lh, int nvars) {
expdesc e;
check_condition(ls, VLOCAL &amp; lt; = lh- &amp; gt; v.k &amp; &amp; lh- &amp; gt; v.k &amp; lt; = VINDEXED,
&quot; syntax error &quot; );
if (testnext(ls, ',')) { /* assignment - &amp; gt; `,' primaryexp assignment */
struct LHS_assign nv;
nv.prev = lh;
primaryexp(ls, &amp; nv.v);
if (nv.v.k == VLOCAL)
check_conflict(ls, lh, &amp; nv.v);
luaY_checklimit(ls- &amp; gt; fs, nvars, LUAI_MAXCCALLS - ls- &amp; gt; L- &amp; gt; nCcalls,
&quot; variables in assignment &quot; );
assignment(ls, &amp; nv, nvars+1);
}
else { /* assignment - &amp; gt; `=' explist1 */
int nexps;
checknext(ls, '=');
nexps = explist1(ls, &amp; e);
if (nexps != nvars) {
adjust_assign(ls, nvars, nexps, &amp; e);
if (nexps &amp; gt; nvars)
ls- &amp; gt; fs- &amp; gt; freereg -= nexps - nvars; /* remove extra values */
}
else {
luaK_setoneret(ls- &amp; gt; fs, &amp; e); /* close last expression */
luaK_storevar(ls- &amp; gt; fs, &amp; lh- &amp; gt; v, &amp; e);
return; /* avoid default */
}
}
init_exp( &amp; e, VNONRELOC, ls- &amp; gt; fs- &amp; gt; freereg-1); /* default assignment */
luaK_storevar(ls- &amp; gt; fs, &amp; lh- &amp; gt; v, &amp; e);
}


static int cond (LexState *ls) {
/* cond - &amp; gt; exp */
expdesc v;
expr(ls, &amp; v); /* read condition */
if (v.k == VNIL) v.k = VFALSE; /* `falses' are all equal here */
luaK_goiftrue(ls- &amp; gt; fs, &amp; v);
return v.f;
}


static void breakstat (LexState *ls) {
FuncState *fs = ls- &amp; gt; fs;
BlockCnt *bl = fs- &amp; gt; bl;
int upval = 0;
while (bl &amp; &amp; !bl- &amp; gt; isbreakable) {
upval |= bl- &amp; gt; upval;
bl = bl- &amp; gt; previous;
}
if (!bl)
luaX_syntaxerror(ls, &quot; no loop to break &quot; );
if (upval)
luaK_codeABC(fs, OP_CLOSE, bl- &amp; gt; nactvar, 0, 0);
luaK_concat(fs, &amp; bl- &amp; gt; breaklist, luaK_jump(fs));
}


static void whilestat (LexState *ls, int line) {
/* whilestat - &amp; gt; WHILE cond DO block END */
FuncState *fs = ls- &amp; gt; fs;
int whileinit;
int condexit;
BlockCnt bl;
luaX_next(ls); /* skip WHILE */
whileinit = luaK_getlabel(fs);
condexit = cond(ls);
enterblock(fs, &amp; bl, 1);
checknext(ls, TK_DO);
block(ls);
luaK_patchlist(fs, luaK_jump(fs), whileinit);
check_match(ls, TK_END, TK_WHILE, line);
leaveblock(fs);
luaK_patchtohere(fs, condexit); /* false conditions finish the loop */
}


static void repeatstat (LexState *ls, int line) {
/* repeatstat - &amp; gt; REPEAT block UNTIL cond */
int condexit;
FuncState *fs = ls- &amp; gt; fs;
int repeat_init = luaK_getlabel(fs);
BlockCnt bl1, bl2;
enterblock(fs, &amp; bl1, 1); /* loop block */
enterblock(fs, &amp; bl2, 0); /* scope block */
luaX_next(ls); /* skip REPEAT */
chunk(ls);
check_match(ls, TK_UNTIL, TK_REPEAT, line);
condexit = cond(ls); /* read condition (inside scope block) */
if (!bl2.upval) { /* no upvalues? */
leaveblock(fs); /* finish scope */
luaK_patchlist(ls- &amp; gt; fs, condexit, repeat_init); /* close the loop */
}
else { /* complete semantics when there are upvalues */
breakstat(ls); /* if condition then break */
luaK_patchtohere(ls- &amp; gt; fs, condexit); /* else... */
leaveblock(fs); /* finish scope... */
luaK_patchlist(ls- &amp; gt; fs, luaK_jump(fs), repeat_init); /* and repeat */
}
leaveblock(fs); /* finish loop */
}


static int exp1 (LexState *ls) {
expdesc e;
int k;
expr(ls, &amp; e);
k = e.k;
luaK_exp2nextreg(ls- &amp; gt; fs, &amp; e);
return k;
}


static void forbody (LexState *ls, int base, int line, int nvars, int isnum) {
/* forbody - &amp; gt; DO block */
BlockCnt bl;
FuncState *fs = ls- &amp; gt; fs;
int prep, endfor;
adjustlocalvars(ls, 3); /* control variables */
checknext(ls, TK_DO);
prep = isnum ? luaK_codeAsBx(fs, OP_FORPREP, base, NO_JUMP) : luaK_jump(fs);
enterblock(fs, &amp; bl, 0); /* scope for declared variables */
adjustlocalvars(ls, nvars);
luaK_reserveregs(fs, nvars);
block(ls);
leaveblock(fs); /* end of scope for declared variables */
luaK_patchtohere(fs, prep);
endfor = (isnum) ? luaK_codeAsBx(fs, OP_FORLOOP, base, NO_JUMP) :
luaK_codeABC(fs, OP_TFORLOOP, base, 0, nvars);
luaK_fixline(fs, line); /* pretend that `OP_FOR' starts the loop */
luaK_patchlist(fs, (isnum ? endfor : luaK_jump(fs)), prep + 1);
}


static void fornum (LexState *ls, TString *varname, int line) {
/* fornum - &amp; gt; NAME = exp1,exp1[,exp1] forbody */
FuncState *fs = ls- &amp; gt; fs;
int base = fs- &amp; gt; freereg;
new_localvarliteral(ls, &quot; (for index) &quot; , 0);
new_localvarliteral(ls, &quot; (for limit) &quot; , 1);
new_localvarliteral(ls, &quot; (for step) &quot; , 2);
new_localvar(ls, varname, 3);
checknext(ls, '=');
exp1(ls); /* initial value */
checknext(ls, ',');
exp1(ls); /* limit */
if (testnext(ls, ','))
exp1(ls); /* optional step */
else { /* default step = 1 */
luaK_codeABx(fs, OP_LOADK, fs- &amp; gt; freereg, luaK_numberK(fs, 1));
luaK_reserveregs(fs, 1);
}
forbody(ls, base, line, 1, 1);
}


static void forlist (LexState *ls, TString *indexname) {
/* forlist - &amp; gt; NAME {,NAME} IN explist1 forbody */
FuncState *fs = ls- &amp; gt; fs;
expdesc e;
int nvars = 0;
int line;
int base = fs- &amp; gt; freereg;
/* create control variables */
new_localvarliteral(ls, &quot; (for generator) &quot; , nvars++);
new_localvarliteral(ls, &quot; (for state) &quot; , nvars++);
new_localvarliteral(ls, &quot; (for control) &quot; , nvars++);
/* create declared variables */
new_localvar(ls, indexname, nvars++);
while (testnext(ls, ','))
new_localvar(ls, str_checkname(ls), nvars++);
checknext(ls, TK_IN);
line = ls- &amp; gt; linenumber;
adjust_assign(ls, 3, explist1(ls, &amp; e), &amp; e);
luaK_checkstack(fs, 3); /* extra space to call generator */
forbody(ls, base, line, nvars - 3, 0);
}


static void forstat (LexState *ls, int line) {
/* forstat - &amp; gt; FOR (fornum | forlist) END */
FuncState *fs = ls- &amp; gt; fs;
TString *varname;
BlockCnt bl;
enterblock(fs, &amp; bl, 1); /* scope for loop and control variables */
luaX_next(ls); /* skip `for' */
varname = str_checkname(ls); /* first variable name */
switch (ls- &amp; gt; t.token) {
case '=': fornum(ls, varname, line); break;
case ',': case TK_IN: forlist(ls, varname); break;
default: luaX_syntaxerror(ls, LUA_QL( &quot; = &quot; ) &quot; or &quot; LUA_QL( &quot; in &quot; ) &quot; expected &quot; );
}
check_match(ls, TK_END, TK_FOR, line);
leaveblock(fs); /* loop scope (`break' jumps to this point) */
}


static int test_then_block (LexState *ls) {
/* test_then_block - &amp; gt; [IF | ELSEIF] cond THEN block */
int condexit;
luaX_next(ls); /* skip IF or ELSEIF */
condexit = cond(ls);
checknext(ls, TK_THEN);
block(ls); /* `then' part */
return condexit;
}


static void ifstat (LexState *ls, int line) {
/* ifstat - &amp; gt; IF cond THEN block {ELSEIF cond THEN block} [ELSE block] END */
FuncState *fs = ls- &amp; gt; fs;
int flist;
int escapelist = NO_JUMP;
flist = test_then_block(ls); /* IF cond THEN block */
while (ls- &amp; gt; t.token == TK_ELSEIF) {
luaK_concat(fs, &amp; escapelist, luaK_jump(fs));
luaK_patchtohere(fs, flist);
flist = test_then_block(ls); /* ELSEIF cond THEN block */
}
if (ls- &amp; gt; t.token == TK_ELSE) {
luaK_concat(fs, &amp; escapelist, luaK_jump(fs));
luaK_patchtohere(fs, flist);
luaX_next(ls); /* skip ELSE (after patch, for correct line info) */
block(ls); /* `else' part */
}
else
luaK_concat(fs, &amp; escapelist, flist);
luaK_patchtohere(fs, escapelist);
check_match(ls, TK_END, TK_IF, line);
}


static void localfunc (LexState *ls) {
expdesc v, b;
FuncState *fs = ls- &amp; gt; fs;
new_localvar(ls, str_checkname(ls), 0);
init_exp( &amp; v, VLOCAL, fs- &amp; gt; freereg);
luaK_reserveregs(fs, 1);
adjustlocalvars(ls, 1);
body(ls, &amp; b, 0, ls- &amp; gt; linenumber);
luaK_storevar(fs, &amp; v, &amp; b);
/* debug information will only see the variable after this point! */
getlocvar(fs, fs- &amp; gt; nactvar - 1).startpc = fs- &amp; gt; pc;
}


static void localstat (LexState *ls) {
/* stat - &amp; gt; LOCAL NAME {`,' NAME} [`=' explist1] */
int nvars = 0;
int nexps;
expdesc e;
do {
new_localvar(ls, str_checkname(ls), nvars++);
} while (testnext(ls, ','));
if (testnext(ls, '='))
nexps = explist1(ls, &amp; e);
else {
e.k = VVOID;
nexps = 0;
}
adjust_assign(ls, nvars, nexps, &amp; e);
adjustlocalvars(ls, nvars);
}


static int funcname (LexState *ls, expdesc *v) {
/* funcname - &amp; gt; NAME {field} [`:' NAME] */
int needself = 0;
singlevar(ls, v);
while (ls- &amp; gt; t.token == '.')
field(ls, v);
if (ls- &amp; gt; t.token == ':') {
needself = 1;
field(ls, v);
}
return needself;
}


static void funcstat (LexState *ls, int line) {
/* funcstat - &amp; gt; FUNCTION funcname body */
int needself;
expdesc v, b;
luaX_next(ls); /* skip FUNCTION */
needself = funcname(ls, &amp; v);
body(ls, &amp; b, needself, line);
luaK_storevar(ls- &amp; gt; fs, &amp; v, &amp; b);
luaK_fixline(ls- &amp; gt; fs, line); /* definition `happens' in the first line */
}


static void exprstat (LexState *ls) {
/* stat - &amp; gt; func | assignment */
FuncState *fs = ls- &amp; gt; fs;
struct LHS_assign v;
primaryexp(ls, &amp; v.v);
if (v.v.k == VCALL) /* stat - &amp; gt; func */
SETARG_C(getcode(fs, &amp; v.v), 1); /* call statement uses no results */
else { /* stat - &amp; gt; assignment */
v.prev = NULL;
assignment(ls, &amp; v, 1);
}
}


static void retstat (LexState *ls) {
/* stat - &amp; gt; RETURN explist */
FuncState *fs = ls- &amp; gt; fs;
expdesc e;
int first, nret; /* registers with returned values */
luaX_next(ls); /* skip RETURN */
if (block_follow(ls- &amp; gt; t.token) || ls- &amp; gt; t.token == ';')
first = nret = 0; /* return no values */
else {
nret = explist1(ls, &amp; e); /* optional return values */
if (hasmultret(e.k)) {
luaK_setmultret(fs, &amp; e);
if (e.k == VCALL &amp; &amp; nret == 1) { /* tail call? */
SET_OPCODE(getcode(fs, &amp; e), OP_TAILCALL);
lua_assert(GETARG_A(getcode(fs, &amp; e)) == fs- &amp; gt; nactvar);
}
first = fs- &amp; gt; nactvar;
nret = LUA_MULTRET; /* return all values */
}
else {
if (nret == 1) /* only one single value? */
first = luaK_exp2anyreg(fs, &amp; e);
else {
luaK_exp2nextreg(fs, &amp; e); /* values must go to the `stack' */
first = fs- &amp; gt; nactvar; /* return all `active' values */
lua_assert(nret == fs- &amp; gt; freereg - first);
}
}
}
luaK_ret(fs, first, nret);
}


static int statement (LexState *ls) {
int line = ls- &amp; gt; linenumber; /* may be needed for error messages */
switch (ls- &amp; gt; t.token) {
case TK_IF: { /* stat - &amp; gt; ifstat */
ifstat(ls, line);
return 0;
}
case TK_WHILE: { /* stat - &amp; gt; whilestat */
whilestat(ls, line);
return 0;
}
case TK_DO: { /* stat - &amp; gt; DO block END */
luaX_next(ls); /* skip DO */
block(ls);
check_match(ls, TK_END, TK_DO, line);
return 0;
}
case TK_FOR: { /* stat - &amp; gt; forstat */
forstat(ls, line);
return 0;
}
case TK_REPEAT: { /* stat - &amp; gt; repeatstat */
repeatstat(ls, line);
return 0;
}
case TK_FUNCTION: {
funcstat(ls, line); /* stat - &amp; gt; funcstat */
return 0;
}
case TK_LOCAL: { /* stat - &amp; gt; localstat */
luaX_next(ls); /* skip LOCAL */
if (testnext(ls, TK_FUNCTION)) /* local function? */
localfunc(ls);
else
localstat(ls);
return 0;
}
case TK_RETURN: { /* stat - &amp; gt; retstat */
retstat(ls);
return 1; /* must be last statement */
}
case TK_BREAK: { /* stat - &amp; gt; breakstat */
luaX_next(ls); /* skip BREAK */
breakstat(ls);
return 1; /* must be last statement */
}
default: {
exprstat(ls);
return 0; /* to avoid warnings */
}
}
}


static void chunk (LexState *ls) {
/* chunk - &amp; gt; { stat [`;'] } */
int islast = 0;
enterlevel(ls);
while (!islast &amp; &amp; !block_follow(ls- &amp; gt; t.token)) {
islast = statement(ls);
testnext(ls, ';');
lua_assert(ls- &amp; gt; fs- &amp; gt; f- &amp; gt; maxstacksize &amp; gt; = ls- &amp; gt; fs- &amp; gt; freereg &amp; &amp;
ls- &amp; gt; fs- &amp; gt; freereg &amp; gt; = ls- &amp; gt; fs- &amp; gt; nactvar);
ls- &amp; gt; fs- &amp; gt; freereg = ls- &amp; gt; fs- &amp; gt; nactvar; /* free registers */
}
leavelevel(ls);
}

/* }====================================================================== */


scite228.zip > lobject.h

/*
** $Id$
** Type definitions for Lua objects
** See Copyright Notice in lua.h
*/


#ifndef lobject_h
#define lobject_h


#include &amp; lt; stdarg.h &amp; gt;


#include &quot; llimits.h &quot;
#include &quot; lua.h &quot;


/* tags for values visible from Lua */
#define LAST_TAG LUA_TTHREAD

#define NUM_TAGS (LAST_TAG+1)


/*
** Extra tags for non-values
*/
#define LUA_TPROTO (LAST_TAG+1)
#define LUA_TUPVAL (LAST_TAG+2)
#define LUA_TDEADKEY (LAST_TAG+3)


/*
** Union of all collectable objects
*/
typedef union GCObject GCObject;


/*
** Common Header for all collectable objects (in macro form, to be
** included in other objects)
*/
#define CommonHeader GCObject *next; lu_byte tt; lu_byte marked


/*
** Common header in struct form
*/
typedef struct GCheader {
CommonHeader;
} GCheader;




/*
** Union of all Lua values
*/
typedef union {
GCObject *gc;
void *p;
lua_Number n;
int b;
} Value;


/*
** Tagged Values
*/

#define TValuefields Value value; int tt

typedef struct lua_TValue {
TValuefields;
} TValue;


/* Macros to test type */
#define ttisnil(o) (ttype(o) == LUA_TNIL)
#define ttisnumber(o) (ttype(o) == LUA_TNUMBER)
#define ttisstring(o) (ttype(o) == LUA_TSTRING)
#define ttistable(o) (ttype(o) == LUA_TTABLE)
#define ttisfunction(o) (ttype(o) == LUA_TFUNCTION)
#define ttisboolean(o) (ttype(o) == LUA_TBOOLEAN)
#define ttisuserdata(o) (ttype(o) == LUA_TUSERDATA)
#define ttisthread(o) (ttype(o) == LUA_TTHREAD)
#define ttislightuserdata(o) (ttype(o) == LUA_TLIGHTUSERDATA)

/* Macros to access values */
#define ttype(o) ((o)- &amp; gt; tt)
#define gcvalue(o) check_exp(iscollectable(o), (o)- &amp; gt; value.gc)
#define pvalue(o) check_exp(ttislightuserdata(o), (o)- &amp; gt; value.p)
#define nvalue(o) check_exp(ttisnumber(o), (o)- &amp; gt; value.n)
#define rawtsvalue(o) check_exp(ttisstring(o), &amp; (o)- &amp; gt; value.gc- &amp; gt; ts)
#define tsvalue(o) ( &amp; rawtsvalue(o)- &amp; gt; tsv)
#define rawuvalue(o) check_exp(ttisuserdata(o), &amp; (o)- &amp; gt; value.gc- &amp; gt; u)
#define uvalue(o) ( &amp; rawuvalue(o)- &amp; gt; uv)
#define clvalue(o) check_exp(ttisfunction(o), &amp; (o)- &amp; gt; value.gc- &amp; gt; cl)
#define hvalue(o) check_exp(ttistable(o), &amp; (o)- &amp; gt; value.gc- &amp; gt; h)
#define bvalue(o) check_exp(ttisboolean(o), (o)- &amp; gt; value.b)
#define thvalue(o) check_exp(ttisthread(o), &amp; (o)- &amp; gt; value.gc- &amp; gt; th)

#define l_isfalse(o) (ttisnil(o) || (ttisboolean(o) &amp; &amp; bvalue(o) == 0))

/*
** for internal debug only
*/
#define checkconsistency(obj) \
lua_assert(!iscollectable(obj) || (ttype(obj) == (obj)- &amp; gt; value.gc- &amp; gt; gch.tt))

#define checkliveness(g,obj) \
lua_assert(!iscollectable(obj) || \
((ttype(obj) == (obj)- &amp; gt; value.gc- &amp; gt; gch.tt) &amp; &amp; !isdead(g, (obj)- &amp; gt; value.gc)))


/* Macros to set values */
#define setnilvalue(obj) ((obj)- &amp; gt; tt=LUA_TNIL)

#define setnvalue(obj,x) \
{ TValue *i_o=(obj); i_o- &amp; gt; value.n=(x); i_o- &amp; gt; tt=LUA_TNUMBER; }

#define setpvalue(obj,x) \
{ TValue *i_o=(obj); i_o- &amp; gt; value.p=(x); i_o- &amp; gt; tt=LUA_TLIGHTUSERDATA; }

#define setbvalue(obj,x) \
{ TValue *i_o=(obj); i_o- &amp; gt; value.b=(x); i_o- &amp; gt; tt=LUA_TBOOLEAN; }

#define setsvalue(L,obj,x) \
{ TValue *i_o=(obj); \
i_o- &amp; gt; value.gc=cast(GCObject *, (x)); i_o- &amp; gt; tt=LUA_TSTRING; \
checkliveness(G(L),i_o); }

#define setuvalue(L,obj,x) \
{ TValue *i_o=(obj); \
i_o- &amp; gt; value.gc=cast(GCObject *, (x)); i_o- &amp; gt; tt=LUA_TUSERDATA; \
checkliveness(G(L),i_o); }

#define setthvalue(L,obj,x) \
{ TValue *i_o=(obj); \
i_o- &amp; gt; value.gc=cast(GCObject *, (x)); i_o- &amp; gt; tt=LUA_TTHREAD; \
checkliveness(G(L),i_o); }

#define setclvalue(L,obj,x) \
{ TValue *i_o=(obj); \
i_o- &amp; gt; value.gc=cast(GCObject *, (x)); i_o- &amp; gt; tt=LUA_TFUNCTION; \
checkliveness(G(L),i_o); }

#define sethvalue(L,obj,x) \
{ TValue *i_o=(obj); \
i_o- &amp; gt; value.gc=cast(GCObject *, (x)); i_o- &amp; gt; tt=LUA_TTABLE; \
checkliveness(G(L),i_o); }

#define setptvalue(L,obj,x) \
{ TValue *i_o=(obj); \
i_o- &amp; gt; value.gc=cast(GCObject *, (x)); i_o- &amp; gt; tt=LUA_TPROTO; \
checkliveness(G(L),i_o); }




#define setobj(L,obj1,obj2) \
{ const TValue *o2=(obj2); TValue *o1=(obj1); \
o1- &amp; gt; value = o2- &amp; gt; value; o1- &amp; gt; tt=o2- &amp; gt; tt; \
checkliveness(G(L),o1); }


/*
** different types of sets, according to destination
*/

/* from stack to (same) stack */
#define setobjs2s setobj
/* to stack (not from same stack) */
#define setobj2s setobj
#define setsvalue2s setsvalue
#define sethvalue2s sethvalue
#define setptvalue2s setptvalue
/* from table to same table */
#define setobjt2t setobj
/* to table */
#define setobj2t setobj
/* to new object */
#define setobj2n setobj
#define setsvalue2n setsvalue

#define setttype(obj, tt) (ttype(obj) = (tt))


#define iscollectable(o) (ttype(o) &amp; gt; = LUA_TSTRING)



typedef TValue *StkId; /* index to stack elements */


/*
** String headers for string table
*/
typedef union TString {
L_Umaxalign dummy; /* ensures maximum alignment for strings */
struct {
CommonHeader;
lu_byte reserved;
unsigned int hash;
size_t len;
} tsv;
} TString;


#define getstr(ts) cast(const char *, (ts) + 1)
#define svalue(o) getstr(rawtsvalue(o))



typedef union Udata {
L_Umaxalign dummy; /* ensures maximum alignment for `local' udata */
struct {
CommonHeader;
struct Table *metatable;
struct Table *env;
size_t len;
} uv;
} Udata;




/*
** Function Prototypes
*/
typedef struct Proto {
CommonHeader;
TValue *k; /* constants used by the function */
Instruction *code;
struct Proto **p; /* functions defined inside the function */
int *lineinfo; /* map from opcodes to source lines */
struct LocVar *locvars; /* information about local variables */
TString **upvalues; /* upvalue names */
TString *source;
int sizeupvalues;
int sizek; /* size of `k' */
int sizecode;
int sizelineinfo;
int sizep; /* size of `p' */
int sizelocvars;
int linedefined;
int lastlinedefined;
GCObject *gclist;
lu_byte nups; /* number of upvalues */
lu_byte numparams;
lu_byte is_vararg;
lu_byte maxstacksize;
} Proto;


/* masks for new-style vararg */
#define VARARG_HASARG 1
#define VARARG_ISVARARG 2
#define VARARG_NEEDSARG 4


typedef struct LocVar {
TString *varname;
int startpc; /* first point where variable is active */
int endpc; /* first point where variable is dead */
} LocVar;



/*
** Upvalues
*/

typedef struct UpVal {
CommonHeader;
TValue *v; /* points to stack or to its own value */
union {
TValue value; /* the value (when closed) */
struct { /* double linked list (when open) */
struct UpVal *prev;
struct UpVal *next;
} l;
} u;
} UpVal;


/*
** Closures
*/

#define ClosureHeader \
CommonHeader; lu_byte isC; lu_byte nupvalues; GCObject *gclist; \
struct Table *env

typedef struct CClosure {
ClosureHeader;
lua_CFunction f;
TValue upvalue[1];
} CClosure;


typedef struct LClosure {
ClosureHeader;
struct Proto *p;
UpVal *upvals[1];
} LClosure;


typedef union Closure {
CClosure c;
LClosure l;
} Closure;


#define iscfunction(o) (ttype(o) == LUA_TFUNCTION &amp; &amp; clvalue(o)- &amp; gt; c.isC)
#define isLfunction(o) (ttype(o) == LUA_TFUNCTION &amp; &amp; !clvalue(o)- &amp; gt; c.isC)


/*
** Tables
*/

typedef union TKey {
struct {
TValuefields;
struct Node *next; /* for chaining */
} nk;
TValue tvk;
} TKey;


typedef struct Node {
TValue i_val;
TKey i_key;
} Node;


typedef struct Table {
CommonHeader;
lu_byte flags; /* 1 &amp; lt; &amp; lt; p means tagmethod(p) is not present */
lu_byte lsizenode; /* log2 of size of `node' array */
struct Table *metatable;
TValue *array; /* array part */
Node *node;
Node *lastfree; /* any free position is before this position */
GCObject *gclist;
int sizearray; /* size of `array' array */
} Table;



/*
** `module' operation for hashing (size is always a power of 2)
*/
#define lmod(s,size) \
(check_exp((size &amp; (size-1))==0, (cast(int, (s) &amp; ((size)-1)))))


#define twoto(x) (1 &amp; lt; &amp; lt; (x))
#define sizenode(t) (twoto((t)- &amp; gt; lsizenode))


#define luaO_nilobject ( &amp; luaO_nilobject_)

LUAI_DATA const TValue luaO_nilobject_;

#define ceillog2(x) (luaO_log2((x)-1) + 1)

LUAI_FUNC int luaO_log2 (unsigned int x);
LUAI_FUNC int luaO_int2fb (unsigned int x);
LUAI_FUNC int luaO_fb2int (int x);
LUAI_FUNC int luaO_rawequalObj (const TValue *t1, const TValue *t2);
LUAI_FUNC int luaO_str2d (const char *s, lua_Number *result);
LUAI_FUNC const char *luaO_pushvfstring (lua_State *L, const char *fmt,
va_list argp);
LUAI_FUNC const char *luaO_pushfstring (lua_State *L, const char *fmt, ...);
LUAI_FUNC void luaO_chunkid (char *out, const char *source, size_t len);


#endif


scite228.zip > lcode.h

/*
** $Id$
** Code generator for Lua
** See Copyright Notice in lua.h
*/

#ifndef lcode_h
#define lcode_h

#include &quot; llex.h &quot;
#include &quot; lobject.h &quot;
#include &quot; lopcodes.h &quot;
#include &quot; lparser.h &quot;


/*
** Marks the end of a patch list. It is an invalid value both as an absolute
** address, and as a list link (would link an element to itself).
*/
#define NO_JUMP (-1)


/*
** grep &quot; ORDER OPR &quot; if you change these enums
*/
typedef enum BinOpr {
OPR_ADD, OPR_SUB, OPR_MUL, OPR_DIV, OPR_MOD, OPR_POW,
OPR_CONCAT,
OPR_NE, OPR_EQ,
OPR_LT, OPR_LE, OPR_GT, OPR_GE,
OPR_AND, OPR_OR,
OPR_NOBINOPR
} BinOpr;


typedef enum UnOpr { OPR_MINUS, OPR_NOT, OPR_LEN, OPR_NOUNOPR } UnOpr;


#define getcode(fs,e) ((fs)- &amp; gt; f- &amp; gt; code[(e)- &amp; gt; u.s.info])

#define luaK_codeAsBx(fs,o,A,sBx) luaK_codeABx(fs,o,A,(sBx)+MAXARG_sBx)

#define luaK_setmultret(fs,e) luaK_setreturns(fs, e, LUA_MULTRET)

LUAI_FUNC int luaK_codeABx (FuncState *fs, OpCode o, int A, unsigned int Bx);
LUAI_FUNC int luaK_codeABC (FuncState *fs, OpCode o, int A, int B, int C);
LUAI_FUNC void luaK_fixline (FuncState *fs, int line);
LUAI_FUNC void luaK_nil (FuncState *fs, int from, int n);
LUAI_FUNC void luaK_reserveregs (FuncState *fs, int n);
LUAI_FUNC void luaK_checkstack (FuncState *fs, int n);
LUAI_FUNC int luaK_stringK (FuncState *fs, TString *s);
LUAI_FUNC int luaK_numberK (FuncState *fs, lua_Number r);
LUAI_FUNC void luaK_dischargevars (FuncState *fs, expdesc *e);
LUAI_FUNC int luaK_exp2anyreg (FuncState *fs, expdesc *e);
LUAI_FUNC void luaK_exp2nextreg (FuncState *fs, expdesc *e);
LUAI_FUNC void luaK_exp2val (FuncState *fs, expdesc *e);
LUAI_FUNC int luaK_exp2RK (FuncState *fs, expdesc *e);
LUAI_FUNC void luaK_self (FuncState *fs, expdesc *e, expdesc *key);
LUAI_FUNC void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k);
LUAI_FUNC void luaK_goiftrue (FuncState *fs, expdesc *e);
LUAI_FUNC void luaK_storevar (FuncState *fs, expdesc *var, expdesc *e);
LUAI_FUNC void luaK_setreturns (FuncState *fs, expdesc *e, int nresults);
LUAI_FUNC void luaK_setoneret (FuncState *fs, expdesc *e);
LUAI_FUNC int luaK_jump (FuncState *fs);
LUAI_FUNC void luaK_ret (FuncState *fs, int first, int nret);
LUAI_FUNC void luaK_patchlist (FuncState *fs, int list, int target);
LUAI_FUNC void luaK_patchtohere (FuncState *fs, int list);
LUAI_FUNC void luaK_concat (FuncState *fs, int *l1, int l2);
LUAI_FUNC int luaK_getlabel (FuncState *fs);
LUAI_FUNC void luaK_prefix (FuncState *fs, UnOpr op, expdesc *v);
LUAI_FUNC void luaK_infix (FuncState *fs, BinOpr op, expdesc *v);
LUAI_FUNC void luaK_posfix (FuncState *fs, BinOpr op, expdesc *v1, expdesc *v2);
LUAI_FUNC void luaK_setlist (FuncState *fs, int base, int nelems, int tostore);


#endif


scite228.zip > lobject.c

/*
** $Id$
** Some generic functions over Lua objects
** See Copyright Notice in lua.h
*/

#include &amp; lt; ctype.h &amp; gt;
#include &amp; lt; stdarg.h &amp; gt;
#include &amp; lt; stdio.h &amp; gt;
#include &amp; lt; stdlib.h &amp; gt;
#include &amp; lt; string.h &amp; gt;

#define lobject_c
#define LUA_CORE

#include &quot; lua.h &quot;

#include &quot; ldo.h &quot;
#include &quot; lmem.h &quot;
#include &quot; lobject.h &quot;
#include &quot; lstate.h &quot;
#include &quot; lstring.h &quot;
#include &quot; lvm.h &quot;



const TValue luaO_nilobject_ = {{NULL}, LUA_TNIL};


/*
** converts an integer to a &quot; floating point byte &quot; , represented as
** (eeeeexxx), where the real value is (1xxx) * 2^(eeeee - 1) if
** eeeee != 0 and (xxx) otherwise.
*/
int luaO_int2fb (unsigned int x) {
int e = 0; /* expoent */
while (x &amp; gt; = 16) {
x = (x+1) &amp; gt; &amp; gt; 1;
e++;
}
if (x &amp; lt; 8) return x;
else return ((e+1) &amp; lt; &amp; lt; 3) | (cast_int(x) - 8);
}


/* converts back */
int luaO_fb2int (int x) {
int e = (x &amp; gt; &amp; gt; 3) &amp; 31;
if (e == 0) return x;
else return ((x &amp; 7)+8) &amp; lt; &amp; lt; (e - 1);
}


int luaO_log2 (unsigned int x) {
static const lu_byte log_2[256] = {
0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8
};
int l = -1;
while (x &amp; gt; = 256) { l += 8; x &amp; gt; &amp; gt; = 8; }
return l + log_2[x];

}


int luaO_rawequalObj (const TValue *t1, const TValue *t2) {
if (ttype(t1) != ttype(t2)) return 0;
else switch (ttype(t1)) {
case LUA_TNIL:
return 1;
case LUA_TNUMBER:
return luai_numeq(nvalue(t1), nvalue(t2));
case LUA_TBOOLEAN:
return bvalue(t1) == bvalue(t2); /* boolean true must be 1 !! */
case LUA_TLIGHTUSERDATA:
return pvalue(t1) == pvalue(t2);
default:
lua_assert(iscollectable(t1));
return gcvalue(t1) == gcvalue(t2);
}
}


int luaO_str2d (const char *s, lua_Number *result) {
char *endptr;
*result = lua_str2number(s, &amp; endptr);
if (endptr == s) return 0; /* conversion failed */
if (*endptr == 'x' || *endptr == 'X') /* maybe an hexadecimal constant? */
*result = cast_num(strtoul(s, &amp; endptr, 16));
if (*endptr == '\0') return 1; /* most common case */
while (isspace(cast(unsigned char, *endptr))) endptr++;
if (*endptr != '\0') return 0; /* invalid trailing characters? */
return 1;
}



static void pushstr (lua_State *L, const char *str) {
setsvalue2s(L, L- &amp; gt; top, luaS_new(L, str));
incr_top(L);
}


/* this function handles only `%d', `%c', %f, %p, and `%s' formats */
const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) {
int n = 1;
pushstr(L, &quot; &quot; );
for (;;) {
const char *e = strchr(fmt, '%');
if (e == NULL) break;
setsvalue2s(L, L- &amp; gt; top, luaS_newlstr(L, fmt, e-fmt));
incr_top(L);
switch (*(e+1)) {
case 's': {
const char *s = va_arg(argp, char *);
if (s == NULL) s = &quot; (null) &quot; ;
pushstr(L, s);
break;
}
case 'c': {
char buff[2];
buff[0] = cast(char, va_arg(argp, int));
buff[1] = '\0';
pushstr(L, buff);
break;
}
case 'd': {
setnvalue(L- &amp; gt; top, cast_num(va_arg(argp, int)));
incr_top(L);
break;
}
case 'f': {
setnvalue(L- &amp; gt; top, cast_num(va_arg(argp, l_uacNumber)));
incr_top(L);
break;
}
case 'p': {
char buff[4*sizeof(void *) + 8]; /* should be enough space for a `%p' */
sprintf(buff, &quot; %p &quot; , va_arg(argp, void *));
pushstr(L, buff);
break;
}
case '%': {
pushstr(L, &quot; % &quot; );
break;
}
default: {
char buff[3];
buff[0] = '%';
buff[1] = *(e+1);
buff[2] = '\0';
pushstr(L, buff);
break;
}
}
n += 2;
fmt = e+2;
}
pushstr(L, fmt);
luaV_concat(L, n+1, cast_int(L- &amp; gt; top - L- &amp; gt; base) - 1);
L- &amp; gt; top -= n;
return svalue(L- &amp; gt; top - 1);
}


const char *luaO_pushfstring (lua_State *L, const char *fmt, ...) {
const char *msg;
va_list argp;
va_start(argp, fmt);
msg = luaO_pushvfstring(L, fmt, argp);
va_end(argp);
return msg;
}


void luaO_chunkid (char *out, const char *source, size_t bufflen) {
if (*source == '=') {
strncpy(out, source+1, bufflen); /* remove first char */
out[bufflen-1] = '\0'; /* ensures null termination */
}
else { /* out = &quot; source &quot; , or &quot; ...source &quot; */
if (*source == '@') {
size_t l;
source++; /* skip the `@' */
bufflen -= sizeof( &quot; '...' &quot; );
l = strlen(source);
strcpy(out, &quot; &quot; );
if (l &amp; gt; bufflen) {
source += (l-bufflen); /* get last part of file name */
strcat(out, &quot; ... &quot; );
}
strcat(out, source);
}
else { /* out = [string &quot; string &quot; ] */
size_t len = strcspn(source, &quot; \n\r &quot; ); /* stop at first newline */
bufflen -= sizeof( &quot; [string \ &quot; ...\ &quot; ] &quot; );
if (len &amp; gt; bufflen) len = bufflen;
strcpy(out, &quot; [string \ &quot; &quot; );
if (source[len] != '\0') { /* must truncate? */
strncat(out, source, len);
strcat(out, &quot; ... &quot; );
}
else
strcat(out, source);
strcat(out, &quot; \ &quot; ] &quot; );
}
}
}


scite228.zip > lzio.c

/*
** $Id$
** a generic input stream interface
** See Copyright Notice in lua.h
*/


#include &amp; lt; string.h &amp; gt;

#define lzio_c
#define LUA_CORE

#include &quot; lua.h &quot;

#include &quot; llimits.h &quot;
#include &quot; lmem.h &quot;
#include &quot; lstate.h &quot;
#include &quot; lzio.h &quot;


int luaZ_fill (ZIO *z) {
size_t size;
lua_State *L = z- &amp; gt; L;
const char *buff;
lua_unlock(L);
buff = z- &amp; gt; reader(L, z- &amp; gt; data, &amp; size);
lua_lock(L);
if (buff == NULL || size == 0) return EOZ;
z- &amp; gt; n = size - 1;
z- &amp; gt; p = buff;
return char2int(*(z- &amp; gt; p++));
}


int luaZ_lookahead (ZIO *z) {
if (z- &amp; gt; n == 0) {
if (luaZ_fill(z) == EOZ)
return EOZ;
else {
z- &amp; gt; n++; /* luaZ_fill removed first byte; put back it */
z- &amp; gt; p--;
}
}
return char2int(*z- &amp; gt; p);
}


void luaZ_init (lua_State *L, ZIO *z, lua_Reader reader, void *data) {
z- &amp; gt; L = L;
z- &amp; gt; reader = reader;
z- &amp; gt; data = data;
z- &amp; gt; n = 0;
z- &amp; gt; p = NULL;
}


/* --------------------------------------------------------------- read --- */
size_t luaZ_read (ZIO *z, void *b, size_t n) {
while (n) {
size_t m;
if (luaZ_lookahead(z) == EOZ)
return n; /* return number of missing bytes */
m = (n &amp; lt; = z- &amp; gt; n) ? n : z- &amp; gt; n; /* min. between n and z- &amp; gt; n */
memcpy(b, z- &amp; gt; p, m);
z- &amp; gt; n -= m;
z- &amp; gt; p += m;
b = (char *)b + m;
n -= m;
}
return 0;
}

/* ------------------------------------------------------------------------ */
char *luaZ_openspace (lua_State *L, Mbuffer *buff, size_t n) {
if (n &amp; gt; buff- &amp; gt; buffsize) {
if (n &amp; lt; LUA_MINBUFFER) n = LUA_MINBUFFER;
luaZ_resizebuffer(L, buff, n);
}
return buff- &amp; gt; buffer;
}


scite228.zip > lstate.c

/*
** $Id$
** Global State
** See Copyright Notice in lua.h
*/


#include &amp; lt; stddef.h &amp; gt;

#define lstate_c
#define LUA_CORE

#include &quot; lua.h &quot;

#include &quot; ldebug.h &quot;
#include &quot; ldo.h &quot;
#include &quot; lfunc.h &quot;
#include &quot; lgc.h &quot;
#include &quot; llex.h &quot;
#include &quot; lmem.h &quot;
#include &quot; lstate.h &quot;
#include &quot; lstring.h &quot;
#include &quot; ltable.h &quot;
#include &quot; ltm.h &quot;


#define state_size(x) (sizeof(x) + LUAI_EXTRASPACE)
#define fromstate(l) (cast(lu_byte *, (l)) - LUAI_EXTRASPACE)
#define tostate(l) (cast(lua_State *, cast(lu_byte *, l) + LUAI_EXTRASPACE))


/*
** Main thread combines a thread state and the global state
*/
typedef struct LG {
lua_State l;
global_State g;
} LG;



static void stack_init (lua_State *L1, lua_State *L) {
/* initialize CallInfo array */
L1- &amp; gt; base_ci = luaM_newvector(L, BASIC_CI_SIZE, CallInfo);
L1- &amp; gt; ci = L1- &amp; gt; base_ci;
L1- &amp; gt; size_ci = BASIC_CI_SIZE;
L1- &amp; gt; end_ci = L1- &amp; gt; base_ci + L1- &amp; gt; size_ci - 1;
/* initialize stack array */
L1- &amp; gt; stack = luaM_newvector(L, BASIC_STACK_SIZE + EXTRA_STACK, TValue);
L1- &amp; gt; stacksize = BASIC_STACK_SIZE + EXTRA_STACK;
L1- &amp; gt; top = L1- &amp; gt; stack;
L1- &amp; gt; stack_last = L1- &amp; gt; stack+(L1- &amp; gt; stacksize - EXTRA_STACK)-1;
/* initialize first ci */
L1- &amp; gt; ci- &amp; gt; func = L1- &amp; gt; top;
setnilvalue(L1- &amp; gt; top++); /* `function' entry for this `ci' */
L1- &amp; gt; base = L1- &amp; gt; ci- &amp; gt; base = L1- &amp; gt; top;
L1- &amp; gt; ci- &amp; gt; top = L1- &amp; gt; top + LUA_MINSTACK;
}


static void freestack (lua_State *L, lua_State *L1) {
luaM_freearray(L, L1- &amp; gt; base_ci, L1- &amp; gt; size_ci, CallInfo);
luaM_freearray(L, L1- &amp; gt; stack, L1- &amp; gt; stacksize, TValue);
}


/*
** open parts that may cause memory-allocation errors
*/
static void f_luaopen (lua_State *L, void *ud) {
global_State *g = G(L);
UNUSED(ud);
stack_init(L, L); /* init stack */
sethvalue(L, gt(L), luaH_new(L, 0, 2)); /* table of globals */
sethvalue(L, registry(L), luaH_new(L, 0, 2)); /* registry */
luaS_resize(L, MINSTRTABSIZE); /* initial size of string table */
luaT_init(L);
luaX_init(L);
luaS_fix(luaS_newliteral(L, MEMERRMSG));
g- &amp; gt; GCthreshold = 4*g- &amp; gt; totalbytes;
}


static void preinit_state (lua_State *L, global_State *g) {
G(L) = g;
L- &amp; gt; stack = NULL;
L- &amp; gt; stacksize = 0;
L- &amp; gt; errorJmp = NULL;
L- &amp; gt; hook = NULL;
L- &amp; gt; hookmask = 0;
L- &amp; gt; basehookcount = 0;
L- &amp; gt; allowhook = 1;
resethookcount(L);
L- &amp; gt; openupval = NULL;
L- &amp; gt; size_ci = 0;
L- &amp; gt; nCcalls = L- &amp; gt; baseCcalls = 0;
L- &amp; gt; status = 0;
L- &amp; gt; base_ci = L- &amp; gt; ci = NULL;
L- &amp; gt; savedpc = NULL;
L- &amp; gt; errfunc = 0;
setnilvalue(gt(L));
}


static void close_state (lua_State *L) {
global_State *g = G(L);
luaF_close(L, L- &amp; gt; stack); /* close all upvalues for this thread */
luaC_freeall(L); /* collect all objects */
lua_assert(g- &amp; gt; rootgc == obj2gco(L));
lua_assert(g- &amp; gt; strt.nuse == 0);
luaM_freearray(L, G(L)- &amp; gt; strt.hash, G(L)- &amp; gt; strt.size, TString *);
luaZ_freebuffer(L, &amp; g- &amp; gt; buff);
freestack(L, L);
lua_assert(g- &amp; gt; totalbytes == sizeof(LG));
(*g- &amp; gt; frealloc)(g- &amp; gt; ud, fromstate(L), state_size(LG), 0);
}


lua_State *luaE_newthread (lua_State *L) {
lua_State *L1 = tostate(luaM_malloc(L, state_size(lua_State)));
luaC_link(L, obj2gco(L1), LUA_TTHREAD);
preinit_state(L1, G(L));
stack_init(L1, L); /* init stack */
setobj2n(L, gt(L1), gt(L)); /* share table of globals */
L1- &amp; gt; hookmask = L- &amp; gt; hookmask;
L1- &amp; gt; basehookcount = L- &amp; gt; basehookcount;
L1- &amp; gt; hook = L- &amp; gt; hook;
resethookcount(L1);
lua_assert(iswhite(obj2gco(L1)));
return L1;
}


void luaE_freethread (lua_State *L, lua_State *L1) {
luaF_close(L1, L1- &amp; gt; stack); /* close all upvalues for this thread */
lua_assert(L1- &amp; gt; openupval == NULL);
luai_userstatefree(L1);
freestack(L, L1);
luaM_freemem(L, fromstate(L1), state_size(lua_State));
}


LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) {
int i;
lua_State *L;
global_State *g;
void *l = (*f)(ud, NULL, 0, state_size(LG));
if (l == NULL) return NULL;
L = tostate(l);
g = &amp; ((LG *)L)- &amp; gt; g;
L- &amp; gt; next = NULL;
L- &amp; gt; tt = LUA_TTHREAD;
g- &amp; gt; currentwhite = bit2mask(WHITE0BIT, FIXEDBIT);
L- &amp; gt; marked = luaC_white(g);
set2bits(L- &amp; gt; marked, FIXEDBIT, SFIXEDBIT);
preinit_state(L, g);
g- &amp; gt; frealloc = f;
g- &amp; gt; ud = ud;
g- &amp; gt; mainthread = L;
g- &amp; gt; uvhead.u.l.prev = &amp; g- &amp; gt; uvhead;
g- &amp; gt; uvhead.u.l.next = &amp; g- &amp; gt; uvhead;
g- &amp; gt; GCthreshold = 0; /* mark it as unfinished state */
g- &amp; gt; strt.size = 0;
g- &amp; gt; strt.nuse = 0;
g- &amp; gt; strt.hash = NULL;
setnilvalue(registry(L));
luaZ_initbuffer(L, &amp; g- &amp; gt; buff);
g- &amp; gt; panic = NULL;
g- &amp; gt; gcstate = GCSpause;
g- &amp; gt; rootgc = obj2gco(L);
g- &amp; gt; sweepstrgc = 0;
g- &amp; gt; sweepgc = &amp; g- &amp; gt; rootgc;
g- &amp; gt; gray = NULL;
g- &amp; gt; grayagain = NULL;
g- &amp; gt; weak = NULL;
g- &amp; gt; tmudata = NULL;
g- &amp; gt; totalbytes = sizeof(LG);
g- &amp; gt; gcpause = LUAI_GCPAUSE;
g- &amp; gt; gcstepmul = LUAI_GCMUL;
g- &amp; gt; gcdept = 0;
for (i=0; i &amp; lt; NUM_TAGS; i++) g- &amp; gt; mt[i] = NULL;
if (luaD_rawrunprotected(L, f_luaopen, NULL) != 0) {
/* memory allocation error: free partial state */
close_state(L);
L = NULL;
}
else
luai_userstateopen(L);
return L;
}


static void callallgcTM (lua_State *L, void *ud) {
UNUSED(ud);
luaC_callGCTM(L); /* call GC metamethods for all udata */
}


LUA_API void lua_close (lua_State *L) {
L = G(L)- &amp; gt; mainthread; /* only the main thread can be closed */
lua_lock(L);
luaF_close(L, L- &amp; gt; stack); /* close all upvalues for this thread */
luaC_separateudata(L, 1); /* separate udata that have GC metamethods */
L- &amp; gt; errfunc = 0; /* no error function during GC metamethods */
do { /* repeat until no more errors */
L- &amp; gt; ci = L- &amp; gt; base_ci;
L- &amp; gt; base = L- &amp; gt; top = L- &amp; gt; ci- &amp; gt; base;
L- &amp; gt; nCcalls = L- &amp; gt; baseCcalls = 0;
} while (luaD_rawrunprotected(L, callallgcTM, NULL) != 0);
lua_assert(G(L)- &amp; gt; tmudata == NULL);
luai_userstateclose(L);
close_state(L);
}


scite228.zip > lmem.c

/*
** $Id$
** Interface to Memory Manager
** See Copyright Notice in lua.h
*/


#include &amp; lt; stddef.h &amp; gt;

#define lmem_c
#define LUA_CORE

#include &quot; lua.h &quot;

#include &quot; ldebug.h &quot;
#include &quot; ldo.h &quot;
#include &quot; lmem.h &quot;
#include &quot; lobject.h &quot;
#include &quot; lstate.h &quot;



/*
** About the realloc function:
** void * frealloc (void *ud, void *ptr, size_t osize, size_t nsize);
** (`osize' is the old size, `nsize' is the new size)
**
** Lua ensures that (ptr == NULL) iff (osize == 0).
**
** * frealloc(ud, NULL, 0, x) creates a new block of size `x'
**
** * frealloc(ud, p, x, 0) frees the block `p'
** (in this specific case, frealloc must return NULL).
** particularly, frealloc(ud, NULL, 0, 0) does nothing
** (which is equivalent to free(NULL) in ANSI C)
**
** frealloc returns NULL if it cannot create or reallocate the area
** (any reallocation to an equal or smaller size cannot fail!)
*/



#define MINSIZEARRAY 4


void *luaM_growaux_ (lua_State *L, void *block, int *size, size_t size_elems,
int limit, const char *errormsg) {
void *newblock;
int newsize;
if (*size &amp; gt; = limit/2) { /* cannot double it? */
if (*size &amp; gt; = limit) /* cannot grow even a little? */
luaG_runerror(L, errormsg);
newsize = limit; /* still have at least one free place */
}
else {
newsize = (*size)*2;
if (newsize &amp; lt; MINSIZEARRAY)
newsize = MINSIZEARRAY; /* minimum size */
}
newblock = luaM_reallocv(L, block, *size, newsize, size_elems);
*size = newsize; /* update only when everything else is OK */
return newblock;
}


void *luaM_toobig (lua_State *L) {
luaG_runerror(L, &quot; memory allocation error: block too big &quot; );
return NULL; /* to avoid warnings */
}



/*
** generic allocation routine.
*/
void *luaM_realloc_ (lua_State *L, void *block, size_t osize, size_t nsize) {
global_State *g = G(L);
lua_assert((osize == 0) == (block == NULL));
block = (*g- &amp; gt; frealloc)(g- &amp; gt; ud, block, osize, nsize);
if (block == NULL &amp; &amp; nsize &amp; gt; 0)
luaD_throw(L, LUA_ERRMEM);
lua_assert((nsize == 0) == (block == NULL));
g- &amp; gt; totalbytes = (g- &amp; gt; totalbytes - osize) + nsize;
return block;
}


scite228.zip > lstring.c

/*
** $Id$
** String table (keeps all strings handled by Lua)
** See Copyright Notice in lua.h
*/


#include &amp; lt; string.h &amp; gt;

#define lstring_c
#define LUA_CORE

#include &quot; lua.h &quot;

#include &quot; lmem.h &quot;
#include &quot; lobject.h &quot;
#include &quot; lstate.h &quot;
#include &quot; lstring.h &quot;



void luaS_resize (lua_State *L, int newsize) {
GCObject **newhash;
stringtable *tb;
int i;
if (G(L)- &amp; gt; gcstate == GCSsweepstring)
return; /* cannot resize during GC traverse */
newhash = luaM_newvector(L, newsize, GCObject *);
tb = &amp; G(L)- &amp; gt; strt;
for (i=0; i &amp; lt; newsize; i++) newhash[i] = NULL;
/* rehash */
for (i=0; i &amp; lt; tb- &amp; gt; size; i++) {
GCObject *p = tb- &amp; gt; hash[i];
while (p) { /* for each node in the list */
GCObject *next = p- &amp; gt; gch.next; /* save next */
unsigned int h = gco2ts(p)- &amp; gt; hash;
int h1 = lmod(h, newsize); /* new position */
lua_assert(cast_int(h%newsize) == lmod(h, newsize));
p- &amp; gt; gch.next = newhash[h1]; /* chain it */
newhash[h1] = p;
p = next;
}
}
luaM_freearray(L, tb- &amp; gt; hash, tb- &amp; gt; size, TString *);
tb- &amp; gt; size = newsize;
tb- &amp; gt; hash = newhash;
}


static TString *newlstr (lua_State *L, const char *str, size_t l,
unsigned int h) {
TString *ts;
stringtable *tb;
if (l+1 &amp; gt; (MAX_SIZET - sizeof(TString))/sizeof(char))
luaM_toobig(L);
ts = cast(TString *, luaM_malloc(L, (l+1)*sizeof(char)+sizeof(TString)));
ts- &amp; gt; tsv.len = l;
ts- &amp; gt; tsv.hash = h;
ts- &amp; gt; tsv.marked = luaC_white(G(L));
ts- &amp; gt; tsv.tt = LUA_TSTRING;
ts- &amp; gt; tsv.reserved = 0;
memcpy(ts+1, str, l*sizeof(char));
((char *)(ts+1))[l] = '\0'; /* ending 0 */
tb = &amp; G(L)- &amp; gt; strt;
h = lmod(h, tb- &amp; gt; size);
ts- &amp; gt; tsv.next = tb- &amp; gt; hash[h]; /* chain new entry */
tb- &amp; gt; hash[h] = obj2gco(ts);
tb- &amp; gt; nuse++;
if (tb- &amp; gt; nuse &amp; gt; cast(lu_int32, tb- &amp; gt; size) &amp; &amp; tb- &amp; gt; size &amp; lt; = MAX_INT/2)
luaS_resize(L, tb- &amp; gt; size*2); /* too crowded */
return ts;
}


TString *luaS_newlstr (lua_State *L, const char *str, size_t l) {
GCObject *o;
unsigned int h = cast(unsigned int, l); /* seed */
size_t step = (l &amp; gt; &amp; gt; 5)+1; /* if string is too long, don't hash all its chars */
size_t l1;
for (l1=l; l1 &amp; gt; =step; l1-=step) /* compute hash */
h = h ^ ((h &amp; lt; &amp; lt; 5)+(h &amp; gt; &amp; gt; 2)+cast(unsigned char, str[l1-1]));
for (o = G(L)- &amp; gt; strt.hash[lmod(h, G(L)- &amp; gt; strt.size)];
o != NULL;
o = o- &amp; gt; gch.next) {
TString *ts = rawgco2ts(o);
if (ts- &amp; gt; tsv.len == l &amp; &amp; (memcmp(str, getstr(ts), l) == 0)) {
/* string may be dead */
if (isdead(G(L), o)) changewhite(o);
return ts;
}
}
return newlstr(L, str, l, h); /* not found */
}


Udata *luaS_newudata (lua_State *L, size_t s, Table *e) {
Udata *u;
if (s &amp; gt; MAX_SIZET - sizeof(Udata))
luaM_toobig(L);
u = cast(Udata *, luaM_malloc(L, s + sizeof(Udata)));
u- &amp; gt; uv.marked = luaC_white(G(L)); /* is not finalized */
u- &amp; gt; uv.tt = LUA_TUSERDATA;
u- &amp; gt; uv.len = s;
u- &amp; gt; uv.metatable = NULL;
u- &amp; gt; uv.env = e;
/* chain it on udata list (after main thread) */
u- &amp; gt; uv.next = G(L)- &amp; gt; mainthread- &amp; gt; next;
G(L)- &amp; gt; mainthread- &amp; gt; next = obj2gco(u);
return u;
}


scite228.zip > lundump.c

/*
** $Id$
** load precompiled Lua chunks
** See Copyright Notice in lua.h
*/

#include &amp; lt; string.h &amp; gt;

#define lundump_c
#define LUA_CORE

#include &quot; lua.h &quot;

#include &quot; ldebug.h &quot;
#include &quot; ldo.h &quot;
#include &quot; lfunc.h &quot;
#include &quot; lmem.h &quot;
#include &quot; lobject.h &quot;
#include &quot; lstring.h &quot;
#include &quot; lundump.h &quot;
#include &quot; lzio.h &quot;

typedef struct {
lua_State* L;
ZIO* Z;
Mbuffer* b;
const char* name;
} LoadState;

#ifdef LUAC_TRUST_BINARIES
#define IF(c,s)
#define error(S,s)
#else
#define IF(c,s) if (c) error(S,s)

static void error(LoadState* S, const char* why)
{
luaO_pushfstring(S- &amp; gt; L, &quot; %s: %s in precompiled chunk &quot; ,S- &amp; gt; name,why);
luaD_throw(S- &amp; gt; L,LUA_ERRSYNTAX);
}
#endif

#define LoadMem(S,b,n,size) LoadBlock(S,b,(n)*(size))
#define LoadByte(S) (lu_byte)LoadChar(S)
#define LoadVar(S,x) LoadMem(S, &amp; x,1,sizeof(x))
#define LoadVector(S,b,n,size) LoadMem(S,b,n,size)

static void LoadBlock(LoadState* S, void* b, size_t size)
{
size_t r=luaZ_read(S- &amp; gt; Z,b,size);
IF (r!=0, &quot; unexpected end &quot; );
}

static int LoadChar(LoadState* S)
{
char x;
LoadVar(S,x);
return x;
}

static int LoadInt(LoadState* S)
{
int x;
LoadVar(S,x);
IF (x &amp; lt; 0, &quot; bad integer &quot; );
return x;
}

static lua_Number LoadNumber(LoadState* S)
{
lua_Number x;
LoadVar(S,x);
return x;
}

static TString* LoadString(LoadState* S)
{
size_t size;
LoadVar(S,size);
if (size==0)
return NULL;
else
{
char* s=luaZ_openspace(S- &amp; gt; L,S- &amp; gt; b,size);
LoadBlock(S,s,size);
return luaS_newlstr(S- &amp; gt; L,s,size-1); /* remove trailing '\0' */
}
}

static void LoadCode(LoadState* S, Proto* f)
{
int n=LoadInt(S);
f- &amp; gt; code=luaM_newvector(S- &amp; gt; L,n,Instruction);
f- &amp; gt; sizecode=n;
LoadVector(S,f- &amp; gt; code,n,sizeof(Instruction));
}

static Proto* LoadFunction(LoadState* S, TString* p);

static void LoadConstants(LoadState* S, Proto* f)
{
int i,n;
n=LoadInt(S);
f- &amp; gt; k=luaM_newvector(S- &amp; gt; L,n,TValue);
f- &amp; gt; sizek=n;
for (i=0; i &amp; lt; n; i++) setnilvalue( &amp; f- &amp; gt; k[i]);
for (i=0; i &amp; lt; n; i++)
{
TValue* o= &amp; f- &amp; gt; k[i];
int t=LoadChar(S);
switch (t)
{
case LUA_TNIL:
setnilvalue(o);
break;
case LUA_TBOOLEAN:
setbvalue(o,LoadChar(S)!=0);
break;
case LUA_TNUMBER:
setnvalue(o,LoadNumber(S));
break;
case LUA_TSTRING:
setsvalue2n(S- &amp; gt; L,o,LoadString(S));
break;
default:
error(S, &quot; bad constant &quot; );
break;
}
}
n=LoadInt(S);
f- &amp; gt; p=luaM_newvector(S- &amp; gt; L,n,Proto*);
f- &amp; gt; sizep=n;
for (i=0; i &amp; lt; n; i++) f- &amp; gt; p[i]=NULL;
for (i=0; i &amp; lt; n; i++) f- &amp; gt; p[i]=LoadFunction(S,f- &amp; gt; source);
}

static void LoadDebug(LoadState* S, Proto* f)
{
int i,n;
n=LoadInt(S);
f- &amp; gt; lineinfo=luaM_newvector(S- &amp; gt; L,n,int);
f- &amp; gt; sizelineinfo=n;
LoadVector(S,f- &amp; gt; lineinfo,n,sizeof(int));
n=LoadInt(S);
f- &amp; gt; locvars=luaM_newvector(S- &amp; gt; L,n,LocVar);
f- &amp; gt; sizelocvars=n;
for (i=0; i &amp; lt; n; i++) f- &amp; gt; locvars[i].varname=NULL;
for (i=0; i &amp; lt; n; i++)
{
f- &amp; gt; locvars[i].varname=LoadString(S);
f- &amp; gt; locvars[i].startpc=LoadInt(S);
f- &amp; gt; locvars[i].endpc=LoadInt(S);
}
n=LoadInt(S);
f- &amp; gt; upvalues=luaM_newvector(S- &amp; gt; L,n,TString*);
f- &amp; gt; sizeupvalues=n;
for (i=0; i &amp; lt; n; i++) f- &amp; gt; upvalues[i]=NULL;
for (i=0; i &amp; lt; n; i++) f- &amp; gt; upvalues[i]=LoadString(S);
}

static Proto* LoadFunction(LoadState* S, TString* p)
{
Proto* f;
if (++S- &amp; gt; L- &amp; gt; nCcalls &amp; gt; LUAI_MAXCCALLS) error(S, &quot; code too deep &quot; );
f=luaF_newproto(S- &amp; gt; L);
setptvalue2s(S- &amp; gt; L,S- &amp; gt; L- &amp; gt; top,f); incr_top(S- &amp; gt; L);
f- &amp; gt; source=LoadString(S); if (f- &amp; gt; source==NULL) f- &amp; gt; source=p;
f- &amp; gt; linedefined=LoadInt(S);
f- &amp; gt; lastlinedefined=LoadInt(S);
f- &amp; gt; nups=LoadByte(S);
f- &amp; gt; numparams=LoadByte(S);
f- &amp; gt; is_vararg=LoadByte(S);
f- &amp; gt; maxstacksize=LoadByte(S);
LoadCode(S,f);
LoadConstants(S,f);
LoadDebug(S,f);
IF (!luaG_checkcode(f), &quot; bad code &quot; );
S- &amp; gt; L- &amp; gt; top--;
S- &amp; gt; L- &amp; gt; nCcalls--;
return f;
}

static void LoadHeader(LoadState* S)
{
char h[LUAC_HEADERSIZE];
char s[LUAC_HEADERSIZE];
luaU_header(h);
LoadBlock(S,s,LUAC_HEADERSIZE);
IF (memcmp(h,s,LUAC_HEADERSIZE)!=0, &quot; bad header &quot; );
}

/*
** load precompiled chunk
*/
Proto* luaU_undump (lua_State* L, ZIO* Z, Mbuffer* buff, const char* name)
{
LoadState S;
if (*name=='@' || *name=='=')
S.name=name+1;
else if (*name==LUA_SIGNATURE[0])
S.name= &quot; binary string &quot; ;
else
S.name=name;
S.L=L;
S.Z=Z;
S.b=buff;
LoadHeader( &amp; S);
return LoadFunction( &amp; S,luaS_newliteral(L, &quot; =? &quot; ));
}

/*
* make header
*/
void luaU_header (char* h)
{
int x=1;
memcpy(h,LUA_SIGNATURE,sizeof(LUA_SIGNATURE)-1);
h+=sizeof(LUA_SIGNATURE)-1;
*h++=(char)LUAC_VERSION;
*h++=(char)LUAC_FORMAT;
*h++=(char)*(char*) &amp; x; /* endianness */
*h++=(char)sizeof(int);
*h++=(char)sizeof(size_t);
*h++=(char)sizeof(Instruction);
*h++=(char)sizeof(lua_Number);
*h++=(char)(((lua_Number)0.5)==0); /* is lua_Number integral? */
}


scite228.zip > lopcodes.h

/*
** $Id$
** Opcodes for Lua virtual machine
** See Copyright Notice in lua.h
*/

#ifndef lopcodes_h
#define lopcodes_h

#include &quot; llimits.h &quot;


/*===========================================================================
We assume that instructions are unsigned numbers.
All instructions have an opcode in the first 6 bits.
Instructions can have the following fields:
`A' : 8 bits
`B' : 9 bits
`C' : 9 bits
`Bx' : 18 bits (`B' and `C' together)
`sBx' : signed Bx

A signed argument is represented in excess K; that is, the number
value is the unsigned value minus K. K is exactly the maximum value
for that argument (so that -max is represented by 0, and +max is
represented by 2*max), which is half the maximum for the corresponding
unsigned argument.
===========================================================================*/


enum OpMode {iABC, iABx, iAsBx}; /* basic instruction format */


/*
** size and position of opcode arguments.
*/
#define SIZE_C 9
#define SIZE_B 9
#define SIZE_Bx (SIZE_C + SIZE_B)
#define SIZE_A 8

#define SIZE_OP 6

#define POS_OP 0
#define POS_A (POS_OP + SIZE_OP)
#define POS_C (POS_A + SIZE_A)
#define POS_B (POS_C + SIZE_C)
#define POS_Bx POS_C


/*
** limits for opcode arguments.
** we use (signed) int to manipulate most arguments,
** so they must fit in LUAI_BITSINT-1 bits (-1 for sign)
*/
#if SIZE_Bx &amp; lt; LUAI_BITSINT-1
#define MAXARG_Bx ((1 &amp; lt; &amp; lt; SIZE_Bx)-1)
#define MAXARG_sBx (MAXARG_Bx &amp; gt; &amp; gt; 1) /* `sBx' is signed */
#else
#define MAXARG_Bx MAX_INT
#define MAXARG_sBx MAX_INT
#endif


#define MAXARG_A ((1 &amp; lt; &amp; lt; SIZE_A)-1)
#define MAXARG_B ((1 &amp; lt; &amp; lt; SIZE_B)-1)
#define MAXARG_C ((1 &amp; lt; &amp; lt; SIZE_C)-1)


/* creates a mask with `n' 1 bits at position `p' */
#define MASK1(n,p) ((~((~(Instruction)0) &amp; lt; &amp; lt; n)) &amp; lt; &amp; lt; p)

/* creates a mask with `n' 0 bits at position `p' */
#define MASK0(n,p) (~MASK1(n,p))

/*
** the following macros help to manipulate instructions
*/

#define GET_OPCODE(i) (cast(OpCode, ((i) &amp; gt; &amp; gt; POS_OP) &amp; MASK1(SIZE_OP,0)))
#define SET_OPCODE(i,o) ((i) = (((i) &amp; MASK0(SIZE_OP,POS_OP)) | \
((cast(Instruction, o) &amp; lt; &amp; lt; POS_OP) &amp; MASK1(SIZE_OP,POS_OP))))

#define GETARG_A(i) (cast(int, ((i) &amp; gt; &amp; gt; POS_A) &amp; MASK1(SIZE_A,0)))
#define SETARG_A(i,u) ((i) = (((i) &amp; MASK0(SIZE_A,POS_A)) | \
((cast(Instruction, u) &amp; lt; &amp; lt; POS_A) &amp; MASK1(SIZE_A,POS_A))))

#define GETARG_B(i) (cast(int, ((i) &amp; gt; &amp; gt; POS_B) &amp; MASK1(SIZE_B,0)))
#define SETARG_B(i,b) ((i) = (((i) &amp; MASK0(SIZE_B,POS_B)) | \
((cast(Instruction, b) &amp; lt; &amp; lt; POS_B) &amp; MASK1(SIZE_B,POS_B))))

#define GETARG_C(i) (cast(int, ((i) &amp; gt; &amp; gt; POS_C) &amp; MASK1(SIZE_C,0)))
#define SETARG_C(i,b) ((i) = (((i) &amp; MASK0(SIZE_C,POS_C)) | \
((cast(Instruction, b) &amp; lt; &amp; lt; POS_C) &amp; MASK1(SIZE_C,POS_C))))

#define GETARG_Bx(i) (cast(int, ((i) &amp; gt; &amp; gt; POS_Bx) &amp; MASK1(SIZE_Bx,0)))
#define SETARG_Bx(i,b) ((i) = (((i) &amp; MASK0(SIZE_Bx,POS_Bx)) | \
((cast(Instruction, b) &amp; lt; &amp; lt; POS_Bx) &amp; MASK1(SIZE_Bx,POS_Bx))))

#define GETARG_sBx(i) (GETARG_Bx(i)-MAXARG_sBx)
#define SETARG_sBx(i,b) SETARG_Bx((i),cast(unsigned int, (b)+MAXARG_sBx))


#define CREATE_ABC(o,a,b,c) ((cast(Instruction, o) &amp; lt; &amp; lt; POS_OP) \
| (cast(Instruction, a) &amp; lt; &amp; lt; POS_A) \
| (cast(Instruction, b) &amp; lt; &amp; lt; POS_B) \
| (cast(Instruction, c) &amp; lt; &amp; lt; POS_C))

#define CREATE_ABx(o,a,bc) ((cast(Instruction, o) &amp; lt; &amp; lt; POS_OP) \
| (cast(Instruction, a) &amp; lt; &amp; lt; POS_A) \
| (cast(Instruction, bc) &amp; lt; &amp; lt; POS_Bx))


/*
** Macros to operate RK indices
*/

/* this bit 1 means constant (0 means register) */
#define BITRK (1 &amp; lt; &amp; lt; (SIZE_B - 1))

/* test whether value is a constant */
#define ISK(x) ((x) &amp; BITRK)

/* gets the index of the constant */
#define INDEXK(r) ((int)(r) &amp; ~BITRK)

#define MAXINDEXRK (BITRK - 1)

/* code a constant index as a RK value */
#define RKASK(x) ((x) | BITRK)


/*
** invalid register that fits in 8 bits
*/
#define NO_REG MAXARG_A


/*
** R(x) - register
** Kst(x) - constant (in constant table)
** RK(x) == if ISK(x) then Kst(INDEXK(x)) else R(x)
*/


/*
** grep &quot; ORDER OP &quot; if you change these enums
*/

typedef enum {
/*----------------------------------------------------------------------
name args description
------------------------------------------------------------------------*/
OP_MOVE,/* A B R(A) := R(B) */
OP_LOADK,/* A Bx R(A) := Kst(Bx) */
OP_LOADBOOL,/* A B C R(A) := (Bool)B; if (C) pc++ */
OP_LOADNIL,/* A B R(A) := ... := R(B) := nil */
OP_GETUPVAL,/* A B R(A) := UpValue[B] */

OP_GETGLOBAL,/* A Bx R(A) := Gbl[Kst(Bx)] */
OP_GETTABLE,/* A B C R(A) := R(B)[RK(C)] */

OP_SETGLOBAL,/* A Bx Gbl[Kst(Bx)] := R(A) */
OP_SETUPVAL,/* A B UpValue[B] := R(A) */
OP_SETTABLE,/* A B C R(A)[RK(B)] := RK(C) */

OP_NEWTABLE,/* A B C R(A) := {} (size = B,C) */

OP_SELF,/* A B C R(A+1) := R(B); R(A) := R(B)[RK(C)] */

OP_ADD,/* A B C R(A) := RK(B) + RK(C) */
OP_SUB,/* A B C R(A) := RK(B) - RK(C) */
OP_MUL,/* A B C R(A) := RK(B) * RK(C) */
OP_DIV,/* A B C R(A) := RK(B) / RK(C) */
OP_MOD,/* A B C R(A) := RK(B) % RK(C) */
OP_POW,/* A B C R(A) := RK(B) ^ RK(C) */
OP_UNM,/* A B R(A) := -R(B) */
OP_NOT,/* A B R(A) := not R(B) */
OP_LEN,/* A B R(A) := length of R(B) */

OP_CONCAT,/* A B C R(A) := R(B).. ... ..R(C) */

OP_JMP,/* sBx pc+=sBx */

OP_EQ,/* A B C if ((RK(B) == RK(C)) ~= A) then pc++ */
OP_LT,/* A B C if ((RK(B) &amp; lt; RK(C)) ~= A) then pc++ */
OP_LE,/* A B C if ((RK(B) &amp; lt; = RK(C)) ~= A) then pc++ */

OP_TEST,/* A C if not (R(A) &amp; lt; = &amp; gt; C) then pc++ */
OP_TESTSET,/* A B C if (R(B) &amp; lt; = &amp; gt; C) then R(A) := R(B) else pc++ */

OP_CALL,/* A B C R(A), ... ,R(A+C-2) := R(A)(R(A+1), ... ,R(A+B-1)) */
OP_TAILCALL,/* A B C return R(A)(R(A+1), ... ,R(A+B-1)) */
OP_RETURN,/* A B return R(A), ... ,R(A+B-2) (see note) */

OP_FORLOOP,/* A sBx R(A)+=R(A+2);
if R(A) &amp; lt; ?= R(A+1) then { pc+=sBx; R(A+3)=R(A) }*/
OP_FORPREP,/* A sBx R(A)-=R(A+2); pc+=sBx */

OP_TFORLOOP,/* A C R(A+3), ... ,R(A+2+C) := R(A)(R(A+1), R(A+2));
if R(A+3) ~= nil then R(A+2)=R(A+3) else pc++ */
OP_SETLIST,/* A B C R(A)[(C-1)*FPF+i] := R(A+i), 1 &amp; lt; = i &amp; lt; = B */

OP_CLOSE,/* A close all variables in the stack up to ( &amp; gt; =) R(A)*/
OP_CLOSURE,/* A Bx R(A) := closure(KPROTO[Bx], R(A), ... ,R(A+n)) */

OP_VARARG/* A B R(A), R(A+1), ..., R(A+B-1) = vararg */
} OpCode;


#define NUM_OPCODES (cast(int, OP_VARARG) + 1)



/*===========================================================================
Notes:
(*) In OP_CALL, if (B == 0) then B = top. C is the number of returns - 1,
and can be 0: OP_CALL then sets `top' to last_result+1, so
next open instruction (OP_CALL, OP_RETURN, OP_SETLIST) may use `top'.

(*) In OP_VARARG, if (B == 0) then use actual number of varargs and
set top (like in OP_CALL with C == 0).

(*) In OP_RETURN, if (B == 0) then return up to `top'

(*) In OP_SETLIST, if (B == 0) then B = `top';
if (C == 0) then next `instruction' is real C

(*) For comparisons, A specifies what condition the test should accept
(true or false).

(*) All `skips' (pc++) assume that next instruction is a jump
===========================================================================*/


/*
** masks for instruction properties. The format is:
** bits 0-1: op mode
** bits 2-3: C arg mode
** bits 4-5: B arg mode
** bit 6: instruction set register A
** bit 7: operator is a test
*/

enum OpArgMask {
OpArgN, /* argument is not used */
OpArgU, /* argument is used */
OpArgR, /* argument is a register or a jump offset */
OpArgK /* argument is a constant or register/constant */
};

LUAI_DATA const lu_byte luaP_opmodes[NUM_OPCODES];

#define getOpMode(m) (cast(enum OpMode, luaP_opmodes[m] &amp; 3))
#define getBMode(m) (cast(enum OpArgMask, (luaP_opmodes[m] &amp; gt; &amp; gt; 4) &amp; 3))
#define getCMode(m) (cast(enum OpArgMask, (luaP_opmodes[m] &amp; gt; &amp; gt; 2) &amp; 3))
#define testAMode(m) (luaP_opmodes[m] &amp; (1 &amp; lt; &amp; lt; 6))
#define testTMode(m) (luaP_opmodes[m] &amp; (1 &amp; lt; &amp; lt; 7))


LUAI_DATA const char *const luaP_opnames[NUM_OPCODES+1]; /* opcode names */


/* number of list items to accumulate before a SETLIST instruction */
#define LFIELDS_PER_FLUSH 50


#endif


scite228.zip > llimits.h

/*
** $Id$
** Limits, basic types, and some other `installation-dependent' definitions
** See Copyright Notice in lua.h
*/

#ifndef llimits_h
#define llimits_h


#include &amp; lt; limits.h &amp; gt;
#include &amp; lt; stddef.h &amp; gt;


#include &quot; lua.h &quot;


typedef LUAI_UINT32 lu_int32;

typedef LUAI_UMEM lu_mem;

typedef LUAI_MEM l_mem;



/* chars used as small naturals (so that `char' is reserved for characters) */
typedef unsigned char lu_byte;


#define MAX_SIZET ((size_t)(~(size_t)0)-2)

#define MAX_LUMEM ((lu_mem)(~(lu_mem)0)-2)


#define MAX_INT (INT_MAX-2) /* maximum value of an int (-2 for safety) */

/*
** conversion of pointer to integer
** this is for hashing only; there is no problem if the integer
** cannot hold the whole pointer value
*/
#define IntPoint(p) ((unsigned int)(lu_mem)(p))



/* type to ensure maximum alignment */
typedef LUAI_USER_ALIGNMENT_T L_Umaxalign;


/* result of a `usual argument conversion' over lua_Number */
typedef LUAI_UACNUMBER l_uacNumber;


/* internal assertions for in-house debugging */
#ifdef lua_assert

#define check_exp(c,e) (lua_assert(c), (e))
#define api_check(l,e) lua_assert(e)

#else

#define lua_assert(c) ((void)0)
#define check_exp(c,e) (e)
#define api_check luai_apicheck

#endif


#ifndef UNUSED
#define UNUSED(x) ((void)(x)) /* to avoid warnings */
#endif


#ifndef cast
#define cast(t, exp) ((t)(exp))
#endif

#define cast_byte(i) cast(lu_byte, (i))
#define cast_num(i) cast(lua_Number, (i))
#define cast_int(i) cast(int, (i))



/*
** type for virtual-machine instructions
** must be an unsigned with (at least) 4 bytes (see details in lopcodes.h)
*/
typedef lu_int32 Instruction;



/* maximum stack for a Lua function */
#define MAXSTACK 250



/* minimum size for the string table (must be power of 2) */
#ifndef MINSTRTABSIZE
#define MINSTRTABSIZE 32
#endif


/* minimum size for string buffer */
#ifndef LUA_MINBUFFER
#define LUA_MINBUFFER 32
#endif


#ifndef lua_lock
#define lua_lock(L) ((void) 0)
#define lua_unlock(L) ((void) 0)
#endif

#ifndef luai_threadyield
#define luai_threadyield(L) {lua_unlock(L); lua_lock(L);}
#endif


/*
** macro to control inclusion of some hard tests on stack reallocation
*/
#ifndef HARDSTACKTESTS
#define condhardstacktests(x) ((void)0)
#else
#define condhardstacktests(x) x
#endif

#endif


scite228.zip > lvm.c

/*
** $Id$
** Lua virtual machine
** See Copyright Notice in lua.h
*/


#include &amp; lt; stdio.h &amp; gt;
#include &amp; lt; stdlib.h &amp; gt;
#include &amp; lt; string.h &amp; gt;

#define lvm_c
#define LUA_CORE

#include &quot; lua.h &quot;

#include &quot; ldebug.h &quot;
#include &quot; ldo.h &quot;
#include &quot; lfunc.h &quot;
#include &quot; lgc.h &quot;
#include &quot; lobject.h &quot;
#include &quot; lopcodes.h &quot;
#include &quot; lstate.h &quot;
#include &quot; lstring.h &quot;
#include &quot; ltable.h &quot;
#include &quot; ltm.h &quot;
#include &quot; lvm.h &quot;



/* limit for table tag-method chains (to avoid loops) */
#define MAXTAGLOOP 100


const TValue *luaV_tonumber (const TValue *obj, TValue *n) {
lua_Number num;
if (ttisnumber(obj)) return obj;
if (ttisstring(obj) &amp; &amp; luaO_str2d(svalue(obj), &amp; num)) {
setnvalue(n, num);
return n;
}
else
return NULL;
}


int luaV_tostring (lua_State *L, StkId obj) {
if (!ttisnumber(obj))
return 0;
else {
char s[LUAI_MAXNUMBER2STR];
lua_Number n = nvalue(obj);
lua_number2str(s, n);
setsvalue2s(L, obj, luaS_new(L, s));
return 1;
}
}


static void traceexec (lua_State *L, const Instruction *pc) {
lu_byte mask = L- &amp; gt; hookmask;
const Instruction *oldpc = L- &amp; gt; savedpc;
L- &amp; gt; savedpc = pc;
if ((mask &amp; LUA_MASKCOUNT) &amp; &amp; L- &amp; gt; hookcount == 0) {
resethookcount(L);
luaD_callhook(L, LUA_HOOKCOUNT, -1);
}
if (mask &amp; LUA_MASKLINE) {
Proto *p = ci_func(L- &amp; gt; ci)- &amp; gt; l.p;
int npc = pcRel(pc, p);
int newline = getline(p, npc);
/* call linehook when enter a new function, when jump back (loop),
or when enter a new line */
if (npc == 0 || pc &amp; lt; = oldpc || newline != getline(p, pcRel(oldpc, p)))
luaD_callhook(L, LUA_HOOKLINE, newline);
}
}


static void callTMres (lua_State *L, StkId res, const TValue *f,
const TValue *p1, const TValue *p2) {
ptrdiff_t result = savestack(L, res);
setobj2s(L, L- &amp; gt; top, f); /* push function */
setobj2s(L, L- &amp; gt; top+1, p1); /* 1st argument */
setobj2s(L, L- &amp; gt; top+2, p2); /* 2nd argument */
luaD_checkstack(L, 3);
L- &amp; gt; top += 3;
luaD_call(L, L- &amp; gt; top - 3, 1);
res = restorestack(L, result);
L- &amp; gt; top--;
setobjs2s(L, res, L- &amp; gt; top);
}



static void callTM (lua_State *L, const TValue *f, const TValue *p1,
const TValue *p2, const TValue *p3) {
setobj2s(L, L- &amp; gt; top, f); /* push function */
setobj2s(L, L- &amp; gt; top+1, p1); /* 1st argument */
setobj2s(L, L- &amp; gt; top+2, p2); /* 2nd argument */
setobj2s(L, L- &amp; gt; top+3, p3); /* 3th argument */
luaD_checkstack(L, 4);
L- &amp; gt; top += 4;
luaD_call(L, L- &amp; gt; top - 4, 0);
}


void luaV_gettable (lua_State *L, const TValue *t, TValue *key, StkId val) {
int loop;
for (loop = 0; loop &amp; lt; MAXTAGLOOP; loop++) {
const TValue *tm;
if (ttistable(t)) { /* `t' is a table? */
Table *h = hvalue(t);
const TValue *res = luaH_get(h, key); /* do a primitive get */
if (!ttisnil(res) || /* result is no nil? */
(tm = fasttm(L, h- &amp; gt; metatable, TM_INDEX)) == NULL) { /* or no TM? */
setobj2s(L, val, res);
return;
}
/* else will try the tag method */
}
else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_INDEX)))
luaG_typeerror(L, t, &quot; index &quot; );
if (ttisfunction(tm)) {
callTMres(L, val, tm, t, key);
return;
}
t = tm; /* else repeat with `tm' */
}
luaG_runerror(L, &quot; loop in gettable &quot; );
}


void luaV_settable (lua_State *L, const TValue *t, TValue *key, StkId val) {
int loop;
for (loop = 0; loop &amp; lt; MAXTAGLOOP; loop++) {
const TValue *tm;
if (ttistable(t)) { /* `t' is a table? */
Table *h = hvalue(t);
TValue *oldval = luaH_set(L, h, key); /* do a primitive set */
if (!ttisnil(oldval) || /* result is no nil? */
(tm = fasttm(L, h- &amp; gt; metatable, TM_NEWINDEX)) == NULL) { /* or no TM? */
setobj2t(L, oldval, val);
luaC_barriert(L, h, val);
return;
}
/* else will try the tag method */
}
else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_NEWINDEX)))
luaG_typeerror(L, t, &quot; index &quot; );
if (ttisfunction(tm)) {
callTM(L, tm, t, key, val);
return;
}
t = tm; /* else repeat with `tm' */
}
luaG_runerror(L, &quot; loop in settable &quot; );
}


static int call_binTM (lua_State *L, const TValue *p1, const TValue *p2,
StkId res, TMS event) {
const TValue *tm = luaT_gettmbyobj(L, p1, event); /* try first operand */
if (ttisnil(tm))
tm = luaT_gettmbyobj(L, p2, event); /* try second operand */
if (ttisnil(tm)) return 0;
callTMres(L, res, tm, p1, p2);
return 1;
}


static const TValue *get_compTM (lua_State *L, Table *mt1, Table *mt2,
TMS event) {
const TValue *tm1 = fasttm(L, mt1, event);
const TValue *tm2;
if (tm1 == NULL) return NULL; /* no metamethod */
if (mt1 == mt2) return tm1; /* same metatables = &amp; gt; same metamethods */
tm2 = fasttm(L, mt2, event);
if (tm2 == NULL) return NULL; /* no metamethod */
if (luaO_rawequalObj(tm1, tm2)) /* same metamethods? */
return tm1;
return NULL;
}


static int call_orderTM (lua_State *L, const TValue *p1, const TValue *p2,
TMS event) {
const TValue *tm1 = luaT_gettmbyobj(L, p1, event);
const TValue *tm2;
if (ttisnil(tm1)) return -1; /* no metamethod? */
tm2 = luaT_gettmbyobj(L, p2, event);
if (!luaO_rawequalObj(tm1, tm2)) /* different metamethods? */
return -1;
callTMres(L, L- &amp; gt; top, tm1, p1, p2);
return !l_isfalse(L- &amp; gt; top);
}


static int l_strcmp (const TString *ls, const TString *rs) {
const char *l = getstr(ls);
size_t ll = ls- &amp; gt; tsv.len;
const char *r = getstr(rs);
size_t lr = rs- &amp; gt; tsv.len;
for (;;) {
int temp = strcoll(l, r);
if (temp != 0) return temp;
else { /* strings are equal up to a `\0' */
size_t len = strlen(l); /* index of first `\0' in both strings */
if (len == lr) /* r is finished? */
return (len == ll) ? 0 : 1;
else if (len == ll) /* l is finished? */
return -1; /* l is smaller than r (because r is not finished) */
/* both strings longer than `len'; go on comparing (after the `\0') */
len++;
l += len; ll -= len; r += len; lr -= len;
}
}
}


int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r) {
int res;
if (ttype(l) != ttype(r))
return luaG_ordererror(L, l, r);
else if (ttisnumber(l))
return luai_numlt(nvalue(l), nvalue(r));
else if (ttisstring(l))
return l_strcmp(rawtsvalue(l), rawtsvalue(r)) &amp; lt; 0;
else if ((res = call_orderTM(L, l, r, TM_LT)) != -1)
return res;
return luaG_ordererror(L, l, r);
}


static int lessequal (lua_State *L, const TValue *l, const TValue *r) {
int res;
if (ttype(l) != ttype(r))
return luaG_ordererror(L, l, r);
else if (ttisnumber(l))
return luai_numle(nvalue(l), nvalue(r));
else if (ttisstring(l))
return l_strcmp(rawtsvalue(l), rawtsvalue(r)) &amp; lt; = 0;
else if ((res = call_orderTM(L, l, r, TM_LE)) != -1) /* first try `le' */
return res;
else if ((res = call_orderTM(L, r, l, TM_LT)) != -1) /* else try `lt' */
return !res;
return luaG_ordererror(L, l, r);
}


int luaV_equalval (lua_State *L, const TValue *t1, const TValue *t2) {
const TValue *tm;
lua_assert(ttype(t1) == ttype(t2));
switch (ttype(t1)) {
case LUA_TNIL: return 1;
case LUA_TNUMBER: return luai_numeq(nvalue(t1), nvalue(t2));
case LUA_TBOOLEAN: return bvalue(t1) == bvalue(t2); /* true must be 1 !! */
case LUA_TLIGHTUSERDATA: return pvalue(t1) == pvalue(t2);
case LUA_TUSERDATA: {
if (uvalue(t1) == uvalue(t2)) return 1;
tm = get_compTM(L, uvalue(t1)- &amp; gt; metatable, uvalue(t2)- &amp; gt; metatable,
TM_EQ);
break; /* will try TM */
}
case LUA_TTABLE: {
if (hvalue(t1) == hvalue(t2)) return 1;
tm = get_compTM(L, hvalue(t1)- &amp; gt; metatable, hvalue(t2)- &amp; gt; metatable, TM_EQ);
break; /* will try TM */
}
default: return gcvalue(t1) == gcvalue(t2);
}
if (tm == NULL) return 0; /* no TM? */
callTMres(L, L- &amp; gt; top, tm, t1, t2); /* call TM */
return !l_isfalse(L- &amp; gt; top);
}


void luaV_concat (lua_State *L, int total, int last) {
do {
StkId top = L- &amp; gt; base + last + 1;
int n = 2; /* number of elements handled in this pass (at least 2) */
if (!(ttisstring(top-2) || ttisnumber(top-2)) || !tostring(L, top-1)) {
if (!call_binTM(L, top-2, top-1, top-2, TM_CONCAT))
luaG_concaterror(L, top-2, top-1);
} else if (tsvalue(top-1)- &amp; gt; len == 0) /* second op is empty? */
(void)tostring(L, top - 2); /* result is first op (as string) */
else {
/* at least two string values; get as many as possible */
size_t tl = tsvalue(top-1)- &amp; gt; len;
char *buffer;
int i;
/* collect total length */
for (n = 1; n &amp; lt; total &amp; &amp; tostring(L, top-n-1); n++) {
size_t l = tsvalue(top-n-1)- &amp; gt; len;
if (l &amp; gt; = MAX_SIZET - tl) luaG_runerror(L, &quot; string length overflow &quot; );
tl += l;
}
buffer = luaZ_openspace(L, &amp; G(L)- &amp; gt; buff, tl);
tl = 0;
for (i=n; i &amp; gt; 0; i--) { /* concat all strings */
size_t l = tsvalue(top-i)- &amp; gt; len;
memcpy(buffer+tl, svalue(top-i), l);
tl += l;
}
setsvalue2s(L, top-n, luaS_newlstr(L, buffer, tl));
}
total -= n-1; /* got `n' strings to create 1 new */
last -= n-1;
} while (total &amp; gt; 1); /* repeat until only 1 result left */
}


static void Arith (lua_State *L, StkId ra, const TValue *rb,
const TValue *rc, TMS op) {
TValue tempb, tempc;
const TValue *b, *c;
if ((b = luaV_tonumber(rb, &amp; tempb)) != NULL &amp; &amp;
(c = luaV_tonumber(rc, &amp; tempc)) != NULL) {
lua_Number nb = nvalue(b), nc = nvalue(c);
switch (op) {
case TM_ADD: setnvalue(ra, luai_numadd(nb, nc)); break;
case TM_SUB: setnvalue(ra, luai_numsub(nb, nc)); break;
case TM_MUL: setnvalue(ra, luai_nummul(nb, nc)); break;
case TM_DIV: setnvalue(ra, luai_numdiv(nb, nc)); break;
case TM_MOD: setnvalue(ra, luai_nummod(nb, nc)); break;
case TM_POW: setnvalue(ra, luai_numpow(nb, nc)); break;
case TM_UNM: setnvalue(ra, luai_numunm(nb)); break;
default: lua_assert(0); break;
}
}
else if (!call_binTM(L, rb, rc, ra, op))
luaG_aritherror(L, rb, rc);
}



/*
** some macros for common tasks in `luaV_execute'
*/

#define runtime_check(L, c) { if (!(c)) break; }

#define RA(i) (base+GETARG_A(i))
/* to be used after possible stack reallocation */
#define RB(i) check_exp(getBMode(GET_OPCODE(i)) == OpArgR, base+GETARG_B(i))
#define RC(i) check_exp(getCMode(GET_OPCODE(i)) == OpArgR, base+GETARG_C(i))
#define RKB(i) check_exp(getBMode(GET_OPCODE(i)) == OpArgK, \
ISK(GETARG_B(i)) ? k+INDEXK(GETARG_B(i)) : base+GETARG_B(i))
#define RKC(i) check_exp(getCMode(GET_OPCODE(i)) == OpArgK, \
ISK(GETARG_C(i)) ? k+INDEXK(GETARG_C(i)) : base+GETARG_C(i))
#define KBx(i) check_exp(getBMode(GET_OPCODE(i)) == OpArgK, k+GETARG_Bx(i))


#define dojump(L,pc,i) {(pc) += (i); luai_threadyield(L);}


#define Protect(x) { L- &amp; gt; savedpc = pc; {x;}; base = L- &amp; gt; base; }


#define arith_op(op,tm) { \
TValue *rb = RKB(i); \
TValue *rc = RKC(i); \
if (ttisnumber(rb) &amp; &amp; ttisnumber(rc)) { \
lua_Number nb = nvalue(rb), nc = nvalue(rc); \
setnvalue(ra, op(nb, nc)); \
} \
else \
Protect(Arith(L, ra, rb, rc, tm)); \
}



void luaV_execute (lua_State *L, int nexeccalls) {
LClosure *cl;
StkId base;
TValue *k;
const Instruction *pc;
reentry: /* entry point */
lua_assert(isLua(L- &amp; gt; ci));
pc = L- &amp; gt; savedpc;
cl = &amp; clvalue(L- &amp; gt; ci- &amp; gt; func)- &amp; gt; l;
base = L- &amp; gt; base;
k = cl- &amp; gt; p- &amp; gt; k;
/* main loop of interpreter */
for (;;) {
const Instruction i = *pc++;
StkId ra;
if ((L- &amp; gt; hookmask &amp; (LUA_MASKLINE | LUA_MASKCOUNT)) &amp; &amp;
(--L- &amp; gt; hookcount == 0 || L- &amp; gt; hookmask &amp; LUA_MASKLINE)) {
traceexec(L, pc);
if (L- &amp; gt; status == LUA_YIELD) { /* did hook yield? */
L- &amp; gt; savedpc = pc - 1;
return;
}
base = L- &amp; gt; base;
}
/* warning!! several calls may realloc the stack and invalidate `ra' */
ra = RA(i);
lua_assert(base == L- &amp; gt; base &amp; &amp; L- &amp; gt; base == L- &amp; gt; ci- &amp; gt; base);
lua_assert(base &amp; lt; = L- &amp; gt; top &amp; &amp; L- &amp; gt; top &amp; lt; = L- &amp; gt; stack + L- &amp; gt; stacksize);
lua_assert(L- &amp; gt; top == L- &amp; gt; ci- &amp; gt; top || luaG_checkopenop(i));
switch (GET_OPCODE(i)) {
case OP_MOVE: {
setobjs2s(L, ra, RB(i));
continue;
}
case OP_LOADK: {
setobj2s(L, ra, KBx(i));
continue;
}
case OP_LOADBOOL: {
setbvalue(ra, GETARG_B(i));
if (GETARG_C(i)) pc++; /* skip next instruction (if C) */
continue;
}
case OP_LOADNIL: {
TValue *rb = RB(i);
do {
setnilvalue(rb--);
} while (rb &amp; gt; = ra);
continue;
}
case OP_GETUPVAL: {
int b = GETARG_B(i);
setobj2s(L, ra, cl- &amp; gt; upvals[b]- &amp; gt; v);
continue;
}
case OP_GETGLOBAL: {
TValue g;
TValue *rb = KBx(i);
sethvalue(L, &amp; g, cl- &amp; gt; env);
lua_assert(ttisstring(rb));
Protect(luaV_gettable(L, &amp; g, rb, ra));
continue;
}
case OP_GETTABLE: {
Protect(luaV_gettable(L, RB(i), RKC(i), ra));
continue;
}
case OP_SETGLOBAL: {
TValue g;
sethvalue(L, &amp; g, cl- &amp; gt; env);
lua_assert(ttisstring(KBx(i)));
Protect(luaV_settable(L, &amp; g, KBx(i), ra));
continue;
}
case OP_SETUPVAL: {
UpVal *uv = cl- &amp; gt; upvals[GETARG_B(i)];
setobj(L, uv- &amp; gt; v, ra);
luaC_barrier(L, uv, ra);
continue;
}
case OP_SETTABLE: {
Protect(luaV_settable(L, ra, RKB(i), RKC(i)));
continue;
}
case OP_NEWTABLE: {
int b = GETARG_B(i);
int c = GETARG_C(i);
sethvalue(L, ra, luaH_new(L, luaO_fb2int(b), luaO_fb2int(c)));
Protect(luaC_checkGC(L));
continue;
}
case OP_SELF: {
StkId rb = RB(i);
setobjs2s(L, ra+1, rb);
Protect(luaV_gettable(L, rb, RKC(i), ra));
continue;
}
case OP_ADD: {
arith_op(luai_numadd, TM_ADD);
continue;
}
case OP_SUB: {
arith_op(luai_numsub, TM_SUB);
continue;
}
case OP_MUL: {
arith_op(luai_nummul, TM_MUL);
continue;
}
case OP_DIV: {
arith_op(luai_numdiv, TM_DIV);
continue;
}
case OP_MOD: {
arith_op(luai_nummod, TM_MOD);
continue;
}
case OP_POW: {
arith_op(luai_numpow, TM_POW);
continue;
}
case OP_UNM: {
TValue *rb = RB(i);
if (ttisnumber(rb)) {
lua_Number nb = nvalue(rb);
setnvalue(ra, luai_numunm(nb));
}
else {
Protect(Arith(L, ra, rb, rb, TM_UNM));
}
continue;
}
case OP_NOT: {
int res = l_isfalse(RB(i)); /* next assignment may change this value */
setbvalue(ra, res);
continue;
}
case OP_LEN: {
const TValue *rb = RB(i);
switch (ttype(rb)) {
case LUA_TTABLE: {
setnvalue(ra, cast_num(luaH_getn(hvalue(rb))));
break;
}
case LUA_TSTRING: {
setnvalue(ra, cast_num(tsvalue(rb)- &amp; gt; len));
break;
}
default: { /* try metamethod */
Protect(
if (!call_binTM(L, rb, luaO_nilobject, ra, TM_LEN))
luaG_typeerror(L, rb, &quot; get length of &quot; );
)
}
}
continue;
}
case OP_CONCAT: {
int b = GETARG_B(i);
int c = GETARG_C(i);
Protect(luaV_concat(L, c-b+1, c); luaC_checkGC(L));
setobjs2s(L, RA(i), base+b);
continue;
}
case OP_JMP: {
dojump(L, pc, GETARG_sBx(i));
continue;
}
case OP_EQ: {
TValue *rb = RKB(i);
TValue *rc = RKC(i);
Protect(
if (equalobj(L, rb, rc) == GETARG_A(i))
dojump(L, pc, GETARG_sBx(*pc));
)
pc++;
continue;
}
case OP_LT: {
Protect(
if (luaV_lessthan(L, RKB(i), RKC(i)) == GETARG_A(i))
dojump(L, pc, GETARG_sBx(*pc));
)
pc++;
continue;
}
case OP_LE: {
Protect(
if (lessequal(L, RKB(i), RKC(i)) == GETARG_A(i))
dojump(L, pc, GETARG_sBx(*pc));
)
pc++;
continue;
}
case OP_TEST: {
if (l_isfalse(ra) != GETARG_C(i))
dojump(L, pc, GETARG_sBx(*pc));
pc++;
continue;
}
case OP_TESTSET: {
TValue *rb = RB(i);
if (l_isfalse(rb) != GETARG_C(i)) {
setobjs2s(L, ra, rb);
dojump(L, pc, GETARG_sBx(*pc));
}
pc++;
continue;
}
case OP_CALL: {
int b = GETARG_B(i);
int nresults = GETARG_C(i) - 1;
if (b != 0) L- &amp; gt; top = ra+b; /* else previous instruction set top */
L- &amp; gt; savedpc = pc;
switch (luaD_precall(L, ra, nresults)) {
case PCRLUA: {
nexeccalls++;
goto reentry; /* restart luaV_execute over new Lua function */
}
case PCRC: {
/* it was a C function (`precall' called it); adjust results */
if (nresults &amp; gt; = 0) L- &amp; gt; top = L- &amp; gt; ci- &amp; gt; top;
base = L- &amp; gt; base;
continue;
}
default: {
return; /* yield */
}
}
}
case OP_TAILCALL: {
int b = GETARG_B(i);
if (b != 0) L- &amp; gt; top = ra+b; /* else previous instruction set top */
L- &amp; gt; savedpc = pc;
lua_assert(GETARG_C(i) - 1 == LUA_MULTRET);
switch (luaD_precall(L, ra, LUA_MULTRET)) {
case PCRLUA: {
/* tail call: put new frame in place of previous one */
CallInfo *ci = L- &amp; gt; ci - 1; /* previous frame */
int aux;
StkId func = ci- &amp; gt; func;
StkId pfunc = (ci+1)- &amp; gt; func; /* previous function index */
if (L- &amp; gt; openupval) luaF_close(L, ci- &amp; gt; base);
L- &amp; gt; base = ci- &amp; gt; base = ci- &amp; gt; func + ((ci+1)- &amp; gt; base - pfunc);
for (aux = 0; pfunc+aux &amp; lt; L- &amp; gt; top; aux++) /* move frame down */
setobjs2s(L, func+aux, pfunc+aux);
ci- &amp; gt; top = L- &amp; gt; top = func+aux; /* correct top */
lua_assert(L- &amp; gt; top == L- &amp; gt; base + clvalue(func)- &amp; gt; l.p- &amp; gt; maxstacksize);
ci- &amp; gt; savedpc = L- &amp; gt; savedpc;
ci- &amp; gt; tailcalls++; /* one more call lost */
L- &amp; gt; ci--; /* remove new frame */
goto reentry;
}
case PCRC: { /* it was a C function (`precall' called it) */
base = L- &amp; gt; base;
continue;
}
default: {
return; /* yield */
}
}
}
case OP_RETURN: {
int b = GETARG_B(i);
if (b != 0) L- &amp; gt; top = ra+b-1;
if (L- &amp; gt; openupval) luaF_close(L, base);
L- &amp; gt; savedpc = pc;
b = luaD_poscall(L, ra);
if (--nexeccalls == 0) /* was previous function running `here'? */
return; /* no: return */
else { /* yes: continue its execution */
if (b) L- &amp; gt; top = L- &amp; gt; ci- &amp; gt; top;
lua_assert(isLua(L- &amp; gt; ci));
lua_assert(GET_OPCODE(*((L- &amp; gt; ci)- &amp; gt; savedpc - 1)) == OP_CALL);
goto reentry;
}
}
case OP_FORLOOP: {
lua_Number step = nvalue(ra+2);
lua_Number idx = luai_numadd(nvalue(ra), step); /* increment index */
lua_Number limit = nvalue(ra+1);
if (luai_numlt(0, step) ? luai_numle(idx, limit)
: luai_numle(limit, idx)) {
dojump(L, pc, GETARG_sBx(i)); /* jump back */
setnvalue(ra, idx); /* update internal index... */
setnvalue(ra+3, idx); /* ...and external index */
}
continue;
}
case OP_FORPREP: {
const TValue *init = ra;
const TValue *plimit = ra+1;
const TValue *pstep = ra+2;
L- &amp; gt; savedpc = pc; /* next steps may throw errors */
if (!tonumber(init, ra))
luaG_runerror(L, LUA_QL( &quot; for &quot; ) &quot; initial value must be a number &quot; );
else if (!tonumber(plimit, ra+1))
luaG_runerror(L, LUA_QL( &quot; for &quot; ) &quot; limit must be a number &quot; );
else if (!tonumber(pstep, ra+2))
luaG_runerror(L, LUA_QL( &quot; for &quot; ) &quot; step must be a number &quot; );
setnvalue(ra, luai_numsub(nvalue(ra), nvalue(pstep)));
dojump(L, pc, GETARG_sBx(i));
continue;
}
case OP_TFORLOOP: {
StkId cb = ra + 3; /* call base */
setobjs2s(L, cb+2, ra+2);
setobjs2s(L, cb+1, ra+1);
setobjs2s(L, cb, ra);
L- &amp; gt; top = cb+3; /* func. + 2 args (state and index) */
Protect(luaD_call(L, cb, GETARG_C(i)));
L- &amp; gt; top = L- &amp; gt; ci- &amp; gt; top;
cb = RA(i) + 3; /* previous call may change the stack */
if (!ttisnil(cb)) { /* continue loop? */
setobjs2s(L, cb-1, cb); /* save control variable */
dojump(L, pc, GETARG_sBx(*pc)); /* jump back */
}
pc++;
continue;
}
case OP_SETLIST: {
int n = GETARG_B(i);
int c = GETARG_C(i);
int last;
Table *h;
if (n == 0) {
n = cast_int(L- &amp; gt; top - ra) - 1;
L- &amp; gt; top = L- &amp; gt; ci- &amp; gt; top;
}
if (c == 0) c = cast_int(*pc++);
runtime_check(L, ttistable(ra));
h = hvalue(ra);
last = ((c-1)*LFIELDS_PER_FLUSH) + n;
if (last &amp; gt; h- &amp; gt; sizearray) /* needs more space? */
luaH_resizearray(L, h, last); /* pre-alloc it at once */
for (; n &amp; gt; 0; n--) {
TValue *val = ra+n;
setobj2t(L, luaH_setnum(L, h, last--), val);
luaC_barriert(L, h, val);
}
continue;
}
case OP_CLOSE: {
luaF_close(L, ra);
continue;
}
case OP_CLOSURE: {
Proto *p;
Closure *ncl;
int nup, j;
p = cl- &amp; gt; p- &amp; gt; p[GETARG_Bx(i)];
nup = p- &amp; gt; nups;
ncl = luaF_newLclosure(L, nup, cl- &amp; gt; env);
ncl- &amp; gt; l.p = p;
for (j=0; j &amp; lt; nup; j++, pc++) {
if (GET_OPCODE(*pc) == OP_GETUPVAL)
ncl- &amp; gt; l.upvals[j] = cl- &amp; gt; upvals[GETARG_B(*pc)];
else {
lua_assert(GET_OPCODE(*pc) == OP_MOVE);
ncl- &amp; gt; l.upvals[j] = luaF_findupval(L, base + GETARG_B(*pc));
}
}
setclvalue(L, ra, ncl);
Protect(luaC_checkGC(L));
continue;
}
case OP_VARARG: {
int b = GETARG_B(i) - 1;
int j;
CallInfo *ci = L- &amp; gt; ci;
int n = cast_int(ci- &amp; gt; base - ci- &amp; gt; func) - cl- &amp; gt; p- &amp; gt; numparams - 1;
if (b == LUA_MULTRET) {
Protect(luaD_checkstack(L, n));
ra = RA(i); /* previous call may change the stack */
b = n;
L- &amp; gt; top = ra + n;
}
for (j = 0; j &amp; lt; b; j++) {
if (j &amp; lt; n) {
setobjs2s(L, ra + j, ci- &amp; gt; base - n + j);
}
else {
setnilvalue(ra + j);
}
}
continue;
}
}
}
}


scite228.zip > lopcodes.c

/*
** $Id$
** See Copyright Notice in lua.h
*/


#define lopcodes_c
#define LUA_CORE


#include &quot; lopcodes.h &quot;


/* ORDER OP */

const char *const luaP_opnames[NUM_OPCODES+1] = {
&quot; MOVE &quot; ,
&quot; LOADK &quot; ,
&quot; LOADBOOL &quot; ,
&quot; LOADNIL &quot; ,
&quot; GETUPVAL &quot; ,
&quot; GETGLOBAL &quot; ,
&quot; GETTABLE &quot; ,
&quot; SETGLOBAL &quot; ,
&quot; SETUPVAL &quot; ,
&quot; SETTABLE &quot; ,
&quot; NEWTABLE &quot; ,
&quot; SELF &quot; ,
&quot; ADD &quot; ,
&quot; SUB &quot; ,
&quot; MUL &quot; ,
&quot; DIV &quot; ,
&quot; MOD &quot; ,
&quot; POW &quot; ,
&quot; UNM &quot; ,
&quot; NOT &quot; ,
&quot; LEN &quot; ,
&quot; CONCAT &quot; ,
&quot; JMP &quot; ,
&quot; EQ &quot; ,
&quot; LT &quot; ,
&quot; LE &quot; ,
&quot; TEST &quot; ,
&quot; TESTSET &quot; ,
&quot; CALL &quot; ,
&quot; TAILCALL &quot; ,
&quot; RETURN &quot; ,
&quot; FORLOOP &quot; ,
&quot; FORPREP &quot; ,
&quot; TFORLOOP &quot; ,
&quot; SETLIST &quot; ,
&quot; CLOSE &quot; ,
&quot; CLOSURE &quot; ,
&quot; VARARG &quot; ,
NULL
};


#define opmode(t,a,b,c,m) (((t) &amp; lt; &amp; lt; 7) | ((a) &amp; lt; &amp; lt; 6) | ((b) &amp; lt; &amp; lt; 4) | ((c) &amp; lt; &amp; lt; 2) | (m))

const lu_byte luaP_opmodes[NUM_OPCODES] = {
/* T A B C mode opcode */
opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_MOVE */
,opmode(0, 1, OpArgK, OpArgN, iABx) /* OP_LOADK */
,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_LOADBOOL */
,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_LOADNIL */
,opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_GETUPVAL */
,opmode(0, 1, OpArgK, OpArgN, iABx) /* OP_GETGLOBAL */
,opmode(0, 1, OpArgR, OpArgK, iABC) /* OP_GETTABLE */
,opmode(0, 0, OpArgK, OpArgN, iABx) /* OP_SETGLOBAL */
,opmode(0, 0, OpArgU, OpArgN, iABC) /* OP_SETUPVAL */
,opmode(0, 0, OpArgK, OpArgK, iABC) /* OP_SETTABLE */
,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_NEWTABLE */
,opmode(0, 1, OpArgR, OpArgK, iABC) /* OP_SELF */
,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_ADD */
,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_SUB */
,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_MUL */
,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_DIV */
,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_MOD */
,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_POW */
,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_UNM */
,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_NOT */
,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_LEN */
,opmode(0, 1, OpArgR, OpArgR, iABC) /* OP_CONCAT */
,opmode(0, 0, OpArgR, OpArgN, iAsBx) /* OP_JMP */
,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_EQ */
,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_LT */
,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_LE */
,opmode(1, 1, OpArgR, OpArgU, iABC) /* OP_TEST */
,opmode(1, 1, OpArgR, OpArgU, iABC) /* OP_TESTSET */
,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_CALL */
,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_TAILCALL */
,opmode(0, 0, OpArgU, OpArgN, iABC) /* OP_RETURN */
,opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_FORLOOP */
,opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_FORPREP */
,opmode(1, 0, OpArgN, OpArgU, iABC) /* OP_TFORLOOP */
,opmode(0, 0, OpArgU, OpArgU, iABC) /* OP_SETLIST */
,opmode(0, 0, OpArgN, OpArgN, iABC) /* OP_CLOSE */
,opmode(0, 1, OpArgU, OpArgN, iABx) /* OP_CLOSURE */
,opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_VARARG */
};


scite228.zip > lstring.h

/*
** $Id$
** String table (keep all strings handled by Lua)
** See Copyright Notice in lua.h
*/

#ifndef lstring_h
#define lstring_h


#include &quot; lgc.h &quot;
#include &quot; lobject.h &quot;
#include &quot; lstate.h &quot;


#define sizestring(s) (sizeof(union TString)+((s)- &amp; gt; len+1)*sizeof(char))

#define sizeudata(u) (sizeof(union Udata)+(u)- &amp; gt; len)

#define luaS_new(L, s) (luaS_newlstr(L, s, strlen(s)))
#define luaS_newliteral(L, s) (luaS_newlstr(L, &quot; &quot; s, \
(sizeof(s)/sizeof(char))-1))

#define luaS_fix(s) l_setbit((s)- &amp; gt; tsv.marked, FIXEDBIT)

LUAI_FUNC void luaS_resize (lua_State *L, int newsize);
LUAI_FUNC Udata *luaS_newudata (lua_State *L, size_t s, Table *e);
LUAI_FUNC TString *luaS_newlstr (lua_State *L, const char *str, size_t l);


#endif


scite228.zip > lauxlib.h

/*
** $Id$
** Auxiliary functions for building Lua libraries
** See Copyright Notice in lua.h
*/


#ifndef lauxlib_h
#define lauxlib_h


#include &amp; lt; stddef.h &amp; gt;
#include &amp; lt; stdio.h &amp; gt;

#include &quot; lua.h &quot;


#if defined(LUA_COMPAT_GETN)
LUALIB_API int (luaL_getn) (lua_State *L, int t);
LUALIB_API void (luaL_setn) (lua_State *L, int t, int n);
#else
#define luaL_getn(L,i) ((int)lua_objlen(L, i))
#define luaL_setn(L,i,j) ((void)0) /* no op! */
#endif

#if defined(LUA_COMPAT_OPENLIB)
#define luaI_openlib luaL_openlib
#endif


/* extra error code for `luaL_load' */
#define LUA_ERRFILE (LUA_ERRERR+1)


typedef struct luaL_Reg {
const char *name;
lua_CFunction func;
} luaL_Reg;



LUALIB_API void (luaI_openlib) (lua_State *L, const char *libname,
const luaL_Reg *l, int nup);
LUALIB_API void (luaL_register) (lua_State *L, const char *libname,
const luaL_Reg *l);
LUALIB_API int (luaL_getmetafield) (lua_State *L, int obj, const char *e);
LUALIB_API int (luaL_callmeta) (lua_State *L, int obj, const char *e);
LUALIB_API int (luaL_typerror) (lua_State *L, int narg, const char *tname);
LUALIB_API int (luaL_argerror) (lua_State *L, int numarg, const char *extramsg);
LUALIB_API const char *(luaL_checklstring) (lua_State *L, int numArg,
size_t *l);
LUALIB_API const char *(luaL_optlstring) (lua_State *L, int numArg,
const char *def, size_t *l);
LUALIB_API lua_Number (luaL_checknumber) (lua_State *L, int numArg);
LUALIB_API lua_Number (luaL_optnumber) (lua_State *L, int nArg, lua_Number def);

LUALIB_API lua_Integer (luaL_checkinteger) (lua_State *L, int numArg);
LUALIB_API lua_Integer (luaL_optinteger) (lua_State *L, int nArg,
lua_Integer def);

LUALIB_API void (luaL_checkstack) (lua_State *L, int sz, const char *msg);
LUALIB_API void (luaL_checktype) (lua_State *L, int narg, int t);
LUALIB_API void (luaL_checkany) (lua_State *L, int narg);

LUALIB_API int (luaL_newmetatable) (lua_State *L, const char *tname);
LUALIB_API void *(luaL_checkudata) (lua_State *L, int ud, const char *tname);

LUALIB_API void (luaL_where) (lua_State *L, int lvl);
LUALIB_API int (luaL_error) (lua_State *L, const char *fmt, ...);

LUALIB_API int (luaL_checkoption) (lua_State *L, int narg, const char *def,
const char *const lst[]);

LUALIB_API int (luaL_ref) (lua_State *L, int t);
LUALIB_API void (luaL_unref) (lua_State *L, int t, int ref);

LUALIB_API int (luaL_loadfile) (lua_State *L, const char *filename);
LUALIB_API int (luaL_loadbuffer) (lua_State *L, const char *buff, size_t sz,
const char *name);
LUALIB_API int (luaL_loadstring) (lua_State *L, const char *s);

LUALIB_API lua_State *(luaL_newstate) (void);


LUALIB_API const char *(luaL_gsub) (lua_State *L, const char *s, const char *p,
const char *r);

LUALIB_API const char *(luaL_findtable) (lua_State *L, int idx,
const char *fname, int szhint);




/*
** ===============================================================
** some useful macros
** ===============================================================
*/

#define luaL_argcheck(L, cond,numarg,extramsg) \
((void)((cond) || luaL_argerror(L, (numarg), (extramsg))))
#define luaL_checkstring(L,n) (luaL_checklstring(L, (n), NULL))
#define luaL_optstring(L,n,d) (luaL_optlstring(L, (n), (d), NULL))
#define luaL_checkint(L,n) ((int)luaL_checkinteger(L, (n)))
#define luaL_optint(L,n,d) ((int)luaL_optinteger(L, (n), (d)))
#define luaL_checklong(L,n) ((long)luaL_checkinteger(L, (n)))
#define luaL_optlong(L,n,d) ((long)luaL_optinteger(L, (n), (d)))

#define luaL_typename(L,i) lua_typename(L, lua_type(L,(i)))

#define luaL_dofile(L, fn) \
(luaL_loadfile(L, fn) || lua_pcall(L, 0, LUA_MULTRET, 0))

#define luaL_dostring(L, s) \
(luaL_loadstring(L, s) || lua_pcall(L, 0, LUA_MULTRET, 0))

#define luaL_getmetatable(L,n) (lua_getfield(L, LUA_REGISTRYINDEX, (n)))

#define luaL_opt(L,f,n,d) (lua_isnoneornil(L,(n)) ? (d) : f(L,(n)))

/*
** {======================================================
** Generic Buffer manipulation
** =======================================================
*/



typedef struct luaL_Buffer {
char *p; /* current position in buffer */
int lvl; /* number of strings in the stack (level) */
lua_State *L;
char buffer[LUAL_BUFFERSIZE];
} luaL_Buffer;

#define luaL_addchar(B,c) \
((void)((B)- &amp; gt; p &amp; lt; ((B)- &amp; gt; buffer+LUAL_BUFFERSIZE) || luaL_prepbuffer(B)), \
(*(B)- &amp; gt; p++ = (char)(c)))

/* compatibility only */
#define luaL_putchar(B,c) luaL_addchar(B,c)

#define luaL_addsize(B,n) ((B)- &amp; gt; p += (n))

LUALIB_API void (luaL_buffinit) (lua_State *L, luaL_Buffer *B);
LUALIB_API char *(luaL_prepbuffer) (luaL_Buffer *B);
LUALIB_API void (luaL_addlstring) (luaL_Buffer *B, const char *s, size_t l);
LUALIB_API void (luaL_addstring) (luaL_Buffer *B, const char *s);
LUALIB_API void (luaL_addvalue) (luaL_Buffer *B);
LUALIB_API void (luaL_pushresult) (luaL_Buffer *B);


/* }====================================================== */


/* compatibility with ref system */

/* pre-defined references */
#define LUA_NOREF (-2)
#define LUA_REFNIL (-1)

#define lua_ref(L,lock) ((lock) ? luaL_ref(L, LUA_REGISTRYINDEX) : \
(lua_pushstring(L, &quot; unlocked references are obsolete &quot; ), lua_error(L), 0))

#define lua_unref(L,ref) luaL_unref(L, LUA_REGISTRYINDEX, (ref))

#define lua_getref(L,ref) lua_rawgeti(L, LUA_REGISTRYINDEX, (ref))


#define luaL_reg luaL_Reg

#endif


scite228.zip > lualib.h

/*
** $Id$
** Lua standard libraries
** See Copyright Notice in lua.h
*/


#ifndef lualib_h
#define lualib_h

#include &quot; lua.h &quot;


/* Key to file-handle type */
#define LUA_FILEHANDLE &quot; FILE* &quot;


#define LUA_COLIBNAME &quot; coroutine &quot;
LUALIB_API int (luaopen_base) (lua_State *L);

#define LUA_TABLIBNAME &quot; table &quot;
LUALIB_API int (luaopen_table) (lua_State *L);

#define LUA_IOLIBNAME &quot; io &quot;
LUALIB_API int (luaopen_io) (lua_State *L);

#define LUA_OSLIBNAME &quot; os &quot;
LUALIB_API int (luaopen_os) (lua_State *L);

#define LUA_STRLIBNAME &quot; string &quot;
LUALIB_API int (luaopen_string) (lua_State *L);

#define LUA_MATHLIBNAME &quot; math &quot;
LUALIB_API int (luaopen_math) (lua_State *L);

#define LUA_DBLIBNAME &quot; debug &quot;
LUALIB_API int (luaopen_debug) (lua_State *L);

#define LUA_LOADLIBNAME &quot; package &quot;
LUALIB_API int (luaopen_package) (lua_State *L);


/* open all previous libraries */
LUALIB_API void (luaL_openlibs) (lua_State *L);



#ifndef lua_assert
#define lua_assert(x) ((void)0)
#endif


#endif


scite228.zip > lua.h

/*
** $Id$
** Lua - An Extensible Extension Language
** Lua.org, PUC-Rio, Brazil (http://www.lua.org)
** See Copyright Notice at the end of this file
*/


#ifndef lua_h
#define lua_h

#include &amp; lt; stdarg.h &amp; gt;
#include &amp; lt; stddef.h &amp; gt;


#include &quot; luaconf.h &quot;


#define LUA_VERSION &quot; Lua 5.1 &quot;
#define LUA_RELEASE &quot; Lua 5.1.4 &quot;
#define LUA_VERSION_NUM 501
#define LUA_COPYRIGHT &quot; Copyright (C) 1994-2008 Lua.org, PUC-Rio &quot;
#define LUA_AUTHORS &quot; R. Ierusalimschy, L. H. de Figueiredo &amp; W. Celes &quot;


/* mark for precompiled code (` &amp; lt; esc &amp; gt; Lua') */
#define LUA_SIGNATURE &quot; \033Lua &quot;

/* option for multiple returns in `lua_pcall' and `lua_call' */
#define LUA_MULTRET (-1)


/*
** pseudo-indices
*/
#define LUA_REGISTRYINDEX (-10000)
#define LUA_ENVIRONINDEX (-10001)
#define LUA_GLOBALSINDEX (-10002)
#define lua_upvalueindex(i) (LUA_GLOBALSINDEX-(i))


/* thread status; 0 is OK */
#define LUA_YIELD 1
#define LUA_ERRRUN 2
#define LUA_ERRSYNTAX 3
#define LUA_ERRMEM 4
#define LUA_ERRERR 5


typedef struct lua_State lua_State;

typedef int (*lua_CFunction) (lua_State *L);


/*
** functions that read/write blocks when loading/dumping Lua chunks
*/
typedef const char * (*lua_Reader) (lua_State *L, void *ud, size_t *sz);

typedef int (*lua_Writer) (lua_State *L, const void* p, size_t sz, void* ud);


/*
** prototype for memory-allocation functions
*/
typedef void * (*lua_Alloc) (void *ud, void *ptr, size_t osize, size_t nsize);


/*
** basic types
*/
#define LUA_TNONE (-1)

#define LUA_TNIL 0
#define LUA_TBOOLEAN 1
#define LUA_TLIGHTUSERDATA 2
#define LUA_TNUMBER 3
#define LUA_TSTRING 4
#define LUA_TTABLE 5
#define LUA_TFUNCTION 6
#define LUA_TUSERDATA 7
#define LUA_TTHREAD 8



/* minimum Lua stack available to a C function */
#define LUA_MINSTACK 20


/*
** generic extra include file
*/
#if defined(LUA_USER_H)
#include LUA_USER_H
#endif


/* type of numbers in Lua */
typedef LUA_NUMBER lua_Number;


/* type for integer functions */
typedef LUA_INTEGER lua_Integer;



/*
** state manipulation
*/
LUA_API lua_State *(lua_newstate) (lua_Alloc f, void *ud);
LUA_API void (lua_close) (lua_State *L);
LUA_API lua_State *(lua_newthread) (lua_State *L);

LUA_API lua_CFunction (lua_atpanic) (lua_State *L, lua_CFunction panicf);


/*
** basic stack manipulation
*/
LUA_API int (lua_gettop) (lua_State *L);
LUA_API void (lua_settop) (lua_State *L, int idx);
LUA_API void (lua_pushvalue) (lua_State *L, int idx);
LUA_API void (lua_remove) (lua_State *L, int idx);
LUA_API void (lua_insert) (lua_State *L, int idx);
LUA_API void (lua_replace) (lua_State *L, int idx);
LUA_API int (lua_checkstack) (lua_State *L, int sz);

LUA_API void (lua_xmove) (lua_State *from, lua_State *to, int n);


/*
** access functions (stack - &amp; gt; C)
*/

LUA_API int (lua_isnumber) (lua_State *L, int idx);
LUA_API int (lua_isstring) (lua_State *L, int idx);
LUA_API int (lua_iscfunction) (lua_State *L, int idx);
LUA_API int (lua_isuserdata) (lua_State *L, int idx);
LUA_API int (lua_type) (lua_State *L, int idx);
LUA_API const char *(lua_typename) (lua_State *L, int tp);

LUA_API int (lua_equal) (lua_State *L, int idx1, int idx2);
LUA_API int (lua_rawequal) (lua_State *L, int idx1, int idx2);
LUA_API int (lua_lessthan) (lua_State *L, int idx1, int idx2);

LUA_API lua_Number (lua_tonumber) (lua_State *L, int idx);
LUA_API lua_Integer (lua_tointeger) (lua_State *L, int idx);
LUA_API int (lua_toboolean) (lua_State *L, int idx);
LUA_API const char *(lua_tolstring) (lua_State *L, int idx, size_t *len);
LUA_API size_t (lua_objlen) (lua_State *L, int idx);
LUA_API lua_CFunction (lua_tocfunction) (lua_State *L, int idx);
LUA_API void *(lua_touserdata) (lua_State *L, int idx);
LUA_API lua_State *(lua_tothread) (lua_State *L, int idx);
LUA_API const void *(lua_topointer) (lua_State *L, int idx);


/*
** push functions (C - &amp; gt; stack)
*/
LUA_API void (lua_pushnil) (lua_State *L);
LUA_API void (lua_pushnumber) (lua_State *L, lua_Number n);
LUA_API void (lua_pushinteger) (lua_State *L, lua_Integer n);
LUA_API void (lua_pushlstring) (lua_State *L, const char *s, size_t l);
LUA_API void (lua_pushstring) (lua_State *L, const char *s);
LUA_API const char *(lua_pushvfstring) (lua_State *L, const char *fmt,
va_list argp);
LUA_API const char *(lua_pushfstring) (lua_State *L, const char *fmt, ...);
LUA_API void (lua_pushcclosure) (lua_State *L, lua_CFunction fn, int n);
LUA_API void (lua_pushboolean) (lua_State *L, int b);
LUA_API void (lua_pushlightuserdata) (lua_State *L, void *p);
LUA_API int (lua_pushthread) (lua_State *L);


/*
** get functions (Lua - &amp; gt; stack)
*/
LUA_API void (lua_gettable) (lua_State *L, int idx);
LUA_API void (lua_getfield) (lua_State *L, int idx, const char *k);
LUA_API void (lua_rawget) (lua_State *L, int idx);
LUA_API void (lua_rawgeti) (lua_State *L, int idx, int n);
LUA_API void (lua_createtable) (lua_State *L, int narr, int nrec);
LUA_API void *(lua_newuserdata) (lua_State *L, size_t sz);
LUA_API int (lua_getmetatable) (lua_State *L, int objindex);
LUA_API void (lua_getfenv) (lua_State *L, int idx);


/*
** set functions (stack - &amp; gt; Lua)
*/
LUA_API void (lua_settable) (lua_State *L, int idx);
LUA_API void (lua_setfield) (lua_State *L, int idx, const char *k);
LUA_API void (lua_rawset) (lua_State *L, int idx);
LUA_API void (lua_rawseti) (lua_State *L, int idx, int n);
LUA_API int (lua_setmetatable) (lua_State *L, int objindex);
LUA_API int (lua_setfenv) (lua_State *L, int idx);


/*
** `load' and `call' functions (load and run Lua code)
*/
LUA_API void (lua_call) (lua_State *L, int nargs, int nresults);
LUA_API int (lua_pcall) (lua_State *L, int nargs, int nresults, int errfunc);
LUA_API int (lua_cpcall) (lua_State *L, lua_CFunction func, void *ud);
LUA_API int (lua_load) (lua_State *L, lua_Reader reader, void *dt,
const char *chunkname);

LUA_API int (lua_dump) (lua_State *L, lua_Writer writer, void *data);


/*
** coroutine functions
*/
LUA_API int (lua_yield) (lua_State *L, int nresults);
LUA_API int (lua_resume) (lua_State *L, int narg);
LUA_API int (lua_status) (lua_State *L);

/*
** garbage-collection function and options
*/

#define LUA_GCSTOP 0
#define LUA_GCRESTART 1
#define LUA_GCCOLLECT 2
#define LUA_GCCOUNT 3
#define LUA_GCCOUNTB 4
#define LUA_GCSTEP 5
#define LUA_GCSETPAUSE 6
#define LUA_GCSETSTEPMUL 7

LUA_API int (lua_gc) (lua_State *L, int what, int data);


/*
** miscellaneous functions
*/

LUA_API int (lua_error) (lua_State *L);

LUA_API int (lua_next) (lua_State *L, int idx);

LUA_API void (lua_concat) (lua_State *L, int n);

LUA_API lua_Alloc (lua_getallocf) (lua_State *L, void **ud);
LUA_API void lua_setallocf (lua_State *L, lua_Alloc f, void *ud);



/*
** ===============================================================
** some useful macros
** ===============================================================
*/

#define lua_pop(L,n) lua_settop(L, -(n)-1)

#define lua_newtable(L) lua_createtable(L, 0, 0)

#define lua_register(L,n,f) (lua_pushcfunction(L, (f)), lua_setglobal(L, (n)))

#define lua_pushcfunction(L,f) lua_pushcclosure(L, (f), 0)

#define lua_strlen(L,i) lua_objlen(L, (i))

#define lua_isfunction(L,n) (lua_type(L, (n)) == LUA_TFUNCTION)
#define lua_istable(L,n) (lua_type(L, (n)) == LUA_TTABLE)
#define lua_islightuserdata(L,n) (lua_type(L, (n)) == LUA_TLIGHTUSERDATA)
#define lua_isnil(L,n) (lua_type(L, (n)) == LUA_TNIL)
#define lua_isboolean(L,n) (lua_type(L, (n)) == LUA_TBOOLEAN)
#define lua_isthread(L,n) (lua_type(L, (n)) == LUA_TTHREAD)
#define lua_isnone(L,n) (lua_type(L, (n)) == LUA_TNONE)
#define lua_isnoneornil(L, n) (lua_type(L, (n)) &amp; lt; = 0)

#define lua_pushliteral(L, s) \
lua_pushlstring(L, &quot; &quot; s, (sizeof(s)/sizeof(char))-1)

#define lua_setglobal(L,s) lua_setfield(L, LUA_GLOBALSINDEX, (s))
#define lua_getglobal(L,s) lua_getfield(L, LUA_GLOBALSINDEX, (s))

#define lua_tostring(L,i) lua_tolstring(L, (i), NULL)



/*
** compatibility macros and functions
*/

#define lua_open() luaL_newstate()

#define lua_getregistry(L) lua_pushvalue(L, LUA_REGISTRYINDEX)

#define lua_getgccount(L) lua_gc(L, LUA_GCCOUNT, 0)

#define lua_Chunkreader lua_Reader
#define lua_Chunkwriter lua_Writer


/* hack */
LUA_API void lua_setlevel (lua_State *from, lua_State *to);


/*
** {======================================================================
** Debug API
** =======================================================================
*/


/*
** Event codes
*/
#define LUA_HOOKCALL 0
#define LUA_HOOKRET 1
#define LUA_HOOKLINE 2
#define LUA_HOOKCOUNT 3
#define LUA_HOOKTAILRET 4


/*
** Event masks
*/
#define LUA_MASKCALL (1 &amp; lt; &amp; lt; LUA_HOOKCALL)
#define LUA_MASKRET (1 &amp; lt; &amp; lt; LUA_HOOKRET)
#define LUA_MASKLINE (1 &amp; lt; &amp; lt; LUA_HOOKLINE)
#define LUA_MASKCOUNT (1 &amp; lt; &amp; lt; LUA_HOOKCOUNT)

typedef struct lua_Debug lua_Debug; /* activation record */


/* Functions to be called by the debuger in specific events */
typedef void (*lua_Hook) (lua_State *L, lua_Debug *ar);


LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar);
LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar);
LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n);
LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n);
LUA_API const char *lua_getupvalue (lua_State *L, int funcindex, int n);
LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n);

LUA_API int lua_sethook (lua_State *L, lua_Hook func, int mask, int count);
LUA_API lua_Hook lua_gethook (lua_State *L);
LUA_API int lua_gethookmask (lua_State *L);
LUA_API int lua_gethookcount (lua_State *L);


struct lua_Debug {
int event;
const char *name; /* (n) */
const char *namewhat; /* (n) `global', `local', `field', `method' */
const char *what; /* (S) `Lua', `C', `main', `tail' */
const char *source; /* (S) */
int currentline; /* (l) */
int nups; /* (u) number of upvalues */
int linedefined; /* (S) */
int lastlinedefined; /* (S) */
char short_src[LUA_IDSIZE]; /* (S) */
/* private part */
int i_ci; /* active function */
};

/* }====================================================================== */


/******************************************************************************
* Copyright (C) 1994-2008 Lua.org, PUC-Rio. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* &quot; Software &quot; ), 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 &quot; AS IS &quot; , 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.
******************************************************************************/


#endif


scite228.zip > luaconf.h

/*
** $Id$
** Configuration file for Lua
** See Copyright Notice in lua.h
*/


#ifndef lconfig_h
#define lconfig_h

#include &amp; lt; limits.h &amp; gt;
#include &amp; lt; stddef.h &amp; gt;


/*
** ==================================================================
** Search for &quot; @@ &quot; to find all configurable definitions.
** ===================================================================
*/


/*
@@ LUA_ANSI controls the use of non-ansi features.
** CHANGE it (define it) if you want Lua to avoid the use of any
** non-ansi feature or library.
*/
#if defined(__STRICT_ANSI__)
#define LUA_ANSI
#endif


#if !defined(LUA_ANSI) &amp; &amp; defined(_WIN32)
#define LUA_WIN
#endif

#if defined(LUA_USE_LINUX)
#define LUA_USE_POSIX
#define LUA_USE_DLOPEN /* needs an extra library: -ldl */
#define LUA_USE_READLINE /* needs some extra libraries */
#endif

#if defined(LUA_USE_MACOSX)
#define LUA_USE_POSIX
#define LUA_DL_DYLD /* does not need extra library */
#endif



/*
@@ LUA_USE_POSIX includes all functionallity listed as X/Open System
@* Interfaces Extension (XSI).
** CHANGE it (define it) if your system is XSI compatible.
*/
#if defined(LUA_USE_POSIX)
#define LUA_USE_MKSTEMP
#define LUA_USE_ISATTY
#define LUA_USE_POPEN
#define LUA_USE_ULONGJMP
#endif


/*
@@ LUA_PATH and LUA_CPATH are the names of the environment variables that
@* Lua check to set its paths.
@@ LUA_INIT is the name of the environment variable that Lua
@* checks for initialization code.
** CHANGE them if you want different names.
*/
#define LUA_PATH &quot; LUA_PATH &quot;
#define LUA_CPATH &quot; LUA_CPATH &quot;
#define LUA_INIT &quot; LUA_INIT &quot;


/*
@@ LUA_PATH_DEFAULT is the default path that Lua uses to look for
@* Lua libraries.
@@ LUA_CPATH_DEFAULT is the default path that Lua uses to look for
@* C libraries.
** CHANGE them if your machine has a non-conventional directory
** hierarchy or if you want to install your libraries in
** non-conventional directories.
*/
#if defined(_WIN32)
/*
** In Windows, any exclamation mark ('!') in the path is replaced by the
** path of the directory of the executable file of the current process.
*/
#define LUA_LDIR &quot; !\\lua\\ &quot;
#define LUA_CDIR &quot; !\\ &quot;
#define LUA_PATH_DEFAULT \
&quot; .\\?.lua; &quot; LUA_LDIR &quot; ?.lua; &quot; LUA_LDIR &quot; ?\\init.lua; &quot; \
LUA_CDIR &quot; ?.lua; &quot; LUA_CDIR &quot; ?\\init.lua &quot;
#define LUA_CPATH_DEFAULT \
&quot; .\\?.dll; &quot; LUA_CDIR &quot; ?.dll; &quot; LUA_CDIR &quot; loadall.dll &quot;

#else
#define LUA_ROOT &quot; /usr/local/ &quot;
#define LUA_LDIR LUA_ROOT &quot; share/lua/5.1/ &quot;
#define LUA_CDIR LUA_ROOT &quot; lib/lua/5.1/ &quot;
#define LUA_PATH_DEFAULT \
&quot; ./?.lua; &quot; LUA_LDIR &quot; ?.lua; &quot; LUA_LDIR &quot; ?/init.lua; &quot; \
LUA_CDIR &quot; ?.lua; &quot; LUA_CDIR &quot; ?/init.lua &quot;
#define LUA_CPATH_DEFAULT \
&quot; ./?.so; &quot; LUA_CDIR &quot; ?.so; &quot; LUA_CDIR &quot; loadall.so &quot;
#endif


/*
@@ LUA_DIRSEP is the directory separator (for submodules).
** CHANGE it if your machine does not use &quot; / &quot; as the directory separator
** and is not Windows. (On Windows Lua automatically uses &quot; \ &quot; .)
*/
#if defined(_WIN32)
#define LUA_DIRSEP &quot; \\ &quot;
#else
#define LUA_DIRSEP &quot; / &quot;
#endif


/*
@@ LUA_PATHSEP is the character that separates templates in a path.
@@ LUA_PATH_MARK is the string that marks the substitution points in a
@* template.
@@ LUA_EXECDIR in a Windows path is replaced by the executable's
@* directory.
@@ LUA_IGMARK is a mark to ignore all before it when bulding the
@* luaopen_ function name.
** CHANGE them if for some reason your system cannot use those
** characters. (E.g., if one of those characters is a common character
** in file/directory names.) Probably you do not need to change them.
*/
#define LUA_PATHSEP &quot; ; &quot;
#define LUA_PATH_MARK &quot; ? &quot;
#define LUA_EXECDIR &quot; ! &quot;
#define LUA_IGMARK &quot; - &quot;


/*
@@ LUA_INTEGER is the integral type used by lua_pushinteger/lua_tointeger.
** CHANGE that if ptrdiff_t is not adequate on your machine. (On most
** machines, ptrdiff_t gives a good choice between int or long.)
*/
#define LUA_INTEGER ptrdiff_t


/*
@@ LUA_API is a mark for all core API functions.
@@ LUALIB_API is a mark for all standard library functions.
** CHANGE them if you need to define those functions in some special way.
** For instance, if you want to create one Windows DLL with the core and
** the libraries, you may want to use the following definition (define
** LUA_BUILD_AS_DLL to get it).
*/
#if defined(LUA_BUILD_AS_DLL)

#if defined(LUA_CORE) || defined(LUA_LIB)
#define LUA_API __declspec(dllexport)
#else
#define LUA_API __declspec(dllimport)
#endif

#else

#if defined(_WIN32)
#define LUA_API __declspec(dllexport)
#else
#define LUA_API extern
#endif

#endif

/* more often than not the libs go together with the core */
#define LUALIB_API LUA_API


/*
@@ LUAI_FUNC is a mark for all extern functions that are not to be
@* exported to outside modules.
@@ LUAI_DATA is a mark for all extern (const) variables that are not to
@* be exported to outside modules.
** CHANGE them if you need to mark them in some special way. Elf/gcc
** (versions 3.2 and later) mark them as &quot; hidden &quot; to optimize access
** when Lua is compiled as a shared library.
*/
#if defined(luaall_c)
#define LUAI_FUNC static
#define LUAI_DATA /* empty */

#elif defined(__GNUC__) &amp; &amp; ((__GNUC__*100 + __GNUC_MINOR__) &amp; gt; = 302) &amp; &amp; \
defined(__ELF__)
#define LUAI_FUNC __attribute__((visibility( &quot; hidden &quot; ))) extern
#define LUAI_DATA LUAI_FUNC

#else
#define LUAI_FUNC extern
#define LUAI_DATA extern
#endif



/*
@@ LUA_QL describes how error messages quote program elements.
** CHANGE it if you want a different appearance.
*/
#define LUA_QL(x) &quot; ' &quot; x &quot; ' &quot;
#define LUA_QS LUA_QL( &quot; %s &quot; )


/*
@@ LUA_IDSIZE gives the maximum size for the description of the source
@* of a function in debug information.
** CHANGE it if you want a different size.
*/
#define LUA_IDSIZE 60


/*
** {==================================================================
** Stand-alone configuration
** ===================================================================
*/

#if defined(lua_c) || defined(luaall_c)

/*
@@ lua_stdin_is_tty detects whether the standard input is a 'tty' (that
@* is, whether we're running lua interactively).
** CHANGE it if you have a better definition for non-POSIX/non-Windows
** systems.
*/
#if defined(LUA_USE_ISATTY)
#include &amp; lt; unistd.h &amp; gt;
#define lua_stdin_is_tty() isatty(0)
#elif defined(LUA_WIN)
#include &amp; lt; io.h &amp; gt;
#include &amp; lt; stdio.h &amp; gt;
#define lua_stdin_is_tty() _isatty(_fileno(stdin))
#else
#define lua_stdin_is_tty() 1 /* assume stdin is a tty */
#endif


/*
@@ LUA_PROMPT is the default prompt used by stand-alone Lua.
@@ LUA_PROMPT2 is the default continuation prompt used by stand-alone Lua.
** CHANGE them if you want different prompts. (You can also change the
** prompts dynamically, assigning to globals _PROMPT/_PROMPT2.)
*/
#define LUA_PROMPT &quot; &amp; gt; &quot;
#define LUA_PROMPT2 &quot; &amp; gt; &amp; gt; &quot;


/*
@@ LUA_PROGNAME is the default name for the stand-alone Lua program.
** CHANGE it if your stand-alone interpreter has a different name and
** your system is not able to detect that name automatically.
*/
#define LUA_PROGNAME &quot; lua &quot;


/*
@@ LUA_MAXINPUT is the maximum length for an input line in the
@* stand-alone interpreter.
** CHANGE it if you need longer lines.
*/
#define LUA_MAXINPUT 512


/*
@@ lua_readline defines how to show a prompt and then read a line from
@* the standard input.
@@ lua_saveline defines how to &quot; save &quot; a read line in a &quot; history &quot; .
@@ lua_freeline defines how to free a line read by lua_readline.
** CHANGE them if you want to improve this functionality (e.g., by using
** GNU readline and history facilities).
*/
#if defined(LUA_USE_READLINE)
#include &amp; lt; stdio.h &amp; gt;
#include &amp; lt; readline/readline.h &amp; gt;
#include &amp; lt; readline/history.h &amp; gt;
#define lua_readline(L,b,p) ((void)L, ((b)=readline(p)) != NULL)
#define lua_saveline(L,idx) \
if (lua_strlen(L,idx) &amp; gt; 0) /* non-empty line? */ \
add_history(lua_tostring(L, idx)); /* add it to history */
#define lua_freeline(L,b) ((void)L, free(b))
#else
#define lua_readline(L,b,p) \
((void)L, fputs(p, stdout), fflush(stdout), /* show prompt */ \
fgets(b, LUA_MAXINPUT, stdin) != NULL) /* get line */
#define lua_saveline(L,idx) { (void)L; (void)idx; }
#define lua_freeline(L,b) { (void)L; (void)b; }
#endif

#endif

/* }================================================================== */


/*
@@ LUAI_GCPAUSE defines the default pause between garbage-collector cycles
@* as a percentage.
** CHANGE it if you want the GC to run faster or slower (higher values
** mean larger pauses which mean slower collection.) You can also change
** this value dynamically.
*/
#define LUAI_GCPAUSE 200 /* 200% (wait memory to double before next GC) */


/*
@@ LUAI_GCMUL defines the default speed of garbage collection relative to
@* memory allocation as a percentage.
** CHANGE it if you want to change the granularity of the garbage
** collection. (Higher values mean coarser collections. 0 represents
** infinity, where each step performs a full collection.) You can also
** change this value dynamically.
*/
#define LUAI_GCMUL 200 /* GC runs 'twice the speed' of memory allocation */



/*
@@ LUA_COMPAT_GETN controls compatibility with old getn behavior.
** CHANGE it (define it) if you want exact compatibility with the
** behavior of setn/getn in Lua 5.0.
*/
#undef LUA_COMPAT_GETN

/*
@@ LUA_COMPAT_LOADLIB controls compatibility about global loadlib.
** CHANGE it to undefined as soon as you do not need a global 'loadlib'
** function (the function is still available as 'package.loadlib').
*/
#undef LUA_COMPAT_LOADLIB

/*
@@ LUA_COMPAT_VARARG controls compatibility with old vararg feature.
** CHANGE it to undefined as soon as your programs use only '...' to
** access vararg parameters (instead of the old 'arg' table).
*/
#define LUA_COMPAT_VARARG

/*
@@ LUA_COMPAT_MOD controls compatibility with old math.mod function.
** CHANGE it to undefined as soon as your programs use 'math.fmod' or
** the new '%' operator instead of 'math.mod'.
*/
#define LUA_COMPAT_MOD

/*
@@ LUA_COMPAT_LSTR controls compatibility with old long string nesting
@* facility.
** CHANGE it to 2 if you want the old behaviour, or undefine it to turn
** off the advisory error when nesting [[...]].
*/
#define LUA_COMPAT_LSTR 1

/*
@@ LUA_COMPAT_GFIND controls compatibility with old 'string.gfind' name.
** CHANGE it to undefined as soon as you rename 'string.gfind' to
** 'string.gmatch'.
*/
#define LUA_COMPAT_GFIND

/*
@@ LUA_COMPAT_OPENLIB controls compatibility with old 'luaL_openlib'
@* behavior.
** CHANGE it to undefined as soon as you replace to 'luaL_register'
** your uses of 'luaL_openlib'
*/
#define LUA_COMPAT_OPENLIB



/*
@@ luai_apicheck is the assert macro used by the Lua-C API.
** CHANGE luai_apicheck if you want Lua to perform some checks in the
** parameters it gets from API calls. This may slow down the interpreter
** a bit, but may be quite useful when debugging C code that interfaces
** with Lua. A useful redefinition is to use assert.h.
*/
#if defined(LUA_USE_APICHECK)
#include &amp; lt; assert.h &amp; gt;
#define luai_apicheck(L,o) { (void)L; assert(o); }
#else
#define luai_apicheck(L,o) { (void)L; }
#endif


/*
@@ LUAI_BITSINT defines the number of bits in an int.
** CHANGE here if Lua cannot automatically detect the number of bits of
** your machine. Probably you do not need to change this.
*/
/* avoid overflows in comparison */
#if INT_MAX-20 &amp; lt; 32760
#define LUAI_BITSINT 16
#elif INT_MAX &amp; gt; 2147483640L
/* int has at least 32 bits */
#define LUAI_BITSINT 32
#else
#error &quot; you must define LUA_BITSINT with number of bits in an integer &quot;
#endif


/*
@@ LUAI_UINT32 is an unsigned integer with at least 32 bits.
@@ LUAI_INT32 is an signed integer with at least 32 bits.
@@ LUAI_UMEM is an unsigned integer big enough to count the total
@* memory used by Lua.
@@ LUAI_MEM is a signed integer big enough to count the total memory
@* used by Lua.
** CHANGE here if for some weird reason the default definitions are not
** good enough for your machine. (The definitions in the 'else'
** part always works, but may waste space on machines with 64-bit
** longs.) Probably you do not need to change this.
*/
#if LUAI_BITSINT &amp; gt; = 32
#define LUAI_UINT32 unsigned int
#define LUAI_INT32 int
#define LUAI_MAXINT32 INT_MAX
#define LUAI_UMEM size_t
#define LUAI_MEM ptrdiff_t
#else
/* 16-bit ints */
#define LUAI_UINT32 unsigned long
#define LUAI_INT32 long
#define LUAI_MAXINT32 LONG_MAX
#define LUAI_UMEM unsigned long
#define LUAI_MEM long
#endif


/*
@@ LUAI_MAXCALLS limits the number of nested calls.
** CHANGE it if you need really deep recursive calls. This limit is
** arbitrary; its only purpose is to stop infinite recursion before
** exhausting memory.
*/
#define LUAI_MAXCALLS 20000


/*
@@ LUAI_MAXCSTACK limits the number of Lua stack slots that a C function
@* can use.
** CHANGE it if you need lots of (Lua) stack space for your C
** functions. This limit is arbitrary; its only purpose is to stop C
** functions to consume unlimited stack space. (must be smaller than
** -LUA_REGISTRYINDEX)
*/
#define LUAI_MAXCSTACK 8000



/*
** {==================================================================
** CHANGE (to smaller values) the following definitions if your system
** has a small C stack. (Or you may want to change them to larger
** values if your system has a large C stack and these limits are
** too rigid for you.) Some of these constants control the size of
** stack-allocated arrays used by the compiler or the interpreter, while
** others limit the maximum number of recursive calls that the compiler
** or the interpreter can perform. Values too large may cause a C stack
** overflow for some forms of deep constructs.
** ===================================================================
*/


/*
@@ LUAI_MAXCCALLS is the maximum depth for nested C calls (short) and
@* syntactical nested non-terminals in a program.
*/
#define LUAI_MAXCCALLS 200


/*
@@ LUAI_MAXVARS is the maximum number of local variables per function
@* (must be smaller than 250).
*/
#define LUAI_MAXVARS 200


/*
@@ LUAI_MAXUPVALUES is the maximum number of upvalues per function
@* (must be smaller than 250).
*/
#define LUAI_MAXUPVALUES 60


/*
@@ LUAL_BUFFERSIZE is the buffer size used by the lauxlib buffer system.
*/
#define LUAL_BUFFERSIZE BUFSIZ

/* }================================================================== */




/*
** {==================================================================
@@ LUA_NUMBER is the type of numbers in Lua.
** CHANGE the following definitions only if you want to build Lua
** with a number type different from double. You may also need to
** change lua_number2int &amp; lua_number2integer.
** ===================================================================
*/

#define LUA_NUMBER_DOUBLE
#define LUA_NUMBER double

/*
@@ LUAI_UACNUMBER is the result of an 'usual argument conversion'
@* over a number.
*/
#define LUAI_UACNUMBER double


/*
@@ LUA_NUMBER_SCAN is the format for reading numbers.
@@ LUA_NUMBER_FMT is the format for writing numbers.
@@ lua_number2str converts a number to a string.
@@ LUAI_MAXNUMBER2STR is maximum size of previous conversion.
@@ lua_str2number converts a string to a number.
*/
#define LUA_NUMBER_SCAN &quot; %lf &quot;
#define LUA_NUMBER_FMT &quot; %.14g &quot;
#define lua_number2str(s,n) sprintf((s), LUA_NUMBER_FMT, (n))
#define LUAI_MAXNUMBER2STR 32 /* 16 digits, sign, point, and \0 */
#define lua_str2number(s,p) strtod((s), (p))


/*
@@ The luai_num* macros define the primitive operations over numbers.
*/
#if defined(LUA_CORE)
#include &amp; lt; math.h &amp; gt;
#define luai_numadd(a,b) ((a)+(b))
#define luai_numsub(a,b) ((a)-(b))
#define luai_nummul(a,b) ((a)*(b))
#define luai_numdiv(a,b) ((a)/(b))
#define luai_nummod(a,b) ((a) - floor((a)/(b))*(b))
#define luai_numpow(a,b) (pow(a,b))
#define luai_numunm(a) (-(a))
#define luai_numeq(a,b) ((a)==(b))
#define luai_numlt(a,b) ((a) &amp; lt; (b))
#define luai_numle(a,b) ((a) &amp; lt; =(b))
#define luai_numisnan(a) (!luai_numeq((a), (a)))
#endif


/*
@@ lua_number2int is a macro to convert lua_Number to int.
@@ lua_number2integer is a macro to convert lua_Number to lua_Integer.
** CHANGE them if you know a faster way to convert a lua_Number to
** int (with any rounding method and without throwing errors) in your
** system. In Pentium machines, a naive typecast from double to int
** in C is extremely slow, so any alternative is worth trying.
*/

/* On a Pentium, resort to a trick */
#if defined(LUA_NUMBER_DOUBLE) &amp; &amp; !defined(LUA_ANSI) &amp; &amp; !defined(__SSE2__) &amp; &amp; \
(defined(__i386) || defined (_M_IX86) || defined(__i386__))

/* On a Microsoft compiler, use assembler */
#if defined(_MSC_VER)

#define lua_number2int(i,d) __asm fld d __asm fistp i
#define lua_number2integer(i,n) lua_number2int(i, n)

/* the next trick should work on any Pentium, but sometimes clashes
with a DirectX idiosyncrasy */
#else

union luai_Cast { double l_d; long l_l; };
#define lua_number2int(i,d) \
{ volatile union luai_Cast u; u.l_d = (d) + 6755399441055744.0; (i) = u.l_l; }
#define lua_number2integer(i,n) lua_number2int(i, n)

#endif


/* this option always works, but may be slow */
#else
#define lua_number2int(i,d) ((i)=(int)(d))
#define lua_number2integer(i,d) ((i)=(lua_Integer)(d))

#endif

/* }================================================================== */


/*
@@ LUAI_USER_ALIGNMENT_T is a type that requires maximum alignment.
** CHANGE it if your system requires alignments larger than double. (For
** instance, if your system supports long doubles and they must be
** aligned in 16-byte boundaries, then you should add long double in the
** union.) Probably you do not need to change this.
*/
#define LUAI_USER_ALIGNMENT_T union { double u; void *s; long l; }


/*
@@ LUAI_THROW/LUAI_TRY define how Lua does exception handling.
** CHANGE them if you prefer to use longjmp/setjmp even with C++
** or if want/don't to use _longjmp/_setjmp instead of regular
** longjmp/setjmp. By default, Lua handles errors with exceptions when
** compiling as C++ code, with _longjmp/_setjmp when asked to use them,
** and with longjmp/setjmp otherwise.
*/
#if defined(__cplusplus)
/* C++ exceptions */
#define LUAI_THROW(L,c) throw(c)
#define LUAI_TRY(L,c,a) try { a } catch(...) \
{ if ((c)- &amp; gt; status == 0) (c)- &amp; gt; status = -1; }
#define luai_jmpbuf int /* dummy variable */

#elif defined(LUA_USE_ULONGJMP)
/* in Unix, try _longjmp/_setjmp (more efficient) */
#define LUAI_THROW(L,c) _longjmp((c)- &amp; gt; b, 1)
#define LUAI_TRY(L,c,a) if (_setjmp((c)- &amp; gt; b) == 0) { a }
#define luai_jmpbuf jmp_buf

#else
/* default handling with long jumps */
#define LUAI_THROW(L,c) longjmp((c)- &amp; gt; b, 1)
#define LUAI_TRY(L,c,a) if (setjmp((c)- &amp; gt; b) == 0) { a }
#define luai_jmpbuf jmp_buf

#endif


/*
@@ LUA_MAXCAPTURES is the maximum number of captures that a pattern
@* can do during pattern-matching.
** CHANGE it if you need more captures. This limit is arbitrary.
*/
#define LUA_MAXCAPTURES 32


/*
@@ lua_tmpnam is the function that the OS library uses to create a
@* temporary name.
@@ LUA_TMPNAMBUFSIZE is the maximum size of a name created by lua_tmpnam.
** CHANGE them if you have an alternative to tmpnam (which is considered
** insecure) or if you want the original tmpnam anyway. By default, Lua
** uses tmpnam except when POSIX is available, where it uses mkstemp.
*/
#if defined(loslib_c) || defined(luaall_c)

#if defined(LUA_USE_MKSTEMP)
#include &amp; lt; unistd.h &amp; gt;
#define LUA_TMPNAMBUFSIZE 32
#define lua_tmpnam(b,e) { \
strcpy(b, &quot; /tmp/lua_XXXXXX &quot; ); \
e = mkstemp(b); \
if (e != -1) close(e); \
e = (e == -1); }

#else
#define LUA_TMPNAMBUFSIZE L_tmpnam
#define lua_tmpnam(b,e) { e = (tmpnam(b) == NULL); }
#endif

#endif


/*
@@ lua_popen spawns a new process connected to the current one through
@* the file streams.
** CHANGE it if you have a way to implement it in your system.
*/
#if defined(LUA_USE_POPEN)

#define lua_popen(L,c,m) ((void)L, fflush(NULL), popen(c,m))
#define lua_pclose(L,file) ((void)L, (pclose(file) != -1))

#elif defined(LUA_WIN)

#define lua_popen(L,c,m) ((void)L, _popen(c,m))
#define lua_pclose(L,file) ((void)L, (_pclose(file) != -1))

#else

#define lua_popen(L,c,m) ((void)((void)c, m), \
luaL_error(L, LUA_QL( &quot; popen &quot; ) &quot; not supported &quot; ), (FILE*)0)
#define lua_pclose(L,file) ((void)((void)L, file), 0)

#endif

/*
@@ LUA_DL_* define which dynamic-library system Lua should use.
** CHANGE here if Lua has problems choosing the appropriate
** dynamic-library system for your platform (either Windows' DLL, Mac's
** dyld, or Unix's dlopen). If your system is some kind of Unix, there
** is a good chance that it has dlopen, so LUA_DL_DLOPEN will work for
** it. To use dlopen you also need to adapt the src/Makefile (probably
** adding -ldl to the linker options), so Lua does not select it
** automatically. (When you change the makefile to add -ldl, you must
** also add -DLUA_USE_DLOPEN.)
** If you do not want any kind of dynamic library, undefine all these
** options.
** By default, _WIN32 gets LUA_DL_DLL and MAC OS X gets LUA_DL_DYLD.
*/
#if defined(LUA_USE_DLOPEN)
#define LUA_DL_DLOPEN
#endif

#if defined(LUA_WIN)
#define LUA_DL_DLL
#endif


/*
@@ LUAI_EXTRASPACE allows you to add user-specific data in a lua_State
@* (the data goes just *before* the lua_State pointer).
** CHANGE (define) this if you really need that. This value must be
** a multiple of the maximum alignment required for your machine.
*/
#define LUAI_EXTRASPACE 0


/*
@@ luai_userstate* allow user-specific actions on threads.
** CHANGE them if you defined LUAI_EXTRASPACE and need to do something
** extra when a thread is created/deleted/resumed/yielded.
*/
#define luai_userstateopen(L) ((void)L)
#define luai_userstateclose(L) ((void)L)
#define luai_userstatethread(L,L1) ((void)L)
#define luai_userstatefree(L) ((void)L)
#define luai_userstateresume(L,n) ((void)L)
#define luai_userstateyield(L,n) ((void)L)


/*
@@ LUA_INTFRMLEN is the length modifier for integer conversions
@* in 'string.format'.
@@ LUA_INTFRM_T is the integer type correspoding to the previous length
@* modifier.
** CHANGE them if your system supports long long or does not support long.
*/

#if defined(LUA_USELONGLONG)

#define LUA_INTFRMLEN &quot; ll &quot;
#define LUA_INTFRM_T long long

#else

#define LUA_INTFRMLEN &quot; l &quot;
#define LUA_INTFRM_T long

#endif



/* =================================================================== */

/*
** Local configuration. You can use this space to add your redefinitions
** without modifying the main part of the file.
*/



#endif


scite228.zip > .hg_archival.txt

repo: dfc7523942ae501c035e4c36e791803c09d112e5
node: 73d6e5aa8df65c6969222dcc4e9cf5a4709ef0d6
branch: default
latesttag: rel-2-27
latesttagdistance: 23


scite228.zip > SciIcon.h

/* XPM */
static const char * SciIcon_xpm[] = {
&quot; 16 16 17 1 &quot; ,
&quot; c None &quot; ,
&quot; . c #666666 &quot; ,
&quot; + c #424242 &quot; ,
&quot; @ c #4D4D4D &quot; ,
&quot; # c #777777 &quot; ,
&quot; $ c #555555 &quot; ,
&quot; % c #868686 &quot; ,
&quot; &amp; c #333333 &quot; ,
&quot; * c #292929 &quot; ,
&quot; = c #A0A0A4 &quot; ,
&quot; - c #808080 &quot; ,
&quot; ; c #C0C0C0 &quot; ,
&quot; &amp; gt; c #999999 &quot; ,
&quot; , c #E3E3E3 &quot; ,
&quot; ' c #161616 &quot; ,
&quot; ) c #B2B2B2 &quot; ,
&quot; ! c #D7D7D7 &quot; ,
&quot; .+@@+# &quot; ,
&quot; $+$$@+@+@$ &quot; ,
&quot; $@+% &amp; .@@@++@ &quot; ,
&quot; $@*=@-@- &amp; .+ &amp; &amp; @ &quot; ,
&quot; #+@;* &amp; gt; # &amp; &amp; gt; &amp; @+*+ &quot; ,
&quot; .$*;*,*=='..'++ &amp; &quot; ,
&quot; + &amp; .%#.,*$; &amp; *. &amp; * &amp; &quot; ,
&quot; *@)*,$+,@ &amp; =.' &amp; .' &quot; ,
&quot; *$ &amp; ;*,$*!=*+%$'' &quot; ,
&quot; **@$)*;%*.;$***' &quot; ,
&quot; * &amp; &amp; &amp; &amp; $*#- &amp; *@+ &amp; '' &quot; ,
&quot; ** &amp; @*$**@+*''' &quot; ,
&quot; &amp; * &amp; +.'++*'* &amp; ** &quot; ,
&quot; ** &amp; *+ &amp; * &amp; &amp; *'' &quot; ,
&quot; ********'' &quot; ,
&quot; *''''' &quot; };


scite228.zip > DirectorExtension.h

// SciTE - Scintilla based Text Editor
/** @file DirectorExtension.h
** Extension for communicating with a director program.
**/
// Copyright 1998-2001 by Neil Hodgson &amp; lt; neilh@scintilla.org &amp; gt;
// The License.txt file describes the conditions under which this software may be distributed.

class DirectorExtension : public Extension {
private:
DirectorExtension() : inputWatcher(-1), inputChannel(0) {} // Singleton
DirectorExtension(const DirectorExtension &amp; ); // Disable copy ctor
void operator=(const DirectorExtension &amp; ); // Disable operator=

public:
static DirectorExtension &amp; Instance();

// Implement the Extension interface
virtual bool Initialise(ExtensionAPI *host_);
virtual bool Finalise();
virtual bool Clear();
virtual bool Load(const char *filename);

virtual bool OnOpen(const char *path);
virtual bool OnSwitchFile(const char *path);
virtual bool OnSave(const char *path);
virtual bool OnChar(char ch);
virtual bool OnExecute(const char *s);
virtual bool OnSavePointReached();
virtual bool OnSavePointLeft();
virtual bool OnStyle(unsigned int startPos, int lengthDoc, int initStyle, StyleWriter *styler);
virtual bool OnDoubleClick();
virtual bool OnUpdateUI();
virtual bool OnMarginClick();
virtual bool OnMacro(const char *command, const char *params);

virtual bool SendProperty(const char *prop);
virtual bool OnClose(const char *path);

// Allow messages through to extension
void HandleStringMessage(const char *message);

void CreatePipe(bool forceNew = false);
private:
int inputWatcher;
GIOChannel *inputChannel;
};


scite228.zip > Widget.h

// SciTE - Scintilla based Text Editor
// Widget.h - code for manipulating GTK+ widgets
// Copyright 2010 by Neil Hodgson &amp; lt; neilh@scintilla.org &amp; gt;
// The License.txt file describes the conditions under which this software may be distributed.

// Callback thunk class connects GTK+ signals to a simple command method.

#if GTK_CHECK_VERSION(2,20,0)
#define IS_WIDGET_FOCUSSED(w) (gtk_widget_has_focus(GTK_WIDGET(w)))
#define IS_WIDGET_SENSITIVE(w) (gtk_widget_get_sensitive(GTK_WIDGET(w)))
#else
#define IS_WIDGET_FOCUSSED(w) (GTK_WIDGET_HAS_FOCUS(w))
#define IS_WIDGET_SENSITIVE(w) (GTK_WIDGET_SENSITIVE(w))
#endif

class CommandHandler {
public:
virtual void PerformCommand(int commandNumber) = 0;
};

template &amp; lt; int commandNumber &amp; gt;
class CommandSignal {
public:
void Attach(GtkWidget *w, CommandHandler *object, const char *sigName= &quot; clicked &quot; ) {
g_signal_connect(G_OBJECT(w), sigName, G_CALLBACK(Function), object);
}
static void Function(GtkWidget */*w*/, CommandHandler *object) {
object- &amp; gt; PerformCommand(commandNumber);
}
};

template &amp; lt; int commandNumber &amp; gt;
inline void CommandAttach(GtkWidget *w, CommandHandler *object, const char *sigName= &quot; clicked &quot; ) {
CommandSignal &amp; lt; commandNumber &amp; gt; sig;
sig.Attach(w, object, sigName);
}

// Callback thunk class connects GTK+ signals to an instance method.
template &amp; lt; class T, void (T::*method)() &amp; gt;
class ObjectSignal {
public:
static void Function(GtkWidget */*w*/, T *object) {
(object- &amp; gt; *method)();
}
};

class WBase : public GUI::Window {
public:
operator GtkWidget*();
GtkWidget* Pointer();
bool Sensitive();
void SetSensitive(bool sensitive);
};

inline GtkWidget *Widget(const GUI::Window &amp; w) {
return reinterpret_cast &amp; lt; GtkWidget * &amp; gt; (w.GetID());
}

class WStatic : public WBase {
public:
void Create(GUI::gui_string text);
void SetMnemonicFor(WBase &amp; w);
};

class WEntry : public WBase {
public:
void Create(const GUI::gui_char *text=0);
void ActivatesDefault();
const GUI::gui_char *Text();
int Value();
void SetText(const GUI::gui_char *text);
};

class WComboBoxEntry : public WBase {
public:
void Create();
GtkEntry *Entry();
void ActivatesDefault();
const GUI::gui_char *Text();
void SetText(const GUI::gui_char *text);
bool HasFocusOnSelfOrChild();
void RemoveText(int position);
void AppendText(const char *text);
void FillFromMemory(const std::vector &amp; lt; std::string &amp; gt; &amp; mem, bool useTop = false);
};

class WButton : public WBase {
public:
void Create(GUI::gui_string text, GCallback func, gpointer data);
void Create(GUI::gui_string text);
};

class WToggle : public WBase {
public:
void Create(const GUI::gui_string &amp; text);
bool Active();
void SetActive(bool active);
};

class WCheckDraw : public WBase {
bool isActive;
GdkPixbuf *pbGrey;
GtkStyle *pStyle;
bool over;
static gboolean Focus(GtkWidget *widget, GdkEventFocus *event, WCheckDraw *pcd);
gint Press(GtkWidget *widget, GdkEventButton *event);
static gint ButtonsPress(GtkWidget *widget, GdkEventButton *event, WCheckDraw *pcd);
static gboolean MouseEnterLeave(GtkWidget *widget, GdkEventCrossing *event, WCheckDraw *pcd);
static gboolean KeyDown(GtkWidget *widget, GdkEventKey *event, WCheckDraw *pcd);
#if GTK_CHECK_VERSION(3,0,0)
gboolean Draw(GtkWidget *widget, cairo_t *cr);
static gboolean DrawEvent(GtkWidget *widget, cairo_t *cr, WCheckDraw *pcd);
#else
gboolean Expose(GtkWidget *widget, GdkEventExpose *event);
static gboolean ExposeEvent(GtkWidget *widget, GdkEventExpose *event, WCheckDraw *pcd);
#endif
public:
WCheckDraw();
~WCheckDraw();
void Create(const char **xpmImage, GUI::gui_string toolTip, GtkStyle *pStyle_);
bool Active();
void SetActive(bool active);
void Toggle();
enum { checkIconWidth = 16, checkButtonWidth = 16 + 3 * 2 + 1};
};

class WTable : public WBase {
private:
int rows;
int columns;
int next;
public:
WTable(int rows_, int columns_);
void Add(GtkWidget *child=0, int width=1, bool expand=false,
int xpadding=5, int ypadding=5);
void Label(GtkWidget *child);
void PackInto(GtkBox *box, gboolean expand=TRUE);
};

GUI::gui_char KeyFromLabel(GUI::gui_string label);

class Dialog : public GUI::Window {
public:
void Create(const GUI::gui_string &amp; title);
void Display(GtkWidget *parent = 0, bool modal=true);
GtkWidget *ResponseButton(const GUI::gui_string &amp; text, int responseID);
void Present();
GtkWidget *ContentArea();

private:
static void SignalDestroy(GtkWidget *, Dialog *d);
};

void DestroyDialog(GtkWidget *, gpointer *window);

class BaseWin : public GUI::Window {
protected:
ILocalize *localiser;
public:
BaseWin() : localiser(0) {
}
void SetLocalizer(ILocalize *localiser_) {
localiser = localiser_;
}
};

class Strip : public BaseWin {
protected:
bool allowMenuActions;
bool childHasFocus;
enum { heightButton=23, heightStatic=12, widthCombo=20};
public:
bool visible;
Strip() : allowMenuActions(false), childHasFocus(false), visible(false) {
}
virtual ~Strip() {
}
virtual void Creation(GtkWidget *container);
virtual void Show(int buttonHeight);
virtual void Close();
virtual bool KeyDown(GdkEventKey *event);
virtual void ShowPopup() = 0;
virtual void MenuAction(guint action) = 0;
static void MenuSignal(GtkMenuItem *menuItem, Strip *pStrip);
void AddToPopUp(GUI::Menu &amp; popup, const char *label, int cmd, bool checked);
virtual void ChildFocus(GtkWidget *widget);
static gboolean ChildFocusSignal(GtkContainer *container, GtkWidget *widget, Strip *pStrip);
virtual gboolean Focus(GtkDirectionType direction) = 0;
static gboolean FocusSignal(GtkWidget *widget, GtkDirectionType direction, Strip *pStrip);
bool VisibleHasFocus();
static gint ButtonsPress(GtkWidget *widget, GdkEventButton *event, Strip *pstrip);
};


scite228.zip > pixmapsGNOME.h

// Set of images for tool bar buttons
// Icons Copyright(C) 1998 by Dean S. Jones
// http://jfa.javalobby.org/projects/icons/
// Modified to have same names as tigert.h
// Not really anything to do with Gnome - just calling this
// file pixmapsGNOME to fit in with previous code.

/* XPM */
static const char * editcopy_xpm[] = {
&quot; 20 20 13 1 &quot; ,
&quot; c None &quot; ,
&quot; . c #B6B6B6 &quot; ,
&quot; + c #6E6E6E &quot; ,
&quot; @ c #000000 &quot; ,
&quot; # c #8EFFFF &quot; ,
&quot; $ c #FFB1B1 &quot; ,
&quot; % c #B1FFFF &quot; ,
&quot; &amp; c #3E3E3E &quot; ,
&quot; * c #DADADA &quot; ,
&quot; = c #F2F2F2 &quot; ,
&quot; - c #FFFFFF &quot; ,
&quot; ; c #CECECE &quot; ,
&quot; &amp; gt; c #E6E6E6 &quot; ,
&quot; .+++++++++. &quot; ,
&quot; +@@@@@@@@@+. &quot; ,
&quot; +@#$%%% &amp; *+ &amp; +. &quot; ,
&quot; +@.$*=- &amp; -*+@+. &quot; ,
&quot; +@#$%%.+++++++++. &quot; ,
&quot; +@.$*=+@@@@@@@@@+. &quot; ,
&quot; +@#$%%+@#$%%% &amp; *+ &amp; +. &quot; ,
&quot; +@.$*=+@.$; &amp; gt; = &amp; -*+@+. &quot; ,
&quot; +@#$%%+@#$%%% &amp; --*@+. &quot; ,
&quot; +@.$*=+@.$; &amp; gt; =++++@+. &quot; ,
&quot; +@#$%%+@#$%%%%%%%@+. &quot; ,
&quot; +@.$*=+@.$; &amp; gt; =---=@+. &quot; ,
&quot; +@#$%%+@#$%%%%%%%@+. &quot; ,
&quot; +@@@@@+@.$; &amp; gt; =---=@+. &quot; ,
&quot; .++++++@#$%%%%%%%@+. &quot; ,
&quot; .....+@.$; &amp; gt; =---=@+. &quot; ,
&quot; +@#$%%%%%%%@+. &quot; ,
&quot; +@@@@@@@@@@@+. &quot; ,
&quot; .+++++++++++.. &quot; ,
&quot; ............ &quot; };
/* XPM */
static const char * editcut_xpm[] = {
&quot; 20 20 14 1 &quot; ,
&quot; c None &quot; ,
&quot; . c #7A7A7A &quot; ,
&quot; + c #AAAAAA &quot; ,
&quot; @ c #C0C0C0 &quot; ,
&quot; # c #4A4A4A &quot; ,
&quot; $ c #000000 &quot; ,
&quot; % c #CECECE &quot; ,
&quot; &amp; c #FFFFFF &quot; ,
&quot; * c #B6B6B6 &quot; ,
&quot; = c #9E9E9E &quot; ,
&quot; - c #E6E6E6 &quot; ,
&quot; ; c #F2F2F2 &quot; ,
&quot; &amp; gt; c #6E6E6E &quot; ,
&quot; , c #DADADA &quot; ,
&quot; ... ...+@ &quot; ,
&quot; .#$$. .$$$.+ &quot; ,
&quot; .$%$$. .$$ &amp; $.+ &quot; ,
&quot; .$* &amp; $$. .$$ &amp; %$.+ &quot; ,
&quot; .$=- &amp; $$. .$$ &amp; %*$.+ &quot; ,
&quot; .$$@- &amp; $$..$$ &amp; %*$$.+ &quot; ,
&quot; .$$@- &amp; $$$$ &amp; %*$$.+ &quot; ,
&quot; .$$@- &amp; .$ &amp; %*$$.+ &quot; ,
&quot; .$$@-;..*$$.+ &quot; ,
&quot; .$$@$ &amp; $$$.+ &quot; ,
&quot; .$$+-%$ &amp; gt; +++ &quot; ,
&quot; ...$..$$%%$...+ &quot; ,
&quot; .$$$$$$.$$$$$$$.+ &quot; ,
&quot; .$$++=$.+.$$=++$$.+ &quot; ,
&quot; +$$+,@,$. +.$,@,+$$+ &quot; ,
&quot; +$$ &amp; @ &amp; ;$. .$+,@ &amp; $$+ &quot; ,
&quot; +$$+ &amp; ;$$+ +$$+ &amp; ;$$+ &quot; ,
&quot; .$$$$$+ +$$$$$. &quot; ,
&quot; .$$$+ +$$$. &quot; ,
&quot; +++ +++ &quot; };
/* XPM */
static const char * close_xpm[] = {
&quot; 20 20 242 2 &quot; ,
&quot; c None &quot; ,
&quot; . c #000000 &quot; ,
&quot; + c #800000 &quot; ,
&quot; @ c #008000 &quot; ,
&quot; # c #808000 &quot; ,
&quot; $ c #000080 &quot; ,
&quot; % c #800080 &quot; ,
&quot; &amp; c #008080 &quot; ,
&quot; * c #C0C0C0 &quot; ,
&quot; = c #C0DCC0 &quot; ,
&quot; - c #A6CAF0 &quot; ,
&quot; ; c #FFF0D4 &quot; ,
&quot; &amp; gt; c #FFE2B1 &quot; ,
&quot; , c #FFD48E &quot; ,
&quot; ' c #FFC66B &quot; ,
&quot; ) c #FFB848 &quot; ,
&quot; ! c #FFAA25 &quot; ,
&quot; ~ c #FFAA00 &quot; ,
&quot; { c #DC9200 &quot; ,
&quot; ] c #B97A00 &quot; ,
&quot; ^ c #966200 &quot; ,
&quot; / c #734A00 &quot; ,
&quot; ( c #503200 &quot; ,
&quot; _ c #FFE3D4 &quot; ,
&quot; : c #FFC7B1 &quot; ,
&quot; &amp; lt; c #FFAB8E &quot; ,
&quot; [ c #FF8F6B &quot; ,
&quot; } c #FF7348 &quot; ,
&quot; | c #FF5725 &quot; ,
&quot; 1 c #FF5500 &quot; ,
&quot; 2 c #DC4900 &quot; ,
&quot; 3 c #B93D00 &quot; ,
&quot; 4 c #963100 &quot; ,
&quot; 5 c #732500 &quot; ,
&quot; 6 c #501900 &quot; ,
&quot; 7 c #FFD4D4 &quot; ,
&quot; 8 c #FFB1B1 &quot; ,
&quot; 9 c #FF8E8E &quot; ,
&quot; 0 c #FF6B6B &quot; ,
&quot; a c #FF4848 &quot; ,
&quot; b c #FF2525 &quot; ,
&quot; c c #FE0000 &quot; ,
&quot; d c #DC0000 &quot; ,
&quot; e c #B90000 &quot; ,
&quot; f c #960000 &quot; ,
&quot; g c #730000 &quot; ,
&quot; h c #500000 &quot; ,
&quot; i c #FFD4E3 &quot; ,
&quot; j c #FFB1C7 &quot; ,
&quot; k c #FF8EAB &quot; ,
&quot; l c #FF6B8F &quot; ,
&quot; m c #FF4873 &quot; ,
&quot; n c #FF2557 &quot; ,
&quot; o c #FF0055 &quot; ,
&quot; p c #DC0049 &quot; ,
&quot; q c #B9003D &quot; ,
&quot; r c #960031 &quot; ,
&quot; s c #730025 &quot; ,
&quot; t c #500019 &quot; ,
&quot; u c #FFD4F0 &quot; ,
&quot; v c #FFB1E2 &quot; ,
&quot; w c #FF8ED4 &quot; ,
&quot; x c #FF6BC6 &quot; ,
&quot; y c #FF48B8 &quot; ,
&quot; z c #FF25AA &quot; ,
&quot; A c #FF00AA &quot; ,
&quot; B c #DC0092 &quot; ,
&quot; C c #B9007A &quot; ,
&quot; D c #960062 &quot; ,
&quot; E c #73004A &quot; ,
&quot; F c #500032 &quot; ,
&quot; G c #FFD4FF &quot; ,
&quot; H c #FFB1FF &quot; ,
&quot; I c #FF8EFF &quot; ,
&quot; J c #FF6BFF &quot; ,
&quot; K c #FF48FF &quot; ,
&quot; L c #FF25FF &quot; ,
&quot; M c #FE00FE &quot; ,
&quot; N c #DC00DC &quot; ,
&quot; O c #B900B9 &quot; ,
&quot; P c #960096 &quot; ,
&quot; Q c #730073 &quot; ,
&quot; R c #500050 &quot; ,
&quot; S c #F0D4FF &quot; ,
&quot; T c #E2B1FF &quot; ,
&quot; U c #D48EFF &quot; ,
&quot; V c #C66BFF &quot; ,
&quot; W c #B848FF &quot; ,
&quot; X c #AA25FF &quot; ,
&quot; Y c #AA00FF &quot; ,
&quot; Z c #9200DC &quot; ,
&quot; ` c #7A00B9 &quot; ,
&quot; . c #620096 &quot; ,
&quot; .. c #4A0073 &quot; ,
&quot; +. c #320050 &quot; ,
&quot; @. c #E3D4FF &quot; ,
&quot; #. c #C7B1FF &quot; ,
&quot; $. c #AB8EFF &quot; ,
&quot; %. c #8F6BFF &quot; ,
&quot; &amp; . c #7348FF &quot; ,
&quot; *. c #5725FF &quot; ,
&quot; =. c #5500FF &quot; ,
&quot; -. c #4900DC &quot; ,
&quot; ;. c #3D00B9 &quot; ,
&quot; &amp; gt; . c #310096 &quot; ,
&quot; ,. c #250073 &quot; ,
&quot; '. c #190050 &quot; ,
&quot; ). c #D4D4FF &quot; ,
&quot; !. c #B1B1FF &quot; ,
&quot; ~. c #8E8EFF &quot; ,
&quot; {. c #6B6BFF &quot; ,
&quot; ]. c #4848FF &quot; ,
&quot; ^. c #2525FF &quot; ,
&quot; /. c #0000FE &quot; ,
&quot; (. c #0000DC &quot; ,
&quot; _. c #0000B9 &quot; ,
&quot; :. c #000096 &quot; ,
&quot; &amp; lt; . c #000073 &quot; ,
&quot; [. c #000050 &quot; ,
&quot; }. c #D4E3FF &quot; ,
&quot; |. c #B1C7FF &quot; ,
&quot; 1. c #8EABFF &quot; ,
&quot; 2. c #6B8FFF &quot; ,
&quot; 3. c #4873FF &quot; ,
&quot; 4. c #2557FF &quot; ,
&quot; 5. c #0055FF &quot; ,
&quot; 6. c #0049DC &quot; ,
&quot; 7. c #003DB9 &quot; ,
&quot; 8. c #003196 &quot; ,
&quot; 9. c #002573 &quot; ,
&quot; 0. c #001950 &quot; ,
&quot; a. c #D4F0FF &quot; ,
&quot; b. c #B1E2FF &quot; ,
&quot; c. c #8ED4FF &quot; ,
&quot; d. c #6BC6FF &quot; ,
&quot; e. c #48B8FF &quot; ,
&quot; f. c #25AAFF &quot; ,
&quot; g. c #00AAFF &quot; ,
&quot; h. c #0092DC &quot; ,
&quot; i. c #007AB9 &quot; ,
&quot; j. c #006296 &quot; ,
&quot; k. c #004A73 &quot; ,
&quot; l. c #003250 &quot; ,
&quot; m. c #D4FFFF &quot; ,
&quot; n. c #B1FFFF &quot; ,
&quot; o. c #8EFFFF &quot; ,
&quot; p. c #6BFFFF &quot; ,
&quot; q. c #48FFFF &quot; ,
&quot; r. c #25FFFF &quot; ,
&quot; s. c #00FEFE &quot; ,
&quot; t. c #00DCDC &quot; ,
&quot; u. c #00B9B9 &quot; ,
&quot; v. c #009696 &quot; ,
&quot; w. c #007373 &quot; ,
&quot; x. c #005050 &quot; ,
&quot; y. c #D4FFF0 &quot; ,
&quot; z. c #B1FFE2 &quot; ,
&quot; A. c #8EFFD4 &quot; ,
&quot; B. c #6BFFC6 &quot; ,
&quot; C. c #48FFB8 &quot; ,
&quot; D. c #25FFAA &quot; ,
&quot; E. c #00FFAA &quot; ,
&quot; F. c #00DC92 &quot; ,
&quot; G. c #00B97A &quot; ,
&quot; H. c #009662 &quot; ,
&quot; I. c #00734A &quot; ,
&quot; J. c #005032 &quot; ,
&quot; K. c #D4FFE3 &quot; ,
&quot; L. c #B1FFC7 &quot; ,
&quot; M. c #8EFFAB &quot; ,
&quot; N. c #6BFF8F &quot; ,
&quot; O. c #48FF73 &quot; ,
&quot; P. c #25FF57 &quot; ,
&quot; Q. c #00FF55 &quot; ,
&quot; R. c #00DC49 &quot; ,
&quot; S. c #00B93D &quot; ,
&quot; T. c #009631 &quot; ,
&quot; U. c #007325 &quot; ,
&quot; V. c #005019 &quot; ,
&quot; W. c #D4FFD4 &quot; ,
&quot; X. c #B1FFB1 &quot; ,
&quot; Y. c #8EFF8E &quot; ,
&quot; Z. c #6BFF6B &quot; ,
&quot; `. c #48FF48 &quot; ,
&quot; + c #25FF25 &quot; ,
&quot; .+ c #00FE00 &quot; ,
&quot; ++ c #00DC00 &quot; ,
&quot; @+ c #00B900 &quot; ,
&quot; #+ c #009600 &quot; ,
&quot; $+ c #007300 &quot; ,
&quot; %+ c #005000 &quot; ,
&quot; &amp; + c #E3FFD4 &quot; ,
&quot; *+ c #C7FFB1 &quot; ,
&quot; =+ c #ABFF8E &quot; ,
&quot; -+ c #8FFF6B &quot; ,
&quot; ;+ c #73FF48 &quot; ,
&quot; &amp; gt; + c #57FF25 &quot; ,
&quot; ,+ c #55FF00 &quot; ,
&quot; '+ c #49DC00 &quot; ,
&quot; )+ c #3DB900 &quot; ,
&quot; !+ c #319600 &quot; ,
&quot; ~+ c #257300 &quot; ,
&quot; {+ c #195000 &quot; ,
&quot; ]+ c #F0FFD4 &quot; ,
&quot; ^+ c #E2FFB1 &quot; ,
&quot; /+ c #D4FF8E &quot; ,
&quot; (+ c #C6FF6B &quot; ,
&quot; _+ c #B8FF48 &quot; ,
&quot; :+ c #AAFF25 &quot; ,
&quot; &amp; lt; + c #AAFF00 &quot; ,
&quot; [+ c #92DC00 &quot; ,
&quot; }+ c #7AB900 &quot; ,
&quot; |+ c #629600 &quot; ,
&quot; 1+ c #4A7300 &quot; ,
&quot; 2+ c #325000 &quot; ,
&quot; 3+ c #FFFFD4 &quot; ,
&quot; 4+ c #FFFFB1 &quot; ,
&quot; 5+ c #FFFF8E &quot; ,
&quot; 6+ c #FFFF6B &quot; ,
&quot; 7+ c #FFFF48 &quot; ,
&quot; 8+ c #FFFF25 &quot; ,
&quot; 9+ c #FEFE00 &quot; ,
&quot; 0+ c #DCDC00 &quot; ,
&quot; a+ c #B9B900 &quot; ,
&quot; b+ c #969600 &quot; ,
&quot; c+ c #737300 &quot; ,
&quot; d+ c #505000 &quot; ,
&quot; e+ c #F2F2F2 &quot; ,
&quot; f+ c #E6E6E6 &quot; ,
&quot; g+ c #DADADA &quot; ,
&quot; h+ c #CECECE &quot; ,
&quot; i+ c #C2C2C2 &quot; ,
&quot; j+ c #B6B6B6 &quot; ,
&quot; k+ c #AAAAAA &quot; ,
&quot; l+ c #9E9E9E &quot; ,
&quot; m+ c #929292 &quot; ,
&quot; n+ c #868686 &quot; ,
&quot; o+ c #7A7A7A &quot; ,
&quot; p+ c #6E6E6E &quot; ,
&quot; q+ c #626262 &quot; ,
&quot; r+ c #565656 &quot; ,
&quot; s+ c #4A4A4A &quot; ,
&quot; &quot; ,
&quot; . . . s+. . &quot; ,
&quot; . . l . . s+. l . . &quot; ,
&quot; . . l p l . . s+. l p l . . &quot; ,
&quot; . l p p p l . . s+. l p p p r . &quot; ,
&quot; . . r p p p l . q+q+. l p p p r . . &quot; ,
&quot; . . r p p p l . . l p p p r . . &quot; ,
&quot; . . r p p p l l p p p r . . &quot; ,
&quot; . . r p p p p p p r . . &quot; ,
&quot; q+. r p p p p r . q+ &quot; ,
&quot; q+. l p p p p l . q+ &quot; ,
&quot; . . l p p p p p p l . . &quot; ,
&quot; . . l p p p r r p p p l . . &quot; ,
&quot; . . l p p p r . . r p p p l . . &quot; ,
&quot; . . l p p p r . q+q+. r p p p l . . &quot; ,
&quot; . p p p p r . . s+. r p p p p . &quot; ,
&quot; . . r p r . . s+. r p r . . &quot; ,
&quot; . . r . . s+. r . . &quot; ,
&quot; . . . s+. . &quot; ,
&quot; &quot; };
#if 0
/* XPM */
static const char * DocumentIn_xpm[] = {
&quot; 20 20 17 1 &quot; ,
&quot; c None &quot; ,
&quot; . c #B6B6B6 &quot; ,
&quot; + c #626262 &quot; ,
&quot; @ c #000000 &quot; ,
&quot; # c #B1FFFF &quot; ,
&quot; $ c #FFB1B1 &quot; ,
&quot; % c #CECECE &quot; ,
&quot; &amp; c #7A7A7A &quot; ,
&quot; * c #E6E6E6 &quot; ,
&quot; = c #FFFFFF &quot; ,
&quot; - c #868686 &quot; ,
&quot; ; c #007373 &quot; ,
&quot; &amp; gt; c #6E6E6E &quot; ,
&quot; , c #48B8FF &quot; ,
&quot; ' c #8ED4FF &quot; ,
&quot; ) c #0092DC &quot; ,
&quot; ! c #DADADA &quot; ,
&quot; .+++++++++++. &quot; ,
&quot; +@@@@@@@@@@@+. &quot; ,
&quot; +@#$####%@% &amp; @+. &quot; ,
&quot; +@.$%***%@=% &amp; @+. &quot; ,
&quot; +@#$####%@==% &amp; @+. &quot; ,
&quot; +@.$%**=%@===%@+. &quot; ,
&quot; +@#$####%@@@@@@+. &quot; ,
&quot; +@.$%**==%%%%%@+. &quot; ,
&quot; +@#-;#########@+. &quot; ,
&quot; +@.@@ &amp; gt; *====***@+. &quot; ,
&quot; ---@-@,@;#######@+. &quot; ,
&quot; @@@@@@,,@ &amp; gt; ====**@+. &quot; ,
&quot; @',,,,,,,@;#####@+. &quot; ,
&quot; @))))),,)@ &amp; gt; ====*@+. &quot; ,
&quot; @@@@@@,)@;######@+. &quot; ,
&quot; ---@+@)@ &amp; gt; ****===@+. &quot; ,
&quot; +@#@@;########@+. &quot; ,
&quot; +@.--%!!!!****@+. &quot; ,
&quot; +@@@@@@@@@@@@@@+. &quot; ,
&quot; .++++++++++++++. &quot; };
#endif
#if 0
/* XPM */
static const char * Forward_xpm[] = {
&quot; 20 20 22 1 &quot; ,
&quot; c None &quot; ,
&quot; . c #AAAAAA &quot; ,
&quot; + c #626262 &quot; ,
&quot; @ c #3E3E3E &quot; ,
&quot; # c #000000 &quot; ,
&quot; $ c #626200 &quot; ,
&quot; % c #937A00 &quot; ,
&quot; &amp; c #B6B6B6 &quot; ,
&quot; * c #AF9200 &quot; ,
&quot; = c #FFF0D4 &quot; ,
&quot; - c #DFD48E &quot; ,
&quot; ; c #FFFFFF &quot; ,
&quot; &amp; gt; c #C3B848 &quot; ,
&quot; , c #BDAA25 &quot; ,
&quot; ' c #9E9E9E &quot; ,
&quot; ) c #F2F2F2 &quot; ,
&quot; ! c #DADADA &quot; ,
&quot; ~ c #48B8FF &quot; ,
&quot; { c #565656 &quot; ,
&quot; ] c #323200 &quot; ,
&quot; ^ c #8ED4FF &quot; ,
&quot; / c #0092DC &quot; ,
&quot; .+@#@+. &quot; ,
&quot; .@#$%$#@. &quot; ,
&quot; &amp; +#*=--%#+ &amp; &quot; ,
&quot; &amp; @$=;- &amp; gt; ,$@ &amp; &quot; ,
&quot; &amp; #%--- &amp; gt; ,%# &amp; &quot; ,
&quot; &amp; @$- &amp; gt; &amp; gt; ,*$@ &amp; &quot; ,
&quot; +#%,,*%#+ &quot; ,
&quot; '+#$%$#+' &quot; ,
&quot; +####@#@####+ &quot; ,
&quot; @@+#)))))!!!!#+ &quot; ,
&quot; ##@#!.))!!!.!#+ &quot; ,
&quot; +++++#~##.{)!!!!{!#+ &quot; ,
&quot; ######~~#@]]]]]]]!#+ &quot; ,
&quot; #^~~~~~~~#]*%%%%]!#+ &quot; ,
&quot; #/////~~/##*%]*%###+ &quot; ,
&quot; ######~/#@#*%]*%#++ &amp; &quot; ,
&quot; +++++#/#@+#*%#*%#+ &quot; ,
&quot; ##@ +#*%#*%#+ &quot; ,
&quot; @@ +#$$#$$#+ &quot; ,
&quot; +#######+ &quot; };
#endif
#if 0
/* XPM */
static const char * Help_xpm[] = {
&quot; 20 20 20 1 &quot; ,
&quot; c None &quot; ,
&quot; . c #B6B6B6 &quot; ,
&quot; + c #626262 &quot; ,
&quot; @ c #000000 &quot; ,
&quot; # c #505000 &quot; ,
&quot; $ c #FFAA25 &quot; ,
&quot; % c #FFC66B &quot; ,
&quot; &amp; c #FFE2B1 &quot; ,
&quot; * c #FFFFFF &quot; ,
&quot; = c #FFFF6B &quot; ,
&quot; - c #B9B900 &quot; ,
&quot; ; c #969600 &quot; ,
&quot; &amp; gt; c #3E3E3E &quot; ,
&quot; , c #808000 &quot; ,
&quot; ' c #FEFE00 &quot; ,
&quot; ) c #1A1A1A &quot; ,
&quot; ! c #DCDC00 &quot; ,
&quot; ~ c #323232 &quot; ,
&quot; { c #262626 &quot; ,
&quot; ] c #6E6E6E &quot; ,
&quot; .++++++++++++++++. &quot; ,
&quot; .+@@@@@@@@@@@@@@@@+. &quot; ,
&quot; +@#$%%%%%%%%%%%%$#@+ &quot; ,
&quot; +@$% &amp; &amp; &amp; &amp; &amp; &amp; &amp; &amp; &amp; &amp; &amp; &amp; &amp; $@+ &quot; ,
&quot; +@% &amp; **=-;+ &amp; gt; ,-=== &amp; %@+ &quot; ,
&quot; +@% &amp; *=' &amp; gt; ,=+@)!== &amp; %@+ &quot; ,
&quot; +@% &amp; *=!@~=!@@-== &amp; %@+ &quot; ,
&quot; +@% &amp; *==~+=!@@-== &amp; %@+ &quot; ,
&quot; +@% &amp; *=====,@ &amp; gt; !== &amp; %@+ &quot; ,
&quot; +@% &amp; *====={+!=== &amp; %@+ &quot; ,
&quot; +@% &amp; =====]-===== &amp; %@+ &quot; ,
&quot; +@% &amp; ====! &amp; gt; ;===== &amp; %@+ &quot; ,
&quot; +@% &amp; ====+@@===== &amp; %@+ &quot; ,
&quot; +@% &amp; ====;@ &amp; gt; ===== &amp; %@+ &quot; ,
&quot; +@$%========== &amp; &amp; %$@+ &quot; ,
&quot; +@#$ &amp; = &amp; &amp; %%%%%%%%$#@+ &quot; ,
&quot; +@@ &amp; &amp; &amp; %$@@@@@@@@@+. &quot; ,
&quot; +@%%$@@ &amp; gt; ++++++++. &quot; ,
&quot; +@$@@ &amp; gt; + &quot; ,
&quot; +@@@+. &quot; };
#endif
#if 0
/* XPM */
static const char * Left_xpm[] = {
&quot; 20 20 11 1 &quot; ,
&quot; c None &quot; ,
&quot; . c #B6B6B6 &quot; ,
&quot; + c #626262 &quot; ,
&quot; @ c #000000 &quot; ,
&quot; # c #8ED4FF &quot; ,
&quot; $ c #B1E2FF &quot; ,
&quot; % c #48B8FF &quot; ,
&quot; &amp; c #FFFFFF &quot; ,
&quot; * c #25AAFF &quot; ,
&quot; = c #0092DC &quot; ,
&quot; - c #007AB9 &quot; ,
&quot; &quot; ,
&quot; &quot; ,
&quot; .. &quot; ,
&quot; .++. &quot; ,
&quot; .+@@+. &quot; ,
&quot; .+@#@+.......... &quot; ,
&quot; .+@#$@+++++++++++. &quot; ,
&quot; .+@#$%@@@@@@@@@@@@+ &quot; ,
&quot; .+@# &amp; %%%#########*@+ &quot; ,
&quot; +@# &amp; %%%%%%%%%%%%%=@+ &quot; ,
&quot; +@-*%%%%%%%%%%%%%=@+ &quot; ,
&quot; .+@-*%*===========@+ &quot; ,
&quot; .+@-**@@@@@@@@@@@@+ &quot; ,
&quot; .+@-*@+++++++++++. &quot; ,
&quot; .+@-@+.......... &quot; ,
&quot; .+@@+. &quot; ,
&quot; .++. &quot; ,
&quot; .. &quot; ,
&quot; &quot; ,
&quot; &quot; };
#endif
/* XPM */
static const char * search_xpm[] = {
&quot; 20 20 21 1 &quot; ,
&quot; c None &quot; ,
&quot; . c #AAAAAA &quot; ,
&quot; + c #7A7A7A &quot; ,
&quot; @ c #626262 &quot; ,
&quot; # c #929292 &quot; ,
&quot; $ c #4A4A4A &quot; ,
&quot; % c #000000 &quot; ,
&quot; &amp; c #6E6E6E &quot; ,
&quot; * c #B6B6B6 &quot; ,
&quot; = c #DADADA &quot; ,
&quot; - c #D4D4FF &quot; ,
&quot; ; c #FFFFFF &quot; ,
&quot; &amp; gt; c #B1B1FF &quot; ,
&quot; , c #C7B1FF &quot; ,
&quot; ' c #3E3E3E &quot; ,
&quot; ) c #4A4A00 &quot; ,
&quot; ! c #626200 &quot; ,
&quot; ~ c #AF9200 &quot; ,
&quot; { c #937A00 &quot; ,
&quot; ] c #F8E2B1 &quot; ,
&quot; ^ c #323200 &quot; ,
&quot; .+@@@@+. &quot; ,
&quot; #@$%%%%$@# &quot; ,
&quot; #$% &amp; *==* &amp; %$# &quot; ,
&quot; .@%*=----=*%@. &quot; ,
&quot; +$ &amp; =-; &amp; gt; &amp; gt; --= &amp; $+ &quot; ,
&quot; @%*-;;,, &amp; gt; --*%@ &quot; ,
&quot; @%=- &amp; gt; ,,,, &amp; gt; -=%@ &quot; ,
&quot; @%=- &amp; gt; ,,,, &amp; gt; -=%@ &quot; ,
&quot; @%*-- &amp; gt; ,, &amp; gt; --*%@ &quot; ,
&quot; +$ &amp; =-- &amp; gt; &amp; gt; --= &amp; '+ &quot; ,
&quot; .@%*=----=*%%' &quot; ,
&quot; #$% &amp; *==* &amp; %$)%' &quot; ,
&quot; #@$%%%%'%!~{%' &quot; ,
&quot; .+@@@@+'%~]{%' &quot; ,
&quot; '%~]{%' &quot; ,
&quot; '%~]{%' &quot; ,
&quot; '%~]{%' &quot; ,
&quot; '%~]!% &quot; ,
&quot; '%!^' &quot; ,
&quot; '%'# &quot; };
/* XPM */
static const char * filenew_xpm[] = {
&quot; 20 20 16 1 &quot; ,
&quot; c None &quot; ,
&quot; . c #B6B6B6 &quot; ,
&quot; + c #626262 &quot; ,
&quot; @ c #DC9200 &quot; ,
&quot; # c #000000 &quot; ,
&quot; $ c #FFC66B &quot; ,
&quot; % c #FFFF00 &quot; ,
&quot; &amp; c #B1FFFF &quot; ,
&quot; * c #CECECE &quot; ,
&quot; = c #7A7A7A &quot; ,
&quot; - c #FFAA00 &quot; ,
&quot; ; c #DCDC00 &quot; ,
&quot; &amp; gt; c #E6E6E6 &quot; ,
&quot; , c #FFFFFF &quot; ,
&quot; ' c #DADADA &quot; ,
&quot; ) c #FFB1B1 &quot; ,
&quot; .++@++++++++. &quot; ,
&quot; +#@$@#######+. &quot; ,
&quot; +@$%$@ &amp; &amp; *#*=#+. &quot; ,
&quot; @-;%;-@ &amp; gt; *#,*=#+. &quot; ,
&quot; @-;;,;;-@*#,,*=#+. &quot; ,
&quot; $%%%,,%%%%$#,,,*#+. &quot; ,
&quot; @-;;%;;-@*######+. &quot; ,
&quot; @-;%;-@,,*****#+. &quot; ,
&quot; +@$%$@ &amp; &amp; &amp; &amp; &amp; &amp; &amp; &amp; #+. &quot; ,
&quot; +#-%- &amp; gt; &amp; gt; ,,,, &amp; gt; &amp; gt; &amp; gt; #+. &quot; ,
&quot; +#-%- &amp; &amp; &amp; &amp; &amp; &amp; &amp; &amp; &amp; #+. &quot; ,
&quot; +#-%-' &amp; gt; ,,,,, &amp; gt; &amp; gt; #+. &quot; ,
&quot; +#@$@ &amp; &amp; &amp; &amp; &amp; &amp; &amp; &amp; &amp; #+. &quot; ,
&quot; +#.@*' &amp; gt; &amp; gt; ,,,,, &amp; gt; #+. &quot; ,
&quot; +# &amp; ) &amp; &amp; &amp; &amp; &amp; &amp; &amp; &amp; &amp; &amp; #+. &quot; ,
&quot; +#.)**' &amp; gt; &amp; gt; &amp; gt; &amp; gt; ,,,#+. &quot; ,
&quot; +# &amp; ) &amp; &amp; &amp; &amp; &amp; &amp; &amp; &amp; &amp; &amp; #+. &quot; ,
&quot; +#.)**'''' &amp; gt; &amp; gt; &amp; gt; &amp; gt; #+. &quot; ,
&quot; +##############+. &quot; ,
&quot; .++++++++++++++. &quot; };
/* XPM */
static const char * fileopen_xpm[] = {
&quot; 20 20 15 1 &quot; ,
&quot; c None &quot; ,
&quot; . c #B6B6B6 &quot; ,
&quot; + c #868686 &quot; ,
&quot; @ c #6E6E6E &quot; ,
&quot; # c #000000 &quot; ,
&quot; $ c #626262 &quot; ,
&quot; % c #D1C96B &quot; ,
&quot; &amp; c #FFF0D4 &quot; ,
&quot; * c #AF9200 &quot; ,
&quot; = c #C3B848 &quot; ,
&quot; - c #DFD48E &quot; ,
&quot; ; c #929292 &quot; ,
&quot; &amp; gt; c #937A00 &quot; ,
&quot; , c #BDAA25 &quot; ,
&quot; ' c #626200 &quot; ,
&quot; &quot; ,
&quot; &quot; ,
&quot; .+@@@@@+. &quot; ,
&quot; .+@#####$+.. &quot; ,
&quot; .@#% &amp; &amp; &amp; &amp; #$@@@@@@@@@. &quot; ,
&quot; .@# &amp; %%%%*##########@ &quot; ,
&quot; .@# &amp; ==%%%--------*#@ &quot; ,
&quot; .@# &amp; ===%%%%%%%%%%*#@ &quot; ,
&quot; ;@# &amp; === &amp; gt; &amp; gt; &amp; gt; &amp; gt; &amp; gt; &amp; gt; &amp; gt; &amp; gt; &amp; gt; =*#@ &quot; ,
&quot; @## &amp; gt; &amp; gt; &amp; gt; &amp; gt; &amp; &amp; &amp; &amp; &amp; &amp; &amp; &amp; &amp; gt; =*#@ &quot; ,
&quot; # &amp; &amp; &amp; &amp; &amp; ========= &amp; gt; * &amp; gt; #@ &quot; ,
&quot; #,=============* &amp; gt; &amp; gt; #@ &quot; ,
&quot; # &amp; gt; ============== &amp; gt; &amp; gt; #@ &quot; ,
&quot; @#,============= &amp; gt; &amp; gt; #@ &quot; ,
&quot; ;# &amp; gt; =============* &amp; gt; #@ &quot; ,
&quot; .@#**************'#@ &quot; ,
&quot; .;#################@ &quot; ,
&quot; .@@@@@@@@@@@@@@@@@. &quot; ,
&quot; ................. &quot; ,
&quot; &quot; };
/* XPM */
static const char * editpaste_xpm[] = {
&quot; 20 20 18 1 &quot; ,
&quot; c None &quot; ,
&quot; . c #B6B6B6 &quot; ,
&quot; + c #000000 &quot; ,
&quot; @ c #626262 &quot; ,
&quot; # c #FFFFFF &quot; ,
&quot; $ c #DADADA &quot; ,
&quot; % c #E6E6E6 &quot; ,
&quot; &amp; c #B97A00 &quot; ,
&quot; * c #7A7A7A &quot; ,
&quot; = c #966200 &quot; ,
&quot; - c #734A00 &quot; ,
&quot; ; c #6E6E6E &quot; ,
&quot; &amp; gt; c #8EFFFF &quot; ,
&quot; , c #FFB1B1 &quot; ,
&quot; ' c #B1FFFF &quot; ,
&quot; ) c #3E3E3E &quot; ,
&quot; ! c #CECECE &quot; ,
&quot; ~ c #F2F2F2 &quot; ,
&quot; ....++++++.... &quot; ,
&quot; .@@@+##@@$$+@@@. &quot; ,
&quot; .@+++%.......+++@. &quot; ,
&quot; .@+ &amp; +#.******+ &amp; +@. &quot; ,
&quot; .@+ &amp; =++++++++-=+@. &quot; ,
&quot; .@+ &amp; ==--------=+@. &quot; ,
&quot; .@+ &amp; ==-+++++++++;. &quot; ,
&quot; .@+ &amp; ==-+ &amp; gt; ,''')$;);. &quot; ,
&quot; .@+ &amp; ==-+.,!%~)#$;+@ &quot; ,
&quot; .@+ &amp; ==-+ &amp; gt; ,''')##$+@ &quot; ,
&quot; .@+ &amp; ==-+.,!%~;;;;+@ &quot; ,
&quot; .@+ &amp; ==-+ &amp; gt; ,'''''''+@ &quot; ,
&quot; .@+ &amp; ==-+.,!%~###~+@ &quot; ,
&quot; .@+ &amp; ==-+ &amp; gt; ,'''''''+@ &quot; ,
&quot; .@+ &amp; ==-+.,!%~###~+@ &quot; ,
&quot; .@+ &amp; ==-+ &amp; gt; ,'''''''+@ &quot; ,
&quot; .@+ &amp; ===+.,!%~###~+@ &quot; ,
&quot; .@++++++ &amp; gt; ,'''''''+@ &quot; ,
&quot; .@@@@@+++++++++++@ &quot; ,
&quot; .....@@@@@@@@@@@. &quot; };
#if 0
/* XPM */
static const char * Print_xpm[] = {
&quot; 20 20 25 1 &quot; ,
&quot; c None &quot; ,
&quot; . c #B6B6B6 &quot; ,
&quot; + c #626262 &quot; ,
&quot; @ c #000000 &quot; ,
&quot; # c #323232 &quot; ,
&quot; $ c #AAAAAA &quot; ,
&quot; % c #FFC7B1 &quot; ,
&quot; &amp; c #CECECE &quot; ,
&quot; * c #E6E6E6 &quot; ,
&quot; = c #FFFFFF &quot; ,
&quot; - c #8EFFFF &quot; ,
&quot; ; c #6E6E6E &quot; ,
&quot; &amp; gt; c #00DCDC &quot; ,
&quot; , c #C2C2C2 &quot; ,
&quot; ' c #4A4A00 &quot; ,
&quot; ) c #00B9B9 &quot; ,
&quot; ! c #FFAB8E &quot; ,
&quot; ~ c #937A00 &quot; ,
&quot; { c #F8E2B1 &quot; ,
&quot; ] c #C3B848 &quot; ,
&quot; ^ c #C5AA00 &quot; ,
&quot; / c #AF9200 &quot; ,
&quot; ( c #DFD48E &quot; ,
&quot; _ c #D1C96B &quot; ,
&quot; : c #626200 &quot; ,
&quot; .+@@@@@@@@@#. &quot; ,
&quot; .@$% &amp; **====@+. &quot; ,
&quot; .+@-%-------@;. &quot; ,
&quot; ..@$% &amp; ***===@#. &quot; ,
&quot; .++@ &amp; gt; % &amp; gt; &amp; gt; &amp; gt; &amp; gt; &amp; gt; --@#.. &quot; ,
&quot; .+@@$%,,, &amp; ***@'@@; &quot; ,
&quot; .+@+@)!))) &amp; gt; &amp; gt; &amp; gt; &amp; gt; @'~~@ &quot; ,
&quot; .+@+{''''''''''']=^@ &quot; ,
&quot; +@+{]]]]]]]]]]]]=^/@ &quot; ,
&quot; +@==============^{/@ &quot; ,
&quot; +@{{{{{{{{{{{((^{(/@ &quot; ,
&quot; +@{{_____(((::(^((/@ &quot; ,
&quot; +@{_____(((((~(^(//@ &quot; ,
&quot; +@________(((((^/]~@ &quot; ,
&quot; +@~~~~~~~~~~~~~~]]@# &quot; ,
&quot; +@+]]]]]]]]]]]^~]@#. &quot; ,
&quot; .+@+^^^^^^^^^^~]@#. &quot; ,
&quot; .+@@@@@@@@@@@@@#. &quot; ,
&quot; .+++++++++++++. &quot; ,
&quot; ............. &quot; };
#endif
/* XPM */
static const char * redo_xpm[] = {
&quot; 20 20 12 1 &quot; ,
&quot; c None &quot; ,
&quot; . c #B6B6B6 &quot; ,
&quot; + c #626262 &quot; ,
&quot; @ c #4A4A4A &quot; ,
&quot; # c #000000 &quot; ,
&quot; $ c #00B900 &quot; ,
&quot; % c #9E9E9E &quot; ,
&quot; &amp; c #7A7A7A &quot; ,
&quot; * c #00AB3D &quot; ,
&quot; = c #005000 &quot; ,
&quot; - c #009631 &quot; ,
&quot; ; c #007325 &quot; ,
&quot; &quot; ,
&quot; &quot; ,
&quot; &quot; ,
&quot; .+@. &quot; ,
&quot; .+##@. &quot; ,
&quot; .......+#$#@. &quot; ,
&quot; %% &amp; ++++++#*$#@. &quot; ,
&quot; % &amp; #########**$#@. &quot; ,
&quot; % &amp; #=-*$$$$$$*-*$#@. &quot; ,
&quot; . &amp; #=------------*$#@ &quot; ,
&quot; %#=--------------=#+ &quot; ,
&quot; &amp; #;----======---=#+. &quot; ,
&quot; #=----=######--=#+. &quot; ,
&quot; #=---;#%%%%+#-=#+. &quot; ,
&quot; #=---;#% +#=#+. &quot; ,
&quot; #=---;#% +##+. &quot; ,
&quot; +######% .++. &quot; ,
&quot; %++++++% &quot; ,
&quot; &quot; ,
&quot; &quot; };
/* XPM */
static const char * filesave_xpm[] = {
&quot; 20 20 16 1 &quot; ,
&quot; c None &quot; ,
&quot; . c #6E6E6E &quot; ,
&quot; + c #4A4A4A &quot; ,
&quot; @ c #000000 &quot; ,
&quot; # c #7A7A7A &quot; ,
&quot; $ c #929292 &quot; ,
&quot; % c #9E9E9E &quot; ,
&quot; &amp; c #B6B6B6 &quot; ,
&quot; * c #C2C2C2 &quot; ,
&quot; = c #AAAAAA &quot; ,
&quot; - c #565656 &quot; ,
&quot; ; c #626262 &quot; ,
&quot; &amp; gt; c #FFFFFF &quot; ,
&quot; , c #DADADA &quot; ,
&quot; ' c #3E3E3E &quot; ,
&quot; ) c #CECECE &quot; ,
&quot; .++..............++. &quot; ,
&quot; +++@@@@@@@@@@@@@@+++ &quot; ,
&quot; ++#$............%#++ &quot; ,
&quot; +@#$............%#@+ &quot; ,
&quot; +@#$............%#@+ &quot; ,
&quot; +@#$............ &amp; #@+ &quot; ,
&quot; +@#$............*#@+ &quot; ,
&quot; +@#$............*#@+ &quot; ,
&quot; +@#$............ &amp; #@+ &quot; ,
&quot; +@##$$$$$== &amp; &amp; &amp; * &amp; ##@+ &quot; ,
&quot; +@################@+ &quot; ,
&quot; +@##--------;;;;##@+ &quot; ,
&quot; +@#- &amp; gt; &amp; gt; ,,,,,,*'-;%#@+ &quot; ,
&quot; +@#- &amp; gt; ;-' &amp; gt; )*),'-;%#@+ &quot; ,
&quot; +@#-,;-' &amp; gt; *)*,'-;%#@+ &quot; ,
&quot; +@#-,;-' &amp; gt; )*),'-;%#@+ &quot; ,
&quot; +@#-,;-' &amp; gt; *)*,'-;%#@+ &quot; ,
&quot; +@+-,===****,'-;%#@+ &quot; ,
&quot; =+@@@@@@@@@@@@@@@@@+ &quot; ,
&quot; =+++++++++++++++++. &quot; };
#if 0
/* XPM */
static const char * filesave_all_xpm[] = {
&quot; 20 20 13 1 &quot; ,
&quot; c None &quot; ,
&quot; . c #6E6E6E &quot; ,
&quot; + c #4A4A4A &quot; ,
&quot; @ c #000000 &quot; ,
&quot; # c #B6B6B6 &quot; ,
&quot; $ c #CECECE &quot; ,
&quot; % c #929292 &quot; ,
&quot; &amp; c #7A7A7A &quot; ,
&quot; * c #FFFFFF &quot; ,
&quot; = c #F2F2F2 &quot; ,
&quot; - c #565656 &quot; ,
&quot; ; c #DADADA &quot; ,
&quot; &amp; gt; c #C2C2C2 &quot; ,
&quot; .++.........++. &quot; ,
&quot; +++@@@@@@@@@+++# &quot; ,
&quot; ++$.........$++# &quot; ,
&quot; +@%.........#@+# &quot; ,
&quot; .++.........++..#@+# &quot; ,
&quot; +++@@@@@@@@@+++.$@+# &quot; ,
&quot; ++$.........$++$ &amp; @+# &quot; ,
&quot; +@%.........#@+ &amp; &amp; @+# &quot; ,
&quot; +@%.........#@+% &amp; @+# &quot; ,
&quot; +@%.........$@+. &amp; @+# &quot; ,
&quot; +@ &amp; %%%%%###$ &amp; @+. &amp; @+# &quot; ,
&quot; +@ &amp; &amp; &amp; &amp; &amp; &amp; &amp; &amp; &amp; &amp; &amp; @+. &amp; @+# &quot; ,
&quot; +@ &amp; &amp; ......%% &amp; @+. &amp; @+# &quot; ,
&quot; +@ &amp; .***===-. &amp; @+@@@+# &quot; ,
&quot; +@ &amp; .;.- &amp; gt; &amp; gt; ;-. &amp; @++++.# &quot; ,
&quot; +@ &amp; .;-@ &amp; gt; &amp; gt; ;-. &amp; @+#### &quot; ,
&quot; +@+.; &amp; &amp; &amp; gt; &amp; gt; ;-. &amp; @+# &quot; ,
&quot; #+@@@@@@@@@@@@+# &quot; ,
&quot; #++++++++++++.# &quot; ,
&quot; ############# &quot; };
#endif
/* XPM */
static const char * undo_xpm[] = {
&quot; 20 20 16 1 &quot; ,
&quot; c None &quot; ,
&quot; . c #B6B6B6 &quot; ,
&quot; + c #4A4A4A &quot; ,
&quot; @ c #626262 &quot; ,
&quot; # c #000000 &quot; ,
&quot; $ c #FF6B8F &quot; ,
&quot; % c #FFB1C7 &quot; ,
&quot; &amp; c #7A7A7A &quot; ,
&quot; * c #9E9E9E &quot; ,
&quot; = c #DC0049 &quot; ,
&quot; - c #FFFFFF &quot; ,
&quot; ; c #FF0055 &quot; ,
&quot; &amp; gt; c #B9003D &quot; ,
&quot; , c #960031 &quot; ,
&quot; ' c #B90000 &quot; ,
&quot; ) c #501900 &quot; ,
&quot; &quot; ,
&quot; &quot; ,
&quot; &quot; ,
&quot; .+@. &quot; ,
&quot; .+##@. &quot; ,
&quot; .+#$#@....... &quot; ,
&quot; .+#$%#@@@@@@ &amp; ** &quot; ,
&quot; .+#$%=######### &amp; * &quot; ,
&quot; .+#$-==;;;;;;= &amp; gt; ,# &amp; * &quot; ,
&quot; +#$-============,# &amp; . &quot; ,
&quot; @#,$=============,#* &quot; ,
&quot; .@#,'=',,,,,,==== &amp; gt; # &amp; &quot; ,
&quot; .@#,''######,====)# &quot; ,
&quot; .@#,'#@****# &amp; gt; ===)# &quot; ,
&quot; .@#,#@ *# &amp; gt; ===)# &quot; ,
&quot; .@##@ *# &amp; gt; ===)# &quot; ,
&quot; .@@. *######@ &quot; ,
&quot; *@@@@@@* &quot; ,
&quot; &quot; ,
&quot; &quot; };
/* XPM */
static const char * replace_xpm[] = {
&quot; 20 20 257 2 &quot; ,
&quot; c None &quot; ,
&quot; . c #000000 &quot; ,
&quot; + c #800000 &quot; ,
&quot; @ c #008000 &quot; ,
&quot; # c #808000 &quot; ,
&quot; $ c #000080 &quot; ,
&quot; % c #800080 &quot; ,
&quot; &amp; c #008080 &quot; ,
&quot; * c #C0C0C0 &quot; ,
&quot; = c #C0DCC0 &quot; ,
&quot; - c #A6CAF0 &quot; ,
&quot; ; c #FFF0D4 &quot; ,
&quot; &amp; gt; c #F8E2B1 &quot; ,
&quot; , c #DFD48E &quot; ,
&quot; ' c #D1C96B &quot; ,
&quot; ) c #C3B848 &quot; ,
&quot; ! c #BDAA25 &quot; ,
&quot; ~ c #C5AA00 &quot; ,
&quot; { c #AF9200 &quot; ,
&quot; ] c #937A00 &quot; ,
&quot; ^ c #626200 &quot; ,
&quot; / c #4A4A00 &quot; ,
&quot; ( c #323200 &quot; ,
&quot; _ c #FFE3D4 &quot; ,
&quot; : c #FFC7B1 &quot; ,
&quot; &amp; lt; c #FFAB8E &quot; ,
&quot; [ c #FF8F6B &quot; ,
&quot; } c #FF7348 &quot; ,
&quot; | c #FF5725 &quot; ,
&quot; 1 c #FF5500 &quot; ,
&quot; 2 c #DC4900 &quot; ,
&quot; 3 c #B93D00 &quot; ,
&quot; 4 c #963100 &quot; ,
&quot; 5 c #732500 &quot; ,
&quot; 6 c #501900 &quot; ,
&quot; 7 c #FFD4D4 &quot; ,
&quot; 8 c #FFB1B1 &quot; ,
&quot; 9 c #FF8E8E &quot; ,
&quot; 0 c #FF6B6B &quot; ,
&quot; a c #FF4848 &quot; ,
&quot; b c #FF2525 &quot; ,
&quot; c c #FE0000 &quot; ,
&quot; d c #DC0000 &quot; ,
&quot; e c #B90000 &quot; ,
&quot; f c #960000 &quot; ,
&quot; g c #730000 &quot; ,
&quot; h c #500000 &quot; ,
&quot; i c #FFD4E3 &quot; ,
&quot; j c #FFB1C7 &quot; ,
&quot; k c #FF8EAB &quot; ,
&quot; l c #FF6B8F &quot; ,
&quot; m c #FF4873 &quot; ,
&quot; n c #FF2557 &quot; ,
&quot; o c #FF0055 &quot; ,
&quot; p c #DC0049 &quot; ,
&quot; q c #B9003D &quot; ,
&quot; r c #960031 &quot; ,
&quot; s c #730025 &quot; ,
&quot; t c #500019 &quot; ,
&quot; u c #FFD4F0 &quot; ,
&quot; v c #FFB1E2 &quot; ,
&quot; w c #FF8ED4 &quot; ,
&quot; x c #FF6BC6 &quot; ,
&quot; y c #FF48B8 &quot; ,
&quot; z c #FF25AA &quot; ,
&quot; A c #FF00AA &quot; ,
&quot; B c #DC0092 &quot; ,
&quot; C c #B9007A &quot; ,
&quot; D c #960062 &quot; ,
&quot; E c #73004A &quot; ,
&quot; F c #500032 &quot; ,
&quot; G c #FFD4FF &quot; ,
&quot; H c #FFB1FF &quot; ,
&quot; I c #FF8EFF &quot; ,
&quot; J c #FF6BFF &quot; ,
&quot; K c #FF48FF &quot; ,
&quot; L c #FF25FF &quot; ,
&quot; M c #FE00FE &quot; ,
&quot; N c #DC00DC &quot; ,
&quot; O c #B900B9 &quot; ,
&quot; P c #960096 &quot; ,
&quot; Q c #730073 &quot; ,
&quot; R c #500050 &quot; ,
&quot; S c #F0D4FF &quot; ,
&quot; T c #E2B1FF &quot; ,
&quot; U c #D48EFF &quot; ,
&quot; V c #C66BFF &quot; ,
&quot; W c #B848FF &quot; ,
&quot; X c #AA25FF &quot; ,
&quot; Y c #AA00FF &quot; ,
&quot; Z c #9200DC &quot; ,
&quot; ` c #7A00B9 &quot; ,
&quot; . c #620096 &quot; ,
&quot; .. c #4A0073 &quot; ,
&quot; +. c #320050 &quot; ,
&quot; @. c #E3D4FF &quot; ,
&quot; #. c #C7B1FF &quot; ,
&quot; $. c #AB8EFF &quot; ,
&quot; %. c #8F6BFF &quot; ,
&quot; &amp; . c #7348FF &quot; ,
&quot; *. c #5725FF &quot; ,
&quot; =. c #5500FF &quot; ,
&quot; -. c #4900DC &quot; ,
&quot; ;. c #3D00B9 &quot; ,
&quot; &amp; gt; . c #310096 &quot; ,
&quot; ,. c #250073 &quot; ,
&quot; '. c #190050 &quot; ,
&quot; ). c #D4D4FF &quot; ,
&quot; !. c #B1B1FF &quot; ,
&quot; ~. c #8E8EFF &quot; ,
&quot; {. c #6B6BFF &quot; ,
&quot; ]. c #4848FF &quot; ,
&quot; ^. c #2525FF &quot; ,
&quot; /. c #0000FE &quot; ,
&quot; (. c #0000DC &quot; ,
&quot; _. c #0000B9 &quot; ,
&quot; :. c #000096 &quot; ,
&quot; &amp; lt; . c #000073 &quot; ,
&quot; [. c #000050 &quot; ,
&quot; }. c #D4E3FF &quot; ,
&quot; |. c #B1C7FF &quot; ,
&quot; 1. c #8EABFF &quot; ,
&quot; 2. c #6B8FFF &quot; ,
&quot; 3. c #4873FF &quot; ,
&quot; 4. c #2557FF &quot; ,
&quot; 5. c #0055FF &quot; ,
&quot; 6. c #0049DC &quot; ,
&quot; 7. c #003DB9 &quot; ,
&quot; 8. c #003196 &quot; ,
&quot; 9. c #002573 &quot; ,
&quot; 0. c #001950 &quot; ,
&quot; a. c #D4F0FF &quot; ,
&quot; b. c #B1E2FF &quot; ,
&quot; c. c #8ED4FF &quot; ,
&quot; d. c #6BC6FF &quot; ,
&quot; e. c #48B8FF &quot; ,
&quot; f. c #25AAFF &quot; ,
&quot; g. c #00AAFF &quot; ,
&quot; h. c #0092DC &quot; ,
&quot; i. c #007AB9 &quot; ,
&quot; j. c #006296 &quot; ,
&quot; k. c #004A73 &quot; ,
&quot; l. c #003250 &quot; ,
&quot; m. c #D4FFFF &quot; ,
&quot; n. c #B1FFFF &quot; ,
&quot; o. c #8EFFFF &quot; ,
&quot; p. c #6BFFFF &quot; ,
&quot; q. c #48FFFF &quot; ,
&quot; r. c #25FFFF &quot; ,
&quot; s. c #00FEFE &quot; ,
&quot; t. c #00DCDC &quot; ,
&quot; u. c #00B9B9 &quot; ,
&quot; v. c #009696 &quot; ,
&quot; w. c #007373 &quot; ,
&quot; x. c #005050 &quot; ,
&quot; y. c #D4FFF0 &quot; ,
&quot; z. c #B1FFE2 &quot; ,
&quot; A. c #8EFFD4 &quot; ,
&quot; B. c #6BFFC6 &quot; ,
&quot; C. c #48FFB8 &quot; ,
&quot; D. c #25FFAA &quot; ,
&quot; E. c #00FFAA &quot; ,
&quot; F. c #00DC92 &quot; ,
&quot; G. c #00B97A &quot; ,
&quot; H. c #009662 &quot; ,
&quot; I. c #00734A &quot; ,
&quot; J. c #005032 &quot; ,
&quot; K. c #D4FFE3 &quot; ,
&quot; L. c #B1FFC7 &quot; ,
&quot; M. c #8EFFAB &quot; ,
&quot; N. c #6BFF8F &quot; ,
&quot; O. c #48FF73 &quot; ,
&quot; P. c #25FF57 &quot; ,
&quot; Q. c #00FF55 &quot; ,
&quot; R. c #00DC49 &quot; ,
&quot; S. c #00B93D &quot; ,
&quot; T. c #009631 &quot; ,
&quot; U. c #007325 &quot; ,
&quot; V. c #005019 &quot; ,
&quot; W. c #D4FFD4 &quot; ,
&quot; X. c #B1FFB1 &quot; ,
&quot; Y. c #8EFF8E &quot; ,
&quot; Z. c #6BFF6B &quot; ,
&quot; `. c #48FF48 &quot; ,
&quot; + c #25FF25 &quot; ,
&quot; .+ c #00FE00 &quot; ,
&quot; ++ c #00DC00 &quot; ,
&quot; @+ c #00B900 &quot; ,
&quot; #+ c #009600 &quot; ,
&quot; $+ c #007300 &quot; ,
&quot; %+ c #005000 &quot; ,
&quot; &amp; + c #E3FFD4 &quot; ,
&quot; *+ c #C7FFB1 &quot; ,
&quot; =+ c #ABFF8E &quot; ,
&quot; -+ c #8FFF6B &quot; ,
&quot; ;+ c #73FF48 &quot; ,
&quot; &amp; gt; + c #57FF25 &quot; ,
&quot; ,+ c #55FF00 &quot; ,
&quot; '+ c #49DC00 &quot; ,
&quot; )+ c #3DB900 &quot; ,
&quot; !+ c #319600 &quot; ,
&quot; ~+ c #257300 &quot; ,
&quot; {+ c #195000 &quot; ,
&quot; ]+ c #F0FFD4 &quot; ,
&quot; ^+ c #E2FFB1 &quot; ,
&quot; /+ c #D4FF8E &quot; ,
&quot; (+ c #C6FF6B &quot; ,
&quot; _+ c #B8FF48 &quot; ,
&quot; :+ c #AAFF25 &quot; ,
&quot; &amp; lt; + c #AAFF00 &quot; ,
&quot; [+ c #92DC00 &quot; ,
&quot; }+ c #7AB900 &quot; ,
&quot; |+ c #629600 &quot; ,
&quot; 1+ c #4A7300 &quot; ,
&quot; 2+ c #325000 &quot; ,
&quot; 3+ c #FFFFD4 &quot; ,
&quot; 4+ c #FFFFB1 &quot; ,
&quot; 5+ c #FFFF8E &quot; ,
&quot; 6+ c #FFFF6B &quot; ,
&quot; 7+ c #FFFF48 &quot; ,
&quot; 8+ c #FFFF25 &quot; ,
&quot; 9+ c #FEFE00 &quot; ,
&quot; 0+ c #DCDC00 &quot; ,
&quot; a+ c #B9B900 &quot; ,
&quot; b+ c #969600 &quot; ,
&quot; c+ c #737300 &quot; ,
&quot; d+ c #505000 &quot; ,
&quot; e+ c #F2F2F2 &quot; ,
&quot; f+ c #E6E6E6 &quot; ,
&quot; g+ c #DADADA &quot; ,
&quot; h+ c #CECECE &quot; ,
&quot; i+ c #C2C2C2 &quot; ,
&quot; j+ c #B6B6B6 &quot; ,
&quot; k+ c #AAAAAA &quot; ,
&quot; l+ c #9E9E9E &quot; ,
&quot; m+ c #929292 &quot; ,
&quot; n+ c #868686 &quot; ,
&quot; o+ c #7A7A7A &quot; ,
&quot; p+ c #6E6E6E &quot; ,
&quot; q+ c #626262 &quot; ,
&quot; r+ c #565656 &quot; ,
&quot; s+ c #4A4A4A &quot; ,
&quot; t+ c #3E3E3E &quot; ,
&quot; u+ c #323232 &quot; ,
&quot; v+ c #262626 &quot; ,
&quot; w+ c #1A1A1A &quot; ,
&quot; x+ c #0E0E0E &quot; ,
&quot; y+ c #FFFBF0 &quot; ,
&quot; z+ c #A0A0A4 &quot; ,
&quot; A+ c #808080 &quot; ,
&quot; B+ c #FF0000 &quot; ,
&quot; C+ c #00FF00 &quot; ,
&quot; D+ c #FFFF00 &quot; ,
&quot; E+ c #0000FF &quot; ,
&quot; F+ c #FF00FF &quot; ,
&quot; G+ c #00FFFF &quot; ,
&quot; H+ c #FFFFFF &quot; ,
&quot; k+o+q+q+q+q+o+k+ &quot; ,
&quot; m+q+s+. . . . s+q+m+ j+m+m+ &quot; ,
&quot; m+s+. p+j+g+g+j+p+. s+m+ t+. t+m+ &quot; ,
&quot; k+q+. j+g+).).).).g+j+. q+k+t+. 9 . t+m+ &quot; ,
&quot; o+s+p+g+).H+!.!.).).g+p+s+t+. 7 8 9 . t+ &quot; ,
&quot; q+. j+).H+H+#.#.!.).).j+t+. . 8 8 9 0 . &quot; ,
&quot; q+. g+).!.#.#.#.#.!.).t+. ~ t+. 9 0 . t+ &quot; ,
&quot; q+. g+).!.#.#.#.#.!.t+. ~ 3+9+t+. . t+ &quot; ,
&quot; q+. j+).).!.#.#.!.t+. ~ 3+9+[ } . t+ &quot; ,
&quot; o+s+p+g+).).!.!.t+. ~ 3+9+[ } . t+ &quot; ,
&quot; k+q+. j+g+).).t+. ~ 3+9+[ } . t+ &quot; ,
&quot; m+s+. p+j+t+. ~ 3+9+[ } . t+ &quot; ,
&quot; m+q+s+t+. ~ 3+9+[ } . t+. t+ &quot; ,
&quot; k+t+. ~ 3+9+[ } . t+ &amp; gt; ] . t+ &quot; ,
&quot; t+. ~ 3+9+[ } . t+. { &amp; gt; ] . t+ &quot; ,
&quot; j+t+. . t+9+[ } . t+ t+. { &amp; gt; ] . t+ &quot; ,
&quot; k+/ &amp; gt; ; . t+} . t+ t+. { &amp; gt; ] . t+ &quot; ,
&quot; m+^ ; &amp; gt; &amp; gt; . . t+ t+. { &amp; gt; ^ . &quot; ,
&quot; p+^ &amp; gt; &amp; gt; &amp; gt; . t+ t+. ^ ( t+ &quot; ,
&quot; p+. ^ ^ / t+ t+. t+m+ &quot; };

/* XPM */
/*
static const char * replace_xpm[] = {
&quot; 20 20 9 1 &quot; ,
&quot; c None &quot; ,
&quot; . c #4A4A4A &quot; ,
&quot; + c #6E6E6E &quot; ,
&quot; @ c #000000 &quot; ,
&quot; # c #006296 &quot; ,
&quot; $ c #0092DC &quot; ,
&quot; % c #007AB9 &quot; ,
&quot; &amp; c #868686 &quot; ,
&quot; * c #003250 &quot; ,
&quot; &quot; ,
&quot; .....+.....+ &quot; ,
&quot; .@@@@@@@@@@@@. &quot; ,
&quot; .@####@@####@@. &quot; ,
&quot; .@@#$$#@@#$$#@@. &quot; ,
&quot; .@@#$%#@@#$%#@@. &quot; ,
&quot; .@@#$%#@@#$%#@@. &quot; ,
&quot; .@@#$%#@@$%%#@@. &quot; ,
&quot; .@@#$%#@@$%%#@@ &amp; &quot; ,
&quot; .@*#$%#@*$$%#@@ &quot; ,
&quot; .@*#$%#@*#$%#@@ &quot; ,
&quot; .@@#$%#@@#$%#@@ &amp; &quot; ,
&quot; .@@#$%#@@#$%#@@. &quot; ,
&quot; .@@#$%#@@#$%#@@. &quot; ,
&quot; .@@#%%#@@#%%#@@. &quot; ,
&quot; .@@#%%#@@#%%#@@. &quot; ,
&quot; .@####@@####@@. &quot; ,
&quot; .@@@@@@@@@@@@. &quot; ,
&quot; .....+.....+ &quot; ,
&quot; &quot; };
*/
#if 0
/* XPM */
static const char * World_xpm[] = {
&quot; 20 20 32 1 &quot; ,
&quot; c None &quot; ,
&quot; . c #B6B6B6 &quot; ,
&quot; + c #AAAAAA &quot; ,
&quot; @ c #868686 &quot; ,
&quot; # c #6E6E6E &quot; ,
&quot; $ c #4A4A4A &quot; ,
&quot; % c #323232 &quot; ,
&quot; &amp; c #000000 &quot; ,
&quot; * c #565656 &quot; ,
&quot; = c #006296 &quot; ,
&quot; - c #CECECE &quot; ,
&quot; ; c #FFFFFF &quot; ,
&quot; &amp; gt; c #007AB9 &quot; ,
&quot; , c #0092DC &quot; ,
&quot; ' c #48B8FF &quot; ,
&quot; ) c #007373 &quot; ,
&quot; ! c #00734A &quot; ,
&quot; ~ c #00AAFF &quot; ,
&quot; { c #8ED4FF &quot; ,
&quot; ] c #25AAFF &quot; ,
&quot; ^ c #00B9B9 &quot; ,
&quot; / c #005050 &quot; ,
&quot; ( c #DADADA &quot; ,
&quot; _ c #C5AA00 &quot; ,
&quot; : c #626200 &quot; ,
&quot; &amp; lt; c #4A4A00 &quot; ,
&quot; [ c #323200 &quot; ,
&quot; } c #3E3E3E &quot; ,
&quot; | c #B1FFFF &quot; ,
&quot; 1 c #48FFFF &quot; ,
&quot; 2 c #004A73 &quot; ,
&quot; 3 c #003250 &quot; ,
&quot; ..+@##@+.. &quot; ,
&quot; .@$% &amp; ** &amp; %$@. &quot; ,
&quot; .* &amp; =-;;-; &amp; gt; = &amp; *. &quot; ,
&quot; .* &amp; ,,';-;-')) &amp; *. &quot; ,
&quot; .* &amp; !~{{']']^/// &amp; *. &quot; ,
&quot; .@ &amp; !^;;'](((!_:: &amp; lt; &amp; @. &quot; ,
&quot; .$!^.;']';;((_:: &amp; lt; [$. &quot; ,
&quot; +%:'{']']]]^!_:: &amp; lt; [%+ &quot; ,
&quot; @ &amp; :...((((^!:_: &amp; lt; &amp; lt; [ &amp; @ &quot; ,
&quot; #} &amp; lt; [.(;|||11_:: &amp; lt; [ &amp; gt; 2# &quot; ,
&quot; #} &amp; lt; ..((((],!::: &amp; lt; &amp; gt; &amp; gt; 2# &quot; ,
&quot; @ &amp; @.((],],]/:: &amp; lt; , &amp; gt; &amp; gt; &amp; @ &quot; ,
&quot; +%@.,],],],,/: &amp; lt; &amp; gt; &amp; gt; =%+ &quot; ,
&quot; .$[,,,,,,,,,,/ &amp; lt; &amp; gt; =3$. &quot; ,
&quot; .@ &amp; , &amp; gt; ,@, &amp; gt; , &amp; gt; ,@ &amp; gt; /23 &amp; @. &quot; ,
&quot; .* &amp; 3@.@ &amp; gt; &amp; gt; &amp; gt; .;@23 &amp; *. &quot; ,
&quot; .* &amp; 3%..;..@23 &amp; *. &quot; ,
&quot; .* &amp; 3%;;;.@3 &amp; *. &quot; ,
&quot; .@$% &amp; %% &amp; %$@. &quot; ,
&quot; ..+@##@+.. &quot; };
#endif
/* XPM */
static const char * findinfiles_xpm[] = {
&quot; 20 20 28 1 &quot; ,
&quot; c None &quot; ,
&quot; . c #AAAAAA &quot; ,
&quot; + c #7A7A7A &quot; ,
&quot; @ c #626262 &quot; ,
&quot; # c #B6B6B6 &quot; ,
&quot; $ c #929292 &quot; ,
&quot; % c #4A4A4A &quot; ,
&quot; &amp; c #000000 &quot; ,
&quot; * c #6E6E6E &quot; ,
&quot; = c #FF8E8E &quot; ,
&quot; - c #DADADA &quot; ,
&quot; ; c #FFB1B1 &quot; ,
&quot; &amp; gt; c #FFFFFF &quot; ,
&quot; , c #005050 &quot; ,
&quot; ' c #D4FFFF &quot; ,
&quot; ) c #CECECE &quot; ,
&quot; ! c #007373 &quot; ,
&quot; ~ c #00DCDC &quot; ,
&quot; { c #00B9B9 &quot; ,
&quot; ] c #B1FFFF &quot; ,
&quot; ^ c #3E3E3E &quot; ,
&quot; / c #E6E6E6 &quot; ,
&quot; ( c #505000 &quot; ,
&quot; _ c #626200 &quot; ,
&quot; : c #AF9200 &quot; ,
&quot; &amp; lt; c #937A00 &quot; ,
&quot; [ c #9E9E9E &quot; ,
&quot; } c #F8E2B1 &quot; ,
&quot; .+@@@@@@@@@# &quot; ,
&quot; $@% &amp; &amp; &amp; &amp; %@ &amp; &amp; &amp; @# &quot; ,
&quot; $% &amp; *=--#* &amp; %$+ &amp; @# &quot; ,
&quot; .@ &amp; #;; &amp; gt; &amp; gt; &amp; gt; &amp; gt; # &amp; @.+ &amp; @# &quot; ,
&quot; +%,';;''''',%+)+ &amp; @# &quot; ,
&quot; @ &amp; !~;;~~~~~! &amp; @ &amp; gt; ) &amp; @# &quot; ,
&quot; @ &amp; - &amp; gt; ;; &amp; gt; &amp; gt; &amp; gt; &amp; gt; &amp; gt; - &amp; @ &amp; &amp; &amp; @# &quot; ,
&quot; @ &amp; - &amp; gt; ;; &amp; gt; &amp; gt; &amp; gt; &amp; gt; &amp; gt; - &amp; @)) &amp; @# &quot; ,
&quot; @ &amp; {';;'''''{ &amp; @]] &amp; @# &quot; ,
&quot; +%!~;;~~~~~!^+// &amp; @# &quot; ,
&quot; .@ &amp; #;; &amp; gt; &amp; gt; &amp; gt; -# &amp; &amp; ^]] &amp; @# &quot; ,
&quot; $% &amp; *=--#* &amp; %( &amp; ^/ &amp; @# &quot; ,
&quot; @ &amp; % &amp; &amp; &amp; &amp; % &amp; _: &amp; lt; &amp; ^ &amp; @# &quot; ,
&quot; @ &amp; [=###/^ &amp; :} &amp; lt; &amp; ^@# &quot; ,
&quot; @ &amp; ];]]]]]^ &amp; :} &amp; lt; &amp; ^# &quot; ,
&quot; @ &amp; #;))-///^ &amp; :} &amp; lt; &amp; ^ &quot; ,
&quot; @ &amp; ];]]]]]]]^ &amp; :} &amp; lt; &amp; ^ &quot; ,
&quot; @ &amp; #;))----//^ &amp; :}_ &amp; &quot; ,
&quot; @ &amp; &amp; &amp; &amp; &amp; &amp; &amp; &amp; &amp; &amp; &amp; &amp; ^ &amp; _ &amp; ^ &quot; ,
&quot; #@@@@@@@@@@@@@^ &amp; ^ &quot; };
/* XPM */
static const char * findnext_xpm[] = {
&quot; 20 20 30 1 &quot; ,
&quot; c None &quot; ,
&quot; . c #AAAAAA &quot; ,
&quot; + c #7A7A7A &quot; ,
&quot; @ c #626262 &quot; ,
&quot; # c #929292 &quot; ,
&quot; $ c #4A4A4A &quot; ,
&quot; % c #000000 &quot; ,
&quot; &amp; c #6E6E6E &quot; ,
&quot; * c #B6B6B6 &quot; ,
&quot; = c #DADADA &quot; ,
&quot; - c #D4D4FF &quot; ,
&quot; ; c #FFFFFF &quot; ,
&quot; &amp; gt; c #B1B1FF &quot; ,
&quot; , c #C7B1FF &quot; ,
&quot; ' c #3E3E3E &quot; ,
&quot; ) c #4A4A00 &quot; ,
&quot; ! c #E6E6E6 &quot; ,
&quot; ~ c #303030 &quot; ,
&quot; { c #676709 &quot; ,
&quot; ] c #AF9200 &quot; ,
&quot; ^ c #937A00 &quot; ,
&quot; / c #48B8FF &quot; ,
&quot; ( c #007373 &quot; ,
&quot; _ c #B1FFFF &quot; ,
&quot; : c #F8E2B1 &quot; ,
&quot; &amp; lt; c #686868 &quot; ,
&quot; [ c #8ED4FF &quot; ,
&quot; } c #0092DC &quot; ,
&quot; | c #626200 &quot; ,
&quot; 1 c #323200 &quot; ,
&quot; .+@@@@+. &quot; ,
&quot; #@$%%%%$@# &quot; ,
&quot; #$% &amp; *==* &amp; %$# &quot; ,
&quot; .@%*=----=*%@. &quot; ,
&quot; +$ &amp; =-; &amp; gt; &amp; gt; --= &amp; $+ &quot; ,
&quot; @%*-;;,, &amp; gt; --*%@ &quot; ,
&quot; @%=- &amp; gt; ,,,, &amp; gt; -=%@ &quot; ,
&quot; @%=- &amp; gt; ,,,, &amp; gt; -=%@ &quot; ,
&quot; @%*-- &amp; gt; ,, &amp; gt; --*%@ &quot; ,
&quot; +$ &amp; =-- &amp; gt; &amp; gt; --= &amp; '+ &quot; ,
&quot; .@%*=----=*%%' &quot; ,
&quot; #$% &amp; *==* &amp; %$)%' &quot; ,
&quot; #@$%%% &amp; !~{]^%' &quot; ,
&quot; .+@%/%(_%]:^%' &quot; ,
&quot; %%%%%%%//% &amp; &amp; lt; %]:^%' &quot; ,
&quot; %[////////%('%]:^%' &quot; ,
&quot; %}}}}}}//}% &amp; '%]:^%' &quot; ,
&quot; %%%%%%%/}%( '%]:|% &quot; ,
&quot; %}% &amp; '%|1' &quot; ,
&quot; %%( '%'# &quot; };
/* XPM */
static const char * next_xpm[] = {
&quot; 20 20 17 1 &quot; ,
&quot; c None &quot; ,
&quot; . c #B6B6B6 &quot; ,
&quot; + c #626262 &quot; ,
&quot; @ c #000000 &quot; ,
&quot; # c #B1FFFF &quot; ,
&quot; $ c #FFB1B1 &quot; ,
&quot; % c #CECECE &quot; ,
&quot; &amp; c #7A7A7A &quot; ,
&quot; * c #E6E6E6 &quot; ,
&quot; = c #FFFFFF &quot; ,
&quot; - c #868686 &quot; ,
&quot; ; c #007373 &quot; ,
&quot; &amp; gt; c #6E6E6E &quot; ,
&quot; , c #48B8FF &quot; ,
&quot; ' c #8ED4FF &quot; ,
&quot; ) c #0092DC &quot; ,
&quot; ! c #DADADA &quot; ,
&quot; .+++++++++++. &quot; ,
&quot; +@@@@@@@@@@@+. &quot; ,
&quot; +@#$####%@% &amp; @+. &quot; ,
&quot; +@.$%***%@=% &amp; @+. &quot; ,
&quot; +@#$####%@==% &amp; @+. &quot; ,
&quot; +@.$%**=%@===%@+. &quot; ,
&quot; +@#$####%@@@@@@+. &quot; ,
&quot; +@.$%**==%%%%%@+. &quot; ,
&quot; +@#-;#########@+. &quot; ,
&quot; +@.@@ &amp; gt; *====***@+. &quot; ,
&quot; ---@-@,@;#######@+. &quot; ,
&quot; @@@@@@,,@ &amp; gt; ====**@+. &quot; ,
&quot; @',,,,,,,@;#####@+. &quot; ,
&quot; @))))),,)@ &amp; gt; ====*@+. &quot; ,
&quot; @@@@@@,)@;######@+. &quot; ,
&quot; ---@+@)@ &amp; gt; ****===@+. &quot; ,
&quot; +@#@@;########@+. &quot; ,
&quot; +@.--%!!!!****@+. &quot; ,
&quot; +@@@@@@@@@@@@@@+. &quot; ,
&quot; .++++++++++++++. &quot; };
/* XPM */
static const char * prev_xpm[] = {
&quot; 20 20 17 1 &quot; ,
&quot; c None &quot; ,
&quot; . c #B6B6B6 &quot; ,
&quot; + c #626262 &quot; ,
&quot; @ c #000000 &quot; ,
&quot; # c #7A7A7A &quot; ,
&quot; $ c #CECECE &quot; ,
&quot; % c #B1FFFF &quot; ,
&quot; &amp; c #FFB1B1 &quot; ,
&quot; * c #FFFFFF &quot; ,
&quot; = c #E6E6E6 &quot; ,
&quot; - c #007373 &quot; ,
&quot; ; c #868686 &quot; ,
&quot; &amp; gt; c #6E6E6E &quot; ,
&quot; , c #48B8FF &quot; ,
&quot; ' c #8ED4FF &quot; ,
&quot; ) c #0092DC &quot; ,
&quot; ! c #DADADA &quot; ,
&quot; .+++++++++++. &quot; ,
&quot; .+@@@@@@@@@@@+ &quot; ,
&quot; .+@#$@$%%%% &amp; %@+ &quot; ,
&quot; .+@#$*@$===$ &amp; .@+ &quot; ,
&quot; .+@#$**@$%%%% &amp; %@+ &quot; ,
&quot; .+@$***@$*==$ &amp; .@+ &quot; ,
&quot; .+@@@@@@$%%%% &amp; %@+ &quot; ,
&quot; .+@$$$$$**==$ &amp; .@+ &quot; ,
&quot; .+@%%%%%%%%%-;%@+ &quot; ,
&quot; .+@===****= &amp; gt; @@.@+ &quot; ,
&quot; .+@%%%%%%%-@,@;@;;; &quot; ,
&quot; .+@==**** &amp; gt; @,,@@@@@@ &quot; ,
&quot; .+@%%%%%-@,,,,,,,'@ &quot; ,
&quot; .+@=**** &amp; gt; @),,)))))@ &quot; ,
&quot; .+@%%%%%%-@),@@@@@@ &quot; ,
&quot; .+@***==== &amp; gt; @)@+@;;; &quot; ,
&quot; .+@%%%%%%%%-@@%@+ &quot; ,
&quot; .+@====!!!!$;;.@+ &quot; ,
&quot; .+@@@@@@@@@@@@@@+ &quot; ,
&quot; .++++++++++++++. &quot; };
/* XPM */
static const char * build_xpm[] = {
&quot; 20 20 17 1 &quot; ,
&quot; c None &quot; ,
&quot; . c #626262 &quot; ,
&quot; + c #000000 &quot; ,
&quot; @ c #4A4A4A &quot; ,
&quot; # c #AAAAAA &quot; ,
&quot; $ c #FFFFFF &quot; ,
&quot; % c #DADADA &quot; ,
&quot; &amp; c #868686 &quot; ,
&quot; * c #CECECE &quot; ,
&quot; = c #B6B6B6 &quot; ,
&quot; - c #9E9E9E &quot; ,
&quot; ; c #6E6E6E &quot; ,
&quot; &amp; gt; c #929292 &quot; ,
&quot; , c #C2C2C2 &quot; ,
&quot; ' c #7A7A7A &quot; ,
&quot; ) c #323232 &quot; ,
&quot; ! c #3E3E3E &quot; ,
&quot; .+++@@+++++..# &quot; ,
&quot; +$$% &amp; &amp; $$%%%++@.# &quot; ,
&quot; +$%*.+++@@+++++..# &quot; ,
&quot; +%==+$$% &amp; &amp; $$%%%++@.# &quot; ,
&quot; += &amp; &amp; +$%*=*$%****-;+. &quot; ,
&quot; .++++%== &amp; ;=====***-+ &quot; ,
&quot; &amp; gt; ...+= &amp; &amp; @@; &amp; gt; &amp; gt; &amp; gt; ;++ &amp; gt; *+ &quot; ,
&quot; .+++..+ &amp; &amp; ;+..+++ &quot; ,
&quot; &amp; gt; ...,.+''+. ... &quot; ,
&quot; .+%,.+$%+. &quot; ,
&quot; #++++.+%,+. &quot; ,
&quot; '+.++.+%,+. &quot; ,
&quot; '+'.#++++++# &quot; ,
&quot; .+.)'+.++.+' &quot; ,
&quot; .+'.'+'.))+' &quot; ,
&quot; .+;).+.)).+. &quot; ,
&quot; .+'..+'.))+. &quot; ,
&quot; '+;).+;)).+. &quot; ,
&quot; #!!+++'.))+. &quot; ,
&quot; '+;))!!' &quot; };
/* XPM */
/*
static const char * xbuild_xpm[] = {
&quot; 20 20 17 1 &quot; ,
&quot; c None &quot; ,
&quot; . c #929292 &quot; ,
&quot; + c #626262 &quot; ,
&quot; @ c #AAAAAA &quot; ,
&quot; # c #000000 &quot; ,
&quot; $ c #4A4A4A &quot; ,
&quot; % c #FFFFFF &quot; ,
&quot; &amp; c #DADADA &quot; ,
&quot; * c #868686 &quot; ,
&quot; = c #CECECE &quot; ,
&quot; - c #B6B6B6 &quot; ,
&quot; ; c #9E9E9E &quot; ,
&quot; &amp; gt; c #6E6E6E &quot; ,
&quot; , c #7A7A7A &quot; ,
&quot; ' c #C2C2C2 &quot; ,
&quot; ) c #323232 &quot; ,
&quot; ! c #3E3E3E &quot; ,
&quot; .+++@@+++++@ &quot; ,
&quot; .+###$$#####++@ &quot; ,
&quot; +#%% &amp; **%% &amp; &amp; &amp; ##$+@ &quot; ,
&quot; +#% &amp; =-=% &amp; ====; &amp; gt; #+@ &quot; ,
&quot; +# &amp; --* &amp; gt; -----===;#+ &quot; ,
&quot; +#-**$$ &amp; gt; ... &amp; gt; ##.=#+ &quot; ,
&quot; .+###++#** &amp; gt; #++###+ &quot; ,
&quot; .+++ +#,,#+ +++ &quot; ,
&quot; +#% &amp; #+ &quot; ,
&quot; +# &amp; '#+ &quot; ,
&quot; +# &amp; '#+ &quot; ,
&quot; @######@ &quot; ,
&quot; ,#+##+#, &quot; ,
&quot; ,#,+))#, &quot; ,
&quot; +#+))+#+ &quot; ,
&quot; +#,+))#+ &quot; ,
&quot; +# &amp; gt; ))+#+ &quot; ,
&quot; +#,+))#+ &quot; ,
&quot; ,# &amp; gt; ))+#, &quot; ,
&quot; @!!##!!@ &quot; };
*/
/* XPM */
static const char * compile_xpm[] = {
&quot; 20 20 16 1 &quot; ,
&quot; c None &quot; ,
&quot; . c #929292 &quot; ,
&quot; + c #626262 &quot; ,
&quot; @ c #1A1A1A &quot; ,
&quot; # c #000000 &quot; ,
&quot; $ c #3E3E3E &quot; ,
&quot; % c #7A7A7A &quot; ,
&quot; &amp; c #E6E6E6 &quot; ,
&quot; * c #565656 &quot; ,
&quot; = c #6E6E6E &quot; ,
&quot; - c #4A4A4A &quot; ,
&quot; ; c #323232 &quot; ,
&quot; &amp; gt; c #B6B6B6 &quot; ,
&quot; , c #CECECE &quot; ,
&quot; ' c #9E9E9E &quot; ,
&quot; ) c #868686 &quot; ,
&quot; &quot; ,
&quot; .++++. .++++. &quot; ,
&quot; .@####$ $####@. &quot; ,
&quot; .@% &amp; .#$ $# &amp; .+@. &quot; ,
&quot; .#*.=#++++#.=*#. &quot; ,
&quot; .#*=*#----#+-*#. &quot; ,
&quot; +#=*#;+ +;#+-#+ &quot; ,
&quot; +;=*##;+##+;##+-; &quot; ,
&quot; +#;;;;;;;;;;;;;;#+ &quot; ,
&quot; +# &amp; gt; &amp; ,-# ## # &amp; gt; &amp; ,-#+ &quot; ,
&quot; +#','-# ## #','-#+ &quot; ,
&quot; -#) &amp; gt; %-######) &amp; gt; %-#- &quot; ,
&quot; .#=)'%-#++++#)'%)=#. &quot; ,
&quot; +#.=.+-#+ +#=.+=.#+ &quot; ,
&quot; +#)=)+-#+ +#=)+=)#+ &quot; ,
&quot; +#--+*-#+ +#-+*--#+ &quot; ,
&quot; +#+=.+*#+ +#+.+*-#+ &quot; ,
&quot; +#######+ +#######+ &quot; ,
&quot; +++++++ +++++++ &quot; ,
&quot; &quot; };

/* XPM */
static const char * stop_xpm[] = {
&quot; 20 20 13 1 &quot; ,
&quot; c None &quot; ,
&quot; . c #FFD4E3 &quot; ,
&quot; + c #FFB1C7 &quot; ,
&quot; @ c #FF8EAB &quot; ,
&quot; # c #FF6B8F &quot; ,
&quot; $ c #FF4873 &quot; ,
&quot; % c #FF2557 &quot; ,
&quot; &amp; c #DC0049 &quot; ,
&quot; * c #960031 &quot; ,
&quot; = c #800000 &quot; ,
&quot; - c #626262 &quot; ,
&quot; ; c #4A4A4A &quot; ,
&quot; &amp; gt; c #000000 &quot; ,
&quot; - &amp; gt; &amp; gt; &amp; gt; &amp; gt; &amp; gt; &amp; gt; &amp; gt; &amp; gt; - &quot; ,
&quot; ; &amp; gt; ######## &amp; gt; ; &quot; ,
&quot; ; &amp; gt; #$ &amp; &amp; &amp; &amp; &amp; &amp; &amp; # &amp; gt; ; &quot; ,
&quot; ; &amp; gt; #$ &amp; &amp; &amp; &amp; &amp; &amp; &amp; &amp; &amp; # &amp; gt; ; &quot; ,
&quot; ; &amp; gt; #$ &amp; &amp; &amp; &amp; &amp; &amp; &amp; &amp; &amp; &amp; &amp; # &amp; gt; ; &quot; ,
&quot; - &amp; gt; #$ &amp; &amp; &amp; &amp; &amp; &amp; &amp; &amp; &amp; &amp; &amp; &amp; &amp; # &amp; gt; - &quot; ,
&quot; &amp; gt; #$ &amp; &amp; &amp; &amp; &amp; &amp; &amp; &amp; &amp; &amp; &amp; &amp; &amp; &amp; &amp; &amp; &amp; gt; &quot; ,
&quot; &amp; gt; #$+.+...@...#...#* &amp; gt; &quot; ,
&quot; &amp; gt; #+@ &amp; &amp; &amp; .$+@$@+.%#.* &amp; gt; &quot; ,
&quot; &amp; gt; #$..@$.$.$ &amp; $....#* &amp; gt; &quot; ,
&quot; &amp; gt; #% &amp; &amp; +@.$+@$@+.$ &amp; &amp; * &amp; gt; &quot; ,
&quot; &amp; gt; #@..@$.$ &amp; ...#.% &amp; &amp; * &amp; gt; &quot; ,
&quot; &amp; gt; # &amp; $% &amp; &amp; % &amp; &amp; %%% &amp; $ &amp; &amp; &amp; * &amp; gt; &quot; ,
&quot; &amp; gt; &amp; &amp; &amp; &amp; &amp; &amp; &amp; &amp; &amp; &amp; &amp; &amp; &amp; &amp; &amp; &amp; &amp; * &amp; gt; &quot; ,
&quot; - &amp; gt; * &amp; &amp; &amp; &amp; &amp; &amp; &amp; &amp; &amp; &amp; &amp; &amp; &amp; &amp; * &amp; gt; ; &quot; ,
&quot; ; &amp; gt; * &amp; &amp; &amp; &amp; &amp; &amp; &amp; &amp; &amp; &amp; &amp; &amp; * &amp; gt; &amp; gt; &quot; ,
&quot; ; &amp; gt; * &amp; &amp; &amp; &amp; &amp; &amp; &amp; &amp; &amp; &amp; * &amp; gt; &amp; gt; &quot; ,
&quot; ; &amp; gt; * &amp; &amp; &amp; &amp; &amp; &amp; &amp; &amp; * &amp; gt; &amp; gt; &quot; ,
&quot; ; &amp; gt; ******** &amp; gt; &amp; gt; &quot; ,
&quot; - &amp; gt; &amp; gt; &amp; gt; &amp; gt; &amp; gt; &amp; gt; &amp; gt; &amp; gt; ; &quot; };


scite228.zip > SingleThreadExtension.h

// SciTE - Scintilla based Text Editor
/** @file SingleThreadExtension.h
** Extension that wraps another extension so that OnExecute calls are always
** seen by the wrapped extension as coming from the initial thread, despite
** the fact that SciTE calls it from a worker thread on Windows.
**/
// Copyright 1998-2004 by Neil Hodgson &amp; lt; neilh@scintilla.org &amp; gt;
// The License.txt file describes the conditions under which this software may be distributed.

#ifndef SINGLETHREADEXTENSION_H
#define SINGLETHREADEXTENSION_H

#include &amp; lt; windows.h &amp; gt;
#include &quot; Extender.h &quot;

class SingleThreadExtension: public Extension {
public:
SingleThreadExtension(Extension &amp; ext_) : ext( &amp; ext_), hwndDispatcher(NULL) {}
virtual ~SingleThreadExtension() { Finalise(); }

virtual bool Initialise(ExtensionAPI *host_);
virtual bool Finalise();
virtual bool Clear();
virtual bool Load(const char *filename);

virtual bool InitBuffer(int);
virtual bool ActivateBuffer(int);
virtual bool RemoveBuffer(int);

virtual bool OnOpen(const char *);
virtual bool OnSwitchFile(const char *);
virtual bool OnBeforeSave(const char *);
virtual bool OnSave(const char *);
virtual bool OnChar(char);
virtual bool OnExecute(const char *);
virtual bool OnSavePointReached();
virtual bool OnSavePointLeft();
virtual bool OnStyle(unsigned int, int, int, StyleWriter *);
virtual bool OnDoubleClick();
virtual bool OnUpdateUI();
virtual bool OnMarginClick();
virtual bool OnMacro(const char *, const char *);
virtual bool OnUserListSelection(int, const char *);
virtual bool SendProperty(const char *);
virtual bool OnKey(int, int);
virtual bool OnDwellStart(int, const char *);
virtual bool OnClose(const char *);

protected:
Extension *ext;

// Since the number of extensions requiring this is never likely to be large,
// each wrapped extension gets its own dispatcher window.
HWND hwndDispatcher;
static LRESULT PASCAL WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);

private:
// Copying is unsupported.
SingleThreadExtension(const SingleThreadExtension &amp; copy);
SingleThreadExtension &amp; operator=(const SingleThreadExtension &amp; copy);
};

#endif


scite228.zip > DirectorExtension.h

// SciTE - Scintilla based Text Editor
/** @file DirectorExtension.h
** Extension for communicating with a director program.
**/
// Copyright 1998-2001 by Neil Hodgson &amp; lt; neilh@scintilla.org &amp; gt;
// The License.txt file describes the conditions under which this software may be distributed.

class DirectorExtension : public Extension {
private:
DirectorExtension() {} // Singleton
DirectorExtension(const DirectorExtension &amp; ); // Disable copy ctor
void operator=(const DirectorExtension &amp; ); // Disable operator=

public:
static DirectorExtension &amp; Instance();

// Implement the Extension interface
virtual bool Initialise(ExtensionAPI *host_);
virtual bool Finalise();
virtual bool Clear();
virtual bool Load(const char *filename);

virtual bool OnOpen(const char *path);
virtual bool OnSwitchFile(const char *path);
virtual bool OnSave(const char *path);
virtual bool OnChar(char ch);
virtual bool OnExecute(const char *s);
virtual bool OnSavePointReached();
virtual bool OnSavePointLeft();
virtual bool OnStyle(unsigned int startPos, int lengthDoc, int initStyle, StyleWriter *styler);
virtual bool OnDoubleClick();
virtual bool OnUpdateUI();
virtual bool OnMarginClick();
virtual bool OnMacro(const char *command, const char *params);

virtual bool SendProperty(const char *prop);
virtual bool OnClose(const char *path);

// Allow messages through to extension
void HandleStringMessage(const char *message);
};


scite228.zip > SciTEWin.h

// SciTE - Scintilla based Text Editor
/** @file SciTEWin.h
** Header of main code for the Windows version of the editor.
**/
// Copyright 1998-2003 by Neil Hodgson &amp; lt; neilh@scintilla.org &amp; gt;
// The License.txt file describes the conditions under which this software may be distributed.

#include &amp; lt; stdlib.h &amp; gt;
#include &amp; lt; string.h &amp; gt;
#include &amp; lt; ctype.h &amp; gt;
#include &amp; lt; stdio.h &amp; gt;
#include &amp; lt; fcntl.h &amp; gt;
#include &amp; lt; stdarg.h &amp; gt;
#include &amp; lt; sys/stat.h &amp; gt;

#ifdef _MSC_VER
#pragma warning(disable: 4786)
#endif

#include &amp; lt; string &amp; gt;
#include &amp; lt; vector &amp; gt;
#include &amp; lt; deque &amp; gt;
#include &amp; lt; map &amp; gt;
#include &amp; lt; algorithm &amp; gt;

#ifdef __MINGW_H
#define _WIN32_IE 0x0400
#endif

#undef _WIN32_WINNT
#define _WIN32_WINNT 0x0501
#undef WINVER
#define WINVER 0x0501
#ifdef _MSC_VER
// windows.h, et al, use a lot of nameless struct/unions - can't fix it, so allow it
#pragma warning(disable: 4201)
#endif
#include &amp; lt; windows.h &amp; gt;
#if defined(_MSC_VER) &amp; &amp; (_MSC_VER &amp; lt; = 1200)
// Old compilers do not have Uxtheme.h
typedef HANDLE HTHEME;
#else
#include &amp; lt; uxtheme.h &amp; gt;
#endif
#ifdef _MSC_VER
// okay, that's done, don't allow it in our code
#pragma warning(default: 4201)
#endif
#include &amp; lt; commctrl.h &amp; gt;
#include &amp; lt; richedit.h &amp; gt;
#include &amp; lt; shlwapi.h &amp; gt;

#include &amp; lt; io.h &amp; gt;
#include &amp; lt; process.h &amp; gt;
#include &amp; lt; mmsystem.h &amp; gt;
#include &amp; lt; commctrl.h &amp; gt;
#ifdef _MSC_VER
#include &amp; lt; direct.h &amp; gt;
#endif
#ifdef __DMC__
#include &amp; lt; dir.h &amp; gt;
#endif

#include &quot; Scintilla.h &quot;

#include &quot; GUI.h &quot;

#include &quot; SString.h &quot;
#include &quot; StringList.h &quot;
#include &quot; StringHelpers.h &quot;
#include &quot; FilePath.h &quot;
#include &quot; PropSetFile.h &quot;
#include &quot; StyleWriter.h &quot;
#include &quot; Extender.h &quot;
#include &quot; SciTE.h &quot;
#include &quot; Mutex.h &quot;
#include &quot; JobQueue.h &quot;
#include &quot; SciTEBase.h &quot;
#include &quot; SciTEKeys.h &quot;
#include &quot; UniqueInstance.h &quot;

const int SCITE_TRAY = WM_APP + 0;
const int SCITE_DROP = WM_APP + 1;

class Dialog;

class SciTEWin;

inline HWND HwndOf(GUI::Window w) {
return reinterpret_cast &amp; lt; HWND &amp; gt; (w.GetID());
}

class BaseWin : public GUI::Window {
protected:
ILocalize *localiser;
public:
BaseWin() : localiser(0) {
}
void SetLocalizer(ILocalize *localiser_) {
localiser = localiser_;
}
HWND Hwnd() const {
return reinterpret_cast &amp; lt; HWND &amp; gt; (GetID());
}
virtual LRESULT WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam) = 0;
static LRESULT PASCAL StWndProc(
HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam);
};

class ContentWin : public BaseWin {
SciTEWin *pSciTEWin;
bool capturedMouse;
public:
ContentWin() : pSciTEWin(0), capturedMouse(false) {
}
void SetSciTE(SciTEWin *pSciTEWin_) {
pSciTEWin = pSciTEWin_;
}
void Paint(HDC hDC, GUI::Rectangle rcPaint);
LRESULT WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam);
};

class Strip : public BaseWin {
protected:
HFONT fontText;
HTHEME hTheme;
bool capturedMouse;
SIZE closeSize;
enum stripCloseState { csNone, csOver, csClicked, csClickedOver } closeState;
GUI::Window wToolTip;

GUI::Window CreateText(const char *text);
GUI::Window CreateButton(const char *text, int ident, bool check=false);
void Tab(bool forwards);
virtual void Creation();
virtual void Destruction();
virtual void Close();
virtual bool KeyDown(WPARAM key);
virtual bool Command(WPARAM wParam);
virtual void Size();
virtual void Paint(HDC hDC);
GUI::Rectangle CloseArea();
void InvalidateClose();
bool MouseInClose(GUI::Point pt);
void TrackMouse(GUI::Point pt);
void SetTheme();
virtual LRESULT CustomDraw(NMHDR *pnmh);
virtual LRESULT WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam);
public:
bool visible;
Strip() : fontText(0), hTheme(0), capturedMouse(false), closeState(csNone), visible(false) {
closeSize.cx = 11;
closeSize.cy = 11;
}
virtual int Height() {
return 25;
}
};

class SearchStrip : public Strip {
int entered;
int lineHeight;
GUI::Window wStaticFind;
GUI::Window wText;
GUI::Window wButton;
Searcher *pSearcher;
public:
SearchStrip() : entered(0), lineHeight(20), pSearcher(0) {
}
virtual void Creation();
virtual void Destruction();
void SetSearcher(Searcher *pSearcher_);
virtual void Close();
void Focus();
virtual bool KeyDown(WPARAM key);
void Next(bool select);
virtual bool Command(WPARAM wParam);
virtual void Size();
virtual void Paint(HDC hDC);
virtual LRESULT WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam);
virtual int Height() {
return lineHeight + 1;
}
};

class FindStrip : public Strip {
int entered;
int lineHeight;
GUI::Window wStaticFind;
GUI::Window wText;
GUI::Window wButton;
GUI::Window wButtonMarkAll;
GUI::Window wCheckWord;
GUI::Window wCheckCase;
GUI::Window wCheckRE;
GUI::Window wCheckBE;
GUI::Window wCheckWrap;
GUI::Window wCheckUp;
Searcher *pSearcher;
public:
FindStrip() : entered(0), lineHeight(20), pSearcher(0) {
}
virtual void Creation();
virtual void Destruction();
void SetSearcher(Searcher *pSearcher_);
virtual void Close();
void Focus();
virtual bool KeyDown(WPARAM key);
void Next(bool markAll, bool invertDirection);
void AddToPopUp(GUI::Menu &amp; popup, const char *label, int cmd, bool checked);
void ShowPopup();
virtual bool Command(WPARAM wParam);
virtual void Size();
virtual void Paint(HDC hDC);
virtual LRESULT WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam);
void CheckButtons();
void Show();
virtual int Height() {
return lineHeight + 1;
}
};

class ReplaceStrip : public Strip {
int entered;
int lineHeight;
GUI::Window wStaticFind;
GUI::Window wText;
GUI::Window wCheckWord;
GUI::Window wCheckCase;
GUI::Window wButtonFind;
GUI::Window wButtonReplaceAll;
GUI::Window wCheckRE;
GUI::Window wCheckWrap;
GUI::Window wCheckBE;
GUI::Window wStaticReplace;
GUI::Window wReplace;
GUI::Window wButtonReplace;
GUI::Window wButtonReplaceInSelection;
Searcher *pSearcher;
public:
ReplaceStrip() : entered(0), lineHeight(20), pSearcher(0) {
}
virtual void Creation();
virtual void Destruction();
void SetSearcher(Searcher *pSearcher_);
virtual void Close();
void Focus();
virtual bool KeyDown(WPARAM key);
void AddToPopUp(GUI::Menu &amp; popup, const char *label, int cmd, bool checked);
void ShowPopup();
void HandleReplaceCommand(int cmd, bool reverseFind = false);
virtual bool Command(WPARAM wParam);
virtual void Size();
virtual void Paint(HDC hDC);
virtual LRESULT WndProc(UINT iMessage, WPARAM wParam, LPARAM lParam);
void CheckButtons();
void Show();
virtual int Height() {
return lineHeight * 2 + 1;
}
};

struct Band {
bool visible;
int height;
bool expands;
GUI::Window win;
Band(bool visible_, int height_, bool expands_, GUI::Window win_) :
visible(visible_),
height(height_),
expands(expands_),
win(win_) {
}
};

/** Windows specific stuff.
**/
class SciTEWin : public SciTEBase {
friend class ContentWin;
friend class Strip;
friend class SearchStrip;
friend class FindStrip;
friend class ReplaceStrip;

protected:

int cmdShow;
static HINSTANCE hInstance;
static const TCHAR *className;
static const TCHAR *classNameInternal;
static SciTEWin *app;
WINDOWPLACEMENT winPlace;
RECT rcWorkArea;
GUI::gui_char openWhat[200];
bool modalParameters;
int filterDefault;
bool staticBuild;
int menuSource;
std::deque &amp; lt; GUI::gui_string &amp; gt; dropFilesQueue;

// Fields also used in tool execution thread
HANDLE hWriteSubProcess;
DWORD subProcessGroupId;
int outputScroll;

HACCEL hAccTable;

GUI::Rectangle pagesetupMargin;
HGLOBAL hDevMode;
HGLOBAL hDevNames;

UniqueInstance uniqueInstance;

/// HTMLHelp module
HMODULE hHH;
/// Multimedia (sound) module
HMODULE hMM;

// Tab Bar
TCITEM tie;
HFONT fontTabs;

/// Preserve focus during deactivation
HWND wFocus;

GUI::Window wFindInFiles;
GUI::Window wFindReplace;
GUI::Window wParameters;

ContentWin contents;
SearchStrip searchStrip;
FindStrip findStrip;
ReplaceStrip replaceStrip;

enum { bandTool, bandTab, bandContents, bandSearch, bandFind, bandReplace, bandStatus };
std::vector &amp; lt; Band &amp; gt; bands;

virtual void ReadLocalization();
virtual void GetWindowPosition(int *left, int *top, int *width, int *height, int *maximize);

virtual void ReadProperties();

virtual void SizeContentWindows();
virtual void SizeSubWindows();

virtual void SetMenuItem(int menuNumber, int position, int itemID,
const GUI::gui_char *text, const GUI::gui_char *mnemonic = 0);
virtual void RedrawMenu();
virtual void DestroyMenuItem(int menuNumber, int itemID);
virtual void CheckAMenuItem(int wIDCheckItem, bool val);
virtual void EnableAMenuItem(int wIDCheckItem, bool val);
virtual void CheckMenus();

void LocaliseAccelerators();
GUI::gui_string LocaliseAccelerator(const GUI::gui_char *Accelerator, int cmd);
void LocaliseMenu(HMENU hmenu);
void LocaliseMenus();
void LocaliseControl(HWND w);
void LocaliseDialog(HWND wDialog);

int DoDialog(HINSTANCE hInst, const TCHAR *resName, HWND hWnd, DLGPROC lpProc);
GUI::gui_string DialogFilterFromProperty(const GUI::gui_char *filterProperty);
virtual bool OpenDialog(FilePath directory, const GUI::gui_char *filter);
FilePath ChooseSaveName(FilePath directory, const char *title, const GUI::gui_char *filter=0, const char *ext=0);
virtual bool SaveAsDialog();
virtual void SaveACopy();
virtual void SaveAsHTML();
virtual void SaveAsRTF();
virtual void SaveAsPDF();
virtual void SaveAsTEX();
virtual void SaveAsXML();
virtual void LoadSessionDialog();
virtual void SaveSessionDialog();
virtual bool PreOpenCheck(const GUI::gui_char *file);
virtual bool IsStdinBlocked();

/// Print the current buffer.
virtual void Print(bool showDialog);
/// Handle default print setup values and ask the user its preferences.
virtual void PrintSetup();

BOOL HandleReplaceCommand(int cmd, bool reverseFind = false);

virtual int WindowMessageBox(GUI::Window &amp; w, const GUI::gui_string &amp; msg, int style);
virtual void FindMessageBox(const SString &amp; msg, const SString *findItem=0);
virtual void AboutDialog();
void DropFiles(HDROP hdrop);
void MinimizeToTray();
void RestoreFromTray();
GUI::gui_string ProcessArgs(const GUI::gui_char *cmdLine);
virtual void QuitProgram();

virtual FilePath GetDefaultDirectory();
virtual FilePath GetSciteDefaultHome();
virtual FilePath GetSciteUserHome();

virtual void SetFileProperties(PropSetFile &amp; ps);
virtual void SetStatusBarText(const char *s);

virtual void TabInsert(int index, const GUI::gui_char *title);
virtual void TabSelect(int index);
virtual void RemoveAllTabs();

/// Warn the user, by means defined in its properties.
virtual void WarnUser(int warnID);

virtual void Notify(SCNotification *notification);
virtual void ShowToolBar();
virtual void ShowTabBar();
virtual void ShowStatusBar();
virtual void ActivateWindow(const char *timestamp);
void ExecuteHelp(const char *cmd);
void ExecuteOtherHelp(const char *cmd);
void CopyAsRTF();
void CopyPath();
void FullScreenToggle();
void Command(WPARAM wParam, LPARAM lParam);
HWND MainHWND();

BOOL FindMessage(HWND hDlg, UINT message, WPARAM wParam);
static BOOL CALLBACK FindDlg(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
BOOL ReplaceMessage(HWND hDlg, UINT message, WPARAM wParam);
static BOOL CALLBACK ReplaceDlg(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
virtual void UIClosed();
void PerformGrep();
void FillCombos(Dialog &amp; dlg);
BOOL GrepMessage(HWND hDlg, UINT message, WPARAM wParam);
static BOOL CALLBACK GrepDlg(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
virtual void FindIncrement();
bool FindReplaceAdvanced();
virtual void Find();
virtual void FindInFiles();
virtual void Replace();
virtual void FindReplace(bool replace);
virtual void DestroyFindReplace();

BOOL GoLineMessage(HWND hDlg, UINT message, WPARAM wParam);
static BOOL CALLBACK GoLineDlg(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
virtual void GoLineDialog();

BOOL AbbrevMessage(HWND hDlg, UINT message, WPARAM wParam);
static BOOL CALLBACK AbbrevDlg(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
virtual bool AbbrevDialog();

BOOL TabSizeMessage(HWND hDlg, UINT message, WPARAM wParam);
static BOOL CALLBACK TabSizeDlg(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
virtual void TabSizeDialog();

virtual bool ParametersOpen();
void ParamGrab();
virtual bool ParametersDialog(bool