From 717c5cba84edfecc735505db4df7d01519c509b0 Mon Sep 17 00:00:00 2001 From: tomcw Date: Fri, 13 Feb 2015 22:40:53 +0000 Subject: [PATCH 01/20] New save-state (.aws) v2: . Format now extensible for supporting new hardware types in the future . Include missing items like Apple2Type, CyclesThisVideoFrame (#255) Continue to support loading of old v1 format. Added card save/load for: . Mouse (#260) . HDD (#260) . Printer Extended card support for: . SSC Other: . Added save-state v1 struct size checks . Create SaveState_Structs_v2.h and split out common into SaveState_Structs_common.h . Refactor HardDisk.cpp to use imagehandle; and consolidate with Disk.cpp . Fix Disk/HD_GetFullPathName() which wasn't always returning full pathname . Consolidate common GetImageTitle() and move into DiskImage.cpp --- ApplewinExpress9.00.vcproj | 12 +- source/6821.h | 41 +- source/Applewin.cpp | 16 +- source/Applewin.h | 2 +- source/CPU.cpp | 61 +- source/CPU.h | 10 +- source/Common.h | 2 +- source/Configuration/IPropertySheet.h | 3 + source/Configuration/PageAdvanced.cpp | 1 - source/Configuration/PageInput.cpp | 2 +- source/Configuration/PageSound.cpp | 2 +- source/Configuration/PropertySheet.h | 4 + source/Configuration/PropertySheetHelper.cpp | 58 +- source/Configuration/PropertySheetHelper.h | 1 + source/Debugger/Debug.cpp | 2 +- source/Debugger/Debug.h | 2 +- source/Debugger/Debugger_Display.cpp | 2 +- source/Disk.cpp | 381 +++++++----- source/Disk.h | 8 +- source/DiskImage.cpp | 123 +++- source/DiskImage.h | 13 +- source/DiskImageHelper.cpp | 8 +- source/Frame.cpp | 8 +- source/Harddisk.cpp | 426 ++++++++++---- source/Harddisk.h | 9 +- source/Joystick.cpp | 17 +- source/Joystick.h | 5 +- source/Keyboard.cpp | 36 +- source/Keyboard.h | 6 +- source/Memory.cpp | 110 ++-- source/Memory.h | 8 +- source/Mockingboard.cpp | 130 ++++- source/Mockingboard.h | 7 +- source/MouseInterface.cpp | 164 +++++- source/MouseInterface.h | 5 +- source/ParallelPrinter.cpp | 111 +++- source/ParallelPrinter.h | 6 +- source/SaveState.cpp | 575 +++++++++++++++---- source/SaveState_Structs_common.h | 77 +++ source/{Structs.h => SaveState_Structs_v1.h} | 162 ++---- source/SaveState_Structs_v2.h | 114 ++++ source/SerialComms.cpp | 161 +++++- source/SerialComms.h | 6 +- source/Speaker.cpp | 17 +- source/Speaker.h | 5 +- source/StdAfx.h | 2 +- source/Video.cpp | 25 +- source/Video.h | 5 +- 48 files changed, 2195 insertions(+), 756 deletions(-) create mode 100644 source/SaveState_Structs_common.h rename source/{Structs.h => SaveState_Structs_v1.h} (56%) create mode 100644 source/SaveState_Structs_v2.h diff --git a/ApplewinExpress9.00.vcproj b/ApplewinExpress9.00.vcproj index 55966eea..3973237d 100644 --- a/ApplewinExpress9.00.vcproj +++ b/ApplewinExpress9.00.vcproj @@ -755,11 +755,19 @@ > + + + + diff --git a/source/6821.h b/source/6821.h index fb92378a..5b269581 100644 --- a/source/6821.h +++ b/source/6821.h @@ -32,6 +32,21 @@ typedef struct mem_write_handler func; } STWriteHandler; +struct mc6821_s { + /* MC6821 register. */ + BYTE pra; + BYTE ddra; + BYTE cra; + BYTE prb; + BYTE ddrb; + BYTE crb; + + /* Drive structure */ +// struct drive_s *drive; +}; +typedef struct mc6821_s mc6821_t; + + class C6821 { public: @@ -64,6 +79,18 @@ public: m_stOutB.objTo = objTo; m_stOutB.func = func; } + void Get6821(mc6821_t& r6821, BYTE& byIA, BYTE& byIB) + { + r6821 = mc6821[0]; + byIA = m_byIA; + byIB = m_byIB; + } + void Set6821(const mc6821_t& r6821, const BYTE byIA, const BYTE byIB) + { + mc6821[0] = r6821; + m_byIA = byIA; + m_byIB = byIB; + } // AppleWin:TC END private: @@ -75,20 +102,6 @@ private: //struct drive_s; - struct mc6821_s { - /* MC6821 register. */ - BYTE pra; - BYTE ddra; - BYTE cra; - BYTE prb; - BYTE ddrb; - BYTE crb; - - /* Drive structure */ - // struct drive_s *drive; - }; - typedef struct mc6821_s mc6821_t; - //struct drive_context_s; void mc6821_init(/*struct drive_context_s *drv*/); void mc6821_reset(/*struct drive_context_s *drv*/); diff --git a/source/Applewin.cpp b/source/Applewin.cpp index a4d5ee05..8a379095 100644 --- a/source/Applewin.cpp +++ b/source/Applewin.cpp @@ -469,12 +469,6 @@ void LoadConfiguration(void) if(REGLOAD(TEXT(REGVALUE_HDD_ENABLED), &dwTmp)) HD_SetEnabled(dwTmp ? true : false); - char szHDVPathname[MAX_PATH] = {0}; - if(RegLoadString(TEXT(REG_PREFS), TEXT(REGVALUE_PREF_LAST_HARDDISK_1), 1, szHDVPathname, sizeof(szHDVPathname))) - HD_InsertDisk(HARDDISK_1, szHDVPathname); - if(RegLoadString(TEXT(REG_PREFS), TEXT(REGVALUE_PREF_LAST_HARDDISK_2), 1, szHDVPathname, sizeof(szHDVPathname))) - HD_InsertDisk(HARDDISK_2, szHDVPathname); - if(REGLOAD(TEXT(REGVALUE_PDL_XTRIM), &dwTmp)) JoySetTrim((short)dwTmp, true); if(REGLOAD(TEXT(REGVALUE_PDL_YTRIM), &dwTmp)) @@ -509,6 +503,16 @@ void LoadConfiguration(void) char szFilename[MAX_PATH] = {0}; + RegLoadString(TEXT(REG_PREFS), TEXT(REGVALUE_PREF_HDV_START_DIR), 1, szFilename, MAX_PATH); + if (szFilename[0] == 0) + GetCurrentDirectory(sizeof(szFilename), szFilename); + SetCurrentImageDir(szFilename); + + HD_LoadLastDiskImage(HARDDISK_1); + HD_LoadLastDiskImage(HARDDISK_2); + + // + // Current/Starting Dir is the "root" of where the user keeps his disk images RegLoadString(TEXT(REG_PREFS), TEXT(REGVALUE_PREF_START_DIR), 1, szFilename, MAX_PATH); if (szFilename[0] == 0) diff --git a/source/Applewin.h b/source/Applewin.h index 172bd308..e55c7c2a 100644 --- a/source/Applewin.h +++ b/source/Applewin.h @@ -1,6 +1,6 @@ #pragma once -#include "Structs.h" +#include "SaveState_Structs_common.h" #include "Common.h" void SetCurrentCLK6502(); diff --git a/source/CPU.cpp b/source/CPU.cpp index fadaecbb..62a98d37 100644 --- a/source/CPU.cpp +++ b/source/CPU.cpp @@ -102,6 +102,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #include "Z80VICE\z80mem.h" #include "Debugger\Debug.h" +#include "SaveState_Structs_v2.h" #define AF_SIGN 0x80 @@ -642,30 +643,46 @@ void CpuReset() //=========================================================================== -DWORD CpuGetSnapshot(SS_CPU6502* pSS) +void CpuSetSnapshot_v1(const BYTE A, const BYTE X, const BYTE Y, const BYTE P, const BYTE SP, const USHORT PC, const unsigned __int64 CumulativeCycles) { - pSS->A = regs.a; - pSS->X = regs.x; - pSS->Y = regs.y; - pSS->P = regs.ps | AF_RESERVED | AF_BREAK; - pSS->S = (BYTE) (regs.sp & 0xff); - pSS->PC = regs.pc; - pSS->g_nCumulativeCycles = g_nCumulativeCycles; + regs.a = A; + regs.x = X; + regs.y = Y; + regs.ps = P | (AF_RESERVED | AF_BREAK); + regs.sp = ((USHORT)SP) | 0x100; + regs.pc = PC; - return 0; -} - -DWORD CpuSetSnapshot(SS_CPU6502* pSS) -{ - regs.a = pSS->A; - regs.x = pSS->X; - regs.y = pSS->Y; - regs.ps = pSS->P | AF_RESERVED | AF_BREAK; - regs.sp = (USHORT)pSS->S | 0x100; - regs.pc = pSS->PC; CpuIrqReset(); CpuNmiReset(); - g_nCumulativeCycles = pSS->g_nCumulativeCycles; - - return 0; + g_nCumulativeCycles = CumulativeCycles; +} + +// + +void CpuGetSnapshot(SS_CPU6502_v2& CPU) +{ + regs.ps |= (AF_RESERVED | AF_BREAK); + + CPU.A = regs.a; + CPU.X = regs.x; + CPU.Y = regs.y; + CPU.P = regs.ps; + CPU.S = (BYTE) regs.sp; + CPU.PC = regs.pc; + + CPU.CumulativeCycles = g_nCumulativeCycles; +} + +void CpuSetSnapshot(const SS_CPU6502_v2& CPU) +{ + regs.a = CPU.A; + regs.x = CPU.X; + regs.y = CPU.Y; + regs.ps = CPU.P | (AF_RESERVED | AF_BREAK); + regs.sp = ((USHORT)CPU.S) | 0x100; + regs.pc = CPU.PC; + + CpuIrqReset(); + CpuNmiReset(); + g_nCumulativeCycles = CPU.CumulativeCycles; } diff --git a/source/CPU.h b/source/CPU.h index 58c5d886..7b60cd7e 100644 --- a/source/CPU.h +++ b/source/CPU.h @@ -1,6 +1,7 @@ #pragma once -typedef struct _regsrec { +struct regsrec +{ BYTE a; // accumulator BYTE x; // index X BYTE y; // index Y @@ -8,7 +9,7 @@ typedef struct _regsrec { WORD pc; // program counter WORD sp; // stack pointer BYTE bJammed; // CPU has crashed (NMOS 6502 only) -} regsrec, *regsptr; +}; extern regsrec regs; extern unsigned __int64 g_nCumulativeCycles; @@ -26,8 +27,9 @@ void CpuNmiReset(); void CpuNmiAssert(eIRQSRC Device); void CpuNmiDeassert(eIRQSRC Device); void CpuReset (); -DWORD CpuGetSnapshot(SS_CPU6502* pSS); -DWORD CpuSetSnapshot(SS_CPU6502* pSS); +void CpuSetSnapshot_v1(const BYTE A, const BYTE X, const BYTE Y, const BYTE P, const BYTE SP, const USHORT PC, const unsigned __int64 CumulativeCycles); +void CpuGetSnapshot(struct SS_CPU6502_v2& CPU); +void CpuSetSnapshot(const struct SS_CPU6502_v2& CPU); BYTE CpuRead(USHORT addr, ULONG uExecutedCycles); void CpuWrite(USHORT addr, BYTE a, ULONG uExecutedCycles); diff --git a/source/Common.h b/source/Common.h index dc549637..b2f9ee22 100644 --- a/source/Common.h +++ b/source/Common.h @@ -164,7 +164,7 @@ enum eIRQSRC {IS_6522=0, IS_SPEECH, IS_SSC, IS_MOUSE}; #define IS_APPLE2C (g_Apple2Type & APPLE2C_MASK) #define IS_CLONE() (g_Apple2Type & APPLECLONE_MASK) -// NB. These get persisted to the Registry, so don't change the values for these enums! +// NB. These get persisted to the Registry & save-state file, so don't change the values for these enums! enum eApple2Type { A2TYPE_APPLE2=0, A2TYPE_APPLE2PLUS, diff --git a/source/Configuration/IPropertySheet.h b/source/Configuration/IPropertySheet.h index c25b2ce8..b0312009 100644 --- a/source/Configuration/IPropertySheet.h +++ b/source/Configuration/IPropertySheet.h @@ -1,10 +1,13 @@ #pragma once +class CConfigNeedingRestart; + __interface IPropertySheet { void Init(void); DWORD GetVolumeMax(void); // TODO:TC: Move out of here bool SaveStateSelectImage(HWND hWindow, bool bSave); // TODO:TC: Move out of here + void ApplyNewConfig(const CConfigNeedingRestart& ConfigNew, const CConfigNeedingRestart& ConfigOld); UINT GetScrollLockToggle(void); void SetScrollLockToggle(UINT uValue); diff --git a/source/Configuration/PageAdvanced.cpp b/source/Configuration/PageAdvanced.cpp index de469041..c50cf5c7 100644 --- a/source/Configuration/PageAdvanced.cpp +++ b/source/Configuration/PageAdvanced.cpp @@ -22,7 +22,6 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "StdAfx.h" -#include "..\Structs.h" #include "..\Common.h" #include "..\ParallelPrinter.h" diff --git a/source/Configuration/PageInput.cpp b/source/Configuration/PageInput.cpp index 9326afee..940b9978 100644 --- a/source/Configuration/PageInput.cpp +++ b/source/Configuration/PageInput.cpp @@ -22,7 +22,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "StdAfx.h" -#include "..\Structs.h" +#include "..\SaveState_Structs_common.h" #include "..\Common.h" #include "..\Keyboard.h" diff --git a/source/Configuration/PageSound.cpp b/source/Configuration/PageSound.cpp index 92e73002..6f459dd7 100644 --- a/source/Configuration/PageSound.cpp +++ b/source/Configuration/PageSound.cpp @@ -22,7 +22,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "StdAfx.h" -#include "..\Structs.h" +#include "..\SaveState_Structs_common.h" #include "..\Common.h" #include "..\Mockingboard.h" diff --git a/source/Configuration/PropertySheet.h b/source/Configuration/PropertySheet.h index ba1dc6bb..82ae0edd 100644 --- a/source/Configuration/PropertySheet.h +++ b/source/Configuration/PropertySheet.h @@ -24,6 +24,10 @@ public: virtual void Init(void); virtual DWORD GetVolumeMax(void); // TODO:TC: Move out of here virtual bool SaveStateSelectImage(HWND hWindow, bool bSave); // TODO:TC: Move out of here + void ApplyNewConfig(const CConfigNeedingRestart& ConfigNew, const CConfigNeedingRestart& ConfigOld) + { + m_PropertySheetHelper.ApplyNewConfig(ConfigNew, ConfigOld); + } virtual UINT GetScrollLockToggle(void){ return m_PageInput.GetScrollLockToggle(); } virtual void SetScrollLockToggle(UINT uValue){ m_PageInput.SetScrollLockToggle(uValue); } diff --git a/source/Configuration/PropertySheetHelper.cpp b/source/Configuration/PropertySheetHelper.cpp index b135b059..c9e93e31 100644 --- a/source/Configuration/PropertySheetHelper.cpp +++ b/source/Configuration/PropertySheetHelper.cpp @@ -319,35 +319,40 @@ bool CPropertySheetHelper::CheckChangesForRestart(HWND hWnd) return true; // OK } -#define CONFIG_CHANGED(var) \ - (m_ConfigOld.var != m_ConfigNew.var) +#define CONFIG_CHANGED_LOCAL(var) \ + (ConfigOld.var != ConfigNew.var) // Apply changes to Registry +void CPropertySheetHelper::ApplyNewConfig(const CConfigNeedingRestart& ConfigNew, const CConfigNeedingRestart& ConfigOld) +{ + if (CONFIG_CHANGED_LOCAL(m_Apple2Type)) + { + SaveComputerType(ConfigNew.m_Apple2Type); + } + + if (CONFIG_CHANGED_LOCAL(m_Slot[4])) + SetSlot4(ConfigNew.m_Slot[4]); + + if (CONFIG_CHANGED_LOCAL(m_Slot[5])) + SetSlot5(ConfigNew.m_Slot[5]); + + if (CONFIG_CHANGED_LOCAL(m_bEnhanceDisk)) + REGSAVE(TEXT(REGVALUE_ENHANCE_DISK_SPEED), ConfigNew.m_bEnhanceDisk); + + if (CONFIG_CHANGED_LOCAL(m_bEnableHDD)) + { + REGSAVE(TEXT(REGVALUE_HDD_ENABLED), ConfigNew.m_bEnableHDD ? 1 : 0); + } + + if (CONFIG_CHANGED_LOCAL(m_bEnableTheFreezesF8Rom)) + { + REGSAVE(TEXT(REGVALUE_THE_FREEZES_F8_ROM), ConfigNew.m_bEnableTheFreezesF8Rom); + } +} + void CPropertySheetHelper::ApplyNewConfig(void) { - if (CONFIG_CHANGED(m_Apple2Type)) - { - SaveComputerType(m_ConfigNew.m_Apple2Type); - } - - if (CONFIG_CHANGED(m_Slot[4])) - SetSlot4(m_ConfigNew.m_Slot[4]); - - if (CONFIG_CHANGED(m_Slot[5])) - SetSlot5(m_ConfigNew.m_Slot[5]); - - if (CONFIG_CHANGED(m_bEnhanceDisk)) - REGSAVE(TEXT(REGVALUE_ENHANCE_DISK_SPEED), m_ConfigNew.m_bEnhanceDisk); - - if (CONFIG_CHANGED(m_bEnableHDD)) - { - REGSAVE(TEXT(REGVALUE_HDD_ENABLED), m_ConfigNew.m_bEnableHDD ? 1 : 0); - } - - if (CONFIG_CHANGED(m_bEnableTheFreezesF8Rom)) - { - REGSAVE(TEXT(REGVALUE_THE_FREEZES_F8_ROM), m_ConfigNew.m_bEnableTheFreezesF8Rom); - } + ApplyNewConfig(m_ConfigNew, m_ConfigOld); } void CPropertySheetHelper::SaveCurrentConfig(void) @@ -411,6 +416,9 @@ bool CPropertySheetHelper::IsOkToRestart(HWND hWnd) return true; } +#define CONFIG_CHANGED(var) \ + (m_ConfigOld.var != m_ConfigNew.var) + bool CPropertySheetHelper::HardwareConfigChanged(HWND hWnd) { std::string strMsg("The emulator needs to restart as the hardware configuration has changed:\n"); diff --git a/source/Configuration/PropertySheetHelper.h b/source/Configuration/PropertySheetHelper.h index 74896cdb..42503688 100644 --- a/source/Configuration/PropertySheetHelper.h +++ b/source/Configuration/PropertySheetHelper.h @@ -37,6 +37,7 @@ public: CConfigNeedingRestart& GetConfigNew(void) { return m_ConfigNew; } bool IsConfigChanged(void) { return m_ConfigNew != m_ConfigOld; } void SetDoBenchmark(void) { m_bDoBenchmark = true; } + void ApplyNewConfig(const CConfigNeedingRestart& ConfigNew, const CConfigNeedingRestart& ConfigOld); private: bool IsOkToSaveLoadState(HWND hWnd, const bool bConfigChanged); diff --git a/source/Debugger/Debug.cpp b/source/Debugger/Debug.cpp index cde48207..78a2e92d 100644 --- a/source/Debugger/Debug.cpp +++ b/source/Debugger/Debug.cpp @@ -4285,7 +4285,7 @@ Update_t CmdMemoryLoad (int nArgs) if (bBankSpecified) { - MemUpdatePaging(1); + MemUpdatePaging(TRUE); } else { diff --git a/source/Debugger/Debug.h b/source/Debugger/Debug.h index 26c3ecec..5c69c604 100644 --- a/source/Debugger/Debug.h +++ b/source/Debugger/Debug.h @@ -1,6 +1,6 @@ #pragma once -#include "..\Structs.h" +#include "..\SaveState_Structs_v1.h" // For SS_CARD_MOCKINGBOARD #include "..\Common.h" #include "Debugger_Types.h" diff --git a/source/Debugger/Debugger_Display.cpp b/source/Debugger/Debugger_Display.cpp index 6e4c98dd..47270730 100644 --- a/source/Debugger/Debugger_Display.cpp +++ b/source/Debugger/Debugger_Display.cpp @@ -2437,7 +2437,7 @@ void DrawMemory ( int line, int iMemDump ) SS_CARD_MOCKINGBOARD SS_MB; if ((eDevice == DEV_SY6522) || (eDevice == DEV_AY8910)) - MB_GetSnapshot(&SS_MB, 4+(nAddr>>1)); // Slot4 or Slot5 + MB_GetSnapshot_v1(&SS_MB, 4+(nAddr>>1)); // Slot4 or Slot5 int nFontWidth = g_aFontConfig[ FONT_INFO ]._nFontWidthAvg; diff --git a/source/Disk.cpp b/source/Disk.cpp index 211ca632..84e338e4 100644 --- a/source/Disk.cpp +++ b/source/Disk.cpp @@ -28,6 +28,8 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #include "StdAfx.h" +#include "SaveState_Structs_v1.h" + #include "AppleWin.h" #include "Disk.h" #include "DiskImage.h" @@ -61,21 +63,18 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // Private ________________________________________________________________________________________ - const int MAX_DISK_IMAGE_NAME = 15; - const int MAX_DISK_FULL_NAME = 127; - struct Disk_t { TCHAR imagename[ MAX_DISK_IMAGE_NAME + 1 ]; // (ie. no extension) TCHAR fullname [ MAX_DISK_FULL_NAME + 1 ]; // or : This is persisted to the snapshot file - std::string strDiskPathFilename; - std::string strFilenameInZip; // 0x00 or + std::string strFilenameInZip; // "" or HIMAGE imagehandle; // Init'd by DiskInsert() -> ImageOpen() + bool bWriteProtected; + // int track; LPBYTE trackimage; int phase; int byte; - bool bWriteProtected; BOOL trackimagedata; BOOL trackimagedirty; DWORD spinning; @@ -86,14 +85,13 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA { memcpy(imagename, other.imagename, sizeof(imagename)); memcpy(fullname , other.fullname, sizeof(fullname)); - strDiskPathFilename = other.strDiskPathFilename; strFilenameInZip = other.strFilenameInZip; imagehandle = other.imagehandle; + bWriteProtected = other.bWriteProtected; track = other.track; trackimage = other.trackimage; phase = other.phase; byte = other.byte; - bWriteProtected = other.bWriteProtected; trackimagedata = other.trackimagedata; trackimagedirty = other.trackimagedirty; spinning = other.spinning; @@ -109,8 +107,9 @@ static Disk_t g_aFloppyDisk[NUM_DRIVES]; static BYTE floppylatch = 0; static BOOL floppymotoron = 0; static BOOL floppywritemode = 0; -static WORD phases; // state bits for stepper magnet phases 0 - 3 +static WORD phases = 0; // state bits for stepper magnet phases 0 - 3 static bool g_bSaveDiskImage = true; // Save the DiskImage name to Registry +static UINT g_uSlot = 0; static void CheckSpinning(); static Disk_Status_e GetDriveLightStatus( const int iDrive ); @@ -127,14 +126,9 @@ int DiskGetCurrentPhase(void) { return g_aFloppyDisk[currdrive].phase; } int DiskGetCurrentOffset(void) { return g_aFloppyDisk[currdrive].byte; } int DiskGetTrack( int drive ) { return g_aFloppyDisk[ drive ].track; } -const std::string& DiskGetDiskPathFilename(const int iDrive) +const char* DiskGetDiskPathFilename(const int iDrive) { - return g_aFloppyDisk[iDrive].strDiskPathFilename; -} - -static void DiskSetDiskPathFilename(const int iDrive, const std::string strPathName) -{ - g_aFloppyDisk[iDrive].strDiskPathFilename = strPathName; + return g_aFloppyDisk[iDrive].fullname; } char* DiskGetCurrentState(void) @@ -164,7 +158,7 @@ char* DiskGetCurrentState(void) //=========================================================================== - void Disk_LoadLastDiskImage(const int iDrive) +void Disk_LoadLastDiskImage(const int iDrive) { _ASSERT(iDrive == DRIVE_1 || iDrive == DRIVE_2); @@ -175,22 +169,15 @@ char* DiskGetCurrentState(void) ? REGVALUE_PREF_LAST_DISK_1 : REGVALUE_PREF_LAST_DISK_2; - if (RegLoadString(TEXT(REG_PREFS),pRegKey,1,sFilePath,MAX_PATH)) + if (RegLoadString(TEXT(REG_PREFS), pRegKey, 1, sFilePath, MAX_PATH)) { sFilePath[ MAX_PATH ] = 0; - DiskSetDiskPathFilename(iDrive, sFilePath); -#if _DEBUG -// MessageBox(g_hFrameWindow,pFileName,pRegKey,MB_OK); -#endif - - // _tcscat(imagefilename,TEXT("MASTER.DSK")); // TODO: Should remember last disk by user g_bSaveDiskImage = false; // Pass in ptr to local copy of filepath, since RemoveDisk() sets DiskPathFilename = "" DiskInsert(iDrive, sFilePath, IMAGE_USE_FILES_WRITE_PROTECT_STATUS, IMAGE_DONT_CREATE); g_bSaveDiskImage = true; } - //else MessageBox(g_hFrameWindow,"Reg Key/Value not found",pRegKey,MB_OK); } //=========================================================================== @@ -202,7 +189,7 @@ void Disk_SaveLastDiskImage(const int iDrive) if (!g_bSaveDiskImage) return; - const char *pFileName = DiskGetDiskPathFilename(iDrive).c_str(); + const char *pFileName = g_aFloppyDisk[iDrive].fullname; if (iDrive == DRIVE_1) RegSaveString(TEXT(REG_PREFS), REGVALUE_PREF_LAST_DISK_1, TRUE, pFileName); @@ -249,53 +236,6 @@ static Disk_Status_e GetDriveLightStatus(const int iDrive) return DISK_STATUS_OFF; } -//=========================================================================== - -static void GetImageTitle(LPCTSTR imagefilename, Disk_t* fptr) -{ - TCHAR imagetitle[ MAX_DISK_FULL_NAME+1 ]; - LPCTSTR startpos = imagefilename; - - // imagetitle = - if (_tcsrchr(startpos,TEXT('\\'))) - startpos = _tcsrchr(startpos,TEXT('\\'))+1; - - _tcsncpy(imagetitle,startpos,MAX_DISK_FULL_NAME); - imagetitle[MAX_DISK_FULL_NAME] = 0; - - // if imagetitle contains a lowercase char, then found=1 (why?) - BOOL found = 0; - int loop = 0; - while (imagetitle[loop] && !found) - { - if (IsCharLower(imagetitle[loop])) - found = 1; - else - loop++; - } - - if ((!found) && (loop > 2)) - CharLowerBuff(imagetitle+1,_tcslen(imagetitle+1)); - - // fptr->fullname = - _tcsncpy( fptr->fullname, imagetitle, MAX_DISK_FULL_NAME ); - fptr->fullname[ MAX_DISK_FULL_NAME ] = 0; - - if (imagetitle[0]) - { - LPTSTR dot = imagetitle; - if (_tcsrchr(dot,TEXT('.'))) - dot = _tcsrchr(dot,TEXT('.')); - if (dot > imagetitle) - *dot = 0; - } - - // fptr->imagename = (ie. no extension) - _tcsncpy( fptr->imagename, imagetitle, MAX_DISK_IMAGE_NAME ); - fptr->imagename[ MAX_DISK_IMAGE_NAME ] = 0; -} - - //=========================================================================== static bool IsDriveValid(const int iDrive) @@ -370,7 +310,6 @@ static void RemoveDisk(const int iDrive) memset( pFloppy->imagename, 0, MAX_DISK_IMAGE_NAME+1 ); memset( pFloppy->fullname , 0, MAX_DISK_FULL_NAME +1 ); pFloppy->strFilenameInZip = ""; - DiskSetDiskPathFilename(iDrive, ""); Disk_SaveLastDiskImage( iDrive ); Video_ResetScreenshotCounter( NULL ); @@ -558,6 +497,11 @@ LPCTSTR DiskGetFullDiskFilename(const int iDrive) return DiskGetFullName(iDrive); } +static LPCTSTR DiskGetFullPathName(const int iDrive) +{ + return ImageGetPathname(g_aFloppyDisk[iDrive].imagehandle); +} + // Return the imagename // . Used by Drive Button's icons & Property Sheet Page (Save snapshot) LPCTSTR DiskGetBaseName(const int iDrive) @@ -611,10 +555,20 @@ ImageError_e DiskInsert(const int iDrive, LPCTSTR pszImageFilename, const bool b else fptr->bWriteProtected = bForceWriteProtected ? true : (dwAttributes & FILE_ATTRIBUTE_READONLY); - // Check if image is being used by the other HDD, and unplug it in order to be swapped - std::string otherDisk = DiskGetDiskPathFilename(!iDrive); - if (!strcmp(otherDisk.c_str(), pszImageFilename)) { - DiskEject(!iDrive); + // Check if image is being used by the other drive, and if so remove it in order so it can be swapped + { + const char* pszOtherPathname = DiskGetFullPathName(!iDrive); + + char szCurrentPathname[MAX_PATH]; + DWORD uNameLen = GetFullPathName(pszImageFilename, MAX_PATH, szCurrentPathname, NULL); + if (uNameLen == 0 || uNameLen >= MAX_PATH) + strcpy_s(szCurrentPathname, MAX_PATH, pszImageFilename); + + if (!strcmp(pszOtherPathname, szCurrentPathname)) + { + DiskEject(!iDrive); + FrameRefreshStatus(DRAW_LEDS | DRAW_BUTTON_DRIVES); + } } ImageError_e Error = ImageOpen(pszImageFilename, @@ -637,19 +591,15 @@ ImageError_e DiskInsert(const int iDrive, LPCTSTR pszImageFilename, const bool b if (Error == eIMAGE_ERROR_NONE) { - GetImageTitle(pszImageFilename, fptr); - - DiskSetDiskPathFilename(iDrive, pszImageFilename); - - //MessageBox( g_hFrameWindow, imagefilename, fptr->imagename, MB_OK ); - Video_ResetScreenshotCounter( fptr->imagename ); + GetImageTitle(pszImageFilename, fptr->imagename, fptr->fullname); + Video_ResetScreenshotCounter(fptr->imagename); } else { - Video_ResetScreenshotCounter( NULL ); + Video_ResetScreenshotCounter(NULL); } - Disk_SaveLastDiskImage( iDrive ); + Disk_SaveLastDiskImage(iDrive); return Error; } @@ -730,6 +680,13 @@ void DiskNotifyInvalidImage(const int iDrive, LPCTSTR pszImageFilename, const Im pszImageFilename); break; + case eIMAGE_ERROR_FAILED_TO_GET_PATHNAME: + wsprintf( + szBuffer, + TEXT("Unable to GetFullPathName() for the file: %s."), + pszImageFilename); + break; + default: // IGNORE OTHER ERRORS SILENTLY return; @@ -852,7 +809,7 @@ void DiskReset(void) //=========================================================================== -void DiskSelectImage(const int iDrive, LPSTR pszFilename) +static bool DiskSelectImage(const int iDrive, LPCSTR pszFilename) { TCHAR directory[MAX_PATH] = TEXT(""); TCHAR filename[MAX_PATH] = TEXT(""); @@ -880,6 +837,8 @@ void DiskSelectImage(const int iDrive, LPSTR pszFilename) ofn.Flags = OFN_PATHMUSTEXIST; ofn.lpstrTitle = title; + bool bRes = false; + if (GetOpenFileName(&ofn)) { if ((!ofn.nFileExtension) || !filename[ofn.nFileExtension]) @@ -888,16 +847,18 @@ void DiskSelectImage(const int iDrive, LPSTR pszFilename) ImageError_e Error = DiskInsert(iDrive, filename, ofn.Flags & OFN_READONLY, IMAGE_CREATE); if (Error == eIMAGE_ERROR_NONE) { - DiskSetDiskPathFilename(iDrive, filename); filename[ofn.nFileOffset] = 0; if (_tcsicmp(directory, filename)) RegSaveString(TEXT(REG_PREFS), TEXT(REGVALUE_PREF_START_DIR), 1, filename); + bRes = true; } else { DiskNotifyInvalidImage(iDrive, filename, Error); } } + + return bRes; } //=========================================================================== @@ -1040,6 +1001,8 @@ void DiskLoadRom(LPBYTE pCxRomPeripheral, UINT uSlot) // . In this case we can patch to compensate for an ADC or EOR checksum but not both RegisterIoHandler(uSlot, Disk_IORead, Disk_IOWrite, NULL, NULL, NULL, NULL); + + g_uSlot = uSlot; } //=========================================================================== @@ -1100,53 +1063,13 @@ static BYTE __stdcall Disk_IOWrite(WORD pc, WORD addr, BYTE bWrite, BYTE d, ULON //=========================================================================== -DWORD DiskGetSnapshot(SS_CARD_DISK2* pSS, DWORD dwSlot) +int DiskSetSnapshot_v1(const SS_CARD_DISK2* const pSS) { - pSS->Hdr.UnitHdr.dwLength = sizeof(SS_CARD_DISK2); - pSS->Hdr.UnitHdr.dwVersion = MAKE_VERSION(1,0,0,2); + if(pSS->Hdr.UnitHdr.hdr.v1.dwVersion > MAKE_VERSION(1,0,0,2)) + return -1; - pSS->Hdr.dwSlot = dwSlot; - pSS->Hdr.dwType = CT_Disk2; - - pSS->phases = phases; // new in 1.0.0.2 disk snapshots - pSS->currdrive = currdrive; // this was an int in 1.0.0.1 disk snapshots - pSS->diskaccessed = diskaccessed; - pSS->enhancedisk = enhancedisk; - pSS->floppylatch = floppylatch; - pSS->floppymotoron = floppymotoron; - pSS->floppywritemode = floppywritemode; - - for(UINT i=0; iUnit[i].szFileName, g_aFloppyDisk[i].fullname); - pSS->Unit[i].track = g_aFloppyDisk[i].track; - pSS->Unit[i].phase = g_aFloppyDisk[i].phase; - pSS->Unit[i].byte = g_aFloppyDisk[i].byte; - pSS->Unit[i].writeprotected = g_aFloppyDisk[i].bWriteProtected ? TRUE : FALSE; - pSS->Unit[i].trackimagedata = g_aFloppyDisk[i].trackimagedata; - pSS->Unit[i].trackimagedirty = g_aFloppyDisk[i].trackimagedirty; - pSS->Unit[i].spinning = g_aFloppyDisk[i].spinning; - pSS->Unit[i].writelight = g_aFloppyDisk[i].writelight; - pSS->Unit[i].nibbles = g_aFloppyDisk[i].nibbles; - - if(g_aFloppyDisk[i].trackimage) - memcpy(pSS->Unit[i].nTrack, g_aFloppyDisk[i].trackimage, NIBBLES_PER_TRACK); - else - memset(pSS->Unit[i].nTrack, 0, NIBBLES_PER_TRACK); - } - - return 0; -} - -DWORD DiskSetSnapshot(SS_CARD_DISK2* pSS, DWORD /*dwSlot*/) -{ - if(pSS->Hdr.UnitHdr.dwVersion > MAKE_VERSION(1,0,0,2)) - { - return -1; - } - - phases = pSS->phases; // new in 1.0.0.2 disk snapshots - currdrive = pSS->currdrive; // this was an int in 1.0.0.1 disk snapshots + phases = pSS->phases; + currdrive = pSS->currdrive; diskaccessed = pSS->diskaccessed; enhancedisk = pSS->enhancedisk; floppylatch = pSS->floppylatch; @@ -1183,7 +1106,6 @@ DWORD DiskSetSnapshot(SS_CARD_DISK2* pSS, DWORD /*dwSlot*/) // DiskInsert() sets up: // . imagename // . fullname - // . strDiskPathFilename // . writeprotected } @@ -1225,3 +1147,194 @@ DWORD DiskSetSnapshot(SS_CARD_DISK2* pSS, DWORD /*dwSlot*/) return 0; } + +//=========================================================================== + +struct DISK2_Unit_v2 +{ + char szFileName[MAX_PATH]; + UINT Track; + UINT Phase; + UINT Byte; + BOOL WriteProtected; + BOOL TrackImageData; + BOOL TrackImageDirty; + DWORD Spinning; + DWORD WriteLight; + UINT Nibbles; + BYTE TrackImage[NIBBLES_PER_TRACK]; +}; + +struct SS_CARD_DISK2_v2 +{ + SS_CARD_HDR Hdr; + DISK2_Unit_v2 Unit[2]; + WORD Phases; + WORD CurrDrive; + BOOL DiskAccessed; + BOOL EnhanceDisk; + BYTE FloppyLatch; + BOOL FloppyMotorOn; + BOOL FloppyWriteMode; +}; + +void DiskGetSnapshot(const HANDLE hFile) +{ + SS_CARD_DISK2_v2 CardDisk2; + + SS_CARD_DISK2_v2* const pSS = &CardDisk2; + + pSS->Hdr.UnitHdr.hdr.v2.Length = sizeof(SS_CARD_DISK2); + pSS->Hdr.UnitHdr.hdr.v2.Type = UT_Card; + pSS->Hdr.UnitHdr.hdr.v2.Version = 1; + + pSS->Hdr.Slot = g_uSlot; + pSS->Hdr.Type = CT_Disk2; + + pSS->Phases = phases; + pSS->CurrDrive = currdrive; + pSS->DiskAccessed = diskaccessed; + pSS->EnhanceDisk = enhancedisk; + pSS->FloppyLatch = floppylatch; + pSS->FloppyMotorOn = floppymotoron; + pSS->FloppyWriteMode = floppywritemode; + + for(UINT i=0; iUnit[i].szFileName, g_aFloppyDisk[i].fullname); + pSS->Unit[i].Track = g_aFloppyDisk[i].track; + pSS->Unit[i].Phase = g_aFloppyDisk[i].phase; + pSS->Unit[i].Byte = g_aFloppyDisk[i].byte; + pSS->Unit[i].WriteProtected = g_aFloppyDisk[i].bWriteProtected ? TRUE : FALSE; + pSS->Unit[i].TrackImageData = g_aFloppyDisk[i].trackimagedata; + pSS->Unit[i].TrackImageDirty = g_aFloppyDisk[i].trackimagedirty; + pSS->Unit[i].Spinning = g_aFloppyDisk[i].spinning; + pSS->Unit[i].WriteLight = g_aFloppyDisk[i].writelight; + pSS->Unit[i].Nibbles = g_aFloppyDisk[i].nibbles; + + if(g_aFloppyDisk[i].trackimage) + memcpy(pSS->Unit[i].TrackImage, g_aFloppyDisk[i].trackimage, NIBBLES_PER_TRACK); + else + memset(pSS->Unit[i].TrackImage, 0, NIBBLES_PER_TRACK); + } + + // + + DWORD dwBytesWritten; + BOOL bRes = WriteFile( hFile, + &CardDisk2, + CardDisk2.Hdr.UnitHdr.hdr.v2.Length, + &dwBytesWritten, + NULL); + + if(!bRes || (dwBytesWritten != CardDisk2.Hdr.UnitHdr.hdr.v2.Length)) + { + //dwError = GetLastError(); + throw std::string("Save error: Disk]["); + } +} + +void DiskSetSnapshot(const HANDLE hFile) +{ + SS_CARD_DISK2_v2 CardDisk2; + + DWORD dwBytesRead; + BOOL bRes = ReadFile( hFile, + &CardDisk2, + sizeof(CardDisk2), + &dwBytesRead, + NULL); + + if (dwBytesRead != sizeof(CardDisk2)) + throw std::string("Card: file corrupt"); + + if (CardDisk2.Hdr.Slot != 6) // fixme + throw std::string("Card: wrong slot"); + + if (CardDisk2.Hdr.UnitHdr.hdr.v2.Version > 1) + throw std::string("Card: wrong version"); + + if (CardDisk2.Hdr.UnitHdr.hdr.v2.Length != sizeof(SS_CARD_DISK2_v2)) + throw std::string("Card: unit size mismatch"); + + const SS_CARD_DISK2_v2* const pSS = &CardDisk2; + + phases = pSS->Phases; + currdrive = pSS->CurrDrive; + diskaccessed = pSS->DiskAccessed; + enhancedisk = pSS->EnhanceDisk; + floppylatch = pSS->FloppyLatch; + floppymotoron = pSS->FloppyMotorOn; + floppywritemode = pSS->FloppyWriteMode; + + // Eject all disks first in case Drive-2 contains disk to be inserted into Drive-1 + for(UINT i=0; iUnit[i].szFileName[0] == 0x00) + continue; + + DWORD dwAttributes = GetFileAttributes(pSS->Unit[i].szFileName); + if(dwAttributes == INVALID_FILE_ATTRIBUTES) + { + // Get user to browse for file + bResSelectImage = DiskSelectImage(i, pSS->Unit[i].szFileName); + + dwAttributes = GetFileAttributes(pSS->Unit[i].szFileName); + } + + bool bImageError = (dwAttributes == INVALID_FILE_ATTRIBUTES); + if (!bImageError) + { + if(DiskInsert(i, pSS->Unit[i].szFileName, dwAttributes & FILE_ATTRIBUTE_READONLY, IMAGE_DONT_CREATE) != eIMAGE_ERROR_NONE) + bImageError = true; + + // DiskInsert() sets up: + // . imagename + // . fullname + // . writeprotected + } + + // + +// strcpy(g_aFloppyDisk[i].fullname, pSS->Unit[i].szFileName); + g_aFloppyDisk[i].track = pSS->Unit[i].Track; + g_aFloppyDisk[i].phase = pSS->Unit[i].Phase; + g_aFloppyDisk[i].byte = pSS->Unit[i].Byte; +// g_aFloppyDisk[i].writeprotected = pSS->Unit[i].WriteProtected; + g_aFloppyDisk[i].trackimagedata = pSS->Unit[i].TrackImageData; + g_aFloppyDisk[i].trackimagedirty = pSS->Unit[i].TrackImageDirty; + g_aFloppyDisk[i].spinning = pSS->Unit[i].Spinning; + g_aFloppyDisk[i].writelight = pSS->Unit[i].WriteLight; + g_aFloppyDisk[i].nibbles = pSS->Unit[i].Nibbles; + + // + + if(!bImageError) + { + if((g_aFloppyDisk[i].trackimage == NULL) && g_aFloppyDisk[i].nibbles) + AllocTrack(i); + + if(g_aFloppyDisk[i].trackimage == NULL) + bImageError = true; + else + memcpy(g_aFloppyDisk[i].trackimage, pSS->Unit[i].TrackImage, NIBBLES_PER_TRACK); + } + + if(bImageError) + { + g_aFloppyDisk[i].trackimagedata = 0; + g_aFloppyDisk[i].trackimagedirty = 0; + g_aFloppyDisk[i].nibbles = 0; + } + } + + FrameRefreshStatus(DRAW_LEDS | DRAW_BUTTON_DRIVES); +} diff --git a/source/Disk.h b/source/Disk.h index 5c7daa02..e597ef51 100644 --- a/source/Disk.h +++ b/source/Disk.h @@ -40,7 +40,7 @@ const bool IMAGE_DONT_CREATE = false; const bool IMAGE_CREATE = true; extern BOOL enhancedisk; -const std::string& DiskGetDiskPathFilename(const int iDrive); +const char* DiskGetDiskPathFilename(const int iDrive); void DiskInitialize(void); // DiskIIManagerStartup() void DiskDestroy(void); // no, doesn't "destroy" the disk image. DiskIIManagerShutdown() @@ -70,8 +70,10 @@ void DiskSelect(const int iDrive); void DiskUpdatePosition(DWORD); bool DiskDriveSwap(void); void DiskLoadRom(LPBYTE pCxRomPeripheral, UINT uSlot); -DWORD DiskGetSnapshot(SS_CARD_DISK2* pSS, DWORD dwSlot); -DWORD DiskSetSnapshot(SS_CARD_DISK2* pSS, DWORD dwSlot); + +int DiskSetSnapshot_v1(const struct SS_CARD_DISK2* const pSS); +void DiskGetSnapshot(const HANDLE hFile); +void DiskSetSnapshot(const HANDLE hFile); void Disk_LoadLastDiskImage(const int iDrive); void Disk_SaveLastDiskImage(const int iDrive); diff --git a/source/DiskImage.cpp b/source/DiskImage.cpp index 86992b97..001c5427 100644 --- a/source/DiskImage.cpp +++ b/source/DiskImage.cpp @@ -27,7 +27,6 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "StdAfx.h" -#include "Structs.h" #include "Common.h" #include "DiskImage.h" @@ -40,32 +39,37 @@ static CDiskImageHelper sg_DiskImageHelper; // Pre: *pWriteProtected_ already set to file's r/w status - see DiskInsert() ImageError_e ImageOpen( LPCTSTR pszImageFilename, - HIMAGE* hDiskImage_, - bool* pWriteProtected_, + HIMAGE* hDiskImage, + bool* pWriteProtected, const bool bCreateIfNecessary, - std::string& strFilenameInZip) + std::string& strFilenameInZip, + const bool bExpectFloppy /*=true*/) { - if (! (pszImageFilename && hDiskImage_ && pWriteProtected_ && sg_DiskImageHelper.GetWorkBuffer())) + if (! (pszImageFilename && hDiskImage && pWriteProtected && sg_DiskImageHelper.GetWorkBuffer())) return eIMAGE_ERROR_BAD_POINTER; // CREATE A RECORD FOR THE FILE, AND RETURN AN IMAGE HANDLE - *hDiskImage_ = (HIMAGE) VirtualAlloc(NULL, sizeof(ImageInfo), MEM_COMMIT, PAGE_READWRITE); - if (*hDiskImage_ == NULL) + *hDiskImage = (HIMAGE) VirtualAlloc(NULL, sizeof(ImageInfo), MEM_COMMIT, PAGE_READWRITE); + if (*hDiskImage == NULL) return eIMAGE_ERROR_BAD_POINTER; - ZeroMemory(*hDiskImage_, sizeof(ImageInfo)); - ImageInfo* pImageInfo = (ImageInfo*) *hDiskImage_; - pImageInfo->bWriteProtected = *pWriteProtected_; + ZeroMemory(*hDiskImage, sizeof(ImageInfo)); + ImageInfo* pImageInfo = (ImageInfo*) *hDiskImage; + pImageInfo->bWriteProtected = *pWriteProtected; ImageError_e Err = sg_DiskImageHelper.Open(pszImageFilename, pImageInfo, bCreateIfNecessary, strFilenameInZip); - if (pImageInfo->pImageType != NULL && Err == eIMAGE_ERROR_NONE && pImageInfo->pImageType->GetType() == eImageHDV) - Err = eIMAGE_ERROR_UNSUPPORTED_HDV; - if (Err != eIMAGE_ERROR_NONE) { - ImageClose(*hDiskImage_, true); - *hDiskImage_ = (HIMAGE)0; + ImageClose(*hDiskImage, true); + *hDiskImage = (HIMAGE)0; + return Err; + } + + if (pImageInfo->pImageType && pImageInfo->pImageType->GetType() == eImageHDV) + { + if (bExpectFloppy) + Err = eIMAGE_ERROR_UNSUPPORTED_HDV; return Err; } @@ -76,7 +80,7 @@ ImageError_e ImageOpen( LPCTSTR pszImageFilename, for (UINT uTrack = 0; uTrack < pImageInfo->uNumTracks; uTrack++) pImageInfo->ValidTrack[uTrack] = (pImageInfo->uImageSize > 0) ? 1 : 0; - *pWriteProtected_ = pImageInfo->bWriteProtected; + *pWriteProtected = pImageInfo->bWriteProtected; return eIMAGE_ERROR_NONE; } @@ -185,6 +189,36 @@ void ImageWriteTrack( const HIMAGE hDiskImage, //=========================================================================== +bool ImageReadBlock( const HIMAGE hDiskImage, + UINT nBlock, + LPBYTE pBlockBuffer) +{ + ImageInfo* ptr = (ImageInfo*) hDiskImage; + + bool bRes = false; + if (ptr->pImageType->AllowRW()) + bRes = ptr->pImageType->Read(ptr, nBlock, pBlockBuffer); + + return bRes; +} + +//=========================================================================== + +bool ImageWriteBlock( const HIMAGE hDiskImage, + UINT nBlock, + LPBYTE pBlockBuffer) +{ + ImageInfo* ptr = (ImageInfo*) hDiskImage; + + bool bRes = false; + if (ptr->pImageType->AllowRW() && !ptr->bWriteProtected) + bRes = ptr->pImageType->Write(ptr, nBlock, pBlockBuffer); + + return bRes; +} + +//=========================================================================== + int ImageGetNumTracks(const HIMAGE hDiskImage) { ImageInfo* ptr = (ImageInfo*) hDiskImage; @@ -202,3 +236,60 @@ bool ImageIsMultiFileZip(const HIMAGE hDiskImage) ImageInfo* ptr = (ImageInfo*) hDiskImage; return ptr ? (ptr->uNumEntriesInZip > 1) : false; } + +const char* ImageGetPathname(const HIMAGE hDiskImage) +{ + static char* szEmpty = ""; + ImageInfo* ptr = (ImageInfo*) hDiskImage; + return ptr ? ptr->szFilename : szEmpty; +} + +UINT ImageGetImageSize(const HIMAGE hDiskImage) +{ + ImageInfo* ptr = (ImageInfo*) hDiskImage; + return ptr ? ptr->uImageSize : 0; +} + +void GetImageTitle(LPCTSTR pPathname, TCHAR* pImageName, TCHAR* pFullName) +{ + TCHAR imagetitle[ MAX_DISK_FULL_NAME+1 ]; + LPCTSTR startpos = pPathname; + + // imagetitle = + if (_tcsrchr(startpos, TEXT('\\'))) + startpos = _tcsrchr(startpos, TEXT('\\'))+1; + + _tcsncpy(imagetitle, startpos, MAX_DISK_FULL_NAME); + imagetitle[MAX_DISK_FULL_NAME] = 0; + + // if imagetitle contains a lowercase char, then found=1 (why?) + BOOL found = 0; + int loop = 0; + while (imagetitle[loop] && !found) + { + if (IsCharLower(imagetitle[loop])) + found = 1; + else + loop++; + } + + if ((!found) && (loop > 2)) + CharLowerBuff(imagetitle+1, _tcslen(imagetitle+1)); + + // pFullName = + _tcsncpy( pFullName, imagetitle, MAX_DISK_FULL_NAME ); + pFullName[ MAX_DISK_FULL_NAME ] = 0; + + if (imagetitle[0]) + { + LPTSTR dot = imagetitle; + if (_tcsrchr(dot, TEXT('.'))) + dot = _tcsrchr(dot, TEXT('.')); + if (dot > imagetitle) + *dot = 0; + } + + // pImageName = (ie. no extension) + _tcsncpy( pImageName, imagetitle, MAX_DISK_IMAGE_NAME ); + pImageName[ MAX_DISK_IMAGE_NAME ] = 0; +} diff --git a/source/DiskImage.h b/source/DiskImage.h index b712399f..73b5bd4d 100644 --- a/source/DiskImage.h +++ b/source/DiskImage.h @@ -55,9 +55,14 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA eIMAGE_ERROR_UNABLE_TO_OPEN, eIMAGE_ERROR_UNABLE_TO_OPEN_GZ, eIMAGE_ERROR_UNABLE_TO_OPEN_ZIP, + eIMAGE_ERROR_FAILED_TO_GET_PATHNAME, }; -ImageError_e ImageOpen(LPCTSTR pszImageFilename, HIMAGE* hDiskImage_, bool* pWriteProtected_, const bool bCreateIfNecessary, std::string& strFilenameInZip); + const int MAX_DISK_IMAGE_NAME = 15; + const int MAX_DISK_FULL_NAME = 127; + + +ImageError_e ImageOpen(LPCTSTR pszImageFilename, HIMAGE* hDiskImage, bool* pWriteProtected, const bool bCreateIfNecessary, std::string& strFilenameInZip, const bool bExpectFloppy=true); void ImageClose(const HIMAGE hDiskImage, const bool bOpenError=false); BOOL ImageBoot(const HIMAGE hDiskImage); void ImageDestroy(void); @@ -65,7 +70,13 @@ void ImageInitialize(void); void ImageReadTrack(const HIMAGE hDiskImage, int nTrack, int nQuarterTrack, LPBYTE pTrackImageBuffer, int* pNibbles); void ImageWriteTrack(const HIMAGE hDiskImage, int nTrack, int nQuarterTrack, LPBYTE pTrackImage, int nNibbles); +bool ImageReadBlock(const HIMAGE hDiskImage, UINT nBlock, LPBYTE pBlockBuffer); +bool ImageWriteBlock(const HIMAGE hDiskImage, UINT nBlock, LPBYTE pBlockBuffer); int ImageGetNumTracks(const HIMAGE hDiskImage); bool ImageIsWriteProtected(const HIMAGE hDiskImage); bool ImageIsMultiFileZip(const HIMAGE hDiskImage); +const char* ImageGetPathname(const HIMAGE hDiskImage); +UINT ImageGetImageSize(const HIMAGE hDiskImage); + +void GetImageTitle(LPCTSTR pPathname, TCHAR* pImageName, TCHAR* pFullName); diff --git a/source/DiskImageHelper.cpp b/source/DiskImageHelper.cpp index 4eeef4a8..11d692bc 100644 --- a/source/DiskImageHelper.cpp +++ b/source/DiskImageHelper.cpp @@ -28,7 +28,6 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #include "stdafx.h" -#include "Structs.h" #include "Common.h" #include "zlib.h" @@ -1435,7 +1434,9 @@ ImageError_e CImageHelperBase::Open( LPCTSTR pszImageFilename, if (Err != eIMAGE_ERROR_NONE) return Err; - _tcsncpy(pImageInfo->szFilename, pszImageFilename, MAX_PATH); + DWORD uNameLen = GetFullPathName(pszImageFilename, MAX_PATH, pImageInfo->szFilename, NULL); + if (uNameLen == 0 || uNameLen >= MAX_PATH) + Err = eIMAGE_ERROR_FAILED_TO_GET_PATHNAME; return eIMAGE_ERROR_NONE; } @@ -1453,9 +1454,10 @@ void CImageHelperBase::Close(ImageInfo* pImageInfo, const bool bDeleteFile) if (bDeleteFile) { DeleteFile(pImageInfo->szFilename); - pImageInfo->szFilename[0] = 0; } + pImageInfo->szFilename[0] = 0; + delete [] pImageInfo->pImageBuffer; pImageInfo->pImageBuffer = NULL; } diff --git a/source/Frame.cpp b/source/Frame.cpp index e4960e9b..84cc1d45 100644 --- a/source/Frame.cpp +++ b/source/Frame.cpp @@ -563,7 +563,8 @@ static void DrawFrameWindow () else if (g_nAppMode == MODE_DEBUG) DebugDisplay(1); else - // Win7: In fullscreen mode with 1 redraw, the the screen doesn't get redraw. + // Win7: In fullscreen mode with 1 redraw, the screen doesn't get redraw. + // TC: 07/01/2015: Tryed with MP's double-buffered DX full-screen code, but still the same. VideoRedrawScreen(g_bIsFullScreen ? 2 : 1); // TC: 22/06/2014: Why 2 redraws in full-screen mode (32-bit only)? (8-bit doesn't need this nor does Win8, just Win7 or older OS's) // DD Full-Screen Palette: BUGFIX: needs to come _after_ all drawing... @@ -617,6 +618,9 @@ void FrameDrawDiskLEDS( HDC passdc ) //=========================================================================== void FrameDrawDiskStatus( HDC passdc ) { + if (mem == NULL) + return; + // We use the actual drive since probing from memory doesn't tell us anything we don't already know. // DOS3.3 ProDOS // Drive $B7EA $BE3D @@ -1023,7 +1027,7 @@ LRESULT CALLBACK FrameWndProc ( if (!restart) { DiskDestroy(); ImageDestroy(); - HD_Cleanup(); + HD_Destroy(); } PrintDestroy(); sg_SSC.CommDestroy(); diff --git a/source/Harddisk.cpp b/source/Harddisk.cpp index 3406140e..9934abd3 100644 --- a/source/Harddisk.cpp +++ b/source/Harddisk.cpp @@ -4,7 +4,7 @@ AppleWin : An Apple //e emulator for Windows Copyright (C) 1994-1996, Michael O'Brien Copyright (C) 1999-2001, Oliver Schmidt Copyright (C) 2002-2005, Tom Charlesworth -Copyright (C) 2006-2007, Tom Charlesworth, Michael Pohoreski +Copyright (C) 2006-2015, Tom Charlesworth, Michael Pohoreski AppleWin is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -114,22 +114,23 @@ Overview struct HDD { // From Disk_t - TCHAR imagename[16]; // Not used - TCHAR fullname[128]; + TCHAR imagename[ MAX_DISK_IMAGE_NAME + 1 ]; // (ie. no extension) [not used] + TCHAR fullname[ MAX_DISK_FULL_NAME + 1 ]; // or + std::string strFilenameInZip; // "" or [not used] + HIMAGE imagehandle; // Init'd by HD_Insert() -> ImageOpen() + bool bWriteProtected; // Needed for ImageOpen() [otherwise not used] // BYTE hd_error; WORD hd_memblock; UINT hd_diskblock; WORD hd_buf_ptr; BOOL hd_imageloaded; - BYTE hd_buf[HD_BLOCK_SIZE+1]; // Why +1? + BYTE hd_buf[HD_BLOCK_SIZE+1]; // Why +1? Probably for erroreous reads beyond the block size (ie. reads from I/O addr 0xC0F8) #if HD_LED Disk_Status_e hd_status_next; Disk_Status_e hd_status_prev; #endif - - ImageInfo Info; }; static bool g_bHD_RomLoaded = false; @@ -143,114 +144,85 @@ static BYTE g_nHD_Command; static HDD g_HardDisk[NUM_HARDDISKS] = {0}; +static bool g_bSaveDiskImage = true; // Save the DiskImage name to Registry static UINT g_uSlot = 7; static CHardDiskImageHelper sg_HardDiskImageHelper; //=========================================================================== +static void HD_SaveLastDiskImage(const int iDrive); + static void HD_CleanupDrive(const int iDrive) { - sg_HardDiskImageHelper.Close(&g_HardDisk[iDrive].Info, false); - - g_HardDisk[iDrive].hd_imageloaded = false; - g_HardDisk[iDrive].imagename[0] = 0; - g_HardDisk[iDrive].fullname[0] = 0; - g_HardDisk[iDrive].Info.szFilename[0] = 0; -} - -static ImageError_e ImageOpen( LPCTSTR pszImageFilename, - const int iDrive, - const bool bCreateIfNecessary, - std::string& strFilenameInZip) -{ - if (!pszImageFilename) - return eIMAGE_ERROR_BAD_POINTER; - - HDD* pHDD = &g_HardDisk[iDrive]; - ImageInfo* pImageInfo = &pHDD->Info; - pImageInfo->bWriteProtected = false; - - ImageError_e Err = sg_HardDiskImageHelper.Open(pszImageFilename, pImageInfo, bCreateIfNecessary, strFilenameInZip); - - if (Err != eIMAGE_ERROR_NONE) + if (g_HardDisk[iDrive].imagehandle) { - HD_CleanupDrive(iDrive); - return Err; + ImageClose(g_HardDisk[iDrive].imagehandle); + g_HardDisk[iDrive].imagehandle = (HIMAGE)0; } - return eIMAGE_ERROR_NONE; + g_HardDisk[iDrive].hd_imageloaded = false; + + g_HardDisk[iDrive].imagename[0] = 0; + g_HardDisk[iDrive].fullname[0] = 0; + g_HardDisk[iDrive].strFilenameInZip = ""; + + HD_SaveLastDiskImage(iDrive); } //----------------------------------------------------------------------------- -static void GetImageTitle(LPCTSTR pszImageFilename, HDD* pHardDrive) -{ - TCHAR imagetitle[128]; - LPCTSTR startpos = pszImageFilename; - - // imagetitle = - if (_tcsrchr(startpos,TEXT('\\'))) - startpos = _tcsrchr(startpos,TEXT('\\'))+1; - _tcsncpy(imagetitle,startpos,127); - imagetitle[127] = 0; - - // if imagetitle contains a lowercase char, then found=1 (why?) - BOOL found = 0; - int loop = 0; - while (imagetitle[loop] && !found) - { - if (IsCharLower(imagetitle[loop])) - found = 1; - else - loop++; - } - - if ((!found) && (loop > 2)) - CharLowerBuff(imagetitle+1,_tcslen(imagetitle+1)); - - // hdptr->fullname = - _tcsncpy(pHardDrive->fullname,imagetitle,127); - pHardDrive->fullname[127] = 0; - - if (imagetitle[0]) - { - LPTSTR dot = imagetitle; - if (_tcsrchr(dot,TEXT('.'))) - dot = _tcsrchr(dot,TEXT('.')); - if (dot > imagetitle) - *dot = 0; - } - - // hdptr->imagename = (ie. no extension) - _tcsncpy(pHardDrive->imagename,imagetitle,15); - pHardDrive->imagename[15] = 0; -} - static void NotifyInvalidImage(TCHAR* pszImageFilename) { // TC: TO DO } -static BOOL HD_Load_Image(const int iDrive, LPCSTR pszImageFilename) +//=========================================================================== + +BOOL HD_Insert(const int iDrive, LPCTSTR pszImageFilename); + +void HD_LoadLastDiskImage(const int iDrive) { - const bool bCreateIfNecessary = false; // NB. Don't allow creation of HDV files - std::string strFilenameInZip; // TODO: Use this - ImageError_e Error = ImageOpen(pszImageFilename, iDrive, bCreateIfNecessary, strFilenameInZip); + _ASSERT(iDrive == HARDDISK_1 || iDrive == HARDDISK_2); - g_HardDisk[iDrive].hd_imageloaded = (Error == eIMAGE_ERROR_NONE); + char sFilePath[ MAX_PATH + 1]; + sFilePath[0] = 0; -#if HD_LED - g_HardDisk[iDrive].hd_status_next = DISK_STATUS_OFF; - g_HardDisk[iDrive].hd_status_prev = DISK_STATUS_OFF; -#endif + char *pRegKey = (iDrive == HARDDISK_1) + ? REGVALUE_PREF_LAST_HARDDISK_1 + : REGVALUE_PREF_LAST_HARDDISK_2; - return g_HardDisk[iDrive].hd_imageloaded; + if (RegLoadString(TEXT(REG_PREFS), pRegKey, 1, sFilePath, MAX_PATH)) + { + sFilePath[ MAX_PATH ] = 0; + + g_bSaveDiskImage = false; + // Pass in ptr to local copy of filepath, since RemoveDisk() sets DiskPathFilename = "" // todo: update comment for HD func + HD_Insert(iDrive, sFilePath); + g_bSaveDiskImage = true; + } } //=========================================================================== -// everything below is global +static void HD_SaveLastDiskImage(const int iDrive) +{ + _ASSERT(iDrive == HARDDISK_1 || iDrive == HARDDISK_2); + + if (!g_bSaveDiskImage) + return; + + const char *pFileName = g_HardDisk[iDrive].fullname; + + if (iDrive == HARDDISK_1) + RegSaveString(TEXT(REG_PREFS), REGVALUE_PREF_LAST_HARDDISK_1, TRUE, pFileName); + else + RegSaveString(TEXT(REG_PREFS), REGVALUE_PREF_LAST_HARDDISK_2, TRUE, pFileName); +} + +//=========================================================================== + +// (Nearly) everything below is global static BYTE __stdcall HD_IO_EMUL(WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft); @@ -263,7 +235,8 @@ bool HD_CardIsEnabled(void) // Called by: // . LoadConfiguration() - Done at each restart -// . DiskDlg_OK() - When HD is enabled/disabled on UI +// . RestoreCurrentConfig() - Done when Config dialog is cancelled +// . Snapshot_LoadState_v2() - Done to default to disabled state void HD_SetEnabled(const bool bEnabled) { if(g_bHD_Enabled == bEnabled) @@ -298,17 +271,17 @@ LPCTSTR HD_GetFullName(const int iDrive) LPCTSTR HD_GetFullPathName(const int iDrive) { - return g_HardDisk[iDrive].Info.szFilename; + return ImageGetPathname(g_HardDisk[iDrive].imagehandle); } -static LPCTSTR HD_DiskGetBaseName (const int iDrive) // Not used +static LPCTSTR HD_DiskGetBaseName(const int iDrive) // Not used { return g_HardDisk[iDrive].imagename; } //------------------------------------- -VOID HD_Load_Rom(const LPBYTE pCxRomPeripheral, const UINT uSlot) +void HD_Load_Rom(const LPBYTE pCxRomPeripheral, const UINT uSlot) { if(!g_bHD_Enabled) return; @@ -336,46 +309,82 @@ VOID HD_Load_Rom(const LPBYTE pCxRomPeripheral, const UINT uSlot) RegisterIoHandler(g_uSlot, HD_IO_EMUL, HD_IO_EMUL, NULL, NULL, NULL, NULL); } -VOID HD_Cleanup(void) +void HD_Destroy(void) { - for(int i=HARDDISK_1; i= MAX_PATH) + strcpy_s(szCurrentPathname, MAX_PATH, pszImageFilename); + + if (!strcmp(pszOtherPathname, szCurrentPathname)) + { + HD_Unplug(!iDrive); + FrameRefreshStatus(DRAW_LEDS); + } } - BOOL bResult = HD_Load_Image(iDrive, pszImageFilename); + const bool bCreateIfNecessary = false; // NB. Don't allow creation of HDV files + const bool bExpectFloppy = false; + ImageError_e Error = ImageOpen(pszImageFilename, + &g_HardDisk[iDrive].imagehandle, + &g_HardDisk[iDrive].bWriteProtected, + bCreateIfNecessary, + g_HardDisk[iDrive].strFilenameInZip, // TODO: Use this + bExpectFloppy); - if (bResult) - GetImageTitle(pszImageFilename, &g_HardDisk[iDrive]); + g_HardDisk[iDrive].hd_imageloaded = (Error == eIMAGE_ERROR_NONE); - return bResult; +#if HD_LED + g_HardDisk[iDrive].hd_status_next = DISK_STATUS_OFF; + g_HardDisk[iDrive].hd_status_prev = DISK_STATUS_OFF; +#endif + + if (Error == eIMAGE_ERROR_NONE) + { + GetImageTitle(pszImageFilename, g_HardDisk[iDrive].imagename, g_HardDisk[iDrive].fullname); + } + + HD_SaveLastDiskImage(iDrive); + + return g_HardDisk[iDrive].hd_imageloaded; } -void HD_Select(const int iDrive) +static bool HD_SelectImage(const int iDrive, LPCSTR pszFilename) { TCHAR directory[MAX_PATH] = TEXT(""); TCHAR filename[MAX_PATH] = TEXT(""); TCHAR title[40]; + strcpy(filename, pszFilename); + RegLoadString(TEXT(REG_PREFS), TEXT(REGVALUE_PREF_HDV_START_DIR), 1, directory, MAX_PATH); _tcscpy(title, TEXT("Select HDV Image For HDD ")); _tcscat(title, iDrive ? TEXT("2") : TEXT("1")); + _ASSERT(sizeof(OPENFILENAME) == sizeof(OPENFILENAME_NT4)); // Required for Win98/ME support (selected by _WIN32_WINNT=0x0400 in stdafx.h) + OPENFILENAME ofn; ZeroMemory(&ofn,sizeof(OPENFILENAME)); ofn.lStructSize = sizeof(OPENFILENAME); @@ -389,22 +398,32 @@ void HD_Select(const int iDrive) ofn.Flags = OFN_FILEMUSTEXIST | OFN_HIDEREADONLY; // Don't allow creation & hide the read-only checkbox ofn.lpstrTitle = title; + bool bRes = false; + if (GetOpenFileName(&ofn)) { if ((!ofn.nFileExtension) || !filename[ofn.nFileExtension]) _tcscat(filename,TEXT(".hdv")); - if (HD_InsertDisk(iDrive, filename)) + if (HD_Insert(iDrive, filename)) { filename[ofn.nFileOffset] = 0; if (_tcsicmp(directory, filename)) RegSaveString(TEXT(REG_PREFS), TEXT(REGVALUE_PREF_HDV_START_DIR), 1, filename); + bRes = true; } else { NotifyInvalidImage(filename); } } + + return bRes; +} + +void HD_Select(const int iDrive) +{ + HD_SelectImage(iDrive, TEXT("")); } void HD_Unplug(const int iDrive) @@ -450,33 +469,33 @@ static BYTE __stdcall HD_IO_EMUL(WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG { default: case 0x00: //status - if (pHDD->Info.uImageSize == 0) + if (ImageGetImageSize(pHDD->imagehandle) == 0) { pHDD->hd_error = 1; r = DEVICE_IO_ERROR; } break; case 0x01: //read - if ((pHDD->hd_diskblock * HD_BLOCK_SIZE) < pHDD->Info.uImageSize) + if ((pHDD->hd_diskblock * HD_BLOCK_SIZE) < ImageGetImageSize(pHDD->imagehandle)) + { + bool bRes = ImageReadBlock(pHDD->imagehandle, pHDD->hd_diskblock, pHDD->hd_buf); + if (bRes) { - bool bRes = pHDD->Info.pImageType->Read(&pHDD->Info, pHDD->hd_diskblock, pHDD->hd_buf); - if (bRes) - { - pHDD->hd_error = 0; - r = 0; - pHDD->hd_buf_ptr = 0; - } - else - { - pHDD->hd_error = 1; - r = DEVICE_IO_ERROR; - } + pHDD->hd_error = 0; + r = 0; + pHDD->hd_buf_ptr = 0; } else { pHDD->hd_error = 1; r = DEVICE_IO_ERROR; } + } + else + { + pHDD->hd_error = 1; + r = DEVICE_IO_ERROR; + } break; case 0x02: //write { @@ -484,17 +503,17 @@ static BYTE __stdcall HD_IO_EMUL(WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG pHDD->hd_status_next = DISK_STATUS_WRITE; #endif bool bRes = true; - const bool bAppendBlocks = (pHDD->hd_diskblock * HD_BLOCK_SIZE) >= pHDD->Info.uImageSize; + const bool bAppendBlocks = (pHDD->hd_diskblock * HD_BLOCK_SIZE) >= ImageGetImageSize(pHDD->imagehandle); if (bAppendBlocks) { ZeroMemory(pHDD->hd_buf, HD_BLOCK_SIZE); // Inefficient (especially for gzip/zip files!) - UINT uBlock = pHDD->Info.uImageSize / HD_BLOCK_SIZE; + UINT uBlock = ImageGetImageSize(pHDD->imagehandle) / HD_BLOCK_SIZE; while (uBlock < pHDD->hd_diskblock) { - bRes = pHDD->Info.pImageType->Write(&pHDD->Info, uBlock++, pHDD->hd_buf); + bRes = ImageWriteBlock(pHDD->imagehandle, uBlock++, pHDD->hd_buf); _ASSERT(bRes); if (!bRes) break; @@ -504,7 +523,7 @@ static BYTE __stdcall HD_IO_EMUL(WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG MoveMemory(pHDD->hd_buf, mem+pHDD->hd_memblock, HD_BLOCK_SIZE); if (bRes) - bRes = pHDD->Info.pImageType->Write(&pHDD->Info, pHDD->hd_diskblock, pHDD->hd_buf); + bRes = ImageWriteBlock(pHDD->imagehandle, pHDD->hd_diskblock, pHDD->hd_buf); if (bRes) { @@ -560,7 +579,8 @@ static BYTE __stdcall HD_IO_EMUL(WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG break; case 0xF8: r = pHDD->hd_buf[pHDD->hd_buf_ptr]; - pHDD->hd_buf_ptr++; + if (pHDD->hd_buf_ptr < sizeof(pHDD->hd_buf)-1) + pHDD->hd_buf_ptr++; break; default: #if HD_LED @@ -631,3 +651,159 @@ void HD_GetLightStatus (Disk_Status_e *pDisk1Status_) *pDisk1Status_ = DISK_STATUS_OFF; } } + +//=========================================================================== + +struct HDD_Unit +{ + char szFilename[MAX_PATH]; + BYTE error; + WORD memblock; + UINT diskblock; + WORD buf_ptr; + BOOL imageloaded; + BYTE buf[HD_BLOCK_SIZE]; + UINT status_next; + UINT status_prev; +}; + +struct SS_CARD_HDD +{ + SS_CARD_HDR Hdr; + HDD_Unit Unit[NUM_HARDDISKS]; + BYTE CurrUnit; + BYTE Command; +}; + +void HD_GetSnapshot(const HANDLE hFile) +{ + if (!HD_CardIsEnabled()) + return; + + SS_CARD_HDD CardHDD; + + CardHDD.Hdr.UnitHdr.hdr.v2.Length = sizeof(SS_CARD_HDD); + CardHDD.Hdr.UnitHdr.hdr.v2.Type = UT_Card; + CardHDD.Hdr.UnitHdr.hdr.v2.Version = 1; + + CardHDD.Hdr.Slot = g_uSlot; + CardHDD.Hdr.Type = CT_GenericHDD; + + CardHDD.CurrUnit = g_nHD_UnitNum; + CardHDD.Command = g_nHD_Command; + + for (UINT i=0; i 1) + throw std::string("Card: wrong version"); + + if (CardHDD.Hdr.UnitHdr.hdr.v2.Length != sizeof(SS_CARD_HDD)) + throw std::string("Card: unit size mismatch"); + + g_nHD_UnitNum = CardHDD.CurrUnit; + g_nHD_Command = CardHDD.Command; + + // Unplug all HDDs first in case HDD-2 is to be plugged in as HDD-1 + for (UINT i=0; ig_nJoyCntrResetCycle = g_nJoyCntrResetCycle; - return 0; + g_nJoyCntrResetCycle = JoyCntrResetCycle; } -DWORD JoySetSnapshot(SS_IO_Joystick* pSS) +// + +void JoyGetSnapshot(unsigned __int64& rJoyCntrResetCycle) { - g_nJoyCntrResetCycle = pSS->g_nJoyCntrResetCycle; - return 0; + rJoyCntrResetCycle = g_nJoyCntrResetCycle; +} + +void JoySetSnapshot(const unsigned __int64 JoyCntrResetCycle) +{ + g_nJoyCntrResetCycle = JoyCntrResetCycle; } diff --git a/source/Joystick.h b/source/Joystick.h index 9889c2c9..f4dfba56 100644 --- a/source/Joystick.h +++ b/source/Joystick.h @@ -24,8 +24,9 @@ void JoyDisableUsingMouse(); void JoySetTrim(short nValue, bool bAxisX); short JoyGetTrim(bool bAxisX); void JoyportControl(const UINT uControl); -DWORD JoyGetSnapshot(SS_IO_Joystick* pSS); -DWORD JoySetSnapshot(SS_IO_Joystick* pSS); +void JoySetSnapshot_v1(const unsigned __int64 JoyCntrResetCycle); +void JoyGetSnapshot(unsigned __int64& rJoyCntrResetCycle); +void JoySetSnapshot(const unsigned __int64 JoyCntrResetCycle); BYTE __stdcall JoyReadButton(WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft); BYTE __stdcall JoyReadPosition(WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft); diff --git a/source/Keyboard.cpp b/source/Keyboard.cpp index 2b1e1727..e3e3e2d1 100644 --- a/source/Keyboard.cpp +++ b/source/Keyboard.cpp @@ -50,7 +50,6 @@ static bool g_bCapsLock = true; //Caps lock key for Apple2 and Lat/Cyr lock for static bool g_bP8CapsLock = true; //Caps lock key of Pravets 8A/C static int lastvirtkey = 0; // Current PC keycode static BYTE keycode = 0; // Current Apple keycode -static DWORD keyboardqueries = 0; #ifdef KEY_OLD // Original @@ -160,14 +159,6 @@ BYTE KeybGetKeycode () // Used by MemCheckPaging() & VideoCheckMode() return keycode; } -//=========================================================================== -DWORD KeybGetNumQueries () // Used in determining 'idleness' of Apple system -{ - DWORD result = keyboardqueries; - keyboardqueries = 0; - return result; -} - //=========================================================================== void KeybQueueKeypress (int key, BOOL bASCII) { @@ -425,10 +416,6 @@ static char ClipboardCurrChar(bool bIncPtr) BYTE __stdcall KeybReadData (WORD, WORD, BYTE, BYTE, ULONG) { - keyboardqueries++; - - // - if(g_bPasteFromClipboard) ClipboardInit(); @@ -463,10 +450,6 @@ BYTE __stdcall KeybReadData (WORD, WORD, BYTE, BYTE, ULONG) BYTE __stdcall KeybReadFlag (WORD, WORD, BYTE, BYTE, ULONG) { - keyboardqueries++; - - // - if(g_bPasteFromClipboard) ClipboardInit(); @@ -516,16 +499,19 @@ void KeybToggleP8ACapsLock () //=========================================================================== -DWORD KeybGetSnapshot(SS_IO_Keyboard* pSS) +void KeybSetSnapshot_v1(const BYTE LastKey) { - pSS->keyboardqueries = keyboardqueries; - pSS->nLastKey = g_nLastKey; - return 0; + g_nLastKey = LastKey; } -DWORD KeybSetSnapshot(SS_IO_Keyboard* pSS) +// + +void KeybGetSnapshot(BYTE& rLastKey) { - keyboardqueries = pSS->keyboardqueries; - g_nLastKey = pSS->nLastKey; - return 0; + rLastKey = g_nLastKey; +} + +void KeybSetSnapshot(const BYTE LastKey) +{ + g_nLastKey = LastKey; } diff --git a/source/Keyboard.h b/source/Keyboard.h index 0010b677..7544d486 100644 --- a/source/Keyboard.h +++ b/source/Keyboard.h @@ -11,12 +11,12 @@ bool KeybGetShiftStatus(); bool KeybGetCapsAllowed(); //For Pravets8A/C only void KeybUpdateCtrlShiftStatus(); BYTE KeybGetKeycode (); -DWORD KeybGetNumQueries (); void KeybQueueKeypress (int,BOOL); void KeybToggleCapsLock (); void KeybToggleP8ACapsLock (); -DWORD KeybGetSnapshot(SS_IO_Keyboard* pSS); -DWORD KeybSetSnapshot(SS_IO_Keyboard* pSS); +void KeybSetSnapshot_v1(const BYTE LastKey); +void KeybGetSnapshot(BYTE& rLastKey); +void KeybSetSnapshot(const BYTE LastKey); BYTE __stdcall KeybReadData (WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft); BYTE __stdcall KeybReadFlag (WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft); diff --git a/source/Memory.cpp b/source/Memory.cpp index 3868e0b2..9c97e0fb 100644 --- a/source/Memory.cpp +++ b/source/Memory.cpp @@ -51,6 +51,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #include "..\resource\resource.h" #include "Configuration\PropertySheet.h" #include "Debugger\DebugDefs.h" +#include "SaveState_Structs_v2.h" // Memory Flag #define MF_80STORE 0x00000001 @@ -1103,17 +1104,14 @@ LPBYTE MemGetCxRomPeripheral() //=========================================================================== +const UINT CxRomSize = 4*1024; +const UINT Apple2RomSize = 12*1024; +const UINT Apple2eRomSize = Apple2RomSize+CxRomSize; +//const UINT Pravets82RomSize = 12*1024; +//const UINT Pravets8ARomSize = Pravets82RomSize+CxRomSize; + void MemInitialize() { - // Init the I/O handlers - InitIoHandlers(); - - const UINT CxRomSize = 4*1024; - const UINT Apple2RomSize = 12*1024; - const UINT Apple2eRomSize = Apple2RomSize+CxRomSize; - //const UINT Pravets82RomSize = 12*1024; - //const UINT Pravets8ARomSize = Pravets82RomSize+CxRomSize; - // ALLOCATE MEMORY FOR THE APPLE MEMORY IMAGE AND ASSOCIATED DATA STRUCTURES memaux = (LPBYTE)VirtualAlloc(NULL,_6502_MEM_END+1,MEM_COMMIT,PAGE_READWRITE); memmain = (LPBYTE)VirtualAlloc(NULL,_6502_MEM_END+1,MEM_COMMIT,PAGE_READWRITE); @@ -1154,6 +1152,14 @@ void MemInitialize() i++; #endif + MemInitializeROM(); + MemInitializeCustomF8ROM(); + MemInitializeIO(); + MemReset(); +} + +void MemInitializeROM(void) +{ // READ THE APPLE FIRMWARE ROMS INTO THE ROM IMAGE UINT ROM_SIZE = 0; HRSRC hResInfo = NULL; @@ -1210,8 +1216,6 @@ void MemInitialize() if (pData == NULL) return; - // - memset(pCxRomInternal,0,CxRomSize); memset(pCxRomPeripheral,0,CxRomSize); @@ -1223,17 +1227,23 @@ void MemInitialize() } _ASSERT(ROM_SIZE == Apple2RomSize); - memcpy(memrom, pData, Apple2RomSize); // ROM at $D000...$FFFF + memcpy(memrom, pData, Apple2RomSize); // ROM at $D000...$FFFF +} +void MemInitializeCustomF8ROM(void) +{ const UINT F8RomSize = 0x800; if (g_hCustomRomF8 != INVALID_HANDLE_VALUE) { + BYTE OldRom[Apple2RomSize]; // NB. 12KB on stack + memcpy(OldRom, memrom, Apple2RomSize); + SetFilePointer(g_hCustomRomF8, 0, NULL, FILE_BEGIN); DWORD uNumBytesRead; BOOL bRes = ReadFile(g_hCustomRomF8, memrom+Apple2RomSize-F8RomSize, F8RomSize, &uNumBytesRead, NULL); if (uNumBytesRead != F8RomSize) { - memcpy(memrom, pData, Apple2RomSize); // ROM at $D000...$FFFF + memcpy(memrom, OldRom, Apple2RomSize); // ROM at $D000...$FFFF bRes = FALSE; } @@ -1248,15 +1258,27 @@ void MemInitialize() if (sg_PropertySheet.GetTheFreezesF8Rom() && IS_APPLE2) { - hResInfo = FindResource(NULL, MAKEINTRESOURCE(IDR_FREEZES_F8_ROM), "ROM"); + HGLOBAL hResData = NULL; + BYTE* pData = NULL; + + HRSRC hResInfo = FindResource(NULL, MAKEINTRESOURCE(IDR_FREEZES_F8_ROM), "ROM"); if (hResInfo && (SizeofResource(NULL, hResInfo) == 0x800) && (hResData = LoadResource(NULL, hResInfo)) && (pData = (BYTE*) LockResource(hResData))) { memcpy(memrom+Apple2RomSize-F8RomSize, pData, F8RomSize); } } +} - // +// Called by: +// . MemInitialize() +// . Snapshot_LoadState_v2() +// +// Since called by LoadState(), then this must not init any cards +// - it should only init the card I/O hooks +void MemInitializeIO(void) +{ + InitIoHandlers(); const UINT uSlot = 0; RegisterIoHandler(uSlot, MemSetPaging, MemSetPaging, NULL, NULL, NULL, NULL); @@ -1297,8 +1319,6 @@ void MemInitialize() DiskLoadRom(pCxRomPeripheral, 6); // $C600 : Disk][ f/w HD_Load_Rom(pCxRomPeripheral, 7); // $C700 : HDD f/w - - MemReset(); } inline DWORD getRandomTime() @@ -1647,27 +1667,43 @@ LPVOID MemGetSlotParameters(UINT uSlot) // . If we were to save the state when 'modechanging' is set, then on restoring the state, the 6502 code will immediately update the read memory mode. // . This will work correctly. -DWORD MemGetSnapshot(SS_BaseMemory* pSS) +void MemSetSnapshot_v1(const DWORD MemMode, const BOOL LastWriteRam, const BYTE* const pMemMain, const BYTE* const pMemAux) { - pSS->dwMemMode = memmode; - pSS->bLastWriteRam = lastwriteram; + SetMemMode(MemMode); + lastwriteram = LastWriteRam; - for(DWORD dwOffset = 0x0000; dwOffset < 0x10000; dwOffset+=0x100) - { - memcpy(pSS->nMemMain+dwOffset, MemGetMainPtr((WORD)dwOffset), 0x100); - memcpy(pSS->nMemAux+dwOffset, MemGetAuxPtr((WORD)dwOffset), 0x100); - } - - return 0; -} - -DWORD MemSetSnapshot(SS_BaseMemory* pSS) -{ - SetMemMode(pSS->dwMemMode); - lastwriteram = pSS->bLastWriteRam; - - memcpy(memmain, pSS->nMemMain, nMemMainSize); - memcpy(memaux, pSS->nMemAux, nMemAuxSize); + memcpy(memmain, pMemMain, nMemMainSize); + memcpy(memaux, pMemAux, nMemAuxSize); + memset(memdirty, 0, 0x100); + + // + + modechanging = 0; + + UpdatePaging(1); // Initialize=1 +} + +// + +void MemGetSnapshot(SS_BaseMemory_v2& Memory) +{ + Memory.dwMemMode = memmode; + Memory.bLastWriteRam = lastwriteram; + + for(DWORD dwOffset = 0x0000; dwOffset < 0x10000; dwOffset+=0x100) + { + memcpy(Memory.MemMain+dwOffset, MemGetMainPtr((WORD)dwOffset), 0x100); + memcpy(Memory.MemAux+dwOffset, MemGetAuxPtr((WORD)dwOffset), 0x100); + } +} + +void MemSetSnapshot(const SS_BaseMemory_v2& Memory) +{ + SetMemMode(Memory.dwMemMode); + lastwriteram = Memory.bLastWriteRam; + + memcpy(memmain, Memory.MemMain, nMemMainSize); + memcpy(memaux, Memory.MemAux, nMemAuxSize); memset(memdirty, 0, 0x100); // @@ -1675,6 +1711,4 @@ DWORD MemSetSnapshot(SS_BaseMemory* pSS) modechanging = 0; UpdatePaging(1); // Initialize=1 - - return 0; } diff --git a/source/Memory.h b/source/Memory.h index 207cd1b1..bc5a0a53 100644 --- a/source/Memory.h +++ b/source/Memory.h @@ -44,14 +44,18 @@ LPBYTE MemGetMainPtr(const WORD); LPBYTE MemGetBankPtr(const UINT nBank); LPBYTE MemGetCxRomPeripheral(); void MemInitialize (); +void MemInitializeROM(void); +void MemInitializeCustomF8ROM(void); +void MemInitializeIO(void); BYTE MemReadFloatingBus(const ULONG uExecutedCycles); BYTE MemReadFloatingBus(const BYTE highbit, const ULONG uExecutedCycles); void MemReset (); void MemResetPaging (); void MemUpdatePaging(BOOL initialize); LPVOID MemGetSlotParameters (UINT uSlot); -DWORD MemGetSnapshot(SS_BaseMemory* pSS); -DWORD MemSetSnapshot(SS_BaseMemory* pSS); +void MemSetSnapshot_v1(const DWORD MemMode, const BOOL LastWriteRam, const BYTE* const pMemMain, const BYTE* const pMemAux); +void MemGetSnapshot(struct SS_BaseMemory_v2& Memory); +void MemSetSnapshot(const struct SS_BaseMemory_v2& Memory); BYTE __stdcall IO_Null(WORD programcounter, WORD address, BYTE write, BYTE value, ULONG nCycles); diff --git a/source/Mockingboard.cpp b/source/Mockingboard.cpp index 590c7870..405ad239 100644 --- a/source/Mockingboard.cpp +++ b/source/Mockingboard.cpp @@ -77,6 +77,8 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #include "StdAfx.h" +#include "SaveState_Structs_v1.h" + #include "AppleWin.h" #include "CPU.h" #include "Log.h" @@ -1761,13 +1763,15 @@ void MB_SetVolume(DWORD dwVolume, DWORD dwVolumeMax) //=========================================================================== -DWORD MB_GetSnapshot(SS_CARD_MOCKINGBOARD* pSS, DWORD dwSlot) +// Called by debugger - Debugger_Display.cpp +void MB_GetSnapshot_v1(SS_CARD_MOCKINGBOARD* const pSS, const DWORD dwSlot) { - pSS->Hdr.UnitHdr.dwLength = sizeof(SS_CARD_DISK2); - pSS->Hdr.UnitHdr.dwVersion = MAKE_VERSION(1,0,0,0); + pSS->Hdr.UnitHdr.hdr.v2.Length = sizeof(SS_CARD_MOCKINGBOARD); + pSS->Hdr.UnitHdr.hdr.v2.Type = UT_Card; + pSS->Hdr.UnitHdr.hdr.v2.Version = 1; - pSS->Hdr.dwSlot = dwSlot; - pSS->Hdr.dwType = CT_MockingboardC; + pSS->Hdr.Slot = dwSlot; + pSS->Hdr.Type = CT_MockingboardC; UINT nMbCardNum = dwSlot - SLOT4; UINT nDeviceNum = nMbCardNum*2; @@ -1783,16 +1787,14 @@ DWORD MB_GetSnapshot(SS_CARD_MOCKINGBOARD* pSS, DWORD dwSlot) nDeviceNum++; pMB++; } - - return 0; } -DWORD MB_SetSnapshot(SS_CARD_MOCKINGBOARD* pSS, DWORD /*dwSlot*/) +int MB_SetSnapshot_v1(const SS_CARD_MOCKINGBOARD* const pSS, const DWORD /*dwSlot*/) { - if(pSS->Hdr.UnitHdr.dwVersion != MAKE_VERSION(1,0,0,0)) + if(pSS->Hdr.UnitHdr.hdr.v1.dwVersion != MAKE_VERSION(1,0,0,0)) return -1; - UINT nMbCardNum = pSS->Hdr.dwSlot - SLOT4; + UINT nMbCardNum = pSS->Hdr.Slot - SLOT4; UINT nDeviceNum = nMbCardNum*2; SY6522_AY8910* pMB = &g_MB[nDeviceNum]; @@ -1832,3 +1834,111 @@ DWORD MB_SetSnapshot(SS_CARD_MOCKINGBOARD* pSS, DWORD /*dwSlot*/) return 0; } + +//=========================================================================== + +void MB_GetSnapshot(const HANDLE hFile, const UINT uSlot) +{ + SS_CARD_MOCKINGBOARD CardMockingboardC; + + SS_CARD_MOCKINGBOARD* const pSS = &CardMockingboardC; + + pSS->Hdr.UnitHdr.hdr.v2.Length = sizeof(SS_CARD_MOCKINGBOARD); + pSS->Hdr.UnitHdr.hdr.v2.Type = UT_Card; + pSS->Hdr.UnitHdr.hdr.v2.Version = 1; + + pSS->Hdr.Slot = uSlot; // fixme: object should be just 1 Mockingboard card & it will know its slot + pSS->Hdr.Type = CT_MockingboardC; + + UINT nMbCardNum = uSlot - SLOT4; + UINT nDeviceNum = nMbCardNum*2; + SY6522_AY8910* pMB = &g_MB[nDeviceNum]; + + for(UINT i=0; iUnit[i].RegsSY6522, &pMB->sy6522, sizeof(SY6522)); + memcpy(&pSS->Unit[i].RegsAY8910, AY8910_GetRegsPtr(nDeviceNum), 16); + memcpy(&pSS->Unit[i].RegsSSI263, &pMB->SpeechChip, sizeof(SSI263A)); + pSS->Unit[i].nAYCurrentRegister = pMB->nAYCurrentRegister; + + nDeviceNum++; + pMB++; + } + + // + + DWORD dwBytesWritten; + BOOL bRes = WriteFile( hFile, + &CardMockingboardC, + CardMockingboardC.Hdr.UnitHdr.hdr.v2.Length, + &dwBytesWritten, + NULL); + + if(!bRes || (dwBytesWritten != CardMockingboardC.Hdr.UnitHdr.hdr.v2.Length)) + { + //dwError = GetLastError(); + throw std::string("Save error: Mockingboard"); + } +} + +void MB_SetSnapshot(const HANDLE hFile) +{ + SS_CARD_MOCKINGBOARD CardMockingboardC; + + DWORD dwBytesRead; + BOOL bRes = ReadFile( hFile, + &CardMockingboardC, + sizeof(CardMockingboardC), + &dwBytesRead, + NULL); + + if (dwBytesRead != sizeof(CardMockingboardC)) + throw std::string("Card: file corrupt"); + + if (CardMockingboardC.Hdr.Slot != 4 && CardMockingboardC.Hdr.Slot != 5) // fixme + throw std::string("Card: wrong slot"); + + if (CardMockingboardC.Hdr.UnitHdr.hdr.v2.Version > 1) + throw std::string("Card: wrong version"); + + if (CardMockingboardC.Hdr.UnitHdr.hdr.v2.Length != sizeof(SS_CARD_MOCKINGBOARD)) + throw std::string("Card: unit size mismatch"); + + UINT nMbCardNum = CardMockingboardC.Hdr.Slot - SLOT4; + UINT nDeviceNum = nMbCardNum*2; + SY6522_AY8910* pMB = &g_MB[nDeviceNum]; + + g_nSSI263Device = 0; + g_nCurrentActivePhoneme = -1; + + for(UINT i=0; isy6522, &CardMockingboardC.Unit[i].RegsSY6522, sizeof(SY6522)); + memcpy(AY8910_GetRegsPtr(nDeviceNum), &CardMockingboardC.Unit[i].RegsAY8910, 16); + memcpy(&pMB->SpeechChip, &CardMockingboardC.Unit[i].RegsSSI263, sizeof(SSI263A)); + pMB->nAYCurrentRegister = CardMockingboardC.Unit[i].nAYCurrentRegister; + + StartTimer(pMB); // Attempt to start timer + + // + + // Crude - currently only support a single speech chip + // FIX THIS: + // . Speech chip could be Votrax instead + // . Is this IRQ compatible with Phasor? + if(pMB->SpeechChip.DurationPhonome) + { + g_nSSI263Device = nDeviceNum; + + if((pMB->SpeechChip.CurrentMode != MODE_IRQ_DISABLED) && (pMB->sy6522.PCR == 0x0C) && (pMB->sy6522.IER & IxR_PERIPHERAL)) + { + pMB->sy6522.IFR |= IxR_PERIPHERAL; + UpdateIFR(pMB); + pMB->SpeechChip.CurrentMode |= 1; // Set SSI263's D7 pin + } + } + + nDeviceNum++; + pMB++; + } +} diff --git a/source/Mockingboard.h b/source/Mockingboard.h index edd337b8..dc9f55c5 100644 --- a/source/Mockingboard.h +++ b/source/Mockingboard.h @@ -22,5 +22,8 @@ double MB_GetFramePeriod(); bool MB_IsActive(); DWORD MB_GetVolume(); void MB_SetVolume(DWORD dwVolume, DWORD dwVolumeMax); -DWORD MB_GetSnapshot(SS_CARD_MOCKINGBOARD* pSS, DWORD dwSlot); -DWORD MB_SetSnapshot(SS_CARD_MOCKINGBOARD* pSS, DWORD dwSlot); + +void MB_GetSnapshot_v1(struct SS_CARD_MOCKINGBOARD* const pSS, const DWORD dwSlot); // For debugger +int MB_SetSnapshot_v1(const struct SS_CARD_MOCKINGBOARD* const pSS, const DWORD dwSlot); +void MB_GetSnapshot(const HANDLE hFile, const UINT uSlot); +void MB_SetSnapshot(const HANDLE hFile); diff --git a/source/MouseInterface.cpp b/source/MouseInterface.cpp index 0805e3ff..442fed43 100644 --- a/source/MouseInterface.cpp +++ b/source/MouseInterface.cpp @@ -41,7 +41,7 @@ Etc. #include "stdafx.h" -#include "Structs.h" +#include "SaveState_Structs_common.h" #include "Common.h" #include "CPU.h" @@ -598,6 +598,166 @@ void CMouseInterface::SetButton(eBUTTON Button, eBUTTONSTATE State) OnMouseEvent(); } +struct MouseCard_Unit +{ + //6821 + mc6821_t mc6821; + BYTE byIA; + BYTE byIB; + + //MouseCard + int nDataLen; + BYTE byMode; + + BYTE by6821B; + BYTE by6821A; + BYTE byBuff[8]; + int nBuffPos; + + BYTE byState; + int nX; + int nY; + BOOL bBtn0; + BOOL bBtn1; + + bool bVBL; + + // + + int iX; + int iMinX; + int iMaxX; + int iY; + int iMinY; + int iMaxY; + + BOOL bButtons[2]; + + // + + bool bActive; // Mouse h/w is active within the Apple][ VM + bool bEnabled; // Windows' mouse events get passed to Apple]['s mouse h/w +}; + +struct SS_CARD_MOUSECARD +{ + SS_CARD_HDR Hdr; + MouseCard_Unit Unit; +}; + +// Post: +// 0 = No mouse card +// >0 = Mouse card saved OK from slot n +// -1 = File error +int CMouseInterface::GetSnapshot(const HANDLE hFile) +{ + if (!m_bActive) + return 0; + + SS_CARD_MOUSECARD CardMouseCard; + + CardMouseCard.Hdr.UnitHdr.hdr.v2.Length = sizeof(SS_CARD_MOUSECARD); + CardMouseCard.Hdr.UnitHdr.hdr.v2.Type = UT_Card; + CardMouseCard.Hdr.UnitHdr.hdr.v2.Version = 1; + + CardMouseCard.Hdr.Slot = m_uSlot; + CardMouseCard.Hdr.Type = CT_MouseInterface; + + MouseCard_Unit& Unit = CardMouseCard.Unit; + + m_6821.Get6821(Unit.mc6821, Unit.byIA, Unit.byIB); + + Unit.nDataLen = m_nDataLen; + Unit.byMode = m_byMode; + Unit.by6821B = m_by6821B; + Unit.by6821A = m_by6821A; + memcpy(Unit.byBuff, m_byBuff, sizeof(Unit.byBuff)); + Unit.nBuffPos = m_nBuffPos; + Unit.byState = m_byState; + Unit.nX = m_nX; + Unit.nY = m_nY; + Unit.bBtn0 = m_bBtn0; + Unit.bBtn1 = m_bBtn1; + Unit.bVBL = m_bVBL; + Unit.iX = m_iX; + Unit.iMinX = m_iMinX; + Unit.iMaxX = m_iMaxX; + Unit.iY = m_iY; + Unit.iMinY = m_iMinY; + Unit.iMaxY = m_iMaxY; + Unit.bButtons[0] = m_bButtons[0]; + Unit.bButtons[1] = m_bButtons[1]; + Unit.bActive = m_bActive; + Unit.bEnabled = m_bEnabled; + + // + + DWORD dwBytesWritten; + BOOL bRes = WriteFile( hFile, + &CardMouseCard, + CardMouseCard.Hdr.UnitHdr.hdr.v2.Length, + &dwBytesWritten, + NULL); + + if(!bRes || (dwBytesWritten != CardMouseCard.Hdr.UnitHdr.hdr.v2.Length)) + throw std::string("Save error: Mouse"); + + return m_uSlot; +} + +void CMouseInterface::SetSnapshot(const HANDLE hFile) +{ + SS_CARD_MOUSECARD CardMouseCard; + + DWORD dwBytesRead; + BOOL bRes = ReadFile( hFile, + &CardMouseCard, + sizeof(CardMouseCard), + &dwBytesRead, + NULL); + + if (dwBytesRead != sizeof(CardMouseCard)) + throw std::string("Card: file corrupt"); + + if (CardMouseCard.Hdr.Slot != 4) // fixme + throw std::string("Card: wrong slot"); + + if (CardMouseCard.Hdr.UnitHdr.hdr.v2.Version > 1) + throw std::string("Card: wrong version"); + + if (CardMouseCard.Hdr.UnitHdr.hdr.v2.Length != sizeof(SS_CARD_MOUSECARD)) + throw std::string("Card: unit size mismatch"); + + const MouseCard_Unit& Unit = CardMouseCard.Unit; + + m_6821.Set6821(Unit.mc6821, Unit.byIA, Unit.byIB); + + m_nDataLen = Unit.nDataLen; + m_byMode = Unit.byMode; + m_by6821B = Unit.by6821B; + m_by6821A = Unit.by6821A; + memcpy(m_byBuff, Unit.byBuff, sizeof(Unit.byBuff)); + m_nBuffPos = Unit.nBuffPos; + m_byState = Unit.byState; + m_nX = Unit.nX; + m_nY = Unit.nY; + m_bBtn0 = Unit.bBtn0; + m_bBtn1 = Unit.bBtn1; + m_bVBL = Unit.bVBL; + m_iX = Unit.iX; + m_iMinX = Unit.iMinX; + m_iMaxX = Unit.iMaxX; + m_iY = Unit.iY; + m_iMinY = Unit.iMinY; + m_iMaxY = Unit.iMaxY; + m_bButtons[0] = Unit.bButtons[0]; + m_bButtons[1] = Unit.bButtons[1]; + + m_bActive = Unit.bActive; + //m_bEnabled = Unit.bEnabled; + //m_uSlot = CardMouseCard.Hdr.Slot; +} + //============================================================================= // DirectInput interface //============================================================================= @@ -819,4 +979,4 @@ namespace DIMouse return S_OK; } -}; // namespace DIMouse \ No newline at end of file +}; // namespace DIMouse diff --git a/source/MouseInterface.h b/source/MouseInterface.h index 6c13a4f2..600b6321 100644 --- a/source/MouseInterface.h +++ b/source/MouseInterface.h @@ -12,7 +12,6 @@ public: void Initialize(LPBYTE pCxRomPeripheral, UINT uSlot); void Uninitialize(); void Reset(); - void SetSlotRom(); static BYTE __stdcall IORead(WORD PC, WORD uAddr, BYTE bWrite, BYTE uValue, ULONG nCyclesLeft); static BYTE __stdcall IOWrite(WORD PC, WORD uAddr, BYTE bWrite, BYTE uValue, ULONG nCyclesLeft); @@ -38,7 +37,11 @@ public: m_iY = iY; } + int GetSnapshot(const HANDLE hFile); + void SetSnapshot(const HANDLE hFile); + protected: + void SetSlotRom(); void On6821_A(BYTE byData); void On6821_B(BYTE byData); void OnCommand(); diff --git a/source/ParallelPrinter.cpp b/source/ParallelPrinter.cpp index 2ef531a6..a26498f4 100644 --- a/source/ParallelPrinter.cpp +++ b/source/ParallelPrinter.cpp @@ -36,18 +36,19 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #include "..\resource\resource.h" static DWORD inactivity = 0; +static int g_iPrinterIdleLimit = 10; static FILE* file = NULL; DWORD const PRINTDRVR_SIZE = APPLE_SLOT_SIZE; -TCHAR filepath[MAX_PATH * 2]; #define DEFAULT_PRINT_FILENAME "Printer.txt" static char g_szPrintFilename[MAX_PATH] = {0}; bool g_bDumpToPrinter = false; bool g_bConvertEncoding = true; bool g_bFilterUnprintable = true; bool g_bPrinterAppend = false; -int g_iPrinterIdleLimit = 10; bool g_bEnableDumpToRealPrinter = false; +static UINT g_uSlot = 0; + //=========================================================================== static BYTE __stdcall PrintStatus(WORD, WORD, BYTE, BYTE, ULONG); @@ -79,6 +80,8 @@ VOID PrintLoadRom(LPBYTE pCxRomPeripheral, const UINT uSlot) // RegisterIoHandler(uSlot, PrintStatus, PrintTransmit, NULL, NULL, NULL, NULL); + + g_uSlot = uSlot; } //=========================================================================== @@ -245,8 +248,110 @@ unsigned int Printer_GetIdleLimit() return g_iPrinterIdleLimit; } -//unsigned int void Printer_SetIdleLimit(unsigned int Duration) { g_iPrinterIdleLimit = Duration; } + +//=========================================================================== + +struct PrinterCard_Unit +{ + DWORD Inactivity; + UINT PrinterIdleLimit; + char PrintFilename[MAX_PATH]; + BOOL IsFileOpen; + BOOL DumpToPrinter; + BOOL ConvertEncoding; + BOOL FilterUnprintable; + BOOL PrinterAppend; + BOOL EnableDumpToRealPrinter; +}; + +struct SS_CARD_PRINTER +{ + SS_CARD_HDR Hdr; + PrinterCard_Unit Unit; +}; + +void Printer_GetSnapshot(const HANDLE hFile) +{ + SS_CARD_PRINTER CardPrinter; + + SS_CARD_PRINTER* const pSS = &CardPrinter; + + pSS->Hdr.UnitHdr.hdr.v2.Length = sizeof(SS_CARD_PRINTER); + pSS->Hdr.UnitHdr.hdr.v2.Type = UT_Card; + pSS->Hdr.UnitHdr.hdr.v2.Version = 1; + + pSS->Hdr.Slot = g_uSlot; + pSS->Hdr.Type = CT_GenericPrinter; + + CardPrinter.Unit.Inactivity = inactivity; + CardPrinter.Unit.PrinterIdleLimit = g_iPrinterIdleLimit; + memcpy(CardPrinter.Unit.PrintFilename, g_szPrintFilename, sizeof(CardPrinter.Unit.PrintFilename)); + CardPrinter.Unit.IsFileOpen = (file != NULL); + CardPrinter.Unit.DumpToPrinter = g_bDumpToPrinter; + CardPrinter.Unit.ConvertEncoding = g_bConvertEncoding; + CardPrinter.Unit.FilterUnprintable = g_bFilterUnprintable; + CardPrinter.Unit.PrinterAppend = g_bPrinterAppend; + CardPrinter.Unit.EnableDumpToRealPrinter = g_bEnableDumpToRealPrinter; + + // + + DWORD dwBytesWritten; + BOOL bRes = WriteFile( hFile, + &CardPrinter, + CardPrinter.Hdr.UnitHdr.hdr.v2.Length, + &dwBytesWritten, + NULL); + + if(!bRes || (dwBytesWritten != CardPrinter.Hdr.UnitHdr.hdr.v2.Length)) + { + //dwError = GetLastError(); + throw std::string("Save error: Printer Card"); + } +} + +void Printer_SetSnapshot(const HANDLE hFile) +{ + SS_CARD_PRINTER CardPrinter; + + DWORD dwBytesRead; + BOOL bRes = ReadFile( hFile, + &CardPrinter, + sizeof(CardPrinter), + &dwBytesRead, + NULL); + + if (dwBytesRead != sizeof(CardPrinter)) + throw std::string("Card: file corrupt"); + + if (CardPrinter.Hdr.Slot != 1) // fixme + throw std::string("Card: wrong slot"); + + if (CardPrinter.Hdr.UnitHdr.hdr.v2.Version > 1) + throw std::string("Card: wrong version"); + + if (CardPrinter.Hdr.UnitHdr.hdr.v2.Length != sizeof(SS_CARD_PRINTER)) + throw std::string("Card: unit size mismatch"); + + ClosePrint(); // Close current print session (and close file handle) + + inactivity = CardPrinter.Unit.Inactivity; + g_iPrinterIdleLimit = CardPrinter.Unit.PrinterIdleLimit; + memcpy(g_szPrintFilename, CardPrinter.Unit.PrintFilename, sizeof(g_szPrintFilename)); + if (CardPrinter.Unit.IsFileOpen) + { + g_bPrinterAppend = true; // Re-open print-file in append mode + BOOL bRes = CheckPrint(); + if (!bRes) + throw std::string("Printer Card: Unable to resume printing to file"); + } + + g_bDumpToPrinter = CardPrinter.Unit.DumpToPrinter == TRUE; + g_bConvertEncoding = CardPrinter.Unit.ConvertEncoding == TRUE; + g_bFilterUnprintable = CardPrinter.Unit.FilterUnprintable == TRUE; + g_bPrinterAppend = CardPrinter.Unit.PrinterAppend == TRUE; + g_bEnableDumpToRealPrinter = CardPrinter.Unit.EnableDumpToRealPrinter == TRUE; +} diff --git a/source/ParallelPrinter.h b/source/ParallelPrinter.h index d2936a13..fc227231 100644 --- a/source/ParallelPrinter.h +++ b/source/ParallelPrinter.h @@ -9,11 +9,11 @@ char* Printer_GetFilename(); void Printer_SetIdleLimit(unsigned int Duration); unsigned int Printer_GetIdleLimit(); +void Printer_GetSnapshot(const HANDLE hFile); +void Printer_SetSnapshot(const HANDLE hFile); + extern bool g_bDumpToPrinter; extern bool g_bConvertEncoding; extern bool g_bFilterUnprintable; extern bool g_bPrinterAppend; -extern int g_iPrinterIdleLimit; -extern bool g_bFilterUnprintable; -extern bool g_bPrinterAppend; extern bool g_bEnableDumpToRealPrinter; // Set by cmd-line: -printer-real diff --git a/source/SaveState.cpp b/source/SaveState.cpp index 5c38beed..4229fc15 100644 --- a/source/SaveState.cpp +++ b/source/SaveState.cpp @@ -23,11 +23,14 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA /* Description: Save-state (snapshot) module * - * Author: Copyright (c) 2004-2006 Tom Charlesworth + * Author: Copyright (c) 2004-2015 Tom Charlesworth */ #include "StdAfx.h" +#include "SaveState_Structs_v1.h" +#include "SaveState_Structs_v2.h" + #include "AppleWin.h" #include "CPU.h" #include "Disk.h" @@ -36,10 +39,15 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #include "Keyboard.h" #include "Memory.h" #include "Mockingboard.h" +#include "MouseInterface.h" +#include "ParallelPrinter.h" #include "SerialComms.h" #include "Speaker.h" #include "Video.h" +#include "Configuration\Config.h" +#include "Configuration\IPropertySheet.h" + #define DEFAULT_SNAPSHOT_NAME "SaveState.aws" @@ -93,22 +101,27 @@ const char* Snapshot_GetPath() //----------------------------------------------------------------------------- -void Snapshot_LoadState() +static void Snapshot_LoadState_v1() // .aws v1.0.0.1, up to (and including) AppleWin v1.25.0 { - char szMessage[32 + MAX_PATH]; - std::string strOldImageDir; + std::string strOldImageDir(g_sCurrentDir); - APPLEWIN_SNAPSHOT* pSS = (APPLEWIN_SNAPSHOT*) new char[sizeof(APPLEWIN_SNAPSHOT)]; + APPLEWIN_SNAPSHOT_v1* pSS = (APPLEWIN_SNAPSHOT_v1*) new char[sizeof(APPLEWIN_SNAPSHOT_v1)]; // throw's bad_alloc try { - strOldImageDir = g_sCurrentDir; +#if _MSC_VER >= 1600 // static_assert supported from VS2010 (cl.exe v16.00) + static_assert(kSnapshotSize_v1 == sizeof(APPLEWIN_SNAPSHOT_v1), "Save-state v1 struct size mismatch"); +#else + // A compile error here means sizeof(APPLEWIN_SNAPSHOT_v1) is wrong, eg. one of the constituent structs has been modified + typedef char VerifySizesAreEqual[kSnapshotSize_v1 == sizeof(APPLEWIN_SNAPSHOT_v1) ? 1 : -1]; +#endif + + if (kSnapshotSize_v1 != sizeof(APPLEWIN_SNAPSHOT_v1)) + throw std::string("Save-state v1 struct size mismatch"); + SetCurrentImageDir(g_strSaveStatePath.c_str()); // Allow .dsk's load without prompting - if(pSS == NULL) - throw(0); - - memset(pSS, 0, sizeof(APPLEWIN_SNAPSHOT)); + memset(pSS, 0, sizeof(APPLEWIN_SNAPSHOT_v1)); // @@ -121,39 +134,26 @@ void Snapshot_LoadState() NULL); if(hFile == INVALID_HANDLE_VALUE) - { - strcpy(szMessage, "File not found: "); - strcpy(szMessage + strlen(szMessage), g_strSaveStatePathname.c_str()); - throw(0); - } + throw std::string("File not found: ") + g_strSaveStatePathname; DWORD dwBytesRead; BOOL bRes = ReadFile( hFile, pSS, - sizeof(APPLEWIN_SNAPSHOT), + sizeof(APPLEWIN_SNAPSHOT_v1), &dwBytesRead, NULL); CloseHandle(hFile); - if(!bRes || (dwBytesRead != sizeof(APPLEWIN_SNAPSHOT))) - { + if(!bRes || (dwBytesRead != sizeof(APPLEWIN_SNAPSHOT_v1))) // File size wrong: probably because of version mismatch or corrupt file - strcpy(szMessage, "File size mismatch"); - throw(0); - } + throw std::string("File size mismatch"); if(pSS->Hdr.dwTag != AW_SS_TAG) - { - strcpy(szMessage, "File corrupt"); - throw(0); - } + throw std::string("File corrupt"); if(pSS->Hdr.dwVersion != MAKE_VERSION(1,0,0,1)) - { - strcpy(szMessage, "Version mismatch"); - throw(0); - } + throw std::string("Version mismatch"); // TO DO: Verify checksum @@ -173,34 +173,40 @@ void Snapshot_LoadState() // Apple2 unit // - CpuSetSnapshot(&pSS->Apple2Unit.CPU6502); - sg_SSC.CommSetSnapshot(&pSS->Apple2Unit.Comms); - JoySetSnapshot(&pSS->Apple2Unit.Joystick); - KeybSetSnapshot(&pSS->Apple2Unit.Keyboard); - SpkrSetSnapshot(&pSS->Apple2Unit.Speaker); - VideoSetSnapshot(&pSS->Apple2Unit.Video); - MemSetSnapshot(&pSS->Apple2Unit.Memory); + SS_CPU6502& CPU = pSS->Apple2Unit.CPU6502; + CpuSetSnapshot_v1(CPU.A, CPU.X, CPU.Y, CPU.P, CPU.S, CPU.PC, CPU.nCumulativeCycles); + + SS_IO_Comms& SSC = pSS->Apple2Unit.Comms; + sg_SSC.SetSnapshot_v1(SSC.baudrate, SSC.bytesize, SSC.commandbyte, SSC.comminactivity, SSC.controlbyte, SSC.parity, SSC.stopbits); + + JoySetSnapshot_v1(pSS->Apple2Unit.Joystick.nJoyCntrResetCycle); + KeybSetSnapshot_v1(pSS->Apple2Unit.Keyboard.nLastKey); + SpkrSetSnapshot_v1(pSS->Apple2Unit.Speaker.nSpkrLastCycle); + VideoSetSnapshot_v1(pSS->Apple2Unit.Video.bAltCharSet, pSS->Apple2Unit.Video.dwVidMode); + MemSetSnapshot_v1(pSS->Apple2Unit.Memory.dwMemMode, pSS->Apple2Unit.Memory.bLastWriteRam, pSS->Apple2Unit.Memory.nMemMain, pSS->Apple2Unit.Memory.nMemAux); // // // Slot4: Mockingboard - MB_SetSnapshot(&pSS->Mockingboard1, 4); + MB_SetSnapshot_v1(&pSS->Mockingboard1, 4); // // Slot5: Mockingboard - MB_SetSnapshot(&pSS->Mockingboard2, 5); + MB_SetSnapshot_v1(&pSS->Mockingboard2, 5); // // Slot6: Disk][ - DiskSetSnapshot(&pSS->Disk2, 6); + DiskSetSnapshot_v1(&pSS->Disk2); SetLoadedSaveStateFlag(true); + + MemUpdatePaging(TRUE); } - catch(int) + catch(std::string szMessage) { MessageBox( g_hFrameWindow, - szMessage, + szMessage.c_str(), TEXT("Load State"), MB_ICONEXCLAMATION | MB_SETFOREGROUND); @@ -212,104 +218,429 @@ void Snapshot_LoadState() //----------------------------------------------------------------------------- -void Snapshot_SaveState() +HANDLE m_hFile = INVALID_HANDLE_VALUE; +CConfigNeedingRestart m_ConfigNew; + +static void Snapshot_LoadState_FileHdr(SS_FILE_HDR& Hdr) { - APPLEWIN_SNAPSHOT* pSS = (APPLEWIN_SNAPSHOT*) new char[sizeof(APPLEWIN_SNAPSHOT)]; - if(pSS == NULL) + try { - // To do + m_hFile = CreateFile( g_strSaveStatePathname.c_str(), + GENERIC_READ, + 0, + NULL, + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, + NULL); + + if(m_hFile == INVALID_HANDLE_VALUE) + throw std::string("File not found: ") + g_strSaveStatePathname; + + DWORD dwBytesRead; + BOOL bRes = ReadFile( m_hFile, + &Hdr, + sizeof(Hdr), + &dwBytesRead, + NULL); + + if(!bRes || (dwBytesRead != sizeof(Hdr))) + throw std::string("File size mismatch"); + + if(Hdr.dwTag != AW_SS_TAG) + throw std::string("File corrupt"); + } + catch(std::string szMessage) + { + MessageBox( g_hFrameWindow, + szMessage.c_str(), + TEXT("Load State"), + MB_ICONEXCLAMATION | MB_SETFOREGROUND); + + if(m_hFile == INVALID_HANDLE_VALUE) + { + CloseHandle(m_hFile); + m_hFile = INVALID_HANDLE_VALUE; + } + } +} + +#define UNIT_APPLE2_VER 1 +#define UNIT_CARD_VER 1 +#define UNIT_CONFIG_VER 1 + +static void LoadUnitApple2(DWORD Length, DWORD Version) +{ + SS_APPLE2_Unit_v2 Apple2Unit; + + if (Version != UNIT_APPLE2_VER) + throw std::string("Apple2: Version mismatch"); + + if (Length != sizeof(Apple2Unit)) + throw std::string("Apple2: Length mismatch"); + + if (SetFilePointer(m_hFile, -(LONG)sizeof(Apple2Unit.UnitHdr), NULL, FILE_CURRENT) == INVALID_SET_FILE_POINTER) + throw std::string("Apple2: file corrupt"); + + DWORD dwBytesRead; + BOOL bRes = ReadFile( m_hFile, + &Apple2Unit, + Length, + &dwBytesRead, + NULL); + + if (dwBytesRead != Length) + throw std::string("Apple2: file corrupt"); + + g_Apple2Type = (eApple2Type) Apple2Unit.Apple2Type; + m_ConfigNew.m_Apple2Type = g_Apple2Type; + + CpuSetSnapshot(Apple2Unit.CPU6502); + JoySetSnapshot(Apple2Unit.Joystick.JoyCntrResetCycle); + KeybSetSnapshot(Apple2Unit.Keyboard.LastKey); + SpkrSetSnapshot(Apple2Unit.Speaker.SpkrLastCycle); + VideoSetSnapshot(Apple2Unit.Video); + MemSetSnapshot(Apple2Unit.Memory); +} + +//=== + +static void LoadCardDisk2(void) +{ + DiskSetSnapshot(m_hFile); +} + +static void LoadCardMockingboardC(void) +{ + MB_SetSnapshot(m_hFile); +} + +static void LoadCardMouseInterface(void) +{ + sg_Mouse.SetSnapshot(m_hFile); +} + +static void LoadCardSSC(void) +{ + sg_SSC.SetSnapshot(m_hFile); +} + +static void LoadCardPrinter(void) +{ + Printer_SetSnapshot(m_hFile); +} + +static void LoadCardHDD(void) +{ + HD_SetSnapshot(m_hFile, g_strSaveStatePath); + m_ConfigNew.m_bEnableHDD = true; +} + +//=== + +static void LoadUnitCard(DWORD Length, DWORD Version) +{ + SS_CARD_HDR Card; + + if (Version != UNIT_APPLE2_VER) + throw std::string("Card: Version mismatch"); + + if (Length < sizeof(Card)) + throw std::string("Card: file corrupt"); + + if (SetFilePointer(m_hFile, -(LONG)sizeof(Card.UnitHdr), NULL, FILE_CURRENT) == INVALID_SET_FILE_POINTER) + throw std::string("Card: file corrupt"); + + DWORD dwBytesRead; + BOOL bRes = ReadFile( m_hFile, + &Card, + sizeof(Card), + &dwBytesRead, + NULL); + + if (dwBytesRead != sizeof(Card)) + throw std::string("Card: file corrupt"); + + //currently cards are changed by restarting machine (ie. all slot empty) then adding cards (most of which are hardcoded to specific slots) + + if (SetFilePointer(m_hFile, -(LONG)sizeof(SS_CARD_HDR), NULL, FILE_CURRENT) == INVALID_SET_FILE_POINTER) + throw std::string("Card: file corrupt"); + + bool bIsCardSupported = true; + + switch(Card.Type) + { + case CT_Empty: + throw std::string("Card: todo"); + break; + case CT_Disk2: + LoadCardDisk2(); + break; + case CT_SSC: + LoadCardSSC(); + break; + case CT_MockingboardC: + LoadCardMockingboardC(); + break; + case CT_GenericPrinter: + LoadCardPrinter(); + break; + case CT_GenericHDD: + LoadCardHDD(); + break; + case CT_MouseInterface: + LoadCardMouseInterface(); + break; + case CT_Z80: + throw std::string("Card: todo"); + break; + case CT_Phasor: + throw std::string("Card: todo"); + break; + default: + //throw std::string("Card: unsupported"); + bIsCardSupported = false; + if (SetFilePointer(m_hFile, Card.UnitHdr.hdr.v2.Length, NULL, FILE_CURRENT) == INVALID_SET_FILE_POINTER) + throw std::string("Card: failed to skip unsupported card"); + } + + if (bIsCardSupported) + m_ConfigNew.m_Slot[Card.Slot] = (SS_CARDTYPE) Card.Type; +} + +static void LoadUnitConfig(DWORD Length, DWORD Version) +{ + SS_APPLEWIN_CONFIG Cfg; + + if (Version != UNIT_CONFIG_VER) + throw std::string("Config: Version mismatch"); + + if (Length != sizeof(Cfg)) + throw std::string("Config: Length mismatch"); + + if (SetFilePointer(m_hFile, -(LONG)sizeof(Cfg.UnitHdr), NULL, FILE_CURRENT) == INVALID_SET_FILE_POINTER) + throw std::string("Config: file corrupt"); + + DWORD dwBytesRead; + BOOL bRes = ReadFile( m_hFile, + &Cfg, + Length, + &dwBytesRead, + NULL); + + if (dwBytesRead != Length) + throw std::string("Config: file corrupt"); + + // todo: + //m_ConfigNew.m_bEnhanceDisk; + //m_ConfigNew.m_bEnableHDD; +} + +static void Snapshot_LoadState_v2(DWORD dwVersion) +{ + try + { + if (dwVersion != MAKE_VERSION(2,0,0,0)) + throw std::string("Version mismatch"); + + CConfigNeedingRestart ConfigOld; + ConfigOld.m_Slot[1] = CT_GenericPrinter; // fixme + ConfigOld.m_Slot[2] = CT_SSC; // fixme + ConfigOld.m_Slot[6] = CT_Disk2; // fixme + ConfigOld.m_Slot[7] = ConfigOld.m_bEnableHDD ? CT_GenericHDD : CT_Empty; // fixme + + for (UINT i=0; iHdr.dwTag = AW_SS_TAG; - pSS->Hdr.dwVersion = MAKE_VERSION(1,0,0,1); - pSS->Hdr.dwChecksum = 0; // TO DO +//----------------------------------------------------------------------------- - // - // Apple2 unit - // - - pSS->Apple2Unit.UnitHdr.dwLength = sizeof(SS_APPLE2_Unit); - pSS->Apple2Unit.UnitHdr.dwVersion = MAKE_VERSION(1,0,0,0); - - CpuGetSnapshot(&pSS->Apple2Unit.CPU6502); - sg_SSC.CommGetSnapshot(&pSS->Apple2Unit.Comms); - JoyGetSnapshot(&pSS->Apple2Unit.Joystick); - KeybGetSnapshot(&pSS->Apple2Unit.Keyboard); - SpkrGetSnapshot(&pSS->Apple2Unit.Speaker); - VideoGetSnapshot(&pSS->Apple2Unit.Video); - MemGetSnapshot(&pSS->Apple2Unit.Memory); - - // - // Slot1: Empty - pSS->Empty1.Hdr.UnitHdr.dwLength = sizeof(SS_CARD_EMPTY); - pSS->Empty1.Hdr.UnitHdr.dwVersion = MAKE_VERSION(1,0,0,0); - pSS->Empty1.Hdr.dwSlot = 1; - pSS->Empty1.Hdr.dwType = CT_Empty; - - // - // Slot2: Empty - pSS->Empty2.Hdr.UnitHdr.dwLength = sizeof(SS_CARD_EMPTY); - pSS->Empty2.Hdr.UnitHdr.dwVersion = MAKE_VERSION(1,0,0,0); - pSS->Empty2.Hdr.dwSlot = 2; - pSS->Empty2.Hdr.dwType = CT_Empty; - - // - // Slot3: Empty - pSS->Empty3.Hdr.UnitHdr.dwLength = sizeof(SS_CARD_EMPTY); - pSS->Empty3.Hdr.UnitHdr.dwVersion = MAKE_VERSION(1,0,0,0); - pSS->Empty3.Hdr.dwSlot = 3; - pSS->Empty3.Hdr.dwType = CT_Empty; - - // - // Slot4: Mockingboard - MB_GetSnapshot(&pSS->Mockingboard1, 4); - - // - // Slot5: Mockingboard - MB_GetSnapshot(&pSS->Mockingboard2, 5); - - // - // Slot6: Disk][ - DiskGetSnapshot(&pSS->Disk2, 6); - - // - - HANDLE hFile = CreateFile( g_strSaveStatePathname.c_str(), - GENERIC_WRITE, - 0, - NULL, - CREATE_ALWAYS, - FILE_ATTRIBUTE_NORMAL, - NULL); - - DWORD dwError = GetLastError(); - _ASSERT((dwError == 0) || (dwError == ERROR_ALREADY_EXISTS)); - - if(hFile != INVALID_HANDLE_VALUE) +void Snapshot_SaveState() +{ + try { + // todo: append '.aws' if missing + + m_hFile = CreateFile( g_strSaveStatePathname.c_str(), + GENERIC_WRITE, + 0, + NULL, + CREATE_ALWAYS, + FILE_ATTRIBUTE_NORMAL, + NULL); + + DWORD dwError = GetLastError(); + _ASSERT((dwError == 0) || (dwError == ERROR_ALREADY_EXISTS)); + + // todo: handle ERROR_ALREADY_EXISTS - ask if user wants to replace existing file + + if(m_hFile == INVALID_HANDLE_VALUE) + { + //dwError = GetLastError(); + throw std::string("Save error"); + } + + // + + APPLEWIN_SNAPSHOT_v2 AppleSnapshotv2; + + AppleSnapshotv2.Hdr.dwTag = AW_SS_TAG; + AppleSnapshotv2.Hdr.dwVersion = MAKE_VERSION(2,0,0,0); + AppleSnapshotv2.Hdr.dwChecksum = 0; // TO DO + + SS_APPLE2_Unit_v2& Apple2Unit = AppleSnapshotv2.Apple2Unit; + + // + // Apple2 unit + // + + Apple2Unit.UnitHdr.hdr.v2.Length = sizeof(SS_APPLE2_Unit_v2); + Apple2Unit.UnitHdr.hdr.v2.Type = UT_Apple2; + Apple2Unit.UnitHdr.hdr.v2.Version = UNIT_APPLE2_VER; + + Apple2Unit.Apple2Type = g_Apple2Type; + + CpuGetSnapshot(Apple2Unit.CPU6502); + JoyGetSnapshot(Apple2Unit.Joystick.JoyCntrResetCycle); + KeybGetSnapshot(Apple2Unit.Keyboard.LastKey); + SpkrGetSnapshot(Apple2Unit.Speaker.SpkrLastCycle); + VideoGetSnapshot(Apple2Unit.Video); + MemGetSnapshot(Apple2Unit.Memory); + DWORD dwBytesWritten; - BOOL bRes = WriteFile( hFile, - pSS, - sizeof(APPLEWIN_SNAPSHOT), + BOOL bRes = WriteFile( m_hFile, + &AppleSnapshotv2, + sizeof(APPLEWIN_SNAPSHOT_v2), &dwBytesWritten, NULL); - if(!bRes || (dwBytesWritten != sizeof(APPLEWIN_SNAPSHOT))) - dwError = GetLastError(); + if(!bRes || (dwBytesWritten != sizeof(APPLEWIN_SNAPSHOT_v2))) + { + //dwError = GetLastError(); + throw std::string("Save error"); + } - CloseHandle(hFile); + // + + Printer_GetSnapshot(m_hFile); + + sg_SSC.GetSnapshot(m_hFile); + + sg_Mouse.GetSnapshot(m_hFile); + + if (g_Slot4 == CT_MockingboardC) + MB_GetSnapshot(m_hFile, 4); + + if (g_Slot5 == CT_MockingboardC) + MB_GetSnapshot(m_hFile, 5); + + DiskGetSnapshot(m_hFile); + + HD_GetSnapshot(m_hFile); } - else + catch(std::string szMessage) { - dwError = GetLastError(); + MessageBox( g_hFrameWindow, + szMessage.c_str(), + TEXT("Save State"), + MB_ICONEXCLAMATION | MB_SETFOREGROUND); } - _ASSERT((dwError == 0) || (dwError == ERROR_ALREADY_EXISTS)); - - delete [] pSS; + CloseHandle(m_hFile); + m_hFile = INVALID_HANDLE_VALUE; } //----------------------------------------------------------------------------- diff --git a/source/SaveState_Structs_common.h b/source/SaveState_Structs_common.h new file mode 100644 index 00000000..3732d558 --- /dev/null +++ b/source/SaveState_Structs_common.h @@ -0,0 +1,77 @@ +#pragma once + +// Structs used by save-state file + +// *** DON'T CHANGE ANY STRUCT WITHOUT CONSIDERING BACKWARDS COMPATIBILITY WITH .AWS FORMAT *** + +///////////////////////////////////////////////////////////////////////////////// + +#define MAKE_VERSION(a,b,c,d) ((a<<24) | (b<<16) | (c<<8) | (d)) + +#define AW_SS_TAG 'SSWA' // 'AWSS' = AppleWin SnapShot + +struct SS_FILE_HDR +{ + DWORD dwTag; // "AWSS" + DWORD dwVersion; + DWORD dwChecksum; +}; + +struct SS_UNIT_HDR +{ + union + { + struct + { + DWORD dwLength; // Byte length of this unit struct + DWORD dwVersion; + } v1; + struct + { + DWORD Length; // Byte length of this unit struct + WORD Type; // SS_UNIT_TYPE + WORD Version; // Incrementing value from 1 + } v2; + } hdr; +}; + +enum SS_UNIT_TYPE +{ + UT_Reserved = 0, + UT_Apple2, + UT_Card, + UT_Config, +}; + +const UINT nMemMainSize = 64*1024; +const UINT nMemAuxSize = 64*1024; + +struct SS_CARD_HDR +{ + SS_UNIT_HDR UnitHdr; + DWORD Type; // SS_CARDTYPE + DWORD Slot; // [1..7], 0=Language card, 8=Aux +}; + +enum SS_CARDTYPE +{ + CT_Empty = 0, + CT_Disk2, // Apple Disk][ + CT_SSC, // Apple Super Serial Card + CT_MockingboardC, // Soundcard + CT_GenericPrinter, + CT_GenericHDD, // Hard disk + CT_GenericClock, + CT_MouseInterface, + CT_Z80, + CT_Phasor, // Soundcard + CT_Echo, // Soundcard + CT_SAM, // Soundcard: Software Automated Mouth +}; + +///////////////////////////////////////////////////////////////////////////////// + +struct SS_CARD_EMPTY +{ + SS_CARD_HDR Hdr; +}; diff --git a/source/Structs.h b/source/SaveState_Structs_v1.h similarity index 56% rename from source/Structs.h rename to source/SaveState_Structs_v1.h index f2af25ac..f4c84645 100644 --- a/source/Structs.h +++ b/source/SaveState_Structs_v1.h @@ -1,34 +1,15 @@ #pragma once #include "DiskDefs.h" +#include "SaveState_Structs_common.h" -// Structs used by save-state file +// Structs used by save-state file v1 // *** DON'T CHANGE ANY STRUCT WITHOUT CONSIDERING BACKWARDS COMPATIBILITY WITH .AWS FORMAT *** -#define MAKE_VERSION(a,b,c,d) ((a<<24) | (b<<16) | (c<<8) | (d)) - -#define AW_SS_TAG 'SSWA' // 'AWSS' = AppleWin SnapShot - -typedef struct -{ - DWORD dwTag; // "AWSS" - DWORD dwVersion; - DWORD dwChecksum; -} SS_FILE_HDR; - -typedef struct -{ - DWORD dwLength; // Byte length of this unit struct - DWORD dwVersion; -} SS_UNIT_HDR; - ///////////////////////////////////////////////////////////////////////////////// -const UINT nMemMainSize = 64*1024; -const UINT nMemAuxSize = 64*1024; - -typedef struct +struct SS_CPU6502 { BYTE A; BYTE X; @@ -36,13 +17,13 @@ typedef struct BYTE P; BYTE S; USHORT PC; - unsigned __int64 g_nCumulativeCycles; + unsigned __int64 nCumulativeCycles; // IRQ = OR-sum of all interrupt sources -} SS_CPU6502; +}; const UINT uRecvBufferSize = 9; -typedef struct +struct SS_IO_Comms { DWORD baudrate; BYTE bytesize; @@ -53,121 +34,53 @@ typedef struct BYTE recvbuffer[uRecvBufferSize]; DWORD recvbytes; BYTE stopbits; -} SS_IO_Comms; +}; -typedef struct +struct SS_IO_Joystick { - unsigned __int64 g_nJoyCntrResetCycle; -} SS_IO_Joystick; + unsigned __int64 nJoyCntrResetCycle; +}; -typedef struct +struct SS_IO_Keyboard { DWORD keyboardqueries; BYTE nLastKey; -} SS_IO_Keyboard; +}; -//typedef struct -//{ -//} SS_IO_Memory; - -typedef struct +struct SS_IO_Speaker { - unsigned __int64 g_nSpkrLastCycle; -} SS_IO_Speaker; + unsigned __int64 nSpkrLastCycle; +}; -typedef struct +struct SS_IO_Video { bool bAltCharSet; // charoffs DWORD dwVidMode; -} SS_IO_Video; +}; -typedef struct +struct SS_BaseMemory { DWORD dwMemMode; BOOL bLastWriteRam; BYTE nMemMain[nMemMainSize]; BYTE nMemAux[nMemAuxSize]; -} SS_BaseMemory; +}; -typedef struct +struct SS_APPLE2_Unit { SS_UNIT_HDR UnitHdr; SS_CPU6502 CPU6502; SS_IO_Comms Comms; SS_IO_Joystick Joystick; SS_IO_Keyboard Keyboard; -// SS_IO_Memory Memory; SS_IO_Speaker Speaker; SS_IO_Video Video; SS_BaseMemory Memory; -} SS_APPLE2_Unit; - -///////////////////////////////////////////////////////////////////////////////// - -typedef struct -{ - DWORD dwComputerEmulation; - bool bCustomSpeed; - DWORD dwEmulationSpeed; - bool bEnhancedDiskSpeed; - DWORD dwJoystickType[2]; - bool bMockingboardEnabled; - DWORD dwMonochromeColor; - DWORD dwSerialPort; - DWORD dwSoundType; // Sound Emulation - DWORD dwVideoType; // Video Emulation -} SS_AW_CFG; - -typedef struct -{ - char StartingDir[MAX_PATH]; - DWORD dwWindowXpos; - DWORD dwWindowYpos; -} SS_AW_PREFS; - -typedef struct -{ - SS_UNIT_HDR UnitHdr; - DWORD dwAppleWinVersion; - SS_AW_PREFS Prefs; - SS_AW_CFG Cfg; -} SS_APPLEWIN_CONFIG; - -///////////////////////////////////////////////////////////////////////////////// - -typedef struct -{ - SS_UNIT_HDR UnitHdr; - DWORD dwType; // SS_CARDTYPE - DWORD dwSlot; // [1..7] -} SS_CARD_HDR; - -enum SS_CARDTYPE -{ - CT_Empty = 0, - CT_Disk2, // Apple Disk][ - CT_SSC, // Apple Super Serial Card - CT_MockingboardC, // Soundcard - CT_GenericPrinter, - CT_GenericHDD, // Hard disk - CT_GenericClock, - CT_MouseInterface, - CT_Z80, - CT_Phasor, // Soundcard - CT_Echo, // Soundcard - CT_SAM, // Soundcard: Software Automated Mouth }; ///////////////////////////////////////////////////////////////////////////////// -typedef struct -{ - SS_CARD_HDR Hdr; -} SS_CARD_EMPTY; - -///////////////////////////////////////////////////////////////////////////////// - -typedef struct +struct DISK2_Unit { char szFileName[MAX_PATH]; int track; @@ -180,9 +93,9 @@ typedef struct DWORD writelight; int nibbles; BYTE nTrack[NIBBLES_PER_TRACK]; -} DISK2_Unit; +}; -typedef struct +struct SS_CARD_DISK2 { SS_CARD_HDR Hdr; DISK2_Unit Unit[2]; @@ -193,11 +106,11 @@ typedef struct BYTE floppylatch; BOOL floppymotoron; BOOL floppywritemode; -} SS_CARD_DISK2; +}; ///////////////////////////////////////////////////////////////////////////////// -typedef struct +struct IWORD { union { @@ -208,9 +121,9 @@ typedef struct }; USHORT w; }; -} IWORD; +}; -typedef struct +struct SY6522 { BYTE ORB; // $00 - Port B BYTE ORA; // $01 - Port A (with handshaking) @@ -234,9 +147,9 @@ typedef struct BYTE IFR; // $0D - Interrupt Flag Register BYTE IER; // $0E - Interrupt Enable Register BYTE ORA_NO_HS; // $0F - Port A (without handshaking) -} SY6522; +}; -typedef struct +struct SSI263A { BYTE DurationPhonome; BYTE Inflection; // I10..I3 @@ -245,9 +158,9 @@ typedef struct BYTE FilterFreq; // BYTE CurrentMode; // b7:6=Mode; b0=D7 pin (for IRQ) -} SSI263A; +}; -typedef struct +struct MB_Unit { SY6522 RegsSY6522; BYTE RegsAY8910[16]; @@ -256,23 +169,22 @@ typedef struct bool bTimer1IrqPending; bool bTimer2IrqPending; bool bSpeechIrqPending; -} MB_Unit; +}; const UINT MB_UNITS_PER_CARD = 2; -typedef struct +struct SS_CARD_MOCKINGBOARD { SS_CARD_HDR Hdr; MB_Unit Unit[MB_UNITS_PER_CARD]; -} SS_CARD_MOCKINGBOARD; +}; ///////////////////////////////////////////////////////////////////////////////// -typedef struct +struct APPLEWIN_SNAPSHOT_v1 { SS_FILE_HDR Hdr; SS_APPLE2_Unit Apple2Unit; -// SS_APPLEWIN_CONFIG AppleWinCfg; SS_CARD_EMPTY Empty1; // Slot1 SS_CARD_EMPTY Empty2; // Slot2 SS_CARD_EMPTY Empty3; // Slot3 @@ -280,6 +192,6 @@ typedef struct SS_CARD_MOCKINGBOARD Mockingboard2; // Slot5 SS_CARD_DISK2 Disk2; // Slot6 SS_CARD_EMPTY Empty7; // Slot7 -} APPLEWIN_SNAPSHOT; +}; -///////////////////////////////////////////////////////////////////////////////// +const UINT kSnapshotSize_v1 = 145400; // Const size for v1 diff --git a/source/SaveState_Structs_v2.h b/source/SaveState_Structs_v2.h new file mode 100644 index 00000000..cec392cf --- /dev/null +++ b/source/SaveState_Structs_v2.h @@ -0,0 +1,114 @@ +#pragma once + +#include "SaveState_Structs_common.h" + +// Structs used by save-state file v2 + +// *** DON'T CHANGE ANY STRUCT WITHOUT CONSIDERING BACKWARDS COMPATIBILITY WITH .AWS FORMAT *** + +///////////////////////////////////////////////////////////////////////////////// + +struct SS_CPU6502_v2 +{ + BYTE A; + BYTE X; + BYTE Y; + BYTE P; + BYTE S; + USHORT PC; + unsigned __int64 CumulativeCycles; + // IRQ = OR-sum of all interrupt sources +}; + +struct SS_IO_Joystick_v2 +{ + unsigned __int64 JoyCntrResetCycle; +}; + +struct SS_IO_Keyboard_v2 +{ + BYTE LastKey; +}; + +struct SS_IO_Speaker_v2 +{ + unsigned __int64 SpkrLastCycle; +}; + +struct SS_IO_Video_v2 +{ + UINT32 AltCharSet; + UINT32 VideoMode; + UINT32 CyclesThisVideoFrame; +}; + +struct SS_BaseMemory_v2 +{ + DWORD dwMemMode; + BOOL bLastWriteRam; + BYTE MemMain[nMemMainSize]; + BYTE MemAux[nMemAuxSize]; +}; + +struct SS_APPLE2_Unit_v2 +{ + SS_UNIT_HDR UnitHdr; + UINT32 Apple2Type; + SS_CPU6502_v2 CPU6502; + SS_IO_Joystick_v2 Joystick; + SS_IO_Keyboard_v2 Keyboard; + SS_IO_Speaker_v2 Speaker; + SS_IO_Video_v2 Video; + SS_BaseMemory_v2 Memory; +}; + +///////////////////////////////////////////////////////////////////////////////// + +#pragma pack(push,4) // push current alignment to stack & set alignment to 4 + // - need so that 12-byte Hdr doesn't get padded to 16 bytes + // - NB. take care not to affect the old v2 structs + +struct APPLEWIN_SNAPSHOT_v2 +{ + SS_FILE_HDR Hdr; + SS_APPLE2_Unit_v2 Apple2Unit; +// SS_CARD_EMPTY[7] Slots; // Slot 0..7 (0=language card for Apple][) +// SS_CARD_EMPTY AuxSlot; // Apple//e auxiliary slot (including optional RAMworks memory) +// SS_APPLEWIN_CONFIG AppleWinCfg; +}; + +#pragma pack(pop) + +///////////////////////////////////////////////////////////////////////////////// + +struct SS_AW_CFG +{ + UINT32 AppleWinVersion; + UINT32 VideoMode; + UINT32 MonochromeColor; + float ClockFreqMHz; + // + UINT32 JoystickType[2]; + UINT32 JoystickTrim[2]; + UINT32 IsAllowCursorsToBeRead; + UINT32 IsAutofire; + UINT32 IsKeyboardAutocentering; + UINT32 IsSwapButton0and1; + // + UINT32 SpeakerVolume; + UINT32 MockingboardVolume; + // + UINT32 IsEnhancedDiskSpeed; + // + UINT32 IsEncodingConversionForClones; + UINT32 IsFilterUnprintableChars; + UINT32 IsAppendToFile; + UINT32 TerminatePrintingAfterIdleSecs; + UINT32 IsUsingFreezesF8Rom; +}; + +struct SS_APPLEWIN_CONFIG +{ + SS_UNIT_HDR UnitHdr; + SS_AW_CFG Cfg; +}; diff --git a/source/SerialComms.cpp b/source/SerialComms.cpp index 77b55f91..ec91f4af 100644 --- a/source/SerialComms.cpp +++ b/source/SerialComms.cpp @@ -72,7 +72,8 @@ SSC_DIPSW CSuperSerialCard::m_DIPSWDefault = CSuperSerialCard::CSuperSerialCard() : m_aySerialPortChoices(NULL), - m_uTCPChoiceItemIdx(0) + m_uTCPChoiceItemIdx(0), + m_uSlot(0) { memset(m_ayCurrentSerialPortName, 0, sizeof(m_ayCurrentSerialPortName)); m_dwSerialPortItem = 0; @@ -831,6 +832,8 @@ void CSuperSerialCard::CommInitialize(LPBYTE pCxRomPeripheral, UINT uSlot) memcpy(pCxRomPeripheral + uSlot*256, pData+SSC_SLOT_FW_OFFSET, SSC_SLOT_FW_SIZE); + m_uSlot = uSlot; + // Expansion ROM if (m_pExpansionRom == NULL) { @@ -1293,30 +1296,144 @@ void CSuperSerialCard::SetSerialPortName(const char* pSerialPortName) //=========================================================================== -DWORD CSuperSerialCard::CommGetSnapshot(SS_IO_Comms* pSS) +void CSuperSerialCard::SetSnapshot_v1( const DWORD baudrate, + const BYTE bytesize, + const BYTE commandbyte, + const DWORD comminactivity, + const BYTE controlbyte, + const BYTE parity, + const BYTE stopbits) { - pSS->baudrate = m_uBaudRate; - pSS->bytesize = m_uByteSize; - pSS->commandbyte = m_uCommandByte; - pSS->comminactivity = m_dwCommInactivity; - pSS->controlbyte = m_uControlByte; - pSS->parity = m_uParity; -// memcpy(pSS->recvbuffer, m_RecvBuffer, uRecvBufferSize); - pSS->recvbytes = 0; - pSS->stopbits = m_uStopBits; - return 0; + m_uBaudRate = baudrate; + m_uByteSize = bytesize; + m_uCommandByte = commandbyte; + m_dwCommInactivity = comminactivity; + m_uControlByte = controlbyte; + m_uParity = parity; +// memcpy(m_RecvBuffer, pSS->recvbuffer, uRecvBufferSize); +// m_vRecvBytes = recvbytes; + m_uStopBits = stopbits; } -DWORD CSuperSerialCard::CommSetSnapshot(SS_IO_Comms* pSS) +//=========================================================================== + +struct SSC_Unit { - m_uBaudRate = pSS->baudrate; - m_uByteSize = pSS->bytesize; - m_uCommandByte = pSS->commandbyte; - m_dwCommInactivity = pSS->comminactivity; - m_uControlByte = pSS->controlbyte; - m_uParity = pSS->parity; -// memcpy(m_RecvBuffer, pSS->recvbuffer, uRecvBufferSize); -// m_vRecvBytes = pSS->recvbytes; - m_uStopBits = pSS->stopbits; + SSC_DIPSW DIPSWDefault; + SSC_DIPSW DIPSWCurrent; + + DWORD uBaudRate; + + BYTE uStopBits; + BYTE uByteSize; + BYTE uParity; + + BYTE uControlByte; + BYTE uCommandByte; + + DWORD dwCommInactivity; // If non-zero then COM port open + + bool bTxIrqEnabled; + bool bRxIrqEnabled; + + bool vbTxIrqPending; + bool vbRxIrqPending; + + bool bWrittenTx; +}; + +struct SS_CARD_SSC +{ + SS_CARD_HDR Hdr; + SSC_Unit Unit; +}; + +// Post: +// 0 = No card +// >0 = Card saved OK from slot n +// -1 = File error +int CSuperSerialCard::GetSnapshot(const HANDLE hFile) +{ + SS_CARD_SSC CardSuperSerial; + + CardSuperSerial.Hdr.UnitHdr.hdr.v2.Length = sizeof(SS_CARD_SSC); + CardSuperSerial.Hdr.UnitHdr.hdr.v2.Type = UT_Card; + CardSuperSerial.Hdr.UnitHdr.hdr.v2.Version = 1; + + CardSuperSerial.Hdr.Slot = m_uSlot; + CardSuperSerial.Hdr.Type = CT_SSC; + + SSC_Unit& Unit = CardSuperSerial.Unit; + + Unit.DIPSWDefault = m_DIPSWDefault; + Unit.DIPSWCurrent = m_DIPSWCurrent; + Unit.uBaudRate = m_uBaudRate; + Unit.uStopBits = m_uStopBits; + Unit.uByteSize = m_uByteSize; + Unit.uParity = m_uParity; + Unit.uControlByte = m_uControlByte; + Unit.uCommandByte = m_uCommandByte; + Unit.dwCommInactivity = m_dwCommInactivity; + Unit.bTxIrqEnabled = m_bTxIrqEnabled; + Unit.bRxIrqEnabled = m_bRxIrqEnabled; + Unit.vbTxIrqPending = m_vbTxIrqPending; + Unit.vbRxIrqPending = m_vbRxIrqPending; + Unit.bWrittenTx = m_bWrittenTx; + + // + + DWORD dwBytesWritten; + BOOL bRes = WriteFile( hFile, + &CardSuperSerial, + CardSuperSerial.Hdr.UnitHdr.hdr.v2.Length, + &dwBytesWritten, + NULL); + + if(!bRes || (dwBytesWritten != CardSuperSerial.Hdr.UnitHdr.hdr.v2.Length)) + throw std::string("Save error: SSC"); + + return m_uSlot; +} + +int CSuperSerialCard::SetSnapshot(const HANDLE hFile) +{ + SS_CARD_SSC CardSuperSerial; + + DWORD dwBytesRead; + BOOL bRes = ReadFile( hFile, + &CardSuperSerial, + sizeof(CardSuperSerial), + &dwBytesRead, + NULL); + + if (dwBytesRead != sizeof(CardSuperSerial)) + throw std::string("Card: file corrupt"); + + if (CardSuperSerial.Hdr.Slot != 2) // fixme + throw std::string("Card: wrong slot"); + + if (CardSuperSerial.Hdr.UnitHdr.hdr.v2.Version != 1) + throw std::string("Card: wrong version"); + + if (CardSuperSerial.Hdr.UnitHdr.hdr.v2.Length != sizeof(SS_CARD_SSC)) + throw std::string("Card: unit size mismatch"); + + SSC_Unit& Unit = CardSuperSerial.Unit; + + m_DIPSWDefault = Unit.DIPSWDefault; + m_DIPSWCurrent = Unit.DIPSWCurrent; + m_uBaudRate = Unit.uBaudRate; + m_uStopBits = Unit.uStopBits; + m_uByteSize = Unit.uByteSize; + m_uParity = Unit.uParity; + m_uControlByte = Unit.uControlByte; + m_uCommandByte = Unit.uCommandByte; + m_dwCommInactivity = Unit.dwCommInactivity; + m_bTxIrqEnabled = Unit.bTxIrqEnabled; + m_bRxIrqEnabled = Unit.bRxIrqEnabled; + m_vbTxIrqPending = Unit.vbTxIrqPending; + m_vbRxIrqPending = Unit.vbRxIrqPending; + m_bWrittenTx = Unit.bWrittenTx; + return 0; } diff --git a/source/SerialComms.h b/source/SerialComms.h index d75d2ea9..7be33799 100644 --- a/source/SerialComms.h +++ b/source/SerialComms.h @@ -33,8 +33,9 @@ public: void CommDestroy(); void CommSetSerialPort(HWND hWindow, DWORD dwNewSerialPortItem); void CommUpdate(DWORD); - DWORD CommGetSnapshot(SS_IO_Comms* pSS); - DWORD CommSetSnapshot(SS_IO_Comms* pSS); + void SetSnapshot_v1(const DWORD baudrate, const BYTE bytesize, const BYTE commandbyte, const DWORD comminactivity, const BYTE controlbyte, const BYTE parity, const BYTE stopbits); + int GetSnapshot(const HANDLE hFile); + int SetSnapshot(const HANDLE hFile); char* GetSerialPortChoices(); DWORD GetSerialPort() { return m_dwSerialPortItem; } // Drop-down list item @@ -134,4 +135,5 @@ private: OVERLAPPED m_o; BYTE* m_pExpansionRom; + UINT m_uSlot; }; diff --git a/source/Speaker.cpp b/source/Speaker.cpp index 3608ecd6..da574207 100644 --- a/source/Speaker.cpp +++ b/source/Speaker.cpp @@ -1080,14 +1080,19 @@ void Spkr_DSUninit() //============================================================================= -DWORD SpkrGetSnapshot(SS_IO_Speaker* pSS) +void SpkrSetSnapshot_v1(const unsigned __int64 SpkrLastCycle) { - pSS->g_nSpkrLastCycle = g_nSpkrLastCycle; - return 0; + g_nSpkrLastCycle = SpkrLastCycle; } -DWORD SpkrSetSnapshot(SS_IO_Speaker* pSS) +// + +void SpkrGetSnapshot(unsigned __int64& rSpkrLastCycle) { - g_nSpkrLastCycle = pSS->g_nSpkrLastCycle; - return 0; + rSpkrLastCycle = g_nSpkrLastCycle; +} + +void SpkrSetSnapshot(const unsigned __int64 SpkrLastCycle) +{ + g_nSpkrLastCycle = SpkrLastCycle; } diff --git a/source/Speaker.h b/source/Speaker.h index 8e93fbbe..d4b960d2 100644 --- a/source/Speaker.h +++ b/source/Speaker.h @@ -19,7 +19,8 @@ void Spkr_Demute(); bool Spkr_IsActive(); bool Spkr_DSInit(); void Spkr_DSUninit(); -DWORD SpkrGetSnapshot(SS_IO_Speaker* pSS); -DWORD SpkrSetSnapshot(SS_IO_Speaker* pSS); +void SpkrSetSnapshot_v1(const unsigned __int64 SpkrLastCycle); +void SpkrGetSnapshot(unsigned __int64& rSpkrLastCycle); +void SpkrSetSnapshot(const unsigned __int64 SpkrLastCycle); BYTE __stdcall SpkrToggle (WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft); diff --git a/source/StdAfx.h b/source/StdAfx.h index 2e0d77a7..bcbbd3c8 100644 --- a/source/StdAfx.h +++ b/source/StdAfx.h @@ -23,7 +23,6 @@ #include #include #include -#include #include #include @@ -36,6 +35,7 @@ #include #include #include +#include #include // SM_CXPADDEDBORDER is not supported on 2000 & XP: diff --git a/source/Video.cpp b/source/Video.cpp index 8f9cbd95..7030f290 100644 --- a/source/Video.cpp +++ b/source/Video.cpp @@ -39,6 +39,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #include "..\resource\resource.h" #include "Configuration\PropertySheet.h" #include "Debugger\Debugger_Color.h" // For NUM_DEBUG_COLORS +#include "SaveState_Structs_v2.h" #define HALF_PIXEL_SOLID 1 #define HALF_PIXEL_BLEED 0 @@ -2941,20 +2942,26 @@ void VideoSetForceFullRedraw(void) //=========================================================================== -DWORD VideoGetSnapshot(SS_IO_Video* pSS) +void VideoSetSnapshot_v1(const UINT AltCharSet, const UINT VideoMode) { - pSS->bAltCharSet = !(g_nAltCharSetOffset == 0); - pSS->dwVidMode = g_uVideoMode; - return 0; + g_nAltCharSetOffset = !AltCharSet ? 0 : 256; + g_uVideoMode = VideoMode; } -//=========================================================================== +// -DWORD VideoSetSnapshot(SS_IO_Video* pSS) +void VideoGetSnapshot(SS_IO_Video_v2& Video) { - g_nAltCharSetOffset = !pSS->bAltCharSet ? 0 : 256; - g_uVideoMode = pSS->dwVidMode; - return 0; + Video.AltCharSet = !(g_nAltCharSetOffset == 0); + Video.VideoMode = g_uVideoMode; + Video.CyclesThisVideoFrame = g_dwCyclesThisFrame; +} + +void VideoSetSnapshot(const SS_IO_Video_v2& Video) +{ + g_nAltCharSetOffset = !Video.AltCharSet ? 0 : 256; + g_uVideoMode = Video.VideoMode; + g_dwCyclesThisFrame = Video.CyclesThisVideoFrame; } //=========================================================================== diff --git a/source/Video.h b/source/Video.h index 9aa270b9..93f179f5 100644 --- a/source/Video.h +++ b/source/Video.h @@ -85,8 +85,9 @@ bool VideoGetSWAltCharSet(void); void VideoSetForceFullRedraw(void); -DWORD VideoGetSnapshot(SS_IO_Video* pSS); -DWORD VideoSetSnapshot(SS_IO_Video* pSS); +void VideoSetSnapshot_v1(const UINT AltCharSet, const UINT VideoMode); +void VideoGetSnapshot(struct SS_IO_Video_v2& Video); +void VideoSetSnapshot(const struct SS_IO_Video_v2& Video); void _Video_Dirty(); void _Video_RedrawScreen( VideoUpdateFuncPtr_t update, bool bMixed = false ); From 498f01edde5dc4e6331f4497c7696320a99c3520 Mon Sep 17 00:00:00 2001 From: tomcw Date: Sat, 11 Apr 2015 22:24:54 +0100 Subject: [PATCH 02/20] New save-state (.aws) v2: Added card save/load for: . Phasor (#260) . CP/M (#260) . 80 column card: . aux memory now saved separately from main memory . extended memory (RAMworks) (#260) Mockingboard & Phasor: . Full AY8910 internal state now preserved. . needed for eg. envelope, ay_change[], etc . also Phasor player only updates AY regs that have changed Other: . On restore error, then PostMessage(WM_USER_RESTART), so that emulator not left in intermediate state . Fix: Start Dir wasn't set when drag & dropping an image onto a drive icon or double-clicking an image file --- source/AY8910.cpp | 186 ++++++++++++++- source/AY8910.h | 7 + source/Applewin.cpp | 5 - source/Configuration/Config.h | 2 + source/Debugger/Debugger_Display.cpp | 2 +- source/Disk.cpp | 15 +- source/Harddisk.cpp | 14 +- source/Memory.cpp | 162 +++++++++++-- source/Memory.h | 2 + source/Mockingboard.cpp | 337 ++++++++++++++++++++++----- source/Mockingboard.h | 7 +- source/SaveState.cpp | 77 ++++-- source/SaveState_Structs_common.h | 58 +++++ source/SaveState_Structs_v1.h | 74 +----- source/SaveState_Structs_v2.h | 7 +- source/Z80VICE/z80.cpp | 188 ++++++++++++++- source/Z80VICE/z80regs.h | 2 + source/z80emu.h | 4 + 18 files changed, 972 insertions(+), 177 deletions(-) diff --git a/source/AY8910.cpp b/source/AY8910.cpp index 7600740e..aa23ba1c 100644 --- a/source/AY8910.cpp +++ b/source/AY8910.cpp @@ -114,12 +114,17 @@ static int rstereopos, rchan1pos, rchan2pos, rchan3pos; double CAY8910::m_fCurrentCLK_AY8910 = 0.0; -CAY8910::CAY8910() : - // Init the statics that were in sound_ay_overlay() - rng(1), - noise_toggle(0), - env_first(1), env_rev(0), env_counter(15) +void CAY8910::init(void) { + // Init the statics that were in sound_ay_overlay() + rng = 1; + noise_toggle = 0; + env_first = 1; env_rev = 0; env_counter = 15; +} + +CAY8910::CAY8910(void) +{ + init(); m_fCurrentCLK_AY8910 = g_fCurrentCLK6502; }; @@ -731,6 +736,8 @@ void CAY8910::sound_ay_reset( void ) { int f; + init(); // AppleWin:TC + /* recalculate timings based on new machines ay clock */ sound_ay_init(); @@ -940,6 +947,157 @@ sound_beeper( int is_tape, int on ) } #endif +// disable warning C4200: zero-sized array in struct/union +#pragma warning(disable: 4200) + +struct SS_AY8910 +{ + unsigned int ay_tone_tick[3], ay_tone_high[3], ay_noise_tick; + unsigned int ay_tone_subcycles, ay_env_subcycles; + unsigned int ay_env_internal_tick, ay_env_tick; + unsigned int ay_tick_incr; + unsigned int ay_tone_period[3], ay_noise_period, ay_env_period; + + BYTE sound_ay_registers[16]; + + int rng; + int noise_toggle; + int env_first, env_rev, env_counter; + + int ay_change_count; + void* ay_change[0]; // real type is ay_change_tag (but this is private) +}; + +UINT CAY8910::GetSnapshot(const HANDLE hFile) +{ + const UINT uAYChangeLength = ay_change_count * sizeof(ay_change_tag); + const UINT uAYTotalLength = sizeof(SS_AY8910) + uAYChangeLength; + + if (hFile == NULL) + return uAYTotalLength; + + // + + SS_AY8910 ay_state; + + memcpy(ay_state.ay_tone_tick, ay_tone_tick, sizeof(ay_tone_tick)); + memcpy(ay_state.ay_tone_high, ay_tone_high, sizeof(ay_tone_high)); + ay_state.ay_noise_tick = ay_noise_tick; + ay_state.ay_tone_subcycles = ay_tone_subcycles; + ay_state.ay_env_subcycles = ay_env_subcycles; + ay_state.ay_env_internal_tick = ay_env_internal_tick; + ay_state.ay_env_tick = ay_env_tick; + ay_state.ay_tick_incr = ay_tick_incr; + memcpy(ay_state.ay_tone_period, ay_tone_period, sizeof(ay_tone_period)); + ay_state.ay_noise_period = ay_noise_period; + ay_state.ay_env_period = ay_env_period; + + memcpy(ay_state.sound_ay_registers, sound_ay_registers, sizeof(sound_ay_registers)); + + ay_state.rng = rng; + ay_state.noise_toggle = noise_toggle; + ay_state.env_first = env_first; + ay_state.env_rev = env_rev; + ay_state.env_counter = env_counter; + + ay_state.ay_change_count = ay_change_count; + + // + + DWORD dwBytesWritten; + BOOL bRes = WriteFile( hFile, + &ay_state, + sizeof(SS_AY8910), + &dwBytesWritten, + NULL); + + if(!bRes || (dwBytesWritten != sizeof(SS_AY8910))) + { + //dwError = GetLastError(); + throw std::string("Save error: AY8910"); + } + + // + + if (uAYChangeLength) + { + DWORD dwBytesWritten2; + BOOL bRes2 = WriteFile( hFile, + ay_change, + uAYChangeLength, + &dwBytesWritten2, + NULL); + + if(!bRes2 || (dwBytesWritten2 != uAYChangeLength)) + { + //dwError = GetLastError(); + throw std::string("Save error: AY8910"); + } + } + + return uAYTotalLength; +} + +UINT CAY8910::SetSnapshot(const HANDLE hFile) +{ + SS_AY8910 ay_state; + + DWORD dwBytesRead; + BOOL bRes = ReadFile( hFile, + &ay_state, + sizeof(SS_AY8910), + &dwBytesRead, + NULL); + + if (dwBytesRead != sizeof(SS_AY8910)) + throw std::string("Card: file corrupt"); + + if (ay_state.ay_change_count > AY_CHANGE_MAX) + throw std::string("Card: file corrupt"); + + // + + memcpy(ay_tone_tick, ay_state.ay_tone_tick, sizeof(ay_tone_tick)); + memcpy(ay_tone_high, ay_state.ay_tone_high, sizeof(ay_tone_high)); + ay_noise_tick = ay_state.ay_noise_tick; + ay_tone_subcycles = ay_state.ay_tone_subcycles; + ay_env_subcycles = ay_state.ay_env_subcycles; + ay_env_internal_tick = ay_state.ay_env_internal_tick; + ay_env_tick = ay_state.ay_env_tick; + ay_tick_incr = ay_state.ay_tick_incr; + memcpy(ay_tone_period, ay_state.ay_tone_period, sizeof(ay_tone_period)); + ay_noise_period = ay_state.ay_noise_period; + ay_env_period = ay_state.ay_env_period; + + memcpy(sound_ay_registers, ay_state.sound_ay_registers, sizeof(sound_ay_registers)); + + rng = ay_state.rng; + noise_toggle = ay_state.noise_toggle; + env_first = ay_state.env_first; + env_rev = ay_state.env_rev; + env_counter = ay_state.env_counter; + + ay_change_count = ay_state.ay_change_count; + + // + + const UINT uLength = ay_change_count * sizeof(ay_change_tag); + if (uLength) + { + DWORD dwBytesRead2; + BOOL bRes = ReadFile( hFile, + ay_change, + uLength, + &dwBytesRead2, + NULL); + + if (dwBytesRead2 != uLength) + throw std::string("Card: file corrupt"); + } + + return dwBytesRead+uLength; +} + /////////////////////////////////////////////////////////////////////////////// // AY8910 interface @@ -996,8 +1154,24 @@ void AY8910_InitClock(int nClock) BYTE* AY8910_GetRegsPtr(UINT uChip) { - if(uChip >= MAX_8910) + if (uChip >= MAX_8910) return NULL; return g_AY8910[uChip].GetAYRegsPtr(); } + +UINT AY8910_GetSnapshot(const HANDLE hFile, UINT uChip) +{ + if (uChip >= MAX_8910) + return 0; + + return g_AY8910[uChip].GetSnapshot(hFile); +} + +UINT AY8910_SetSnapshot(const HANDLE hFile, UINT uChip) +{ + if (uChip >= MAX_8910) + return 0; + + return g_AY8910[uChip].SetSnapshot(hFile); +} diff --git a/source/AY8910.h b/source/AY8910.h index 59a53359..00c4cf76 100644 --- a/source/AY8910.h +++ b/source/AY8910.h @@ -17,6 +17,9 @@ BYTE* AY8910_GetRegsPtr(UINT uChip); void AY8910UpdateSetCycles(); +UINT AY8910_GetSnapshot(const HANDLE hFile, UINT uChip); +UINT AY8910_SetSnapshot(const HANDLE hFile, UINT uChip); + //------------------------------------- // FUSE stuff @@ -43,8 +46,12 @@ public: void sound_frame( void ); BYTE* GetAYRegsPtr( void ) { return &sound_ay_registers[0]; } static void SetCLK( double CLK ) { m_fCurrentCLK_AY8910 = CLK; } + void ClearAYChangeCount( void ) { ay_change_count = 0; } + UINT GetSnapshot(const HANDLE hFile); + UINT SetSnapshot(const HANDLE hFile); private: + void init( void ); void sound_end( void ); void sound_ay_overlay( void ); diff --git a/source/Applewin.cpp b/source/Applewin.cpp index 8a379095..2f8272ef 100644 --- a/source/Applewin.cpp +++ b/source/Applewin.cpp @@ -494,11 +494,6 @@ void LoadConfiguration(void) if(REGLOAD(TEXT(REGVALUE_SLOT5), &dwTmp)) g_Slot5 = (SS_CARDTYPE) dwTmp; - if (g_Slot4 == CT_MockingboardC || g_Slot4 == CT_Phasor) - MB_SetSoundcardType(g_Slot4); - else - MB_SetSoundcardType(CT_Empty); - // char szFilename[MAX_PATH] = {0}; diff --git a/source/Configuration/Config.h b/source/Configuration/Config.h index 2915d6cb..2724bf69 100644 --- a/source/Configuration/Config.h +++ b/source/Configuration/Config.h @@ -15,6 +15,7 @@ public: m_bEnableHDD = HD_CardIsEnabled(); m_bEnableTheFreezesF8Rom = bEnableTheFreezesF8Rom; memset(&m_Slot, 0, sizeof(m_Slot)); + m_SlotAux = CT_Empty; m_Slot[4] = g_Slot4; m_Slot[5] = g_Slot5; } @@ -47,6 +48,7 @@ public: eApple2Type m_Apple2Type; SS_CARDTYPE m_Slot[NUM_SLOTS]; // 0..7 + SS_CARDTYPE m_SlotAux; BOOL m_bEnhanceDisk; bool m_bEnableHDD; UINT m_bEnableTheFreezesF8Rom; diff --git a/source/Debugger/Debugger_Display.cpp b/source/Debugger/Debugger_Display.cpp index 47270730..172ed307 100644 --- a/source/Debugger/Debugger_Display.cpp +++ b/source/Debugger/Debugger_Display.cpp @@ -2434,7 +2434,7 @@ void DrawMemory ( int line, int iMemDump ) DEVICE_e eDevice = pMD->eDevice; MemoryView_e iView = pMD->eView; - SS_CARD_MOCKINGBOARD SS_MB; + SS_CARD_MOCKINGBOARD_v1 SS_MB; if ((eDevice == DEV_SY6522) || (eDevice == DEV_AY8910)) MB_GetSnapshot_v1(&SS_MB, 4+(nAddr>>1)); // Slot4 or Slot5 diff --git a/source/Disk.cpp b/source/Disk.cpp index 84e338e4..a7359273 100644 --- a/source/Disk.cpp +++ b/source/Disk.cpp @@ -117,6 +117,7 @@ static bool IsDriveValid( const int iDrive ); static void ReadTrack (int drive); static void RemoveDisk (int drive); static void WriteTrack (int drive); +static LPCTSTR DiskGetFullPathName(const int iDrive); //=========================================================================== @@ -195,6 +196,17 @@ void Disk_SaveLastDiskImage(const int iDrive) RegSaveString(TEXT(REG_PREFS), REGVALUE_PREF_LAST_DISK_1, TRUE, pFileName); else RegSaveString(TEXT(REG_PREFS), REGVALUE_PREF_LAST_DISK_2, TRUE, pFileName); + + // + + char szPathName[MAX_PATH]; + strcpy(szPathName, DiskGetFullPathName(iDrive)); + if (_tcsrchr(szPathName, TEXT('\\'))) + { + char* pPathEnd = _tcsrchr(szPathName, TEXT('\\'))+1; + *pPathEnd = 0; + RegSaveString(TEXT(REG_PREFS), TEXT(REGVALUE_PREF_START_DIR), 1, szPathName); + } } //=========================================================================== @@ -847,9 +859,6 @@ static bool DiskSelectImage(const int iDrive, LPCSTR pszFilename) ImageError_e Error = DiskInsert(iDrive, filename, ofn.Flags & OFN_READONLY, IMAGE_CREATE); if (Error == eIMAGE_ERROR_NONE) { - filename[ofn.nFileOffset] = 0; - if (_tcsicmp(directory, filename)) - RegSaveString(TEXT(REG_PREFS), TEXT(REGVALUE_PREF_START_DIR), 1, filename); bRes = true; } else diff --git a/source/Harddisk.cpp b/source/Harddisk.cpp index 9934abd3..e7133fd0 100644 --- a/source/Harddisk.cpp +++ b/source/Harddisk.cpp @@ -218,6 +218,17 @@ static void HD_SaveLastDiskImage(const int iDrive) RegSaveString(TEXT(REG_PREFS), REGVALUE_PREF_LAST_HARDDISK_1, TRUE, pFileName); else RegSaveString(TEXT(REG_PREFS), REGVALUE_PREF_LAST_HARDDISK_2, TRUE, pFileName); + + // + + char szPathName[MAX_PATH]; + strcpy(szPathName, HD_GetFullPathName(iDrive)); + if (_tcsrchr(szPathName, TEXT('\\'))) + { + char* pPathEnd = _tcsrchr(szPathName, TEXT('\\'))+1; + *pPathEnd = 0; + RegSaveString(TEXT(REG_PREFS), TEXT(REGVALUE_PREF_HDV_START_DIR), 1, szPathName); + } } //=========================================================================== @@ -407,9 +418,6 @@ static bool HD_SelectImage(const int iDrive, LPCSTR pszFilename) if (HD_Insert(iDrive, filename)) { - filename[ofn.nFileOffset] = 0; - if (_tcsicmp(directory, filename)) - RegSaveString(TEXT(REG_PREFS), TEXT(REGVALUE_PREF_HDV_START_DIR), 1, filename); bRes = true; } else diff --git a/source/Memory.cpp b/source/Memory.cpp index 9c97e0fb..5109a12d 100644 --- a/source/Memory.cpp +++ b/source/Memory.cpp @@ -170,7 +170,7 @@ iofunction IORead[256]; iofunction IOWrite[256]; static LPVOID SlotParameters[NUM_SLOTS]; -static BOOL lastwriteram = 0; +static BOOL lastwriteram = 0; // NB. redundant - only used in MemSetPaging(), where it's forced to 1 LPBYTE mem = NULL; @@ -194,7 +194,8 @@ static BOOL Pravets8charmode = 0; static CNoSlotClock g_NoSlotClock; #ifdef RAMWORKS -UINT g_uMaxExPages = 1; // user requested ram pages +UINT g_uMaxExPages = 1; // user requested ram pages +UINT g_uActiveBank = 0; // 0 = memaux static LPBYTE RWpages[128]; // pointers to RW memory banks #endif @@ -694,11 +695,6 @@ static void InitIoHandlers() // - IO_SELECT = 0; - IO_SELECT_InternalROM = 0; - g_eExpansionRomType = eExpRomNull; - g_uPeripheralRomSlot = 0; - for (i=0; i> 8) & 0xF; return (memshadow[0xD0+bank1page] == pMemBase+(0xC0+bank1page)*256) ? mem+offset+0x1000 // Return ptr to $Dxxx address - 'mem' has (a potentially dirty) 4K RAM BANK1 mapped in at $D000 @@ -1146,7 +1143,9 @@ void MemInitialize() #ifdef RAMWORKS // allocate memory for RAMWorks III - up to 8MB - RWpages[0] = memaux; + g_uActiveBank = 0; + RWpages[g_uActiveBank] = memaux; + UINT i = 1; while ((i < g_uMaxExPages) && (RWpages[i] = (LPBYTE) VirtualAlloc(NULL,_6502_MEM_END+1,MEM_COMMIT,PAGE_READWRITE))) i++; @@ -1340,9 +1339,16 @@ void MemReset() // INITIALIZE THE RAM IMAGES ZeroMemory(memaux ,0x10000); - ZeroMemory(memmain,0x10000); + // Init the I/O ROM vars + IO_SELECT = 0; + IO_SELECT_InternalROM = 0; + g_eExpansionRomType = eExpRomNull; + g_uPeripheralRomSlot = 0; + + // + int iByte; // Memory is pseudo-initialized across various models of Apple ][ //e //c @@ -1453,7 +1459,7 @@ void MemReset() // - "BeachParty-PoacherWars-DaytonDinger-BombsAway.dsk" // - "Dung Beetles, Ms. PacMan, Pooyan, Star Cruiser, Star Thief, Invas. Force.dsk" memmain[ 0x620B ] = 0x0; - + // https://github.com/AppleWin/AppleWin/issues/222 // MIP_PAGE_ADDRESS_LOW // "Copy II+ v5.0.dsk" @@ -1474,7 +1480,7 @@ void MemReset() CpuInitialize(); //Sets Caps Lock = false (Pravets 8A/C only) - z80_reset(); + z80_reset(); // NB. Also called above in CpuInitialize() } //=========================================================================== @@ -1589,7 +1595,8 @@ BYTE __stdcall MemSetPaging(WORD programcounter, WORD address, BYTE write, BYTE case 0x73: // Ramworks III set aux page number if ((value < g_uMaxExPages) && RWpages[value]) { - memaux = RWpages[value]; + g_uActiveBank = value; + memaux = RWpages[g_uActiveBank]; UpdatePaging(0); // Initialize=0 } break; @@ -1679,7 +1686,7 @@ void MemSetSnapshot_v1(const DWORD MemMode, const BOOL LastWriteRam, const BYTE* // modechanging = 0; - + // NB. MemUpdatePaging(TRUE) called at end of Snapshot_LoadState_v1() UpdatePaging(1); // Initialize=1 } @@ -1689,11 +1696,14 @@ void MemGetSnapshot(SS_BaseMemory_v2& Memory) { Memory.dwMemMode = memmode; Memory.bLastWriteRam = lastwriteram; + Memory.IO_SELECT = IO_SELECT; + Memory.IO_SELECT_InternalROM = IO_SELECT_InternalROM; + Memory.ExpansionRomType = g_eExpansionRomType; + Memory.PeripheralRomSlot = g_uPeripheralRomSlot; for(DWORD dwOffset = 0x0000; dwOffset < 0x10000; dwOffset+=0x100) { memcpy(Memory.MemMain+dwOffset, MemGetMainPtr((WORD)dwOffset), 0x100); - memcpy(Memory.MemAux+dwOffset, MemGetAuxPtr((WORD)dwOffset), 0x100); } } @@ -1701,14 +1711,132 @@ void MemSetSnapshot(const SS_BaseMemory_v2& Memory) { SetMemMode(Memory.dwMemMode); lastwriteram = Memory.bLastWriteRam; + IO_SELECT = Memory.IO_SELECT; + IO_SELECT_InternalROM = Memory.IO_SELECT_InternalROM; + g_eExpansionRomType = (eExpansionRomType) Memory.ExpansionRomType; + g_uPeripheralRomSlot = Memory.PeripheralRomSlot; memcpy(memmain, Memory.MemMain, nMemMainSize); - memcpy(memaux, Memory.MemAux, nMemAuxSize); memset(memdirty, 0, 0x100); // modechanging = 0; - - UpdatePaging(1); // Initialize=1 + // NB. MemUpdatePaging(TRUE) called at end of Snapshot_LoadState_v2() + UpdatePaging(1); // Initialize=1 (Still needed, even with call to MemUpdatePaging() - why?) +} + +// + +// disable warning C4200: zero-sized array in struct/union +#pragma warning(disable: 4200) + +struct SS_CARD_80COL_AUX_MEMORY +{ + SS_CARD_HDR Hdr; + UINT NumBanks; + UINT ActiveBank; + BYTE MemAux[0]; +}; + +void MemGetSnapshotAux(const HANDLE hFile) +{ + if (IS_APPLE2) + { + return; // No Aux slot for AppleII + } + + if (IS_APPLE2C) + { + _ASSERT(g_uMaxExPages == 1); + } + + const UINT uSize = sizeof(SS_CARD_80COL_AUX_MEMORY) + g_uMaxExPages*(_6502_MEM_END+1); + + SS_CARD_80COL_AUX_MEMORY* const pSS = (SS_CARD_80COL_AUX_MEMORY*) new BYTE [uSize]; + + pSS->Hdr.UnitHdr.hdr.v2.Length = uSize; + pSS->Hdr.UnitHdr.hdr.v2.Type = UT_Card; + pSS->Hdr.UnitHdr.hdr.v2.Version = 1; + + pSS->Hdr.Slot = kSLOT_AUX; + pSS->Hdr.Type = g_uMaxExPages == 0 ? CT_80Col : + g_uMaxExPages == 1 ? CT_Extended80Col : + CT_RamWorksIII; + + pSS->ActiveBank = g_uActiveBank; + pSS->NumBanks = g_uMaxExPages; + + for(UINT uBank = 1; uBank <= g_uMaxExPages; uBank++) + { + memcpy(pSS->MemAux+(uBank-1)*(_6502_MEM_END+1), MemGetBankPtr(uBank), _6502_MEM_END+1); + } + + // + + DWORD dwBytesWritten; + BOOL bRes = WriteFile( hFile, + pSS, + pSS->Hdr.UnitHdr.hdr.v2.Length, + &dwBytesWritten, + NULL); + + delete [] pSS; + + if(!bRes || (dwBytesWritten != uSize)) + { + //dwError = GetLastError(); + throw std::string("Save error: 80COL_AUX_MEMORY card"); + } + +} + +void MemSetSnapshotAux(const HANDLE hFile) +{ + SS_CARD_80COL_AUX_MEMORY Card; + + DWORD dwBytesRead; + BOOL bRes = ReadFile( hFile, + &Card, + sizeof(Card), + &dwBytesRead, + NULL); + + if (dwBytesRead != sizeof(Card)) + throw std::string("Card: file corrupt"); + + if (Card.Hdr.Slot != kSLOT_AUX) + throw std::string("Card: wrong slot"); + + if (Card.Hdr.UnitHdr.hdr.v2.Version > 1) + throw std::string("Card: wrong version"); + + if (Card.Hdr.UnitHdr.hdr.v2.Length < sizeof(SS_CARD_80COL_AUX_MEMORY)) + throw std::string("Card: unit size mismatch"); + + g_uActiveBank = Card.ActiveBank; + g_uMaxExPages = Card.NumBanks; + + for(UINT uBank = 1; uBank <= g_uMaxExPages; uBank++) + { + LPBYTE pBank = MemGetBankPtr(uBank); + if (!pBank) + { + // todo: alloc + _ASSERT(pBank); + break; + } + + bRes = ReadFile( hFile, + pBank, + _6502_MEM_END+1, + &dwBytesRead, + NULL); + + if (dwBytesRead != _6502_MEM_END+1) + throw std::string("Card: file corrupt"); + } + + memaux = RWpages[g_uActiveBank]; + // NB. MemUpdatePaging(TRUE) called at end of Snapshot_LoadState_v2() } diff --git a/source/Memory.h b/source/Memory.h index bc5a0a53..e516a3e5 100644 --- a/source/Memory.h +++ b/source/Memory.h @@ -56,6 +56,8 @@ LPVOID MemGetSlotParameters (UINT uSlot); void MemSetSnapshot_v1(const DWORD MemMode, const BOOL LastWriteRam, const BYTE* const pMemMain, const BYTE* const pMemAux); void MemGetSnapshot(struct SS_BaseMemory_v2& Memory); void MemSetSnapshot(const struct SS_BaseMemory_v2& Memory); +void MemGetSnapshotAux(const HANDLE hFile); +void MemSetSnapshotAux(const HANDLE hFile); BYTE __stdcall IO_Null(WORD programcounter, WORD address, BYTE write, BYTE value, ULONG nCycles); diff --git a/source/Mockingboard.cpp b/source/Mockingboard.cpp index 405ad239..bf9f6e33 100644 --- a/source/Mockingboard.cpp +++ b/source/Mockingboard.cpp @@ -116,14 +116,14 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #define Phasor_SY6522A_Offset (1<= 0) and g_bStopPhoneme = true + static void SSI263_Play(unsigned int nPhoneme) { #if 1 @@ -1013,6 +1021,8 @@ static void SSI263_Play(unsigned int nPhoneme) g_nCurrentActivePhoneme = nPhoneme; + // [1] + hr = SSI263Voice[g_nCurrentActivePhoneme].lpDSBvoice->SetCurrentPosition(0); if(FAILED(hr)) return; @@ -1022,6 +1032,8 @@ static void SSI263_Play(unsigned int nPhoneme) return; SSI263Voice[g_nCurrentActivePhoneme].bActive = true; + + // [2] #else HRESULT hr; bool bPause; @@ -1373,7 +1385,8 @@ void MB_Initialize() // NB. Called when /g_fCurrentCLK6502/ changes void MB_Reinitialize() { - AY8910_InitClock((int)g_fCurrentCLK6502); + AY8910_InitClock((int)g_fCurrentCLK6502); // todo: account for g_PhasorClockScaleFactor? + // NB. Other calls to AY8910_InitClock() use the constant CLK_6502 } //----------------------------------------------------------------------------- @@ -1405,9 +1418,10 @@ static void ResetState() //g_bMBAvailable = false; - //g_SoundcardType = CT_Empty; - //g_bPhasorEnable = false; +// g_SoundcardType = CT_Empty; // Don't uncomment, else _ASSERT will fire in MB_Read() after an F2->MB_Reset() +// g_bPhasorEnable = false; g_nPhasorMode = 0; + g_PhasorClockScaleFactor = 1; } void MB_Reset() @@ -1555,9 +1569,9 @@ static BYTE __stdcall PhasorIO(WORD PC, WORD nAddr, BYTE bWrite, BYTE nValue, UL if(g_nPhasorMode < 2) g_nPhasorMode = nAddr & 1; - double fCLK = (nAddr & 4) ? CLK_6502*2 : CLK_6502; + g_PhasorClockScaleFactor = (nAddr & 4) ? 2 : 1; - AY8910_InitClock((int)fCLK); + AY8910_InitClock((int)(CLK_6502 * g_PhasorClockScaleFactor)); return MemReadFloatingBus(nCyclesLeft); } @@ -1764,9 +1778,9 @@ void MB_SetVolume(DWORD dwVolume, DWORD dwVolumeMax) //=========================================================================== // Called by debugger - Debugger_Display.cpp -void MB_GetSnapshot_v1(SS_CARD_MOCKINGBOARD* const pSS, const DWORD dwSlot) +void MB_GetSnapshot_v1(SS_CARD_MOCKINGBOARD_v1* const pSS, const DWORD dwSlot) { - pSS->Hdr.UnitHdr.hdr.v2.Length = sizeof(SS_CARD_MOCKINGBOARD); + pSS->Hdr.UnitHdr.hdr.v2.Length = sizeof(SS_CARD_MOCKINGBOARD_v1); pSS->Hdr.UnitHdr.hdr.v2.Type = UT_Card; pSS->Hdr.UnitHdr.hdr.v2.Version = 1; @@ -1777,19 +1791,22 @@ void MB_GetSnapshot_v1(SS_CARD_MOCKINGBOARD* const pSS, const DWORD dwSlot) UINT nDeviceNum = nMbCardNum*2; SY6522_AY8910* pMB = &g_MB[nDeviceNum]; - for(UINT i=0; iUnit[i].RegsSY6522, &pMB->sy6522, sizeof(SY6522)); memcpy(&pSS->Unit[i].RegsAY8910, AY8910_GetRegsPtr(nDeviceNum), 16); memcpy(&pSS->Unit[i].RegsSSI263, &pMB->SpeechChip, sizeof(SSI263A)); pSS->Unit[i].nAYCurrentRegister = pMB->nAYCurrentRegister; + pSS->Unit[i].bTimer1IrqPending = false; + pSS->Unit[i].bTimer2IrqPending = false; + pSS->Unit[i].bSpeechIrqPending = false; nDeviceNum++; pMB++; } } -int MB_SetSnapshot_v1(const SS_CARD_MOCKINGBOARD* const pSS, const DWORD /*dwSlot*/) +int MB_SetSnapshot_v1(const SS_CARD_MOCKINGBOARD_v1* const pSS, const DWORD /*dwSlot*/) { if(pSS->Hdr.UnitHdr.hdr.v1.dwVersion != MAKE_VERSION(1,0,0,0)) return -1; @@ -1801,7 +1818,7 @@ int MB_SetSnapshot_v1(const SS_CARD_MOCKINGBOARD* const pSS, const DWORD /*dwSlo g_nSSI263Device = 0; g_nCurrentActivePhoneme = -1; - for(UINT i=0; isy6522, &pSS->Unit[i].RegsSY6522, sizeof(SY6522)); memcpy(AY8910_GetRegsPtr(nDeviceNum), &pSS->Unit[i].RegsAY8910, 16); @@ -1837,86 +1854,134 @@ int MB_SetSnapshot_v1(const SS_CARD_MOCKINGBOARD* const pSS, const DWORD /*dwSlo //=========================================================================== +static UINT DoWriteFile(const HANDLE hFile, const void* const pData, const UINT Length) +{ + DWORD dwBytesWritten; + BOOL bRes = WriteFile( hFile, + pData, + Length, + &dwBytesWritten, + NULL); + + if(!bRes || (dwBytesWritten != Length)) + { + //dwError = GetLastError(); + throw std::string("Card: save error"); + } + + return dwBytesWritten; +} + +static UINT DoReadFile(const HANDLE hFile, void* const pData, const UINT Length) +{ + DWORD dwBytesRead; + BOOL bRes = ReadFile( hFile, + pData, + Length, + &dwBytesRead, + NULL); + + if (dwBytesRead != Length) + throw std::string("Card: file corrupt"); + + return dwBytesRead; +} + +//=========================================================================== + +struct Mockingboard_Unit +{ + SY6522 RegsSY6522; + SSI263A RegsSSI263; + BYTE AYCurrentRegister; + bool bTimer1IrqPending; + bool bTimer2IrqPending; + bool bSpeechIrqPending; +// SS_AY8910 AY8910; // Internal state of AY8910 +}; + +const UINT NUM_MB_UNITS = 2; + +struct SS_CARD_MOCKINGBOARD +{ + SS_CARD_HDR Hdr; + Mockingboard_Unit Unit[NUM_MB_UNITS]; +}; + void MB_GetSnapshot(const HANDLE hFile, const UINT uSlot) { - SS_CARD_MOCKINGBOARD CardMockingboardC; + SS_CARD_MOCKINGBOARD Card; - SS_CARD_MOCKINGBOARD* const pSS = &CardMockingboardC; + Card.Hdr.UnitHdr.hdr.v2.Length = sizeof(SS_CARD_MOCKINGBOARD); + Card.Hdr.UnitHdr.hdr.v2.Type = UT_Card; + Card.Hdr.UnitHdr.hdr.v2.Version = 1; - pSS->Hdr.UnitHdr.hdr.v2.Length = sizeof(SS_CARD_MOCKINGBOARD); - pSS->Hdr.UnitHdr.hdr.v2.Type = UT_Card; - pSS->Hdr.UnitHdr.hdr.v2.Version = 1; + Card.Hdr.Slot = uSlot; // fixme: object should be just 1 Mockingboard card & it will know its slot + Card.Hdr.Type = CT_MockingboardC; - pSS->Hdr.Slot = uSlot; // fixme: object should be just 1 Mockingboard card & it will know its slot - pSS->Hdr.Type = CT_MockingboardC; + const UINT nMbCardNum = uSlot - SLOT4; + Card.Hdr.UnitHdr.hdr.v2.Length += AY8910_GetSnapshot(NULL, nMbCardNum*2+0); + Card.Hdr.UnitHdr.hdr.v2.Length += AY8910_GetSnapshot(NULL, nMbCardNum*2+1); + + UINT uTotalWriteSize = DoWriteFile(hFile, &Card, (UINT)&Card.Unit-(UINT)&Card); + + // - UINT nMbCardNum = uSlot - SLOT4; UINT nDeviceNum = nMbCardNum*2; SY6522_AY8910* pMB = &g_MB[nDeviceNum]; - for(UINT i=0; iUnit[i].RegsSY6522, &pMB->sy6522, sizeof(SY6522)); - memcpy(&pSS->Unit[i].RegsAY8910, AY8910_GetRegsPtr(nDeviceNum), 16); - memcpy(&pSS->Unit[i].RegsSSI263, &pMB->SpeechChip, sizeof(SSI263A)); - pSS->Unit[i].nAYCurrentRegister = pMB->nAYCurrentRegister; + memcpy(&Card.Unit[i].RegsSY6522, &pMB->sy6522, sizeof(SY6522)); + memcpy(&Card.Unit[i].RegsSSI263, &pMB->SpeechChip, sizeof(SSI263A)); + Card.Unit[i].AYCurrentRegister = pMB->nAYCurrentRegister; + Card.Unit[i].bTimer1IrqPending = false; + Card.Unit[i].bTimer2IrqPending = false; + Card.Unit[i].bSpeechIrqPending = false; + uTotalWriteSize += DoWriteFile(hFile, &Card.Unit[i], sizeof(Card.Unit[0])); + + uTotalWriteSize += AY8910_GetSnapshot(hFile, nDeviceNum); nDeviceNum++; pMB++; } - // - - DWORD dwBytesWritten; - BOOL bRes = WriteFile( hFile, - &CardMockingboardC, - CardMockingboardC.Hdr.UnitHdr.hdr.v2.Length, - &dwBytesWritten, - NULL); - - if(!bRes || (dwBytesWritten != CardMockingboardC.Hdr.UnitHdr.hdr.v2.Length)) - { - //dwError = GetLastError(); - throw std::string("Save error: Mockingboard"); - } + _ASSERT(uTotalWriteSize == Card.Hdr.UnitHdr.hdr.v2.Length); + if (uTotalWriteSize != Card.Hdr.UnitHdr.hdr.v2.Length) + throw std::string("Card: unit size mismatch"); } void MB_SetSnapshot(const HANDLE hFile) { - SS_CARD_MOCKINGBOARD CardMockingboardC; + SS_CARD_MOCKINGBOARD Card; - DWORD dwBytesRead; - BOOL bRes = ReadFile( hFile, - &CardMockingboardC, - sizeof(CardMockingboardC), - &dwBytesRead, - NULL); + UINT uTotalReadSize = DoReadFile(hFile, &Card, (UINT)&Card.Unit-(UINT)&Card); - if (dwBytesRead != sizeof(CardMockingboardC)) - throw std::string("Card: file corrupt"); - - if (CardMockingboardC.Hdr.Slot != 4 && CardMockingboardC.Hdr.Slot != 5) // fixme + if (Card.Hdr.Slot != 4 && Card.Hdr.Slot != 5) // fixme throw std::string("Card: wrong slot"); - if (CardMockingboardC.Hdr.UnitHdr.hdr.v2.Version > 1) + if (Card.Hdr.UnitHdr.hdr.v2.Version > 1) throw std::string("Card: wrong version"); - if (CardMockingboardC.Hdr.UnitHdr.hdr.v2.Length != sizeof(SS_CARD_MOCKINGBOARD)) + if (Card.Hdr.UnitHdr.hdr.v2.Length <= sizeof(SS_CARD_MOCKINGBOARD)) throw std::string("Card: unit size mismatch"); - UINT nMbCardNum = CardMockingboardC.Hdr.Slot - SLOT4; + AY8910UpdateSetCycles(); + + const UINT nMbCardNum = Card.Hdr.Slot - SLOT4; UINT nDeviceNum = nMbCardNum*2; SY6522_AY8910* pMB = &g_MB[nDeviceNum]; g_nSSI263Device = 0; g_nCurrentActivePhoneme = -1; - for(UINT i=0; isy6522, &CardMockingboardC.Unit[i].RegsSY6522, sizeof(SY6522)); - memcpy(AY8910_GetRegsPtr(nDeviceNum), &CardMockingboardC.Unit[i].RegsAY8910, 16); - memcpy(&pMB->SpeechChip, &CardMockingboardC.Unit[i].RegsSSI263, sizeof(SSI263A)); - pMB->nAYCurrentRegister = CardMockingboardC.Unit[i].nAYCurrentRegister; + uTotalReadSize += DoReadFile(hFile, &Card.Unit[i], sizeof(Card.Unit[0])); + + memcpy(&pMB->sy6522, &Card.Unit[i].RegsSY6522, sizeof(SY6522)); + memcpy(&pMB->SpeechChip, &Card.Unit[i].RegsSSI263, sizeof(SSI263A)); + pMB->nAYCurrentRegister = Card.Unit[i].AYCurrentRegister; StartTimer(pMB); // Attempt to start timer @@ -1938,7 +2003,163 @@ void MB_SetSnapshot(const HANDLE hFile) } } + uTotalReadSize += AY8910_SetSnapshot(hFile, nDeviceNum); + nDeviceNum++; pMB++; } + + _ASSERT(uTotalReadSize == Card.Hdr.UnitHdr.hdr.v2.Length); + if (uTotalReadSize != Card.Hdr.UnitHdr.hdr.v2.Length) + throw std::string("Card: unit size mismatch"); + + AY8910_InitClock((int)CLK_6502); + + // Setup in MB_InitializeIO() -> MB_SetSoundcardType() + g_SoundcardType = CT_Empty; + g_bPhasorEnable = false; +} + +//=========================================================================== + +struct Phasor_Unit +{ + SY6522 RegsSY6522; + SSI263A RegsSSI263; + BYTE AYCurrentRegister; + bool bTimer1IrqPending; + bool bTimer2IrqPending; + bool bSpeechIrqPending; +// SS_AY8910 AY8910[2]; // Internal state of AY8910 +}; + +const UINT NUM_PHASOR_UNITS = 2; + +struct SS_CARD_PHASOR +{ + SS_CARD_HDR Hdr; + UINT ClockScaleFactor; + UINT Mode; + Phasor_Unit Unit[NUM_PHASOR_UNITS]; +}; + +void Phasor_GetSnapshot(const HANDLE hFile) +{ + SS_CARD_PHASOR Card; + + Card.Hdr.UnitHdr.hdr.v2.Length = sizeof(SS_CARD_PHASOR); + Card.Hdr.UnitHdr.hdr.v2.Type = UT_Card; + Card.Hdr.UnitHdr.hdr.v2.Version = 1; + + const UINT uSlot = 4; // fixme + Card.Hdr.Slot = uSlot; // fixme: object should just be Phasor card & it will know its slot + Card.Hdr.Type = CT_Phasor; + + Card.ClockScaleFactor = g_PhasorClockScaleFactor; + Card.Mode = g_nPhasorMode; + + for (UINT i=0; i<4; i++) + Card.Hdr.UnitHdr.hdr.v2.Length += AY8910_GetSnapshot(NULL, i); + + UINT uTotalWriteSize = DoWriteFile(hFile, &Card, (UINT)&Card.Unit-(UINT)&Card); + + // + + UINT nDeviceNum = 0; + SY6522_AY8910* pMB = &g_MB[0]; // fixme: Phasor uses MB's slot4(2x6522), slot4(2xSSI263), but slot4+5(4xAY8910) + + for(UINT i=0; isy6522, sizeof(SY6522)); + memcpy(&Card.Unit[i].RegsSSI263, &pMB->SpeechChip, sizeof(SSI263A)); + Card.Unit[i].AYCurrentRegister = pMB->nAYCurrentRegister; + Card.Unit[i].bTimer1IrqPending = false; + Card.Unit[i].bTimer2IrqPending = false; + Card.Unit[i].bSpeechIrqPending = false; + uTotalWriteSize += DoWriteFile(hFile, &Card.Unit[i], sizeof(Card.Unit[0])); + + uTotalWriteSize += AY8910_GetSnapshot(hFile, nDeviceNum+0); + uTotalWriteSize += AY8910_GetSnapshot(hFile, nDeviceNum+1); + + nDeviceNum += 2; + pMB++; + } + + _ASSERT(uTotalWriteSize == Card.Hdr.UnitHdr.hdr.v2.Length); + if (uTotalWriteSize != Card.Hdr.UnitHdr.hdr.v2.Length) + throw std::string("Card: unit size mismatch"); +} + +void Phasor_SetSnapshot(const HANDLE hFile) +{ + SS_CARD_PHASOR Card; + + UINT uTotalReadSize = DoReadFile(hFile, &Card, (UINT)&Card.Unit-(UINT)&Card); + + if (Card.Hdr.Slot != 4) // fixme + throw std::string("Card: wrong slot"); + + if (Card.Hdr.UnitHdr.hdr.v2.Version > 1) + throw std::string("Card: wrong version"); + + if (Card.Hdr.UnitHdr.hdr.v2.Length <= sizeof(SS_CARD_PHASOR)) + throw std::string("Card: unit size mismatch"); + + g_PhasorClockScaleFactor = Card.ClockScaleFactor; + g_nPhasorMode = Card.Mode; + + AY8910UpdateSetCycles(); + + UINT nDeviceNum = 0; + SY6522_AY8910* pMB = &g_MB[0]; + + g_nSSI263Device = 0; + g_nCurrentActivePhoneme = -1; + + for(UINT i=0; isy6522, &Card.Unit[i].RegsSY6522, sizeof(SY6522)); + memcpy(&pMB->SpeechChip, &Card.Unit[i].RegsSSI263, sizeof(SSI263A)); + pMB->nAYCurrentRegister = Card.Unit[i].AYCurrentRegister; + + StartTimer(pMB); // Attempt to start timer + + // + + // Crude - currently only support a single speech chip + // FIX THIS: + // . Speech chip could be Votrax instead + // . Is this IRQ compatible with Phasor? + if(pMB->SpeechChip.DurationPhonome) + { + g_nSSI263Device = nDeviceNum; + + if((pMB->SpeechChip.CurrentMode != MODE_IRQ_DISABLED) && (pMB->sy6522.PCR == 0x0C) && (pMB->sy6522.IER & IxR_PERIPHERAL)) + { + pMB->sy6522.IFR |= IxR_PERIPHERAL; + UpdateIFR(pMB); + pMB->SpeechChip.CurrentMode |= 1; // Set SSI263's D7 pin + } + } + + // + + uTotalReadSize += AY8910_SetSnapshot(hFile, nDeviceNum+0); + uTotalReadSize += AY8910_SetSnapshot(hFile, nDeviceNum+1); + + nDeviceNum += 2; + pMB++; + } + + _ASSERT(uTotalReadSize == Card.Hdr.UnitHdr.hdr.v2.Length); + if (uTotalReadSize != Card.Hdr.UnitHdr.hdr.v2.Length) + throw std::string("Card: unit size mismatch"); + + AY8910_InitClock((int)(CLK_6502 * g_PhasorClockScaleFactor)); + + // Setup in MB_InitializeIO() -> MB_SetSoundcardType() + g_SoundcardType = CT_Empty; + g_bPhasorEnable = false; } diff --git a/source/Mockingboard.h b/source/Mockingboard.h index dc9f55c5..b87fe3c0 100644 --- a/source/Mockingboard.h +++ b/source/Mockingboard.h @@ -23,7 +23,10 @@ bool MB_IsActive(); DWORD MB_GetVolume(); void MB_SetVolume(DWORD dwVolume, DWORD dwVolumeMax); -void MB_GetSnapshot_v1(struct SS_CARD_MOCKINGBOARD* const pSS, const DWORD dwSlot); // For debugger -int MB_SetSnapshot_v1(const struct SS_CARD_MOCKINGBOARD* const pSS, const DWORD dwSlot); +void MB_GetSnapshot_v1(struct SS_CARD_MOCKINGBOARD_v1* const pSS, const DWORD dwSlot); // For debugger +int MB_SetSnapshot_v1(const struct SS_CARD_MOCKINGBOARD_v1* const pSS, const DWORD dwSlot); void MB_GetSnapshot(const HANDLE hFile, const UINT uSlot); void MB_SetSnapshot(const HANDLE hFile); + +void Phasor_GetSnapshot(const HANDLE hFile); +void Phasor_SetSnapshot(const HANDLE hFile); diff --git a/source/SaveState.cpp b/source/SaveState.cpp index 4229fc15..1018b755 100644 --- a/source/SaveState.cpp +++ b/source/SaveState.cpp @@ -44,6 +44,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #include "SerialComms.h" #include "Speaker.h" #include "Video.h" +#include "z80emu.h" #include "Configuration\Config.h" #include "Configuration\IPropertySheet.h" @@ -211,6 +212,8 @@ static void Snapshot_LoadState_v1() // .aws v1.0.0.1, up to (and including) Appl MB_ICONEXCLAMATION | MB_SETFOREGROUND); SetCurrentImageDir(strOldImageDir.c_str()); + + PostMessage(g_hFrameWindow, WM_USER_RESTART, 0, 0); // Power-cycle VM (undoing all the new state just loaded) } delete [] pSS; @@ -270,17 +273,16 @@ static void Snapshot_LoadState_FileHdr(SS_FILE_HDR& Hdr) static void LoadUnitApple2(DWORD Length, DWORD Version) { - SS_APPLE2_Unit_v2 Apple2Unit; - if (Version != UNIT_APPLE2_VER) throw std::string("Apple2: Version mismatch"); - if (Length != sizeof(Apple2Unit)) + if (Length != sizeof(SS_APPLE2_Unit_v2)) throw std::string("Apple2: Length mismatch"); - if (SetFilePointer(m_hFile, -(LONG)sizeof(Apple2Unit.UnitHdr), NULL, FILE_CURRENT) == INVALID_SET_FILE_POINTER) + if (SetFilePointer(m_hFile, -(LONG)sizeof(SS_UNIT_HDR), NULL, FILE_CURRENT) == INVALID_SET_FILE_POINTER) throw std::string("Apple2: file corrupt"); + SS_APPLE2_Unit_v2 Apple2Unit; DWORD dwBytesRead; BOOL bRes = ReadFile( m_hFile, &Apple2Unit, @@ -335,6 +337,21 @@ static void LoadCardHDD(void) m_ConfigNew.m_bEnableHDD = true; } +static void LoadCardPhasor(void) +{ + Phasor_SetSnapshot(m_hFile); +} + +static void LoadCardZ80(void) +{ + Z80_SetSnapshot(m_hFile); +} + +static void LoadCard80ColAuxMem(void) +{ + MemSetSnapshotAux(m_hFile); +} + //=== static void LoadUnitCard(DWORD Length, DWORD Version) @@ -391,10 +408,15 @@ static void LoadUnitCard(DWORD Length, DWORD Version) LoadCardMouseInterface(); break; case CT_Z80: - throw std::string("Card: todo"); + LoadCardZ80(); break; case CT_Phasor: - throw std::string("Card: todo"); + LoadCardPhasor(); + break; + case CT_80Col: + case CT_Extended80Col: + case CT_RamWorksIII: + LoadCard80ColAuxMem(); break; default: //throw std::string("Card: unsupported"); @@ -404,7 +426,12 @@ static void LoadUnitCard(DWORD Length, DWORD Version) } if (bIsCardSupported) - m_ConfigNew.m_Slot[Card.Slot] = (SS_CARDTYPE) Card.Type; + { + if (Card.Slot <= 7) + m_ConfigNew.m_Slot[Card.Slot] = (SS_CARDTYPE) Card.Type; + else + m_ConfigNew.m_SlotAux = (SS_CARDTYPE) Card.Type; + } } static void LoadUnitConfig(DWORD Length, DWORD Version) @@ -432,7 +459,6 @@ static void LoadUnitConfig(DWORD Length, DWORD Version) // todo: //m_ConfigNew.m_bEnhanceDisk; - //m_ConfigNew.m_bEnableHDD; } static void Snapshot_LoadState_v2(DWORD dwVersion) @@ -447,14 +473,18 @@ static void Snapshot_LoadState_v2(DWORD dwVersion) ConfigOld.m_Slot[2] = CT_SSC; // fixme ConfigOld.m_Slot[6] = CT_Disk2; // fixme ConfigOld.m_Slot[7] = ConfigOld.m_bEnableHDD ? CT_GenericHDD : CT_Empty; // fixme + //ConfigOld.m_SlotAux = ?; // fixme for (UINT i=0; iHdr.UnitHdr.hdr.v2.Length = sizeof(SS_CARD_Z80); + pSS->Hdr.UnitHdr.hdr.v2.Type = UT_Card; + pSS->Hdr.UnitHdr.hdr.v2.Version = 1; + + pSS->Hdr.Slot = uZ80Slot; // fixme: object should know its slot + pSS->Hdr.Type = CT_Z80; + + pSS->Unit.reg_a = reg_a; + pSS->Unit.reg_b = reg_b; + pSS->Unit.reg_c = reg_c; + pSS->Unit.reg_d = reg_d; + pSS->Unit.reg_e = reg_e; + pSS->Unit.reg_f = reg_f; + pSS->Unit.reg_h = reg_h; + pSS->Unit.reg_l = reg_l; + pSS->Unit.reg_ixh = reg_ixh; + pSS->Unit.reg_ixl = reg_ixl; + pSS->Unit.reg_iyh = reg_iyh; + pSS->Unit.reg_iyl = reg_iyl; + pSS->Unit.reg_sp = reg_sp; + pSS->Unit.z80_reg_pc = z80_reg_pc; + pSS->Unit.reg_i = reg_i; + pSS->Unit.reg_r = reg_r; + + pSS->Unit.iff1 = iff1; + pSS->Unit.iff2 = iff2; + pSS->Unit.im_mode = im_mode; + + pSS->Unit.reg_a2 = reg_a2; + pSS->Unit.reg_b2 = reg_b2; + pSS->Unit.reg_c2 = reg_c2; + pSS->Unit.reg_d2 = reg_d2; + pSS->Unit.reg_e2 = reg_e2; + pSS->Unit.reg_f2 = reg_f2; + pSS->Unit.reg_h2 = reg_h2; + pSS->Unit.reg_l2 = reg_l2; + + // SoftCard SW & HW details: http://apple2info.net/images/f/f0/SC-SWHW.pdf + // . SoftCard uses the Apple II's DMA circuit to pause the 6502 (no CLK to 6502) + // . But: "In Apple II DMA, the 6502 CPU will die after approximately 15 clocks because it depends on the clock to refresh its internal registers." + // ref: Apple Tech Note: https://archive.org/stream/IIe_2523004_RDY_Line/IIe_2523004_RDY_Line_djvu.txt + // NB. Not for 65C02 which is a static processor. + // . SoftCard controls the 6502's RDY line to periodically allow only 1 memory fetch by 6502 (ie. the opcode fetch) + // + // So save /g_ActiveCPU/ to SS_CARD_Z80 (so RDY is like IRQ & NMI signals, ie. saved struct of the producer's card) + // + // NB. Save-state only occurs when message pump runs: + // . ie. at end of 1ms emulation burst + // Either 6502 or Z80 could be active. + // + + pSS->Active = g_ActiveCPU == CPU_Z80 ? 1 : 0; + + // + + DWORD dwBytesWritten; + BOOL bRes = WriteFile( hFile, + &Card, + Card.Hdr.UnitHdr.hdr.v2.Length, + &dwBytesWritten, + NULL); + + if(!bRes || (dwBytesWritten != Card.Hdr.UnitHdr.hdr.v2.Length)) + { + //dwError = GetLastError(); + throw std::string("Save error: Z80"); + } +} + +void Z80_SetSnapshot(const HANDLE hFile) +{ + SS_CARD_Z80 Card; + + DWORD dwBytesRead; + BOOL bRes = ReadFile( hFile, + &Card, + sizeof(Card), + &dwBytesRead, + NULL); + + if (dwBytesRead != sizeof(Card)) + throw std::string("Card: file corrupt"); + + if (Card.Hdr.Slot != 4 && Card.Hdr.Slot != 5) // fixme + throw std::string("Card: wrong slot"); + + if (Card.Hdr.UnitHdr.hdr.v2.Version > 1) + throw std::string("Card: wrong version"); + + if (Card.Hdr.UnitHdr.hdr.v2.Length != sizeof(SS_CARD_Z80)) + throw std::string("Card: unit size mismatch"); + + SS_CARD_Z80* pSS = &Card; + + reg_a = pSS->Unit.reg_a; + reg_b = pSS->Unit.reg_b; + reg_c = pSS->Unit.reg_c; + reg_d = pSS->Unit.reg_d; + reg_e = pSS->Unit.reg_e; + reg_f = pSS->Unit.reg_f; + reg_h = pSS->Unit.reg_h; + reg_l = pSS->Unit.reg_l; + reg_ixh = pSS->Unit.reg_ixh; + reg_ixl = pSS->Unit.reg_ixl; + reg_iyh = pSS->Unit.reg_iyh; + reg_iyl = pSS->Unit.reg_iyl; + reg_sp = pSS->Unit.reg_sp; + z80_reg_pc = pSS->Unit.z80_reg_pc; + reg_i = pSS->Unit.reg_i; + reg_r = pSS->Unit.reg_r; + + iff1 = pSS->Unit.iff1; + iff2 = pSS->Unit.iff2; + im_mode = pSS->Unit.im_mode; + + reg_a2 = pSS->Unit.reg_a2; + reg_b2 = pSS->Unit.reg_b2; + reg_c2 = pSS->Unit.reg_c2; + reg_d2 = pSS->Unit.reg_d2; + reg_e2 = pSS->Unit.reg_e2; + reg_f2 = pSS->Unit.reg_f2; + reg_h2 = pSS->Unit.reg_h2; + reg_l2 = pSS->Unit.reg_l2; + + export_registers(); + + if (pSS->Active) + g_ActiveCPU = CPU_Z80; // Support MS SoftCard in multiple slots (only one Z80 can be active at any one time) +} diff --git a/source/Z80VICE/z80regs.h b/source/Z80VICE/z80regs.h index 025d08fc..54c59e81 100644 --- a/source/Z80VICE/z80regs.h +++ b/source/Z80VICE/z80regs.h @@ -46,6 +46,7 @@ typedef struct z80_regs_s { WORD reg_hl2; } z80_regs_t; +#if 0 // [AppleWin-TC]: unused, so comment out #define Z80_REGS_GET_AF(reg_ptr) ((reg_ptr)->reg_af) #define Z80_REGS_GET_BC(reg_ptr) ((reg_ptr)->reg_bc) #define Z80_REGS_GET_DE(reg_ptr) ((reg_ptr)->reg_de) @@ -75,6 +76,7 @@ typedef struct z80_regs_s { #define Z80_REGS_SET_BC2(reg_ptr, val) ((reg_ptr)->reg_bc2 = (val)) #define Z80_REGS_SET_DE2(reg_ptr, val) ((reg_ptr)->reg_de2 = (val)) #define Z80_REGS_SET_HL2(reg_ptr, val) ((reg_ptr)->reg_hl2 = (val)) +#endif #endif diff --git a/source/z80emu.h b/source/z80emu.h index 18d20504..13e0b705 100644 --- a/source/z80emu.h +++ b/source/z80emu.h @@ -14,3 +14,7 @@ // Protótipos void ConfigureSoftcard(LPBYTE pCxRomPeripheral, UINT uSlot); + +// NB. These are in z80.cpp: +void Z80_GetSnapshot(const HANDLE hFile, const UINT uZ80Slot); +void Z80_SetSnapshot(const HANDLE hFile); From f114a9b8feb51ca6c4008d81bd0c4f6450ef29ef Mon Sep 17 00:00:00 2001 From: tomcw Date: Sun, 12 Apr 2015 17:30:16 +0100 Subject: [PATCH 03/20] Save-state: alloc extra 64K banks for RamWorks card if needed --- source/AY8910.h | 1 - source/Applewin.cpp | 4 ++-- source/Memory.cpp | 32 +++++++++++++++++++------------- source/Memory.h | 1 + source/Mockingboard.cpp | 2 +- 5 files changed, 23 insertions(+), 17 deletions(-) diff --git a/source/AY8910.h b/source/AY8910.h index 00c4cf76..0b7fd50f 100644 --- a/source/AY8910.h +++ b/source/AY8910.h @@ -46,7 +46,6 @@ public: void sound_frame( void ); BYTE* GetAYRegsPtr( void ) { return &sound_ay_registers[0]; } static void SetCLK( double CLK ) { m_fCurrentCLK_AY8910 = CLK; } - void ClearAYChangeCount( void ) { ay_change_count = 0; } UINT GetSnapshot(const HANDLE hFile); UINT SetSnapshot(const HANDLE hFile); diff --git a/source/Applewin.cpp b/source/Applewin.cpp index 2f8272ef..7bbe3a4f 100644 --- a/source/Applewin.cpp +++ b/source/Applewin.cpp @@ -807,8 +807,8 @@ int APIENTRY WinMain(HINSTANCE passinstance, HINSTANCE, LPSTR lpCmdLine, int) lpCmdLine = GetCurrArg(lpNextArg); lpNextArg = GetNextArg(lpNextArg); g_uMaxExPages = atoi(lpCmdLine); - if (g_uMaxExPages > 127) - g_uMaxExPages = 128; + if (g_uMaxExPages > kMaxExMemoryBanks) + g_uMaxExPages = kMaxExMemoryBanks; else if (g_uMaxExPages < 1) g_uMaxExPages = 1; } diff --git a/source/Memory.cpp b/source/Memory.cpp index 5109a12d..ac88869a 100644 --- a/source/Memory.cpp +++ b/source/Memory.cpp @@ -194,9 +194,9 @@ static BOOL Pravets8charmode = 0; static CNoSlotClock g_NoSlotClock; #ifdef RAMWORKS -UINT g_uMaxExPages = 1; // user requested ram pages -UINT g_uActiveBank = 0; // 0 = memaux -static LPBYTE RWpages[128]; // pointers to RW memory banks +UINT g_uMaxExPages = 1; // user requested ram pages (default to 1 aux bank: so total = 128KB) +UINT g_uActiveBank = 0; // 0 = aux 64K for: //e extended 80 Col card, or //c +static LPBYTE RWpages[kMaxExMemoryBanks]; // pointers to RW memory banks #endif BYTE __stdcall IO_Annunciator(WORD programcounter, WORD address, BYTE write, BYTE value, ULONG nCycles); @@ -1024,7 +1024,7 @@ static LPBYTE MemGetPtrBANK1(const WORD offset, const LPBYTE pMemBase) if ((offset & 0xF000) != 0xC000) // Requesting RAM at physical addr $Cxxx (ie. 4K RAM BANK1) return NULL; - // fixme: Need to extend for RAMWORKS / RWpages (when pMemBase == memaux) + // NB. This works for memaux when set to any RWpages[] value, ie. RamWork III "just works" const BYTE bank1page = (offset >> 8) & 0xF; return (memshadow[0xD0+bank1page] == pMemBase+(0xC0+bank1page)*256) ? mem+offset+0x1000 // Return ptr to $Dxxx address - 'mem' has (a potentially dirty) 4K RAM BANK1 mapped in at $D000 @@ -1734,8 +1734,8 @@ void MemSetSnapshot(const SS_BaseMemory_v2& Memory) struct SS_CARD_80COL_AUX_MEMORY { SS_CARD_HDR Hdr; - UINT NumBanks; - UINT ActiveBank; + UINT NumAuxBanks; // [0,1..127] 0=no aux mem, 1=128K system, etc + UINT ActiveAuxBank; // [ 0..126] 0=memaux BYTE MemAux[0]; }; @@ -1764,8 +1764,8 @@ void MemGetSnapshotAux(const HANDLE hFile) g_uMaxExPages == 1 ? CT_Extended80Col : CT_RamWorksIII; - pSS->ActiveBank = g_uActiveBank; - pSS->NumBanks = g_uMaxExPages; + pSS->ActiveAuxBank = g_uActiveBank; + pSS->NumAuxBanks = g_uMaxExPages; for(UINT uBank = 1; uBank <= g_uMaxExPages; uBank++) { @@ -1814,17 +1814,23 @@ void MemSetSnapshotAux(const HANDLE hFile) if (Card.Hdr.UnitHdr.hdr.v2.Length < sizeof(SS_CARD_80COL_AUX_MEMORY)) throw std::string("Card: unit size mismatch"); - g_uActiveBank = Card.ActiveBank; - g_uMaxExPages = Card.NumBanks; + if (Card.NumAuxBanks > kMaxExMemoryBanks) + throw std::string("Card: file corrupt"); + + if (Card.ActiveAuxBank >= Card.NumAuxBanks) + throw std::string("Card: file corrupt"); + + g_uActiveBank = Card.ActiveAuxBank; + g_uMaxExPages = Card.NumAuxBanks; for(UINT uBank = 1; uBank <= g_uMaxExPages; uBank++) { LPBYTE pBank = MemGetBankPtr(uBank); if (!pBank) { - // todo: alloc - _ASSERT(pBank); - break; + pBank = RWpages[uBank-1] = (LPBYTE) VirtualAlloc(NULL,_6502_MEM_END+1,MEM_COMMIT,PAGE_READWRITE); + if (!pBank) + throw std::string("Card: mem alloc failed"); } bRes = ReadFile( hFile, diff --git a/source/Memory.h b/source/Memory.h index e516a3e5..bdd4fb19 100644 --- a/source/Memory.h +++ b/source/Memory.h @@ -32,6 +32,7 @@ extern LPBYTE mem; extern LPBYTE memdirty; #ifdef RAMWORKS +const UINT kMaxExMemoryBanks = 127; // 127 * aux mem(64K) + main mem(64K) = 8MB extern UINT g_uMaxExPages; // user requested ram pages (from cmd line) #endif diff --git a/source/Mockingboard.cpp b/source/Mockingboard.cpp index bf9f6e33..f1d3b2cb 100644 --- a/source/Mockingboard.cpp +++ b/source/Mockingboard.cpp @@ -1000,7 +1000,7 @@ static DWORD WINAPI SSI263Thread(LPVOID lpParameter) //----------------------------------------------------------------------------- -// Warning! Data-race! +// Warning! Data-race! [FIXME] // . SSI263Thread() can asynchronously set /g_nCurrentActivePhoneme/ to -1 // . I have seen it on a call to Play(0,0,0) // . eg. could occur between [1] and [2] From 9ceb95372f274145d0561d41b7c290e0c3b88500 Mon Sep 17 00:00:00 2001 From: tomcw Date: Sun, 12 Apr 2015 18:17:08 +0100 Subject: [PATCH 04/20] SSI263 speech: fix for data-race (todo: raise GH issue, since it resulted in a Win32 crash) --- source/Mockingboard.cpp | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/source/Mockingboard.cpp b/source/Mockingboard.cpp index f1d3b2cb..b8ea7ec0 100644 --- a/source/Mockingboard.cpp +++ b/source/Mockingboard.cpp @@ -157,8 +157,8 @@ static UINT64 g_uLastCumulativeCycles = 0; // SSI263 vars: static USHORT g_nSSI263Device = 0; // SSI263 device# which is generating phoneme-complete IRQ -static int g_nCurrentActivePhoneme = -1; -static bool g_bStopPhoneme = false; +static volatile int g_nCurrentActivePhoneme = -1; // Modified by threads: main & SSI263Thread +static volatile bool g_bStopPhoneme = false; // Modified by threads: main & SSI263Thread static bool g_bVotraxPhoneme = false; static const DWORD SAMPLE_RATE = 44100; // Use a base freq so that DirectX (or sound h/w) doesn't have to up/down-sample @@ -1000,29 +1000,31 @@ static DWORD WINAPI SSI263Thread(LPVOID lpParameter) //----------------------------------------------------------------------------- -// Warning! Data-race! [FIXME] -// . SSI263Thread() can asynchronously set /g_nCurrentActivePhoneme/ to -1 -// . I have seen it on a call to Play(0,0,0) -// . eg. could occur between [1] and [2] -// - presumably after Stop(), wait for: g_bStopPhoneme == false OR for g_nCurrentActivePhoneme == -1 -// - NB. sample could finish between: if (g_nCurrentActivePhoneme >= 0) and g_bStopPhoneme = true - static void SSI263_Play(unsigned int nPhoneme) { #if 1 HRESULT hr; - if(g_nCurrentActivePhoneme >= 0) { - // A write to DURPHON before previous phoneme has completed - g_bStopPhoneme = true; - hr = SSI263Voice[g_nCurrentActivePhoneme].lpDSBvoice->Stop(); + int nCurrPhoneme = g_nCurrentActivePhoneme; // local copy in case SSI263Thread sets it to -1 + if (nCurrPhoneme >= 0) + { + // A write to DURPHON before previous phoneme has completed + g_bStopPhoneme = true; + hr = SSI263Voice[nCurrPhoneme].lpDSBvoice->Stop(); + + // Busy-wait until ACK from SSI263Thread + // . required to avoid data-race + while ( g_bStopPhoneme && // wait for SSI263Thread to ACK the lpDSBVoice->Stop() + g_nCurrentActivePhoneme >= 0) // wait for SSI263Thread to get end of sample event + ; + + g_bStopPhoneme = false; + } } g_nCurrentActivePhoneme = nPhoneme; - // [1] - hr = SSI263Voice[g_nCurrentActivePhoneme].lpDSBvoice->SetCurrentPosition(0); if(FAILED(hr)) return; @@ -1032,8 +1034,6 @@ static void SSI263_Play(unsigned int nPhoneme) return; SSI263Voice[g_nCurrentActivePhoneme].bActive = true; - - // [2] #else HRESULT hr; bool bPause; From 559a236b14fc52f7592830371b488c4cd1514391 Mon Sep 17 00:00:00 2001 From: tomcw Date: Sun, 31 May 2015 22:53:53 +0100 Subject: [PATCH 05/20] Save-state: . On save: append .aws if missing . Added Pravets.cpp/h (for this clone's specific stuff) --- AppleWinExpress2012.vcxproj | 6 ++- AppleWinExpress2012.vcxproj.filters | 9 ++++ AppleWinExpress2013.vcxproj | 4 +- AppleWinExpress2013.vcxproj.filters | 9 ++++ ApplewinExpress9.00.vcproj | 12 +++++ source/Applewin.cpp | 3 -- source/Applewin.h | 3 -- source/Configuration/PropertySheetHelper.cpp | 9 ++-- source/Disk.cpp | 4 +- source/Frame.cpp | 7 +++ source/Keyboard.cpp | 1 + source/Memory.cpp | 30 +++++------- source/Pravets.cpp | 48 ++++++++++++++++++++ source/Pravets.h | 7 +++ source/SaveState.cpp | 34 ++++++-------- source/SaveState_Structs_v2.h | 4 ++ source/SerialComms.cpp | 12 +---- source/SerialComms.h | 4 +- source/Tape.cpp | 1 + 19 files changed, 140 insertions(+), 67 deletions(-) create mode 100644 source/Pravets.cpp create mode 100644 source/Pravets.h diff --git a/AppleWinExpress2012.vcxproj b/AppleWinExpress2012.vcxproj index 9058a6f0..42ba5edb 100644 --- a/AppleWinExpress2012.vcxproj +++ b/AppleWinExpress2012.vcxproj @@ -59,6 +59,7 @@ + @@ -74,6 +75,7 @@ + @@ -94,7 +96,6 @@ - @@ -136,6 +137,7 @@ + @@ -149,6 +151,7 @@ + @@ -187,7 +190,6 @@ NotUsing NotUsing - diff --git a/AppleWinExpress2012.vcxproj.filters b/AppleWinExpress2012.vcxproj.filters index 16d275cb..81d4fde5 100644 --- a/AppleWinExpress2012.vcxproj.filters +++ b/AppleWinExpress2012.vcxproj.filters @@ -30,6 +30,9 @@ {9b13bfc1-31ab-4f55-bb69-b8620ebdc2be} + + {15b450e4-f89f-4d80-9c44-48b32f33f3e3} + {9bcc8097-f610-4843-bd76-a313aa54fbb0} @@ -291,6 +294,9 @@ Source Files\Debugger + + Source Files\Model + @@ -484,6 +490,9 @@ Source Files\Uthernet + + Source Files\Model + diff --git a/AppleWinExpress2013.vcxproj b/AppleWinExpress2013.vcxproj index 87520852..076e57da 100644 --- a/AppleWinExpress2013.vcxproj +++ b/AppleWinExpress2013.vcxproj @@ -75,6 +75,7 @@ + @@ -106,7 +107,7 @@ - + @@ -150,6 +151,7 @@ + diff --git a/AppleWinExpress2013.vcxproj.filters b/AppleWinExpress2013.vcxproj.filters index 2551d0ed..9530e86b 100644 --- a/AppleWinExpress2013.vcxproj.filters +++ b/AppleWinExpress2013.vcxproj.filters @@ -169,6 +169,9 @@ Source Files\Debugger + + Source Files\Model + @@ -417,6 +420,9 @@ Source Files\Disk + + Source Files\Model + @@ -638,6 +644,9 @@ {b5c6889e-727d-4339-96c8-e4284e1d6e0f} + + {15b450e4-f89f-4d80-9c44-48b32f33f3e3} + diff --git a/ApplewinExpress9.00.vcproj b/ApplewinExpress9.00.vcproj index 3973237d..c879979c 100644 --- a/ApplewinExpress9.00.vcproj +++ b/ApplewinExpress9.00.vcproj @@ -955,6 +955,18 @@ > + + + + + + Hdr.Slot = g_uSlot; pSS->Hdr.Type = CT_Disk2; - pSS->Phases = phases; + pSS->Phases = phases; pSS->CurrDrive = currdrive; pSS->DiskAccessed = diskaccessed; pSS->EnhanceDisk = enhancedisk; diff --git a/source/Frame.cpp b/source/Frame.cpp index 84cc1d45..98e8cf9b 100644 --- a/source/Frame.cpp +++ b/source/Frame.cpp @@ -41,6 +41,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #include "Mockingboard.h" #include "MouseInterface.h" #include "ParallelPrinter.h" +#include "Pravets.h" #include "Registry.h" #include "SaveState.h" #include "SerialComms.h" @@ -1992,12 +1993,15 @@ void RelayEvent (UINT message, WPARAM wparam, LPARAM lparam) { } //=========================================================================== + +// todo: consolidate CtrlReset() and ResetMachineState() void ResetMachineState () { DiskReset(); // Set floppymotoron=0 g_bFullSpeed = 0; // Might've hit reset in middle of InternalCpuExecute() - so beep may get (partially) muted MemReset(); + PravetsReset(); DiskBoot(); VideoResetState(); sg_SSC.CommReset(); @@ -2016,12 +2020,15 @@ void ResetMachineState () //=========================================================================== + +// todo: consolidate CtrlReset() and ResetMachineState() void CtrlReset() { // Ctrl+Reset - TODO: This is a terrible place for this code! if (!IS_APPLE2) MemResetPaging(); + PravetsReset(); DiskReset(); KeybReset(); if (!IS_APPLE2) diff --git a/source/Keyboard.cpp b/source/Keyboard.cpp index e3e3e2d1..b217e356 100644 --- a/source/Keyboard.cpp +++ b/source/Keyboard.cpp @@ -31,6 +31,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #include "AppleWin.h" #include "Frame.h" #include "Keyboard.h" +#include "Pravets.h" #include "Tape.h" static bool g_bKeybBufferEnable = false; diff --git a/source/Memory.cpp b/source/Memory.cpp index ac88869a..0aa4e490 100644 --- a/source/Memory.cpp +++ b/source/Memory.cpp @@ -200,7 +200,6 @@ static LPBYTE RWpages[kMaxExMemoryBanks]; // pointers to RW memory banks #endif BYTE __stdcall IO_Annunciator(WORD programcounter, WORD address, BYTE write, BYTE value, ULONG nCycles); -void UpdatePaging(BOOL initialize); //============================================================================= @@ -811,6 +810,16 @@ static void SetMemMode(const DWORD uNewMemMode) //=========================================================================== +static void ResetPaging(BOOL initialize); +static void UpdatePaging(BOOL initialize); + +// Call by: +// . CtrlReset() Soft-reset (Ctrl+Reset) +void MemResetPaging() +{ + ResetPaging(0); // Initialize=0 +} + static void ResetPaging(BOOL initialize) { lastwriteram = 0; @@ -1330,7 +1339,8 @@ inline DWORD getRandomTime() // Called by: // . MemInitialize() // . ResetMachineState() eg. Power-cycle ('Apple-Go' button) -// . Snapshot_LoadState() +// . Snapshot_LoadState_v1() +// . Snapshot_LoadState_v2() void MemReset() { // INITIALIZE THE PAGING TABLES @@ -1485,22 +1495,6 @@ void MemReset() //=========================================================================== -// Call by: -// . Soft-reset (Ctrl+Reset) -// . Snapshot_LoadState() -void MemResetPaging() -{ - ResetPaging(0); // Initialize=0 - if (g_Apple2Type == A2TYPE_PRAVETS8A) - { - P8CAPS_ON = false; - TapeWrite (0, 0, 0, 0 ,0); - FrameRefreshStatus(DRAW_LEDS); - } -} - -//=========================================================================== - BYTE MemReadFloatingBus(const ULONG uExecutedCycles) { return*(LPBYTE)(mem + VideoGetScannerAddress(NULL, uExecutedCycles)); diff --git a/source/Pravets.cpp b/source/Pravets.cpp new file mode 100644 index 00000000..296cf4f7 --- /dev/null +++ b/source/Pravets.cpp @@ -0,0 +1,48 @@ +/* +AppleWin : An Apple //e emulator for Windows + +Copyright (C) 1994-1996, Michael O'Brien +Copyright (C) 1999-2001, Oliver Schmidt +Copyright (C) 2002-2005, Tom Charlesworth +Copyright (C) 2006-2015, Tom Charlesworth, Michael Pohoreski + +AppleWin is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +AppleWin is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with AppleWin; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +/* Description: Pravets - Apple II clone + * + * Author: Various + */ + +#include "StdAfx.h" + +#include "AppleWin.h" +#include "Frame.h" +#include "Keyboard.h" +#include "Tape.h" + +//Pravets 8A/C variables +bool P8CAPS_ON = false; +bool P8Shift = false; + +void PravetsReset(void) +{ + if (g_Apple2Type == A2TYPE_PRAVETS8A) + { + P8CAPS_ON = false; + TapeWrite(0, 0, 0, 0 ,0); + FrameRefreshStatus(DRAW_LEDS); + } +} diff --git a/source/Pravets.h b/source/Pravets.h new file mode 100644 index 00000000..801d1804 --- /dev/null +++ b/source/Pravets.h @@ -0,0 +1,7 @@ +#pragma once + +//Pravets 8A/C only variables +extern bool P8CAPS_ON; +extern bool P8Shift; + +void PravetsReset(void); diff --git a/source/SaveState.cpp b/source/SaveState.cpp index 1018b755..fde5f19a 100644 --- a/source/SaveState.cpp +++ b/source/SaveState.cpp @@ -4,7 +4,7 @@ AppleWin : An Apple //e emulator for Windows Copyright (C) 1994-1996, Michael O'Brien Copyright (C) 1999-2001, Oliver Schmidt Copyright (C) 2002-2005, Tom Charlesworth -Copyright (C) 2006-2007, Tom Charlesworth, Michael Pohoreski +Copyright (C) 2006-2015, Tom Charlesworth, Michael Pohoreski AppleWin is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -41,8 +41,10 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #include "Mockingboard.h" #include "MouseInterface.h" #include "ParallelPrinter.h" +#include "Pravets.h" #include "SerialComms.h" #include "Speaker.h" +#include "Speech.h" #include "Video.h" #include "z80emu.h" @@ -161,10 +163,6 @@ static void Snapshot_LoadState_v1() // .aws v1.0.0.1, up to (and including) Appl // // Reset all sub-systems MemReset(); - - if (!IS_APPLE2) - MemResetPaging(); - DiskReset(); KeybReset(); VideoResetState(); @@ -221,8 +219,8 @@ static void Snapshot_LoadState_v1() // .aws v1.0.0.1, up to (and including) Appl //----------------------------------------------------------------------------- -HANDLE m_hFile = INVALID_HANDLE_VALUE; -CConfigNeedingRestart m_ConfigNew; +static HANDLE m_hFile = INVALID_HANDLE_VALUE; +static CConfigNeedingRestart m_ConfigNew; static void Snapshot_LoadState_FileHdr(SS_FILE_HDR& Hdr) { @@ -267,10 +265,6 @@ static void Snapshot_LoadState_FileHdr(SS_FILE_HDR& Hdr) } } -#define UNIT_APPLE2_VER 1 -#define UNIT_CARD_VER 1 -#define UNIT_CONFIG_VER 1 - static void LoadUnitApple2(DWORD Length, DWORD Version) { if (Version != UNIT_APPLE2_VER) @@ -434,6 +428,7 @@ static void LoadUnitCard(DWORD Length, DWORD Version) } } +#if 0 static void LoadUnitConfig(DWORD Length, DWORD Version) { SS_APPLEWIN_CONFIG Cfg; @@ -460,6 +455,7 @@ static void LoadUnitConfig(DWORD Length, DWORD Version) // todo: //m_ConfigNew.m_bEnhanceDisk; } +#endif static void Snapshot_LoadState_v2(DWORD dwVersion) { @@ -480,16 +476,14 @@ static void Snapshot_LoadState_v2(DWORD dwVersion) m_ConfigNew.m_SlotAux = CT_Empty; MemReset(); - - // fixme: Apple type may change - assume ths can be removed? - if (!IS_APPLE2) - MemResetPaging(); - // fixme-end - + PravetsReset(); DiskReset(); KeybReset(); VideoResetState(); MB_Reset(); +#ifdef USE_SPEECH_API + g_Speech.Reset(); +#endif sg_Mouse.Uninitialize(); sg_Mouse.Reset(); HD_SetEnabled(false); @@ -518,9 +512,11 @@ static void Snapshot_LoadState_v2(DWORD dwVersion) case UT_Card: LoadUnitCard(UnitHdr.hdr.v2.Length, UnitHdr.hdr.v2.Version); break; +#if 0 case UT_Config: LoadUnitConfig(UnitHdr.hdr.v2.Length, UnitHdr.hdr.v2.Version); break; +#endif default: // Log then skip unsupported unit type break; @@ -541,8 +537,6 @@ static void Snapshot_LoadState_v2(DWORD dwVersion) MemInitializeIO(); MemUpdatePaging(TRUE); - - //PostMessage(g_hFrameWindow, WM_USER_RESTART, 0, 0); // No, as this power-cycles VM (undoing all the new state just loaded) } catch(std::string szMessage) { @@ -584,8 +578,6 @@ void Snapshot_SaveState() { try { - // todo: append '.aws' if missing - m_hFile = CreateFile( g_strSaveStatePathname.c_str(), GENERIC_WRITE, 0, diff --git a/source/SaveState_Structs_v2.h b/source/SaveState_Structs_v2.h index 3102047f..22a0eb2c 100644 --- a/source/SaveState_Structs_v2.h +++ b/source/SaveState_Structs_v2.h @@ -8,6 +8,10 @@ ///////////////////////////////////////////////////////////////////////////////// +#define UNIT_APPLE2_VER 1 +#define UNIT_CARD_VER 1 +#define UNIT_CONFIG_VER 1 + struct SS_CPU6502_v2 { BYTE A; diff --git a/source/SerialComms.cpp b/source/SerialComms.cpp index ec91f4af..041a9fca 100644 --- a/source/SerialComms.cpp +++ b/source/SerialComms.cpp @@ -1348,11 +1348,7 @@ struct SS_CARD_SSC SSC_Unit Unit; }; -// Post: -// 0 = No card -// >0 = Card saved OK from slot n -// -1 = File error -int CSuperSerialCard::GetSnapshot(const HANDLE hFile) +void CSuperSerialCard::GetSnapshot(const HANDLE hFile) { SS_CARD_SSC CardSuperSerial; @@ -1391,11 +1387,9 @@ int CSuperSerialCard::GetSnapshot(const HANDLE hFile) if(!bRes || (dwBytesWritten != CardSuperSerial.Hdr.UnitHdr.hdr.v2.Length)) throw std::string("Save error: SSC"); - - return m_uSlot; } -int CSuperSerialCard::SetSnapshot(const HANDLE hFile) +void CSuperSerialCard::SetSnapshot(const HANDLE hFile) { SS_CARD_SSC CardSuperSerial; @@ -1434,6 +1428,4 @@ int CSuperSerialCard::SetSnapshot(const HANDLE hFile) m_vbTxIrqPending = Unit.vbTxIrqPending; m_vbRxIrqPending = Unit.vbRxIrqPending; m_bWrittenTx = Unit.bWrittenTx; - - return 0; } diff --git a/source/SerialComms.h b/source/SerialComms.h index 7be33799..4c5d9859 100644 --- a/source/SerialComms.h +++ b/source/SerialComms.h @@ -34,8 +34,8 @@ public: void CommSetSerialPort(HWND hWindow, DWORD dwNewSerialPortItem); void CommUpdate(DWORD); void SetSnapshot_v1(const DWORD baudrate, const BYTE bytesize, const BYTE commandbyte, const DWORD comminactivity, const BYTE controlbyte, const BYTE parity, const BYTE stopbits); - int GetSnapshot(const HANDLE hFile); - int SetSnapshot(const HANDLE hFile); + void GetSnapshot(const HANDLE hFile); + void SetSnapshot(const HANDLE hFile); char* GetSerialPortChoices(); DWORD GetSerialPort() { return m_dwSerialPortItem; } // Drop-down list item diff --git a/source/Tape.cpp b/source/Tape.cpp index 0aef7f03..065f31f4 100644 --- a/source/Tape.cpp +++ b/source/Tape.cpp @@ -33,6 +33,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #include "AppleWin.h" #include "Keyboard.h" #include "Memory.h" +#include "Pravets.h" static bool g_CapsLockAllowed = false; From 18cd2afdd04e8d01f31319d4bd3e7918c8c1029b Mon Sep 17 00:00:00 2001 From: tomcw Date: Mon, 1 Jun 2015 22:35:57 +0100 Subject: [PATCH 06/20] Save-state: fix for EnableHDD flag not being reset for a new config --- source/SaveState.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/source/SaveState.cpp b/source/SaveState.cpp index fde5f19a..fdc0b7c7 100644 --- a/source/SaveState.cpp +++ b/source/SaveState.cpp @@ -474,6 +474,9 @@ static void Snapshot_LoadState_v2(DWORD dwVersion) for (UINT i=0; i Date: Fri, 21 Aug 2015 21:45:21 +0100 Subject: [PATCH 07/20] Save-state: . add ConfirmReboot . Restore saved configuration . Moved some config to Joystick & SerialCard . save config --- source/Applewin.cpp | 28 +++++-- source/Applewin.h | 2 +- source/Configuration/PageInput.cpp | 10 +-- source/Joystick.cpp | 36 +++++++- source/Joystick.h | 8 +- source/SaveState.cpp | 128 +++++++++++++++++++++++++---- source/SaveState_Structs_common.h | 1 + source/SaveState_Structs_v2.h | 18 ++-- source/SerialComms.cpp | 6 ++ 9 files changed, 192 insertions(+), 45 deletions(-) diff --git a/source/Applewin.cpp b/source/Applewin.cpp index e35f8b0d..7ff05ccf 100644 --- a/source/Applewin.cpp +++ b/source/Applewin.cpp @@ -56,6 +56,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #include "Configuration\PropertySheet.h" #include "Tfe\Tfe.h" +static UINT16 g_AppleWinVersion[4] = {0}; char VERSIONSTRING[16] = "xx.yy.zz.ww"; TCHAR *g_pAppTitle = TITLE_APPLE_2E_ENHANCED; @@ -110,6 +111,11 @@ CSpeech g_Speech; //=========================================================================== +const UINT16* GetAppleWinVersion(void) +{ + return &g_AppleWinVersion[0]; +} + bool GetLoadedSaveStateFlag(void) { return g_bLoadedSaveState; @@ -366,7 +372,7 @@ static void LoadConfigOldJoystick(const UINT uJoyNum) break; } - joytype[uJoyNum] = uNewJoyType; + JoySetJoyType(uJoyNum, uNewJoyType); } //Reads configuration from the registry entries @@ -407,9 +413,15 @@ void LoadConfiguration(void) // - if (!REGLOAD(TEXT(REGVALUE_JOYSTICK0_EMU_TYPE), &joytype[JN_JOYSTICK0])) + DWORD dwJoyType; + if (REGLOAD(TEXT(REGVALUE_JOYSTICK0_EMU_TYPE), &dwJoyType)) + JoySetJoyType(JN_JOYSTICK0, dwJoyType); + else LoadConfigOldJoystick(JN_JOYSTICK0); - if (!REGLOAD(TEXT(REGVALUE_JOYSTICK1_EMU_TYPE), &joytype[JN_JOYSTICK1])) + + if (REGLOAD(TEXT(REGVALUE_JOYSTICK1_EMU_TYPE), &dwJoyType)) + JoySetJoyType(JN_JOYSTICK1, dwJoyType); + else LoadConfigOldJoystick(JN_JOYSTICK1); REGLOAD(TEXT("Sound Emulation") ,&soundtype); @@ -898,11 +910,11 @@ int APIENTRY WinMain(HINSTANCE passinstance, HINSTANCE, LPSTR lpCmdLine, int) // Construct version string from fixed file info block - unsigned long major = pFixedFileInfo->dwFileVersionMS >> 16; - unsigned long minor = pFixedFileInfo->dwFileVersionMS & 0xffff; - unsigned long fix = pFixedFileInfo->dwFileVersionLS >> 16; - unsigned long fix_minor = pFixedFileInfo->dwFileVersionLS & 0xffff; - sprintf(VERSIONSTRING, "%d.%d.%d.%d", major, minor, fix, fix_minor); // potential buffer overflow + unsigned long major = g_AppleWinVersion[0] = pFixedFileInfo->dwFileVersionMS >> 16; + unsigned long minor = g_AppleWinVersion[1] = pFixedFileInfo->dwFileVersionMS & 0xffff; + unsigned long fix = g_AppleWinVersion[2] = pFixedFileInfo->dwFileVersionLS >> 16; + unsigned long fix_minor = g_AppleWinVersion[3] = pFixedFileInfo->dwFileVersionLS & 0xffff; + sprintf(VERSIONSTRING, "%d.%d.%d.%d", major, minor, fix, fix_minor); // potential buffer overflow } } diff --git a/source/Applewin.h b/source/Applewin.h index 933a1752..a8313335 100644 --- a/source/Applewin.h +++ b/source/Applewin.h @@ -6,7 +6,7 @@ void SetCurrentCLK6502(); void SetCurrentImageDir(const char* pszImageDir); - +extern const UINT16* GetAppleWinVersion(void); extern char VERSIONSTRING[]; // Constructed in WinMain() extern TCHAR *g_pAppTitle; diff --git a/source/Configuration/PageInput.cpp b/source/Configuration/PageInput.cpp index 940b9978..7bd0a20b 100644 --- a/source/Configuration/PageInput.cpp +++ b/source/Configuration/PageInput.cpp @@ -214,12 +214,12 @@ void CPageInput::DlgOK(HWND hWnd) if (JoySetEmulationType(hWnd, m_nJoy0ChoiceTranlationTbl[uNewJoyType0], JN_JOYSTICK0, bIsSlot4Mouse)) { - REGSAVE(TEXT(REGVALUE_JOYSTICK0_EMU_TYPE), joytype[0]); + REGSAVE(TEXT(REGVALUE_JOYSTICK0_EMU_TYPE), JoyGetJoyType(0)); } if (JoySetEmulationType(hWnd, m_nJoy1ChoiceTranlationTbl[uNewJoyType1], JN_JOYSTICK1, bIsSlot4Mouse)) { - REGSAVE(TEXT(REGVALUE_JOYSTICK1_EMU_TYPE), joytype[1]); + REGSAVE(TEXT(REGVALUE_JOYSTICK1_EMU_TYPE), JoyGetJoyType(1)); } JoySetTrim((short)SendDlgItemMessage(hWnd, IDC_SPIN_XTRIM, UDM_GETPOS, 0, 0), true); @@ -305,7 +305,7 @@ void CPageInput::InitJoystickChoices(HWND hWnd, int nJoyNum, int nIdcValue) for(UINT i=nJC_KEYBD_CURSORS; i JN_JOYSTICK1) + return; + + joytype[num] = type; + + // Refresh centre positions whenever 'joytype' changes + JoySetTrim(JoyGetTrim(true) , true); + JoySetTrim(JoyGetTrim(false), false); +} + +DWORD JoyGetJoyType(UINT num) +{ + _ASSERT(num <= JN_JOYSTICK1); + if (num > JN_JOYSTICK1) + return J0C_DISABLED; + + return joytype[num]; +} + +//=========================================================================== + void JoySetTrim(short nValue, bool bAxisX) { if(bAxisX) @@ -831,12 +855,18 @@ void JoySetSnapshot_v1(const unsigned __int64 JoyCntrResetCycle) // -void JoyGetSnapshot(unsigned __int64& rJoyCntrResetCycle) +void JoyGetSnapshot(unsigned __int64& rJoyCntrResetCycle, short* pJoystick0Trim, short* pJoystick1Trim) { rJoyCntrResetCycle = g_nJoyCntrResetCycle; + pJoystick0Trim[0] = JoyGetTrim(true); + pJoystick0Trim[1] = JoyGetTrim(false); + pJoystick1Trim[0] = 0; // TBD: not implemented yet + pJoystick1Trim[1] = 0; // TBD: not implemented yet } -void JoySetSnapshot(const unsigned __int64 JoyCntrResetCycle) +void JoySetSnapshot(const unsigned __int64 JoyCntrResetCycle, const short* pJoystick0Trim, const short* pJoystick1Trim) { g_nJoyCntrResetCycle = JoyCntrResetCycle; + JoySetTrim(pJoystick0Trim[0], true); + JoySetTrim(pJoystick0Trim[1], false); } diff --git a/source/Joystick.h b/source/Joystick.h index f4dfba56..6c718088 100644 --- a/source/Joystick.h +++ b/source/Joystick.h @@ -5,8 +5,6 @@ enum JOYNUM {JN_JOYSTICK0=0, JN_JOYSTICK1}; enum JOY0CHOICE {J0C_DISABLED=0, J0C_JOYSTICK1, J0C_KEYBD_CURSORS, J0C_KEYBD_NUMPAD, J0C_MOUSE, J0C_MAX}; enum JOY1CHOICE {J1C_DISABLED=0, J1C_JOYSTICK2, J1C_KEYBD_CURSORS, J1C_KEYBD_NUMPAD, J1C_MOUSE, J1C_MAX}; -extern DWORD joytype[2]; - enum {JOYSTICK_MODE_FLOATING=0, JOYSTICK_MODE_CENTERING}; // Joystick centering control void JoyInitialize(); @@ -21,12 +19,14 @@ BOOL JoyUsingKeyboard(); BOOL JoyUsingKeyboardCursors(); BOOL JoyUsingKeyboardNumpad(); void JoyDisableUsingMouse(); +void JoySetJoyType(UINT num, DWORD type); +DWORD JoyGetJoyType(UINT num); void JoySetTrim(short nValue, bool bAxisX); short JoyGetTrim(bool bAxisX); void JoyportControl(const UINT uControl); void JoySetSnapshot_v1(const unsigned __int64 JoyCntrResetCycle); -void JoyGetSnapshot(unsigned __int64& rJoyCntrResetCycle); -void JoySetSnapshot(const unsigned __int64 JoyCntrResetCycle); +void JoyGetSnapshot(unsigned __int64& rJoyCntrResetCycle, short* pJoystick0Trim, short* pJoystick1Trim); +void JoySetSnapshot(const unsigned __int64 JoyCntrResetCycle, const short* pJoystick0Trim, const short* pJoystick1Trim); BYTE __stdcall JoyReadButton(WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft); BYTE __stdcall JoyReadPosition(WORD pc, WORD addr, BYTE bWrite, BYTE d, ULONG nCyclesLeft); diff --git a/source/SaveState.cpp b/source/SaveState.cpp index fdc0b7c7..e14d0eb3 100644 --- a/source/SaveState.cpp +++ b/source/SaveState.cpp @@ -291,7 +291,7 @@ static void LoadUnitApple2(DWORD Length, DWORD Version) m_ConfigNew.m_Apple2Type = g_Apple2Type; CpuSetSnapshot(Apple2Unit.CPU6502); - JoySetSnapshot(Apple2Unit.Joystick.JoyCntrResetCycle); + JoySetSnapshot(Apple2Unit.Joystick.JoyCntrResetCycle, &Apple2Unit.Joystick.Joystick0Trim[0], &Apple2Unit.Joystick.Joystick1Trim[0]); KeybSetSnapshot(Apple2Unit.Keyboard.LastKey); SpkrSetSnapshot(Apple2Unit.Speaker.SpkrLastCycle); VideoSetSnapshot(Apple2Unit.Video); @@ -428,23 +428,22 @@ static void LoadUnitCard(DWORD Length, DWORD Version) } } -#if 0 static void LoadUnitConfig(DWORD Length, DWORD Version) { - SS_APPLEWIN_CONFIG Cfg; + SS_APPLEWIN_CONFIG Config; if (Version != UNIT_CONFIG_VER) throw std::string("Config: Version mismatch"); - if (Length != sizeof(Cfg)) + if (Length != sizeof(Config)) throw std::string("Config: Length mismatch"); - if (SetFilePointer(m_hFile, -(LONG)sizeof(Cfg.UnitHdr), NULL, FILE_CURRENT) == INVALID_SET_FILE_POINTER) + if (SetFilePointer(m_hFile, -(LONG)sizeof(Config.UnitHdr), NULL, FILE_CURRENT) == INVALID_SET_FILE_POINTER) throw std::string("Config: file corrupt"); DWORD dwBytesRead; BOOL bRes = ReadFile( m_hFile, - &Cfg, + &Config, Length, &dwBytesRead, NULL); @@ -452,10 +451,38 @@ static void LoadUnitConfig(DWORD Length, DWORD Version) if (dwBytesRead != Length) throw std::string("Config: file corrupt"); - // todo: - //m_ConfigNew.m_bEnhanceDisk; + // Restore all config state + + //Config.Cfg.AppleWinVersion // Nothing to do + g_eVideoType = Config.Cfg.VideoMode; + g_uHalfScanLines = Config.Cfg.IsHalfScanLines; + g_bConfirmReboot = Config.Cfg.IsConfirmReboot; + monochrome = Config.Cfg.MonochromeColor; + SetViewportScale(Config.Cfg.WindowScale); + + g_dwSpeed = Config.Cfg.CpuSpeed; + SetCurrentCLK6502(); + + JoySetJoyType(JN_JOYSTICK0, Config.Cfg.JoystickType[0]); + JoySetJoyType(JN_JOYSTICK1, Config.Cfg.JoystickType[1]); + sg_PropertySheet.SetJoystickCursorControl(Config.Cfg.IsAllowCursorsToBeRead); + sg_PropertySheet.SetAutofire(Config.Cfg.IsAutofire); + sg_PropertySheet.SetJoystickCenteringControl(Config.Cfg.IsKeyboardAutocentering); + //Config.Cfg.IsSwapButton0and1; // TBD: not implemented yet + sg_PropertySheet.SetScrollLockToggle(Config.Cfg.IsScrollLockToggle); + sg_PropertySheet.SetMouseShowCrosshair(Config.Cfg.IsMouseShowCrosshair); + sg_PropertySheet.SetMouseRestrictToWindow(Config.Cfg.IsMouseRestrictToWindow); + + soundtype = Config.Cfg.SoundType; + SpkrSetVolume(Config.Cfg.SpeakerVolume, sg_PropertySheet.GetVolumeMax()); + MB_SetVolume(Config.Cfg.MockingboardVolume, sg_PropertySheet.GetVolumeMax()); + + enhancedisk = Config.Cfg.IsEnhancedDiskSpeed; + g_bSaveStateOnExit = Config.Cfg.IsSaveStateOnExit ? true : false; + + g_bPrinterAppend = Config.Cfg.IsAppendToFile ? true : false; + sg_PropertySheet.SetTheFreezesF8Rom(Config.Cfg.IsUsingFreezesF8Rom); } -#endif static void Snapshot_LoadState_v2(DWORD dwVersion) { @@ -467,6 +494,7 @@ static void Snapshot_LoadState_v2(DWORD dwVersion) CConfigNeedingRestart ConfigOld; ConfigOld.m_Slot[1] = CT_GenericPrinter; // fixme ConfigOld.m_Slot[2] = CT_SSC; // fixme + //ConfigOld.m_Slot[3] = CT_Uthernet; // todo ConfigOld.m_Slot[6] = CT_Disk2; // fixme ConfigOld.m_Slot[7] = ConfigOld.m_bEnableHDD ? CT_GenericHDD : CT_Empty; // fixme //ConfigOld.m_SlotAux = ?; // fixme @@ -515,11 +543,9 @@ static void Snapshot_LoadState_v2(DWORD dwVersion) case UT_Card: LoadUnitCard(UnitHdr.hdr.v2.Length, UnitHdr.hdr.v2.Version); break; -#if 0 case UT_Config: LoadUnitConfig(UnitHdr.hdr.v2.Length, UnitHdr.hdr.v2.Version); break; -#endif default: // Log then skip unsupported unit type break; @@ -577,22 +603,84 @@ void Snapshot_LoadState() //----------------------------------------------------------------------------- +// todo: +// . "Uthernet Active" + +static void SaveUnitConfig() +{ + SS_APPLEWIN_CONFIG Config; + memset(&Config, 0, sizeof(Config)); + + Config.UnitHdr.hdr.v2.Length = sizeof(Config); + Config.UnitHdr.hdr.v2.Type = UT_Config; + Config.UnitHdr.hdr.v2.Version = UNIT_CONFIG_VER; + + // + + memcpy(Config.Cfg.AppleWinVersion, GetAppleWinVersion(), sizeof(Config.Cfg.AppleWinVersion)); + Config.Cfg.VideoMode = g_eVideoType; + Config.Cfg.IsHalfScanLines = g_uHalfScanLines; + Config.Cfg.IsConfirmReboot = g_bConfirmReboot; + Config.Cfg.MonochromeColor = monochrome; + Config.Cfg.WindowScale = GetViewportScale(); + Config.Cfg.CpuSpeed = g_dwSpeed; + + Config.Cfg.JoystickType[0] = JoyGetJoyType(JN_JOYSTICK0); + Config.Cfg.JoystickType[1] = JoyGetJoyType(JN_JOYSTICK1); + Config.Cfg.IsAllowCursorsToBeRead = sg_PropertySheet.GetJoystickCursorControl(); + Config.Cfg.IsAutofire = (sg_PropertySheet.GetAutofire(1)<<1) | sg_PropertySheet.GetAutofire(0); + Config.Cfg.IsKeyboardAutocentering = sg_PropertySheet.GetJoystickCenteringControl(); + Config.Cfg.IsSwapButton0and1 = 0; // TBD: not implemented yet + Config.Cfg.IsScrollLockToggle = sg_PropertySheet.GetScrollLockToggle(); + Config.Cfg.IsMouseShowCrosshair = sg_PropertySheet.GetMouseShowCrosshair(); + Config.Cfg.IsMouseRestrictToWindow = sg_PropertySheet.GetMouseRestrictToWindow(); + + Config.Cfg.SoundType = soundtype; + Config.Cfg.SpeakerVolume = SpkrGetVolume(); + Config.Cfg.MockingboardVolume = MB_GetVolume(); + + Config.Cfg.IsEnhancedDiskSpeed = enhancedisk; + Config.Cfg.IsSaveStateOnExit = g_bSaveStateOnExit; + + Config.Cfg.IsAppendToFile = g_bPrinterAppend; + Config.Cfg.IsUsingFreezesF8Rom = sg_PropertySheet.GetTheFreezesF8Rom(); + + // + + DWORD dwBytesWritten; + BOOL bRes = WriteFile( m_hFile, + &Config, + Config.UnitHdr.hdr.v2.Length, + &dwBytesWritten, + NULL); + + if(!bRes || (dwBytesWritten != Config.UnitHdr.hdr.v2.Length)) + { + //dwError = GetLastError(); + throw std::string("Save error: Config"); + } +} + +// todo: +// . Uthernet card + void Snapshot_SaveState() { try { m_hFile = CreateFile( g_strSaveStatePathname.c_str(), - GENERIC_WRITE, - 0, - NULL, - CREATE_ALWAYS, - FILE_ATTRIBUTE_NORMAL, - NULL); + GENERIC_WRITE, + 0, + NULL, + CREATE_ALWAYS, + FILE_ATTRIBUTE_NORMAL, + NULL); DWORD dwError = GetLastError(); _ASSERT((dwError == 0) || (dwError == ERROR_ALREADY_EXISTS)); // todo: handle ERROR_ALREADY_EXISTS - ask if user wants to replace existing file + // - at this point any old file will have been truncated to zero if(m_hFile == INVALID_HANDLE_VALUE) { @@ -621,7 +709,7 @@ void Snapshot_SaveState() Apple2Unit.Apple2Type = g_Apple2Type; CpuGetSnapshot(Apple2Unit.CPU6502); - JoyGetSnapshot(Apple2Unit.Joystick.JoyCntrResetCycle); + JoyGetSnapshot(Apple2Unit.Joystick.JoyCntrResetCycle, &Apple2Unit.Joystick.Joystick0Trim[0], &Apple2Unit.Joystick.Joystick1Trim[0]); KeybGetSnapshot(Apple2Unit.Keyboard.LastKey); SpkrGetSnapshot(Apple2Unit.Speaker.SpkrLastCycle); VideoGetSnapshot(Apple2Unit.Video); @@ -668,6 +756,10 @@ void Snapshot_SaveState() DiskGetSnapshot(m_hFile); HD_GetSnapshot(m_hFile); + + // + + SaveUnitConfig(); } catch(std::string szMessage) { diff --git a/source/SaveState_Structs_common.h b/source/SaveState_Structs_common.h index 61922d98..93ba181a 100644 --- a/source/SaveState_Structs_common.h +++ b/source/SaveState_Structs_common.h @@ -73,6 +73,7 @@ enum SS_CARDTYPE CT_80Col, // 80 column card (no memory) CT_Extended80Col, // Extended 80-col card (64K) CT_RamWorksIII, // RamWorksIII (up to 8MB) + CT_Uthernet, }; ///////////////////////////////////////////////////////////////////////////////// diff --git a/source/SaveState_Structs_v2.h b/source/SaveState_Structs_v2.h index 22a0eb2c..ed14b1b8 100644 --- a/source/SaveState_Structs_v2.h +++ b/source/SaveState_Structs_v2.h @@ -27,6 +27,8 @@ struct SS_CPU6502_v2 struct SS_IO_Joystick_v2 { unsigned __int64 JoyCntrResetCycle; + short Joystick0Trim[2]; // [x,y] + short Joystick1Trim[2]; // [x,y] }; struct SS_IO_Keyboard_v2 @@ -90,27 +92,31 @@ struct APPLEWIN_SNAPSHOT_v2 struct SS_AW_CFG { - UINT32 AppleWinVersion; + UINT16 AppleWinVersion[4]; // major,minor,fix,fix_minor UINT32 VideoMode; + UINT32 IsHalfScanLines; + UINT32 IsConfirmReboot; UINT32 MonochromeColor; - float ClockFreqMHz; + UINT32 WindowScale; + UINT32 CpuSpeed; // UINT32 JoystickType[2]; - UINT32 JoystickTrim[2]; UINT32 IsAllowCursorsToBeRead; UINT32 IsAutofire; UINT32 IsKeyboardAutocentering; UINT32 IsSwapButton0and1; + UINT32 IsScrollLockToggle; + UINT32 IsMouseShowCrosshair; + UINT32 IsMouseRestrictToWindow; // + UINT32 SoundType; UINT32 SpeakerVolume; UINT32 MockingboardVolume; // UINT32 IsEnhancedDiskSpeed; + UINT32 IsSaveStateOnExit; // - UINT32 IsEncodingConversionForClones; - UINT32 IsFilterUnprintableChars; UINT32 IsAppendToFile; - UINT32 TerminatePrintingAfterIdleSecs; UINT32 IsUsingFreezesF8Rom; }; diff --git a/source/SerialComms.cpp b/source/SerialComms.cpp index 041a9fca..167c37d4 100644 --- a/source/SerialComms.cpp +++ b/source/SerialComms.cpp @@ -1340,6 +1340,8 @@ struct SSC_Unit bool vbRxIrqPending; bool bWrittenTx; + + char SerialPortName[8]; }; struct SS_CARD_SSC @@ -1376,6 +1378,8 @@ void CSuperSerialCard::GetSnapshot(const HANDLE hFile) Unit.vbRxIrqPending = m_vbRxIrqPending; Unit.bWrittenTx = m_bWrittenTx; + strncpy_s(Unit.SerialPortName, sizeof(Unit.SerialPortName), GetSerialPortName(), _TRUNCATE); + // DWORD dwBytesWritten; @@ -1428,4 +1432,6 @@ void CSuperSerialCard::SetSnapshot(const HANDLE hFile) m_vbTxIrqPending = Unit.vbTxIrqPending; m_vbRxIrqPending = Unit.vbRxIrqPending; m_bWrittenTx = Unit.bWrittenTx; + + SetSerialPortName(Unit.SerialPortName); } From 431dcde0590638f3713152cfc954c15725ae0769 Mon Sep 17 00:00:00 2001 From: tomcw Date: Fri, 21 Aug 2015 22:09:44 +0100 Subject: [PATCH 08/20] Save-state: Add comments for load/save config state --- source/SaveState.cpp | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/source/SaveState.cpp b/source/SaveState.cpp index e14d0eb3..2f06026e 100644 --- a/source/SaveState.cpp +++ b/source/SaveState.cpp @@ -428,6 +428,12 @@ static void LoadUnitCard(DWORD Length, DWORD Version) } } +// Todo: +// . Should this newly loaded config state be persisted to the Registry? +// - NB. it will get saved if the user opens the Config dialog + makes a change. Is this confusing to the user? +// Notes: +// . WindowScale - don't think this needs restoring (eg. like FullScreen) + static void LoadUnitConfig(DWORD Length, DWORD Version) { SS_APPLEWIN_CONFIG Config; @@ -458,7 +464,7 @@ static void LoadUnitConfig(DWORD Length, DWORD Version) g_uHalfScanLines = Config.Cfg.IsHalfScanLines; g_bConfirmReboot = Config.Cfg.IsConfirmReboot; monochrome = Config.Cfg.MonochromeColor; - SetViewportScale(Config.Cfg.WindowScale); + //Config.Cfg.WindowScale // NB. Just calling SetViewportScale() is no good. Use PostMessage() instead. g_dwSpeed = Config.Cfg.CpuSpeed; SetCurrentCLK6502(); @@ -603,8 +609,10 @@ void Snapshot_LoadState() //----------------------------------------------------------------------------- -// todo: -// . "Uthernet Active" +// Todo: +// . "Uthernet Active" - save this in slot3 card's state? +// Notes: +// . Full Screen - don't think this needs save/restoring static void SaveUnitConfig() { From 2f6e86c0faecd00d1066ce0ca9d5a982df1fce57 Mon Sep 17 00:00:00 2001 From: tomcw Date: Sat, 5 Dec 2015 16:50:27 +0000 Subject: [PATCH 09/20] Added libyaml 0.1.5 Added yaml save-state support for: . Main AppleII unit . Aux memory & RawWorksIII . Printer . SSC . Z80 . Mouse . Mockingboard . Phasor . Disk][ . HDD --- ApplewinExpress9.00.sln | 7 + ApplewinExpress9.00.vcproj | 16 +- libyaml/LICENSE | 19 + libyaml/README | 27 + libyaml/doc/doxygen.cfg | 222 + libyaml/doc/html/annotated.html | 83 + libyaml/doc/html/bc_s.png | Bin 0 -> 677 bytes libyaml/doc/html/classes.html | 78 + libyaml/doc/html/closed.png | Bin 0 -> 126 bytes libyaml/doc/html/doxygen.css | 949 +++++ libyaml/doc/html/doxygen.png | Bin 0 -> 3942 bytes libyaml/doc/html/files.html | 72 + libyaml/doc/html/functions.html | 123 + libyaml/doc/html/functions_0x62.html | 116 + libyaml/doc/html/functions_0x63.html | 119 + libyaml/doc/html/functions_0x64.html | 115 + libyaml/doc/html/functions_0x65.html | 142 + libyaml/doc/html/functions_0x66.html | 111 + libyaml/doc/html/functions_0x68.html | 112 + libyaml/doc/html/functions_0x69.html | 124 + libyaml/doc/html/functions_0x6b.html | 103 + libyaml/doc/html/functions_0x6c.html | 120 + libyaml/doc/html/functions_0x6d.html | 128 + libyaml/doc/html/functions_0x6e.html | 103 + libyaml/doc/html/functions_0x6f.html | 112 + libyaml/doc/html/functions_0x70.html | 132 + libyaml/doc/html/functions_0x71.html | 103 + libyaml/doc/html/functions_0x72.html | 119 + libyaml/doc/html/functions_0x73.html | 195 + libyaml/doc/html/functions_0x74.html | 147 + libyaml/doc/html/functions_0x75.html | 103 + libyaml/doc/html/functions_0x76.html | 112 + libyaml/doc/html/functions_0x77.html | 109 + libyaml/doc/html/functions_vars.html | 123 + libyaml/doc/html/functions_vars_0x62.html | 116 + libyaml/doc/html/functions_vars_0x63.html | 119 + libyaml/doc/html/functions_vars_0x64.html | 115 + libyaml/doc/html/functions_vars_0x65.html | 142 + libyaml/doc/html/functions_vars_0x66.html | 111 + libyaml/doc/html/functions_vars_0x68.html | 112 + libyaml/doc/html/functions_vars_0x69.html | 124 + libyaml/doc/html/functions_vars_0x6b.html | 103 + libyaml/doc/html/functions_vars_0x6c.html | 120 + libyaml/doc/html/functions_vars_0x6d.html | 128 + libyaml/doc/html/functions_vars_0x6e.html | 103 + libyaml/doc/html/functions_vars_0x6f.html | 112 + libyaml/doc/html/functions_vars_0x70.html | 132 + libyaml/doc/html/functions_vars_0x71.html | 103 + libyaml/doc/html/functions_vars_0x72.html | 119 + libyaml/doc/html/functions_vars_0x73.html | 195 + libyaml/doc/html/functions_vars_0x74.html | 147 + libyaml/doc/html/functions_vars_0x75.html | 103 + libyaml/doc/html/functions_vars_0x76.html | 112 + libyaml/doc/html/functions_vars_0x77.html | 109 + libyaml/doc/html/globals.html | 699 ++++ libyaml/doc/html/globals_defs.html | 113 + libyaml/doc/html/globals_enum.html | 110 + libyaml/doc/html/globals_eval.html | 405 ++ libyaml/doc/html/globals_func.html | 228 ++ libyaml/doc/html/globals_type.html | 158 + libyaml/doc/html/group__basic.html | 349 ++ libyaml/doc/html/group__emitter.html | 845 ++++ libyaml/doc/html/group__events.html | 691 ++++ libyaml/doc/html/group__export.html | 91 + libyaml/doc/html/group__nodes.html | 824 ++++ libyaml/doc/html/group__parser.html | 635 +++ libyaml/doc/html/group__styles.html | 251 ++ libyaml/doc/html/group__tokens.html | 276 ++ libyaml/doc/html/group__version.html | 137 + libyaml/doc/html/index.html | 63 + libyaml/doc/html/modules.html | 74 + libyaml/doc/html/nav_f.png | Bin 0 -> 159 bytes libyaml/doc/html/nav_h.png | Bin 0 -> 97 bytes libyaml/doc/html/open.png | Bin 0 -> 118 bytes .../doc/html/structyaml__alias__data__s.html | 137 + libyaml/doc/html/structyaml__document__s.html | 264 ++ libyaml/doc/html/structyaml__emitter__s.html | 1321 ++++++ libyaml/doc/html/structyaml__event__s.html | 525 +++ libyaml/doc/html/structyaml__mark__s.html | 137 + .../doc/html/structyaml__node__pair__s.html | 120 + libyaml/doc/html/structyaml__node__s.html | 449 +++ libyaml/doc/html/structyaml__parser__s.html | 1248 ++++++ .../doc/html/structyaml__simple__key__s.html | 126 + .../html/structyaml__tag__directive__s.html | 120 + libyaml/doc/html/structyaml__token__s.html | 442 ++ .../structyaml__version__directive__s.html | 120 + libyaml/doc/html/tab_a.png | Bin 0 -> 140 bytes libyaml/doc/html/tab_b.png | Bin 0 -> 178 bytes libyaml/doc/html/tab_h.png | Bin 0 -> 192 bytes libyaml/doc/html/tab_s.png | Bin 0 -> 189 bytes libyaml/doc/html/tabs.css | 59 + libyaml/doc/html/yaml_8h.html | 546 +++ libyaml/include/yaml.h | 1971 +++++++++ libyaml/src/api.c | 1392 +++++++ libyaml/src/dumper.c | 394 ++ libyaml/src/emitter.c | 2329 +++++++++++ libyaml/src/loader.c | 444 ++ libyaml/src/parser.c | 1374 +++++++ libyaml/src/reader.c | 469 +++ libyaml/src/scanner.c | 3580 +++++++++++++++++ libyaml/src/writer.c | 141 + libyaml/src/yaml_private.h | 657 +++ libyaml/win32/config.h | 4 + libyaml/win32/yaml2008.vcproj | 215 + source/AY8910.cpp | 206 + source/AY8910.h | 4 + source/CPU.cpp | 67 +- source/CPU.h | 2 + source/Configuration/PropertySheetHelper.cpp | 29 +- source/Configuration/PropertySheetHelper.h | 2 +- source/Disk.cpp | 183 +- source/Disk.h | 3 + source/Harddisk.cpp | 147 +- source/Harddisk.h | 3 + source/Joystick.cpp | 39 + source/Joystick.h | 2 + source/Keyboard.cpp | 27 + source/Keyboard.h | 2 + source/Memory.cpp | 201 + source/Memory.h | 5 + source/Mockingboard.cpp | 336 +- source/Mockingboard.h | 6 + source/MouseInterface.cpp | 162 + source/MouseInterface.h | 5 + source/ParallelPrinter.cpp | 70 + source/ParallelPrinter.h | 3 + source/SaveState.cpp | 386 +- source/SaveState_Structs_common.h | 2 +- source/SaveState_Structs_v2.h | 4 +- source/SerialComms.cpp | 111 + source/SerialComms.h | 5 + source/Speaker.cpp | 27 + source/Speaker.h | 2 + source/StdAfx.h | 1 + source/Video.cpp | 33 + source/Video.h | 2 + source/YamlHelper.cpp | 421 ++ source/YamlHelper.h | 300 ++ source/Z80VICE/z80.cpp | 137 + source/z80emu.h | 3 + test/TestCPU6502/stdafx.h | 2 + 141 files changed, 34010 insertions(+), 32 deletions(-) create mode 100644 libyaml/LICENSE create mode 100644 libyaml/README create mode 100644 libyaml/doc/doxygen.cfg create mode 100644 libyaml/doc/html/annotated.html create mode 100644 libyaml/doc/html/bc_s.png create mode 100644 libyaml/doc/html/classes.html create mode 100644 libyaml/doc/html/closed.png create mode 100644 libyaml/doc/html/doxygen.css create mode 100644 libyaml/doc/html/doxygen.png create mode 100644 libyaml/doc/html/files.html create mode 100644 libyaml/doc/html/functions.html create mode 100644 libyaml/doc/html/functions_0x62.html create mode 100644 libyaml/doc/html/functions_0x63.html create mode 100644 libyaml/doc/html/functions_0x64.html create mode 100644 libyaml/doc/html/functions_0x65.html create mode 100644 libyaml/doc/html/functions_0x66.html create mode 100644 libyaml/doc/html/functions_0x68.html create mode 100644 libyaml/doc/html/functions_0x69.html create mode 100644 libyaml/doc/html/functions_0x6b.html create mode 100644 libyaml/doc/html/functions_0x6c.html create mode 100644 libyaml/doc/html/functions_0x6d.html create mode 100644 libyaml/doc/html/functions_0x6e.html create mode 100644 libyaml/doc/html/functions_0x6f.html create mode 100644 libyaml/doc/html/functions_0x70.html create mode 100644 libyaml/doc/html/functions_0x71.html create mode 100644 libyaml/doc/html/functions_0x72.html create mode 100644 libyaml/doc/html/functions_0x73.html create mode 100644 libyaml/doc/html/functions_0x74.html create mode 100644 libyaml/doc/html/functions_0x75.html create mode 100644 libyaml/doc/html/functions_0x76.html create mode 100644 libyaml/doc/html/functions_0x77.html create mode 100644 libyaml/doc/html/functions_vars.html create mode 100644 libyaml/doc/html/functions_vars_0x62.html create mode 100644 libyaml/doc/html/functions_vars_0x63.html create mode 100644 libyaml/doc/html/functions_vars_0x64.html create mode 100644 libyaml/doc/html/functions_vars_0x65.html create mode 100644 libyaml/doc/html/functions_vars_0x66.html create mode 100644 libyaml/doc/html/functions_vars_0x68.html create mode 100644 libyaml/doc/html/functions_vars_0x69.html create mode 100644 libyaml/doc/html/functions_vars_0x6b.html create mode 100644 libyaml/doc/html/functions_vars_0x6c.html create mode 100644 libyaml/doc/html/functions_vars_0x6d.html create mode 100644 libyaml/doc/html/functions_vars_0x6e.html create mode 100644 libyaml/doc/html/functions_vars_0x6f.html create mode 100644 libyaml/doc/html/functions_vars_0x70.html create mode 100644 libyaml/doc/html/functions_vars_0x71.html create mode 100644 libyaml/doc/html/functions_vars_0x72.html create mode 100644 libyaml/doc/html/functions_vars_0x73.html create mode 100644 libyaml/doc/html/functions_vars_0x74.html create mode 100644 libyaml/doc/html/functions_vars_0x75.html create mode 100644 libyaml/doc/html/functions_vars_0x76.html create mode 100644 libyaml/doc/html/functions_vars_0x77.html create mode 100644 libyaml/doc/html/globals.html create mode 100644 libyaml/doc/html/globals_defs.html create mode 100644 libyaml/doc/html/globals_enum.html create mode 100644 libyaml/doc/html/globals_eval.html create mode 100644 libyaml/doc/html/globals_func.html create mode 100644 libyaml/doc/html/globals_type.html create mode 100644 libyaml/doc/html/group__basic.html create mode 100644 libyaml/doc/html/group__emitter.html create mode 100644 libyaml/doc/html/group__events.html create mode 100644 libyaml/doc/html/group__export.html create mode 100644 libyaml/doc/html/group__nodes.html create mode 100644 libyaml/doc/html/group__parser.html create mode 100644 libyaml/doc/html/group__styles.html create mode 100644 libyaml/doc/html/group__tokens.html create mode 100644 libyaml/doc/html/group__version.html create mode 100644 libyaml/doc/html/index.html create mode 100644 libyaml/doc/html/modules.html create mode 100644 libyaml/doc/html/nav_f.png create mode 100644 libyaml/doc/html/nav_h.png create mode 100644 libyaml/doc/html/open.png create mode 100644 libyaml/doc/html/structyaml__alias__data__s.html create mode 100644 libyaml/doc/html/structyaml__document__s.html create mode 100644 libyaml/doc/html/structyaml__emitter__s.html create mode 100644 libyaml/doc/html/structyaml__event__s.html create mode 100644 libyaml/doc/html/structyaml__mark__s.html create mode 100644 libyaml/doc/html/structyaml__node__pair__s.html create mode 100644 libyaml/doc/html/structyaml__node__s.html create mode 100644 libyaml/doc/html/structyaml__parser__s.html create mode 100644 libyaml/doc/html/structyaml__simple__key__s.html create mode 100644 libyaml/doc/html/structyaml__tag__directive__s.html create mode 100644 libyaml/doc/html/structyaml__token__s.html create mode 100644 libyaml/doc/html/structyaml__version__directive__s.html create mode 100644 libyaml/doc/html/tab_a.png create mode 100644 libyaml/doc/html/tab_b.png create mode 100644 libyaml/doc/html/tab_h.png create mode 100644 libyaml/doc/html/tab_s.png create mode 100644 libyaml/doc/html/tabs.css create mode 100644 libyaml/doc/html/yaml_8h.html create mode 100644 libyaml/include/yaml.h create mode 100644 libyaml/src/api.c create mode 100644 libyaml/src/dumper.c create mode 100644 libyaml/src/emitter.c create mode 100644 libyaml/src/loader.c create mode 100644 libyaml/src/parser.c create mode 100644 libyaml/src/reader.c create mode 100644 libyaml/src/scanner.c create mode 100644 libyaml/src/writer.c create mode 100644 libyaml/src/yaml_private.h create mode 100644 libyaml/win32/config.h create mode 100644 libyaml/win32/yaml2008.vcproj create mode 100644 source/YamlHelper.cpp create mode 100644 source/YamlHelper.h diff --git a/ApplewinExpress9.00.sln b/ApplewinExpress9.00.sln index 93c42b2b..475784bc 100644 --- a/ApplewinExpress9.00.sln +++ b/ApplewinExpress9.00.sln @@ -3,6 +3,7 @@ Microsoft Visual Studio Solution File, Format Version 10.00 # Visual Studio 2008 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Applewin", "ApplewinExpress9.00.vcproj", "{1DA0C491-B5F4-4EC8-B1D2-CF6BE635DADC}" ProjectSection(ProjectDependencies) = postProject + {5CE8051A-3F0C-4C39-B1C0-3338E48BA60F} = {5CE8051A-3F0C-4C39-B1C0-3338E48BA60F} {7935B998-C713-42AE-8F6D-9FF9080A1B1B} = {7935B998-C713-42AE-8F6D-9FF9080A1B1B} {2CC8CA9F-E37E-41A4-BFAD-77E54EB783A2} = {2CC8CA9F-E37E-41A4-BFAD-77E54EB783A2} {709278B8-C583-4BD8-90DE-4E4F35A3BD8B} = {709278B8-C583-4BD8-90DE-4E4F35A3BD8B} @@ -14,6 +15,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zip_lib", "zip_lib\zip_lib. EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TestCPU6502", "test\TestCPU6502\TestCPU6502.vcproj", "{2CC8CA9F-E37E-41A4-BFAD-77E54EB783A2}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "yaml", "libyaml\win32\yaml2008.vcproj", "{5CE8051A-3F0C-4C39-B1C0-3338E48BA60F}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 @@ -36,6 +39,10 @@ Global {2CC8CA9F-E37E-41A4-BFAD-77E54EB783A2}.Debug|Win32.Build.0 = Debug|Win32 {2CC8CA9F-E37E-41A4-BFAD-77E54EB783A2}.Release|Win32.ActiveCfg = Release|Win32 {2CC8CA9F-E37E-41A4-BFAD-77E54EB783A2}.Release|Win32.Build.0 = Release|Win32 + {5CE8051A-3F0C-4C39-B1C0-3338E48BA60F}.Debug|Win32.ActiveCfg = Debug|Win32 + {5CE8051A-3F0C-4C39-B1C0-3338E48BA60F}.Debug|Win32.Build.0 = Debug|Win32 + {5CE8051A-3F0C-4C39-B1C0-3338E48BA60F}.Release|Win32.ActiveCfg = Release|Win32 + {5CE8051A-3F0C-4C39-B1C0-3338E48BA60F}.Release|Win32.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/ApplewinExpress9.00.vcproj b/ApplewinExpress9.00.vcproj index 95b6ae55..b710ac63 100644 --- a/ApplewinExpress9.00.vcproj +++ b/ApplewinExpress9.00.vcproj @@ -56,8 +56,8 @@ FavorSizeOrSpeed="1" OmitFramePointers="true" WholeProgramOptimization="true" - AdditionalIncludeDirectories="source\cpu;source\emulator;source\debugger;zlib;zip_lib" - PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_CRT_SECURE_NO_DEPRECATE;NO_DSHOW_STRSAFE" + AdditionalIncludeDirectories="source\cpu;source\emulator;source\debugger;zlib;zip_lib;libyaml\include" + PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_CRT_SECURE_NO_DEPRECATE;NO_DSHOW_STRSAFE;YAML_DECLARE_STATIC" StringPooling="true" RuntimeLibrary="0" EnableFunctionLevelLinking="true" @@ -157,8 +157,8 @@ Name="VCCLCompilerTool" AdditionalOptions="/Zm200 " Optimization="0" - AdditionalIncludeDirectories="source\cpu;source\emulator;source\debugger;zlib;zip_lib" - PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_CRT_SECURE_NO_DEPRECATE;NO_DSHOW_STRSAFE" + AdditionalIncludeDirectories="source\cpu;source\emulator;source\debugger;zlib;zip_lib;libyaml\include" + PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_CRT_SECURE_NO_DEPRECATE;NO_DSHOW_STRSAFE;YAML_DECLARE_STATIC" MinimalRebuild="true" RuntimeLibrary="1" UsePrecompiledHeader="2" @@ -746,6 +746,14 @@ RelativePath=".\source\Tape.h" > + + + + diff --git a/libyaml/LICENSE b/libyaml/LICENSE new file mode 100644 index 00000000..050ced23 --- /dev/null +++ b/libyaml/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2006 Kirill Simonov + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/libyaml/README b/libyaml/README new file mode 100644 index 00000000..d35ebcc9 --- /dev/null +++ b/libyaml/README @@ -0,0 +1,27 @@ +LibYAML - A C library for parsing and emitting YAML. + +To build and install the library, run: +$ ./configure +$ make +# make install + +If you checked the source code from the Subversion repository, run +$ ./bootstrap +$ ./configure +$ make +# make install + +For more information, check the LibYAML homepage: +'http://pyyaml.org/wiki/LibYAML'. + +Post your questions and opinions to the YAML-Core mailing list: +'http://lists.sourceforge.net/lists/listinfo/yaml-core'. + +Submit bug reports and feature requests to the LibYAML bug tracker: +'http://pyyaml.org/newticket?component=libyaml'. + +LibYAML is written by Kirill Simonov . It is released +under the MIT license. See the file LICENSE for more details. + +This project is developed for Python Software Foundation as a part of +Google Summer of Code under the mentorship of Clark Evans. diff --git a/libyaml/doc/doxygen.cfg b/libyaml/doc/doxygen.cfg new file mode 100644 index 00000000..a58bb177 --- /dev/null +++ b/libyaml/doc/doxygen.cfg @@ -0,0 +1,222 @@ +# Doxyfile 1.4.4 + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- +PROJECT_NAME = $(PACKAGE) +PROJECT_NUMBER = $(VERSION) +OUTPUT_DIRECTORY = $(top_builddir)/doc/ +CREATE_SUBDIRS = NO +OUTPUT_LANGUAGE = English +USE_WINDOWS_ENCODING = NO +BRIEF_MEMBER_DESC = YES +REPEAT_BRIEF = YES +ABBREVIATE_BRIEF = +ALWAYS_DETAILED_SEC = NO +INLINE_INHERITED_MEMB = NO +FULL_PATH_NAMES = YES +STRIP_FROM_PATH = +STRIP_FROM_INC_PATH = +SHORT_NAMES = NO +JAVADOC_AUTOBRIEF = YES +MULTILINE_CPP_IS_BRIEF = NO +DETAILS_AT_TOP = NO +INHERIT_DOCS = YES +DISTRIBUTE_GROUP_DOC = NO +SEPARATE_MEMBER_PAGES = NO +TAB_SIZE = 8 +ALIASES = +OPTIMIZE_OUTPUT_FOR_C = YES +OPTIMIZE_OUTPUT_JAVA = NO +SUBGROUPING = YES +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- +EXTRACT_ALL = NO +EXTRACT_PRIVATE = NO +EXTRACT_STATIC = NO +EXTRACT_LOCAL_CLASSES = NO +EXTRACT_LOCAL_METHODS = NO +HIDE_UNDOC_MEMBERS = NO +HIDE_UNDOC_CLASSES = NO +HIDE_FRIEND_COMPOUNDS = NO +HIDE_IN_BODY_DOCS = NO +INTERNAL_DOCS = NO +CASE_SENSE_NAMES = YES +HIDE_SCOPE_NAMES = NO +SHOW_INCLUDE_FILES = YES +INLINE_INFO = YES +SORT_MEMBER_DOCS = NO +SORT_BRIEF_DOCS = NO +SORT_BY_SCOPE_NAME = NO +GENERATE_TODOLIST = YES +GENERATE_TESTLIST = YES +GENERATE_BUGLIST = YES +GENERATE_DEPRECATEDLIST= YES +ENABLED_SECTIONS = +MAX_INITIALIZER_LINES = 30 +SHOW_USED_FILES = YES +SHOW_DIRECTORIES = YES +FILE_VERSION_FILTER = +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- +QUIET = NO +WARNINGS = YES +WARN_IF_UNDOCUMENTED = YES +WARN_IF_DOC_ERROR = YES +WARN_NO_PARAMDOC = NO +WARN_FORMAT = "$file:$line: $text" +WARN_LOGFILE = +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- +INPUT = $(top_srcdir)/include/ +FILE_PATTERNS = *.h +RECURSIVE = YES +EXCLUDE = +EXCLUDE_SYMLINKS = NO +EXCLUDE_PATTERNS = +EXAMPLE_PATH = +EXAMPLE_PATTERNS = +EXAMPLE_RECURSIVE = NO +IMAGE_PATH = +INPUT_FILTER = +FILTER_PATTERNS = +FILTER_SOURCE_FILES = NO +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- +SOURCE_BROWSER = NO +INLINE_SOURCES = NO +STRIP_CODE_COMMENTS = YES +REFERENCED_BY_RELATION = NO +REFERENCES_RELATION = NO +USE_HTAGS = NO +VERBATIM_HEADERS = NO +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- +ALPHABETICAL_INDEX = NO +COLS_IN_ALPHA_INDEX = 5 +IGNORE_PREFIX = +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- +GENERATE_HTML = YES +HTML_OUTPUT = html +HTML_FILE_EXTENSION = .html +HTML_HEADER = +HTML_FOOTER = +HTML_STYLESHEET = +HTML_ALIGN_MEMBERS = YES +GENERATE_HTMLHELP = NO +CHM_FILE = +HHC_LOCATION = +GENERATE_CHI = NO +BINARY_TOC = NO +TOC_EXPAND = NO +DISABLE_INDEX = NO +ENUM_VALUES_PER_LINE = 1 +GENERATE_TREEVIEW = NO +TREEVIEW_WIDTH = 250 +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- +GENERATE_LATEX = NO +LATEX_OUTPUT = latex +LATEX_CMD_NAME = latex +MAKEINDEX_CMD_NAME = makeindex +COMPACT_LATEX = NO +PAPER_TYPE = a4wide +EXTRA_PACKAGES = +LATEX_HEADER = +PDF_HYPERLINKS = NO +USE_PDFLATEX = NO +LATEX_BATCHMODE = NO +LATEX_HIDE_INDICES = NO +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- +GENERATE_RTF = NO +RTF_OUTPUT = rtf +COMPACT_RTF = NO +RTF_HYPERLINKS = NO +RTF_STYLESHEET_FILE = +RTF_EXTENSIONS_FILE = +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- +GENERATE_MAN = NO +MAN_OUTPUT = man +MAN_EXTENSION = .3 +MAN_LINKS = NO +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- +GENERATE_XML = NO +XML_OUTPUT = xml +XML_SCHEMA = +XML_DTD = +XML_PROGRAMLISTING = YES +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- +GENERATE_AUTOGEN_DEF = NO +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- +GENERATE_PERLMOD = NO +PERLMOD_LATEX = NO +PERLMOD_PRETTY = YES +PERLMOD_MAKEVAR_PREFIX = +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- +ENABLE_PREPROCESSING = YES +MACRO_EXPANSION = YES +EXPAND_ONLY_PREDEF = YES +SEARCH_INCLUDES = YES +INCLUDE_PATH = +INCLUDE_FILE_PATTERNS = +PREDEFINED = "YAML_DECLARE(type)=type" +EXPAND_AS_DEFINED = +SKIP_FUNCTION_MACROS = YES +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- +TAGFILES = +GENERATE_TAGFILE = +ALLEXTERNALS = NO +EXTERNAL_GROUPS = YES +PERL_PATH = /usr/bin/perl +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- +CLASS_DIAGRAMS = NO +HIDE_UNDOC_RELATIONS = YES +HAVE_DOT = NO +CLASS_GRAPH = YES +COLLABORATION_GRAPH = YES +GROUP_GRAPHS = YES +UML_LOOK = NO +TEMPLATE_RELATIONS = NO +INCLUDE_GRAPH = YES +INCLUDED_BY_GRAPH = YES +CALL_GRAPH = NO +GRAPHICAL_HIERARCHY = YES +DIRECTORY_GRAPH = YES +DOT_IMAGE_FORMAT = png +DOT_PATH = +DOTFILE_DIRS = +MAX_DOT_GRAPH_WIDTH = 1024 +MAX_DOT_GRAPH_HEIGHT = 1024 +MAX_DOT_GRAPH_DEPTH = 0 +DOT_TRANSPARENT = NO +DOT_MULTI_TARGETS = NO +GENERATE_LEGEND = YES +DOT_CLEANUP = YES +#--------------------------------------------------------------------------- +# Configuration::additions related to the search engine +#--------------------------------------------------------------------------- +SEARCHENGINE = NO diff --git a/libyaml/doc/html/annotated.html b/libyaml/doc/html/annotated.html new file mode 100644 index 00000000..064df4b9 --- /dev/null +++ b/libyaml/doc/html/annotated.html @@ -0,0 +1,83 @@ + + + + + +yaml: Data Structures + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.5 +
+ +
+
+ + + + +
+
+
+
Data Structures
+
+
+
Here are the data structures with brief descriptions:
+ + + + + + + + + + + + +
yaml_alias_data_sThis structure holds aliases data
yaml_document_sThe document structure
yaml_emitter_sThe emitter structure
yaml_event_sThe event structure
yaml_mark_sThe pointer position
yaml_node_pair_sAn element of a mapping node
yaml_node_sThe node structure
yaml_parser_sThe parser structure
yaml_simple_key_sThis structure holds information about a potential simple key
yaml_tag_directive_sThe tag directive data
yaml_token_sThe token structure
yaml_version_directive_sThe version directive data
+
+ + + + + + diff --git a/libyaml/doc/html/bc_s.png b/libyaml/doc/html/bc_s.png new file mode 100644 index 0000000000000000000000000000000000000000..e4018628b5b45cb4301037485a29d7d74ac22138 GIT binary patch literal 677 zcmV;W0$TlvP)X?0Pv5h+5!wElpi=&YL!gfY!djl#UDdPKy97F|A-deTa@qo3BWh1YQIvzmHR^g zFjV4I6pLB7_*vEZk^%p7c7Bh>0`4r^X#gpJE_Vz9fSHKqclcZaV^k3gX%h+1`u||O zZ+BY?7(R=ayr^kXE=E0Dw=$Ud3VJ?9^Cz@hP?388Cw5>9TloOJ>^KczCgj zns2=|0!a|)Yq3{hjL{xyy7|Tk0N}Pe+g9PUTL!4{#;eUhrNd@!_T<>Vu+35c)h>sq ztgb?(6W3oFLz#%?OMEV@{j#4LuDvjVGZ~6hpQT8li5b0yjvK8c4efl+vSz5)P6 zle78)00_Iv5)&E~hnOdcd}L}i+MU>k+Q8#@KjqJJN`gRj(~)RmNrck9ht@LelPtVO zwp(J;k!T=gC#%o(13-^E+g@aqc()pf{+j|0w)AH*Mq$54UjLv#jV$RYpz3Vjg$$=u z>yjfBQOhL=^@+#4#$l|{~}HZ-?1Yy{lI*$N}*YDC`<{+;>_#gMXZdz4NI00000 LNkvXXu0mjfx86dR literal 0 HcmV?d00001 diff --git a/libyaml/doc/html/classes.html b/libyaml/doc/html/classes.html new file mode 100644 index 00000000..d086d23d --- /dev/null +++ b/libyaml/doc/html/classes.html @@ -0,0 +1,78 @@ + + + + + +yaml: Data Structure Index + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.5 +
+ +
+
+ + + + +
+
+
+
Data Structure Index
+
+ + + + + + + diff --git a/libyaml/doc/html/closed.png b/libyaml/doc/html/closed.png new file mode 100644 index 0000000000000000000000000000000000000000..b7d4bd9fef2272c74b94762c9e2496177017775e GIT binary patch literal 126 zcmeAS@N?(olHy`uVBq!ia0vp^oFL4>1|%O$WD@{VuAVNAAr*{o?>h22DDp4|bgj*t z)u^AqcA-V@guRYpb17F<&b?_~8HV>~XqWvB;^$!VVSTy0!eQcJp_yD7TIQA>7dijs YXf6~H5cs^Q6KEiVr>mdKI;Vst0NsWqGynhq literal 0 HcmV?d00001 diff --git a/libyaml/doc/html/doxygen.css b/libyaml/doc/html/doxygen.css new file mode 100644 index 00000000..cee0d06b --- /dev/null +++ b/libyaml/doc/html/doxygen.css @@ -0,0 +1,949 @@ +/* The standard CSS for doxygen */ + +body, table, div, p, dl { + font-family: Lucida Grande, Verdana, Geneva, Arial, sans-serif; + font-size: 13px; + line-height: 1.3; +} + +/* @group Heading Levels */ + +h1 { + font-size: 150%; +} + +.title { + font-size: 150%; + font-weight: bold; + margin: 10px 2px; +} + +h2 { + font-size: 120%; +} + +h3 { + font-size: 100%; +} + +dt { + font-weight: bold; +} + +div.multicol { + -moz-column-gap: 1em; + -webkit-column-gap: 1em; + -moz-column-count: 3; + -webkit-column-count: 3; +} + +p.startli, p.startdd, p.starttd { + margin-top: 2px; +} + +p.endli { + margin-bottom: 0px; +} + +p.enddd { + margin-bottom: 4px; +} + +p.endtd { + margin-bottom: 2px; +} + +/* @end */ + +caption { + font-weight: bold; +} + +span.legend { + font-size: 70%; + text-align: center; +} + +h3.version { + font-size: 90%; + text-align: center; +} + +div.qindex, div.navtab{ + background-color: #EBEFF6; + border: 1px solid #A3B4D7; + text-align: center; +} + +div.qindex, div.navpath { + width: 100%; + line-height: 140%; +} + +div.navtab { + margin-right: 15px; +} + +/* @group Link Styling */ + +a { + color: #3D578C; + font-weight: normal; + text-decoration: none; +} + +.contents a:visited { + color: #4665A2; +} + +a:hover { + text-decoration: underline; +} + +a.qindex { + font-weight: bold; +} + +a.qindexHL { + font-weight: bold; + background-color: #9CAFD4; + color: #ffffff; + border: 1px double #869DCA; +} + +.contents a.qindexHL:visited { + color: #ffffff; +} + +a.el { + font-weight: bold; +} + +a.elRef { +} + +a.code, a.code:visited { + color: #4665A2; +} + +a.codeRef, a.codeRef:visited { + color: #4665A2; +} + +/* @end */ + +dl.el { + margin-left: -1cm; +} + +.fragment { + font-family: monospace, fixed; + font-size: 105%; +} + +pre.fragment { + border: 1px solid #C4CFE5; + background-color: #FBFCFD; + padding: 4px 6px; + margin: 4px 8px 4px 2px; + overflow: auto; + word-wrap: break-word; + font-size: 9pt; + line-height: 125%; +} + +div.ah { + background-color: black; + font-weight: bold; + color: #ffffff; + margin-bottom: 3px; + margin-top: 3px; + padding: 0.2em; + border: solid thin #333; + border-radius: 0.5em; + -webkit-border-radius: .5em; + -moz-border-radius: .5em; + box-shadow: 2px 2px 3px #999; + -webkit-box-shadow: 2px 2px 3px #999; + -moz-box-shadow: rgba(0, 0, 0, 0.15) 2px 2px 2px; + background-image: -webkit-gradient(linear, left top, left bottom, from(#eee), to(#000),color-stop(0.3, #444)); + background-image: -moz-linear-gradient(center top, #eee 0%, #444 40%, #000); +} + +div.groupHeader { + margin-left: 16px; + margin-top: 12px; + font-weight: bold; +} + +div.groupText { + margin-left: 16px; + font-style: italic; +} + +body { + background-color: white; + color: black; + margin: 0; +} + +div.contents { + margin-top: 10px; + margin-left: 8px; + margin-right: 8px; +} + +td.indexkey { + background-color: #EBEFF6; + font-weight: bold; + border: 1px solid #C4CFE5; + margin: 2px 0px 2px 0; + padding: 2px 10px; + white-space: nowrap; + vertical-align: top; +} + +td.indexvalue { + background-color: #EBEFF6; + border: 1px solid #C4CFE5; + padding: 2px 10px; + margin: 2px 0px; +} + +tr.memlist { + background-color: #EEF1F7; +} + +p.formulaDsp { + text-align: center; +} + +img.formulaDsp { + +} + +img.formulaInl { + vertical-align: middle; +} + +div.center { + text-align: center; + margin-top: 0px; + margin-bottom: 0px; + padding: 0px; +} + +div.center img { + border: 0px; +} + +address.footer { + text-align: right; + padding-right: 12px; +} + +img.footer { + border: 0px; + vertical-align: middle; +} + +/* @group Code Colorization */ + +span.keyword { + color: #008000 +} + +span.keywordtype { + color: #604020 +} + +span.keywordflow { + color: #e08000 +} + +span.comment { + color: #800000 +} + +span.preprocessor { + color: #806020 +} + +span.stringliteral { + color: #002080 +} + +span.charliteral { + color: #008080 +} + +span.vhdldigit { + color: #ff00ff +} + +span.vhdlchar { + color: #000000 +} + +span.vhdlkeyword { + color: #700070 +} + +span.vhdllogic { + color: #ff0000 +} + +/* @end */ + +/* +.search { + color: #003399; + font-weight: bold; +} + +form.search { + margin-bottom: 0px; + margin-top: 0px; +} + +input.search { + font-size: 75%; + color: #000080; + font-weight: normal; + background-color: #e8eef2; +} +*/ + +td.tiny { + font-size: 75%; +} + +.dirtab { + padding: 4px; + border-collapse: collapse; + border: 1px solid #A3B4D7; +} + +th.dirtab { + background: #EBEFF6; + font-weight: bold; +} + +hr { + height: 0px; + border: none; + border-top: 1px solid #4A6AAA; +} + +hr.footer { + height: 1px; +} + +/* @group Member Descriptions */ + +table.memberdecls { + border-spacing: 0px; + padding: 0px; +} + +.mdescLeft, .mdescRight, +.memItemLeft, .memItemRight, +.memTemplItemLeft, .memTemplItemRight, .memTemplParams { + background-color: #F9FAFC; + border: none; + margin: 4px; + padding: 1px 0 0 8px; +} + +.mdescLeft, .mdescRight { + padding: 0px 8px 4px 8px; + color: #555; +} + +.memItemLeft, .memItemRight, .memTemplParams { + border-top: 1px solid #C4CFE5; +} + +.memItemLeft, .memTemplItemLeft { + white-space: nowrap; +} + +.memItemRight { + width: 100%; +} + +.memTemplParams { + color: #4665A2; + white-space: nowrap; +} + +/* @end */ + +/* @group Member Details */ + +/* Styles for detailed member documentation */ + +.memtemplate { + font-size: 80%; + color: #4665A2; + font-weight: normal; + margin-left: 9px; +} + +.memnav { + background-color: #EBEFF6; + border: 1px solid #A3B4D7; + text-align: center; + margin: 2px; + margin-right: 15px; + padding: 2px; +} + +.mempage { + width: 100%; +} + +.memitem { + padding: 0; + margin-bottom: 10px; + margin-right: 5px; +} + +.memname { + white-space: nowrap; + font-weight: bold; + margin-left: 6px; +} + +.memproto, dl.reflist dt { + border-top: 1px solid #A8B8D9; + border-left: 1px solid #A8B8D9; + border-right: 1px solid #A8B8D9; + padding: 6px 0px 6px 0px; + color: #253555; + font-weight: bold; + text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9); + /* opera specific markup */ + box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); + border-top-right-radius: 8px; + border-top-left-radius: 8px; + /* firefox specific markup */ + -moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px; + -moz-border-radius-topright: 8px; + -moz-border-radius-topleft: 8px; + /* webkit specific markup */ + -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); + -webkit-border-top-right-radius: 8px; + -webkit-border-top-left-radius: 8px; + background-image:url('nav_f.png'); + background-repeat:repeat-x; + background-color: #E2E8F2; + +} + +.memdoc, dl.reflist dd { + border-bottom: 1px solid #A8B8D9; + border-left: 1px solid #A8B8D9; + border-right: 1px solid #A8B8D9; + padding: 2px 5px; + background-color: #FBFCFD; + border-top-width: 0; + /* opera specific markup */ + border-bottom-left-radius: 8px; + border-bottom-right-radius: 8px; + box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); + /* firefox specific markup */ + -moz-border-radius-bottomleft: 8px; + -moz-border-radius-bottomright: 8px; + -moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px; + background-image: -moz-linear-gradient(center top, #FFFFFF 0%, #FFFFFF 60%, #F7F8FB 95%, #EEF1F7); + /* webkit specific markup */ + -webkit-border-bottom-left-radius: 8px; + -webkit-border-bottom-right-radius: 8px; + -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); + background-image: -webkit-gradient(linear,center top,center bottom,from(#FFFFFF), color-stop(0.6,#FFFFFF), color-stop(0.60,#FFFFFF), color-stop(0.95,#F7F8FB), to(#EEF1F7)); +} + +dl.reflist dt { + padding: 5px; +} + +dl.reflist dd { + margin: 0px 0px 10px 0px; + padding: 5px; +} + +.paramkey { + text-align: right; +} + +.paramtype { + white-space: nowrap; +} + +.paramname { + color: #602020; + white-space: nowrap; +} +.paramname em { + font-style: normal; +} + +.params, .retval, .exception, .tparams { + border-spacing: 6px 2px; +} + +.params .paramname, .retval .paramname { + font-weight: bold; + vertical-align: top; +} + +.params .paramtype { + font-style: italic; + vertical-align: top; +} + +.params .paramdir { + font-family: "courier new",courier,monospace; + vertical-align: top; +} + + + + +/* @end */ + +/* @group Directory (tree) */ + +/* for the tree view */ + +.ftvtree { + font-family: sans-serif; + margin: 0px; +} + +/* these are for tree view when used as main index */ + +.directory { + font-size: 9pt; + font-weight: bold; + margin: 5px; +} + +.directory h3 { + margin: 0px; + margin-top: 1em; + font-size: 11pt; +} + +/* +The following two styles can be used to replace the root node title +with an image of your choice. Simply uncomment the next two styles, +specify the name of your image and be sure to set 'height' to the +proper pixel height of your image. +*/ + +/* +.directory h3.swap { + height: 61px; + background-repeat: no-repeat; + background-image: url("yourimage.gif"); +} +.directory h3.swap span { + display: none; +} +*/ + +.directory > h3 { + margin-top: 0; +} + +.directory p { + margin: 0px; + white-space: nowrap; +} + +.directory div { + display: none; + margin: 0px; +} + +.directory img { + vertical-align: -30%; +} + +/* these are for tree view when not used as main index */ + +.directory-alt { + font-size: 100%; + font-weight: bold; +} + +.directory-alt h3 { + margin: 0px; + margin-top: 1em; + font-size: 11pt; +} + +.directory-alt > h3 { + margin-top: 0; +} + +.directory-alt p { + margin: 0px; + white-space: nowrap; +} + +.directory-alt div { + display: none; + margin: 0px; +} + +.directory-alt img { + vertical-align: -30%; +} + +/* @end */ + +div.dynheader { + margin-top: 8px; +} + +address { + font-style: normal; + color: #2A3D61; +} + +table.doxtable { + border-collapse:collapse; +} + +table.doxtable td, table.doxtable th { + border: 1px solid #2D4068; + padding: 3px 7px 2px; +} + +table.doxtable th { + background-color: #374F7F; + color: #FFFFFF; + font-size: 110%; + padding-bottom: 4px; + padding-top: 5px; + text-align:left; +} + +table.fieldtable { + width: 100%; + margin-bottom: 10px; + border: 1px solid #A8B8D9; + border-spacing: 0px; + -moz-border-radius: 4px; + -webkit-border-radius: 4px; + border-radius: 4px; + -moz-box-shadow: rgba(0, 0, 0, 0.15) 2px 2px 2px; + -webkit-box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.15); + box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.15); +} + +.fieldtable td, .fieldtable th { + padding: 3px 7px 2px; +} + +.fieldtable td.fieldtype, .fieldtable td.fieldname { + white-space: nowrap; + border-right: 1px solid #A8B8D9; + border-bottom: 1px solid #A8B8D9; + vertical-align: top; +} + +.fieldtable td.fielddoc { + border-bottom: 1px solid #A8B8D9; + width: 100%; +} + +.fieldtable tr:last-child td { + border-bottom: none; +} + +.fieldtable th { + background-image:url('nav_f.png'); + background-repeat:repeat-x; + background-color: #E2E8F2; + font-size: 90%; + color: #253555; + padding-bottom: 4px; + padding-top: 5px; + text-align:left; + -moz-border-radius-topleft: 4px; + -moz-border-radius-topright: 4px; + -webkit-border-top-left-radius: 4px; + -webkit-border-top-right-radius: 4px; + border-top-left-radius: 4px; + border-top-right-radius: 4px; + border-bottom: 1px solid #A8B8D9; +} + + +.tabsearch { + top: 0px; + left: 10px; + height: 36px; + background-image: url('tab_b.png'); + z-index: 101; + overflow: hidden; + font-size: 13px; +} + +.navpath ul +{ + font-size: 11px; + background-image:url('tab_b.png'); + background-repeat:repeat-x; + height:30px; + line-height:30px; + color:#8AA0CC; + border:solid 1px #C2CDE4; + overflow:hidden; + margin:0px; + padding:0px; +} + +.navpath li +{ + list-style-type:none; + float:left; + padding-left:10px; + padding-right:15px; + background-image:url('bc_s.png'); + background-repeat:no-repeat; + background-position:right; + color:#364D7C; +} + +.navpath li.navelem a +{ + height:32px; + display:block; + text-decoration: none; + outline: none; +} + +.navpath li.navelem a:hover +{ + color:#6884BD; +} + +.navpath li.footer +{ + list-style-type:none; + float:right; + padding-left:10px; + padding-right:15px; + background-image:none; + background-repeat:no-repeat; + background-position:right; + color:#364D7C; + font-size: 8pt; +} + + +div.summary +{ + float: right; + font-size: 8pt; + padding-right: 5px; + width: 50%; + text-align: right; +} + +div.summary a +{ + white-space: nowrap; +} + +div.ingroups +{ + margin-left: 5px; + font-size: 8pt; + padding-left: 5px; + width: 50%; + text-align: left; +} + +div.ingroups a +{ + white-space: nowrap; +} + +div.header +{ + background-image:url('nav_h.png'); + background-repeat:repeat-x; + background-color: #F9FAFC; + margin: 0px; + border-bottom: 1px solid #C4CFE5; +} + +div.headertitle +{ + padding: 5px 5px 5px 7px; +} + +dl +{ + padding: 0 0 0 10px; +} + +dl.note, dl.warning, dl.attention, dl.pre, dl.post, dl.invariant, dl.deprecated, dl.todo, dl.test, dl.bug +{ + border-left:4px solid; + padding: 0 0 0 6px; +} + +dl.note +{ + border-color: #D0C000; +} + +dl.warning, dl.attention +{ + border-color: #FF0000; +} + +dl.pre, dl.post, dl.invariant +{ + border-color: #00D000; +} + +dl.deprecated +{ + border-color: #505050; +} + +dl.todo +{ + border-color: #00C0E0; +} + +dl.test +{ + border-color: #3030E0; +} + +dl.bug +{ + border-color: #C08050; +} + +#projectlogo +{ + text-align: center; + vertical-align: bottom; + border-collapse: separate; +} + +#projectlogo img +{ + border: 0px none; +} + +#projectname +{ + font: 300% Tahoma, Arial,sans-serif; + margin: 0px; + padding: 2px 0px; +} + +#projectbrief +{ + font: 120% Tahoma, Arial,sans-serif; + margin: 0px; + padding: 0px; +} + +#projectnumber +{ + font: 50% Tahoma, Arial,sans-serif; + margin: 0px; + padding: 0px; +} + +#titlearea +{ + padding: 0px; + margin: 0px; + width: 100%; + border-bottom: 1px solid #5373B4; +} + +.image +{ + text-align: center; +} + +.dotgraph +{ + text-align: center; +} + +.mscgraph +{ + text-align: center; +} + +.caption +{ + font-weight: bold; +} + +div.zoom +{ + border: 1px solid #90A5CE; +} + +dl.citelist { + margin-bottom:50px; +} + +dl.citelist dt { + color:#334975; + float:left; + font-weight:bold; + margin-right:10px; + padding:5px; +} + +dl.citelist dd { + margin:2px 0; + padding:5px 0; +} + +@media print +{ + #top { display: none; } + #side-nav { display: none; } + #nav-path { display: none; } + body { overflow:visible; } + h1, h2, h3, h4, h5, h6 { page-break-after: avoid; } + .summary { display: none; } + .memitem { page-break-inside: avoid; } + #doc-content + { + margin-left:0 !important; + height:auto !important; + width:auto !important; + overflow:inherit; + display:inline; + } + pre.fragment + { + overflow: visible; + text-wrap: unrestricted; + white-space: -moz-pre-wrap; /* Moz */ + white-space: -pre-wrap; /* Opera 4-6 */ + white-space: -o-pre-wrap; /* Opera 7 */ + white-space: pre-wrap; /* CSS3 */ + word-wrap: break-word; /* IE 5.5+ */ + } +} + diff --git a/libyaml/doc/html/doxygen.png b/libyaml/doc/html/doxygen.png new file mode 100644 index 0000000000000000000000000000000000000000..635ed52fce7057ac24df92ec7664088a881fa5d0 GIT binary patch literal 3942 zcmV-s51H_ZP)95ENDh(OT9xpYZC{M(=rqI* z+1erNEr&9zRjUI-4rN=4BBz>P@ys*xOjGRjzVE*Fx_qvyt9d@B@BO*&@8Mq!nM{Tc z_WoM84-~xLreSL9@vgZ{m2dF}`u=^ZF3syQ-s2tnBwCI3ZFvSfI20Wbj236~Urq*8Kfw@RKKfRQTgE>}uUHK^ptamY=o)LU(xy55zNQ(`qZ znZ&$O075mrrInIXQgw4%GCbMD8Vn`3n3$EaRwtP1D{A!Gs=e!L%3;ayv@I{rAw{xw z^x^>EIWQM8ob3m}$(BaupDMV;Ed8w5|i(*e`7rU$TOc&1o7`|!LyN5jHI z7uWAR!v4c2xMp?}QmRYyf>i}tYGU(g=>DW&==J@GbhR z5@BNVY3O$`^D%gk4khm9XpFhuwzxUhi9T=Du4rpVuYRSMPHeDqo+4htnZRU@G9`0& z9~p)CsFl1|t*wjfoTo&%davN^3RfJUhQ{ZZIAcD77X^XsF_iR&ZMQ;p>K5*+*48)x z+=<>nh+6Uq85jOkg>{z>a;+V`s(I;I%*5s+R@9a^wNoZ03(g9-EcH%uHvX&yp7`D#`9Kw>DU3s zjD-VuW_A-K)unlS4O3f>_B%pPONUmI#oyL};Lglp3=04>0eBBEw$D1k-$WTsoi#K* z$7h`NcyRZsZ#w~6I<%~u!^xDofYrzF>zVIj2N>Ijs`mVR(Oy&*9f}<{JtQj8jJT!oEc!NQXBq5y|6ET*N?7ox*E6#{i- z@_DLD^IYTtg|Pg?A~!7@OCd8p^)kxK%VBM84docx$Z{MvO)iiqep@or-N}TEU8$%; zJih?#yJ9)V1s_`}c3XbY9V}nEKwNz8ILmR|v)(w|D@oVG;=i`+$*)!(xH{9#$2Za;pyZ1wgU#)mHl|&8%iwu%yncO z`T32Ib0$D}j`c}}5M@M#7oR&G=QwU!!Ja*P7|NJt1@lo=d{_dY-q_lmDcH7{BHncF zR@^PmcLC6EsN?6N{fV3o8}>?h9X_@;=&-p7%tms7$_{3w(anwek_k&<&)~c$Ar?S> zy9gKavndTmxqAbE?SMgcWhXPENdKdz7ntt55Y3Hs3jjc~uR-#$tR(1a_abv9`-QzG z^J0Fsbd&yruq%xAsxf3rc=T}$Zx|AD%x{Fd=? z{qhl3kG5w-PqVK9-Gru%7UIEw)bt$ZMF|Z6HpmO)F%@GNT8yT|#FuWPxv@@Ic={;6 zU7)e!XG|1dx=kU|&|)+m+$&|Yw92Fa;*MnegXcCf8XsHfqg_F5t)3Jt8)EkXKuY21 zqt%4}@R8hK*(_JO0*H+Pa)6Pp&K49rKNeQEYb*x9WY`!`Vh3|80YF%I`lxv9_!$hD zOh$>zWaRIW!);6`vA$Zp;5lnGyX^^N%YEjCeJMHPolKCE1ttIqK<$0w&LcE8)`_c2 z^H^qf6ACV0t7FLLCsu#mL&Mb8gE@rZE#k+1Nrrxw+{N0^#bN*~!qt2>S4e#jC$a$` ze4@{)$aTEYq_!#2|t@Fj3e?w-XVuG$Z}kAR?_kgJAlZIJ)0{eHw#fybNooA zp02jyYVc&w!}m#BVP>ef2|U^J(A-#O1R#A&><*?Y! zOwml{CnE+aU3JfKE@uzge(qMY{^6siuXFt;+mMbapU;Ppejl=L#>s2#SMBbfP9AFT znEVA=TBtZ6d-GfF>kOxylg>Ek%qTp*h2ze!^^hOsmKOEE6b;maQ>~R>3#z`Zawbik z88OTykU3_!Atg^+vnM=1n}?%<$dHzn)?k&T#RWwb+*y;XNQbYNHKo3wr~&}Qa$id; z6^D*K9RTQZUuQVg)g~P%!BIiv+cXllt)KEP9IN)1udQKf>p|~lXj7K<-9}0Q%i9+K zXaF7qXclE>sf)7)J4_M%V{;(sFT7HN$o0#_qU#Ah1D{ zon=JihPcgG5xHuvQwOXBkt3(iUdx{6Gn|aa>@C9Cqg%rPK(+REZ4>6t3z7m@Aj;0l zSHh&%cKSJ*+WOJGwe?Y7d(9RAy)&NVS6uj}1m@U}jXH3oVQT9E0A)$ZDRdK>;_i;+ z7vbEoI7$1XK6vNxT(_sJ(GM4s92e;gB&Q zDO;(Ve^%gPG&lWW1fUf_=9-Q1%&`s%aD^o`Q2u`WI9V>Qm#D5?SW<)Njmt@aR5@6( zL4cdTo+Jg@>Brm1^_gf%0Z?}1AppR3NdFE5uzdpBZz;{Thd6SI-$gb2}pFAww$*j(2=s{mdz2E;lBvVcrN@}i2bC`Q5Y_;BID^f0J+ACVhyQsLg0@`okIk+i=LJ=3yvI*oASj62 za3C{Pu_fQ+atw!zN{$Shr*_UV=|jp4#CqWeGE?Jb`pq!|5bDES&-Ix=-N>DpydHqW z+-{QS+i)d;uGS)M%Suw9khR}3N82j|S{a#&Tctme0s%mTy<1S|;@M-+S4#o@!qr;r z+w(n=;@43Y_n#dI0Gb(T0{G7k-KY8k`MPM_Bss$?)SK){KJMrwv!vz42_U_Za zX7lDqiU8ZvCAfGpAtfVC5bQrYa4C)M9G$S4D&VqpJ8)lm$t5FAAR%ywf>*~VaivC70RVFXISv4Lx&tk^Cf1)qQ|rxp z*8H>)cgoM;(eKxH14u~~@JopNr9@A z#-yXVG?$es;EPqsn-j?45^L52U=nT#0A^T3JY$&B3EH&%2UHdv3P=_3$!n76!34ks zz^2ii@sXAu8LKYMmG=_^*qtiiOFNlG3?QYtG%wrCZh|)vlj8vq3sw~f1b8;_TMB>z zPSyDQy_9bbXD*#sNRGMzfSAwUD}ASX;ZGQcGdE=9q~ORU{v$}=z2Bc8EOe2S&);jS zCZB8P`hPoV1NBk)TQP2z{q$NL-GLUc7%>&fecE^E{I5gs?8!qTK7VgR7Z?}-`YG|z zVN-NvOlQ+B;~J*69_Xd1n-0MLKTY6&*%rTi*0^HXniz8{bCMsVpSXqs(GGO)*_#Kz z9YBCQ_VRhtwhMfppMh@OdxjCN0mH`5hKZr>UoxMx`W~u^kD&bskplglOiRxQvep*2 z0mk+kMP>J)K`8X3`6Zq|X~5IQ-_rrOn+_WvU{1Gs{ow1-Eb;K(Z?p$@ugXpr^?PM( z(5Hv;$*X=QZaqG_4q)N1v9sO(Dsei!;%IcIztt6YUs{yj z^77e`UYa^%<-Ts+d*b=ihKt?0_sj!ePNO@K*PGmGD*v^;rRAkduikx~UNk=@{XKeV zp_ir(dTaGVWBr{_02Kg2Xmlsn|IvIIRYivbo|L{yx}yX5Bte@P6C>1KyqvYnT{boB#j-07*qoM6N<$f^XQQ A+yDRo literal 0 HcmV?d00001 diff --git a/libyaml/doc/html/files.html b/libyaml/doc/html/files.html new file mode 100644 index 00000000..1c48dd91 --- /dev/null +++ b/libyaml/doc/html/files.html @@ -0,0 +1,72 @@ + + + + + +yaml: File List + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.5 +
+ +
+
+ + + + +
+
+
+
File List
+
+
+
Here is a list of all documented files with brief descriptions:
+ +
yaml.hPublic interface for libyaml
+
+ + + + + + diff --git a/libyaml/doc/html/functions.html b/libyaml/doc/html/functions.html new file mode 100644 index 00000000..df9299b2 --- /dev/null +++ b/libyaml/doc/html/functions.html @@ -0,0 +1,123 @@ + + + + + +yaml: Data Fields + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.5 +
+ +
+
+ + + + + + +
+
+
Here is a list of all documented struct and union fields with links to the struct/union documentation for each field:
+ +

- a -

+
+ + + + + + diff --git a/libyaml/doc/html/functions_0x62.html b/libyaml/doc/html/functions_0x62.html new file mode 100644 index 00000000..a368fe95 --- /dev/null +++ b/libyaml/doc/html/functions_0x62.html @@ -0,0 +1,116 @@ + + + + + +yaml: Data Fields + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.5 +
+ +
+
+ + + + + + +
+
+
Here is a list of all documented struct and union fields with links to the struct/union documentation for each field:
+ +

- b -

+
+ + + + + + diff --git a/libyaml/doc/html/functions_0x63.html b/libyaml/doc/html/functions_0x63.html new file mode 100644 index 00000000..be4df973 --- /dev/null +++ b/libyaml/doc/html/functions_0x63.html @@ -0,0 +1,119 @@ + + + + + +yaml: Data Fields + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.5 +
+ +
+
+ + + + + + +
+
+
Here is a list of all documented struct and union fields with links to the struct/union documentation for each field:
+ +

- c -

+
+ + + + + + diff --git a/libyaml/doc/html/functions_0x64.html b/libyaml/doc/html/functions_0x64.html new file mode 100644 index 00000000..033adeb5 --- /dev/null +++ b/libyaml/doc/html/functions_0x64.html @@ -0,0 +1,115 @@ + + + + + +yaml: Data Fields + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.5 +
+ +
+
+ + + + + + +
+
+
Here is a list of all documented struct and union fields with links to the struct/union documentation for each field:
+ +

- d -

+
+ + + + + + diff --git a/libyaml/doc/html/functions_0x65.html b/libyaml/doc/html/functions_0x65.html new file mode 100644 index 00000000..ece59bc5 --- /dev/null +++ b/libyaml/doc/html/functions_0x65.html @@ -0,0 +1,142 @@ + + + + + +yaml: Data Fields + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.5 +
+ +
+
+ + + + + + +
+
+
Here is a list of all documented struct and union fields with links to the struct/union documentation for each field:
+ +

- e -

+
+ + + + + + diff --git a/libyaml/doc/html/functions_0x66.html b/libyaml/doc/html/functions_0x66.html new file mode 100644 index 00000000..10edc211 --- /dev/null +++ b/libyaml/doc/html/functions_0x66.html @@ -0,0 +1,111 @@ + + + + + +yaml: Data Fields + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.5 +
+ +
+
+ + + + + + +
+
+
Here is a list of all documented struct and union fields with links to the struct/union documentation for each field:
+ +

- f -

+
+ + + + + + diff --git a/libyaml/doc/html/functions_0x68.html b/libyaml/doc/html/functions_0x68.html new file mode 100644 index 00000000..f0ec097a --- /dev/null +++ b/libyaml/doc/html/functions_0x68.html @@ -0,0 +1,112 @@ + + + + + +yaml: Data Fields + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.5 +
+ +
+
+ + + + + + +
+
+
Here is a list of all documented struct and union fields with links to the struct/union documentation for each field:
+ +

- h -

+
+ + + + + + diff --git a/libyaml/doc/html/functions_0x69.html b/libyaml/doc/html/functions_0x69.html new file mode 100644 index 00000000..612ff197 --- /dev/null +++ b/libyaml/doc/html/functions_0x69.html @@ -0,0 +1,124 @@ + + + + + +yaml: Data Fields + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.5 +
+ +
+
+ + + + + + +
+
+
Here is a list of all documented struct and union fields with links to the struct/union documentation for each field:
+ +

- i -

+
+ + + + + + diff --git a/libyaml/doc/html/functions_0x6b.html b/libyaml/doc/html/functions_0x6b.html new file mode 100644 index 00000000..53e0234f --- /dev/null +++ b/libyaml/doc/html/functions_0x6b.html @@ -0,0 +1,103 @@ + + + + + +yaml: Data Fields + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.5 +
+ +
+
+ + + + + + +
+
+
Here is a list of all documented struct and union fields with links to the struct/union documentation for each field:
+ +

- k -

+
+ + + + + + diff --git a/libyaml/doc/html/functions_0x6c.html b/libyaml/doc/html/functions_0x6c.html new file mode 100644 index 00000000..7b3f6593 --- /dev/null +++ b/libyaml/doc/html/functions_0x6c.html @@ -0,0 +1,120 @@ + + + + + +yaml: Data Fields + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.5 +
+ +
+
+ + + + + + +
+
+
Here is a list of all documented struct and union fields with links to the struct/union documentation for each field:
+ +

- l -

+
+ + + + + + diff --git a/libyaml/doc/html/functions_0x6d.html b/libyaml/doc/html/functions_0x6d.html new file mode 100644 index 00000000..56e3fa0a --- /dev/null +++ b/libyaml/doc/html/functions_0x6d.html @@ -0,0 +1,128 @@ + + + + + +yaml: Data Fields + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.5 +
+ +
+
+ + + + + + +
+
+
Here is a list of all documented struct and union fields with links to the struct/union documentation for each field:
+ +

- m -

+
+ + + + + + diff --git a/libyaml/doc/html/functions_0x6e.html b/libyaml/doc/html/functions_0x6e.html new file mode 100644 index 00000000..c763a036 --- /dev/null +++ b/libyaml/doc/html/functions_0x6e.html @@ -0,0 +1,103 @@ + + + + + +yaml: Data Fields + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.5 +
+ +
+
+ + + + + + +
+
+
Here is a list of all documented struct and union fields with links to the struct/union documentation for each field:
+ +

- n -

+
+ + + + + + diff --git a/libyaml/doc/html/functions_0x6f.html b/libyaml/doc/html/functions_0x6f.html new file mode 100644 index 00000000..c4116909 --- /dev/null +++ b/libyaml/doc/html/functions_0x6f.html @@ -0,0 +1,112 @@ + + + + + +yaml: Data Fields + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.5 +
+ +
+
+ + + + + + +
+
+
Here is a list of all documented struct and union fields with links to the struct/union documentation for each field:
+ +

- o -

+
+ + + + + + diff --git a/libyaml/doc/html/functions_0x70.html b/libyaml/doc/html/functions_0x70.html new file mode 100644 index 00000000..03f9cbf8 --- /dev/null +++ b/libyaml/doc/html/functions_0x70.html @@ -0,0 +1,132 @@ + + + + + +yaml: Data Fields + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.5 +
+ +
+
+ + + + + + +
+
+
Here is a list of all documented struct and union fields with links to the struct/union documentation for each field:
+ +

- p -

+
+ + + + + + diff --git a/libyaml/doc/html/functions_0x71.html b/libyaml/doc/html/functions_0x71.html new file mode 100644 index 00000000..01da5c9d --- /dev/null +++ b/libyaml/doc/html/functions_0x71.html @@ -0,0 +1,103 @@ + + + + + +yaml: Data Fields + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.5 +
+ +
+
+ + + + + + +
+
+
Here is a list of all documented struct and union fields with links to the struct/union documentation for each field:
+ +

- q -

+
+ + + + + + diff --git a/libyaml/doc/html/functions_0x72.html b/libyaml/doc/html/functions_0x72.html new file mode 100644 index 00000000..d6394572 --- /dev/null +++ b/libyaml/doc/html/functions_0x72.html @@ -0,0 +1,119 @@ + + + + + +yaml: Data Fields + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.5 +
+ +
+
+ + + + + + +
+
+
Here is a list of all documented struct and union fields with links to the struct/union documentation for each field:
+ +

- r -

+
+ + + + + + diff --git a/libyaml/doc/html/functions_0x73.html b/libyaml/doc/html/functions_0x73.html new file mode 100644 index 00000000..e295746b --- /dev/null +++ b/libyaml/doc/html/functions_0x73.html @@ -0,0 +1,195 @@ + + + + + +yaml: Data Fields + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.5 +
+ +
+
+ + + + + + +
+
+
Here is a list of all documented struct and union fields with links to the struct/union documentation for each field:
+ +

- s -

+
+ + + + + + diff --git a/libyaml/doc/html/functions_0x74.html b/libyaml/doc/html/functions_0x74.html new file mode 100644 index 00000000..3197f756 --- /dev/null +++ b/libyaml/doc/html/functions_0x74.html @@ -0,0 +1,147 @@ + + + + + +yaml: Data Fields + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.5 +
+ +
+
+ + + + + + +
+
+
Here is a list of all documented struct and union fields with links to the struct/union documentation for each field:
+ +

- t -

+
+ + + + + + diff --git a/libyaml/doc/html/functions_0x75.html b/libyaml/doc/html/functions_0x75.html new file mode 100644 index 00000000..609221bb --- /dev/null +++ b/libyaml/doc/html/functions_0x75.html @@ -0,0 +1,103 @@ + + + + + +yaml: Data Fields + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.5 +
+ +
+
+ + + + + + +
+
+
Here is a list of all documented struct and union fields with links to the struct/union documentation for each field:
+ +

- u -

+
+ + + + + + diff --git a/libyaml/doc/html/functions_0x76.html b/libyaml/doc/html/functions_0x76.html new file mode 100644 index 00000000..fdae18df --- /dev/null +++ b/libyaml/doc/html/functions_0x76.html @@ -0,0 +1,112 @@ + + + + + +yaml: Data Fields + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.5 +
+ +
+
+ + + + + + +
+
+
Here is a list of all documented struct and union fields with links to the struct/union documentation for each field:
+ +

- v -

+
+ + + + + + diff --git a/libyaml/doc/html/functions_0x77.html b/libyaml/doc/html/functions_0x77.html new file mode 100644 index 00000000..eff19afc --- /dev/null +++ b/libyaml/doc/html/functions_0x77.html @@ -0,0 +1,109 @@ + + + + + +yaml: Data Fields + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.5 +
+ +
+
+ + + + + + +
+
+
Here is a list of all documented struct and union fields with links to the struct/union documentation for each field:
+ +

- w -

+
+ + + + + + diff --git a/libyaml/doc/html/functions_vars.html b/libyaml/doc/html/functions_vars.html new file mode 100644 index 00000000..efd1a693 --- /dev/null +++ b/libyaml/doc/html/functions_vars.html @@ -0,0 +1,123 @@ + + + + + +yaml: Data Fields - Variables + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.5 +
+ +
+
+ + + + + + +
+
+  + +

- a -

+
+ + + + + + diff --git a/libyaml/doc/html/functions_vars_0x62.html b/libyaml/doc/html/functions_vars_0x62.html new file mode 100644 index 00000000..c7cb3b5a --- /dev/null +++ b/libyaml/doc/html/functions_vars_0x62.html @@ -0,0 +1,116 @@ + + + + + +yaml: Data Fields - Variables + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.5 +
+ +
+
+ + + + + + +
+
+  + +

- b -

+
+ + + + + + diff --git a/libyaml/doc/html/functions_vars_0x63.html b/libyaml/doc/html/functions_vars_0x63.html new file mode 100644 index 00000000..5ea5cdd6 --- /dev/null +++ b/libyaml/doc/html/functions_vars_0x63.html @@ -0,0 +1,119 @@ + + + + + +yaml: Data Fields - Variables + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.5 +
+ +
+
+ + + + + + +
+
+  + +

- c -

+
+ + + + + + diff --git a/libyaml/doc/html/functions_vars_0x64.html b/libyaml/doc/html/functions_vars_0x64.html new file mode 100644 index 00000000..36493730 --- /dev/null +++ b/libyaml/doc/html/functions_vars_0x64.html @@ -0,0 +1,115 @@ + + + + + +yaml: Data Fields - Variables + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.5 +
+ +
+
+ + + + + + +
+
+  + +

- d -

+
+ + + + + + diff --git a/libyaml/doc/html/functions_vars_0x65.html b/libyaml/doc/html/functions_vars_0x65.html new file mode 100644 index 00000000..e9410d93 --- /dev/null +++ b/libyaml/doc/html/functions_vars_0x65.html @@ -0,0 +1,142 @@ + + + + + +yaml: Data Fields - Variables + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.5 +
+ +
+
+ + + + + + +
+ + + + + + + diff --git a/libyaml/doc/html/functions_vars_0x66.html b/libyaml/doc/html/functions_vars_0x66.html new file mode 100644 index 00000000..cd32059c --- /dev/null +++ b/libyaml/doc/html/functions_vars_0x66.html @@ -0,0 +1,111 @@ + + + + + +yaml: Data Fields - Variables + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.5 +
+ +
+
+ + + + + + +
+
+  + +

- f -

+
+ + + + + + diff --git a/libyaml/doc/html/functions_vars_0x68.html b/libyaml/doc/html/functions_vars_0x68.html new file mode 100644 index 00000000..eda098c1 --- /dev/null +++ b/libyaml/doc/html/functions_vars_0x68.html @@ -0,0 +1,112 @@ + + + + + +yaml: Data Fields - Variables + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.5 +
+ +
+
+ + + + + + +
+
+  + +

- h -

+
+ + + + + + diff --git a/libyaml/doc/html/functions_vars_0x69.html b/libyaml/doc/html/functions_vars_0x69.html new file mode 100644 index 00000000..69950737 --- /dev/null +++ b/libyaml/doc/html/functions_vars_0x69.html @@ -0,0 +1,124 @@ + + + + + +yaml: Data Fields - Variables + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.5 +
+ +
+
+ + + + + + +
+
+  + +

- i -

+
+ + + + + + diff --git a/libyaml/doc/html/functions_vars_0x6b.html b/libyaml/doc/html/functions_vars_0x6b.html new file mode 100644 index 00000000..498b2aec --- /dev/null +++ b/libyaml/doc/html/functions_vars_0x6b.html @@ -0,0 +1,103 @@ + + + + + +yaml: Data Fields - Variables + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.5 +
+ +
+
+ + + + + + +
+
+  + +

- k -

+
+ + + + + + diff --git a/libyaml/doc/html/functions_vars_0x6c.html b/libyaml/doc/html/functions_vars_0x6c.html new file mode 100644 index 00000000..ea1e75f8 --- /dev/null +++ b/libyaml/doc/html/functions_vars_0x6c.html @@ -0,0 +1,120 @@ + + + + + +yaml: Data Fields - Variables + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.5 +
+ +
+
+ + + + + + +
+
+  + +

- l -

+
+ + + + + + diff --git a/libyaml/doc/html/functions_vars_0x6d.html b/libyaml/doc/html/functions_vars_0x6d.html new file mode 100644 index 00000000..c540536c --- /dev/null +++ b/libyaml/doc/html/functions_vars_0x6d.html @@ -0,0 +1,128 @@ + + + + + +yaml: Data Fields - Variables + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.5 +
+ +
+
+ + + + + + +
+
+  + +

- m -

+
+ + + + + + diff --git a/libyaml/doc/html/functions_vars_0x6e.html b/libyaml/doc/html/functions_vars_0x6e.html new file mode 100644 index 00000000..9de08b99 --- /dev/null +++ b/libyaml/doc/html/functions_vars_0x6e.html @@ -0,0 +1,103 @@ + + + + + +yaml: Data Fields - Variables + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.5 +
+ +
+
+ + + + + + +
+
+  + +

- n -

+
+ + + + + + diff --git a/libyaml/doc/html/functions_vars_0x6f.html b/libyaml/doc/html/functions_vars_0x6f.html new file mode 100644 index 00000000..436fcd0b --- /dev/null +++ b/libyaml/doc/html/functions_vars_0x6f.html @@ -0,0 +1,112 @@ + + + + + +yaml: Data Fields - Variables + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.5 +
+ +
+
+ + + + + + +
+
+  + +

- o -

+
+ + + + + + diff --git a/libyaml/doc/html/functions_vars_0x70.html b/libyaml/doc/html/functions_vars_0x70.html new file mode 100644 index 00000000..cc1ef49f --- /dev/null +++ b/libyaml/doc/html/functions_vars_0x70.html @@ -0,0 +1,132 @@ + + + + + +yaml: Data Fields - Variables + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.5 +
+ +
+
+ + + + + + +
+
+  + +

- p -

+
+ + + + + + diff --git a/libyaml/doc/html/functions_vars_0x71.html b/libyaml/doc/html/functions_vars_0x71.html new file mode 100644 index 00000000..d9e18208 --- /dev/null +++ b/libyaml/doc/html/functions_vars_0x71.html @@ -0,0 +1,103 @@ + + + + + +yaml: Data Fields - Variables + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.5 +
+ +
+
+ + + + + + +
+
+  + +

- q -

+
+ + + + + + diff --git a/libyaml/doc/html/functions_vars_0x72.html b/libyaml/doc/html/functions_vars_0x72.html new file mode 100644 index 00000000..09cf76f2 --- /dev/null +++ b/libyaml/doc/html/functions_vars_0x72.html @@ -0,0 +1,119 @@ + + + + + +yaml: Data Fields - Variables + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.5 +
+ +
+
+ + + + + + +
+
+  + +

- r -

+
+ + + + + + diff --git a/libyaml/doc/html/functions_vars_0x73.html b/libyaml/doc/html/functions_vars_0x73.html new file mode 100644 index 00000000..4e82a759 --- /dev/null +++ b/libyaml/doc/html/functions_vars_0x73.html @@ -0,0 +1,195 @@ + + + + + +yaml: Data Fields - Variables + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.5 +
+ +
+
+ + + + + + +
+
+  + +

- s -

+
+ + + + + + diff --git a/libyaml/doc/html/functions_vars_0x74.html b/libyaml/doc/html/functions_vars_0x74.html new file mode 100644 index 00000000..ffcf1c30 --- /dev/null +++ b/libyaml/doc/html/functions_vars_0x74.html @@ -0,0 +1,147 @@ + + + + + +yaml: Data Fields - Variables + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.5 +
+ +
+
+ + + + + + +
+
+  + +

- t -

+
+ + + + + + diff --git a/libyaml/doc/html/functions_vars_0x75.html b/libyaml/doc/html/functions_vars_0x75.html new file mode 100644 index 00000000..51315be6 --- /dev/null +++ b/libyaml/doc/html/functions_vars_0x75.html @@ -0,0 +1,103 @@ + + + + + +yaml: Data Fields - Variables + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.5 +
+ +
+
+ + + + + + +
+
+  + +

- u -

+
+ + + + + + diff --git a/libyaml/doc/html/functions_vars_0x76.html b/libyaml/doc/html/functions_vars_0x76.html new file mode 100644 index 00000000..1321cd8a --- /dev/null +++ b/libyaml/doc/html/functions_vars_0x76.html @@ -0,0 +1,112 @@ + + + + + +yaml: Data Fields - Variables + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.5 +
+ +
+
+ + + + + + +
+
+  + +

- v -

+
+ + + + + + diff --git a/libyaml/doc/html/functions_vars_0x77.html b/libyaml/doc/html/functions_vars_0x77.html new file mode 100644 index 00000000..a19bbb0a --- /dev/null +++ b/libyaml/doc/html/functions_vars_0x77.html @@ -0,0 +1,109 @@ + + + + + +yaml: Data Fields - Variables + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.5 +
+ +
+
+ + + + + + +
+
+  + +

- w -

+
+ + + + + + diff --git a/libyaml/doc/html/globals.html b/libyaml/doc/html/globals.html new file mode 100644 index 00000000..d51d801b --- /dev/null +++ b/libyaml/doc/html/globals.html @@ -0,0 +1,699 @@ + + + + + +yaml: Globals + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.5 +
+ +
+
+ + + + + + +
+
+
Here is a list of all documented functions, variables, defines, enums, and typedefs with links to the documentation:
+ +

- y -

    +
  • yaml_alias_data_t +: yaml.h +
  • +
  • YAML_ALIAS_EVENT +: yaml.h +
  • +
  • yaml_alias_event_initialize() +: yaml.h +
  • +
  • YAML_ALIAS_TOKEN +: yaml.h +
  • +
  • YAML_ANCHOR_TOKEN +: yaml.h +
  • +
  • YAML_ANY_BREAK +: yaml.h +
  • +
  • YAML_ANY_ENCODING +: yaml.h +
  • +
  • YAML_ANY_MAPPING_STYLE +: yaml.h +
  • +
  • YAML_ANY_SCALAR_STYLE +: yaml.h +
  • +
  • YAML_ANY_SEQUENCE_STYLE +: yaml.h +
  • +
  • YAML_BLOCK_END_TOKEN +: yaml.h +
  • +
  • YAML_BLOCK_ENTRY_TOKEN +: yaml.h +
  • +
  • YAML_BLOCK_MAPPING_START_TOKEN +: yaml.h +
  • +
  • YAML_BLOCK_MAPPING_STYLE +: yaml.h +
  • +
  • YAML_BLOCK_SEQUENCE_START_TOKEN +: yaml.h +
  • +
  • YAML_BLOCK_SEQUENCE_STYLE +: yaml.h +
  • +
  • YAML_BOOL_TAG +: yaml.h +
  • +
  • yaml_break_e +: yaml.h +
  • +
  • yaml_break_t +: yaml.h +
  • +
  • yaml_char_t +: yaml.h +
  • +
  • YAML_COMPOSER_ERROR +: yaml.h +
  • +
  • YAML_CR_BREAK +: yaml.h +
  • +
  • YAML_CRLN_BREAK +: yaml.h +
  • +
  • YAML_DECLARE +: yaml.h +
  • +
  • YAML_DEFAULT_MAPPING_TAG +: yaml.h +
  • +
  • YAML_DEFAULT_SCALAR_TAG +: yaml.h +
  • +
  • YAML_DEFAULT_SEQUENCE_TAG +: yaml.h +
  • +
  • yaml_document_add_mapping() +: yaml.h +
  • +
  • yaml_document_add_scalar() +: yaml.h +
  • +
  • yaml_document_add_sequence() +: yaml.h +
  • +
  • yaml_document_append_mapping_pair() +: yaml.h +
  • +
  • yaml_document_append_sequence_item() +: yaml.h +
  • +
  • yaml_document_delete() +: yaml.h +
  • +
  • YAML_DOCUMENT_END_EVENT +: yaml.h +
  • +
  • yaml_document_end_event_initialize() +: yaml.h +
  • +
  • YAML_DOCUMENT_END_TOKEN +: yaml.h +
  • +
  • yaml_document_get_node() +: yaml.h +
  • +
  • yaml_document_get_root_node() +: yaml.h +
  • +
  • yaml_document_initialize() +: yaml.h +
  • +
  • YAML_DOCUMENT_START_EVENT +: yaml.h +
  • +
  • yaml_document_start_event_initialize() +: yaml.h +
  • +
  • YAML_DOCUMENT_START_TOKEN +: yaml.h +
  • +
  • yaml_document_t +: yaml.h +
  • +
  • YAML_DOUBLE_QUOTED_SCALAR_STYLE +: yaml.h +
  • +
  • YAML_EMIT_BLOCK_MAPPING_FIRST_KEY_STATE +: yaml.h +
  • +
  • YAML_EMIT_BLOCK_MAPPING_KEY_STATE +: yaml.h +
  • +
  • YAML_EMIT_BLOCK_MAPPING_SIMPLE_VALUE_STATE +: yaml.h +
  • +
  • YAML_EMIT_BLOCK_MAPPING_VALUE_STATE +: yaml.h +
  • +
  • YAML_EMIT_BLOCK_SEQUENCE_FIRST_ITEM_STATE +: yaml.h +
  • +
  • YAML_EMIT_BLOCK_SEQUENCE_ITEM_STATE +: yaml.h +
  • +
  • YAML_EMIT_DOCUMENT_CONTENT_STATE +: yaml.h +
  • +
  • YAML_EMIT_DOCUMENT_END_STATE +: yaml.h +
  • +
  • YAML_EMIT_DOCUMENT_START_STATE +: yaml.h +
  • +
  • YAML_EMIT_END_STATE +: yaml.h +
  • +
  • YAML_EMIT_FIRST_DOCUMENT_START_STATE +: yaml.h +
  • +
  • YAML_EMIT_FLOW_MAPPING_FIRST_KEY_STATE +: yaml.h +
  • +
  • YAML_EMIT_FLOW_MAPPING_KEY_STATE +: yaml.h +
  • +
  • YAML_EMIT_FLOW_MAPPING_SIMPLE_VALUE_STATE +: yaml.h +
  • +
  • YAML_EMIT_FLOW_MAPPING_VALUE_STATE +: yaml.h +
  • +
  • YAML_EMIT_FLOW_SEQUENCE_FIRST_ITEM_STATE +: yaml.h +
  • +
  • YAML_EMIT_FLOW_SEQUENCE_ITEM_STATE +: yaml.h +
  • +
  • YAML_EMIT_STREAM_START_STATE +: yaml.h +
  • +
  • yaml_emitter_close() +: yaml.h +
  • +
  • yaml_emitter_delete() +: yaml.h +
  • +
  • yaml_emitter_dump() +: yaml.h +
  • +
  • yaml_emitter_emit() +: yaml.h +
  • +
  • YAML_EMITTER_ERROR +: yaml.h +
  • +
  • yaml_emitter_flush() +: yaml.h +
  • +
  • yaml_emitter_initialize() +: yaml.h +
  • +
  • yaml_emitter_open() +: yaml.h +
  • +
  • yaml_emitter_set_break() +: yaml.h +
  • +
  • yaml_emitter_set_canonical() +: yaml.h +
  • +
  • yaml_emitter_set_encoding() +: yaml.h +
  • +
  • yaml_emitter_set_indent() +: yaml.h +
  • +
  • yaml_emitter_set_output() +: yaml.h +
  • +
  • yaml_emitter_set_output_file() +: yaml.h +
  • +
  • yaml_emitter_set_output_string() +: yaml.h +
  • +
  • yaml_emitter_set_unicode() +: yaml.h +
  • +
  • yaml_emitter_set_width() +: yaml.h +
  • +
  • yaml_emitter_state_e +: yaml.h +
  • +
  • yaml_emitter_state_t +: yaml.h +
  • +
  • yaml_emitter_t +: yaml.h +
  • +
  • yaml_encoding_e +: yaml.h +
  • +
  • yaml_encoding_t +: yaml.h +
  • +
  • yaml_error_type_e +: yaml.h +
  • +
  • yaml_error_type_t +: yaml.h +
  • +
  • yaml_event_delete() +: yaml.h +
  • +
  • yaml_event_t +: yaml.h +
  • +
  • yaml_event_type_e +: yaml.h +
  • +
  • yaml_event_type_t +: yaml.h +
  • +
  • YAML_FLOAT_TAG +: yaml.h +
  • +
  • YAML_FLOW_ENTRY_TOKEN +: yaml.h +
  • +
  • YAML_FLOW_MAPPING_END_TOKEN +: yaml.h +
  • +
  • YAML_FLOW_MAPPING_START_TOKEN +: yaml.h +
  • +
  • YAML_FLOW_MAPPING_STYLE +: yaml.h +
  • +
  • YAML_FLOW_SEQUENCE_END_TOKEN +: yaml.h +
  • +
  • YAML_FLOW_SEQUENCE_START_TOKEN +: yaml.h +
  • +
  • YAML_FLOW_SEQUENCE_STYLE +: yaml.h +
  • +
  • YAML_FOLDED_SCALAR_STYLE +: yaml.h +
  • +
  • yaml_get_version() +: yaml.h +
  • +
  • yaml_get_version_string() +: yaml.h +
  • +
  • YAML_INT_TAG +: yaml.h +
  • +
  • YAML_KEY_TOKEN +: yaml.h +
  • +
  • YAML_LITERAL_SCALAR_STYLE +: yaml.h +
  • +
  • YAML_LN_BREAK +: yaml.h +
  • +
  • YAML_MAP_TAG +: yaml.h +
  • +
  • YAML_MAPPING_END_EVENT +: yaml.h +
  • +
  • yaml_mapping_end_event_initialize() +: yaml.h +
  • +
  • YAML_MAPPING_NODE +: yaml.h +
  • +
  • YAML_MAPPING_START_EVENT +: yaml.h +
  • +
  • yaml_mapping_start_event_initialize() +: yaml.h +
  • +
  • yaml_mapping_style_e +: yaml.h +
  • +
  • yaml_mapping_style_t +: yaml.h +
  • +
  • yaml_mark_t +: yaml.h +
  • +
  • YAML_MEMORY_ERROR +: yaml.h +
  • +
  • YAML_NO_ERROR +: yaml.h +
  • +
  • YAML_NO_EVENT +: yaml.h +
  • +
  • YAML_NO_NODE +: yaml.h +
  • +
  • YAML_NO_TOKEN +: yaml.h +
  • +
  • yaml_node_item_t +: yaml.h +
  • +
  • yaml_node_pair_t +: yaml.h +
  • +
  • yaml_node_t +: yaml.h +
  • +
  • yaml_node_type_e +: yaml.h +
  • +
  • yaml_node_type_t +: yaml.h +
  • +
  • YAML_NULL_TAG +: yaml.h +
  • +
  • YAML_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE +: yaml.h +
  • +
  • YAML_PARSE_BLOCK_MAPPING_KEY_STATE +: yaml.h +
  • +
  • YAML_PARSE_BLOCK_MAPPING_VALUE_STATE +: yaml.h +
  • +
  • YAML_PARSE_BLOCK_NODE_OR_INDENTLESS_SEQUENCE_STATE +: yaml.h +
  • +
  • YAML_PARSE_BLOCK_NODE_STATE +: yaml.h +
  • +
  • YAML_PARSE_BLOCK_SEQUENCE_ENTRY_STATE +: yaml.h +
  • +
  • YAML_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE +: yaml.h +
  • +
  • YAML_PARSE_DOCUMENT_CONTENT_STATE +: yaml.h +
  • +
  • YAML_PARSE_DOCUMENT_END_STATE +: yaml.h +
  • +
  • YAML_PARSE_DOCUMENT_START_STATE +: yaml.h +
  • +
  • YAML_PARSE_END_STATE +: yaml.h +
  • +
  • YAML_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE +: yaml.h +
  • +
  • YAML_PARSE_FLOW_MAPPING_FIRST_KEY_STATE +: yaml.h +
  • +
  • YAML_PARSE_FLOW_MAPPING_KEY_STATE +: yaml.h +
  • +
  • YAML_PARSE_FLOW_MAPPING_VALUE_STATE +: yaml.h +
  • +
  • YAML_PARSE_FLOW_NODE_STATE +: yaml.h +
  • +
  • YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE +: yaml.h +
  • +
  • YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE +: yaml.h +
  • +
  • YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE +: yaml.h +
  • +
  • YAML_PARSE_FLOW_SEQUENCE_ENTRY_STATE +: yaml.h +
  • +
  • YAML_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE +: yaml.h +
  • +
  • YAML_PARSE_IMPLICIT_DOCUMENT_START_STATE +: yaml.h +
  • +
  • YAML_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE +: yaml.h +
  • +
  • YAML_PARSE_STREAM_START_STATE +: yaml.h +
  • +
  • yaml_parser_delete() +: yaml.h +
  • +
  • YAML_PARSER_ERROR +: yaml.h +
  • +
  • yaml_parser_initialize() +: yaml.h +
  • +
  • yaml_parser_load() +: yaml.h +
  • +
  • yaml_parser_parse() +: yaml.h +
  • +
  • yaml_parser_scan() +: yaml.h +
  • +
  • yaml_parser_set_encoding() +: yaml.h +
  • +
  • yaml_parser_set_input() +: yaml.h +
  • +
  • yaml_parser_set_input_file() +: yaml.h +
  • +
  • yaml_parser_set_input_string() +: yaml.h +
  • +
  • yaml_parser_state_e +: yaml.h +
  • +
  • yaml_parser_state_t +: yaml.h +
  • +
  • yaml_parser_t +: yaml.h +
  • +
  • YAML_PLAIN_SCALAR_STYLE +: yaml.h +
  • +
  • yaml_read_handler_t +: yaml.h +
  • +
  • YAML_READER_ERROR +: yaml.h +
  • +
  • YAML_SCALAR_EVENT +: yaml.h +
  • +
  • yaml_scalar_event_initialize() +: yaml.h +
  • +
  • YAML_SCALAR_NODE +: yaml.h +
  • +
  • yaml_scalar_style_e +: yaml.h +
  • +
  • yaml_scalar_style_t +: yaml.h +
  • +
  • YAML_SCALAR_TOKEN +: yaml.h +
  • +
  • YAML_SCANNER_ERROR +: yaml.h +
  • +
  • YAML_SEQ_TAG +: yaml.h +
  • +
  • YAML_SEQUENCE_END_EVENT +: yaml.h +
  • +
  • yaml_sequence_end_event_initialize() +: yaml.h +
  • +
  • YAML_SEQUENCE_NODE +: yaml.h +
  • +
  • YAML_SEQUENCE_START_EVENT +: yaml.h +
  • +
  • yaml_sequence_start_event_initialize() +: yaml.h +
  • +
  • yaml_sequence_style_e +: yaml.h +
  • +
  • yaml_sequence_style_t +: yaml.h +
  • +
  • yaml_simple_key_t +: yaml.h +
  • +
  • YAML_SINGLE_QUOTED_SCALAR_STYLE +: yaml.h +
  • +
  • YAML_STR_TAG +: yaml.h +
  • +
  • YAML_STREAM_END_EVENT +: yaml.h +
  • +
  • yaml_stream_end_event_initialize() +: yaml.h +
  • +
  • YAML_STREAM_END_TOKEN +: yaml.h +
  • +
  • YAML_STREAM_START_EVENT +: yaml.h +
  • +
  • yaml_stream_start_event_initialize() +: yaml.h +
  • +
  • YAML_STREAM_START_TOKEN +: yaml.h +
  • +
  • yaml_tag_directive_t +: yaml.h +
  • +
  • YAML_TAG_DIRECTIVE_TOKEN +: yaml.h +
  • +
  • YAML_TAG_TOKEN +: yaml.h +
  • +
  • YAML_TIMESTAMP_TAG +: yaml.h +
  • +
  • yaml_token_delete() +: yaml.h +
  • +
  • yaml_token_t +: yaml.h +
  • +
  • yaml_token_type_e +: yaml.h +
  • +
  • yaml_token_type_t +: yaml.h +
  • +
  • YAML_UTF16BE_ENCODING +: yaml.h +
  • +
  • YAML_UTF16LE_ENCODING +: yaml.h +
  • +
  • YAML_UTF8_ENCODING +: yaml.h +
  • +
  • YAML_VALUE_TOKEN +: yaml.h +
  • +
  • yaml_version_directive_t +: yaml.h +
  • +
  • YAML_VERSION_DIRECTIVE_TOKEN +: yaml.h +
  • +
  • yaml_write_handler_t +: yaml.h +
  • +
  • YAML_WRITER_ERROR +: yaml.h +
  • +
+
+ + + + + + diff --git a/libyaml/doc/html/globals_defs.html b/libyaml/doc/html/globals_defs.html new file mode 100644 index 00000000..84525318 --- /dev/null +++ b/libyaml/doc/html/globals_defs.html @@ -0,0 +1,113 @@ + + + + + +yaml: Globals + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.5 +
+ +
+
+ + + + + +
+
    +
  • YAML_BOOL_TAG +: yaml.h +
  • +
  • YAML_DECLARE +: yaml.h +
  • +
  • YAML_DEFAULT_MAPPING_TAG +: yaml.h +
  • +
  • YAML_DEFAULT_SCALAR_TAG +: yaml.h +
  • +
  • YAML_DEFAULT_SEQUENCE_TAG +: yaml.h +
  • +
  • YAML_FLOAT_TAG +: yaml.h +
  • +
  • YAML_INT_TAG +: yaml.h +
  • +
  • YAML_MAP_TAG +: yaml.h +
  • +
  • YAML_NULL_TAG +: yaml.h +
  • +
  • YAML_SEQ_TAG +: yaml.h +
  • +
  • YAML_STR_TAG +: yaml.h +
  • +
  • YAML_TIMESTAMP_TAG +: yaml.h +
  • +
+
+ + + + + + diff --git a/libyaml/doc/html/globals_enum.html b/libyaml/doc/html/globals_enum.html new file mode 100644 index 00000000..12ab0b53 --- /dev/null +++ b/libyaml/doc/html/globals_enum.html @@ -0,0 +1,110 @@ + + + + + +yaml: Globals + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.5 +
+ +
+
+ + + + + +
+
    +
  • yaml_break_e +: yaml.h +
  • +
  • yaml_emitter_state_e +: yaml.h +
  • +
  • yaml_encoding_e +: yaml.h +
  • +
  • yaml_error_type_e +: yaml.h +
  • +
  • yaml_event_type_e +: yaml.h +
  • +
  • yaml_mapping_style_e +: yaml.h +
  • +
  • yaml_node_type_e +: yaml.h +
  • +
  • yaml_parser_state_e +: yaml.h +
  • +
  • yaml_scalar_style_e +: yaml.h +
  • +
  • yaml_sequence_style_e +: yaml.h +
  • +
  • yaml_token_type_e +: yaml.h +
  • +
+
+ + + + + + diff --git a/libyaml/doc/html/globals_eval.html b/libyaml/doc/html/globals_eval.html new file mode 100644 index 00000000..0d4ef5e5 --- /dev/null +++ b/libyaml/doc/html/globals_eval.html @@ -0,0 +1,405 @@ + + + + + +yaml: Globals + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.5 +
+ +
+
+ + + + + + +
+
+  + +

- y -

    +
  • YAML_ALIAS_EVENT +: yaml.h +
  • +
  • YAML_ALIAS_TOKEN +: yaml.h +
  • +
  • YAML_ANCHOR_TOKEN +: yaml.h +
  • +
  • YAML_ANY_BREAK +: yaml.h +
  • +
  • YAML_ANY_ENCODING +: yaml.h +
  • +
  • YAML_ANY_MAPPING_STYLE +: yaml.h +
  • +
  • YAML_ANY_SCALAR_STYLE +: yaml.h +
  • +
  • YAML_ANY_SEQUENCE_STYLE +: yaml.h +
  • +
  • YAML_BLOCK_END_TOKEN +: yaml.h +
  • +
  • YAML_BLOCK_ENTRY_TOKEN +: yaml.h +
  • +
  • YAML_BLOCK_MAPPING_START_TOKEN +: yaml.h +
  • +
  • YAML_BLOCK_MAPPING_STYLE +: yaml.h +
  • +
  • YAML_BLOCK_SEQUENCE_START_TOKEN +: yaml.h +
  • +
  • YAML_BLOCK_SEQUENCE_STYLE +: yaml.h +
  • +
  • YAML_COMPOSER_ERROR +: yaml.h +
  • +
  • YAML_CR_BREAK +: yaml.h +
  • +
  • YAML_CRLN_BREAK +: yaml.h +
  • +
  • YAML_DOCUMENT_END_EVENT +: yaml.h +
  • +
  • YAML_DOCUMENT_END_TOKEN +: yaml.h +
  • +
  • YAML_DOCUMENT_START_EVENT +: yaml.h +
  • +
  • YAML_DOCUMENT_START_TOKEN +: yaml.h +
  • +
  • YAML_DOUBLE_QUOTED_SCALAR_STYLE +: yaml.h +
  • +
  • YAML_EMIT_BLOCK_MAPPING_FIRST_KEY_STATE +: yaml.h +
  • +
  • YAML_EMIT_BLOCK_MAPPING_KEY_STATE +: yaml.h +
  • +
  • YAML_EMIT_BLOCK_MAPPING_SIMPLE_VALUE_STATE +: yaml.h +
  • +
  • YAML_EMIT_BLOCK_MAPPING_VALUE_STATE +: yaml.h +
  • +
  • YAML_EMIT_BLOCK_SEQUENCE_FIRST_ITEM_STATE +: yaml.h +
  • +
  • YAML_EMIT_BLOCK_SEQUENCE_ITEM_STATE +: yaml.h +
  • +
  • YAML_EMIT_DOCUMENT_CONTENT_STATE +: yaml.h +
  • +
  • YAML_EMIT_DOCUMENT_END_STATE +: yaml.h +
  • +
  • YAML_EMIT_DOCUMENT_START_STATE +: yaml.h +
  • +
  • YAML_EMIT_END_STATE +: yaml.h +
  • +
  • YAML_EMIT_FIRST_DOCUMENT_START_STATE +: yaml.h +
  • +
  • YAML_EMIT_FLOW_MAPPING_FIRST_KEY_STATE +: yaml.h +
  • +
  • YAML_EMIT_FLOW_MAPPING_KEY_STATE +: yaml.h +
  • +
  • YAML_EMIT_FLOW_MAPPING_SIMPLE_VALUE_STATE +: yaml.h +
  • +
  • YAML_EMIT_FLOW_MAPPING_VALUE_STATE +: yaml.h +
  • +
  • YAML_EMIT_FLOW_SEQUENCE_FIRST_ITEM_STATE +: yaml.h +
  • +
  • YAML_EMIT_FLOW_SEQUENCE_ITEM_STATE +: yaml.h +
  • +
  • YAML_EMIT_STREAM_START_STATE +: yaml.h +
  • +
  • YAML_EMITTER_ERROR +: yaml.h +
  • +
  • YAML_FLOW_ENTRY_TOKEN +: yaml.h +
  • +
  • YAML_FLOW_MAPPING_END_TOKEN +: yaml.h +
  • +
  • YAML_FLOW_MAPPING_START_TOKEN +: yaml.h +
  • +
  • YAML_FLOW_MAPPING_STYLE +: yaml.h +
  • +
  • YAML_FLOW_SEQUENCE_END_TOKEN +: yaml.h +
  • +
  • YAML_FLOW_SEQUENCE_START_TOKEN +: yaml.h +
  • +
  • YAML_FLOW_SEQUENCE_STYLE +: yaml.h +
  • +
  • YAML_FOLDED_SCALAR_STYLE +: yaml.h +
  • +
  • YAML_KEY_TOKEN +: yaml.h +
  • +
  • YAML_LITERAL_SCALAR_STYLE +: yaml.h +
  • +
  • YAML_LN_BREAK +: yaml.h +
  • +
  • YAML_MAPPING_END_EVENT +: yaml.h +
  • +
  • YAML_MAPPING_NODE +: yaml.h +
  • +
  • YAML_MAPPING_START_EVENT +: yaml.h +
  • +
  • YAML_MEMORY_ERROR +: yaml.h +
  • +
  • YAML_NO_ERROR +: yaml.h +
  • +
  • YAML_NO_EVENT +: yaml.h +
  • +
  • YAML_NO_NODE +: yaml.h +
  • +
  • YAML_NO_TOKEN +: yaml.h +
  • +
  • YAML_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE +: yaml.h +
  • +
  • YAML_PARSE_BLOCK_MAPPING_KEY_STATE +: yaml.h +
  • +
  • YAML_PARSE_BLOCK_MAPPING_VALUE_STATE +: yaml.h +
  • +
  • YAML_PARSE_BLOCK_NODE_OR_INDENTLESS_SEQUENCE_STATE +: yaml.h +
  • +
  • YAML_PARSE_BLOCK_NODE_STATE +: yaml.h +
  • +
  • YAML_PARSE_BLOCK_SEQUENCE_ENTRY_STATE +: yaml.h +
  • +
  • YAML_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE +: yaml.h +
  • +
  • YAML_PARSE_DOCUMENT_CONTENT_STATE +: yaml.h +
  • +
  • YAML_PARSE_DOCUMENT_END_STATE +: yaml.h +
  • +
  • YAML_PARSE_DOCUMENT_START_STATE +: yaml.h +
  • +
  • YAML_PARSE_END_STATE +: yaml.h +
  • +
  • YAML_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE +: yaml.h +
  • +
  • YAML_PARSE_FLOW_MAPPING_FIRST_KEY_STATE +: yaml.h +
  • +
  • YAML_PARSE_FLOW_MAPPING_KEY_STATE +: yaml.h +
  • +
  • YAML_PARSE_FLOW_MAPPING_VALUE_STATE +: yaml.h +
  • +
  • YAML_PARSE_FLOW_NODE_STATE +: yaml.h +
  • +
  • YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE +: yaml.h +
  • +
  • YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE +: yaml.h +
  • +
  • YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE +: yaml.h +
  • +
  • YAML_PARSE_FLOW_SEQUENCE_ENTRY_STATE +: yaml.h +
  • +
  • YAML_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE +: yaml.h +
  • +
  • YAML_PARSE_IMPLICIT_DOCUMENT_START_STATE +: yaml.h +
  • +
  • YAML_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE +: yaml.h +
  • +
  • YAML_PARSE_STREAM_START_STATE +: yaml.h +
  • +
  • YAML_PARSER_ERROR +: yaml.h +
  • +
  • YAML_PLAIN_SCALAR_STYLE +: yaml.h +
  • +
  • YAML_READER_ERROR +: yaml.h +
  • +
  • YAML_SCALAR_EVENT +: yaml.h +
  • +
  • YAML_SCALAR_NODE +: yaml.h +
  • +
  • YAML_SCALAR_TOKEN +: yaml.h +
  • +
  • YAML_SCANNER_ERROR +: yaml.h +
  • +
  • YAML_SEQUENCE_END_EVENT +: yaml.h +
  • +
  • YAML_SEQUENCE_NODE +: yaml.h +
  • +
  • YAML_SEQUENCE_START_EVENT +: yaml.h +
  • +
  • YAML_SINGLE_QUOTED_SCALAR_STYLE +: yaml.h +
  • +
  • YAML_STREAM_END_EVENT +: yaml.h +
  • +
  • YAML_STREAM_END_TOKEN +: yaml.h +
  • +
  • YAML_STREAM_START_EVENT +: yaml.h +
  • +
  • YAML_STREAM_START_TOKEN +: yaml.h +
  • +
  • YAML_TAG_DIRECTIVE_TOKEN +: yaml.h +
  • +
  • YAML_TAG_TOKEN +: yaml.h +
  • +
  • YAML_UTF16BE_ENCODING +: yaml.h +
  • +
  • YAML_UTF16LE_ENCODING +: yaml.h +
  • +
  • YAML_UTF8_ENCODING +: yaml.h +
  • +
  • YAML_VALUE_TOKEN +: yaml.h +
  • +
  • YAML_VERSION_DIRECTIVE_TOKEN +: yaml.h +
  • +
  • YAML_WRITER_ERROR +: yaml.h +
  • +
+
+ + + + + + diff --git a/libyaml/doc/html/globals_func.html b/libyaml/doc/html/globals_func.html new file mode 100644 index 00000000..c9da4033 --- /dev/null +++ b/libyaml/doc/html/globals_func.html @@ -0,0 +1,228 @@ + + + + + +yaml: Globals + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.5 +
+ +
+
+ + + + + + +
+
+  + +

- y -

    +
  • yaml_alias_event_initialize() +: yaml.h +
  • +
  • yaml_document_add_mapping() +: yaml.h +
  • +
  • yaml_document_add_scalar() +: yaml.h +
  • +
  • yaml_document_add_sequence() +: yaml.h +
  • +
  • yaml_document_append_mapping_pair() +: yaml.h +
  • +
  • yaml_document_append_sequence_item() +: yaml.h +
  • +
  • yaml_document_delete() +: yaml.h +
  • +
  • yaml_document_end_event_initialize() +: yaml.h +
  • +
  • yaml_document_get_node() +: yaml.h +
  • +
  • yaml_document_get_root_node() +: yaml.h +
  • +
  • yaml_document_initialize() +: yaml.h +
  • +
  • yaml_document_start_event_initialize() +: yaml.h +
  • +
  • yaml_emitter_close() +: yaml.h +
  • +
  • yaml_emitter_delete() +: yaml.h +
  • +
  • yaml_emitter_dump() +: yaml.h +
  • +
  • yaml_emitter_emit() +: yaml.h +
  • +
  • yaml_emitter_flush() +: yaml.h +
  • +
  • yaml_emitter_initialize() +: yaml.h +
  • +
  • yaml_emitter_open() +: yaml.h +
  • +
  • yaml_emitter_set_break() +: yaml.h +
  • +
  • yaml_emitter_set_canonical() +: yaml.h +
  • +
  • yaml_emitter_set_encoding() +: yaml.h +
  • +
  • yaml_emitter_set_indent() +: yaml.h +
  • +
  • yaml_emitter_set_output() +: yaml.h +
  • +
  • yaml_emitter_set_output_file() +: yaml.h +
  • +
  • yaml_emitter_set_output_string() +: yaml.h +
  • +
  • yaml_emitter_set_unicode() +: yaml.h +
  • +
  • yaml_emitter_set_width() +: yaml.h +
  • +
  • yaml_event_delete() +: yaml.h +
  • +
  • yaml_get_version() +: yaml.h +
  • +
  • yaml_get_version_string() +: yaml.h +
  • +
  • yaml_mapping_end_event_initialize() +: yaml.h +
  • +
  • yaml_mapping_start_event_initialize() +: yaml.h +
  • +
  • yaml_parser_delete() +: yaml.h +
  • +
  • yaml_parser_initialize() +: yaml.h +
  • +
  • yaml_parser_load() +: yaml.h +
  • +
  • yaml_parser_parse() +: yaml.h +
  • +
  • yaml_parser_scan() +: yaml.h +
  • +
  • yaml_parser_set_encoding() +: yaml.h +
  • +
  • yaml_parser_set_input() +: yaml.h +
  • +
  • yaml_parser_set_input_file() +: yaml.h +
  • +
  • yaml_parser_set_input_string() +: yaml.h +
  • +
  • yaml_scalar_event_initialize() +: yaml.h +
  • +
  • yaml_sequence_end_event_initialize() +: yaml.h +
  • +
  • yaml_sequence_start_event_initialize() +: yaml.h +
  • +
  • yaml_stream_end_event_initialize() +: yaml.h +
  • +
  • yaml_stream_start_event_initialize() +: yaml.h +
  • +
  • yaml_token_delete() +: yaml.h +
  • +
+
+ + + + + + diff --git a/libyaml/doc/html/globals_type.html b/libyaml/doc/html/globals_type.html new file mode 100644 index 00000000..7e7e2a0e --- /dev/null +++ b/libyaml/doc/html/globals_type.html @@ -0,0 +1,158 @@ + + + + + +yaml: Globals + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.5 +
+ +
+
+ + + + + +
+
    +
  • yaml_alias_data_t +: yaml.h +
  • +
  • yaml_break_t +: yaml.h +
  • +
  • yaml_char_t +: yaml.h +
  • +
  • yaml_document_t +: yaml.h +
  • +
  • yaml_emitter_state_t +: yaml.h +
  • +
  • yaml_emitter_t +: yaml.h +
  • +
  • yaml_encoding_t +: yaml.h +
  • +
  • yaml_error_type_t +: yaml.h +
  • +
  • yaml_event_t +: yaml.h +
  • +
  • yaml_event_type_t +: yaml.h +
  • +
  • yaml_mapping_style_t +: yaml.h +
  • +
  • yaml_mark_t +: yaml.h +
  • +
  • yaml_node_item_t +: yaml.h +
  • +
  • yaml_node_pair_t +: yaml.h +
  • +
  • yaml_node_t +: yaml.h +
  • +
  • yaml_node_type_t +: yaml.h +
  • +
  • yaml_parser_state_t +: yaml.h +
  • +
  • yaml_parser_t +: yaml.h +
  • +
  • yaml_read_handler_t +: yaml.h +
  • +
  • yaml_scalar_style_t +: yaml.h +
  • +
  • yaml_sequence_style_t +: yaml.h +
  • +
  • yaml_simple_key_t +: yaml.h +
  • +
  • yaml_tag_directive_t +: yaml.h +
  • +
  • yaml_token_t +: yaml.h +
  • +
  • yaml_token_type_t +: yaml.h +
  • +
  • yaml_version_directive_t +: yaml.h +
  • +
  • yaml_write_handler_t +: yaml.h +
  • +
+
+ + + + + + diff --git a/libyaml/doc/html/group__basic.html b/libyaml/doc/html/group__basic.html new file mode 100644 index 00000000..f8f38106 --- /dev/null +++ b/libyaml/doc/html/group__basic.html @@ -0,0 +1,349 @@ + + + + + +yaml: Basic Types + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.5 +
+ +
+
+ + + +
+
+ +
+
Basic Types
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Data Structures

struct  yaml_version_directive_s
 The version directive data. More...
struct  yaml_tag_directive_s
 The tag directive data. More...
struct  yaml_mark_s
 The pointer position. More...

+Typedefs

typedef unsigned char yaml_char_t
 The character type (UTF-8 octet).
typedef struct
+yaml_version_directive_s 
yaml_version_directive_t
 The version directive data.
typedef struct yaml_tag_directive_s yaml_tag_directive_t
 The tag directive data.
typedef enum yaml_encoding_e yaml_encoding_t
 The stream encoding.
typedef enum yaml_break_e yaml_break_t
 Line break types.
typedef enum yaml_error_type_e yaml_error_type_t
 Many bad things could happen with the parser and emitter.
typedef struct yaml_mark_s yaml_mark_t
 The pointer position.

+Enumerations

enum  yaml_encoding_e {
+  YAML_ANY_ENCODING, +
+  YAML_UTF8_ENCODING, +
+  YAML_UTF16LE_ENCODING, +
+  YAML_UTF16BE_ENCODING +
+ }
 The stream encoding. More...
enum  yaml_break_e {
+  YAML_ANY_BREAK, +
+  YAML_CR_BREAK, +
+  YAML_LN_BREAK, +
+  YAML_CRLN_BREAK +
+ }
 Line break types. More...
enum  yaml_error_type_e {
+  YAML_NO_ERROR, +
+  YAML_MEMORY_ERROR, +
+  YAML_READER_ERROR, +
+  YAML_SCANNER_ERROR, +
+  YAML_PARSER_ERROR, +
+  YAML_COMPOSER_ERROR, +
+  YAML_WRITER_ERROR, +
+  YAML_EMITTER_ERROR +
+ }
 Many bad things could happen with the parser and emitter. More...
+

Typedef Documentation

+ +
+
+ + + + +
typedef unsigned char yaml_char_t
+
+
+ +

The character type (UTF-8 octet).

+ +
+
+ +
+ +
+ +

The version directive data.

+ +
+
+ +
+
+ + + + +
typedef struct yaml_tag_directive_s yaml_tag_directive_t
+
+
+ +

The tag directive data.

+ +
+
+ +
+
+ + + + +
typedef enum yaml_encoding_e yaml_encoding_t
+
+
+ +

The stream encoding.

+ +
+
+ +
+
+ + + + +
typedef enum yaml_break_e yaml_break_t
+
+
+ +

Line break types.

+ +
+
+ +
+
+ + + + +
typedef enum yaml_error_type_e yaml_error_type_t
+
+
+ +

Many bad things could happen with the parser and emitter.

+ +
+
+ +
+
+ + + + +
typedef struct yaml_mark_s yaml_mark_t
+
+
+ +

The pointer position.

+ +
+
+

Enumeration Type Documentation

+ +
+
+ + + + +
enum yaml_encoding_e
+
+
+ +

The stream encoding.

+
Enumerator:
+ + + + +
YAML_ANY_ENCODING  +

Let the parser choose the encoding.

+
YAML_UTF8_ENCODING  +

The default UTF-8 encoding.

+
YAML_UTF16LE_ENCODING  +

The UTF-16-LE encoding with BOM.

+
YAML_UTF16BE_ENCODING  +

The UTF-16-BE encoding with BOM.

+
+
+
+ +
+
+ +
+
+ + + + +
enum yaml_break_e
+
+
+ +

Line break types.

+
Enumerator:
+ + + + +
YAML_ANY_BREAK  +

Let the parser choose the break type.

+
YAML_CR_BREAK  +

Use CR for line breaks (Mac style).

+
YAML_LN_BREAK  +

Use LN for line breaks (Unix style).

+
YAML_CRLN_BREAK  +

Use CR LN for line breaks (DOS style).

+
+
+
+ +
+
+ +
+
+ + + + +
enum yaml_error_type_e
+
+
+ +

Many bad things could happen with the parser and emitter.

+
Enumerator:
+ + + + + + + + +
YAML_NO_ERROR  +

No error is produced.

+
YAML_MEMORY_ERROR  +

Cannot allocate or reallocate a block of memory.

+
YAML_READER_ERROR  +

Cannot read or decode the input stream.

+
YAML_SCANNER_ERROR  +

Cannot scan the input stream.

+
YAML_PARSER_ERROR  +

Cannot parse the input stream.

+
YAML_COMPOSER_ERROR  +

Cannot compose a YAML document.

+
YAML_WRITER_ERROR  +

Cannot write to the output stream.

+
YAML_EMITTER_ERROR  +

Cannot emit a YAML stream.

+
+
+
+ +
+
+
+ + + + + + diff --git a/libyaml/doc/html/group__emitter.html b/libyaml/doc/html/group__emitter.html new file mode 100644 index 00000000..162a93f1 --- /dev/null +++ b/libyaml/doc/html/group__emitter.html @@ -0,0 +1,845 @@ + + + + + +yaml: Emitter Definitions + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.5 +
+ +
+
+ + + +
+
+ +
+
Emitter Definitions
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Data Structures

struct  yaml_emitter_s
 The emitter structure. More...

+Typedefs

typedef int yaml_write_handler_t (void *data, unsigned char *buffer, size_t size)
 The prototype of a write handler.
typedef enum yaml_emitter_state_e yaml_emitter_state_t
 The emitter states.
typedef struct yaml_emitter_s yaml_emitter_t
 The emitter structure.

+Enumerations

enum  yaml_emitter_state_e {
+  YAML_EMIT_STREAM_START_STATE, +
+  YAML_EMIT_FIRST_DOCUMENT_START_STATE, +
+  YAML_EMIT_DOCUMENT_START_STATE, +
+  YAML_EMIT_DOCUMENT_CONTENT_STATE, +
+  YAML_EMIT_DOCUMENT_END_STATE, +
+  YAML_EMIT_FLOW_SEQUENCE_FIRST_ITEM_STATE, +
+  YAML_EMIT_FLOW_SEQUENCE_ITEM_STATE, +
+  YAML_EMIT_FLOW_MAPPING_FIRST_KEY_STATE, +
+  YAML_EMIT_FLOW_MAPPING_KEY_STATE, +
+  YAML_EMIT_FLOW_MAPPING_SIMPLE_VALUE_STATE, +
+  YAML_EMIT_FLOW_MAPPING_VALUE_STATE, +
+  YAML_EMIT_BLOCK_SEQUENCE_FIRST_ITEM_STATE, +
+  YAML_EMIT_BLOCK_SEQUENCE_ITEM_STATE, +
+  YAML_EMIT_BLOCK_MAPPING_FIRST_KEY_STATE, +
+  YAML_EMIT_BLOCK_MAPPING_KEY_STATE, +
+  YAML_EMIT_BLOCK_MAPPING_SIMPLE_VALUE_STATE, +
+  YAML_EMIT_BLOCK_MAPPING_VALUE_STATE, +
+  YAML_EMIT_END_STATE +
+ }
 The emitter states. More...

+Functions

int yaml_emitter_initialize (yaml_emitter_t *emitter)
 Initialize an emitter.
void yaml_emitter_delete (yaml_emitter_t *emitter)
 Destroy an emitter.
void yaml_emitter_set_output_string (yaml_emitter_t *emitter, unsigned char *output, size_t size, size_t *size_written)
 Set a string output.
void yaml_emitter_set_output_file (yaml_emitter_t *emitter, FILE *file)
 Set a file output.
void yaml_emitter_set_output (yaml_emitter_t *emitter, yaml_write_handler_t *handler, void *data)
 Set a generic output handler.
void yaml_emitter_set_encoding (yaml_emitter_t *emitter, yaml_encoding_t encoding)
 Set the output encoding.
void yaml_emitter_set_canonical (yaml_emitter_t *emitter, int canonical)
 Set if the output should be in the "canonical" format as in the YAML specification.
void yaml_emitter_set_indent (yaml_emitter_t *emitter, int indent)
 Set the intendation increment.
void yaml_emitter_set_width (yaml_emitter_t *emitter, int width)
 Set the preferred line width.
void yaml_emitter_set_unicode (yaml_emitter_t *emitter, int unicode)
 Set if unescaped non-ASCII characters are allowed.
void yaml_emitter_set_break (yaml_emitter_t *emitter, yaml_break_t line_break)
 Set the preferred line break.
int yaml_emitter_emit (yaml_emitter_t *emitter, yaml_event_t *event)
 Emit an event.
int yaml_emitter_open (yaml_emitter_t *emitter)
 Start a YAML stream.
int yaml_emitter_close (yaml_emitter_t *emitter)
 Finish a YAML stream.
int yaml_emitter_dump (yaml_emitter_t *emitter, yaml_document_t *document)
 Emit a YAML document.
int yaml_emitter_flush (yaml_emitter_t *emitter)
 Flush the accumulated characters to the output.
+

Typedef Documentation

+ +
+
+ + + + +
typedef int yaml_write_handler_t(void *data, unsigned char *buffer, size_t size)
+
+
+ +

The prototype of a write handler.

+

The write handler is called when the emitter needs to flush the accumulated characters to the output. The handler should write size bytes of the buffer to the output.

+
Parameters:
+ + + + +
[in,out]dataA pointer to an application data specified by yaml_emitter_set_output().
[in]bufferThe buffer with bytes to be written.
[in]sizeThe size of the buffer.
+
+
+
Returns:
On success, the handler should return 1. If the handler failed, the returned value should be 0.
+ +
+
+ +
+
+ + + + +
typedef enum yaml_emitter_state_e yaml_emitter_state_t
+
+
+ +

The emitter states.

+ +
+
+ +
+
+ + + + +
typedef struct yaml_emitter_s yaml_emitter_t
+
+
+ +

The emitter structure.

+

All members are internal. Manage the structure using the yaml_emitter_ family of functions.

+ +
+
+

Enumeration Type Documentation

+ +
+
+ + + + +
enum yaml_emitter_state_e
+
+
+ +

The emitter states.

+
Enumerator:
+ + + + + + + + + + + + + + + + + + +
YAML_EMIT_STREAM_START_STATE  +

Expect STREAM-START.

+
YAML_EMIT_FIRST_DOCUMENT_START_STATE  +

Expect the first DOCUMENT-START or STREAM-END.

+
YAML_EMIT_DOCUMENT_START_STATE  +

Expect DOCUMENT-START or STREAM-END.

+
YAML_EMIT_DOCUMENT_CONTENT_STATE  +

Expect the content of a document.

+
YAML_EMIT_DOCUMENT_END_STATE  +

Expect DOCUMENT-END.

+
YAML_EMIT_FLOW_SEQUENCE_FIRST_ITEM_STATE  +

Expect the first item of a flow sequence.

+
YAML_EMIT_FLOW_SEQUENCE_ITEM_STATE  +

Expect an item of a flow sequence.

+
YAML_EMIT_FLOW_MAPPING_FIRST_KEY_STATE  +

Expect the first key of a flow mapping.

+
YAML_EMIT_FLOW_MAPPING_KEY_STATE  +

Expect a key of a flow mapping.

+
YAML_EMIT_FLOW_MAPPING_SIMPLE_VALUE_STATE  +

Expect a value for a simple key of a flow mapping.

+
YAML_EMIT_FLOW_MAPPING_VALUE_STATE  +

Expect a value of a flow mapping.

+
YAML_EMIT_BLOCK_SEQUENCE_FIRST_ITEM_STATE  +

Expect the first item of a block sequence.

+
YAML_EMIT_BLOCK_SEQUENCE_ITEM_STATE  +

Expect an item of a block sequence.

+
YAML_EMIT_BLOCK_MAPPING_FIRST_KEY_STATE  +

Expect the first key of a block mapping.

+
YAML_EMIT_BLOCK_MAPPING_KEY_STATE  +

Expect the key of a block mapping.

+
YAML_EMIT_BLOCK_MAPPING_SIMPLE_VALUE_STATE  +

Expect a value for a simple key of a block mapping.

+
YAML_EMIT_BLOCK_MAPPING_VALUE_STATE  +

Expect a value of a block mapping.

+
YAML_EMIT_END_STATE  +

Expect nothing.

+
+
+
+ +
+
+

Function Documentation

+ +
+
+ + + + + + + + +
int yaml_emitter_initialize (yaml_emitter_temitter)
+
+
+ +

Initialize an emitter.

+

This function creates a new emitter object. An application is responsible for destroying the object using the yaml_emitter_delete() function.

+
Parameters:
+ + +
[out]emitterAn empty parser object.
+
+
+
Returns:
1 if the function succeeded, 0 on error.
+ +
+
+ +
+
+ + + + + + + + +
void yaml_emitter_delete (yaml_emitter_temitter)
+
+
+ +

Destroy an emitter.

+
Parameters:
+ + +
[in,out]emitterAn emitter object.
+
+
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
void yaml_emitter_set_output_string (yaml_emitter_temitter,
unsigned char * output,
size_t size,
size_t * size_written 
)
+
+
+ +

Set a string output.

+

The emitter will write the output characters to the output buffer of the size size. The emitter will set size_written to the number of written bytes. If the buffer is smaller than required, the emitter produces the YAML_WRITE_ERROR error.

+
Parameters:
+ + + + + +
[in,out]emitterAn emitter object.
[in]outputAn output buffer.
[in]sizeThe buffer size.
[in]size_writtenThe pointer to save the number of written bytes.
+
+
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
void yaml_emitter_set_output_file (yaml_emitter_temitter,
FILE * file 
)
+
+
+ +

Set a file output.

+

file should be a file object open for writing. The application is responsible for closing the file.

+
Parameters:
+ + + +
[in,out]emitterAn emitter object.
[in]fileAn open file.
+
+
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void yaml_emitter_set_output (yaml_emitter_temitter,
yaml_write_handler_thandler,
void * data 
)
+
+
+ +

Set a generic output handler.

+
Parameters:
+ + + + +
[in,out]emitterAn emitter object.
[in]handlerA write handler.
[in]dataAny application data for passing to the write handler.
+
+
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
void yaml_emitter_set_encoding (yaml_emitter_temitter,
yaml_encoding_t encoding 
)
+
+
+ +

Set the output encoding.

+
Parameters:
+ + + +
[in,out]emitterAn emitter object.
[in]encodingThe output encoding.
+
+
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
void yaml_emitter_set_canonical (yaml_emitter_temitter,
int canonical 
)
+
+
+ +

Set if the output should be in the "canonical" format as in the YAML specification.

+
Parameters:
+ + + +
[in,out]emitterAn emitter object.
[in]canonicalIf the output is canonical.
+
+
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
void yaml_emitter_set_indent (yaml_emitter_temitter,
int indent 
)
+
+
+ +

Set the intendation increment.

+
Parameters:
+ + + +
[in,out]emitterAn emitter object.
[in]indentThe indentation increment (1 < . < 10).
+
+
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
void yaml_emitter_set_width (yaml_emitter_temitter,
int width 
)
+
+
+ +

Set the preferred line width.

+

-1 means unlimited.

+
Parameters:
+ + + +
[in,out]emitterAn emitter object.
[in]widthThe preferred line width.
+
+
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
void yaml_emitter_set_unicode (yaml_emitter_temitter,
int unicode 
)
+
+
+ +

Set if unescaped non-ASCII characters are allowed.

+
Parameters:
+ + + +
[in,out]emitterAn emitter object.
[in]unicodeIf unescaped Unicode characters are allowed.
+
+
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
void yaml_emitter_set_break (yaml_emitter_temitter,
yaml_break_t line_break 
)
+
+
+ +

Set the preferred line break.

+
Parameters:
+ + + +
[in,out]emitterAn emitter object.
[in]line_breakThe preferred line break.
+
+
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
int yaml_emitter_emit (yaml_emitter_temitter,
yaml_event_tevent 
)
+
+
+ +

Emit an event.

+

The event object may be generated using the yaml_parser_parse() function. The emitter takes the responsibility for the event object and destroys its content after it is emitted. The event object is destroyed even if the function fails.

+
Parameters:
+ + + +
[in,out]emitterAn emitter object.
[in,out]eventAn event object.
+
+
+
Returns:
1 if the function succeeded, 0 on error.
+ +
+
+ +
+
+ + + + + + + + +
int yaml_emitter_open (yaml_emitter_temitter)
+
+
+ +

Start a YAML stream.

+

This function should be used before yaml_emitter_dump() is called.

+
Parameters:
+ + +
[in,out]emitterAn emitter object.
+
+
+
Returns:
1 if the function succeeded, 0 on error.
+ +
+
+ +
+
+ + + + + + + + +
int yaml_emitter_close (yaml_emitter_temitter)
+
+
+ +

Finish a YAML stream.

+

This function should be used after yaml_emitter_dump() is called.

+
Parameters:
+ + +
[in,out]emitterAn emitter object.
+
+
+
Returns:
1 if the function succeeded, 0 on error.
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
int yaml_emitter_dump (yaml_emitter_temitter,
yaml_document_tdocument 
)
+
+
+ +

Emit a YAML document.

+

The documen object may be generated using the yaml_parser_load() function or the yaml_document_initialize() function. The emitter takes the responsibility for the document object and destoys its content after it is emitted. The document object is destroyedeven if the function fails.

+
Parameters:
+ + + +
[in,out]emitterAn emitter object.
[in,out]documentA document object.
+
+
+
Returns:
1 if the function succeeded, 0 on error.
+ +
+
+ +
+
+ + + + + + + + +
int yaml_emitter_flush (yaml_emitter_temitter)
+
+
+ +

Flush the accumulated characters to the output.

+
Parameters:
+ + +
[in,out]emitterAn emitter object.
+
+
+
Returns:
1 if the function succeeded, 0 on error.
+ +
+
+
+ + + + + + diff --git a/libyaml/doc/html/group__events.html b/libyaml/doc/html/group__events.html new file mode 100644 index 00000000..1d10630f --- /dev/null +++ b/libyaml/doc/html/group__events.html @@ -0,0 +1,691 @@ + + + + + +yaml: Events + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.5 +
+ +
+
+ + + +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Data Structures

struct  yaml_event_s
 The event structure. More...

+Typedefs

typedef enum yaml_event_type_e yaml_event_type_t
 Event types.
typedef struct yaml_event_s yaml_event_t
 The event structure.

+Enumerations

enum  yaml_event_type_e {
+  YAML_NO_EVENT, +
+  YAML_STREAM_START_EVENT, +
+  YAML_STREAM_END_EVENT, +
+  YAML_DOCUMENT_START_EVENT, +
+  YAML_DOCUMENT_END_EVENT, +
+  YAML_ALIAS_EVENT, +
+  YAML_SCALAR_EVENT, +
+  YAML_SEQUENCE_START_EVENT, +
+  YAML_SEQUENCE_END_EVENT, +
+  YAML_MAPPING_START_EVENT, +
+  YAML_MAPPING_END_EVENT +
+ }
 Event types. More...

+Functions

int yaml_stream_start_event_initialize (yaml_event_t *event, yaml_encoding_t encoding)
 Create the STREAM-START event.
int yaml_stream_end_event_initialize (yaml_event_t *event)
 Create the STREAM-END event.
int yaml_document_start_event_initialize (yaml_event_t *event, yaml_version_directive_t *version_directive, yaml_tag_directive_t *tag_directives_start, yaml_tag_directive_t *tag_directives_end, int implicit)
 Create the DOCUMENT-START event.
int yaml_document_end_event_initialize (yaml_event_t *event, int implicit)
 Create the DOCUMENT-END event.
int yaml_alias_event_initialize (yaml_event_t *event, yaml_char_t *anchor)
 Create an ALIAS event.
int yaml_scalar_event_initialize (yaml_event_t *event, yaml_char_t *anchor, yaml_char_t *tag, yaml_char_t *value, int length, int plain_implicit, int quoted_implicit, yaml_scalar_style_t style)
 Create a SCALAR event.
int yaml_sequence_start_event_initialize (yaml_event_t *event, yaml_char_t *anchor, yaml_char_t *tag, int implicit, yaml_sequence_style_t style)
 Create a SEQUENCE-START event.
int yaml_sequence_end_event_initialize (yaml_event_t *event)
 Create a SEQUENCE-END event.
int yaml_mapping_start_event_initialize (yaml_event_t *event, yaml_char_t *anchor, yaml_char_t *tag, int implicit, yaml_mapping_style_t style)
 Create a MAPPING-START event.
int yaml_mapping_end_event_initialize (yaml_event_t *event)
 Create a MAPPING-END event.
void yaml_event_delete (yaml_event_t *event)
 Free any memory allocated for an event object.
+

Typedef Documentation

+ +
+
+ + + + +
typedef enum yaml_event_type_e yaml_event_type_t
+
+
+ +

Event types.

+ +
+
+ +
+
+ + + + +
typedef struct yaml_event_s yaml_event_t
+
+
+ +

The event structure.

+ +
+
+

Enumeration Type Documentation

+ +
+
+ + + + +
enum yaml_event_type_e
+
+
+ +

Event types.

+
Enumerator:
+ + + + + + + + + + + +
YAML_NO_EVENT  +

An empty event.

+
YAML_STREAM_START_EVENT  +

A STREAM-START event.

+
YAML_STREAM_END_EVENT  +

A STREAM-END event.

+
YAML_DOCUMENT_START_EVENT  +

A DOCUMENT-START event.

+
YAML_DOCUMENT_END_EVENT  +

A DOCUMENT-END event.

+
YAML_ALIAS_EVENT  +

An ALIAS event.

+
YAML_SCALAR_EVENT  +

A SCALAR event.

+
YAML_SEQUENCE_START_EVENT  +

A SEQUENCE-START event.

+
YAML_SEQUENCE_END_EVENT  +

A SEQUENCE-END event.

+
YAML_MAPPING_START_EVENT  +

A MAPPING-START event.

+
YAML_MAPPING_END_EVENT  +

A MAPPING-END event.

+
+
+
+ +
+
+

Function Documentation

+ +
+
+ + + + + + + + + + + + + + + + + + +
int yaml_stream_start_event_initialize (yaml_event_tevent,
yaml_encoding_t encoding 
)
+
+
+ +

Create the STREAM-START event.

+
Parameters:
+ + + +
[out]eventAn empty event object.
[in]encodingThe stream encoding.
+
+
+
Returns:
1 if the function succeeded, 0 on error.
+ +
+
+ +
+
+ + + + + + + + +
int yaml_stream_end_event_initialize (yaml_event_tevent)
+
+
+ +

Create the STREAM-END event.

+
Parameters:
+ + +
[out]eventAn empty event object.
+
+
+
Returns:
1 if the function succeeded, 0 on error.
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
int yaml_document_start_event_initialize (yaml_event_tevent,
yaml_version_directive_tversion_directive,
yaml_tag_directive_ttag_directives_start,
yaml_tag_directive_ttag_directives_end,
int implicit 
)
+
+
+ +

Create the DOCUMENT-START event.

+

The implicit argument is considered as a stylistic parameter and may be ignored by the emitter.

+
Parameters:
+ + + + + + +
[out]eventAn empty event object.
[in]version_directiveThe YAML directive value or NULL.
[in]tag_directives_startThe beginning of the TAG directives list.
[in]tag_directives_endThe end of the TAG directives list.
[in]implicitIf the document start indicator is implicit.
+
+
+
Returns:
1 if the function succeeded, 0 on error.
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
int yaml_document_end_event_initialize (yaml_event_tevent,
int implicit 
)
+
+
+ +

Create the DOCUMENT-END event.

+

The implicit argument is considered as a stylistic parameter and may be ignored by the emitter.

+
Parameters:
+ + + +
[out]eventAn empty event object.
[in]implicitIf the document end indicator is implicit.
+
+
+
Returns:
1 if the function succeeded, 0 on error.
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
int yaml_alias_event_initialize (yaml_event_tevent,
yaml_char_tanchor 
)
+
+
+ +

Create an ALIAS event.

+
Parameters:
+ + + +
[out]eventAn empty event object.
[in]anchorThe anchor value.
+
+
+
Returns:
1 if the function succeeded, 0 on error.
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
int yaml_scalar_event_initialize (yaml_event_tevent,
yaml_char_tanchor,
yaml_char_ttag,
yaml_char_tvalue,
int length,
int plain_implicit,
int quoted_implicit,
yaml_scalar_style_t style 
)
+
+
+ +

Create a SCALAR event.

+

The style argument may be ignored by the emitter.

+

Either the tag attribute or one of the plain_implicit and quoted_implicit flags must be set.

+
Parameters:
+ + + + + + + + + +
[out]eventAn empty event object.
[in]anchorThe scalar anchor or NULL.
[in]tagThe scalar tag or NULL.
[in]valueThe scalar value.
[in]lengthThe length of the scalar value.
[in]plain_implicitIf the tag may be omitted for the plain style.
[in]quoted_implicitIf the tag may be omitted for any non-plain style.
[in]styleThe scalar style.
+
+
+
Returns:
1 if the function succeeded, 0 on error.
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
int yaml_sequence_start_event_initialize (yaml_event_tevent,
yaml_char_tanchor,
yaml_char_ttag,
int implicit,
yaml_sequence_style_t style 
)
+
+
+ +

Create a SEQUENCE-START event.

+

The style argument may be ignored by the emitter.

+

Either the tag attribute or the implicit flag must be set.

+
Parameters:
+ + + + + + +
[out]eventAn empty event object.
[in]anchorThe sequence anchor or NULL.
[in]tagThe sequence tag or NULL.
[in]implicitIf the tag may be omitted.
[in]styleThe sequence style.
+
+
+
Returns:
1 if the function succeeded, 0 on error.
+ +
+
+ +
+
+ + + + + + + + +
int yaml_sequence_end_event_initialize (yaml_event_tevent)
+
+
+ +

Create a SEQUENCE-END event.

+
Parameters:
+ + +
[out]eventAn empty event object.
+
+
+
Returns:
1 if the function succeeded, 0 on error.
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
int yaml_mapping_start_event_initialize (yaml_event_tevent,
yaml_char_tanchor,
yaml_char_ttag,
int implicit,
yaml_mapping_style_t style 
)
+
+
+ +

Create a MAPPING-START event.

+

The style argument may be ignored by the emitter.

+

Either the tag attribute or the implicit flag must be set.

+
Parameters:
+ + + + + + +
[out]eventAn empty event object.
[in]anchorThe mapping anchor or NULL.
[in]tagThe mapping tag or NULL.
[in]implicitIf the tag may be omitted.
[in]styleThe mapping style.
+
+
+
Returns:
1 if the function succeeded, 0 on error.
+ +
+
+ +
+
+ + + + + + + + +
int yaml_mapping_end_event_initialize (yaml_event_tevent)
+
+
+ +

Create a MAPPING-END event.

+
Parameters:
+ + +
[out]eventAn empty event object.
+
+
+
Returns:
1 if the function succeeded, 0 on error.
+ +
+
+ +
+
+ + + + + + + + +
void yaml_event_delete (yaml_event_tevent)
+
+
+ +

Free any memory allocated for an event object.

+
Parameters:
+ + +
[in,out]eventAn event object.
+
+
+ +
+
+
+ + + + + + diff --git a/libyaml/doc/html/group__export.html b/libyaml/doc/html/group__export.html new file mode 100644 index 00000000..9f4a9871 --- /dev/null +++ b/libyaml/doc/html/group__export.html @@ -0,0 +1,91 @@ + + + + + +yaml: Export Definitions + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.5 +
+ +
+
+ + + +
+
+ +
+
Export Definitions
+
+
+ + + + +

+Defines

#define YAML_DECLARE(type)   type
 The public API declaration.
+

Define Documentation

+ +
+
+ + + + + + + + +
#define YAML_DECLARE( type)   type
+
+
+ +

The public API declaration.

+ +
+
+
+ + + + + + diff --git a/libyaml/doc/html/group__nodes.html b/libyaml/doc/html/group__nodes.html new file mode 100644 index 00000000..b7294714 --- /dev/null +++ b/libyaml/doc/html/group__nodes.html @@ -0,0 +1,824 @@ + + + + + +yaml: Nodes + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.5 +
+ +
+
+ + + +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Data Structures

struct  yaml_node_pair_s
 An element of a mapping node. More...
struct  yaml_node_s
 The node structure. More...
struct  yaml_document_s
 The document structure. More...

+Defines

#define YAML_NULL_TAG   "tag:yaml.org,2002:null"
 The tag !!null with the only possible value: null.
#define YAML_BOOL_TAG   "tag:yaml.org,2002:bool"
 The tag !!bool with the values: true and falce.
#define YAML_STR_TAG   "tag:yaml.org,2002:str"
 The tag !!str for string values.
#define YAML_INT_TAG   "tag:yaml.org,2002:int"
 The tag !!int for integer values.
#define YAML_FLOAT_TAG   "tag:yaml.org,2002:float"
 The tag !!float for float values.
#define YAML_TIMESTAMP_TAG   "tag:yaml.org,2002:timestamp"
 The tag !!timestamp for date and time values.
#define YAML_SEQ_TAG   "tag:yaml.org,2002:seq"
 The tag !!seq is used to denote sequences.
#define YAML_MAP_TAG   "tag:yaml.org,2002:map"
 The tag !!map is used to denote mapping.
#define YAML_DEFAULT_SCALAR_TAG   YAML_STR_TAG
 The default scalar tag is !!str.
#define YAML_DEFAULT_SEQUENCE_TAG   YAML_SEQ_TAG
 The default sequence tag is !!seq.
#define YAML_DEFAULT_MAPPING_TAG   YAML_MAP_TAG
 The default mapping tag is !!map.

+Typedefs

typedef enum yaml_node_type_e yaml_node_type_t
 Node types.
typedef struct yaml_node_s yaml_node_t
 The forward definition of a document node structure.
typedef int yaml_node_item_t
 An element of a sequence node.
typedef struct yaml_node_pair_s yaml_node_pair_t
 An element of a mapping node.
typedef struct yaml_document_s yaml_document_t
 The document structure.

+Enumerations

enum  yaml_node_type_e {
+  YAML_NO_NODE, +
+  YAML_SCALAR_NODE, +
+  YAML_SEQUENCE_NODE, +
+  YAML_MAPPING_NODE +
+ }
 Node types. More...

+Functions

int yaml_document_initialize (yaml_document_t *document, yaml_version_directive_t *version_directive, yaml_tag_directive_t *tag_directives_start, yaml_tag_directive_t *tag_directives_end, int start_implicit, int end_implicit)
 Create a YAML document.
void yaml_document_delete (yaml_document_t *document)
 Delete a YAML document and all its nodes.
yaml_node_tyaml_document_get_node (yaml_document_t *document, int index)
 Get a node of a YAML document.
yaml_node_tyaml_document_get_root_node (yaml_document_t *document)
 Get the root of a YAML document node.
int yaml_document_add_scalar (yaml_document_t *document, yaml_char_t *tag, yaml_char_t *value, int length, yaml_scalar_style_t style)
 Create a SCALAR node and attach it to the document.
int yaml_document_add_sequence (yaml_document_t *document, yaml_char_t *tag, yaml_sequence_style_t style)
 Create a SEQUENCE node and attach it to the document.
int yaml_document_add_mapping (yaml_document_t *document, yaml_char_t *tag, yaml_mapping_style_t style)
 Create a MAPPING node and attach it to the document.
int yaml_document_append_sequence_item (yaml_document_t *document, int sequence, int item)
 Add an item to a SEQUENCE node.
int yaml_document_append_mapping_pair (yaml_document_t *document, int mapping, int key, int value)
 Add a pair of a key and a value to a MAPPING node.
+

Define Documentation

+ +
+
+ + + + +
#define YAML_NULL_TAG   "tag:yaml.org,2002:null"
+
+
+ +

The tag !!null with the only possible value: null.

+ +
+
+ +
+
+ + + + +
#define YAML_BOOL_TAG   "tag:yaml.org,2002:bool"
+
+
+ +

The tag !!bool with the values: true and falce.

+ +
+
+ +
+
+ + + + +
#define YAML_STR_TAG   "tag:yaml.org,2002:str"
+
+
+ +

The tag !!str for string values.

+ +
+
+ +
+
+ + + + +
#define YAML_INT_TAG   "tag:yaml.org,2002:int"
+
+
+ +

The tag !!int for integer values.

+ +
+
+ +
+
+ + + + +
#define YAML_FLOAT_TAG   "tag:yaml.org,2002:float"
+
+
+ +

The tag !!float for float values.

+ +
+
+ +
+
+ + + + +
#define YAML_TIMESTAMP_TAG   "tag:yaml.org,2002:timestamp"
+
+
+ +

The tag !!timestamp for date and time values.

+ +
+
+ +
+
+ + + + +
#define YAML_SEQ_TAG   "tag:yaml.org,2002:seq"
+
+
+ +

The tag !!seq is used to denote sequences.

+ +
+
+ +
+
+ + + + +
#define YAML_MAP_TAG   "tag:yaml.org,2002:map"
+
+
+ +

The tag !!map is used to denote mapping.

+ +
+
+ +
+
+ + + + +
#define YAML_DEFAULT_SCALAR_TAG   YAML_STR_TAG
+
+
+ +

The default scalar tag is !!str.

+ +
+
+ +
+
+ + + + +
#define YAML_DEFAULT_SEQUENCE_TAG   YAML_SEQ_TAG
+
+
+ +

The default sequence tag is !!seq.

+ +
+
+ +
+
+ + + + +
#define YAML_DEFAULT_MAPPING_TAG   YAML_MAP_TAG
+
+
+ +

The default mapping tag is !!map.

+ +
+
+

Typedef Documentation

+ +
+
+ + + + +
typedef enum yaml_node_type_e yaml_node_type_t
+
+
+ +

Node types.

+ +
+
+ +
+
+ + + + +
typedef struct yaml_node_s yaml_node_t
+
+
+ +

The forward definition of a document node structure.

+ +
+
+ +
+
+ + + + +
typedef int yaml_node_item_t
+
+
+ +

An element of a sequence node.

+ +
+
+ +
+
+ + + + +
typedef struct yaml_node_pair_s yaml_node_pair_t
+
+
+ +

An element of a mapping node.

+ +
+
+ +
+
+ + + + +
typedef struct yaml_document_s yaml_document_t
+
+
+ +

The document structure.

+ +
+
+

Enumeration Type Documentation

+ +
+
+ + + + +
enum yaml_node_type_e
+
+
+ +

Node types.

+
Enumerator:
+ + + + +
YAML_NO_NODE  +

An empty node.

+
YAML_SCALAR_NODE  +

A scalar node.

+
YAML_SEQUENCE_NODE  +

A sequence node.

+
YAML_MAPPING_NODE  +

A mapping node.

+
+
+
+ +
+
+

Function Documentation

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
int yaml_document_initialize (yaml_document_tdocument,
yaml_version_directive_tversion_directive,
yaml_tag_directive_ttag_directives_start,
yaml_tag_directive_ttag_directives_end,
int start_implicit,
int end_implicit 
)
+
+
+ +

Create a YAML document.

+
Parameters:
+ + + + + + + +
[out]documentAn empty document object.
[in]version_directiveThe YAML directive value or NULL.
[in]tag_directives_startThe beginning of the TAG directives list.
[in]tag_directives_endThe end of the TAG directives list.
[in]start_implicitIf the document start indicator is implicit.
[in]end_implicitIf the document end indicator is implicit.
+
+
+
Returns:
1 if the function succeeded, 0 on error.
+ +
+
+ +
+
+ + + + + + + + +
void yaml_document_delete (yaml_document_tdocument)
+
+
+ +

Delete a YAML document and all its nodes.

+
Parameters:
+ + +
[in,out]documentA document object.
+
+
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
yaml_node_t* yaml_document_get_node (yaml_document_tdocument,
int index 
)
+
+
+ +

Get a node of a YAML document.

+

The pointer returned by this function is valid until any of the functions modifying the documents are called.

+
Parameters:
+ + + +
[in]documentA document object.
[in]indexThe node id.
+
+
+
Returns:
the node objct or NULL if node_id is out of range.
+ +
+
+ +
+
+ + + + + + + + +
yaml_node_t* yaml_document_get_root_node (yaml_document_tdocument)
+
+
+ +

Get the root of a YAML document node.

+

The root object is the first object added to the document.

+

The pointer returned by this function is valid until any of the functions modifying the documents are called.

+

An empty document produced by the parser signifies the end of a YAML stream.

+
Parameters:
+ + +
[in]documentA document object.
+
+
+
Returns:
the node object or NULL if the document is empty.
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
int yaml_document_add_scalar (yaml_document_tdocument,
yaml_char_ttag,
yaml_char_tvalue,
int length,
yaml_scalar_style_t style 
)
+
+
+ +

Create a SCALAR node and attach it to the document.

+

The style argument may be ignored by the emitter.

+
Parameters:
+ + + + + + +
[in,out]documentA document object.
[in]tagThe scalar tag.
[in]valueThe scalar value.
[in]lengthThe length of the scalar value.
[in]styleThe scalar style.
+
+
+
Returns:
the node id or 0 on error.
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
int yaml_document_add_sequence (yaml_document_tdocument,
yaml_char_ttag,
yaml_sequence_style_t style 
)
+
+
+ +

Create a SEQUENCE node and attach it to the document.

+

The style argument may be ignored by the emitter.

+
Parameters:
+ + + + +
[in,out]documentA document object.
[in]tagThe sequence tag.
[in]styleThe sequence style.
+
+
+
Returns:
the node id or 0 on error.
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
int yaml_document_add_mapping (yaml_document_tdocument,
yaml_char_ttag,
yaml_mapping_style_t style 
)
+
+
+ +

Create a MAPPING node and attach it to the document.

+

The style argument may be ignored by the emitter.

+
Parameters:
+ + + + +
[in,out]documentA document object.
[in]tagThe sequence tag.
[in]styleThe sequence style.
+
+
+
Returns:
the node id or 0 on error.
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
int yaml_document_append_sequence_item (yaml_document_tdocument,
int sequence,
int item 
)
+
+
+ +

Add an item to a SEQUENCE node.

+
Parameters:
+ + + + +
[in,out]documentA document object.
[in]sequenceThe sequence node id.
[in]itemThe item node id.
+
+
+
Returns:
1 if the function succeeded, 0 on error.
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
int yaml_document_append_mapping_pair (yaml_document_tdocument,
int mapping,
int key,
int value 
)
+
+
+ +

Add a pair of a key and a value to a MAPPING node.

+
Parameters:
+ + + + + +
[in,out]documentA document object.
[in]mappingThe mapping node id.
[in]keyThe key node id.
[in]valueThe value node id.
+
+
+
Returns:
1 if the function succeeded, 0 on error.
+ +
+
+
+ + + + + + diff --git a/libyaml/doc/html/group__parser.html b/libyaml/doc/html/group__parser.html new file mode 100644 index 00000000..5b1d9dec --- /dev/null +++ b/libyaml/doc/html/group__parser.html @@ -0,0 +1,635 @@ + + + + + +yaml: Parser Definitions + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.5 +
+ +
+
+ + + +
+
+ +
+
Parser Definitions
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Data Structures

struct  yaml_simple_key_s
 This structure holds information about a potential simple key. More...
struct  yaml_alias_data_s
 This structure holds aliases data. More...
struct  yaml_parser_s
 The parser structure. More...

+Typedefs

typedef int yaml_read_handler_t (void *data, unsigned char *buffer, size_t size, size_t *size_read)
 The prototype of a read handler.
+typedef struct yaml_simple_key_s yaml_simple_key_t
 This structure holds information about a potential simple key.
+typedef enum yaml_parser_state_e yaml_parser_state_t
 The states of the parser.
+typedef struct yaml_alias_data_s yaml_alias_data_t
 This structure holds aliases data.
typedef struct yaml_parser_s yaml_parser_t
 The parser structure.

+Enumerations

enum  yaml_parser_state_e {
+  YAML_PARSE_STREAM_START_STATE, +
+  YAML_PARSE_IMPLICIT_DOCUMENT_START_STATE, +
+  YAML_PARSE_DOCUMENT_START_STATE, +
+  YAML_PARSE_DOCUMENT_CONTENT_STATE, +
+  YAML_PARSE_DOCUMENT_END_STATE, +
+  YAML_PARSE_BLOCK_NODE_STATE, +
+  YAML_PARSE_BLOCK_NODE_OR_INDENTLESS_SEQUENCE_STATE, +
+  YAML_PARSE_FLOW_NODE_STATE, +
+  YAML_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE, +
+  YAML_PARSE_BLOCK_SEQUENCE_ENTRY_STATE, +
+  YAML_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE, +
+  YAML_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE, +
+  YAML_PARSE_BLOCK_MAPPING_KEY_STATE, +
+  YAML_PARSE_BLOCK_MAPPING_VALUE_STATE, +
+  YAML_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE, +
+  YAML_PARSE_FLOW_SEQUENCE_ENTRY_STATE, +
+  YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE, +
+  YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE, +
+  YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE, +
+  YAML_PARSE_FLOW_MAPPING_FIRST_KEY_STATE, +
+  YAML_PARSE_FLOW_MAPPING_KEY_STATE, +
+  YAML_PARSE_FLOW_MAPPING_VALUE_STATE, +
+  YAML_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE, +
+  YAML_PARSE_END_STATE +
+ }
 The states of the parser. More...

+Functions

int yaml_parser_initialize (yaml_parser_t *parser)
 Initialize a parser.
void yaml_parser_delete (yaml_parser_t *parser)
 Destroy a parser.
void yaml_parser_set_input_string (yaml_parser_t *parser, const unsigned char *input, size_t size)
 Set a string input.
void yaml_parser_set_input_file (yaml_parser_t *parser, FILE *file)
 Set a file input.
void yaml_parser_set_input (yaml_parser_t *parser, yaml_read_handler_t *handler, void *data)
 Set a generic input handler.
void yaml_parser_set_encoding (yaml_parser_t *parser, yaml_encoding_t encoding)
 Set the source encoding.
int yaml_parser_scan (yaml_parser_t *parser, yaml_token_t *token)
 Scan the input stream and produce the next token.
int yaml_parser_parse (yaml_parser_t *parser, yaml_event_t *event)
 Parse the input stream and produce the next parsing event.
int yaml_parser_load (yaml_parser_t *parser, yaml_document_t *document)
 Parse the input stream and produce the next YAML document.
+

Typedef Documentation

+ +
+
+ + + + +
typedef int yaml_read_handler_t(void *data, unsigned char *buffer, size_t size, size_t *size_read)
+
+
+ +

The prototype of a read handler.

+

The read handler is called when the parser needs to read more bytes from the source. The handler should write not more than size bytes to the buffer. The number of written bytes should be set to the length variable.

+
Parameters:
+ + + + + +
[in,out]dataA pointer to an application data specified by yaml_parser_set_input().
[out]bufferThe buffer to write the data from the source.
[in]sizeThe size of the buffer.
[out]size_readThe actual number of bytes read from the source.
+
+
+
Returns:
On success, the handler should return 1. If the handler failed, the returned value should be 0. On EOF, the handler should set the size_read to 0 and return 1.
+ +
+
+ +
+
+ + + + +
typedef struct yaml_parser_s yaml_parser_t
+
+
+ +

The parser structure.

+

All members are internal. Manage the structure using the yaml_parser_ family of functions.

+ +
+
+

Enumeration Type Documentation

+ +
+
+ + + + +
enum yaml_parser_state_e
+
+
+ +

The states of the parser.

+
Enumerator:
+ + + + + + + + + + + + + + + + + + + + + + + + +
YAML_PARSE_STREAM_START_STATE  +

Expect STREAM-START.

+
YAML_PARSE_IMPLICIT_DOCUMENT_START_STATE  +

Expect the beginning of an implicit document.

+
YAML_PARSE_DOCUMENT_START_STATE  +

Expect DOCUMENT-START.

+
YAML_PARSE_DOCUMENT_CONTENT_STATE  +

Expect the content of a document.

+
YAML_PARSE_DOCUMENT_END_STATE  +

Expect DOCUMENT-END.

+
YAML_PARSE_BLOCK_NODE_STATE  +

Expect a block node.

+
YAML_PARSE_BLOCK_NODE_OR_INDENTLESS_SEQUENCE_STATE  +

Expect a block node or indentless sequence.

+
YAML_PARSE_FLOW_NODE_STATE  +

Expect a flow node.

+
YAML_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE  +

Expect the first entry of a block sequence.

+
YAML_PARSE_BLOCK_SEQUENCE_ENTRY_STATE  +

Expect an entry of a block sequence.

+
YAML_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE  +

Expect an entry of an indentless sequence.

+
YAML_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE  +

Expect the first key of a block mapping.

+
YAML_PARSE_BLOCK_MAPPING_KEY_STATE  +

Expect a block mapping key.

+
YAML_PARSE_BLOCK_MAPPING_VALUE_STATE  +

Expect a block mapping value.

+
YAML_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE  +

Expect the first entry of a flow sequence.

+
YAML_PARSE_FLOW_SEQUENCE_ENTRY_STATE  +

Expect an entry of a flow sequence.

+
YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE  +

Expect a key of an ordered mapping.

+
YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE  +

Expect a value of an ordered mapping.

+
YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE  +

Expect the and of an ordered mapping entry.

+
YAML_PARSE_FLOW_MAPPING_FIRST_KEY_STATE  +

Expect the first key of a flow mapping.

+
YAML_PARSE_FLOW_MAPPING_KEY_STATE  +

Expect a key of a flow mapping.

+
YAML_PARSE_FLOW_MAPPING_VALUE_STATE  +

Expect a value of a flow mapping.

+
YAML_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE  +

Expect an empty value of a flow mapping.

+
YAML_PARSE_END_STATE  +

Expect nothing.

+
+
+
+ +
+
+

Function Documentation

+ +
+
+ + + + + + + + +
int yaml_parser_initialize (yaml_parser_tparser)
+
+
+ +

Initialize a parser.

+

This function creates a new parser object. An application is responsible for destroying the object using the yaml_parser_delete() function.

+
Parameters:
+ + +
[out]parserAn empty parser object.
+
+
+
Returns:
1 if the function succeeded, 0 on error.
+ +
+
+ +
+
+ + + + + + + + +
void yaml_parser_delete (yaml_parser_tparser)
+
+
+ +

Destroy a parser.

+
Parameters:
+ + +
[in,out]parserA parser object.
+
+
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void yaml_parser_set_input_string (yaml_parser_tparser,
const unsigned char * input,
size_t size 
)
+
+
+ +

Set a string input.

+

Note that the input pointer must be valid while the parser object exists. The application is responsible for destroing input after destroying the parser.

+
Parameters:
+ + + + +
[in,out]parserA parser object.
[in]inputA source data.
[in]sizeThe length of the source data in bytes.
+
+
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
void yaml_parser_set_input_file (yaml_parser_tparser,
FILE * file 
)
+
+
+ +

Set a file input.

+

file should be a file object open for reading. The application is responsible for closing the file.

+
Parameters:
+ + + +
[in,out]parserA parser object.
[in]fileAn open file.
+
+
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void yaml_parser_set_input (yaml_parser_tparser,
yaml_read_handler_thandler,
void * data 
)
+
+
+ +

Set a generic input handler.

+
Parameters:
+ + + + +
[in,out]parserA parser object.
[in]handlerA read handler.
[in]dataAny application data for passing to the read handler.
+
+
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
void yaml_parser_set_encoding (yaml_parser_tparser,
yaml_encoding_t encoding 
)
+
+
+ +

Set the source encoding.

+
Parameters:
+ + + +
[in,out]parserA parser object.
[in]encodingThe source encoding.
+
+
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
int yaml_parser_scan (yaml_parser_tparser,
yaml_token_ttoken 
)
+
+
+ +

Scan the input stream and produce the next token.

+

Call the function subsequently to produce a sequence of tokens corresponding to the input stream. The initial token has the type YAML_STREAM_START_TOKEN while the ending token has the type YAML_STREAM_END_TOKEN.

+

An application is responsible for freeing any buffers associated with the produced token object using the yaml_token_delete function.

+

An application must not alternate the calls of yaml_parser_scan() with the calls of yaml_parser_parse() or yaml_parser_load(). Doing this will break the parser.

+
Parameters:
+ + + +
[in,out]parserA parser object.
[out]tokenAn empty token object.
+
+
+
Returns:
1 if the function succeeded, 0 on error.
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
int yaml_parser_parse (yaml_parser_tparser,
yaml_event_tevent 
)
+
+
+ +

Parse the input stream and produce the next parsing event.

+

Call the function subsequently to produce a sequence of events corresponding to the input stream. The initial event has the type YAML_STREAM_START_EVENT while the ending event has the type YAML_STREAM_END_EVENT.

+

An application is responsible for freeing any buffers associated with the produced event object using the yaml_event_delete() function.

+

An application must not alternate the calls of yaml_parser_parse() with the calls of yaml_parser_scan() or yaml_parser_load(). Doing this will break the parser.

+
Parameters:
+ + + +
[in,out]parserA parser object.
[out]eventAn empty event object.
+
+
+
Returns:
1 if the function succeeded, 0 on error.
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + +
int yaml_parser_load (yaml_parser_tparser,
yaml_document_tdocument 
)
+
+
+ +

Parse the input stream and produce the next YAML document.

+

Call this function subsequently to produce a sequence of documents constituting the input stream.

+

If the produced document has no root node, it means that the document end has been reached.

+

An application is responsible for freeing any data associated with the produced document object using the yaml_document_delete() function.

+

An application must not alternate the calls of yaml_parser_load() with the calls of yaml_parser_scan() or yaml_parser_parse(). Doing this will break the parser.

+
Parameters:
+ + + +
[in,out]parserA parser object.
[out]documentAn empty document object.
+
+
+
Returns:
1 if the function succeeded, 0 on error.
+ +
+
+
+ + + + + + diff --git a/libyaml/doc/html/group__styles.html b/libyaml/doc/html/group__styles.html new file mode 100644 index 00000000..c3636d66 --- /dev/null +++ b/libyaml/doc/html/group__styles.html @@ -0,0 +1,251 @@ + + + + + +yaml: Node Styles + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.5 +
+ +
+
+ + + +
+
+ +
+
Node Styles
+
+
+ + + + + + + + + + + + + + + +

+Typedefs

typedef enum yaml_scalar_style_e yaml_scalar_style_t
 Scalar styles.
typedef enum yaml_sequence_style_e yaml_sequence_style_t
 Sequence styles.
typedef enum yaml_mapping_style_e yaml_mapping_style_t
 Mapping styles.

+Enumerations

enum  yaml_scalar_style_e {
+  YAML_ANY_SCALAR_STYLE, +
+  YAML_PLAIN_SCALAR_STYLE, +
+  YAML_SINGLE_QUOTED_SCALAR_STYLE, +
+  YAML_DOUBLE_QUOTED_SCALAR_STYLE, +
+  YAML_LITERAL_SCALAR_STYLE, +
+  YAML_FOLDED_SCALAR_STYLE +
+ }
 Scalar styles. More...
enum  yaml_sequence_style_e {
+  YAML_ANY_SEQUENCE_STYLE, +
+  YAML_BLOCK_SEQUENCE_STYLE, +
+  YAML_FLOW_SEQUENCE_STYLE +
+ }
 Sequence styles. More...
enum  yaml_mapping_style_e {
+  YAML_ANY_MAPPING_STYLE, +
+  YAML_BLOCK_MAPPING_STYLE, +
+  YAML_FLOW_MAPPING_STYLE +
+ }
 Mapping styles. More...
+

Typedef Documentation

+ +
+
+ + + + +
typedef enum yaml_scalar_style_e yaml_scalar_style_t
+
+
+ +

Scalar styles.

+ +
+
+ +
+ +
+ +

Sequence styles.

+ +
+
+ +
+
+ + + + +
typedef enum yaml_mapping_style_e yaml_mapping_style_t
+
+
+ +

Mapping styles.

+ +
+
+

Enumeration Type Documentation

+ +
+
+ + + + +
enum yaml_scalar_style_e
+
+
+ +

Scalar styles.

+
Enumerator:
+ + + + + + +
YAML_ANY_SCALAR_STYLE  +

Let the emitter choose the style.

+
YAML_PLAIN_SCALAR_STYLE  +

The plain scalar style.

+
YAML_SINGLE_QUOTED_SCALAR_STYLE  +

The single-quoted scalar style.

+
YAML_DOUBLE_QUOTED_SCALAR_STYLE  +

The double-quoted scalar style.

+
YAML_LITERAL_SCALAR_STYLE  +

The literal scalar style.

+
YAML_FOLDED_SCALAR_STYLE  +

The folded scalar style.

+
+
+
+ +
+
+ +
+
+ + + + +
enum yaml_sequence_style_e
+
+
+ +

Sequence styles.

+
Enumerator:
+ + + +
YAML_ANY_SEQUENCE_STYLE  +

Let the emitter choose the style.

+
YAML_BLOCK_SEQUENCE_STYLE  +

The block sequence style.

+
YAML_FLOW_SEQUENCE_STYLE  +

The flow sequence style.

+
+
+
+ +
+
+ +
+
+ + + + +
enum yaml_mapping_style_e
+
+
+ +

Mapping styles.

+
Enumerator:
+ + + +
YAML_ANY_MAPPING_STYLE  +

Let the emitter choose the style.

+
YAML_BLOCK_MAPPING_STYLE  +

The block mapping style.

+
YAML_FLOW_MAPPING_STYLE  +

The flow mapping style.

+
+
+
+ +
+
+
+ + + + + + diff --git a/libyaml/doc/html/group__tokens.html b/libyaml/doc/html/group__tokens.html new file mode 100644 index 00000000..dcd5bc51 --- /dev/null +++ b/libyaml/doc/html/group__tokens.html @@ -0,0 +1,276 @@ + + + + + +yaml: Tokens + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.5 +
+ +
+
+ + + +
+ +
+ + + + + + + + + + + + + + + +

+Data Structures

struct  yaml_token_s
 The token structure. More...

+Typedefs

typedef enum yaml_token_type_e yaml_token_type_t
 Token types.
typedef struct yaml_token_s yaml_token_t
 The token structure.

+Enumerations

enum  yaml_token_type_e {
+  YAML_NO_TOKEN, +
+  YAML_STREAM_START_TOKEN, +
+  YAML_STREAM_END_TOKEN, +
+  YAML_VERSION_DIRECTIVE_TOKEN, +
+  YAML_TAG_DIRECTIVE_TOKEN, +
+  YAML_DOCUMENT_START_TOKEN, +
+  YAML_DOCUMENT_END_TOKEN, +
+  YAML_BLOCK_SEQUENCE_START_TOKEN, +
+  YAML_BLOCK_MAPPING_START_TOKEN, +
+  YAML_BLOCK_END_TOKEN, +
+  YAML_FLOW_SEQUENCE_START_TOKEN, +
+  YAML_FLOW_SEQUENCE_END_TOKEN, +
+  YAML_FLOW_MAPPING_START_TOKEN, +
+  YAML_FLOW_MAPPING_END_TOKEN, +
+  YAML_BLOCK_ENTRY_TOKEN, +
+  YAML_FLOW_ENTRY_TOKEN, +
+  YAML_KEY_TOKEN, +
+  YAML_VALUE_TOKEN, +
+  YAML_ALIAS_TOKEN, +
+  YAML_ANCHOR_TOKEN, +
+  YAML_TAG_TOKEN, +
+  YAML_SCALAR_TOKEN +
+ }
 Token types. More...

+Functions

void yaml_token_delete (yaml_token_t *token)
 Free any memory allocated for a token object.
+

Typedef Documentation

+ +
+
+ + + + +
typedef enum yaml_token_type_e yaml_token_type_t
+
+
+ +

Token types.

+ +
+
+ +
+
+ + + + +
typedef struct yaml_token_s yaml_token_t
+
+
+ +

The token structure.

+ +
+
+

Enumeration Type Documentation

+ +
+
+ + + + +
enum yaml_token_type_e
+
+
+ +

Token types.

+
Enumerator:
+ + + + + + + + + + + + + + + + + + + + + + +
YAML_NO_TOKEN  +

An empty token.

+
YAML_STREAM_START_TOKEN  +

A STREAM-START token.

+
YAML_STREAM_END_TOKEN  +

A STREAM-END token.

+
YAML_VERSION_DIRECTIVE_TOKEN  +

A VERSION-DIRECTIVE token.

+
YAML_TAG_DIRECTIVE_TOKEN  +

A TAG-DIRECTIVE token.

+
YAML_DOCUMENT_START_TOKEN  +

A DOCUMENT-START token.

+
YAML_DOCUMENT_END_TOKEN  +

A DOCUMENT-END token.

+
YAML_BLOCK_SEQUENCE_START_TOKEN  +

A BLOCK-SEQUENCE-START token.

+
YAML_BLOCK_MAPPING_START_TOKEN  +

A BLOCK-SEQUENCE-END token.

+
YAML_BLOCK_END_TOKEN  +

A BLOCK-END token.

+
YAML_FLOW_SEQUENCE_START_TOKEN  +

A FLOW-SEQUENCE-START token.

+
YAML_FLOW_SEQUENCE_END_TOKEN  +

A FLOW-SEQUENCE-END token.

+
YAML_FLOW_MAPPING_START_TOKEN  +

A FLOW-MAPPING-START token.

+
YAML_FLOW_MAPPING_END_TOKEN  +

A FLOW-MAPPING-END token.

+
YAML_BLOCK_ENTRY_TOKEN  +

A BLOCK-ENTRY token.

+
YAML_FLOW_ENTRY_TOKEN  +

A FLOW-ENTRY token.

+
YAML_KEY_TOKEN  +

A KEY token.

+
YAML_VALUE_TOKEN  +

A VALUE token.

+
YAML_ALIAS_TOKEN  +

An ALIAS token.

+
YAML_ANCHOR_TOKEN  +

An ANCHOR token.

+
YAML_TAG_TOKEN  +

A TAG token.

+
YAML_SCALAR_TOKEN  +

A SCALAR token.

+
+
+
+ +
+
+

Function Documentation

+ +
+
+ + + + + + + + +
void yaml_token_delete (yaml_token_ttoken)
+
+
+ +

Free any memory allocated for a token object.

+
Parameters:
+ + +
[in,out]tokenA token object.
+
+
+ +
+
+
+ + + + + + diff --git a/libyaml/doc/html/group__version.html b/libyaml/doc/html/group__version.html new file mode 100644 index 00000000..98b6fc01 --- /dev/null +++ b/libyaml/doc/html/group__version.html @@ -0,0 +1,137 @@ + + + + + +yaml: Version Information + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.5 +
+ +
+
+ + + +
+
+ +
+
Version Information
+
+
+ + + + + + +

+Functions

const char * yaml_get_version_string (void)
 Get the library version as a string.
void yaml_get_version (int *major, int *minor, int *patch)
 Get the library version numbers.
+

Function Documentation

+ +
+
+ + + + + + + + +
const char* yaml_get_version_string (void )
+
+
+ +

Get the library version as a string.

+
Returns:
The function returns the pointer to a static string of the form "X.Y.Z", where X is the major version number, Y is a minor version number, and Z is the patch version number.
+ +
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
void yaml_get_version (int * major,
int * minor,
int * patch 
)
+
+
+ +

Get the library version numbers.

+
Parameters:
+ + + + +
[out]majorMajor version number.
[out]minorMinor version number.
[out]patchPatch version number.
+
+
+ +
+
+
+ + + + + + diff --git a/libyaml/doc/html/index.html b/libyaml/doc/html/index.html new file mode 100644 index 00000000..36e5f0f2 --- /dev/null +++ b/libyaml/doc/html/index.html @@ -0,0 +1,63 @@ + + + + + +yaml: Main Page + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.5 +
+ +
+
+ + + +
+
+
+
yaml Documentation
+
+
+
+ + + + + + diff --git a/libyaml/doc/html/modules.html b/libyaml/doc/html/modules.html new file mode 100644 index 00000000..039e1656 --- /dev/null +++ b/libyaml/doc/html/modules.html @@ -0,0 +1,74 @@ + + + + + +yaml: Modules + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.5 +
+ +
+
+ + + +
+
+
+
Modules
+
+ + + + + + + diff --git a/libyaml/doc/html/nav_f.png b/libyaml/doc/html/nav_f.png new file mode 100644 index 0000000000000000000000000000000000000000..1b07a16207e67c95fe2ee17e7016e6d08ac7ac99 GIT binary patch literal 159 zcmeAS@N?(olHy`uVBq!ia0vp^j6iI`!2~2XGqLUlQfZzpjv*C{Z|{2YIT`Y>1X`Eg z-tTbne1`SITM8Q!Pb(<)UFZ(m>wMzvKZQqKM~~GcZ=A7j<~E6K62>ozFS=cD3)mf8 z9WX0+R&m(l9KUsLdTx4?9~({T__KA%`}olPJ^N;y|F^pHgs_K%!rj~{8>RwnWbkzL Kb6Mw<&;$VTdq1fF literal 0 HcmV?d00001 diff --git a/libyaml/doc/html/nav_h.png b/libyaml/doc/html/nav_h.png new file mode 100644 index 0000000000000000000000000000000000000000..01f5fa6a596e36bd12c2d6ceff1b0169fda7e699 GIT binary patch literal 97 zcmeAS@N?(olHy`uVBq!ia0vp^j6lr8!2~3AUOE6t1`SUa$B+ufw|6&kG8phMJMJ~w va4>Y+bZ&9QY?(VEUPY_cGd9nQ`um^ZSUyYpAAuKhL7F^W{an^LB{Ts5DmojT literal 0 HcmV?d00001 diff --git a/libyaml/doc/html/open.png b/libyaml/doc/html/open.png new file mode 100644 index 0000000000000000000000000000000000000000..7b35d2c2c389743089632fe24c3104f2173d97af GIT binary patch literal 118 zcmeAS@N?(olHy`uVBq!ia0vp^oFL4>1|%O$WD@{Vww^AIAr*{o=Nbw!DDW^(zOibV zl!F8B0?t?i!vld4k#$~0_AX3zElaokn + + + + +yaml: yaml_alias_data_s Struct Reference + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.5 +
+ +
+
+ + + + +
+
+ +
+
yaml_alias_data_s Struct Reference
+
+
+ +

This structure holds aliases data. + More...

+ +

#include <yaml.h>

+ + + + + + + + +

+Data Fields

yaml_char_tanchor
 The anchor.
int index
 The node id.
yaml_mark_t mark
 The anchor mark.
+

Detailed Description

+

This structure holds aliases data.

+

Field Documentation

+ +
+ +
+ +

The anchor.

+ +
+
+ +
+
+ + + + +
int yaml_alias_data_s::index
+
+
+ +

The node id.

+ +
+
+ +
+ +
+ +

The anchor mark.

+ +
+
+
The documentation for this struct was generated from the following file: +
+ + + + + + diff --git a/libyaml/doc/html/structyaml__document__s.html b/libyaml/doc/html/structyaml__document__s.html new file mode 100644 index 00000000..a9b66d2d --- /dev/null +++ b/libyaml/doc/html/structyaml__document__s.html @@ -0,0 +1,264 @@ + + + + + +yaml: yaml_document_s Struct Reference + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.5 +
+ +
+
+ + + + +
+
+ +
+
yaml_document_s Struct Reference
+
+
+ +

The document structure. + More...

+ +

#include <yaml.h>

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Data Fields

struct {
   yaml_node_t *   start
 The beginning of the stack.
   yaml_node_t *   end
 The end of the stack.
   yaml_node_t *   top
 The top of the stack.
nodes
 The document nodes.
yaml_version_directive_tversion_directive
 The version directive.
struct {
   yaml_tag_directive_t *   start
 The beginning of the tag directives list.
   yaml_tag_directive_t *   end
 The end of the tag directives list.
tag_directives
 The list of tag directives.
+int start_implicit
 Is the document start indicator implicit?
+int end_implicit
 Is the document end indicator implicit?
yaml_mark_t start_mark
 The beginning of the document.
yaml_mark_t end_mark
 The end of the document.
+

Detailed Description

+

The document structure.

+

Field Documentation

+ +
+ +
+ +

The beginning of the stack.

+ +
+
+ +
+ +
+ +

The end of the stack.

+ +
+
+ +
+ +
+ +

The top of the stack.

+ +
+
+ +
+
+ + + + +
struct { ... } yaml_document_s::nodes
+
+
+ +

The document nodes.

+ +
+
+ +
+ +
+ +

The version directive.

+ +
+
+ +
+ +
+ +

The beginning of the tag directives list.

+ +
+
+ +
+ +
+ +

The end of the tag directives list.

+ +
+
+ +
+
+ + + + +
struct { ... } yaml_document_s::tag_directives
+
+
+ +

The list of tag directives.

+ +
+
+ +
+ +
+ +

The beginning of the document.

+ +
+
+ +
+ +
+ +

The end of the document.

+ +
+
+
The documentation for this struct was generated from the following file: +
+ + + + + + diff --git a/libyaml/doc/html/structyaml__emitter__s.html b/libyaml/doc/html/structyaml__emitter__s.html new file mode 100644 index 00000000..ca5b0a5a --- /dev/null +++ b/libyaml/doc/html/structyaml__emitter__s.html @@ -0,0 +1,1321 @@ + + + + + +yaml: yaml_emitter_s Struct Reference + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.5 +
+ +
+
+ + + + +
+
+
+
yaml_emitter_s Struct Reference
+
+
+ +

The emitter structure. + More...

+ +

#include <yaml.h>

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Data Fields

unsigned char * buffer
 The buffer pointer.
size_t size
 The buffer size.
size_t * size_written
 The number of written bytes.
struct {
   unsigned char *   buffer
 The buffer pointer.
   size_t   size
 The buffer size.
   size_t *   size_written
 The number of written bytes.
string
 String output data.
FILE * file
 File output data.
yaml_char_tstart
 The beginning of the buffer.
yaml_char_tend
 The end of the buffer.
yaml_char_tpointer
 The current position of the buffer.
yaml_char_tlast
 The last filled position of the buffer.
unsigned char * start
 The beginning of the buffer.
unsigned char * end
 The end of the buffer.
unsigned char * pointer
 The current position of the buffer.
unsigned char * last
 The last filled position of the buffer.
yaml_emitter_state_tstart
 The beginning of the stack.
yaml_emitter_state_tend
 The end of the stack.
yaml_emitter_state_ttop
 The top of the stack.
yaml_event_tstart
 The beginning of the event queue.
yaml_event_tend
 The end of the event queue.
yaml_event_thead
 The head of the event queue.
yaml_event_ttail
 The tail of the event queue.
int * start
 The beginning of the stack.
int * end
 The end of the stack.
int * top
 The top of the stack.
yaml_tag_directive_tstart
 The beginning of the list.
yaml_tag_directive_tend
 The end of the list.
yaml_tag_directive_ttop
 The top of the list.
yaml_char_tanchor
 The anchor value.
size_t anchor_length
 The anchor length.
+int alias
 Is it an alias?
yaml_char_thandle
 The tag handle.
size_t handle_length
 The tag handle length.
yaml_char_tsuffix
 The tag suffix.
size_t suffix_length
 The tag suffix length.
yaml_char_tvalue
 The scalar value.
size_t length
 The scalar length.
+int multiline
 Does the scalar contain line breaks?
+int flow_plain_allowed
 Can the scalar be expessed in the flow plain style?
+int block_plain_allowed
 Can the scalar be expressed in the block plain style?
+int single_quoted_allowed
 Can the scalar be expressed in the single quoted style?
+int block_allowed
 Can the scalar be expressed in the literal or folded styles?
yaml_scalar_style_t style
 The output style.
int references
 The number of references.
int anchor
 The anchor id.
+int serialized
 If the node has been emitted?
Error handling
yaml_error_type_t error
 Error type.
const char * problem
 Error description.
Writer stuff
yaml_write_handler_twrite_handler
 Write handler.
void * write_handler_data
 A pointer for passing to the white handler.
union {
   struct {
      unsigned char *   buffer
 The buffer pointer.
      size_t   size
 The buffer size.
      size_t *   size_written
 The number of written bytes.
   }   string
 String output data.
   FILE *   file
 File output data.
output
 Standard (string or file) output data.
struct {
   yaml_char_t *   start
 The beginning of the buffer.
   yaml_char_t *   end
 The end of the buffer.
   yaml_char_t *   pointer
 The current position of the buffer.
   yaml_char_t *   last
 The last filled position of the buffer.
buffer
 The working buffer.
struct {
   unsigned char *   start
 The beginning of the buffer.
   unsigned char *   end
 The end of the buffer.
   unsigned char *   pointer
 The current position of the buffer.
   unsigned char *   last
 The last filled position of the buffer.
raw_buffer
 The raw buffer.
yaml_encoding_t encoding
 The stream encoding.
Emitter stuff
+int canonical
 If the output is in the canonical style?
int best_indent
 The number of indentation spaces.
int best_width
 The preferred width of the output lines.
+int unicode
 Allow unescaped non-ASCII characters?
yaml_break_t line_break
 The preferred line break.
struct {
   yaml_emitter_state_t *   start
 The beginning of the stack.
   yaml_emitter_state_t *   end
 The end of the stack.
   yaml_emitter_state_t *   top
 The top of the stack.
states
 The stack of states.
yaml_emitter_state_t state
 The current emitter state.
struct {
   yaml_event_t *   start
 The beginning of the event queue.
   yaml_event_t *   end
 The end of the event queue.
   yaml_event_t *   head
 The head of the event queue.
   yaml_event_t *   tail
 The tail of the event queue.
events
 The event queue.
struct {
   int *   start
 The beginning of the stack.
   int *   end
 The end of the stack.
   int *   top
 The top of the stack.
indents
 The stack of indentation levels.
struct {
   yaml_tag_directive_t *   start
 The beginning of the list.
   yaml_tag_directive_t *   end
 The end of the list.
   yaml_tag_directive_t *   top
 The top of the list.
tag_directives
 The list of tag directives.
int indent
 The current indentation level.
int flow_level
 The current flow level.
+int root_context
 Is it the document root context?
+int sequence_context
 Is it a sequence context?
+int mapping_context
 Is it a mapping context?
+int simple_key_context
 Is it a simple mapping key context?
int line
 The current line.
int column
 The current column.
+int whitespace
 If the last character was a whitespace?
+int indention
 If the last character was an indentation character (' ', '-', '?', ':')?
+int open_ended
 If an explicit document end is required?
struct {
   yaml_char_t *   anchor
 The anchor value.
   size_t   anchor_length
 The anchor length.
   int   alias
 Is it an alias?
anchor_data
 Anchor analysis.
struct {
   yaml_char_t *   handle
 The tag handle.
   size_t   handle_length
 The tag handle length.
   yaml_char_t *   suffix
 The tag suffix.
   size_t   suffix_length
 The tag suffix length.
tag_data
 Tag analysis.
struct {
   yaml_char_t *   value
 The scalar value.
   size_t   length
 The scalar length.
   int   multiline
 Does the scalar contain line breaks?
   int   flow_plain_allowed
 Can the scalar be expessed in the flow plain style?
   int   block_plain_allowed
 Can the scalar be expressed in the block plain style?
   int   single_quoted_allowed
 Can the scalar be expressed in the single quoted style?
   int   block_allowed
 Can the scalar be expressed in the literal or folded styles?
   yaml_scalar_style_t   style
 The output style.
scalar_data
 Scalar analysis.
Dumper stuff
+int opened
 If the stream was already opened?
+int closed
 If the stream was already closed?
struct {
   int   references
 The number of references.
   int   anchor
 The anchor id.
   int   serialized
 If the node has been emitted?
anchors
 The information associated with the document nodes.
int last_anchor_id
 The last assigned anchor id.
yaml_document_tdocument
 The currently emitted document.
+

Detailed Description

+

The emitter structure.

+

All members are internal. Manage the structure using the yaml_emitter_ family of functions.

+

Field Documentation

+ +
+ +
+ +

Error type.

+ +
+
+ +
+
+ + + + +
const char* yaml_emitter_s::problem
+
+
+ +

Error description.

+ +
+
+ +
+ +
+ +

Write handler.

+ +
+
+ +
+ +
+ +

A pointer for passing to the white handler.

+ +
+
+ +
+
+ + + + +
unsigned char* yaml_emitter_s::buffer
+
+
+ +

The buffer pointer.

+ +
+
+ +
+
+ + + + +
size_t yaml_emitter_s::size
+
+
+ +

The buffer size.

+ +
+
+ +
+
+ + + + +
size_t* yaml_emitter_s::size_written
+
+
+ +

The number of written bytes.

+ +
+
+ +
+
+ + + + +
struct { ... } yaml_emitter_s::string
+
+
+ +

String output data.

+ +
+
+ +
+
+ + + + +
FILE* yaml_emitter_s::file
+
+
+ +

File output data.

+ +
+
+ +
+
+ + + + +
union { ... } yaml_emitter_s::output
+
+
+ +

Standard (string or file) output data.

+ +
+
+ +
+ +
+ +

The beginning of the buffer.

+ +
+
+ +
+ +
+ +

The end of the buffer.

+ +
+
+ +
+ +
+ +

The current position of the buffer.

+ +
+
+ +
+ +
+ +

The last filled position of the buffer.

+ +
+
+ +
+
+ + + + +
struct { ... } yaml_emitter_s::buffer
+
+
+ +

The working buffer.

+ +
+
+ +
+
+ + + + +
unsigned char* yaml_emitter_s::start
+
+
+ +

The beginning of the buffer.

+ +
+
+ +
+
+ + + + +
unsigned char* yaml_emitter_s::end
+
+
+ +

The end of the buffer.

+ +
+
+ +
+
+ + + + +
unsigned char* yaml_emitter_s::pointer
+
+
+ +

The current position of the buffer.

+ +
+
+ +
+
+ + + + +
unsigned char* yaml_emitter_s::last
+
+
+ +

The last filled position of the buffer.

+ +
+
+ +
+
+ + + + +
struct { ... } yaml_emitter_s::raw_buffer
+
+
+ +

The raw buffer.

+ +
+
+ +
+ +
+ +

The stream encoding.

+ +
+
+ +
+ +
+ +

The number of indentation spaces.

+ +
+
+ +
+ +
+ +

The preferred width of the output lines.

+ +
+
+ +
+ +
+ +

The preferred line break.

+ +
+
+ +
+ +
+ +

The beginning of the stack.

+ +
+
+ +
+ +
+ +

The end of the stack.

+ +
+
+ +
+ +
+ +

The top of the stack.

+ +
+
+ +
+
+ + + + +
struct { ... } yaml_emitter_s::states
+
+
+ +

The stack of states.

+ +
+
+ +
+ +
+ +

The current emitter state.

+ +
+
+ +
+ +
+ +

The beginning of the event queue.

+ +
+
+ +
+ +
+ +

The end of the event queue.

+ +
+
+ +
+ +
+ +

The head of the event queue.

+ +
+
+ +
+ +
+ +

The tail of the event queue.

+ +
+
+ +
+
+ + + + +
struct { ... } yaml_emitter_s::events
+
+
+ +

The event queue.

+ +
+
+ +
+
+ + + + +
int* yaml_emitter_s::start
+
+
+ +

The beginning of the stack.

+ +
+
+ +
+
+ + + + +
int* yaml_emitter_s::end
+
+
+ +

The end of the stack.

+ +
+
+ +
+
+ + + + +
int* yaml_emitter_s::top
+
+
+ +

The top of the stack.

+ +
+
+ +
+
+ + + + +
struct { ... } yaml_emitter_s::indents
+
+
+ +

The stack of indentation levels.

+ +
+
+ +
+ +
+ +

The beginning of the list.

+ +
+
+ +
+ +
+ +

The end of the list.

+ +
+
+ +
+ +
+ +

The top of the list.

+ +
+
+ +
+
+ + + + +
struct { ... } yaml_emitter_s::tag_directives
+
+
+ +

The list of tag directives.

+ +
+
+ +
+
+ + + + +
int yaml_emitter_s::indent
+
+
+ +

The current indentation level.

+ +
+
+ +
+ +
+ +

The current flow level.

+ +
+
+ +
+
+ + + + +
int yaml_emitter_s::line
+
+
+ +

The current line.

+ +
+
+ +
+
+ + + + +
int yaml_emitter_s::column
+
+
+ +

The current column.

+ +
+
+ +
+ +
+ +

The anchor value.

+ +
+
+ +
+
+ + + + +
size_t yaml_emitter_s::anchor_length
+
+
+ +

The anchor length.

+ +
+
+ +
+
+ + + + +
struct { ... } yaml_emitter_s::anchor_data
+
+
+ +

Anchor analysis.

+ +
+
+ +
+ +
+ +

The tag handle.

+ +
+
+ +
+
+ + + + +
size_t yaml_emitter_s::handle_length
+
+
+ +

The tag handle length.

+ +
+
+ +
+ +
+ +

The tag suffix.

+ +
+
+ +
+
+ + + + +
size_t yaml_emitter_s::suffix_length
+
+
+ +

The tag suffix length.

+ +
+
+ +
+
+ + + + +
struct { ... } yaml_emitter_s::tag_data
+
+
+ +

Tag analysis.

+ +
+
+ +
+ +
+ +

The scalar value.

+ +
+
+ +
+
+ + + + +
size_t yaml_emitter_s::length
+
+
+ +

The scalar length.

+ +
+
+ +
+ +
+ +

The output style.

+ +
+
+ +
+
+ + + + +
struct { ... } yaml_emitter_s::scalar_data
+
+
+ +

Scalar analysis.

+ +
+
+ +
+ +
+ +

The number of references.

+ +
+
+ +
+
+ + + + +
int yaml_emitter_s::anchor
+
+
+ +

The anchor id.

+ +
+
+ +
+
+ + + + +
struct { ... } * yaml_emitter_s::anchors
+
+
+ +

The information associated with the document nodes.

+ +
+
+ +
+ +
+ +

The last assigned anchor id.

+ +
+
+ +
+ +
+ +

The currently emitted document.

+ +
+
+
The documentation for this struct was generated from the following file: +
+ + + + + + diff --git a/libyaml/doc/html/structyaml__event__s.html b/libyaml/doc/html/structyaml__event__s.html new file mode 100644 index 00000000..dd7fe30d --- /dev/null +++ b/libyaml/doc/html/structyaml__event__s.html @@ -0,0 +1,525 @@ + + + + + +yaml: yaml_event_s Struct Reference + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.5 +
+ +
+
+ + + + +
+
+ +
+
yaml_event_s Struct Reference
+
+
+ +

The event structure. + More...

+ +

#include <yaml.h>

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Data Fields

yaml_event_type_t type
 The event type.
union {
   struct {
      yaml_encoding_t   encoding
 The document encoding.
   }   stream_start
 The stream parameters (for YAML_STREAM_START_EVENT).
   struct {
      yaml_version_directive_t *   version_directive
 The version directive.
      struct {
         yaml_tag_directive_t *   start
 The beginning of the tag directives list.
         yaml_tag_directive_t *   end
 The end of the tag directives list.
      }   tag_directives
 The list of tag directives.
      int   implicit
 Is the document indicator implicit?
   }   document_start
 The document parameters (for YAML_DOCUMENT_START_EVENT).
   struct {
      int   implicit
 Is the document end indicator implicit?
   }   document_end
 The document end parameters (for YAML_DOCUMENT_END_EVENT).
   struct {
      yaml_char_t *   anchor
 The anchor.
   }   alias
 The alias parameters (for YAML_ALIAS_EVENT).
   struct {
      yaml_char_t *   anchor
 The anchor.
      yaml_char_t *   tag
 The tag.
      yaml_char_t *   value
 The scalar value.
      size_t   length
 The length of the scalar value.
      int   plain_implicit
 Is the tag optional for the plain style?
      int   quoted_implicit
 Is the tag optional for any non-plain style?
      yaml_scalar_style_t   style
 The scalar style.
   }   scalar
 The scalar parameters (for YAML_SCALAR_EVENT).
   struct {
      yaml_char_t *   anchor
 The anchor.
      yaml_char_t *   tag
 The tag.
      int   implicit
 Is the tag optional?
      yaml_sequence_style_t   style
 The sequence style.
   }   sequence_start
 The sequence parameters (for YAML_SEQUENCE_START_EVENT).
   struct {
      yaml_char_t *   anchor
 The anchor.
      yaml_char_t *   tag
 The tag.
      int   implicit
 Is the tag optional?
      yaml_mapping_style_t   style
 The mapping style.
   }   mapping_start
 The mapping parameters (for YAML_MAPPING_START_EVENT).
data
 The event data.
yaml_mark_t start_mark
 The beginning of the event.
yaml_mark_t end_mark
 The end of the event.
+

Detailed Description

+

The event structure.

+

Field Documentation

+ +
+ +
+ +

The event type.

+ +
+
+ +
+ +
+ +

The document encoding.

+ +
+
+ +
+
+ + + + +
struct { ... } yaml_event_s::stream_start
+
+
+ +

The stream parameters (for YAML_STREAM_START_EVENT).

+ +
+
+ +
+ +
+ +

The version directive.

+ +
+
+ +
+ +
+ +

The beginning of the tag directives list.

+ +
+
+ +
+ +
+ +

The end of the tag directives list.

+ +
+
+ +
+
+ + + + +
struct { ... } yaml_event_s::tag_directives
+
+
+ +

The list of tag directives.

+ +
+
+ +
+
+ + + + +
int yaml_event_s::implicit
+
+
+ +

Is the document indicator implicit?

+

Is the tag optional?

+

Is the document end indicator implicit?

+ +
+
+ +
+
+ + + + +
struct { ... } yaml_event_s::document_start
+
+
+ +

The document parameters (for YAML_DOCUMENT_START_EVENT).

+ +
+
+ +
+
+ + + + +
struct { ... } yaml_event_s::document_end
+
+
+ +

The document end parameters (for YAML_DOCUMENT_END_EVENT).

+ +
+
+ +
+ +
+ +

The anchor.

+ +
+
+ +
+
+ + + + +
struct { ... } yaml_event_s::alias
+
+
+ +

The alias parameters (for YAML_ALIAS_EVENT).

+ +
+
+ +
+ +
+ +

The tag.

+ +
+
+ +
+ +
+ +

The scalar value.

+ +
+
+ +
+
+ + + + +
size_t yaml_event_s::length
+
+
+ +

The length of the scalar value.

+ +
+
+ +
+ +
+ +

The scalar style.

+ +
+
+ +
+
+ + + + +
struct { ... } yaml_event_s::scalar
+
+
+ +

The scalar parameters (for YAML_SCALAR_EVENT).

+ +
+
+ +
+ +
+ +

The sequence style.

+ +
+
+ +
+
+ + + + +
struct { ... } yaml_event_s::sequence_start
+
+
+ +

The sequence parameters (for YAML_SEQUENCE_START_EVENT).

+ +
+
+ +
+ +
+ +

The mapping style.

+ +
+
+ +
+
+ + + + +
struct { ... } yaml_event_s::mapping_start
+
+
+ +

The mapping parameters (for YAML_MAPPING_START_EVENT).

+ +
+
+ +
+
+ + + + +
union { ... } yaml_event_s::data
+
+
+ +

The event data.

+ +
+
+ +
+ +
+ +

The beginning of the event.

+ +
+
+ +
+ +
+ +

The end of the event.

+ +
+
+
The documentation for this struct was generated from the following file: +
+ + + + + + diff --git a/libyaml/doc/html/structyaml__mark__s.html b/libyaml/doc/html/structyaml__mark__s.html new file mode 100644 index 00000000..d9c57a42 --- /dev/null +++ b/libyaml/doc/html/structyaml__mark__s.html @@ -0,0 +1,137 @@ + + + + + +yaml: yaml_mark_s Struct Reference + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.5 +
+ +
+
+ + + + +
+
+ +
+
yaml_mark_s Struct Reference
+
+
+ +

The pointer position. + More...

+ +

#include <yaml.h>

+ + + + + + + + +

+Data Fields

size_t index
 The position index.
size_t line
 The position line.
size_t column
 The position column.
+

Detailed Description

+

The pointer position.

+

Field Documentation

+ +
+
+ + + + +
size_t yaml_mark_s::index
+
+
+ +

The position index.

+ +
+
+ +
+
+ + + + +
size_t yaml_mark_s::line
+
+
+ +

The position line.

+ +
+
+ +
+
+ + + + +
size_t yaml_mark_s::column
+
+
+ +

The position column.

+ +
+
+
The documentation for this struct was generated from the following file: +
+ + + + + + diff --git a/libyaml/doc/html/structyaml__node__pair__s.html b/libyaml/doc/html/structyaml__node__pair__s.html new file mode 100644 index 00000000..2310e24a --- /dev/null +++ b/libyaml/doc/html/structyaml__node__pair__s.html @@ -0,0 +1,120 @@ + + + + + +yaml: yaml_node_pair_s Struct Reference + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.5 +
+ +
+
+ + + + +
+
+ +
+
yaml_node_pair_s Struct Reference
+
+
+ +

An element of a mapping node. + More...

+ +

#include <yaml.h>

+ + + + + + +

+Data Fields

int key
 The key of the element.
int value
 The value of the element.
+

Detailed Description

+

An element of a mapping node.

+

Field Documentation

+ +
+
+ + + + +
int yaml_node_pair_s::key
+
+
+ +

The key of the element.

+ +
+
+ +
+
+ + + + +
int yaml_node_pair_s::value
+
+
+ +

The value of the element.

+ +
+
+
The documentation for this struct was generated from the following file: +
+ + + + + + diff --git a/libyaml/doc/html/structyaml__node__s.html b/libyaml/doc/html/structyaml__node__s.html new file mode 100644 index 00000000..de540fb8 --- /dev/null +++ b/libyaml/doc/html/structyaml__node__s.html @@ -0,0 +1,449 @@ + + + + + +yaml: yaml_node_s Struct Reference + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.5 +
+ +
+
+ + + + +
+
+ +
+
yaml_node_s Struct Reference
+
+
+ +

The node structure. + More...

+ +

#include <yaml.h>

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Data Fields

yaml_node_type_t type
 The node type.
yaml_char_ttag
 The node tag.
union {
   struct {
      yaml_char_t *   value
 The scalar value.
      size_t   length
 The length of the scalar value.
      yaml_scalar_style_t   style
 The scalar style.
   }   scalar
 The scalar parameters (for YAML_SCALAR_NODE).
   struct {
      struct {
         yaml_node_item_t *   start
 The beginning of the stack.
         yaml_node_item_t *   end
 The end of the stack.
         yaml_node_item_t *   top
 The top of the stack.
      }   items
 The stack of sequence items.
      yaml_sequence_style_t   style
 The sequence style.
   }   sequence
 The sequence parameters (for YAML_SEQUENCE_NODE).
   struct {
      struct {
         yaml_node_pair_t *   start
 The beginning of the stack.
         yaml_node_pair_t *   end
 The end of the stack.
         yaml_node_pair_t *   top
 The top of the stack.
      }   pairs
 The stack of mapping pairs (key, value).
      yaml_mapping_style_t   style
 The mapping style.
   }   mapping
 The mapping parameters (for YAML_MAPPING_NODE).
data
 The node data.
yaml_mark_t start_mark
 The beginning of the node.
yaml_mark_t end_mark
 The end of the node.
+

Detailed Description

+

The node structure.

+

Field Documentation

+ +
+ +
+ +

The node type.

+ +
+
+ +
+ +
+ +

The node tag.

+ +
+
+ +
+ +
+ +

The scalar value.

+ +
+
+ +
+
+ + + + +
size_t yaml_node_s::length
+
+
+ +

The length of the scalar value.

+ +
+
+ +
+ +
+ +

The scalar style.

+ +
+
+ +
+
+ + + + +
struct { ... } yaml_node_s::scalar
+
+
+ +

The scalar parameters (for YAML_SCALAR_NODE).

+ +
+
+ +
+ +
+ +

The beginning of the stack.

+ +
+
+ +
+ +
+ +

The end of the stack.

+ +
+
+ +
+ +
+ +

The top of the stack.

+ +
+
+ +
+
+ + + + +
struct { ... } yaml_node_s::items
+
+
+ +

The stack of sequence items.

+ +
+
+ +
+ +
+ +

The sequence style.

+ +
+
+ +
+
+ + + + +
struct { ... } yaml_node_s::sequence
+
+
+ +

The sequence parameters (for YAML_SEQUENCE_NODE).

+ +
+
+ +
+ +
+ +

The beginning of the stack.

+ +
+
+ +
+ +
+ +

The end of the stack.

+ +
+
+ +
+ +
+ +

The top of the stack.

+ +
+
+ +
+
+ + + + +
struct { ... } yaml_node_s::pairs
+
+
+ +

The stack of mapping pairs (key, value).

+ +
+
+ +
+ +
+ +

The mapping style.

+ +
+
+ +
+
+ + + + +
struct { ... } yaml_node_s::mapping
+
+
+ +

The mapping parameters (for YAML_MAPPING_NODE).

+ +
+
+ +
+
+ + + + +
union { ... } yaml_node_s::data
+
+
+ +

The node data.

+ +
+
+ +
+ +
+ +

The beginning of the node.

+ +
+
+ +
+ +
+ +

The end of the node.

+ +
+
+
The documentation for this struct was generated from the following file: +
+ + + + + + diff --git a/libyaml/doc/html/structyaml__parser__s.html b/libyaml/doc/html/structyaml__parser__s.html new file mode 100644 index 00000000..60fe2a8c --- /dev/null +++ b/libyaml/doc/html/structyaml__parser__s.html @@ -0,0 +1,1248 @@ + + + + + +yaml: yaml_parser_s Struct Reference + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.5 +
+ +
+
+ + + + +
+
+
+
yaml_parser_s Struct Reference
+
+
+ +

The parser structure. + More...

+ +

#include <yaml.h>

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Data Fields

const unsigned char * start
 The string start pointer.
const unsigned char * end
 The string end pointer.
const unsigned char * current
 The string current position.
struct {
   const unsigned char *   start
 The string start pointer.
   const unsigned char *   end
 The string end pointer.
   const unsigned char *   current
 The string current position.
string
 String input data.
FILE * file
 File input data.
yaml_char_tstart
 The beginning of the buffer.
yaml_char_tend
 The end of the buffer.
yaml_char_tpointer
 The current position of the buffer.
yaml_char_tlast
 The last filled position of the buffer.
unsigned char * start
 The beginning of the buffer.
unsigned char * end
 The end of the buffer.
unsigned char * pointer
 The current position of the buffer.
unsigned char * last
 The last filled position of the buffer.
yaml_token_tstart
 The beginning of the tokens queue.
yaml_token_tend
 The end of the tokens queue.
yaml_token_thead
 The head of the tokens queue.
yaml_token_ttail
 The tail of the tokens queue.
int * start
 The beginning of the stack.
int * end
 The end of the stack.
int * top
 The top of the stack.
yaml_simple_key_tstart
 The beginning of the stack.
yaml_simple_key_tend
 The end of the stack.
yaml_simple_key_ttop
 The top of the stack.
yaml_parser_state_tstart
 The beginning of the stack.
yaml_parser_state_tend
 The end of the stack.
yaml_parser_state_ttop
 The top of the stack.
yaml_mark_tstart
 The beginning of the stack.
yaml_mark_tend
 The end of the stack.
yaml_mark_ttop
 The top of the stack.
yaml_tag_directive_tstart
 The beginning of the list.
yaml_tag_directive_tend
 The end of the list.
yaml_tag_directive_ttop
 The top of the list.
yaml_alias_data_tstart
 The beginning of the list.
yaml_alias_data_tend
 The end of the list.
yaml_alias_data_ttop
 The top of the list.
Error handling
yaml_error_type_t error
 Error type.
const char * problem
 Error description.
size_t problem_offset
 The byte about which the problem occured.
int problem_value
 The problematic value (-1 is none).
yaml_mark_t problem_mark
 The problem position.
const char * context
 The error context.
yaml_mark_t context_mark
 The context position.
Reader stuff
yaml_read_handler_tread_handler
 Read handler.
void * read_handler_data
 A pointer for passing to the read handler.
union {
   struct {
      const unsigned char *   start
 The string start pointer.
      const unsigned char *   end
 The string end pointer.
      const unsigned char *   current
 The string current position.
   }   string
 String input data.
   FILE *   file
 File input data.
input
 Standard (string or file) input data.
+int eof
 EOF flag.
struct {
   yaml_char_t *   start
 The beginning of the buffer.
   yaml_char_t *   end
 The end of the buffer.
   yaml_char_t *   pointer
 The current position of the buffer.
   yaml_char_t *   last
 The last filled position of the buffer.
buffer
 The working buffer.
+size_t unread
struct {
   unsigned char *   start
 The beginning of the buffer.
   unsigned char *   end
 The end of the buffer.
   unsigned char *   pointer
 The current position of the buffer.
   unsigned char *   last
 The last filled position of the buffer.
raw_buffer
 The raw buffer.
yaml_encoding_t encoding
 The input encoding.
size_t offset
 The offset of the current position (in bytes).
yaml_mark_t mark
 The mark of the current position.
Scanner stuff
+int stream_start_produced
 Have we started to scan the input stream?
+int stream_end_produced
 Have we reached the end of the input stream?
int flow_level
 The number of unclosed '[' and '{' indicators.
struct {
   yaml_token_t *   start
 The beginning of the tokens queue.
   yaml_token_t *   end
 The end of the tokens queue.
   yaml_token_t *   head
 The head of the tokens queue.
   yaml_token_t *   tail
 The tail of the tokens queue.
tokens
 The tokens queue.
size_t tokens_parsed
 The number of tokens fetched from the queue.
+int token_available
struct {
   int *   start
 The beginning of the stack.
   int *   end
 The end of the stack.
   int *   top
 The top of the stack.
indents
 The indentation levels stack.
int indent
 The current indentation level.
+int simple_key_allowed
 May a simple key occur at the current position?
struct {
   yaml_simple_key_t *   start
 The beginning of the stack.
   yaml_simple_key_t *   end
 The end of the stack.
   yaml_simple_key_t *   top
 The top of the stack.
simple_keys
 The stack of simple keys.
Parser stuff
struct {
   yaml_parser_state_t *   start
 The beginning of the stack.
   yaml_parser_state_t *   end
 The end of the stack.
   yaml_parser_state_t *   top
 The top of the stack.
states
 The parser states stack.
yaml_parser_state_t state
 The current parser state.
struct {
   yaml_mark_t *   start
 The beginning of the stack.
   yaml_mark_t *   end
 The end of the stack.
   yaml_mark_t *   top
 The top of the stack.
marks
 The stack of marks.
struct {
   yaml_tag_directive_t *   start
 The beginning of the list.
   yaml_tag_directive_t *   end
 The end of the list.
   yaml_tag_directive_t *   top
 The top of the list.
tag_directives
 The list of TAG directives.
Dumper stuff
struct {
   yaml_alias_data_t *   start
 The beginning of the list.
   yaml_alias_data_t *   end
 The end of the list.
   yaml_alias_data_t *   top
 The top of the list.
aliases
 The alias data.
yaml_document_tdocument
 The currently parsed document.
+

Detailed Description

+

The parser structure.

+

All members are internal. Manage the structure using the yaml_parser_ family of functions.

+

Field Documentation

+ +
+ +
+ +

Error type.

+ +
+
+ +
+
+ + + + +
const char* yaml_parser_s::problem
+
+
+ +

Error description.

+ +
+
+ +
+
+ + + + +
size_t yaml_parser_s::problem_offset
+
+
+ +

The byte about which the problem occured.

+ +
+
+ +
+ +
+ +

The problematic value (-1 is none).

+ +
+
+ +
+ +
+ +

The problem position.

+ +
+
+ +
+
+ + + + +
const char* yaml_parser_s::context
+
+
+ +

The error context.

+ +
+
+ +
+ +
+ +

The context position.

+ +
+
+ +
+ +
+ +

Read handler.

+ +
+
+ +
+ +
+ +

A pointer for passing to the read handler.

+ +
+
+ +
+
+ + + + +
const unsigned char* yaml_parser_s::start
+
+
+ +

The string start pointer.

+ +
+
+ +
+
+ + + + +
const unsigned char* yaml_parser_s::end
+
+
+ +

The string end pointer.

+ +
+
+ +
+
+ + + + +
const unsigned char* yaml_parser_s::current
+
+
+ +

The string current position.

+ +
+
+ +
+
+ + + + +
struct { ... } yaml_parser_s::string
+
+
+ +

String input data.

+ +
+
+ +
+
+ + + + +
FILE* yaml_parser_s::file
+
+
+ +

File input data.

+ +
+
+ +
+
+ + + + +
union { ... } yaml_parser_s::input
+
+
+ +

Standard (string or file) input data.

+ +
+
+ +
+ +
+ +

The beginning of the buffer.

+ +
+
+ +
+ +
+ +

The end of the buffer.

+ +
+
+ +
+ +
+ +

The current position of the buffer.

+ +
+
+ +
+ +
+ +

The last filled position of the buffer.

+ +
+
+ +
+
+ + + + +
struct { ... } yaml_parser_s::buffer
+
+
+ +

The working buffer.

+ +
+
+ +
+
+ + + + +
unsigned char* yaml_parser_s::start
+
+
+ +

The beginning of the buffer.

+ +
+
+ +
+
+ + + + +
unsigned char* yaml_parser_s::end
+
+
+ +

The end of the buffer.

+ +
+
+ +
+
+ + + + +
unsigned char* yaml_parser_s::pointer
+
+
+ +

The current position of the buffer.

+ +
+
+ +
+
+ + + + +
unsigned char* yaml_parser_s::last
+
+
+ +

The last filled position of the buffer.

+ +
+
+ +
+
+ + + + +
struct { ... } yaml_parser_s::raw_buffer
+
+
+ +

The raw buffer.

+ +
+
+ +
+ +
+ +

The input encoding.

+ +
+
+ +
+
+ + + + +
size_t yaml_parser_s::offset
+
+
+ +

The offset of the current position (in bytes).

+ +
+
+ +
+ +
+ +

The mark of the current position.

+ +
+
+ +
+
+ + + + +
int yaml_parser_s::flow_level
+
+
+ +

The number of unclosed '[' and '{' indicators.

+ +
+
+ +
+ +
+ +

The beginning of the tokens queue.

+ +
+
+ +
+ +
+ +

The end of the tokens queue.

+ +
+
+ +
+ +
+ +

The head of the tokens queue.

+ +
+
+ +
+ +
+ +

The tail of the tokens queue.

+ +
+
+ +
+
+ + + + +
struct { ... } yaml_parser_s::tokens
+
+
+ +

The tokens queue.

+ +
+
+ +
+
+ + + + +
size_t yaml_parser_s::tokens_parsed
+
+
+ +

The number of tokens fetched from the queue.

+ +
+
+ +
+
+ + + + +
int* yaml_parser_s::start
+
+
+ +

The beginning of the stack.

+ +
+
+ +
+
+ + + + +
int* yaml_parser_s::end
+
+
+ +

The end of the stack.

+ +
+
+ +
+
+ + + + +
int* yaml_parser_s::top
+
+
+ +

The top of the stack.

+ +
+
+ +
+
+ + + + +
struct { ... } yaml_parser_s::indents
+
+
+ +

The indentation levels stack.

+ +
+
+ +
+
+ + + + +
int yaml_parser_s::indent
+
+
+ +

The current indentation level.

+ +
+
+ +
+ +
+ +

The beginning of the stack.

+ +
+
+ +
+ +
+ +

The end of the stack.

+ +
+
+ +
+ +
+ +

The top of the stack.

+ +
+
+ +
+
+ + + + +
struct { ... } yaml_parser_s::simple_keys
+
+
+ +

The stack of simple keys.

+ +
+
+ +
+ +
+ +

The beginning of the stack.

+ +
+
+ +
+ +
+ +

The end of the stack.

+ +
+
+ +
+ +
+ +

The top of the stack.

+ +
+
+ +
+
+ + + + +
struct { ... } yaml_parser_s::states
+
+
+ +

The parser states stack.

+ +
+
+ +
+ +
+ +

The current parser state.

+ +
+
+ +
+ +
+ +

The beginning of the stack.

+ +
+
+ +
+ +
+ +

The end of the stack.

+ +
+
+ +
+ +
+ +

The top of the stack.

+ +
+
+ +
+
+ + + + +
struct { ... } yaml_parser_s::marks
+
+
+ +

The stack of marks.

+ +
+
+ +
+ +
+ +

The beginning of the list.

+ +
+
+ +
+ +
+ +

The end of the list.

+ +
+
+ +
+ +
+ +

The top of the list.

+ +
+
+ +
+
+ + + + +
struct { ... } yaml_parser_s::tag_directives
+
+
+ +

The list of TAG directives.

+ +
+
+ +
+ +
+ +

The beginning of the list.

+ +
+
+ +
+ +
+ +

The end of the list.

+ +
+
+ +
+ +
+ +

The top of the list.

+ +
+
+ +
+
+ + + + +
struct { ... } yaml_parser_s::aliases
+
+
+ +

The alias data.

+ +
+
+ +
+ +
+ +

The currently parsed document.

+ +
+
+
The documentation for this struct was generated from the following file: +
+ + + + + + diff --git a/libyaml/doc/html/structyaml__simple__key__s.html b/libyaml/doc/html/structyaml__simple__key__s.html new file mode 100644 index 00000000..8e4017e9 --- /dev/null +++ b/libyaml/doc/html/structyaml__simple__key__s.html @@ -0,0 +1,126 @@ + + + + + +yaml: yaml_simple_key_s Struct Reference + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.5 +
+ +
+
+ + + + +
+
+ +
+
yaml_simple_key_s Struct Reference
+
+
+ +

This structure holds information about a potential simple key. + More...

+ +

#include <yaml.h>

+ + + + + + + + + + +

+Data Fields

+int possible
 Is a simple key possible?
+int required
 Is a simple key required?
size_t token_number
 The number of the token.
yaml_mark_t mark
 The position mark.
+

Detailed Description

+

This structure holds information about a potential simple key.

+

Field Documentation

+ +
+ +
+ +

The number of the token.

+ +
+
+ +
+ +
+ +

The position mark.

+ +
+
+
The documentation for this struct was generated from the following file: +
+ + + + + + diff --git a/libyaml/doc/html/structyaml__tag__directive__s.html b/libyaml/doc/html/structyaml__tag__directive__s.html new file mode 100644 index 00000000..0c40dc4f --- /dev/null +++ b/libyaml/doc/html/structyaml__tag__directive__s.html @@ -0,0 +1,120 @@ + + + + + +yaml: yaml_tag_directive_s Struct Reference + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.5 +
+ +
+
+ + + + +
+
+ +
+
yaml_tag_directive_s Struct Reference
+
+
+ +

The tag directive data. + More...

+ +

#include <yaml.h>

+ + + + + + +

+Data Fields

yaml_char_thandle
 The tag handle.
yaml_char_tprefix
 The tag prefix.
+

Detailed Description

+

The tag directive data.

+

Field Documentation

+ +
+ +
+ +

The tag handle.

+ +
+
+ +
+ +
+ +

The tag prefix.

+ +
+
+
The documentation for this struct was generated from the following file: +
+ + + + + + diff --git a/libyaml/doc/html/structyaml__token__s.html b/libyaml/doc/html/structyaml__token__s.html new file mode 100644 index 00000000..15a47fa9 --- /dev/null +++ b/libyaml/doc/html/structyaml__token__s.html @@ -0,0 +1,442 @@ + + + + + +yaml: yaml_token_s Struct Reference + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.5 +
+ +
+
+ + + + +
+
+ +
+
yaml_token_s Struct Reference
+
+
+ +

The token structure. + More...

+ +

#include <yaml.h>

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Data Fields

yaml_token_type_t type
 The token type.
union {
   struct {
      yaml_encoding_t   encoding
 The stream encoding.
   }   stream_start
 The stream start (for YAML_STREAM_START_TOKEN).
   struct {
      yaml_char_t *   value
 The alias value.
   }   alias
 The alias (for YAML_ALIAS_TOKEN).
   struct {
      yaml_char_t *   value
 The anchor value.
   }   anchor
 The anchor (for YAML_ANCHOR_TOKEN).
   struct {
      yaml_char_t *   handle
 The tag handle.
      yaml_char_t *   suffix
 The tag suffix.
   }   tag
 The tag (for YAML_TAG_TOKEN).
   struct {
      yaml_char_t *   value
 The scalar value.
      size_t   length
 The length of the scalar value.
      yaml_scalar_style_t   style
 The scalar style.
   }   scalar
 The scalar value (for YAML_SCALAR_TOKEN).
   struct {
      int   major
 The major version number.
      int   minor
 The minor version number.
   }   version_directive
 The version directive (for YAML_VERSION_DIRECTIVE_TOKEN).
   struct {
      yaml_char_t *   handle
 The tag handle.
      yaml_char_t *   prefix
 The tag prefix.
   }   tag_directive
 The tag directive (for YAML_TAG_DIRECTIVE_TOKEN).
data
 The token data.
yaml_mark_t start_mark
 The beginning of the token.
yaml_mark_t end_mark
 The end of the token.
+

Detailed Description

+

The token structure.

+

Field Documentation

+ +
+ +
+ +

The token type.

+ +
+
+ +
+ +
+ +

The stream encoding.

+ +
+
+ +
+
+ + + + +
struct { ... } yaml_token_s::stream_start
+
+
+ +

The stream start (for YAML_STREAM_START_TOKEN).

+ +
+
+ +
+ +
+ +

The alias value.

+

The scalar value.

+

The anchor value.

+ +
+
+ +
+
+ + + + +
struct { ... } yaml_token_s::alias
+
+
+ +

The alias (for YAML_ALIAS_TOKEN).

+ +
+
+ +
+
+ + + + +
struct { ... } yaml_token_s::anchor
+
+
+ +

The anchor (for YAML_ANCHOR_TOKEN).

+ +
+
+ +
+ +
+ +

The tag handle.

+ +
+
+ +
+ +
+ +

The tag suffix.

+ +
+
+ +
+
+ + + + +
struct { ... } yaml_token_s::tag
+
+
+ +

The tag (for YAML_TAG_TOKEN).

+ +
+
+ +
+
+ + + + +
size_t yaml_token_s::length
+
+
+ +

The length of the scalar value.

+ +
+
+ +
+ +
+ +

The scalar style.

+ +
+
+ +
+
+ + + + +
struct { ... } yaml_token_s::scalar
+
+
+ +

The scalar value (for YAML_SCALAR_TOKEN).

+ +
+
+ +
+
+ + + + +
int yaml_token_s::major
+
+
+ +

The major version number.

+ +
+
+ +
+
+ + + + +
int yaml_token_s::minor
+
+
+ +

The minor version number.

+ +
+
+ +
+
+ + + + +
struct { ... } yaml_token_s::version_directive
+
+
+ +

The version directive (for YAML_VERSION_DIRECTIVE_TOKEN).

+ +
+
+ +
+ +
+ +

The tag prefix.

+ +
+
+ +
+
+ + + + +
struct { ... } yaml_token_s::tag_directive
+
+
+ +

The tag directive (for YAML_TAG_DIRECTIVE_TOKEN).

+ +
+
+ +
+
+ + + + +
union { ... } yaml_token_s::data
+
+
+ +

The token data.

+ +
+
+ +
+ +
+ +

The beginning of the token.

+ +
+
+ +
+ +
+ +

The end of the token.

+ +
+
+
The documentation for this struct was generated from the following file: +
+ + + + + + diff --git a/libyaml/doc/html/structyaml__version__directive__s.html b/libyaml/doc/html/structyaml__version__directive__s.html new file mode 100644 index 00000000..b8faa294 --- /dev/null +++ b/libyaml/doc/html/structyaml__version__directive__s.html @@ -0,0 +1,120 @@ + + + + + +yaml: yaml_version_directive_s Struct Reference + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.5 +
+ +
+
+ + + + +
+
+ +
+
yaml_version_directive_s Struct Reference
+
+
+ +

The version directive data. + More...

+ +

#include <yaml.h>

+ + + + + + +

+Data Fields

int major
 The major version number.
int minor
 The minor version number.
+

Detailed Description

+

The version directive data.

+

Field Documentation

+ +
+ +
+ +

The major version number.

+ +
+
+ +
+ +
+ +

The minor version number.

+ +
+
+
The documentation for this struct was generated from the following file: +
+ + + + + + diff --git a/libyaml/doc/html/tab_a.png b/libyaml/doc/html/tab_a.png new file mode 100644 index 0000000000000000000000000000000000000000..2d99ef23fed78c7683f0b5aa803d937060d288c4 GIT binary patch literal 140 zcmeAS@N?(olHy`uVBq!ia0vp^j6kfy!2~3aiye;!Qo)`sjv*C{Z|CmjY;X`^DSv)) z;hc^cTF;t%XWXdwWP5+kt?jQ5uhqKtjd^EY`^^-S;M%tFAj_l)EwVTK)E@1LSD0{e q?a6($SGQTzz1#QBzr0NMKf^0WCX-0bi?u-G89ZJ6T-G@yGywp8?ljB* literal 0 HcmV?d00001 diff --git a/libyaml/doc/html/tab_b.png b/libyaml/doc/html/tab_b.png new file mode 100644 index 0000000000000000000000000000000000000000..b2c3d2be3c7e518fbca6bb30f571882e72fc506d GIT binary patch literal 178 zcmeAS@N?(olHy`uVBq!ia0vp^j6kfy!2~3aiye;!Qk9-Ajv*C{Z|~mbJ)|JfaM8Xd zIP7xAmLwau9@iXhZTrl-TjWj9jM#?{xt`6uU{<)jb9Suc^QnbhJ(o{ib8=j9u0_mE8M7kgF7f<7W7IEf=8(L_qx|g0H;V7iPxm&Q@G7p8W2Kx&iT|YUM=ITC zY<0Qbr;u&AtXD{o@41wH=7&d8=2Z_{M9Tsa=g*t*@A3H$UOlxZk7?f6RUWpx>Fc_L s#LQ{edY3MpIXkMeV^&YV=9fR%8Jv|Kya=#u06K}m)78&qol`;+0RKEt)&Kwi literal 0 HcmV?d00001 diff --git a/libyaml/doc/html/tab_s.png b/libyaml/doc/html/tab_s.png new file mode 100644 index 0000000000000000000000000000000000000000..978943ac807718de0e69e5a585a8f0a1e5999285 GIT binary patch literal 189 zcmeAS@N?(olHy`uVBq!ia0vp^j6kfy!2~3aiye;!QZ1e?jv*C{Z|}b5Yzkm-c<7z3 zq^cq0=~}Z;b(!Zvb5Z%sTRFKGlz1=qOFg;myyu?$r`wZb^irPsN1a)6)TwB0r+)wb zPL25;=adu89?fTK`qDR>$D*)b_WOmdKI;Vst02j(hg8%>k literal 0 HcmV?d00001 diff --git a/libyaml/doc/html/tabs.css b/libyaml/doc/html/tabs.css new file mode 100644 index 00000000..21920562 --- /dev/null +++ b/libyaml/doc/html/tabs.css @@ -0,0 +1,59 @@ +.tabs, .tabs2, .tabs3 { + background-image: url('tab_b.png'); + width: 100%; + z-index: 101; + font-size: 13px; +} + +.tabs2 { + font-size: 10px; +} +.tabs3 { + font-size: 9px; +} + +.tablist { + margin: 0; + padding: 0; + display: table; +} + +.tablist li { + float: left; + display: table-cell; + background-image: url('tab_b.png'); + line-height: 36px; + list-style: none; +} + +.tablist a { + display: block; + padding: 0 20px; + font-weight: bold; + background-image:url('tab_s.png'); + background-repeat:no-repeat; + background-position:right; + color: #283A5D; + text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9); + text-decoration: none; + outline: none; +} + +.tabs3 .tablist a { + padding: 0 10px; +} + +.tablist a:hover { + background-image: url('tab_h.png'); + background-repeat:repeat-x; + color: #fff; + text-shadow: 0px 1px 1px rgba(0, 0, 0, 1.0); + text-decoration: none; +} + +.tablist li.current a { + background-image: url('tab_a.png'); + background-repeat:repeat-x; + color: #fff; + text-shadow: 0px 1px 1px rgba(0, 0, 0, 1.0); +} diff --git a/libyaml/doc/html/yaml_8h.html b/libyaml/doc/html/yaml_8h.html new file mode 100644 index 00000000..8b7631d6 --- /dev/null +++ b/libyaml/doc/html/yaml_8h.html @@ -0,0 +1,546 @@ + + + + + +yaml: yaml.h File Reference + + + + + + + + +
+ + +
+ + + + + + + + + + + +
+
yaml +  0.1.5 +
+ +
+
+ + + + +
+
+ +
+
yaml.h File Reference
+
+
+ +

Public interface for libyaml. +More...

+
#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Data Structures

struct  yaml_version_directive_s
 The version directive data. More...
struct  yaml_tag_directive_s
 The tag directive data. More...
struct  yaml_mark_s
 The pointer position. More...
struct  yaml_token_s
 The token structure. More...
struct  yaml_event_s
 The event structure. More...
struct  yaml_node_pair_s
 An element of a mapping node. More...
struct  yaml_node_s
 The node structure. More...
struct  yaml_document_s
 The document structure. More...
struct  yaml_simple_key_s
 This structure holds information about a potential simple key. More...
struct  yaml_alias_data_s
 This structure holds aliases data. More...
struct  yaml_parser_s
 The parser structure. More...
struct  yaml_emitter_s
 The emitter structure. More...

+Defines

#define YAML_DECLARE(type)   type
 The public API declaration.
#define YAML_NULL_TAG   "tag:yaml.org,2002:null"
 The tag !!null with the only possible value: null.
#define YAML_BOOL_TAG   "tag:yaml.org,2002:bool"
 The tag !!bool with the values: true and falce.
#define YAML_STR_TAG   "tag:yaml.org,2002:str"
 The tag !!str for string values.
#define YAML_INT_TAG   "tag:yaml.org,2002:int"
 The tag !!int for integer values.
#define YAML_FLOAT_TAG   "tag:yaml.org,2002:float"
 The tag !!float for float values.
#define YAML_TIMESTAMP_TAG   "tag:yaml.org,2002:timestamp"
 The tag !!timestamp for date and time values.
#define YAML_SEQ_TAG   "tag:yaml.org,2002:seq"
 The tag !!seq is used to denote sequences.
#define YAML_MAP_TAG   "tag:yaml.org,2002:map"
 The tag !!map is used to denote mapping.
#define YAML_DEFAULT_SCALAR_TAG   YAML_STR_TAG
 The default scalar tag is !!str.
#define YAML_DEFAULT_SEQUENCE_TAG   YAML_SEQ_TAG
 The default sequence tag is !!seq.
#define YAML_DEFAULT_MAPPING_TAG   YAML_MAP_TAG
 The default mapping tag is !!map.

+Typedefs

typedef unsigned char yaml_char_t
 The character type (UTF-8 octet).
typedef struct
+yaml_version_directive_s 
yaml_version_directive_t
 The version directive data.
typedef struct yaml_tag_directive_s yaml_tag_directive_t
 The tag directive data.
typedef enum yaml_encoding_e yaml_encoding_t
 The stream encoding.
typedef enum yaml_break_e yaml_break_t
 Line break types.
typedef enum yaml_error_type_e yaml_error_type_t
 Many bad things could happen with the parser and emitter.
typedef struct yaml_mark_s yaml_mark_t
 The pointer position.
typedef enum yaml_scalar_style_e yaml_scalar_style_t
 Scalar styles.
typedef enum yaml_sequence_style_e yaml_sequence_style_t
 Sequence styles.
typedef enum yaml_mapping_style_e yaml_mapping_style_t
 Mapping styles.
typedef enum yaml_token_type_e yaml_token_type_t
 Token types.
typedef struct yaml_token_s yaml_token_t
 The token structure.
typedef enum yaml_event_type_e yaml_event_type_t
 Event types.
typedef struct yaml_event_s yaml_event_t
 The event structure.
typedef enum yaml_node_type_e yaml_node_type_t
 Node types.
typedef struct yaml_node_s yaml_node_t
 The forward definition of a document node structure.
typedef int yaml_node_item_t
 An element of a sequence node.
typedef struct yaml_node_pair_s yaml_node_pair_t
 An element of a mapping node.
typedef struct yaml_document_s yaml_document_t
 The document structure.
typedef int yaml_read_handler_t (void *data, unsigned char *buffer, size_t size, size_t *size_read)
 The prototype of a read handler.
+typedef struct yaml_simple_key_s yaml_simple_key_t
 This structure holds information about a potential simple key.
+typedef enum yaml_parser_state_e yaml_parser_state_t
 The states of the parser.
+typedef struct yaml_alias_data_s yaml_alias_data_t
 This structure holds aliases data.
typedef struct yaml_parser_s yaml_parser_t
 The parser structure.
typedef int yaml_write_handler_t (void *data, unsigned char *buffer, size_t size)
 The prototype of a write handler.
typedef enum yaml_emitter_state_e yaml_emitter_state_t
 The emitter states.
typedef struct yaml_emitter_s yaml_emitter_t
 The emitter structure.

+Enumerations

enum  yaml_encoding_e {
+  YAML_ANY_ENCODING, +
+  YAML_UTF8_ENCODING, +
+  YAML_UTF16LE_ENCODING, +
+  YAML_UTF16BE_ENCODING +
+ }
 The stream encoding. More...
enum  yaml_break_e {
+  YAML_ANY_BREAK, +
+  YAML_CR_BREAK, +
+  YAML_LN_BREAK, +
+  YAML_CRLN_BREAK +
+ }
 Line break types. More...
enum  yaml_error_type_e {
+  YAML_NO_ERROR, +
+  YAML_MEMORY_ERROR, +
+  YAML_READER_ERROR, +
+  YAML_SCANNER_ERROR, +
+  YAML_PARSER_ERROR, +
+  YAML_COMPOSER_ERROR, +
+  YAML_WRITER_ERROR, +
+  YAML_EMITTER_ERROR +
+ }
 Many bad things could happen with the parser and emitter. More...
enum  yaml_scalar_style_e {
+  YAML_ANY_SCALAR_STYLE, +
+  YAML_PLAIN_SCALAR_STYLE, +
+  YAML_SINGLE_QUOTED_SCALAR_STYLE, +
+  YAML_DOUBLE_QUOTED_SCALAR_STYLE, +
+  YAML_LITERAL_SCALAR_STYLE, +
+  YAML_FOLDED_SCALAR_STYLE +
+ }
 Scalar styles. More...
enum  yaml_sequence_style_e {
+  YAML_ANY_SEQUENCE_STYLE, +
+  YAML_BLOCK_SEQUENCE_STYLE, +
+  YAML_FLOW_SEQUENCE_STYLE +
+ }
 Sequence styles. More...
enum  yaml_mapping_style_e {
+  YAML_ANY_MAPPING_STYLE, +
+  YAML_BLOCK_MAPPING_STYLE, +
+  YAML_FLOW_MAPPING_STYLE +
+ }
 Mapping styles. More...
enum  yaml_token_type_e {
+  YAML_NO_TOKEN, +
+  YAML_STREAM_START_TOKEN, +
+  YAML_STREAM_END_TOKEN, +
+  YAML_VERSION_DIRECTIVE_TOKEN, +
+  YAML_TAG_DIRECTIVE_TOKEN, +
+  YAML_DOCUMENT_START_TOKEN, +
+  YAML_DOCUMENT_END_TOKEN, +
+  YAML_BLOCK_SEQUENCE_START_TOKEN, +
+  YAML_BLOCK_MAPPING_START_TOKEN, +
+  YAML_BLOCK_END_TOKEN, +
+  YAML_FLOW_SEQUENCE_START_TOKEN, +
+  YAML_FLOW_SEQUENCE_END_TOKEN, +
+  YAML_FLOW_MAPPING_START_TOKEN, +
+  YAML_FLOW_MAPPING_END_TOKEN, +
+  YAML_BLOCK_ENTRY_TOKEN, +
+  YAML_FLOW_ENTRY_TOKEN, +
+  YAML_KEY_TOKEN, +
+  YAML_VALUE_TOKEN, +
+  YAML_ALIAS_TOKEN, +
+  YAML_ANCHOR_TOKEN, +
+  YAML_TAG_TOKEN, +
+  YAML_SCALAR_TOKEN +
+ }
 Token types. More...
enum  yaml_event_type_e {
+  YAML_NO_EVENT, +
+  YAML_STREAM_START_EVENT, +
+  YAML_STREAM_END_EVENT, +
+  YAML_DOCUMENT_START_EVENT, +
+  YAML_DOCUMENT_END_EVENT, +
+  YAML_ALIAS_EVENT, +
+  YAML_SCALAR_EVENT, +
+  YAML_SEQUENCE_START_EVENT, +
+  YAML_SEQUENCE_END_EVENT, +
+  YAML_MAPPING_START_EVENT, +
+  YAML_MAPPING_END_EVENT +
+ }
 Event types. More...
enum  yaml_node_type_e {
+  YAML_NO_NODE, +
+  YAML_SCALAR_NODE, +
+  YAML_SEQUENCE_NODE, +
+  YAML_MAPPING_NODE +
+ }
 Node types. More...
enum  yaml_parser_state_e {
+  YAML_PARSE_STREAM_START_STATE, +
+  YAML_PARSE_IMPLICIT_DOCUMENT_START_STATE, +
+  YAML_PARSE_DOCUMENT_START_STATE, +
+  YAML_PARSE_DOCUMENT_CONTENT_STATE, +
+  YAML_PARSE_DOCUMENT_END_STATE, +
+  YAML_PARSE_BLOCK_NODE_STATE, +
+  YAML_PARSE_BLOCK_NODE_OR_INDENTLESS_SEQUENCE_STATE, +
+  YAML_PARSE_FLOW_NODE_STATE, +
+  YAML_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE, +
+  YAML_PARSE_BLOCK_SEQUENCE_ENTRY_STATE, +
+  YAML_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE, +
+  YAML_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE, +
+  YAML_PARSE_BLOCK_MAPPING_KEY_STATE, +
+  YAML_PARSE_BLOCK_MAPPING_VALUE_STATE, +
+  YAML_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE, +
+  YAML_PARSE_FLOW_SEQUENCE_ENTRY_STATE, +
+  YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE, +
+  YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE, +
+  YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE, +
+  YAML_PARSE_FLOW_MAPPING_FIRST_KEY_STATE, +
+  YAML_PARSE_FLOW_MAPPING_KEY_STATE, +
+  YAML_PARSE_FLOW_MAPPING_VALUE_STATE, +
+  YAML_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE, +
+  YAML_PARSE_END_STATE +
+ }
 The states of the parser. More...
enum  yaml_emitter_state_e {
+  YAML_EMIT_STREAM_START_STATE, +
+  YAML_EMIT_FIRST_DOCUMENT_START_STATE, +
+  YAML_EMIT_DOCUMENT_START_STATE, +
+  YAML_EMIT_DOCUMENT_CONTENT_STATE, +
+  YAML_EMIT_DOCUMENT_END_STATE, +
+  YAML_EMIT_FLOW_SEQUENCE_FIRST_ITEM_STATE, +
+  YAML_EMIT_FLOW_SEQUENCE_ITEM_STATE, +
+  YAML_EMIT_FLOW_MAPPING_FIRST_KEY_STATE, +
+  YAML_EMIT_FLOW_MAPPING_KEY_STATE, +
+  YAML_EMIT_FLOW_MAPPING_SIMPLE_VALUE_STATE, +
+  YAML_EMIT_FLOW_MAPPING_VALUE_STATE, +
+  YAML_EMIT_BLOCK_SEQUENCE_FIRST_ITEM_STATE, +
+  YAML_EMIT_BLOCK_SEQUENCE_ITEM_STATE, +
+  YAML_EMIT_BLOCK_MAPPING_FIRST_KEY_STATE, +
+  YAML_EMIT_BLOCK_MAPPING_KEY_STATE, +
+  YAML_EMIT_BLOCK_MAPPING_SIMPLE_VALUE_STATE, +
+  YAML_EMIT_BLOCK_MAPPING_VALUE_STATE, +
+  YAML_EMIT_END_STATE +
+ }
 The emitter states. More...

+Functions

const char * yaml_get_version_string (void)
 Get the library version as a string.
void yaml_get_version (int *major, int *minor, int *patch)
 Get the library version numbers.
void yaml_token_delete (yaml_token_t *token)
 Free any memory allocated for a token object.
int yaml_stream_start_event_initialize (yaml_event_t *event, yaml_encoding_t encoding)
 Create the STREAM-START event.
int yaml_stream_end_event_initialize (yaml_event_t *event)
 Create the STREAM-END event.
int yaml_document_start_event_initialize (yaml_event_t *event, yaml_version_directive_t *version_directive, yaml_tag_directive_t *tag_directives_start, yaml_tag_directive_t *tag_directives_end, int implicit)
 Create the DOCUMENT-START event.
int yaml_document_end_event_initialize (yaml_event_t *event, int implicit)
 Create the DOCUMENT-END event.
int yaml_alias_event_initialize (yaml_event_t *event, yaml_char_t *anchor)
 Create an ALIAS event.
int yaml_scalar_event_initialize (yaml_event_t *event, yaml_char_t *anchor, yaml_char_t *tag, yaml_char_t *value, int length, int plain_implicit, int quoted_implicit, yaml_scalar_style_t style)
 Create a SCALAR event.
int yaml_sequence_start_event_initialize (yaml_event_t *event, yaml_char_t *anchor, yaml_char_t *tag, int implicit, yaml_sequence_style_t style)
 Create a SEQUENCE-START event.
int yaml_sequence_end_event_initialize (yaml_event_t *event)
 Create a SEQUENCE-END event.
int yaml_mapping_start_event_initialize (yaml_event_t *event, yaml_char_t *anchor, yaml_char_t *tag, int implicit, yaml_mapping_style_t style)
 Create a MAPPING-START event.
int yaml_mapping_end_event_initialize (yaml_event_t *event)
 Create a MAPPING-END event.
void yaml_event_delete (yaml_event_t *event)
 Free any memory allocated for an event object.
int yaml_document_initialize (yaml_document_t *document, yaml_version_directive_t *version_directive, yaml_tag_directive_t *tag_directives_start, yaml_tag_directive_t *tag_directives_end, int start_implicit, int end_implicit)
 Create a YAML document.
void yaml_document_delete (yaml_document_t *document)
 Delete a YAML document and all its nodes.
yaml_node_tyaml_document_get_node (yaml_document_t *document, int index)
 Get a node of a YAML document.
yaml_node_tyaml_document_get_root_node (yaml_document_t *document)
 Get the root of a YAML document node.
int yaml_document_add_scalar (yaml_document_t *document, yaml_char_t *tag, yaml_char_t *value, int length, yaml_scalar_style_t style)
 Create a SCALAR node and attach it to the document.
int yaml_document_add_sequence (yaml_document_t *document, yaml_char_t *tag, yaml_sequence_style_t style)
 Create a SEQUENCE node and attach it to the document.
int yaml_document_add_mapping (yaml_document_t *document, yaml_char_t *tag, yaml_mapping_style_t style)
 Create a MAPPING node and attach it to the document.
int yaml_document_append_sequence_item (yaml_document_t *document, int sequence, int item)
 Add an item to a SEQUENCE node.
int yaml_document_append_mapping_pair (yaml_document_t *document, int mapping, int key, int value)
 Add a pair of a key and a value to a MAPPING node.
int yaml_parser_initialize (yaml_parser_t *parser)
 Initialize a parser.
void yaml_parser_delete (yaml_parser_t *parser)
 Destroy a parser.
void yaml_parser_set_input_string (yaml_parser_t *parser, const unsigned char *input, size_t size)
 Set a string input.
void yaml_parser_set_input_file (yaml_parser_t *parser, FILE *file)
 Set a file input.
void yaml_parser_set_input (yaml_parser_t *parser, yaml_read_handler_t *handler, void *data)
 Set a generic input handler.
void yaml_parser_set_encoding (yaml_parser_t *parser, yaml_encoding_t encoding)
 Set the source encoding.
int yaml_parser_scan (yaml_parser_t *parser, yaml_token_t *token)
 Scan the input stream and produce the next token.
int yaml_parser_parse (yaml_parser_t *parser, yaml_event_t *event)
 Parse the input stream and produce the next parsing event.
int yaml_parser_load (yaml_parser_t *parser, yaml_document_t *document)
 Parse the input stream and produce the next YAML document.
int yaml_emitter_initialize (yaml_emitter_t *emitter)
 Initialize an emitter.
void yaml_emitter_delete (yaml_emitter_t *emitter)
 Destroy an emitter.
void yaml_emitter_set_output_string (yaml_emitter_t *emitter, unsigned char *output, size_t size, size_t *size_written)
 Set a string output.
void yaml_emitter_set_output_file (yaml_emitter_t *emitter, FILE *file)
 Set a file output.
void yaml_emitter_set_output (yaml_emitter_t *emitter, yaml_write_handler_t *handler, void *data)
 Set a generic output handler.
void yaml_emitter_set_encoding (yaml_emitter_t *emitter, yaml_encoding_t encoding)
 Set the output encoding.
void yaml_emitter_set_canonical (yaml_emitter_t *emitter, int canonical)
 Set if the output should be in the "canonical" format as in the YAML specification.
void yaml_emitter_set_indent (yaml_emitter_t *emitter, int indent)
 Set the intendation increment.
void yaml_emitter_set_width (yaml_emitter_t *emitter, int width)
 Set the preferred line width.
void yaml_emitter_set_unicode (yaml_emitter_t *emitter, int unicode)
 Set if unescaped non-ASCII characters are allowed.
void yaml_emitter_set_break (yaml_emitter_t *emitter, yaml_break_t line_break)
 Set the preferred line break.
int yaml_emitter_emit (yaml_emitter_t *emitter, yaml_event_t *event)
 Emit an event.
int yaml_emitter_open (yaml_emitter_t *emitter)
 Start a YAML stream.
int yaml_emitter_close (yaml_emitter_t *emitter)
 Finish a YAML stream.
int yaml_emitter_dump (yaml_emitter_t *emitter, yaml_document_t *document)
 Emit a YAML document.
int yaml_emitter_flush (yaml_emitter_t *emitter)
 Flush the accumulated characters to the output.
+

Detailed Description

+

Public interface for libyaml.

+

Include the header file with the code:

+
 #include <yaml.h>
+
+ + + + + + diff --git a/libyaml/include/yaml.h b/libyaml/include/yaml.h new file mode 100644 index 00000000..5a04d36d --- /dev/null +++ b/libyaml/include/yaml.h @@ -0,0 +1,1971 @@ +/** + * @file yaml.h + * @brief Public interface for libyaml. + * + * Include the header file with the code: + * @code + * #include + * @endcode + */ + +#ifndef YAML_H +#define YAML_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include + +/** + * @defgroup export Export Definitions + * @{ + */ + +/** The public API declaration. */ + +#ifdef _WIN32 +# if defined(YAML_DECLARE_STATIC) +# define YAML_DECLARE(type) type +# elif defined(YAML_DECLARE_EXPORT) +# define YAML_DECLARE(type) __declspec(dllexport) type +# else +# define YAML_DECLARE(type) __declspec(dllimport) type +# endif +#else +# define YAML_DECLARE(type) type +#endif + +/** @} */ + +/** + * @defgroup version Version Information + * @{ + */ + +/** + * Get the library version as a string. + * + * @returns The function returns the pointer to a static string of the form + * @c "X.Y.Z", where @c X is the major version number, @c Y is a minor version + * number, and @c Z is the patch version number. + */ + +YAML_DECLARE(const char *) +yaml_get_version_string(void); + +/** + * Get the library version numbers. + * + * @param[out] major Major version number. + * @param[out] minor Minor version number. + * @param[out] patch Patch version number. + */ + +YAML_DECLARE(void) +yaml_get_version(int *major, int *minor, int *patch); + +/** @} */ + +/** + * @defgroup basic Basic Types + * @{ + */ + +/** The character type (UTF-8 octet). */ +typedef unsigned char yaml_char_t; + +/** The version directive data. */ +typedef struct yaml_version_directive_s { + /** The major version number. */ + int major; + /** The minor version number. */ + int minor; +} yaml_version_directive_t; + +/** The tag directive data. */ +typedef struct yaml_tag_directive_s { + /** The tag handle. */ + yaml_char_t *handle; + /** The tag prefix. */ + yaml_char_t *prefix; +} yaml_tag_directive_t; + +/** The stream encoding. */ +typedef enum yaml_encoding_e { + /** Let the parser choose the encoding. */ + YAML_ANY_ENCODING, + /** The default UTF-8 encoding. */ + YAML_UTF8_ENCODING, + /** The UTF-16-LE encoding with BOM. */ + YAML_UTF16LE_ENCODING, + /** The UTF-16-BE encoding with BOM. */ + YAML_UTF16BE_ENCODING +} yaml_encoding_t; + +/** Line break types. */ + +typedef enum yaml_break_e { + /** Let the parser choose the break type. */ + YAML_ANY_BREAK, + /** Use CR for line breaks (Mac style). */ + YAML_CR_BREAK, + /** Use LN for line breaks (Unix style). */ + YAML_LN_BREAK, + /** Use CR LN for line breaks (DOS style). */ + YAML_CRLN_BREAK +} yaml_break_t; + +/** Many bad things could happen with the parser and emitter. */ +typedef enum yaml_error_type_e { + /** No error is produced. */ + YAML_NO_ERROR, + + /** Cannot allocate or reallocate a block of memory. */ + YAML_MEMORY_ERROR, + + /** Cannot read or decode the input stream. */ + YAML_READER_ERROR, + /** Cannot scan the input stream. */ + YAML_SCANNER_ERROR, + /** Cannot parse the input stream. */ + YAML_PARSER_ERROR, + /** Cannot compose a YAML document. */ + YAML_COMPOSER_ERROR, + + /** Cannot write to the output stream. */ + YAML_WRITER_ERROR, + /** Cannot emit a YAML stream. */ + YAML_EMITTER_ERROR +} yaml_error_type_t; + +/** The pointer position. */ +typedef struct yaml_mark_s { + /** The position index. */ + size_t index; + + /** The position line. */ + size_t line; + + /** The position column. */ + size_t column; +} yaml_mark_t; + +/** @} */ + +/** + * @defgroup styles Node Styles + * @{ + */ + +/** Scalar styles. */ +typedef enum yaml_scalar_style_e { + /** Let the emitter choose the style. */ + YAML_ANY_SCALAR_STYLE, + + /** The plain scalar style. */ + YAML_PLAIN_SCALAR_STYLE, + + /** The single-quoted scalar style. */ + YAML_SINGLE_QUOTED_SCALAR_STYLE, + /** The double-quoted scalar style. */ + YAML_DOUBLE_QUOTED_SCALAR_STYLE, + + /** The literal scalar style. */ + YAML_LITERAL_SCALAR_STYLE, + /** The folded scalar style. */ + YAML_FOLDED_SCALAR_STYLE +} yaml_scalar_style_t; + +/** Sequence styles. */ +typedef enum yaml_sequence_style_e { + /** Let the emitter choose the style. */ + YAML_ANY_SEQUENCE_STYLE, + + /** The block sequence style. */ + YAML_BLOCK_SEQUENCE_STYLE, + /** The flow sequence style. */ + YAML_FLOW_SEQUENCE_STYLE +} yaml_sequence_style_t; + +/** Mapping styles. */ +typedef enum yaml_mapping_style_e { + /** Let the emitter choose the style. */ + YAML_ANY_MAPPING_STYLE, + + /** The block mapping style. */ + YAML_BLOCK_MAPPING_STYLE, + /** The flow mapping style. */ + YAML_FLOW_MAPPING_STYLE +/* YAML_FLOW_SET_MAPPING_STYLE */ +} yaml_mapping_style_t; + +/** @} */ + +/** + * @defgroup tokens Tokens + * @{ + */ + +/** Token types. */ +typedef enum yaml_token_type_e { + /** An empty token. */ + YAML_NO_TOKEN, + + /** A STREAM-START token. */ + YAML_STREAM_START_TOKEN, + /** A STREAM-END token. */ + YAML_STREAM_END_TOKEN, + + /** A VERSION-DIRECTIVE token. */ + YAML_VERSION_DIRECTIVE_TOKEN, + /** A TAG-DIRECTIVE token. */ + YAML_TAG_DIRECTIVE_TOKEN, + /** A DOCUMENT-START token. */ + YAML_DOCUMENT_START_TOKEN, + /** A DOCUMENT-END token. */ + YAML_DOCUMENT_END_TOKEN, + + /** A BLOCK-SEQUENCE-START token. */ + YAML_BLOCK_SEQUENCE_START_TOKEN, + /** A BLOCK-SEQUENCE-END token. */ + YAML_BLOCK_MAPPING_START_TOKEN, + /** A BLOCK-END token. */ + YAML_BLOCK_END_TOKEN, + + /** A FLOW-SEQUENCE-START token. */ + YAML_FLOW_SEQUENCE_START_TOKEN, + /** A FLOW-SEQUENCE-END token. */ + YAML_FLOW_SEQUENCE_END_TOKEN, + /** A FLOW-MAPPING-START token. */ + YAML_FLOW_MAPPING_START_TOKEN, + /** A FLOW-MAPPING-END token. */ + YAML_FLOW_MAPPING_END_TOKEN, + + /** A BLOCK-ENTRY token. */ + YAML_BLOCK_ENTRY_TOKEN, + /** A FLOW-ENTRY token. */ + YAML_FLOW_ENTRY_TOKEN, + /** A KEY token. */ + YAML_KEY_TOKEN, + /** A VALUE token. */ + YAML_VALUE_TOKEN, + + /** An ALIAS token. */ + YAML_ALIAS_TOKEN, + /** An ANCHOR token. */ + YAML_ANCHOR_TOKEN, + /** A TAG token. */ + YAML_TAG_TOKEN, + /** A SCALAR token. */ + YAML_SCALAR_TOKEN +} yaml_token_type_t; + +/** The token structure. */ +typedef struct yaml_token_s { + + /** The token type. */ + yaml_token_type_t type; + + /** The token data. */ + union { + + /** The stream start (for @c YAML_STREAM_START_TOKEN). */ + struct { + /** The stream encoding. */ + yaml_encoding_t encoding; + } stream_start; + + /** The alias (for @c YAML_ALIAS_TOKEN). */ + struct { + /** The alias value. */ + yaml_char_t *value; + } alias; + + /** The anchor (for @c YAML_ANCHOR_TOKEN). */ + struct { + /** The anchor value. */ + yaml_char_t *value; + } anchor; + + /** The tag (for @c YAML_TAG_TOKEN). */ + struct { + /** The tag handle. */ + yaml_char_t *handle; + /** The tag suffix. */ + yaml_char_t *suffix; + } tag; + + /** The scalar value (for @c YAML_SCALAR_TOKEN). */ + struct { + /** The scalar value. */ + yaml_char_t *value; + /** The length of the scalar value. */ + size_t length; + /** The scalar style. */ + yaml_scalar_style_t style; + } scalar; + + /** The version directive (for @c YAML_VERSION_DIRECTIVE_TOKEN). */ + struct { + /** The major version number. */ + int major; + /** The minor version number. */ + int minor; + } version_directive; + + /** The tag directive (for @c YAML_TAG_DIRECTIVE_TOKEN). */ + struct { + /** The tag handle. */ + yaml_char_t *handle; + /** The tag prefix. */ + yaml_char_t *prefix; + } tag_directive; + + } data; + + /** The beginning of the token. */ + yaml_mark_t start_mark; + /** The end of the token. */ + yaml_mark_t end_mark; + +} yaml_token_t; + +/** + * Free any memory allocated for a token object. + * + * @param[in,out] token A token object. + */ + +YAML_DECLARE(void) +yaml_token_delete(yaml_token_t *token); + +/** @} */ + +/** + * @defgroup events Events + * @{ + */ + +/** Event types. */ +typedef enum yaml_event_type_e { + /** An empty event. */ + YAML_NO_EVENT, + + /** A STREAM-START event. */ + YAML_STREAM_START_EVENT, + /** A STREAM-END event. */ + YAML_STREAM_END_EVENT, + + /** A DOCUMENT-START event. */ + YAML_DOCUMENT_START_EVENT, + /** A DOCUMENT-END event. */ + YAML_DOCUMENT_END_EVENT, + + /** An ALIAS event. */ + YAML_ALIAS_EVENT, + /** A SCALAR event. */ + YAML_SCALAR_EVENT, + + /** A SEQUENCE-START event. */ + YAML_SEQUENCE_START_EVENT, + /** A SEQUENCE-END event. */ + YAML_SEQUENCE_END_EVENT, + + /** A MAPPING-START event. */ + YAML_MAPPING_START_EVENT, + /** A MAPPING-END event. */ + YAML_MAPPING_END_EVENT +} yaml_event_type_t; + +/** The event structure. */ +typedef struct yaml_event_s { + + /** The event type. */ + yaml_event_type_t type; + + /** The event data. */ + union { + + /** The stream parameters (for @c YAML_STREAM_START_EVENT). */ + struct { + /** The document encoding. */ + yaml_encoding_t encoding; + } stream_start; + + /** The document parameters (for @c YAML_DOCUMENT_START_EVENT). */ + struct { + /** The version directive. */ + yaml_version_directive_t *version_directive; + + /** The list of tag directives. */ + struct { + /** The beginning of the tag directives list. */ + yaml_tag_directive_t *start; + /** The end of the tag directives list. */ + yaml_tag_directive_t *end; + } tag_directives; + + /** Is the document indicator implicit? */ + int implicit; + } document_start; + + /** The document end parameters (for @c YAML_DOCUMENT_END_EVENT). */ + struct { + /** Is the document end indicator implicit? */ + int implicit; + } document_end; + + /** The alias parameters (for @c YAML_ALIAS_EVENT). */ + struct { + /** The anchor. */ + yaml_char_t *anchor; + } alias; + + /** The scalar parameters (for @c YAML_SCALAR_EVENT). */ + struct { + /** The anchor. */ + yaml_char_t *anchor; + /** The tag. */ + yaml_char_t *tag; + /** The scalar value. */ + yaml_char_t *value; + /** The length of the scalar value. */ + size_t length; + /** Is the tag optional for the plain style? */ + int plain_implicit; + /** Is the tag optional for any non-plain style? */ + int quoted_implicit; + /** The scalar style. */ + yaml_scalar_style_t style; + } scalar; + + /** The sequence parameters (for @c YAML_SEQUENCE_START_EVENT). */ + struct { + /** The anchor. */ + yaml_char_t *anchor; + /** The tag. */ + yaml_char_t *tag; + /** Is the tag optional? */ + int implicit; + /** The sequence style. */ + yaml_sequence_style_t style; + } sequence_start; + + /** The mapping parameters (for @c YAML_MAPPING_START_EVENT). */ + struct { + /** The anchor. */ + yaml_char_t *anchor; + /** The tag. */ + yaml_char_t *tag; + /** Is the tag optional? */ + int implicit; + /** The mapping style. */ + yaml_mapping_style_t style; + } mapping_start; + + } data; + + /** The beginning of the event. */ + yaml_mark_t start_mark; + /** The end of the event. */ + yaml_mark_t end_mark; + +} yaml_event_t; + +/** + * Create the STREAM-START event. + * + * @param[out] event An empty event object. + * @param[in] encoding The stream encoding. + * + * @returns @c 1 if the function succeeded, @c 0 on error. + */ + +YAML_DECLARE(int) +yaml_stream_start_event_initialize(yaml_event_t *event, + yaml_encoding_t encoding); + +/** + * Create the STREAM-END event. + * + * @param[out] event An empty event object. + * + * @returns @c 1 if the function succeeded, @c 0 on error. + */ + +YAML_DECLARE(int) +yaml_stream_end_event_initialize(yaml_event_t *event); + +/** + * Create the DOCUMENT-START event. + * + * The @a implicit argument is considered as a stylistic parameter and may be + * ignored by the emitter. + * + * @param[out] event An empty event object. + * @param[in] version_directive The %YAML directive value or + * @c NULL. + * @param[in] tag_directives_start The beginning of the %TAG + * directives list. + * @param[in] tag_directives_end The end of the %TAG directives + * list. + * @param[in] implicit If the document start indicator is + * implicit. + * + * @returns @c 1 if the function succeeded, @c 0 on error. + */ + +YAML_DECLARE(int) +yaml_document_start_event_initialize(yaml_event_t *event, + yaml_version_directive_t *version_directive, + yaml_tag_directive_t *tag_directives_start, + yaml_tag_directive_t *tag_directives_end, + int implicit); + +/** + * Create the DOCUMENT-END event. + * + * The @a implicit argument is considered as a stylistic parameter and may be + * ignored by the emitter. + * + * @param[out] event An empty event object. + * @param[in] implicit If the document end indicator is implicit. + * + * @returns @c 1 if the function succeeded, @c 0 on error. + */ + +YAML_DECLARE(int) +yaml_document_end_event_initialize(yaml_event_t *event, int implicit); + +/** + * Create an ALIAS event. + * + * @param[out] event An empty event object. + * @param[in] anchor The anchor value. + * + * @returns @c 1 if the function succeeded, @c 0 on error. + */ + +YAML_DECLARE(int) +yaml_alias_event_initialize(yaml_event_t *event, yaml_char_t *anchor); + +/** + * Create a SCALAR event. + * + * The @a style argument may be ignored by the emitter. + * + * Either the @a tag attribute or one of the @a plain_implicit and + * @a quoted_implicit flags must be set. + * + * @param[out] event An empty event object. + * @param[in] anchor The scalar anchor or @c NULL. + * @param[in] tag The scalar tag or @c NULL. + * @param[in] value The scalar value. + * @param[in] length The length of the scalar value. + * @param[in] plain_implicit If the tag may be omitted for the plain + * style. + * @param[in] quoted_implicit If the tag may be omitted for any + * non-plain style. + * @param[in] style The scalar style. + * + * @returns @c 1 if the function succeeded, @c 0 on error. + */ + +YAML_DECLARE(int) +yaml_scalar_event_initialize(yaml_event_t *event, + yaml_char_t *anchor, yaml_char_t *tag, + yaml_char_t *value, int length, + int plain_implicit, int quoted_implicit, + yaml_scalar_style_t style); + +/** + * Create a SEQUENCE-START event. + * + * The @a style argument may be ignored by the emitter. + * + * Either the @a tag attribute or the @a implicit flag must be set. + * + * @param[out] event An empty event object. + * @param[in] anchor The sequence anchor or @c NULL. + * @param[in] tag The sequence tag or @c NULL. + * @param[in] implicit If the tag may be omitted. + * @param[in] style The sequence style. + * + * @returns @c 1 if the function succeeded, @c 0 on error. + */ + +YAML_DECLARE(int) +yaml_sequence_start_event_initialize(yaml_event_t *event, + yaml_char_t *anchor, yaml_char_t *tag, int implicit, + yaml_sequence_style_t style); + +/** + * Create a SEQUENCE-END event. + * + * @param[out] event An empty event object. + * + * @returns @c 1 if the function succeeded, @c 0 on error. + */ + +YAML_DECLARE(int) +yaml_sequence_end_event_initialize(yaml_event_t *event); + +/** + * Create a MAPPING-START event. + * + * The @a style argument may be ignored by the emitter. + * + * Either the @a tag attribute or the @a implicit flag must be set. + * + * @param[out] event An empty event object. + * @param[in] anchor The mapping anchor or @c NULL. + * @param[in] tag The mapping tag or @c NULL. + * @param[in] implicit If the tag may be omitted. + * @param[in] style The mapping style. + * + * @returns @c 1 if the function succeeded, @c 0 on error. + */ + +YAML_DECLARE(int) +yaml_mapping_start_event_initialize(yaml_event_t *event, + yaml_char_t *anchor, yaml_char_t *tag, int implicit, + yaml_mapping_style_t style); + +/** + * Create a MAPPING-END event. + * + * @param[out] event An empty event object. + * + * @returns @c 1 if the function succeeded, @c 0 on error. + */ + +YAML_DECLARE(int) +yaml_mapping_end_event_initialize(yaml_event_t *event); + +/** + * Free any memory allocated for an event object. + * + * @param[in,out] event An event object. + */ + +YAML_DECLARE(void) +yaml_event_delete(yaml_event_t *event); + +/** @} */ + +/** + * @defgroup nodes Nodes + * @{ + */ + +/** The tag @c !!null with the only possible value: @c null. */ +#define YAML_NULL_TAG "tag:yaml.org,2002:null" +/** The tag @c !!bool with the values: @c true and @c falce. */ +#define YAML_BOOL_TAG "tag:yaml.org,2002:bool" +/** The tag @c !!str for string values. */ +#define YAML_STR_TAG "tag:yaml.org,2002:str" +/** The tag @c !!int for integer values. */ +#define YAML_INT_TAG "tag:yaml.org,2002:int" +/** The tag @c !!float for float values. */ +#define YAML_FLOAT_TAG "tag:yaml.org,2002:float" +/** The tag @c !!timestamp for date and time values. */ +#define YAML_TIMESTAMP_TAG "tag:yaml.org,2002:timestamp" + +/** The tag @c !!seq is used to denote sequences. */ +#define YAML_SEQ_TAG "tag:yaml.org,2002:seq" +/** The tag @c !!map is used to denote mapping. */ +#define YAML_MAP_TAG "tag:yaml.org,2002:map" + +/** The default scalar tag is @c !!str. */ +#define YAML_DEFAULT_SCALAR_TAG YAML_STR_TAG +/** The default sequence tag is @c !!seq. */ +#define YAML_DEFAULT_SEQUENCE_TAG YAML_SEQ_TAG +/** The default mapping tag is @c !!map. */ +#define YAML_DEFAULT_MAPPING_TAG YAML_MAP_TAG + +/** Node types. */ +typedef enum yaml_node_type_e { + /** An empty node. */ + YAML_NO_NODE, + + /** A scalar node. */ + YAML_SCALAR_NODE, + /** A sequence node. */ + YAML_SEQUENCE_NODE, + /** A mapping node. */ + YAML_MAPPING_NODE +} yaml_node_type_t; + +/** The forward definition of a document node structure. */ +typedef struct yaml_node_s yaml_node_t; + +/** An element of a sequence node. */ +typedef int yaml_node_item_t; + +/** An element of a mapping node. */ +typedef struct yaml_node_pair_s { + /** The key of the element. */ + int key; + /** The value of the element. */ + int value; +} yaml_node_pair_t; + +/** The node structure. */ +struct yaml_node_s { + + /** The node type. */ + yaml_node_type_t type; + + /** The node tag. */ + yaml_char_t *tag; + + /** The node data. */ + union { + + /** The scalar parameters (for @c YAML_SCALAR_NODE). */ + struct { + /** The scalar value. */ + yaml_char_t *value; + /** The length of the scalar value. */ + size_t length; + /** The scalar style. */ + yaml_scalar_style_t style; + } scalar; + + /** The sequence parameters (for @c YAML_SEQUENCE_NODE). */ + struct { + /** The stack of sequence items. */ + struct { + /** The beginning of the stack. */ + yaml_node_item_t *start; + /** The end of the stack. */ + yaml_node_item_t *end; + /** The top of the stack. */ + yaml_node_item_t *top; + } items; + /** The sequence style. */ + yaml_sequence_style_t style; + } sequence; + + /** The mapping parameters (for @c YAML_MAPPING_NODE). */ + struct { + /** The stack of mapping pairs (key, value). */ + struct { + /** The beginning of the stack. */ + yaml_node_pair_t *start; + /** The end of the stack. */ + yaml_node_pair_t *end; + /** The top of the stack. */ + yaml_node_pair_t *top; + } pairs; + /** The mapping style. */ + yaml_mapping_style_t style; + } mapping; + + } data; + + /** The beginning of the node. */ + yaml_mark_t start_mark; + /** The end of the node. */ + yaml_mark_t end_mark; + +}; + +/** The document structure. */ +typedef struct yaml_document_s { + + /** The document nodes. */ + struct { + /** The beginning of the stack. */ + yaml_node_t *start; + /** The end of the stack. */ + yaml_node_t *end; + /** The top of the stack. */ + yaml_node_t *top; + } nodes; + + /** The version directive. */ + yaml_version_directive_t *version_directive; + + /** The list of tag directives. */ + struct { + /** The beginning of the tag directives list. */ + yaml_tag_directive_t *start; + /** The end of the tag directives list. */ + yaml_tag_directive_t *end; + } tag_directives; + + /** Is the document start indicator implicit? */ + int start_implicit; + /** Is the document end indicator implicit? */ + int end_implicit; + + /** The beginning of the document. */ + yaml_mark_t start_mark; + /** The end of the document. */ + yaml_mark_t end_mark; + +} yaml_document_t; + +/** + * Create a YAML document. + * + * @param[out] document An empty document object. + * @param[in] version_directive The %YAML directive value or + * @c NULL. + * @param[in] tag_directives_start The beginning of the %TAG + * directives list. + * @param[in] tag_directives_end The end of the %TAG directives + * list. + * @param[in] start_implicit If the document start indicator is + * implicit. + * @param[in] end_implicit If the document end indicator is + * implicit. + * + * @returns @c 1 if the function succeeded, @c 0 on error. + */ + +YAML_DECLARE(int) +yaml_document_initialize(yaml_document_t *document, + yaml_version_directive_t *version_directive, + yaml_tag_directive_t *tag_directives_start, + yaml_tag_directive_t *tag_directives_end, + int start_implicit, int end_implicit); + +/** + * Delete a YAML document and all its nodes. + * + * @param[in,out] document A document object. + */ + +YAML_DECLARE(void) +yaml_document_delete(yaml_document_t *document); + +/** + * Get a node of a YAML document. + * + * The pointer returned by this function is valid until any of the functions + * modifying the documents are called. + * + * @param[in] document A document object. + * @param[in] index The node id. + * + * @returns the node objct or @c NULL if @c node_id is out of range. + */ + +YAML_DECLARE(yaml_node_t *) +yaml_document_get_node(yaml_document_t *document, int index); + +/** + * Get the root of a YAML document node. + * + * The root object is the first object added to the document. + * + * The pointer returned by this function is valid until any of the functions + * modifying the documents are called. + * + * An empty document produced by the parser signifies the end of a YAML + * stream. + * + * @param[in] document A document object. + * + * @returns the node object or @c NULL if the document is empty. + */ + +YAML_DECLARE(yaml_node_t *) +yaml_document_get_root_node(yaml_document_t *document); + +/** + * Create a SCALAR node and attach it to the document. + * + * The @a style argument may be ignored by the emitter. + * + * @param[in,out] document A document object. + * @param[in] tag The scalar tag. + * @param[in] value The scalar value. + * @param[in] length The length of the scalar value. + * @param[in] style The scalar style. + * + * @returns the node id or @c 0 on error. + */ + +YAML_DECLARE(int) +yaml_document_add_scalar(yaml_document_t *document, + yaml_char_t *tag, yaml_char_t *value, int length, + yaml_scalar_style_t style); + +/** + * Create a SEQUENCE node and attach it to the document. + * + * The @a style argument may be ignored by the emitter. + * + * @param[in,out] document A document object. + * @param[in] tag The sequence tag. + * @param[in] style The sequence style. + * + * @returns the node id or @c 0 on error. + */ + +YAML_DECLARE(int) +yaml_document_add_sequence(yaml_document_t *document, + yaml_char_t *tag, yaml_sequence_style_t style); + +/** + * Create a MAPPING node and attach it to the document. + * + * The @a style argument may be ignored by the emitter. + * + * @param[in,out] document A document object. + * @param[in] tag The sequence tag. + * @param[in] style The sequence style. + * + * @returns the node id or @c 0 on error. + */ + +YAML_DECLARE(int) +yaml_document_add_mapping(yaml_document_t *document, + yaml_char_t *tag, yaml_mapping_style_t style); + +/** + * Add an item to a SEQUENCE node. + * + * @param[in,out] document A document object. + * @param[in] sequence The sequence node id. + * @param[in] item The item node id. +* + * @returns @c 1 if the function succeeded, @c 0 on error. + */ + +YAML_DECLARE(int) +yaml_document_append_sequence_item(yaml_document_t *document, + int sequence, int item); + +/** + * Add a pair of a key and a value to a MAPPING node. + * + * @param[in,out] document A document object. + * @param[in] mapping The mapping node id. + * @param[in] key The key node id. + * @param[in] value The value node id. +* + * @returns @c 1 if the function succeeded, @c 0 on error. + */ + +YAML_DECLARE(int) +yaml_document_append_mapping_pair(yaml_document_t *document, + int mapping, int key, int value); + +/** @} */ + +/** + * @defgroup parser Parser Definitions + * @{ + */ + +/** + * The prototype of a read handler. + * + * The read handler is called when the parser needs to read more bytes from the + * source. The handler should write not more than @a size bytes to the @a + * buffer. The number of written bytes should be set to the @a length variable. + * + * @param[in,out] data A pointer to an application data specified by + * yaml_parser_set_input(). + * @param[out] buffer The buffer to write the data from the source. + * @param[in] size The size of the buffer. + * @param[out] size_read The actual number of bytes read from the source. + * + * @returns On success, the handler should return @c 1. If the handler failed, + * the returned value should be @c 0. On EOF, the handler should set the + * @a size_read to @c 0 and return @c 1. + */ + +typedef int yaml_read_handler_t(void *data, unsigned char *buffer, size_t size, + size_t *size_read); + +/** + * This structure holds information about a potential simple key. + */ + +typedef struct yaml_simple_key_s { + /** Is a simple key possible? */ + int possible; + + /** Is a simple key required? */ + int required; + + /** The number of the token. */ + size_t token_number; + + /** The position mark. */ + yaml_mark_t mark; +} yaml_simple_key_t; + +/** + * The states of the parser. + */ +typedef enum yaml_parser_state_e { + /** Expect STREAM-START. */ + YAML_PARSE_STREAM_START_STATE, + /** Expect the beginning of an implicit document. */ + YAML_PARSE_IMPLICIT_DOCUMENT_START_STATE, + /** Expect DOCUMENT-START. */ + YAML_PARSE_DOCUMENT_START_STATE, + /** Expect the content of a document. */ + YAML_PARSE_DOCUMENT_CONTENT_STATE, + /** Expect DOCUMENT-END. */ + YAML_PARSE_DOCUMENT_END_STATE, + /** Expect a block node. */ + YAML_PARSE_BLOCK_NODE_STATE, + /** Expect a block node or indentless sequence. */ + YAML_PARSE_BLOCK_NODE_OR_INDENTLESS_SEQUENCE_STATE, + /** Expect a flow node. */ + YAML_PARSE_FLOW_NODE_STATE, + /** Expect the first entry of a block sequence. */ + YAML_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE, + /** Expect an entry of a block sequence. */ + YAML_PARSE_BLOCK_SEQUENCE_ENTRY_STATE, + /** Expect an entry of an indentless sequence. */ + YAML_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE, + /** Expect the first key of a block mapping. */ + YAML_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE, + /** Expect a block mapping key. */ + YAML_PARSE_BLOCK_MAPPING_KEY_STATE, + /** Expect a block mapping value. */ + YAML_PARSE_BLOCK_MAPPING_VALUE_STATE, + /** Expect the first entry of a flow sequence. */ + YAML_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE, + /** Expect an entry of a flow sequence. */ + YAML_PARSE_FLOW_SEQUENCE_ENTRY_STATE, + /** Expect a key of an ordered mapping. */ + YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE, + /** Expect a value of an ordered mapping. */ + YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE, + /** Expect the and of an ordered mapping entry. */ + YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE, + /** Expect the first key of a flow mapping. */ + YAML_PARSE_FLOW_MAPPING_FIRST_KEY_STATE, + /** Expect a key of a flow mapping. */ + YAML_PARSE_FLOW_MAPPING_KEY_STATE, + /** Expect a value of a flow mapping. */ + YAML_PARSE_FLOW_MAPPING_VALUE_STATE, + /** Expect an empty value of a flow mapping. */ + YAML_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE, + /** Expect nothing. */ + YAML_PARSE_END_STATE +} yaml_parser_state_t; + +/** + * This structure holds aliases data. + */ + +typedef struct yaml_alias_data_s { + /** The anchor. */ + yaml_char_t *anchor; + /** The node id. */ + int index; + /** The anchor mark. */ + yaml_mark_t mark; +} yaml_alias_data_t; + +/** + * The parser structure. + * + * All members are internal. Manage the structure using the @c yaml_parser_ + * family of functions. + */ + +typedef struct yaml_parser_s { + + /** + * @name Error handling + * @{ + */ + + /** Error type. */ + yaml_error_type_t error; + /** Error description. */ + const char *problem; + /** The byte about which the problem occured. */ + size_t problem_offset; + /** The problematic value (@c -1 is none). */ + int problem_value; + /** The problem position. */ + yaml_mark_t problem_mark; + /** The error context. */ + const char *context; + /** The context position. */ + yaml_mark_t context_mark; + + /** + * @} + */ + + /** + * @name Reader stuff + * @{ + */ + + /** Read handler. */ + yaml_read_handler_t *read_handler; + + /** A pointer for passing to the read handler. */ + void *read_handler_data; + + /** Standard (string or file) input data. */ + union { + /** String input data. */ + struct { + /** The string start pointer. */ + const unsigned char *start; + /** The string end pointer. */ + const unsigned char *end; + /** The string current position. */ + const unsigned char *current; + } string; + + /** File input data. */ + FILE *file; + } input; + + /** EOF flag */ + int eof; + + /** The working buffer. */ + struct { + /** The beginning of the buffer. */ + yaml_char_t *start; + /** The end of the buffer. */ + yaml_char_t *end; + /** The current position of the buffer. */ + yaml_char_t *pointer; + /** The last filled position of the buffer. */ + yaml_char_t *last; + } buffer; + + /* The number of unread characters in the buffer. */ + size_t unread; + + /** The raw buffer. */ + struct { + /** The beginning of the buffer. */ + unsigned char *start; + /** The end of the buffer. */ + unsigned char *end; + /** The current position of the buffer. */ + unsigned char *pointer; + /** The last filled position of the buffer. */ + unsigned char *last; + } raw_buffer; + + /** The input encoding. */ + yaml_encoding_t encoding; + + /** The offset of the current position (in bytes). */ + size_t offset; + + /** The mark of the current position. */ + yaml_mark_t mark; + + /** + * @} + */ + + /** + * @name Scanner stuff + * @{ + */ + + /** Have we started to scan the input stream? */ + int stream_start_produced; + + /** Have we reached the end of the input stream? */ + int stream_end_produced; + + /** The number of unclosed '[' and '{' indicators. */ + int flow_level; + + /** The tokens queue. */ + struct { + /** The beginning of the tokens queue. */ + yaml_token_t *start; + /** The end of the tokens queue. */ + yaml_token_t *end; + /** The head of the tokens queue. */ + yaml_token_t *head; + /** The tail of the tokens queue. */ + yaml_token_t *tail; + } tokens; + + /** The number of tokens fetched from the queue. */ + size_t tokens_parsed; + + /* Does the tokens queue contain a token ready for dequeueing. */ + int token_available; + + /** The indentation levels stack. */ + struct { + /** The beginning of the stack. */ + int *start; + /** The end of the stack. */ + int *end; + /** The top of the stack. */ + int *top; + } indents; + + /** The current indentation level. */ + int indent; + + /** May a simple key occur at the current position? */ + int simple_key_allowed; + + /** The stack of simple keys. */ + struct { + /** The beginning of the stack. */ + yaml_simple_key_t *start; + /** The end of the stack. */ + yaml_simple_key_t *end; + /** The top of the stack. */ + yaml_simple_key_t *top; + } simple_keys; + + /** + * @} + */ + + /** + * @name Parser stuff + * @{ + */ + + /** The parser states stack. */ + struct { + /** The beginning of the stack. */ + yaml_parser_state_t *start; + /** The end of the stack. */ + yaml_parser_state_t *end; + /** The top of the stack. */ + yaml_parser_state_t *top; + } states; + + /** The current parser state. */ + yaml_parser_state_t state; + + /** The stack of marks. */ + struct { + /** The beginning of the stack. */ + yaml_mark_t *start; + /** The end of the stack. */ + yaml_mark_t *end; + /** The top of the stack. */ + yaml_mark_t *top; + } marks; + + /** The list of TAG directives. */ + struct { + /** The beginning of the list. */ + yaml_tag_directive_t *start; + /** The end of the list. */ + yaml_tag_directive_t *end; + /** The top of the list. */ + yaml_tag_directive_t *top; + } tag_directives; + + /** + * @} + */ + + /** + * @name Dumper stuff + * @{ + */ + + /** The alias data. */ + struct { + /** The beginning of the list. */ + yaml_alias_data_t *start; + /** The end of the list. */ + yaml_alias_data_t *end; + /** The top of the list. */ + yaml_alias_data_t *top; + } aliases; + + /** The currently parsed document. */ + yaml_document_t *document; + + /** + * @} + */ + +} yaml_parser_t; + +/** + * Initialize a parser. + * + * This function creates a new parser object. An application is responsible + * for destroying the object using the yaml_parser_delete() function. + * + * @param[out] parser An empty parser object. + * + * @returns @c 1 if the function succeeded, @c 0 on error. + */ + +YAML_DECLARE(int) +yaml_parser_initialize(yaml_parser_t *parser); + +/** + * Destroy a parser. + * + * @param[in,out] parser A parser object. + */ + +YAML_DECLARE(void) +yaml_parser_delete(yaml_parser_t *parser); + +/** + * Set a string input. + * + * Note that the @a input pointer must be valid while the @a parser object + * exists. The application is responsible for destroing @a input after + * destroying the @a parser. + * + * @param[in,out] parser A parser object. + * @param[in] input A source data. + * @param[in] size The length of the source data in bytes. + */ + +YAML_DECLARE(void) +yaml_parser_set_input_string(yaml_parser_t *parser, + const unsigned char *input, size_t size); + +/** + * Set a file input. + * + * @a file should be a file object open for reading. The application is + * responsible for closing the @a file. + * + * @param[in,out] parser A parser object. + * @param[in] file An open file. + */ + +YAML_DECLARE(void) +yaml_parser_set_input_file(yaml_parser_t *parser, FILE *file); + +/** + * Set a generic input handler. + * + * @param[in,out] parser A parser object. + * @param[in] handler A read handler. + * @param[in] data Any application data for passing to the read + * handler. + */ + +YAML_DECLARE(void) +yaml_parser_set_input(yaml_parser_t *parser, + yaml_read_handler_t *handler, void *data); + +/** + * Set the source encoding. + * + * @param[in,out] parser A parser object. + * @param[in] encoding The source encoding. + */ + +YAML_DECLARE(void) +yaml_parser_set_encoding(yaml_parser_t *parser, yaml_encoding_t encoding); + +/** + * Scan the input stream and produce the next token. + * + * Call the function subsequently to produce a sequence of tokens corresponding + * to the input stream. The initial token has the type + * @c YAML_STREAM_START_TOKEN while the ending token has the type + * @c YAML_STREAM_END_TOKEN. + * + * An application is responsible for freeing any buffers associated with the + * produced token object using the @c yaml_token_delete function. + * + * An application must not alternate the calls of yaml_parser_scan() with the + * calls of yaml_parser_parse() or yaml_parser_load(). Doing this will break + * the parser. + * + * @param[in,out] parser A parser object. + * @param[out] token An empty token object. + * + * @returns @c 1 if the function succeeded, @c 0 on error. + */ + +YAML_DECLARE(int) +yaml_parser_scan(yaml_parser_t *parser, yaml_token_t *token); + +/** + * Parse the input stream and produce the next parsing event. + * + * Call the function subsequently to produce a sequence of events corresponding + * to the input stream. The initial event has the type + * @c YAML_STREAM_START_EVENT while the ending event has the type + * @c YAML_STREAM_END_EVENT. + * + * An application is responsible for freeing any buffers associated with the + * produced event object using the yaml_event_delete() function. + * + * An application must not alternate the calls of yaml_parser_parse() with the + * calls of yaml_parser_scan() or yaml_parser_load(). Doing this will break the + * parser. + * + * @param[in,out] parser A parser object. + * @param[out] event An empty event object. + * + * @returns @c 1 if the function succeeded, @c 0 on error. + */ + +YAML_DECLARE(int) +yaml_parser_parse(yaml_parser_t *parser, yaml_event_t *event); + +/** + * Parse the input stream and produce the next YAML document. + * + * Call this function subsequently to produce a sequence of documents + * constituting the input stream. + * + * If the produced document has no root node, it means that the document + * end has been reached. + * + * An application is responsible for freeing any data associated with the + * produced document object using the yaml_document_delete() function. + * + * An application must not alternate the calls of yaml_parser_load() with the + * calls of yaml_parser_scan() or yaml_parser_parse(). Doing this will break + * the parser. + * + * @param[in,out] parser A parser object. + * @param[out] document An empty document object. + * + * @return @c 1 if the function succeeded, @c 0 on error. + */ + +YAML_DECLARE(int) +yaml_parser_load(yaml_parser_t *parser, yaml_document_t *document); + +/** @} */ + +/** + * @defgroup emitter Emitter Definitions + * @{ + */ + +/** + * The prototype of a write handler. + * + * The write handler is called when the emitter needs to flush the accumulated + * characters to the output. The handler should write @a size bytes of the + * @a buffer to the output. + * + * @param[in,out] data A pointer to an application data specified by + * yaml_emitter_set_output(). + * @param[in] buffer The buffer with bytes to be written. + * @param[in] size The size of the buffer. + * + * @returns On success, the handler should return @c 1. If the handler failed, + * the returned value should be @c 0. + */ + +typedef int yaml_write_handler_t(void *data, unsigned char *buffer, size_t size); + +/** The emitter states. */ +typedef enum yaml_emitter_state_e { + /** Expect STREAM-START. */ + YAML_EMIT_STREAM_START_STATE, + /** Expect the first DOCUMENT-START or STREAM-END. */ + YAML_EMIT_FIRST_DOCUMENT_START_STATE, + /** Expect DOCUMENT-START or STREAM-END. */ + YAML_EMIT_DOCUMENT_START_STATE, + /** Expect the content of a document. */ + YAML_EMIT_DOCUMENT_CONTENT_STATE, + /** Expect DOCUMENT-END. */ + YAML_EMIT_DOCUMENT_END_STATE, + /** Expect the first item of a flow sequence. */ + YAML_EMIT_FLOW_SEQUENCE_FIRST_ITEM_STATE, + /** Expect an item of a flow sequence. */ + YAML_EMIT_FLOW_SEQUENCE_ITEM_STATE, + /** Expect the first key of a flow mapping. */ + YAML_EMIT_FLOW_MAPPING_FIRST_KEY_STATE, + /** Expect a key of a flow mapping. */ + YAML_EMIT_FLOW_MAPPING_KEY_STATE, + /** Expect a value for a simple key of a flow mapping. */ + YAML_EMIT_FLOW_MAPPING_SIMPLE_VALUE_STATE, + /** Expect a value of a flow mapping. */ + YAML_EMIT_FLOW_MAPPING_VALUE_STATE, + /** Expect the first item of a block sequence. */ + YAML_EMIT_BLOCK_SEQUENCE_FIRST_ITEM_STATE, + /** Expect an item of a block sequence. */ + YAML_EMIT_BLOCK_SEQUENCE_ITEM_STATE, + /** Expect the first key of a block mapping. */ + YAML_EMIT_BLOCK_MAPPING_FIRST_KEY_STATE, + /** Expect the key of a block mapping. */ + YAML_EMIT_BLOCK_MAPPING_KEY_STATE, + /** Expect a value for a simple key of a block mapping. */ + YAML_EMIT_BLOCK_MAPPING_SIMPLE_VALUE_STATE, + /** Expect a value of a block mapping. */ + YAML_EMIT_BLOCK_MAPPING_VALUE_STATE, + /** Expect nothing. */ + YAML_EMIT_END_STATE +} yaml_emitter_state_t; + +/** + * The emitter structure. + * + * All members are internal. Manage the structure using the @c yaml_emitter_ + * family of functions. + */ + +typedef struct yaml_emitter_s { + + /** + * @name Error handling + * @{ + */ + + /** Error type. */ + yaml_error_type_t error; + /** Error description. */ + const char *problem; + + /** + * @} + */ + + /** + * @name Writer stuff + * @{ + */ + + /** Write handler. */ + yaml_write_handler_t *write_handler; + + /** A pointer for passing to the white handler. */ + void *write_handler_data; + + /** Standard (string or file) output data. */ + union { + /** String output data. */ + struct { + /** The buffer pointer. */ + unsigned char *buffer; + /** The buffer size. */ + size_t size; + /** The number of written bytes. */ + size_t *size_written; + } string; + + /** File output data. */ + FILE *file; + } output; + + /** The working buffer. */ + struct { + /** The beginning of the buffer. */ + yaml_char_t *start; + /** The end of the buffer. */ + yaml_char_t *end; + /** The current position of the buffer. */ + yaml_char_t *pointer; + /** The last filled position of the buffer. */ + yaml_char_t *last; + } buffer; + + /** The raw buffer. */ + struct { + /** The beginning of the buffer. */ + unsigned char *start; + /** The end of the buffer. */ + unsigned char *end; + /** The current position of the buffer. */ + unsigned char *pointer; + /** The last filled position of the buffer. */ + unsigned char *last; + } raw_buffer; + + /** The stream encoding. */ + yaml_encoding_t encoding; + + /** + * @} + */ + + /** + * @name Emitter stuff + * @{ + */ + + /** If the output is in the canonical style? */ + int canonical; + /** The number of indentation spaces. */ + int best_indent; + /** The preferred width of the output lines. */ + int best_width; + /** Allow unescaped non-ASCII characters? */ + int unicode; + /** The preferred line break. */ + yaml_break_t line_break; + + /** The stack of states. */ + struct { + /** The beginning of the stack. */ + yaml_emitter_state_t *start; + /** The end of the stack. */ + yaml_emitter_state_t *end; + /** The top of the stack. */ + yaml_emitter_state_t *top; + } states; + + /** The current emitter state. */ + yaml_emitter_state_t state; + + /** The event queue. */ + struct { + /** The beginning of the event queue. */ + yaml_event_t *start; + /** The end of the event queue. */ + yaml_event_t *end; + /** The head of the event queue. */ + yaml_event_t *head; + /** The tail of the event queue. */ + yaml_event_t *tail; + } events; + + /** The stack of indentation levels. */ + struct { + /** The beginning of the stack. */ + int *start; + /** The end of the stack. */ + int *end; + /** The top of the stack. */ + int *top; + } indents; + + /** The list of tag directives. */ + struct { + /** The beginning of the list. */ + yaml_tag_directive_t *start; + /** The end of the list. */ + yaml_tag_directive_t *end; + /** The top of the list. */ + yaml_tag_directive_t *top; + } tag_directives; + + /** The current indentation level. */ + int indent; + + /** The current flow level. */ + int flow_level; + + /** Is it the document root context? */ + int root_context; + /** Is it a sequence context? */ + int sequence_context; + /** Is it a mapping context? */ + int mapping_context; + /** Is it a simple mapping key context? */ + int simple_key_context; + + /** The current line. */ + int line; + /** The current column. */ + int column; + /** If the last character was a whitespace? */ + int whitespace; + /** If the last character was an indentation character (' ', '-', '?', ':')? */ + int indention; + /** If an explicit document end is required? */ + int open_ended; + + /** Anchor analysis. */ + struct { + /** The anchor value. */ + yaml_char_t *anchor; + /** The anchor length. */ + size_t anchor_length; + /** Is it an alias? */ + int alias; + } anchor_data; + + /** Tag analysis. */ + struct { + /** The tag handle. */ + yaml_char_t *handle; + /** The tag handle length. */ + size_t handle_length; + /** The tag suffix. */ + yaml_char_t *suffix; + /** The tag suffix length. */ + size_t suffix_length; + } tag_data; + + /** Scalar analysis. */ + struct { + /** The scalar value. */ + yaml_char_t *value; + /** The scalar length. */ + size_t length; + /** Does the scalar contain line breaks? */ + int multiline; + /** Can the scalar be expessed in the flow plain style? */ + int flow_plain_allowed; + /** Can the scalar be expressed in the block plain style? */ + int block_plain_allowed; + /** Can the scalar be expressed in the single quoted style? */ + int single_quoted_allowed; + /** Can the scalar be expressed in the literal or folded styles? */ + int block_allowed; + /** The output style. */ + yaml_scalar_style_t style; + } scalar_data; + + /** + * @} + */ + + /** + * @name Dumper stuff + * @{ + */ + + /** If the stream was already opened? */ + int opened; + /** If the stream was already closed? */ + int closed; + + /** The information associated with the document nodes. */ + struct { + /** The number of references. */ + int references; + /** The anchor id. */ + int anchor; + /** If the node has been emitted? */ + int serialized; + } *anchors; + + /** The last assigned anchor id. */ + int last_anchor_id; + + /** The currently emitted document. */ + yaml_document_t *document; + + /** + * @} + */ + +} yaml_emitter_t; + +/** + * Initialize an emitter. + * + * This function creates a new emitter object. An application is responsible + * for destroying the object using the yaml_emitter_delete() function. + * + * @param[out] emitter An empty parser object. + * + * @returns @c 1 if the function succeeded, @c 0 on error. + */ + +YAML_DECLARE(int) +yaml_emitter_initialize(yaml_emitter_t *emitter); + +/** + * Destroy an emitter. + * + * @param[in,out] emitter An emitter object. + */ + +YAML_DECLARE(void) +yaml_emitter_delete(yaml_emitter_t *emitter); + +/** + * Set a string output. + * + * The emitter will write the output characters to the @a output buffer of the + * size @a size. The emitter will set @a size_written to the number of written + * bytes. If the buffer is smaller than required, the emitter produces the + * YAML_WRITE_ERROR error. + * + * @param[in,out] emitter An emitter object. + * @param[in] output An output buffer. + * @param[in] size The buffer size. + * @param[in] size_written The pointer to save the number of written + * bytes. + */ + +YAML_DECLARE(void) +yaml_emitter_set_output_string(yaml_emitter_t *emitter, + unsigned char *output, size_t size, size_t *size_written); + +/** + * Set a file output. + * + * @a file should be a file object open for writing. The application is + * responsible for closing the @a file. + * + * @param[in,out] emitter An emitter object. + * @param[in] file An open file. + */ + +YAML_DECLARE(void) +yaml_emitter_set_output_file(yaml_emitter_t *emitter, FILE *file); + +/** + * Set a generic output handler. + * + * @param[in,out] emitter An emitter object. + * @param[in] handler A write handler. + * @param[in] data Any application data for passing to the write + * handler. + */ + +YAML_DECLARE(void) +yaml_emitter_set_output(yaml_emitter_t *emitter, + yaml_write_handler_t *handler, void *data); + +/** + * Set the output encoding. + * + * @param[in,out] emitter An emitter object. + * @param[in] encoding The output encoding. + */ + +YAML_DECLARE(void) +yaml_emitter_set_encoding(yaml_emitter_t *emitter, yaml_encoding_t encoding); + +/** + * Set if the output should be in the "canonical" format as in the YAML + * specification. + * + * @param[in,out] emitter An emitter object. + * @param[in] canonical If the output is canonical. + */ + +YAML_DECLARE(void) +yaml_emitter_set_canonical(yaml_emitter_t *emitter, int canonical); + +/** + * Set the intendation increment. + * + * @param[in,out] emitter An emitter object. + * @param[in] indent The indentation increment (1 < . < 10). + */ + +YAML_DECLARE(void) +yaml_emitter_set_indent(yaml_emitter_t *emitter, int indent); + +/** + * Set the preferred line width. @c -1 means unlimited. + * + * @param[in,out] emitter An emitter object. + * @param[in] width The preferred line width. + */ + +YAML_DECLARE(void) +yaml_emitter_set_width(yaml_emitter_t *emitter, int width); + +/** + * Set if unescaped non-ASCII characters are allowed. + * + * @param[in,out] emitter An emitter object. + * @param[in] unicode If unescaped Unicode characters are allowed. + */ + +YAML_DECLARE(void) +yaml_emitter_set_unicode(yaml_emitter_t *emitter, int unicode); + +/** + * Set the preferred line break. + * + * @param[in,out] emitter An emitter object. + * @param[in] line_break The preferred line break. + */ + +YAML_DECLARE(void) +yaml_emitter_set_break(yaml_emitter_t *emitter, yaml_break_t line_break); + +/** + * Emit an event. + * + * The event object may be generated using the yaml_parser_parse() function. + * The emitter takes the responsibility for the event object and destroys its + * content after it is emitted. The event object is destroyed even if the + * function fails. + * + * @param[in,out] emitter An emitter object. + * @param[in,out] event An event object. + * + * @returns @c 1 if the function succeeded, @c 0 on error. + */ + +YAML_DECLARE(int) +yaml_emitter_emit(yaml_emitter_t *emitter, yaml_event_t *event); + +/** + * Start a YAML stream. + * + * This function should be used before yaml_emitter_dump() is called. + * + * @param[in,out] emitter An emitter object. + * + * @returns @c 1 if the function succeeded, @c 0 on error. + */ + +YAML_DECLARE(int) +yaml_emitter_open(yaml_emitter_t *emitter); + +/** + * Finish a YAML stream. + * + * This function should be used after yaml_emitter_dump() is called. + * + * @param[in,out] emitter An emitter object. + * + * @returns @c 1 if the function succeeded, @c 0 on error. + */ + +YAML_DECLARE(int) +yaml_emitter_close(yaml_emitter_t *emitter); + +/** + * Emit a YAML document. + * + * The documen object may be generated using the yaml_parser_load() function + * or the yaml_document_initialize() function. The emitter takes the + * responsibility for the document object and destoys its content after + * it is emitted. The document object is destroyedeven if the function fails. + * + * @param[in,out] emitter An emitter object. + * @param[in,out] document A document object. + * + * @returns @c 1 if the function succeeded, @c 0 on error. + */ + +YAML_DECLARE(int) +yaml_emitter_dump(yaml_emitter_t *emitter, yaml_document_t *document); + +/** + * Flush the accumulated characters to the output. + * + * @param[in,out] emitter An emitter object. + * + * @returns @c 1 if the function succeeded, @c 0 on error. + */ + +YAML_DECLARE(int) +yaml_emitter_flush(yaml_emitter_t *emitter); + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* #ifndef YAML_H */ + diff --git a/libyaml/src/api.c b/libyaml/src/api.c new file mode 100644 index 00000000..c54664d9 --- /dev/null +++ b/libyaml/src/api.c @@ -0,0 +1,1392 @@ + +#include "yaml_private.h" + +/* + * Get the library version. + */ + +YAML_DECLARE(const char *) +yaml_get_version_string(void) +{ + return YAML_VERSION_STRING; +} + +/* + * Get the library version numbers. + */ + +YAML_DECLARE(void) +yaml_get_version(int *major, int *minor, int *patch) +{ + *major = YAML_VERSION_MAJOR; + *minor = YAML_VERSION_MINOR; + *patch = YAML_VERSION_PATCH; +} + +/* + * Allocate a dynamic memory block. + */ + +YAML_DECLARE(void *) +yaml_malloc(size_t size) +{ + return malloc(size ? size : 1); +} + +/* + * Reallocate a dynamic memory block. + */ + +YAML_DECLARE(void *) +yaml_realloc(void *ptr, size_t size) +{ + return ptr ? realloc(ptr, size ? size : 1) : malloc(size ? size : 1); +} + +/* + * Free a dynamic memory block. + */ + +YAML_DECLARE(void) +yaml_free(void *ptr) +{ + if (ptr) free(ptr); +} + +/* + * Duplicate a string. + */ + +YAML_DECLARE(yaml_char_t *) +yaml_strdup(const yaml_char_t *str) +{ + if (!str) + return NULL; + + return (yaml_char_t *)_strdup((char *)str); // TC: strdup() > _strdup() +} + +/* + * Extend a string. + */ + +YAML_DECLARE(int) +yaml_string_extend(yaml_char_t **start, + yaml_char_t **pointer, yaml_char_t **end) +{ + yaml_char_t *new_start = yaml_realloc(*start, (*end - *start)*2); + + if (!new_start) return 0; + + memset(new_start + (*end - *start), 0, *end - *start); + + *pointer = new_start + (*pointer - *start); + *end = new_start + (*end - *start)*2; + *start = new_start; + + return 1; +} + +/* + * Append a string B to a string A. + */ + +YAML_DECLARE(int) +yaml_string_join( + yaml_char_t **a_start, yaml_char_t **a_pointer, yaml_char_t **a_end, + yaml_char_t **b_start, yaml_char_t **b_pointer, yaml_char_t **b_end) +{ + if (*b_start == *b_pointer) + return 1; + + while (*a_end - *a_pointer <= *b_pointer - *b_start) { + if (!yaml_string_extend(a_start, a_pointer, a_end)) + return 0; + } + + memcpy(*a_pointer, *b_start, *b_pointer - *b_start); + *a_pointer += *b_pointer - *b_start; + + return 1; +} + +/* + * Extend a stack. + */ + +YAML_DECLARE(int) +yaml_stack_extend(void **start, void **top, void **end) +{ + void *new_start = yaml_realloc(*start, ((char *)*end - (char *)*start)*2); + + if (!new_start) return 0; + + *top = (char *)new_start + ((char *)*top - (char *)*start); + *end = (char *)new_start + ((char *)*end - (char *)*start)*2; + *start = new_start; + + return 1; +} + +/* + * Extend or move a queue. + */ + +YAML_DECLARE(int) +yaml_queue_extend(void **start, void **head, void **tail, void **end) +{ + /* Check if we need to resize the queue. */ + + if (*start == *head && *tail == *end) { + void *new_start = yaml_realloc(*start, + ((char *)*end - (char *)*start)*2); + + if (!new_start) return 0; + + *head = (char *)new_start + ((char *)*head - (char *)*start); + *tail = (char *)new_start + ((char *)*tail - (char *)*start); + *end = (char *)new_start + ((char *)*end - (char *)*start)*2; + *start = new_start; + } + + /* Check if we need to move the queue at the beginning of the buffer. */ + + if (*tail == *end) { + if (*head != *tail) { + memmove(*start, *head, (char *)*tail - (char *)*head); + } + *tail = (char *)*tail - (char *)*head + (char *)*start; + *head = *start; + } + + return 1; +} + + +/* + * Create a new parser object. + */ + +YAML_DECLARE(int) +yaml_parser_initialize(yaml_parser_t *parser) +{ + assert(parser); /* Non-NULL parser object expected. */ + + memset(parser, 0, sizeof(yaml_parser_t)); + if (!BUFFER_INIT(parser, parser->raw_buffer, INPUT_RAW_BUFFER_SIZE)) + goto error; + if (!BUFFER_INIT(parser, parser->buffer, INPUT_BUFFER_SIZE)) + goto error; + if (!QUEUE_INIT(parser, parser->tokens, INITIAL_QUEUE_SIZE)) + goto error; + if (!STACK_INIT(parser, parser->indents, INITIAL_STACK_SIZE)) + goto error; + if (!STACK_INIT(parser, parser->simple_keys, INITIAL_STACK_SIZE)) + goto error; + if (!STACK_INIT(parser, parser->states, INITIAL_STACK_SIZE)) + goto error; + if (!STACK_INIT(parser, parser->marks, INITIAL_STACK_SIZE)) + goto error; + if (!STACK_INIT(parser, parser->tag_directives, INITIAL_STACK_SIZE)) + goto error; + + return 1; + +error: + + BUFFER_DEL(parser, parser->raw_buffer); + BUFFER_DEL(parser, parser->buffer); + QUEUE_DEL(parser, parser->tokens); + STACK_DEL(parser, parser->indents); + STACK_DEL(parser, parser->simple_keys); + STACK_DEL(parser, parser->states); + STACK_DEL(parser, parser->marks); + STACK_DEL(parser, parser->tag_directives); + + return 0; +} + +/* + * Destroy a parser object. + */ + +YAML_DECLARE(void) +yaml_parser_delete(yaml_parser_t *parser) +{ + assert(parser); /* Non-NULL parser object expected. */ + + BUFFER_DEL(parser, parser->raw_buffer); + BUFFER_DEL(parser, parser->buffer); + while (!QUEUE_EMPTY(parser, parser->tokens)) { + yaml_token_delete(&DEQUEUE(parser, parser->tokens)); + } + QUEUE_DEL(parser, parser->tokens); + STACK_DEL(parser, parser->indents); + STACK_DEL(parser, parser->simple_keys); + STACK_DEL(parser, parser->states); + STACK_DEL(parser, parser->marks); + while (!STACK_EMPTY(parser, parser->tag_directives)) { + yaml_tag_directive_t tag_directive = POP(parser, parser->tag_directives); + yaml_free(tag_directive.handle); + yaml_free(tag_directive.prefix); + } + STACK_DEL(parser, parser->tag_directives); + + memset(parser, 0, sizeof(yaml_parser_t)); +} + +/* + * String read handler. + */ + +static int +yaml_string_read_handler(void *data, unsigned char *buffer, size_t size, + size_t *size_read) +{ + yaml_parser_t *parser = data; + + if (parser->input.string.current == parser->input.string.end) { + *size_read = 0; + return 1; + } + + if (size > (size_t)(parser->input.string.end + - parser->input.string.current)) { + size = parser->input.string.end - parser->input.string.current; + } + + memcpy(buffer, parser->input.string.current, size); + parser->input.string.current += size; + *size_read = size; + return 1; +} + +/* + * File read handler. + */ + +static int +yaml_file_read_handler(void *data, unsigned char *buffer, size_t size, + size_t *size_read) +{ + yaml_parser_t *parser = data; + + *size_read = fread(buffer, 1, size, parser->input.file); + return !ferror(parser->input.file); +} + +/* + * Set a string input. + */ + +YAML_DECLARE(void) +yaml_parser_set_input_string(yaml_parser_t *parser, + const unsigned char *input, size_t size) +{ + assert(parser); /* Non-NULL parser object expected. */ + assert(!parser->read_handler); /* You can set the source only once. */ + assert(input); /* Non-NULL input string expected. */ + + parser->read_handler = yaml_string_read_handler; + parser->read_handler_data = parser; + + parser->input.string.start = input; + parser->input.string.current = input; + parser->input.string.end = input+size; +} + +/* + * Set a file input. + */ + +YAML_DECLARE(void) +yaml_parser_set_input_file(yaml_parser_t *parser, FILE *file) +{ + assert(parser); /* Non-NULL parser object expected. */ + assert(!parser->read_handler); /* You can set the source only once. */ + assert(file); /* Non-NULL file object expected. */ + + parser->read_handler = yaml_file_read_handler; + parser->read_handler_data = parser; + + parser->input.file = file; +} + +/* + * Set a generic input. + */ + +YAML_DECLARE(void) +yaml_parser_set_input(yaml_parser_t *parser, + yaml_read_handler_t *handler, void *data) +{ + assert(parser); /* Non-NULL parser object expected. */ + assert(!parser->read_handler); /* You can set the source only once. */ + assert(handler); /* Non-NULL read handler expected. */ + + parser->read_handler = handler; + parser->read_handler_data = data; +} + +/* + * Set the source encoding. + */ + +YAML_DECLARE(void) +yaml_parser_set_encoding(yaml_parser_t *parser, yaml_encoding_t encoding) +{ + assert(parser); /* Non-NULL parser object expected. */ + assert(!parser->encoding); /* Encoding is already set or detected. */ + + parser->encoding = encoding; +} + +/* + * Create a new emitter object. + */ + +YAML_DECLARE(int) +yaml_emitter_initialize(yaml_emitter_t *emitter) +{ + assert(emitter); /* Non-NULL emitter object expected. */ + + memset(emitter, 0, sizeof(yaml_emitter_t)); + if (!BUFFER_INIT(emitter, emitter->buffer, OUTPUT_BUFFER_SIZE)) + goto error; + if (!BUFFER_INIT(emitter, emitter->raw_buffer, OUTPUT_RAW_BUFFER_SIZE)) + goto error; + if (!STACK_INIT(emitter, emitter->states, INITIAL_STACK_SIZE)) + goto error; + if (!QUEUE_INIT(emitter, emitter->events, INITIAL_QUEUE_SIZE)) + goto error; + if (!STACK_INIT(emitter, emitter->indents, INITIAL_STACK_SIZE)) + goto error; + if (!STACK_INIT(emitter, emitter->tag_directives, INITIAL_STACK_SIZE)) + goto error; + + return 1; + +error: + + BUFFER_DEL(emitter, emitter->buffer); + BUFFER_DEL(emitter, emitter->raw_buffer); + STACK_DEL(emitter, emitter->states); + QUEUE_DEL(emitter, emitter->events); + STACK_DEL(emitter, emitter->indents); + STACK_DEL(emitter, emitter->tag_directives); + + return 0; +} + +/* + * Destroy an emitter object. + */ + +YAML_DECLARE(void) +yaml_emitter_delete(yaml_emitter_t *emitter) +{ + assert(emitter); /* Non-NULL emitter object expected. */ + + BUFFER_DEL(emitter, emitter->buffer); + BUFFER_DEL(emitter, emitter->raw_buffer); + STACK_DEL(emitter, emitter->states); + while (!QUEUE_EMPTY(emitter, emitter->events)) { + yaml_event_delete(&DEQUEUE(emitter, emitter->events)); + } + QUEUE_DEL(emitter, emitter->events); + STACK_DEL(emitter, emitter->indents); + while (!STACK_EMPTY(empty, emitter->tag_directives)) { + yaml_tag_directive_t tag_directive = POP(emitter, emitter->tag_directives); + yaml_free(tag_directive.handle); + yaml_free(tag_directive.prefix); + } + STACK_DEL(emitter, emitter->tag_directives); + yaml_free(emitter->anchors); + + memset(emitter, 0, sizeof(yaml_emitter_t)); +} + +/* + * String write handler. + */ + +static int +yaml_string_write_handler(void *data, unsigned char *buffer, size_t size) +{ + yaml_emitter_t *emitter = data; + + if (emitter->output.string.size + *emitter->output.string.size_written + < size) { + memcpy(emitter->output.string.buffer + + *emitter->output.string.size_written, + buffer, + emitter->output.string.size + - *emitter->output.string.size_written); + *emitter->output.string.size_written = emitter->output.string.size; + return 0; + } + + memcpy(emitter->output.string.buffer + + *emitter->output.string.size_written, buffer, size); + *emitter->output.string.size_written += size; + return 1; +} + +/* + * File write handler. + */ + +static int +yaml_file_write_handler(void *data, unsigned char *buffer, size_t size) +{ + yaml_emitter_t *emitter = data; + + return (fwrite(buffer, 1, size, emitter->output.file) == size); +} +/* + * Set a string output. + */ + +YAML_DECLARE(void) +yaml_emitter_set_output_string(yaml_emitter_t *emitter, + unsigned char *output, size_t size, size_t *size_written) +{ + assert(emitter); /* Non-NULL emitter object expected. */ + assert(!emitter->write_handler); /* You can set the output only once. */ + assert(output); /* Non-NULL output string expected. */ + + emitter->write_handler = yaml_string_write_handler; + emitter->write_handler_data = emitter; + + emitter->output.string.buffer = output; + emitter->output.string.size = size; + emitter->output.string.size_written = size_written; + *size_written = 0; +} + +/* + * Set a file output. + */ + +YAML_DECLARE(void) +yaml_emitter_set_output_file(yaml_emitter_t *emitter, FILE *file) +{ + assert(emitter); /* Non-NULL emitter object expected. */ + assert(!emitter->write_handler); /* You can set the output only once. */ + assert(file); /* Non-NULL file object expected. */ + + emitter->write_handler = yaml_file_write_handler; + emitter->write_handler_data = emitter; + + emitter->output.file = file; +} + +/* + * Set a generic output handler. + */ + +YAML_DECLARE(void) +yaml_emitter_set_output(yaml_emitter_t *emitter, + yaml_write_handler_t *handler, void *data) +{ + assert(emitter); /* Non-NULL emitter object expected. */ + assert(!emitter->write_handler); /* You can set the output only once. */ + assert(handler); /* Non-NULL handler object expected. */ + + emitter->write_handler = handler; + emitter->write_handler_data = data; +} + +/* + * Set the output encoding. + */ + +YAML_DECLARE(void) +yaml_emitter_set_encoding(yaml_emitter_t *emitter, yaml_encoding_t encoding) +{ + assert(emitter); /* Non-NULL emitter object expected. */ + assert(!emitter->encoding); /* You can set encoding only once. */ + + emitter->encoding = encoding; +} + +/* + * Set the canonical output style. + */ + +YAML_DECLARE(void) +yaml_emitter_set_canonical(yaml_emitter_t *emitter, int canonical) +{ + assert(emitter); /* Non-NULL emitter object expected. */ + + emitter->canonical = (canonical != 0); +} + +/* + * Set the indentation increment. + */ + +YAML_DECLARE(void) +yaml_emitter_set_indent(yaml_emitter_t *emitter, int indent) +{ + assert(emitter); /* Non-NULL emitter object expected. */ + + emitter->best_indent = (1 < indent && indent < 10) ? indent : 2; +} + +/* + * Set the preferred line width. + */ + +YAML_DECLARE(void) +yaml_emitter_set_width(yaml_emitter_t *emitter, int width) +{ + assert(emitter); /* Non-NULL emitter object expected. */ + + emitter->best_width = (width >= 0) ? width : -1; +} + +/* + * Set if unescaped non-ASCII characters are allowed. + */ + +YAML_DECLARE(void) +yaml_emitter_set_unicode(yaml_emitter_t *emitter, int unicode) +{ + assert(emitter); /* Non-NULL emitter object expected. */ + + emitter->unicode = (unicode != 0); +} + +/* + * Set the preferred line break character. + */ + +YAML_DECLARE(void) +yaml_emitter_set_break(yaml_emitter_t *emitter, yaml_break_t line_break) +{ + assert(emitter); /* Non-NULL emitter object expected. */ + + emitter->line_break = line_break; +} + +/* + * Destroy a token object. + */ + +YAML_DECLARE(void) +yaml_token_delete(yaml_token_t *token) +{ + assert(token); /* Non-NULL token object expected. */ + + switch (token->type) + { + case YAML_TAG_DIRECTIVE_TOKEN: + yaml_free(token->data.tag_directive.handle); + yaml_free(token->data.tag_directive.prefix); + break; + + case YAML_ALIAS_TOKEN: + yaml_free(token->data.alias.value); + break; + + case YAML_ANCHOR_TOKEN: + yaml_free(token->data.anchor.value); + break; + + case YAML_TAG_TOKEN: + yaml_free(token->data.tag.handle); + yaml_free(token->data.tag.suffix); + break; + + case YAML_SCALAR_TOKEN: + yaml_free(token->data.scalar.value); + break; + + default: + break; + } + + memset(token, 0, sizeof(yaml_token_t)); +} + +/* + * Check if a string is a valid UTF-8 sequence. + * + * Check 'reader.c' for more details on UTF-8 encoding. + */ + +static int +yaml_check_utf8(yaml_char_t *start, size_t length) +{ + yaml_char_t *end = start+length; + yaml_char_t *pointer = start; + + while (pointer < end) { + unsigned char octet; + unsigned int width; + unsigned int value; + size_t k; + + octet = pointer[0]; + width = (octet & 0x80) == 0x00 ? 1 : + (octet & 0xE0) == 0xC0 ? 2 : + (octet & 0xF0) == 0xE0 ? 3 : + (octet & 0xF8) == 0xF0 ? 4 : 0; + value = (octet & 0x80) == 0x00 ? octet & 0x7F : + (octet & 0xE0) == 0xC0 ? octet & 0x1F : + (octet & 0xF0) == 0xE0 ? octet & 0x0F : + (octet & 0xF8) == 0xF0 ? octet & 0x07 : 0; + if (!width) return 0; + if (pointer+width > end) return 0; + for (k = 1; k < width; k ++) { + octet = pointer[k]; + if ((octet & 0xC0) != 0x80) return 0; + value = (value << 6) + (octet & 0x3F); + } + if (!((width == 1) || + (width == 2 && value >= 0x80) || + (width == 3 && value >= 0x800) || + (width == 4 && value >= 0x10000))) return 0; + + pointer += width; + } + + return 1; +} + +/* + * Create STREAM-START. + */ + +YAML_DECLARE(int) +yaml_stream_start_event_initialize(yaml_event_t *event, + yaml_encoding_t encoding) +{ + yaml_mark_t mark = { 0, 0, 0 }; + + assert(event); /* Non-NULL event object is expected. */ + + STREAM_START_EVENT_INIT(*event, encoding, mark, mark); + + return 1; +} + +/* + * Create STREAM-END. + */ + +YAML_DECLARE(int) +yaml_stream_end_event_initialize(yaml_event_t *event) +{ + yaml_mark_t mark = { 0, 0, 0 }; + + assert(event); /* Non-NULL event object is expected. */ + + STREAM_END_EVENT_INIT(*event, mark, mark); + + return 1; +} + +/* + * Create DOCUMENT-START. + */ + +YAML_DECLARE(int) +yaml_document_start_event_initialize(yaml_event_t *event, + yaml_version_directive_t *version_directive, + yaml_tag_directive_t *tag_directives_start, + yaml_tag_directive_t *tag_directives_end, + int implicit) +{ + struct { + yaml_error_type_t error; + } context; + yaml_mark_t mark = { 0, 0, 0 }; + yaml_version_directive_t *version_directive_copy = NULL; + struct { + yaml_tag_directive_t *start; + yaml_tag_directive_t *end; + yaml_tag_directive_t *top; + } tag_directives_copy = { NULL, NULL, NULL }; + yaml_tag_directive_t value = { NULL, NULL }; + + assert(event); /* Non-NULL event object is expected. */ + assert((tag_directives_start && tag_directives_end) || + (tag_directives_start == tag_directives_end)); + /* Valid tag directives are expected. */ + + if (version_directive) { + version_directive_copy = yaml_malloc(sizeof(yaml_version_directive_t)); + if (!version_directive_copy) goto error; + version_directive_copy->major = version_directive->major; + version_directive_copy->minor = version_directive->minor; + } + + if (tag_directives_start != tag_directives_end) { + yaml_tag_directive_t *tag_directive; + if (!STACK_INIT(&context, tag_directives_copy, INITIAL_STACK_SIZE)) + goto error; + for (tag_directive = tag_directives_start; + tag_directive != tag_directives_end; tag_directive ++) { + assert(tag_directive->handle); + assert(tag_directive->prefix); + if (!yaml_check_utf8(tag_directive->handle, + strlen((char *)tag_directive->handle))) + goto error; + if (!yaml_check_utf8(tag_directive->prefix, + strlen((char *)tag_directive->prefix))) + goto error; + value.handle = yaml_strdup(tag_directive->handle); + value.prefix = yaml_strdup(tag_directive->prefix); + if (!value.handle || !value.prefix) goto error; + if (!PUSH(&context, tag_directives_copy, value)) + goto error; + value.handle = NULL; + value.prefix = NULL; + } + } + + DOCUMENT_START_EVENT_INIT(*event, version_directive_copy, + tag_directives_copy.start, tag_directives_copy.top, + implicit, mark, mark); + + return 1; + +error: + yaml_free(version_directive_copy); + while (!STACK_EMPTY(context, tag_directives_copy)) { + yaml_tag_directive_t value = POP(context, tag_directives_copy); + yaml_free(value.handle); + yaml_free(value.prefix); + } + STACK_DEL(context, tag_directives_copy); + yaml_free(value.handle); + yaml_free(value.prefix); + + return 0; +} + +/* + * Create DOCUMENT-END. + */ + +YAML_DECLARE(int) +yaml_document_end_event_initialize(yaml_event_t *event, int implicit) +{ + yaml_mark_t mark = { 0, 0, 0 }; + + assert(event); /* Non-NULL emitter object is expected. */ + + DOCUMENT_END_EVENT_INIT(*event, implicit, mark, mark); + + return 1; +} + +/* + * Create ALIAS. + */ + +YAML_DECLARE(int) +yaml_alias_event_initialize(yaml_event_t *event, yaml_char_t *anchor) +{ + yaml_mark_t mark = { 0, 0, 0 }; + yaml_char_t *anchor_copy = NULL; + + assert(event); /* Non-NULL event object is expected. */ + assert(anchor); /* Non-NULL anchor is expected. */ + + if (!yaml_check_utf8(anchor, strlen((char *)anchor))) return 0; + + anchor_copy = yaml_strdup(anchor); + if (!anchor_copy) + return 0; + + ALIAS_EVENT_INIT(*event, anchor_copy, mark, mark); + + return 1; +} + +/* + * Create SCALAR. + */ + +YAML_DECLARE(int) +yaml_scalar_event_initialize(yaml_event_t *event, + yaml_char_t *anchor, yaml_char_t *tag, + yaml_char_t *value, int length, + int plain_implicit, int quoted_implicit, + yaml_scalar_style_t style) +{ + yaml_mark_t mark = { 0, 0, 0 }; + yaml_char_t *anchor_copy = NULL; + yaml_char_t *tag_copy = NULL; + yaml_char_t *value_copy = NULL; + + assert(event); /* Non-NULL event object is expected. */ + assert(value); /* Non-NULL anchor is expected. */ + + if (anchor) { + if (!yaml_check_utf8(anchor, strlen((char *)anchor))) goto error; + anchor_copy = yaml_strdup(anchor); + if (!anchor_copy) goto error; + } + + if (tag) { + if (!yaml_check_utf8(tag, strlen((char *)tag))) goto error; + tag_copy = yaml_strdup(tag); + if (!tag_copy) goto error; + } + + if (length < 0) { + length = strlen((char *)value); + } + + if (!yaml_check_utf8(value, length)) goto error; + value_copy = yaml_malloc(length+1); + if (!value_copy) goto error; + memcpy(value_copy, value, length); + value_copy[length] = '\0'; + + SCALAR_EVENT_INIT(*event, anchor_copy, tag_copy, value_copy, length, + plain_implicit, quoted_implicit, style, mark, mark); + + return 1; + +error: + yaml_free(anchor_copy); + yaml_free(tag_copy); + yaml_free(value_copy); + + return 0; +} + +/* + * Create SEQUENCE-START. + */ + +YAML_DECLARE(int) +yaml_sequence_start_event_initialize(yaml_event_t *event, + yaml_char_t *anchor, yaml_char_t *tag, int implicit, + yaml_sequence_style_t style) +{ + yaml_mark_t mark = { 0, 0, 0 }; + yaml_char_t *anchor_copy = NULL; + yaml_char_t *tag_copy = NULL; + + assert(event); /* Non-NULL event object is expected. */ + + if (anchor) { + if (!yaml_check_utf8(anchor, strlen((char *)anchor))) goto error; + anchor_copy = yaml_strdup(anchor); + if (!anchor_copy) goto error; + } + + if (tag) { + if (!yaml_check_utf8(tag, strlen((char *)tag))) goto error; + tag_copy = yaml_strdup(tag); + if (!tag_copy) goto error; + } + + SEQUENCE_START_EVENT_INIT(*event, anchor_copy, tag_copy, + implicit, style, mark, mark); + + return 1; + +error: + yaml_free(anchor_copy); + yaml_free(tag_copy); + + return 0; +} + +/* + * Create SEQUENCE-END. + */ + +YAML_DECLARE(int) +yaml_sequence_end_event_initialize(yaml_event_t *event) +{ + yaml_mark_t mark = { 0, 0, 0 }; + + assert(event); /* Non-NULL event object is expected. */ + + SEQUENCE_END_EVENT_INIT(*event, mark, mark); + + return 1; +} + +/* + * Create MAPPING-START. + */ + +YAML_DECLARE(int) +yaml_mapping_start_event_initialize(yaml_event_t *event, + yaml_char_t *anchor, yaml_char_t *tag, int implicit, + yaml_mapping_style_t style) +{ + yaml_mark_t mark = { 0, 0, 0 }; + yaml_char_t *anchor_copy = NULL; + yaml_char_t *tag_copy = NULL; + + assert(event); /* Non-NULL event object is expected. */ + + if (anchor) { + if (!yaml_check_utf8(anchor, strlen((char *)anchor))) goto error; + anchor_copy = yaml_strdup(anchor); + if (!anchor_copy) goto error; + } + + if (tag) { + if (!yaml_check_utf8(tag, strlen((char *)tag))) goto error; + tag_copy = yaml_strdup(tag); + if (!tag_copy) goto error; + } + + MAPPING_START_EVENT_INIT(*event, anchor_copy, tag_copy, + implicit, style, mark, mark); + + return 1; + +error: + yaml_free(anchor_copy); + yaml_free(tag_copy); + + return 0; +} + +/* + * Create MAPPING-END. + */ + +YAML_DECLARE(int) +yaml_mapping_end_event_initialize(yaml_event_t *event) +{ + yaml_mark_t mark = { 0, 0, 0 }; + + assert(event); /* Non-NULL event object is expected. */ + + MAPPING_END_EVENT_INIT(*event, mark, mark); + + return 1; +} + +/* + * Destroy an event object. + */ + +YAML_DECLARE(void) +yaml_event_delete(yaml_event_t *event) +{ + yaml_tag_directive_t *tag_directive; + + assert(event); /* Non-NULL event object expected. */ + + switch (event->type) + { + case YAML_DOCUMENT_START_EVENT: + yaml_free(event->data.document_start.version_directive); + for (tag_directive = event->data.document_start.tag_directives.start; + tag_directive != event->data.document_start.tag_directives.end; + tag_directive++) { + yaml_free(tag_directive->handle); + yaml_free(tag_directive->prefix); + } + yaml_free(event->data.document_start.tag_directives.start); + break; + + case YAML_ALIAS_EVENT: + yaml_free(event->data.alias.anchor); + break; + + case YAML_SCALAR_EVENT: + yaml_free(event->data.scalar.anchor); + yaml_free(event->data.scalar.tag); + yaml_free(event->data.scalar.value); + break; + + case YAML_SEQUENCE_START_EVENT: + yaml_free(event->data.sequence_start.anchor); + yaml_free(event->data.sequence_start.tag); + break; + + case YAML_MAPPING_START_EVENT: + yaml_free(event->data.mapping_start.anchor); + yaml_free(event->data.mapping_start.tag); + break; + + default: + break; + } + + memset(event, 0, sizeof(yaml_event_t)); +} + +/* + * Create a document object. + */ + +YAML_DECLARE(int) +yaml_document_initialize(yaml_document_t *document, + yaml_version_directive_t *version_directive, + yaml_tag_directive_t *tag_directives_start, + yaml_tag_directive_t *tag_directives_end, + int start_implicit, int end_implicit) +{ + struct { + yaml_error_type_t error; + } context; + struct { + yaml_node_t *start; + yaml_node_t *end; + yaml_node_t *top; + } nodes = { NULL, NULL, NULL }; + yaml_version_directive_t *version_directive_copy = NULL; + struct { + yaml_tag_directive_t *start; + yaml_tag_directive_t *end; + yaml_tag_directive_t *top; + } tag_directives_copy = { NULL, NULL, NULL }; + yaml_tag_directive_t value = { NULL, NULL }; + yaml_mark_t mark = { 0, 0, 0 }; + + assert(document); /* Non-NULL document object is expected. */ + assert((tag_directives_start && tag_directives_end) || + (tag_directives_start == tag_directives_end)); + /* Valid tag directives are expected. */ + + if (!STACK_INIT(&context, nodes, INITIAL_STACK_SIZE)) goto error; + + if (version_directive) { + version_directive_copy = yaml_malloc(sizeof(yaml_version_directive_t)); + if (!version_directive_copy) goto error; + version_directive_copy->major = version_directive->major; + version_directive_copy->minor = version_directive->minor; + } + + if (tag_directives_start != tag_directives_end) { + yaml_tag_directive_t *tag_directive; + if (!STACK_INIT(&context, tag_directives_copy, INITIAL_STACK_SIZE)) + goto error; + for (tag_directive = tag_directives_start; + tag_directive != tag_directives_end; tag_directive ++) { + assert(tag_directive->handle); + assert(tag_directive->prefix); + if (!yaml_check_utf8(tag_directive->handle, + strlen((char *)tag_directive->handle))) + goto error; + if (!yaml_check_utf8(tag_directive->prefix, + strlen((char *)tag_directive->prefix))) + goto error; + value.handle = yaml_strdup(tag_directive->handle); + value.prefix = yaml_strdup(tag_directive->prefix); + if (!value.handle || !value.prefix) goto error; + if (!PUSH(&context, tag_directives_copy, value)) + goto error; + value.handle = NULL; + value.prefix = NULL; + } + } + + DOCUMENT_INIT(*document, nodes.start, nodes.end, version_directive_copy, + tag_directives_copy.start, tag_directives_copy.top, + start_implicit, end_implicit, mark, mark); + + return 1; + +error: + STACK_DEL(&context, nodes); + yaml_free(version_directive_copy); + while (!STACK_EMPTY(&context, tag_directives_copy)) { + yaml_tag_directive_t value = POP(&context, tag_directives_copy); + yaml_free(value.handle); + yaml_free(value.prefix); + } + STACK_DEL(&context, tag_directives_copy); + yaml_free(value.handle); + yaml_free(value.prefix); + + return 0; +} + +/* + * Destroy a document object. + */ + +YAML_DECLARE(void) +yaml_document_delete(yaml_document_t *document) +{ + struct { + yaml_error_type_t error; + } context; + yaml_tag_directive_t *tag_directive; + + context.error = YAML_NO_ERROR; /* Eliminate a compliler warning. */ + + assert(document); /* Non-NULL document object is expected. */ + + while (!STACK_EMPTY(&context, document->nodes)) { + yaml_node_t node = POP(&context, document->nodes); + yaml_free(node.tag); + switch (node.type) { + case YAML_SCALAR_NODE: + yaml_free(node.data.scalar.value); + break; + case YAML_SEQUENCE_NODE: + STACK_DEL(&context, node.data.sequence.items); + break; + case YAML_MAPPING_NODE: + STACK_DEL(&context, node.data.mapping.pairs); + break; + default: + assert(0); /* Should not happen. */ + } + } + STACK_DEL(&context, document->nodes); + + yaml_free(document->version_directive); + for (tag_directive = document->tag_directives.start; + tag_directive != document->tag_directives.end; + tag_directive++) { + yaml_free(tag_directive->handle); + yaml_free(tag_directive->prefix); + } + yaml_free(document->tag_directives.start); + + memset(document, 0, sizeof(yaml_document_t)); +} + +/** + * Get a document node. + */ + +YAML_DECLARE(yaml_node_t *) +yaml_document_get_node(yaml_document_t *document, int index) +{ + assert(document); /* Non-NULL document object is expected. */ + + if (index > 0 && document->nodes.start + index <= document->nodes.top) { + return document->nodes.start + index - 1; + } + return NULL; +} + +/** + * Get the root object. + */ + +YAML_DECLARE(yaml_node_t *) +yaml_document_get_root_node(yaml_document_t *document) +{ + assert(document); /* Non-NULL document object is expected. */ + + if (document->nodes.top != document->nodes.start) { + return document->nodes.start; + } + return NULL; +} + +/* + * Add a scalar node to a document. + */ + +YAML_DECLARE(int) +yaml_document_add_scalar(yaml_document_t *document, + yaml_char_t *tag, yaml_char_t *value, int length, + yaml_scalar_style_t style) +{ + struct { + yaml_error_type_t error; + } context; + yaml_mark_t mark = { 0, 0, 0 }; + yaml_char_t *tag_copy = NULL; + yaml_char_t *value_copy = NULL; + yaml_node_t node; + + assert(document); /* Non-NULL document object is expected. */ + assert(value); /* Non-NULL value is expected. */ + + if (!tag) { + tag = (yaml_char_t *)YAML_DEFAULT_SCALAR_TAG; + } + + if (!yaml_check_utf8(tag, strlen((char *)tag))) goto error; + tag_copy = yaml_strdup(tag); + if (!tag_copy) goto error; + + if (length < 0) { + length = strlen((char *)value); + } + + if (!yaml_check_utf8(value, length)) goto error; + value_copy = yaml_malloc(length+1); + if (!value_copy) goto error; + memcpy(value_copy, value, length); + value_copy[length] = '\0'; + + SCALAR_NODE_INIT(node, tag_copy, value_copy, length, style, mark, mark); + if (!PUSH(&context, document->nodes, node)) goto error; + + return document->nodes.top - document->nodes.start; + +error: + yaml_free(tag_copy); + yaml_free(value_copy); + + return 0; +} + +/* + * Add a sequence node to a document. + */ + +YAML_DECLARE(int) +yaml_document_add_sequence(yaml_document_t *document, + yaml_char_t *tag, yaml_sequence_style_t style) +{ + struct { + yaml_error_type_t error; + } context; + yaml_mark_t mark = { 0, 0, 0 }; + yaml_char_t *tag_copy = NULL; + struct { + yaml_node_item_t *start; + yaml_node_item_t *end; + yaml_node_item_t *top; + } items = { NULL, NULL, NULL }; + yaml_node_t node; + + assert(document); /* Non-NULL document object is expected. */ + + if (!tag) { + tag = (yaml_char_t *)YAML_DEFAULT_SEQUENCE_TAG; + } + + if (!yaml_check_utf8(tag, strlen((char *)tag))) goto error; + tag_copy = yaml_strdup(tag); + if (!tag_copy) goto error; + + if (!STACK_INIT(&context, items, INITIAL_STACK_SIZE)) goto error; + + SEQUENCE_NODE_INIT(node, tag_copy, items.start, items.end, + style, mark, mark); + if (!PUSH(&context, document->nodes, node)) goto error; + + return document->nodes.top - document->nodes.start; + +error: + STACK_DEL(&context, items); + yaml_free(tag_copy); + + return 0; +} + +/* + * Add a mapping node to a document. + */ + +YAML_DECLARE(int) +yaml_document_add_mapping(yaml_document_t *document, + yaml_char_t *tag, yaml_mapping_style_t style) +{ + struct { + yaml_error_type_t error; + } context; + yaml_mark_t mark = { 0, 0, 0 }; + yaml_char_t *tag_copy = NULL; + struct { + yaml_node_pair_t *start; + yaml_node_pair_t *end; + yaml_node_pair_t *top; + } pairs = { NULL, NULL, NULL }; + yaml_node_t node; + + assert(document); /* Non-NULL document object is expected. */ + + if (!tag) { + tag = (yaml_char_t *)YAML_DEFAULT_MAPPING_TAG; + } + + if (!yaml_check_utf8(tag, strlen((char *)tag))) goto error; + tag_copy = yaml_strdup(tag); + if (!tag_copy) goto error; + + if (!STACK_INIT(&context, pairs, INITIAL_STACK_SIZE)) goto error; + + MAPPING_NODE_INIT(node, tag_copy, pairs.start, pairs.end, + style, mark, mark); + if (!PUSH(&context, document->nodes, node)) goto error; + + return document->nodes.top - document->nodes.start; + +error: + STACK_DEL(&context, pairs); + yaml_free(tag_copy); + + return 0; +} + +/* + * Append an item to a sequence node. + */ + +YAML_DECLARE(int) +yaml_document_append_sequence_item(yaml_document_t *document, + int sequence, int item) +{ + struct { + yaml_error_type_t error; + } context; + + assert(document); /* Non-NULL document is required. */ + assert(sequence > 0 + && document->nodes.start + sequence <= document->nodes.top); + /* Valid sequence id is required. */ + assert(document->nodes.start[sequence-1].type == YAML_SEQUENCE_NODE); + /* A sequence node is required. */ + assert(item > 0 && document->nodes.start + item <= document->nodes.top); + /* Valid item id is required. */ + + if (!PUSH(&context, + document->nodes.start[sequence-1].data.sequence.items, item)) + return 0; + + return 1; +} + +/* + * Append a pair of a key and a value to a mapping node. + */ + +YAML_DECLARE(int) +yaml_document_append_mapping_pair(yaml_document_t *document, + int mapping, int key, int value) +{ + struct { + yaml_error_type_t error; + } context; + + yaml_node_pair_t pair; + + assert(document); /* Non-NULL document is required. */ + assert(mapping > 0 + && document->nodes.start + mapping <= document->nodes.top); + /* Valid mapping id is required. */ + assert(document->nodes.start[mapping-1].type == YAML_MAPPING_NODE); + /* A mapping node is required. */ + assert(key > 0 && document->nodes.start + key <= document->nodes.top); + /* Valid key id is required. */ + assert(value > 0 && document->nodes.start + value <= document->nodes.top); + /* Valid value id is required. */ + + pair.key = key; + pair.value = value; + + if (!PUSH(&context, + document->nodes.start[mapping-1].data.mapping.pairs, pair)) + return 0; + + return 1; +} + + diff --git a/libyaml/src/dumper.c b/libyaml/src/dumper.c new file mode 100644 index 00000000..203c6a70 --- /dev/null +++ b/libyaml/src/dumper.c @@ -0,0 +1,394 @@ + +#include "yaml_private.h" + +/* + * API functions. + */ + +YAML_DECLARE(int) +yaml_emitter_open(yaml_emitter_t *emitter); + +YAML_DECLARE(int) +yaml_emitter_close(yaml_emitter_t *emitter); + +YAML_DECLARE(int) +yaml_emitter_dump(yaml_emitter_t *emitter, yaml_document_t *document); + +/* + * Clean up functions. + */ + +static void +yaml_emitter_delete_document_and_anchors(yaml_emitter_t *emitter); + +/* + * Anchor functions. + */ + +static void +yaml_emitter_anchor_node(yaml_emitter_t *emitter, int index); + +static yaml_char_t * +yaml_emitter_generate_anchor(yaml_emitter_t *emitter, int anchor_id); + + +/* + * Serialize functions. + */ + +static int +yaml_emitter_dump_node(yaml_emitter_t *emitter, int index); + +static int +yaml_emitter_dump_alias(yaml_emitter_t *emitter, yaml_char_t *anchor); + +static int +yaml_emitter_dump_scalar(yaml_emitter_t *emitter, yaml_node_t *node, + yaml_char_t *anchor); + +static int +yaml_emitter_dump_sequence(yaml_emitter_t *emitter, yaml_node_t *node, + yaml_char_t *anchor); + +static int +yaml_emitter_dump_mapping(yaml_emitter_t *emitter, yaml_node_t *node, + yaml_char_t *anchor); + +/* + * Issue a STREAM-START event. + */ + +YAML_DECLARE(int) +yaml_emitter_open(yaml_emitter_t *emitter) +{ + yaml_event_t event; + yaml_mark_t mark = { 0, 0, 0 }; + + assert(emitter); /* Non-NULL emitter object is required. */ + assert(!emitter->opened); /* Emitter should not be opened yet. */ + + STREAM_START_EVENT_INIT(event, YAML_ANY_ENCODING, mark, mark); + + if (!yaml_emitter_emit(emitter, &event)) { + return 0; + } + + emitter->opened = 1; + + return 1; +} + +/* + * Issue a STREAM-END event. + */ + +YAML_DECLARE(int) +yaml_emitter_close(yaml_emitter_t *emitter) +{ + yaml_event_t event; + yaml_mark_t mark = { 0, 0, 0 }; + + assert(emitter); /* Non-NULL emitter object is required. */ + assert(emitter->opened); /* Emitter should be opened. */ + + if (emitter->closed) return 1; + + STREAM_END_EVENT_INIT(event, mark, mark); + + if (!yaml_emitter_emit(emitter, &event)) { + return 0; + } + + emitter->closed = 1; + + return 1; +} + +/* + * Dump a YAML document. + */ + +YAML_DECLARE(int) +yaml_emitter_dump(yaml_emitter_t *emitter, yaml_document_t *document) +{ + yaml_event_t event; + yaml_mark_t mark = { 0, 0, 0 }; + + assert(emitter); /* Non-NULL emitter object is required. */ + assert(document); /* Non-NULL emitter object is expected. */ + + emitter->document = document; + + if (!emitter->opened) { + if (!yaml_emitter_open(emitter)) goto error; + } + + if (STACK_EMPTY(emitter, document->nodes)) { + if (!yaml_emitter_close(emitter)) goto error; + yaml_emitter_delete_document_and_anchors(emitter); + return 1; + } + + assert(emitter->opened); /* Emitter should be opened. */ + + emitter->anchors = yaml_malloc(sizeof(*(emitter->anchors)) + * (document->nodes.top - document->nodes.start)); + if (!emitter->anchors) goto error; + memset(emitter->anchors, 0, sizeof(*(emitter->anchors)) + * (document->nodes.top - document->nodes.start)); + + DOCUMENT_START_EVENT_INIT(event, document->version_directive, + document->tag_directives.start, document->tag_directives.end, + document->start_implicit, mark, mark); + if (!yaml_emitter_emit(emitter, &event)) goto error; + + yaml_emitter_anchor_node(emitter, 1); + if (!yaml_emitter_dump_node(emitter, 1)) goto error; + + DOCUMENT_END_EVENT_INIT(event, document->end_implicit, mark, mark); + if (!yaml_emitter_emit(emitter, &event)) goto error; + + yaml_emitter_delete_document_and_anchors(emitter); + + return 1; + +error: + + yaml_emitter_delete_document_and_anchors(emitter); + + return 0; +} + +/* + * Clean up the emitter object after a document is dumped. + */ + +static void +yaml_emitter_delete_document_and_anchors(yaml_emitter_t *emitter) +{ + int index; + + if (!emitter->anchors) { + yaml_document_delete(emitter->document); + emitter->document = NULL; + return; + } + + for (index = 0; emitter->document->nodes.start + index + < emitter->document->nodes.top; index ++) { + yaml_node_t node = emitter->document->nodes.start[index]; + if (!emitter->anchors[index].serialized) { + yaml_free(node.tag); + if (node.type == YAML_SCALAR_NODE) { + yaml_free(node.data.scalar.value); + } + } + if (node.type == YAML_SEQUENCE_NODE) { + STACK_DEL(emitter, node.data.sequence.items); + } + if (node.type == YAML_MAPPING_NODE) { + STACK_DEL(emitter, node.data.mapping.pairs); + } + } + + STACK_DEL(emitter, emitter->document->nodes); + yaml_free(emitter->anchors); + + emitter->anchors = NULL; + emitter->last_anchor_id = 0; + emitter->document = NULL; +} + +/* + * Check the references of a node and assign the anchor id if needed. + */ + +static void +yaml_emitter_anchor_node(yaml_emitter_t *emitter, int index) +{ + yaml_node_t *node = emitter->document->nodes.start + index - 1; + yaml_node_item_t *item; + yaml_node_pair_t *pair; + + emitter->anchors[index-1].references ++; + + if (emitter->anchors[index-1].references == 1) { + switch (node->type) { + case YAML_SEQUENCE_NODE: + for (item = node->data.sequence.items.start; + item < node->data.sequence.items.top; item ++) { + yaml_emitter_anchor_node(emitter, *item); + } + break; + case YAML_MAPPING_NODE: + for (pair = node->data.mapping.pairs.start; + pair < node->data.mapping.pairs.top; pair ++) { + yaml_emitter_anchor_node(emitter, pair->key); + yaml_emitter_anchor_node(emitter, pair->value); + } + break; + default: + break; + } + } + + else if (emitter->anchors[index-1].references == 2) { + emitter->anchors[index-1].anchor = (++ emitter->last_anchor_id); + } +} + +/* + * Generate a textual representation for an anchor. + */ + +#define ANCHOR_TEMPLATE "id%03d" +#define ANCHOR_TEMPLATE_LENGTH 16 + +static yaml_char_t * +yaml_emitter_generate_anchor(yaml_emitter_t *emitter, int anchor_id) +{ + yaml_char_t *anchor = yaml_malloc(ANCHOR_TEMPLATE_LENGTH); + + if (!anchor) return NULL; + + sprintf((char *)anchor, ANCHOR_TEMPLATE, anchor_id); + + return anchor; +} + +/* + * Serialize a node. + */ + +static int +yaml_emitter_dump_node(yaml_emitter_t *emitter, int index) +{ + yaml_node_t *node = emitter->document->nodes.start + index - 1; + int anchor_id = emitter->anchors[index-1].anchor; + yaml_char_t *anchor = NULL; + + if (anchor_id) { + anchor = yaml_emitter_generate_anchor(emitter, anchor_id); + if (!anchor) return 0; + } + + if (emitter->anchors[index-1].serialized) { + return yaml_emitter_dump_alias(emitter, anchor); + } + + emitter->anchors[index-1].serialized = 1; + + switch (node->type) { + case YAML_SCALAR_NODE: + return yaml_emitter_dump_scalar(emitter, node, anchor); + case YAML_SEQUENCE_NODE: + return yaml_emitter_dump_sequence(emitter, node, anchor); + case YAML_MAPPING_NODE: + return yaml_emitter_dump_mapping(emitter, node, anchor); + default: + assert(0); /* Could not happen. */ + break; + } + + return 0; /* Could not happen. */ +} + +/* + * Serialize an alias. + */ + +static int +yaml_emitter_dump_alias(yaml_emitter_t *emitter, yaml_char_t *anchor) +{ + yaml_event_t event; + yaml_mark_t mark = { 0, 0, 0 }; + + ALIAS_EVENT_INIT(event, anchor, mark, mark); + + return yaml_emitter_emit(emitter, &event); +} + +/* + * Serialize a scalar. + */ + +static int +yaml_emitter_dump_scalar(yaml_emitter_t *emitter, yaml_node_t *node, + yaml_char_t *anchor) +{ + yaml_event_t event; + yaml_mark_t mark = { 0, 0, 0 }; + + int plain_implicit = (strcmp((char *)node->tag, + YAML_DEFAULT_SCALAR_TAG) == 0); + int quoted_implicit = (strcmp((char *)node->tag, + YAML_DEFAULT_SCALAR_TAG) == 0); + + SCALAR_EVENT_INIT(event, anchor, node->tag, node->data.scalar.value, + node->data.scalar.length, plain_implicit, quoted_implicit, + node->data.scalar.style, mark, mark); + + return yaml_emitter_emit(emitter, &event); +} + +/* + * Serialize a sequence. + */ + +static int +yaml_emitter_dump_sequence(yaml_emitter_t *emitter, yaml_node_t *node, + yaml_char_t *anchor) +{ + yaml_event_t event; + yaml_mark_t mark = { 0, 0, 0 }; + + int implicit = (strcmp((char *)node->tag, YAML_DEFAULT_SEQUENCE_TAG) == 0); + + yaml_node_item_t *item; + + SEQUENCE_START_EVENT_INIT(event, anchor, node->tag, implicit, + node->data.sequence.style, mark, mark); + if (!yaml_emitter_emit(emitter, &event)) return 0; + + for (item = node->data.sequence.items.start; + item < node->data.sequence.items.top; item ++) { + if (!yaml_emitter_dump_node(emitter, *item)) return 0; + } + + SEQUENCE_END_EVENT_INIT(event, mark, mark); + if (!yaml_emitter_emit(emitter, &event)) return 0; + + return 1; +} + +/* + * Serialize a mapping. + */ + +static int +yaml_emitter_dump_mapping(yaml_emitter_t *emitter, yaml_node_t *node, + yaml_char_t *anchor) +{ + yaml_event_t event; + yaml_mark_t mark = { 0, 0, 0 }; + + int implicit = (strcmp((char *)node->tag, YAML_DEFAULT_MAPPING_TAG) == 0); + + yaml_node_pair_t *pair; + + MAPPING_START_EVENT_INIT(event, anchor, node->tag, implicit, + node->data.mapping.style, mark, mark); + if (!yaml_emitter_emit(emitter, &event)) return 0; + + for (pair = node->data.mapping.pairs.start; + pair < node->data.mapping.pairs.top; pair ++) { + if (!yaml_emitter_dump_node(emitter, pair->key)) return 0; + if (!yaml_emitter_dump_node(emitter, pair->value)) return 0; + } + + MAPPING_END_EVENT_INIT(event, mark, mark); + if (!yaml_emitter_emit(emitter, &event)) return 0; + + return 1; +} + diff --git a/libyaml/src/emitter.c b/libyaml/src/emitter.c new file mode 100644 index 00000000..c4b56a26 --- /dev/null +++ b/libyaml/src/emitter.c @@ -0,0 +1,2329 @@ + +#include "yaml_private.h" + +/* + * Flush the buffer if needed. + */ + +#define FLUSH(emitter) \ + ((emitter->buffer.pointer+5 < emitter->buffer.end) \ + || yaml_emitter_flush(emitter)) + +/* + * Put a character to the output buffer. + */ + +#define PUT(emitter,value) \ + (FLUSH(emitter) \ + && (*(emitter->buffer.pointer++) = (yaml_char_t)(value), \ + emitter->column ++, \ + 1)) + +/* + * Put a line break to the output buffer. + */ + +#define PUT_BREAK(emitter) \ + (FLUSH(emitter) \ + && ((emitter->line_break == YAML_CR_BREAK ? \ + (*(emitter->buffer.pointer++) = (yaml_char_t) '\r') : \ + emitter->line_break == YAML_LN_BREAK ? \ + (*(emitter->buffer.pointer++) = (yaml_char_t) '\n') : \ + emitter->line_break == YAML_CRLN_BREAK ? \ + (*(emitter->buffer.pointer++) = (yaml_char_t) '\r', \ + *(emitter->buffer.pointer++) = (yaml_char_t) '\n') : 0), \ + emitter->column = 0, \ + emitter->line ++, \ + 1)) + +/* + * Copy a character from a string into buffer. + */ + +#define WRITE(emitter,string) \ + (FLUSH(emitter) \ + && (COPY(emitter->buffer,string), \ + emitter->column ++, \ + 1)) + +/* + * Copy a line break character from a string into buffer. + */ + +#define WRITE_BREAK(emitter,string) \ + (FLUSH(emitter) \ + && (CHECK(string,'\n') ? \ + (PUT_BREAK(emitter), \ + string.pointer ++, \ + 1) : \ + (COPY(emitter->buffer,string), \ + emitter->column = 0, \ + emitter->line ++, \ + 1))) + +/* + * API functions. + */ + +YAML_DECLARE(int) +yaml_emitter_emit(yaml_emitter_t *emitter, yaml_event_t *event); + +/* + * Utility functions. + */ + +static int +yaml_emitter_set_emitter_error(yaml_emitter_t *emitter, const char *problem); + +static int +yaml_emitter_need_more_events(yaml_emitter_t *emitter); + +static int +yaml_emitter_append_tag_directive(yaml_emitter_t *emitter, + yaml_tag_directive_t value, int allow_duplicates); + +static int +yaml_emitter_increase_indent(yaml_emitter_t *emitter, + int flow, int indentless); + +/* + * State functions. + */ + +static int +yaml_emitter_state_machine(yaml_emitter_t *emitter, yaml_event_t *event); + +static int +yaml_emitter_emit_stream_start(yaml_emitter_t *emitter, + yaml_event_t *event); + +static int +yaml_emitter_emit_document_start(yaml_emitter_t *emitter, + yaml_event_t *event, int first); + +static int +yaml_emitter_emit_document_content(yaml_emitter_t *emitter, + yaml_event_t *event); + +static int +yaml_emitter_emit_document_end(yaml_emitter_t *emitter, + yaml_event_t *event); + +static int +yaml_emitter_emit_flow_sequence_item(yaml_emitter_t *emitter, + yaml_event_t *event, int first); + +static int +yaml_emitter_emit_flow_mapping_key(yaml_emitter_t *emitter, + yaml_event_t *event, int first); + +static int +yaml_emitter_emit_flow_mapping_value(yaml_emitter_t *emitter, + yaml_event_t *event, int simple); + +static int +yaml_emitter_emit_block_sequence_item(yaml_emitter_t *emitter, + yaml_event_t *event, int first); + +static int +yaml_emitter_emit_block_mapping_key(yaml_emitter_t *emitter, + yaml_event_t *event, int first); + +static int +yaml_emitter_emit_block_mapping_value(yaml_emitter_t *emitter, + yaml_event_t *event, int simple); + +static int +yaml_emitter_emit_node(yaml_emitter_t *emitter, yaml_event_t *event, + int root, int sequence, int mapping, int simple_key); + +static int +yaml_emitter_emit_alias(yaml_emitter_t *emitter, yaml_event_t *event); + +static int +yaml_emitter_emit_scalar(yaml_emitter_t *emitter, yaml_event_t *event); + +static int +yaml_emitter_emit_sequence_start(yaml_emitter_t *emitter, yaml_event_t *event); + +static int +yaml_emitter_emit_mapping_start(yaml_emitter_t *emitter, yaml_event_t *event); + +/* + * Checkers. + */ + +static int +yaml_emitter_check_empty_document(yaml_emitter_t *emitter); + +static int +yaml_emitter_check_empty_sequence(yaml_emitter_t *emitter); + +static int +yaml_emitter_check_empty_mapping(yaml_emitter_t *emitter); + +static int +yaml_emitter_check_simple_key(yaml_emitter_t *emitter); + +static int +yaml_emitter_select_scalar_style(yaml_emitter_t *emitter, yaml_event_t *event); + +/* + * Processors. + */ + +static int +yaml_emitter_process_anchor(yaml_emitter_t *emitter); + +static int +yaml_emitter_process_tag(yaml_emitter_t *emitter); + +static int +yaml_emitter_process_scalar(yaml_emitter_t *emitter); + +/* + * Analyzers. + */ + +static int +yaml_emitter_analyze_version_directive(yaml_emitter_t *emitter, + yaml_version_directive_t version_directive); + +static int +yaml_emitter_analyze_tag_directive(yaml_emitter_t *emitter, + yaml_tag_directive_t tag_directive); + +static int +yaml_emitter_analyze_anchor(yaml_emitter_t *emitter, + yaml_char_t *anchor, int alias); + +static int +yaml_emitter_analyze_tag(yaml_emitter_t *emitter, + yaml_char_t *tag); + +static int +yaml_emitter_analyze_scalar(yaml_emitter_t *emitter, + yaml_char_t *value, size_t length); + +static int +yaml_emitter_analyze_event(yaml_emitter_t *emitter, + yaml_event_t *event); + +/* + * Writers. + */ + +static int +yaml_emitter_write_bom(yaml_emitter_t *emitter); + +static int +yaml_emitter_write_indent(yaml_emitter_t *emitter); + +static int +yaml_emitter_write_indicator(yaml_emitter_t *emitter, + char *indicator, int need_whitespace, + int is_whitespace, int is_indention); + +static int +yaml_emitter_write_anchor(yaml_emitter_t *emitter, + yaml_char_t *value, size_t length); + +static int +yaml_emitter_write_tag_handle(yaml_emitter_t *emitter, + yaml_char_t *value, size_t length); + +static int +yaml_emitter_write_tag_content(yaml_emitter_t *emitter, + yaml_char_t *value, size_t length, int need_whitespace); + +static int +yaml_emitter_write_plain_scalar(yaml_emitter_t *emitter, + yaml_char_t *value, size_t length, int allow_breaks); + +static int +yaml_emitter_write_single_quoted_scalar(yaml_emitter_t *emitter, + yaml_char_t *value, size_t length, int allow_breaks); + +static int +yaml_emitter_write_double_quoted_scalar(yaml_emitter_t *emitter, + yaml_char_t *value, size_t length, int allow_breaks); + +static int +yaml_emitter_write_block_scalar_hints(yaml_emitter_t *emitter, + yaml_string_t string); + +static int +yaml_emitter_write_literal_scalar(yaml_emitter_t *emitter, + yaml_char_t *value, size_t length); + +static int +yaml_emitter_write_folded_scalar(yaml_emitter_t *emitter, + yaml_char_t *value, size_t length); + +/* + * Set an emitter error and return 0. + */ + +static int +yaml_emitter_set_emitter_error(yaml_emitter_t *emitter, const char *problem) +{ + emitter->error = YAML_EMITTER_ERROR; + emitter->problem = problem; + + return 0; +} + +/* + * Emit an event. + */ + +YAML_DECLARE(int) +yaml_emitter_emit(yaml_emitter_t *emitter, yaml_event_t *event) +{ + if (!ENQUEUE(emitter, emitter->events, *event)) { + yaml_event_delete(event); + return 0; + } + + while (!yaml_emitter_need_more_events(emitter)) { + if (!yaml_emitter_analyze_event(emitter, emitter->events.head)) + return 0; + if (!yaml_emitter_state_machine(emitter, emitter->events.head)) + return 0; + yaml_event_delete(&DEQUEUE(emitter, emitter->events)); + } + + return 1; +} + +/* + * Check if we need to accumulate more events before emitting. + * + * We accumulate extra + * - 1 event for DOCUMENT-START + * - 2 events for SEQUENCE-START + * - 3 events for MAPPING-START + */ + +static int +yaml_emitter_need_more_events(yaml_emitter_t *emitter) +{ + int level = 0; + int accumulate = 0; + yaml_event_t *event; + + if (QUEUE_EMPTY(emitter, emitter->events)) + return 1; + + switch (emitter->events.head->type) { + case YAML_DOCUMENT_START_EVENT: + accumulate = 1; + break; + case YAML_SEQUENCE_START_EVENT: + accumulate = 2; + break; + case YAML_MAPPING_START_EVENT: + accumulate = 3; + break; + default: + return 0; + } + + if (emitter->events.tail - emitter->events.head > accumulate) + return 0; + + for (event = emitter->events.head; event != emitter->events.tail; event ++) { + switch (event->type) { + case YAML_STREAM_START_EVENT: + case YAML_DOCUMENT_START_EVENT: + case YAML_SEQUENCE_START_EVENT: + case YAML_MAPPING_START_EVENT: + level += 1; + break; + case YAML_STREAM_END_EVENT: + case YAML_DOCUMENT_END_EVENT: + case YAML_SEQUENCE_END_EVENT: + case YAML_MAPPING_END_EVENT: + level -= 1; + break; + default: + break; + } + if (!level) + return 0; + } + + return 1; +} + +/* + * Append a directive to the directives stack. + */ + +static int +yaml_emitter_append_tag_directive(yaml_emitter_t *emitter, + yaml_tag_directive_t value, int allow_duplicates) +{ + yaml_tag_directive_t *tag_directive; + yaml_tag_directive_t copy = { NULL, NULL }; + + for (tag_directive = emitter->tag_directives.start; + tag_directive != emitter->tag_directives.top; tag_directive ++) { + if (strcmp((char *)value.handle, (char *)tag_directive->handle) == 0) { + if (allow_duplicates) + return 1; + return yaml_emitter_set_emitter_error(emitter, + "duplicate %TAG directive"); + } + } + + copy.handle = yaml_strdup(value.handle); + copy.prefix = yaml_strdup(value.prefix); + if (!copy.handle || !copy.prefix) { + emitter->error = YAML_MEMORY_ERROR; + goto error; + } + + if (!PUSH(emitter, emitter->tag_directives, copy)) + goto error; + + return 1; + +error: + yaml_free(copy.handle); + yaml_free(copy.prefix); + return 0; +} + +/* + * Increase the indentation level. + */ + +static int +yaml_emitter_increase_indent(yaml_emitter_t *emitter, + int flow, int indentless) +{ + if (!PUSH(emitter, emitter->indents, emitter->indent)) + return 0; + + if (emitter->indent < 0) { + emitter->indent = flow ? emitter->best_indent : 0; + } + else if (!indentless) { + emitter->indent += emitter->best_indent; + } + + return 1; +} + +/* + * State dispatcher. + */ + +static int +yaml_emitter_state_machine(yaml_emitter_t *emitter, yaml_event_t *event) +{ + switch (emitter->state) + { + case YAML_EMIT_STREAM_START_STATE: + return yaml_emitter_emit_stream_start(emitter, event); + + case YAML_EMIT_FIRST_DOCUMENT_START_STATE: + return yaml_emitter_emit_document_start(emitter, event, 1); + + case YAML_EMIT_DOCUMENT_START_STATE: + return yaml_emitter_emit_document_start(emitter, event, 0); + + case YAML_EMIT_DOCUMENT_CONTENT_STATE: + return yaml_emitter_emit_document_content(emitter, event); + + case YAML_EMIT_DOCUMENT_END_STATE: + return yaml_emitter_emit_document_end(emitter, event); + + case YAML_EMIT_FLOW_SEQUENCE_FIRST_ITEM_STATE: + return yaml_emitter_emit_flow_sequence_item(emitter, event, 1); + + case YAML_EMIT_FLOW_SEQUENCE_ITEM_STATE: + return yaml_emitter_emit_flow_sequence_item(emitter, event, 0); + + case YAML_EMIT_FLOW_MAPPING_FIRST_KEY_STATE: + return yaml_emitter_emit_flow_mapping_key(emitter, event, 1); + + case YAML_EMIT_FLOW_MAPPING_KEY_STATE: + return yaml_emitter_emit_flow_mapping_key(emitter, event, 0); + + case YAML_EMIT_FLOW_MAPPING_SIMPLE_VALUE_STATE: + return yaml_emitter_emit_flow_mapping_value(emitter, event, 1); + + case YAML_EMIT_FLOW_MAPPING_VALUE_STATE: + return yaml_emitter_emit_flow_mapping_value(emitter, event, 0); + + case YAML_EMIT_BLOCK_SEQUENCE_FIRST_ITEM_STATE: + return yaml_emitter_emit_block_sequence_item(emitter, event, 1); + + case YAML_EMIT_BLOCK_SEQUENCE_ITEM_STATE: + return yaml_emitter_emit_block_sequence_item(emitter, event, 0); + + case YAML_EMIT_BLOCK_MAPPING_FIRST_KEY_STATE: + return yaml_emitter_emit_block_mapping_key(emitter, event, 1); + + case YAML_EMIT_BLOCK_MAPPING_KEY_STATE: + return yaml_emitter_emit_block_mapping_key(emitter, event, 0); + + case YAML_EMIT_BLOCK_MAPPING_SIMPLE_VALUE_STATE: + return yaml_emitter_emit_block_mapping_value(emitter, event, 1); + + case YAML_EMIT_BLOCK_MAPPING_VALUE_STATE: + return yaml_emitter_emit_block_mapping_value(emitter, event, 0); + + case YAML_EMIT_END_STATE: + return yaml_emitter_set_emitter_error(emitter, + "expected nothing after STREAM-END"); + + default: + assert(1); /* Invalid state. */ + } + + return 0; +} + +/* + * Expect STREAM-START. + */ + +static int +yaml_emitter_emit_stream_start(yaml_emitter_t *emitter, + yaml_event_t *event) +{ + if (event->type == YAML_STREAM_START_EVENT) + { + if (!emitter->encoding) { + emitter->encoding = event->data.stream_start.encoding; + } + + if (!emitter->encoding) { + emitter->encoding = YAML_UTF8_ENCODING; + } + + if (emitter->best_indent < 2 || emitter->best_indent > 9) { + emitter->best_indent = 2; + } + + if (emitter->best_width >= 0 + && emitter->best_width <= emitter->best_indent*2) { + emitter->best_width = 80; + } + + if (emitter->best_width < 0) { + emitter->best_width = INT_MAX; + } + + if (!emitter->line_break) { + emitter->line_break = YAML_LN_BREAK; + } + + emitter->indent = -1; + + emitter->line = 0; + emitter->column = 0; + emitter->whitespace = 1; + emitter->indention = 1; + + if (emitter->encoding != YAML_UTF8_ENCODING) { + if (!yaml_emitter_write_bom(emitter)) + return 0; + } + + emitter->state = YAML_EMIT_FIRST_DOCUMENT_START_STATE; + + return 1; + } + + return yaml_emitter_set_emitter_error(emitter, + "expected STREAM-START"); +} + +/* + * Expect DOCUMENT-START or STREAM-END. + */ + +static int +yaml_emitter_emit_document_start(yaml_emitter_t *emitter, + yaml_event_t *event, int first) +{ + if (event->type == YAML_DOCUMENT_START_EVENT) + { + yaml_tag_directive_t default_tag_directives[] = { + {(yaml_char_t *)"!", (yaml_char_t *)"!"}, + {(yaml_char_t *)"!!", (yaml_char_t *)"tag:yaml.org,2002:"}, + {NULL, NULL} + }; + yaml_tag_directive_t *tag_directive; + int implicit; + + if (event->data.document_start.version_directive) { + if (!yaml_emitter_analyze_version_directive(emitter, + *event->data.document_start.version_directive)) + return 0; + } + + for (tag_directive = event->data.document_start.tag_directives.start; + tag_directive != event->data.document_start.tag_directives.end; + tag_directive ++) { + if (!yaml_emitter_analyze_tag_directive(emitter, *tag_directive)) + return 0; + if (!yaml_emitter_append_tag_directive(emitter, *tag_directive, 0)) + return 0; + } + + for (tag_directive = default_tag_directives; + tag_directive->handle; tag_directive ++) { + if (!yaml_emitter_append_tag_directive(emitter, *tag_directive, 1)) + return 0; + } + + implicit = event->data.document_start.implicit; + if (!first || emitter->canonical) { + implicit = 0; + } + + if ((event->data.document_start.version_directive || + (event->data.document_start.tag_directives.start + != event->data.document_start.tag_directives.end)) && + emitter->open_ended) + { + if (!yaml_emitter_write_indicator(emitter, "...", 1, 0, 0)) + return 0; + if (!yaml_emitter_write_indent(emitter)) + return 0; + } + + if (event->data.document_start.version_directive) { + implicit = 0; + if (!yaml_emitter_write_indicator(emitter, "%YAML", 1, 0, 0)) + return 0; + if (!yaml_emitter_write_indicator(emitter, "1.1", 1, 0, 0)) + return 0; + if (!yaml_emitter_write_indent(emitter)) + return 0; + } + + if (event->data.document_start.tag_directives.start + != event->data.document_start.tag_directives.end) { + implicit = 0; + for (tag_directive = event->data.document_start.tag_directives.start; + tag_directive != event->data.document_start.tag_directives.end; + tag_directive ++) { + if (!yaml_emitter_write_indicator(emitter, "%TAG", 1, 0, 0)) + return 0; + if (!yaml_emitter_write_tag_handle(emitter, tag_directive->handle, + strlen((char *)tag_directive->handle))) + return 0; + if (!yaml_emitter_write_tag_content(emitter, tag_directive->prefix, + strlen((char *)tag_directive->prefix), 1)) + return 0; + if (!yaml_emitter_write_indent(emitter)) + return 0; + } + } + + if (yaml_emitter_check_empty_document(emitter)) { + implicit = 0; + } + + if (!implicit) { + if (!yaml_emitter_write_indent(emitter)) + return 0; + if (!yaml_emitter_write_indicator(emitter, "---", 1, 0, 0)) + return 0; + if (emitter->canonical) { + if (!yaml_emitter_write_indent(emitter)) + return 0; + } + } + + emitter->state = YAML_EMIT_DOCUMENT_CONTENT_STATE; + + return 1; + } + + else if (event->type == YAML_STREAM_END_EVENT) + { + if (emitter->open_ended) + { + if (!yaml_emitter_write_indicator(emitter, "...", 1, 0, 0)) + return 0; + if (!yaml_emitter_write_indent(emitter)) + return 0; + } + + if (!yaml_emitter_flush(emitter)) + return 0; + + emitter->state = YAML_EMIT_END_STATE; + + return 1; + } + + return yaml_emitter_set_emitter_error(emitter, + "expected DOCUMENT-START or STREAM-END"); +} + +/* + * Expect the root node. + */ + +static int +yaml_emitter_emit_document_content(yaml_emitter_t *emitter, + yaml_event_t *event) +{ + if (!PUSH(emitter, emitter->states, YAML_EMIT_DOCUMENT_END_STATE)) + return 0; + + return yaml_emitter_emit_node(emitter, event, 1, 0, 0, 0); +} + +/* + * Expect DOCUMENT-END. + */ + +static int +yaml_emitter_emit_document_end(yaml_emitter_t *emitter, + yaml_event_t *event) +{ + if (event->type == YAML_DOCUMENT_END_EVENT) + { + if (!yaml_emitter_write_indent(emitter)) + return 0; + if (!event->data.document_end.implicit) { + if (!yaml_emitter_write_indicator(emitter, "...", 1, 0, 0)) + return 0; + if (!yaml_emitter_write_indent(emitter)) + return 0; + } + if (!yaml_emitter_flush(emitter)) + return 0; + + emitter->state = YAML_EMIT_DOCUMENT_START_STATE; + + while (!STACK_EMPTY(emitter, emitter->tag_directives)) { + yaml_tag_directive_t tag_directive = POP(emitter, + emitter->tag_directives); + yaml_free(tag_directive.handle); + yaml_free(tag_directive.prefix); + } + + return 1; + } + + return yaml_emitter_set_emitter_error(emitter, + "expected DOCUMENT-END"); +} + +/* + * + * Expect a flow item node. + */ + +static int +yaml_emitter_emit_flow_sequence_item(yaml_emitter_t *emitter, + yaml_event_t *event, int first) +{ + if (first) + { + if (!yaml_emitter_write_indicator(emitter, "[", 1, 1, 0)) + return 0; + if (!yaml_emitter_increase_indent(emitter, 1, 0)) + return 0; + emitter->flow_level ++; + } + + if (event->type == YAML_SEQUENCE_END_EVENT) + { + emitter->flow_level --; + emitter->indent = POP(emitter, emitter->indents); + if (emitter->canonical && !first) { + if (!yaml_emitter_write_indicator(emitter, ",", 0, 0, 0)) + return 0; + if (!yaml_emitter_write_indent(emitter)) + return 0; + } + if (!yaml_emitter_write_indicator(emitter, "]", 0, 0, 0)) + return 0; + emitter->state = POP(emitter, emitter->states); + + return 1; + } + + if (!first) { + if (!yaml_emitter_write_indicator(emitter, ",", 0, 0, 0)) + return 0; + } + + if (emitter->canonical || emitter->column > emitter->best_width) { + if (!yaml_emitter_write_indent(emitter)) + return 0; + } + if (!PUSH(emitter, emitter->states, YAML_EMIT_FLOW_SEQUENCE_ITEM_STATE)) + return 0; + + return yaml_emitter_emit_node(emitter, event, 0, 1, 0, 0); +} + +/* + * Expect a flow key node. + */ + +static int +yaml_emitter_emit_flow_mapping_key(yaml_emitter_t *emitter, + yaml_event_t *event, int first) +{ + if (first) + { + if (!yaml_emitter_write_indicator(emitter, "{", 1, 1, 0)) + return 0; + if (!yaml_emitter_increase_indent(emitter, 1, 0)) + return 0; + emitter->flow_level ++; + } + + if (event->type == YAML_MAPPING_END_EVENT) + { + emitter->flow_level --; + emitter->indent = POP(emitter, emitter->indents); + if (emitter->canonical && !first) { + if (!yaml_emitter_write_indicator(emitter, ",", 0, 0, 0)) + return 0; + if (!yaml_emitter_write_indent(emitter)) + return 0; + } + if (!yaml_emitter_write_indicator(emitter, "}", 0, 0, 0)) + return 0; + emitter->state = POP(emitter, emitter->states); + + return 1; + } + + if (!first) { + if (!yaml_emitter_write_indicator(emitter, ",", 0, 0, 0)) + return 0; + } + if (emitter->canonical || emitter->column > emitter->best_width) { + if (!yaml_emitter_write_indent(emitter)) + return 0; + } + + if (!emitter->canonical && yaml_emitter_check_simple_key(emitter)) + { + if (!PUSH(emitter, emitter->states, + YAML_EMIT_FLOW_MAPPING_SIMPLE_VALUE_STATE)) + return 0; + + return yaml_emitter_emit_node(emitter, event, 0, 0, 1, 1); + } + else + { + if (!yaml_emitter_write_indicator(emitter, "?", 1, 0, 0)) + return 0; + if (!PUSH(emitter, emitter->states, + YAML_EMIT_FLOW_MAPPING_VALUE_STATE)) + return 0; + + return yaml_emitter_emit_node(emitter, event, 0, 0, 1, 0); + } +} + +/* + * Expect a flow value node. + */ + +static int +yaml_emitter_emit_flow_mapping_value(yaml_emitter_t *emitter, + yaml_event_t *event, int simple) +{ + if (simple) { + if (!yaml_emitter_write_indicator(emitter, ":", 0, 0, 0)) + return 0; + } + else { + if (emitter->canonical || emitter->column > emitter->best_width) { + if (!yaml_emitter_write_indent(emitter)) + return 0; + } + if (!yaml_emitter_write_indicator(emitter, ":", 1, 0, 0)) + return 0; + } + if (!PUSH(emitter, emitter->states, YAML_EMIT_FLOW_MAPPING_KEY_STATE)) + return 0; + return yaml_emitter_emit_node(emitter, event, 0, 0, 1, 0); +} + +/* + * Expect a block item node. + */ + +static int +yaml_emitter_emit_block_sequence_item(yaml_emitter_t *emitter, + yaml_event_t *event, int first) +{ + if (first) + { + if (!yaml_emitter_increase_indent(emitter, 0, + (emitter->mapping_context && !emitter->indention))) + return 0; + } + + if (event->type == YAML_SEQUENCE_END_EVENT) + { + emitter->indent = POP(emitter, emitter->indents); + emitter->state = POP(emitter, emitter->states); + + return 1; + } + + if (!yaml_emitter_write_indent(emitter)) + return 0; + if (!yaml_emitter_write_indicator(emitter, "-", 1, 0, 1)) + return 0; + if (!PUSH(emitter, emitter->states, + YAML_EMIT_BLOCK_SEQUENCE_ITEM_STATE)) + return 0; + + return yaml_emitter_emit_node(emitter, event, 0, 1, 0, 0); +} + +/* + * Expect a block key node. + */ + +static int +yaml_emitter_emit_block_mapping_key(yaml_emitter_t *emitter, + yaml_event_t *event, int first) +{ + if (first) + { + if (!yaml_emitter_increase_indent(emitter, 0, 0)) + return 0; + } + + if (event->type == YAML_MAPPING_END_EVENT) + { + emitter->indent = POP(emitter, emitter->indents); + emitter->state = POP(emitter, emitter->states); + + return 1; + } + + if (!yaml_emitter_write_indent(emitter)) + return 0; + + if (yaml_emitter_check_simple_key(emitter)) + { + if (!PUSH(emitter, emitter->states, + YAML_EMIT_BLOCK_MAPPING_SIMPLE_VALUE_STATE)) + return 0; + + return yaml_emitter_emit_node(emitter, event, 0, 0, 1, 1); + } + else + { + if (!yaml_emitter_write_indicator(emitter, "?", 1, 0, 1)) + return 0; + if (!PUSH(emitter, emitter->states, + YAML_EMIT_BLOCK_MAPPING_VALUE_STATE)) + return 0; + + return yaml_emitter_emit_node(emitter, event, 0, 0, 1, 0); + } +} + +/* + * Expect a block value node. + */ + +static int +yaml_emitter_emit_block_mapping_value(yaml_emitter_t *emitter, + yaml_event_t *event, int simple) +{ + if (simple) { + if (!yaml_emitter_write_indicator(emitter, ":", 0, 0, 0)) + return 0; + } + else { + if (!yaml_emitter_write_indent(emitter)) + return 0; + if (!yaml_emitter_write_indicator(emitter, ":", 1, 0, 1)) + return 0; + } + if (!PUSH(emitter, emitter->states, + YAML_EMIT_BLOCK_MAPPING_KEY_STATE)) + return 0; + + return yaml_emitter_emit_node(emitter, event, 0, 0, 1, 0); +} + +/* + * Expect a node. + */ + +static int +yaml_emitter_emit_node(yaml_emitter_t *emitter, yaml_event_t *event, + int root, int sequence, int mapping, int simple_key) +{ + emitter->root_context = root; + emitter->sequence_context = sequence; + emitter->mapping_context = mapping; + emitter->simple_key_context = simple_key; + + switch (event->type) + { + case YAML_ALIAS_EVENT: + return yaml_emitter_emit_alias(emitter, event); + + case YAML_SCALAR_EVENT: + return yaml_emitter_emit_scalar(emitter, event); + + case YAML_SEQUENCE_START_EVENT: + return yaml_emitter_emit_sequence_start(emitter, event); + + case YAML_MAPPING_START_EVENT: + return yaml_emitter_emit_mapping_start(emitter, event); + + default: + return yaml_emitter_set_emitter_error(emitter, + "expected SCALAR, SEQUENCE-START, MAPPING-START, or ALIAS"); + } + + return 0; +} + +/* + * Expect ALIAS. + */ + +static int +yaml_emitter_emit_alias(yaml_emitter_t *emitter, yaml_event_t *event) +{ + if (!yaml_emitter_process_anchor(emitter)) + return 0; + emitter->state = POP(emitter, emitter->states); + + return 1; +} + +/* + * Expect SCALAR. + */ + +static int +yaml_emitter_emit_scalar(yaml_emitter_t *emitter, yaml_event_t *event) +{ + if (!yaml_emitter_select_scalar_style(emitter, event)) + return 0; + if (!yaml_emitter_process_anchor(emitter)) + return 0; + if (!yaml_emitter_process_tag(emitter)) + return 0; + if (!yaml_emitter_increase_indent(emitter, 1, 0)) + return 0; + if (!yaml_emitter_process_scalar(emitter)) + return 0; + emitter->indent = POP(emitter, emitter->indents); + emitter->state = POP(emitter, emitter->states); + + return 1; +} + +/* + * Expect SEQUENCE-START. + */ + +static int +yaml_emitter_emit_sequence_start(yaml_emitter_t *emitter, yaml_event_t *event) +{ + if (!yaml_emitter_process_anchor(emitter)) + return 0; + if (!yaml_emitter_process_tag(emitter)) + return 0; + + if (emitter->flow_level || emitter->canonical + || event->data.sequence_start.style == YAML_FLOW_SEQUENCE_STYLE + || yaml_emitter_check_empty_sequence(emitter)) { + emitter->state = YAML_EMIT_FLOW_SEQUENCE_FIRST_ITEM_STATE; + } + else { + emitter->state = YAML_EMIT_BLOCK_SEQUENCE_FIRST_ITEM_STATE; + } + + return 1; +} + +/* + * Expect MAPPING-START. + */ + +static int +yaml_emitter_emit_mapping_start(yaml_emitter_t *emitter, yaml_event_t *event) +{ + if (!yaml_emitter_process_anchor(emitter)) + return 0; + if (!yaml_emitter_process_tag(emitter)) + return 0; + + if (emitter->flow_level || emitter->canonical + || event->data.mapping_start.style == YAML_FLOW_MAPPING_STYLE + || yaml_emitter_check_empty_mapping(emitter)) { + emitter->state = YAML_EMIT_FLOW_MAPPING_FIRST_KEY_STATE; + } + else { + emitter->state = YAML_EMIT_BLOCK_MAPPING_FIRST_KEY_STATE; + } + + return 1; +} + +/* + * Check if the document content is an empty scalar. + */ + +static int +yaml_emitter_check_empty_document(yaml_emitter_t *emitter) +{ + return 0; +} + +/* + * Check if the next events represent an empty sequence. + */ + +static int +yaml_emitter_check_empty_sequence(yaml_emitter_t *emitter) +{ + if (emitter->events.tail - emitter->events.head < 2) + return 0; + + return (emitter->events.head[0].type == YAML_SEQUENCE_START_EVENT + && emitter->events.head[1].type == YAML_SEQUENCE_END_EVENT); +} + +/* + * Check if the next events represent an empty mapping. + */ + +static int +yaml_emitter_check_empty_mapping(yaml_emitter_t *emitter) +{ + if (emitter->events.tail - emitter->events.head < 2) + return 0; + + return (emitter->events.head[0].type == YAML_MAPPING_START_EVENT + && emitter->events.head[1].type == YAML_MAPPING_END_EVENT); +} + +/* + * Check if the next node can be expressed as a simple key. + */ + +static int +yaml_emitter_check_simple_key(yaml_emitter_t *emitter) +{ + yaml_event_t *event = emitter->events.head; + size_t length = 0; + + switch (event->type) + { + case YAML_ALIAS_EVENT: + length += emitter->anchor_data.anchor_length; + break; + + case YAML_SCALAR_EVENT: + if (emitter->scalar_data.multiline) + return 0; + length += emitter->anchor_data.anchor_length + + emitter->tag_data.handle_length + + emitter->tag_data.suffix_length + + emitter->scalar_data.length; + break; + + case YAML_SEQUENCE_START_EVENT: + if (!yaml_emitter_check_empty_sequence(emitter)) + return 0; + length += emitter->anchor_data.anchor_length + + emitter->tag_data.handle_length + + emitter->tag_data.suffix_length; + break; + + case YAML_MAPPING_START_EVENT: + if (!yaml_emitter_check_empty_mapping(emitter)) + return 0; + length += emitter->anchor_data.anchor_length + + emitter->tag_data.handle_length + + emitter->tag_data.suffix_length; + break; + + default: + return 0; + } + + if (length > 128) + return 0; + + return 1; +} + +/* + * Determine an acceptable scalar style. + */ + +static int +yaml_emitter_select_scalar_style(yaml_emitter_t *emitter, yaml_event_t *event) +{ + yaml_scalar_style_t style = event->data.scalar.style; + int no_tag = (!emitter->tag_data.handle && !emitter->tag_data.suffix); + + if (no_tag && !event->data.scalar.plain_implicit + && !event->data.scalar.quoted_implicit) { + return yaml_emitter_set_emitter_error(emitter, + "neither tag nor implicit flags are specified"); + } + + if (style == YAML_ANY_SCALAR_STYLE) + style = YAML_PLAIN_SCALAR_STYLE; + + if (emitter->canonical) + style = YAML_DOUBLE_QUOTED_SCALAR_STYLE; + + if (emitter->simple_key_context && emitter->scalar_data.multiline) + style = YAML_DOUBLE_QUOTED_SCALAR_STYLE; + + if (style == YAML_PLAIN_SCALAR_STYLE) + { + if ((emitter->flow_level && !emitter->scalar_data.flow_plain_allowed) + || (!emitter->flow_level && !emitter->scalar_data.block_plain_allowed)) + style = YAML_SINGLE_QUOTED_SCALAR_STYLE; + if (!emitter->scalar_data.length + && (emitter->flow_level || emitter->simple_key_context)) + style = YAML_SINGLE_QUOTED_SCALAR_STYLE; + if (no_tag && !event->data.scalar.plain_implicit) + style = YAML_SINGLE_QUOTED_SCALAR_STYLE; + } + + if (style == YAML_SINGLE_QUOTED_SCALAR_STYLE) + { + if (!emitter->scalar_data.single_quoted_allowed) + style = YAML_DOUBLE_QUOTED_SCALAR_STYLE; + } + + if (style == YAML_LITERAL_SCALAR_STYLE || style == YAML_FOLDED_SCALAR_STYLE) + { + if (!emitter->scalar_data.block_allowed + || emitter->flow_level || emitter->simple_key_context) + style = YAML_DOUBLE_QUOTED_SCALAR_STYLE; + } + + if (no_tag && !event->data.scalar.quoted_implicit + && style != YAML_PLAIN_SCALAR_STYLE) + { + emitter->tag_data.handle = (yaml_char_t *)"!"; + emitter->tag_data.handle_length = 1; + } + + emitter->scalar_data.style = style; + + return 1; +} + +/* + * Write an achor. + */ + +static int +yaml_emitter_process_anchor(yaml_emitter_t *emitter) +{ + if (!emitter->anchor_data.anchor) + return 1; + + if (!yaml_emitter_write_indicator(emitter, + (emitter->anchor_data.alias ? "*" : "&"), 1, 0, 0)) + return 0; + + return yaml_emitter_write_anchor(emitter, + emitter->anchor_data.anchor, emitter->anchor_data.anchor_length); +} + +/* + * Write a tag. + */ + +static int +yaml_emitter_process_tag(yaml_emitter_t *emitter) +{ + if (!emitter->tag_data.handle && !emitter->tag_data.suffix) + return 1; + + if (emitter->tag_data.handle) + { + if (!yaml_emitter_write_tag_handle(emitter, emitter->tag_data.handle, + emitter->tag_data.handle_length)) + return 0; + if (emitter->tag_data.suffix) { + if (!yaml_emitter_write_tag_content(emitter, emitter->tag_data.suffix, + emitter->tag_data.suffix_length, 0)) + return 0; + } + } + else + { + if (!yaml_emitter_write_indicator(emitter, "!<", 1, 0, 0)) + return 0; + if (!yaml_emitter_write_tag_content(emitter, emitter->tag_data.suffix, + emitter->tag_data.suffix_length, 0)) + return 0; + if (!yaml_emitter_write_indicator(emitter, ">", 0, 0, 0)) + return 0; + } + + return 1; +} + +/* + * Write a scalar. + */ + +static int +yaml_emitter_process_scalar(yaml_emitter_t *emitter) +{ + switch (emitter->scalar_data.style) + { + case YAML_PLAIN_SCALAR_STYLE: + return yaml_emitter_write_plain_scalar(emitter, + emitter->scalar_data.value, emitter->scalar_data.length, + !emitter->simple_key_context); + + case YAML_SINGLE_QUOTED_SCALAR_STYLE: + return yaml_emitter_write_single_quoted_scalar(emitter, + emitter->scalar_data.value, emitter->scalar_data.length, + !emitter->simple_key_context); + + case YAML_DOUBLE_QUOTED_SCALAR_STYLE: + return yaml_emitter_write_double_quoted_scalar(emitter, + emitter->scalar_data.value, emitter->scalar_data.length, + !emitter->simple_key_context); + + case YAML_LITERAL_SCALAR_STYLE: + return yaml_emitter_write_literal_scalar(emitter, + emitter->scalar_data.value, emitter->scalar_data.length); + + case YAML_FOLDED_SCALAR_STYLE: + return yaml_emitter_write_folded_scalar(emitter, + emitter->scalar_data.value, emitter->scalar_data.length); + + default: + assert(1); /* Impossible. */ + } + + return 0; +} + +/* + * Check if a %YAML directive is valid. + */ + +static int +yaml_emitter_analyze_version_directive(yaml_emitter_t *emitter, + yaml_version_directive_t version_directive) +{ + if (version_directive.major != 1 || version_directive.minor != 1) { + return yaml_emitter_set_emitter_error(emitter, + "incompatible %YAML directive"); + } + + return 1; +} + +/* + * Check if a %TAG directive is valid. + */ + +static int +yaml_emitter_analyze_tag_directive(yaml_emitter_t *emitter, + yaml_tag_directive_t tag_directive) +{ + yaml_string_t handle; + yaml_string_t prefix; + size_t handle_length; + size_t prefix_length; + + handle_length = strlen((char *)tag_directive.handle); + prefix_length = strlen((char *)tag_directive.prefix); + STRING_ASSIGN(handle, tag_directive.handle, handle_length); + STRING_ASSIGN(prefix, tag_directive.prefix, prefix_length); + + if (handle.start == handle.end) { + return yaml_emitter_set_emitter_error(emitter, + "tag handle must not be empty"); + } + + if (handle.start[0] != '!') { + return yaml_emitter_set_emitter_error(emitter, + "tag handle must start with '!'"); + } + + if (handle.end[-1] != '!') { + return yaml_emitter_set_emitter_error(emitter, + "tag handle must end with '!'"); + } + + handle.pointer ++; + + while (handle.pointer < handle.end-1) { + if (!IS_ALPHA(handle)) { + return yaml_emitter_set_emitter_error(emitter, + "tag handle must contain alphanumerical characters only"); + } + MOVE(handle); + } + + if (prefix.start == prefix.end) { + return yaml_emitter_set_emitter_error(emitter, + "tag prefix must not be empty"); + } + + return 1; +} + +/* + * Check if an anchor is valid. + */ + +static int +yaml_emitter_analyze_anchor(yaml_emitter_t *emitter, + yaml_char_t *anchor, int alias) +{ + size_t anchor_length; + yaml_string_t string; + + anchor_length = strlen((char *)anchor); + STRING_ASSIGN(string, anchor, anchor_length); + + if (string.start == string.end) { + return yaml_emitter_set_emitter_error(emitter, alias ? + "alias value must not be empty" : + "anchor value must not be empty"); + } + + while (string.pointer != string.end) { + if (!IS_ALPHA(string)) { + return yaml_emitter_set_emitter_error(emitter, alias ? + "alias value must contain alphanumerical characters only" : + "anchor value must contain alphanumerical characters only"); + } + MOVE(string); + } + + emitter->anchor_data.anchor = string.start; + emitter->anchor_data.anchor_length = string.end - string.start; + emitter->anchor_data.alias = alias; + + return 1; +} + +/* + * Check if a tag is valid. + */ + +static int +yaml_emitter_analyze_tag(yaml_emitter_t *emitter, + yaml_char_t *tag) +{ + size_t tag_length; + yaml_string_t string; + yaml_tag_directive_t *tag_directive; + + tag_length = strlen((char *)tag); + STRING_ASSIGN(string, tag, tag_length); + + if (string.start == string.end) { + return yaml_emitter_set_emitter_error(emitter, + "tag value must not be empty"); + } + + for (tag_directive = emitter->tag_directives.start; + tag_directive != emitter->tag_directives.top; tag_directive ++) { + size_t prefix_length = strlen((char *)tag_directive->prefix); + if (prefix_length < (size_t)(string.end - string.start) + && strncmp((char *)tag_directive->prefix, (char *)string.start, + prefix_length) == 0) + { + emitter->tag_data.handle = tag_directive->handle; + emitter->tag_data.handle_length = + strlen((char *)tag_directive->handle); + emitter->tag_data.suffix = string.start + prefix_length; + emitter->tag_data.suffix_length = + (string.end - string.start) - prefix_length; + return 1; + } + } + + emitter->tag_data.suffix = string.start; + emitter->tag_data.suffix_length = string.end - string.start; + + return 1; +} + +/* + * Check if a scalar is valid. + */ + +static int +yaml_emitter_analyze_scalar(yaml_emitter_t *emitter, + yaml_char_t *value, size_t length) +{ + yaml_string_t string; + + int block_indicators = 0; + int flow_indicators = 0; + int line_breaks = 0; + int special_characters = 0; + + int leading_space = 0; + int leading_break = 0; + int trailing_space = 0; + int trailing_break = 0; + int break_space = 0; + int space_break = 0; + + int preceeded_by_whitespace = 0; + int followed_by_whitespace = 0; + int previous_space = 0; + int previous_break = 0; + + STRING_ASSIGN(string, value, length); + + emitter->scalar_data.value = value; + emitter->scalar_data.length = length; + + if (string.start == string.end) + { + emitter->scalar_data.multiline = 0; + emitter->scalar_data.flow_plain_allowed = 0; + emitter->scalar_data.block_plain_allowed = 1; + emitter->scalar_data.single_quoted_allowed = 1; + emitter->scalar_data.block_allowed = 0; + + return 1; + } + + if ((CHECK_AT(string, '-', 0) + && CHECK_AT(string, '-', 1) + && CHECK_AT(string, '-', 2)) + || (CHECK_AT(string, '.', 0) + && CHECK_AT(string, '.', 1) + && CHECK_AT(string, '.', 2))) { + block_indicators = 1; + flow_indicators = 1; + } + + preceeded_by_whitespace = 1; + followed_by_whitespace = IS_BLANKZ_AT(string, WIDTH(string)); + + while (string.pointer != string.end) + { + if (string.start == string.pointer) + { + if (CHECK(string, '#') || CHECK(string, ',') + || CHECK(string, '[') || CHECK(string, ']') + || CHECK(string, '{') || CHECK(string, '}') + || CHECK(string, '&') || CHECK(string, '*') + || CHECK(string, '!') || CHECK(string, '|') + || CHECK(string, '>') || CHECK(string, '\'') + || CHECK(string, '"') || CHECK(string, '%') + || CHECK(string, '@') || CHECK(string, '`')) { + flow_indicators = 1; + block_indicators = 1; + } + + if (CHECK(string, '?') || CHECK(string, ':')) { + flow_indicators = 1; + if (followed_by_whitespace) { + block_indicators = 1; + } + } + + if (CHECK(string, '-') && followed_by_whitespace) { + flow_indicators = 1; + block_indicators = 1; + } + } + else + { + if (CHECK(string, ',') || CHECK(string, '?') + || CHECK(string, '[') || CHECK(string, ']') + || CHECK(string, '{') || CHECK(string, '}')) { + flow_indicators = 1; + } + + if (CHECK(string, ':')) { + flow_indicators = 1; + if (followed_by_whitespace) { + block_indicators = 1; + } + } + + if (CHECK(string, '#') && preceeded_by_whitespace) { + flow_indicators = 1; + block_indicators = 1; + } + } + + if (!IS_PRINTABLE(string) + || (!IS_ASCII(string) && !emitter->unicode)) { + special_characters = 1; + } + + if (IS_BREAK(string)) { + line_breaks = 1; + } + + if (IS_SPACE(string)) + { + if (string.start == string.pointer) { + leading_space = 1; + } + if (string.pointer+WIDTH(string) == string.end) { + trailing_space = 1; + } + if (previous_break) { + break_space = 1; + } + previous_space = 1; + previous_break = 0; + } + else if (IS_BREAK(string)) + { + if (string.start == string.pointer) { + leading_break = 1; + } + if (string.pointer+WIDTH(string) == string.end) { + trailing_break = 1; + } + if (previous_space) { + space_break = 1; + } + previous_space = 0; + previous_break = 1; + } + else + { + previous_space = 0; + previous_break = 0; + } + + preceeded_by_whitespace = IS_BLANKZ(string); + MOVE(string); + if (string.pointer != string.end) { + followed_by_whitespace = IS_BLANKZ_AT(string, WIDTH(string)); + } + } + + emitter->scalar_data.multiline = line_breaks; + + emitter->scalar_data.flow_plain_allowed = 1; + emitter->scalar_data.block_plain_allowed = 1; + emitter->scalar_data.single_quoted_allowed = 1; + emitter->scalar_data.block_allowed = 1; + + if (leading_space || leading_break || trailing_space || trailing_break) { + emitter->scalar_data.flow_plain_allowed = 0; + emitter->scalar_data.block_plain_allowed = 0; + } + + if (trailing_space) { + emitter->scalar_data.block_allowed = 0; + } + + if (break_space) { + emitter->scalar_data.flow_plain_allowed = 0; + emitter->scalar_data.block_plain_allowed = 0; + emitter->scalar_data.single_quoted_allowed = 0; + } + + if (space_break || special_characters) { + emitter->scalar_data.flow_plain_allowed = 0; + emitter->scalar_data.block_plain_allowed = 0; + emitter->scalar_data.single_quoted_allowed = 0; + emitter->scalar_data.block_allowed = 0; + } + + if (line_breaks) { + emitter->scalar_data.flow_plain_allowed = 0; + emitter->scalar_data.block_plain_allowed = 0; + } + + if (flow_indicators) { + emitter->scalar_data.flow_plain_allowed = 0; + } + + if (block_indicators) { + emitter->scalar_data.block_plain_allowed = 0; + } + + return 1; +} + +/* + * Check if the event data is valid. + */ + +static int +yaml_emitter_analyze_event(yaml_emitter_t *emitter, + yaml_event_t *event) +{ + emitter->anchor_data.anchor = NULL; + emitter->anchor_data.anchor_length = 0; + emitter->tag_data.handle = NULL; + emitter->tag_data.handle_length = 0; + emitter->tag_data.suffix = NULL; + emitter->tag_data.suffix_length = 0; + emitter->scalar_data.value = NULL; + emitter->scalar_data.length = 0; + + switch (event->type) + { + case YAML_ALIAS_EVENT: + if (!yaml_emitter_analyze_anchor(emitter, + event->data.alias.anchor, 1)) + return 0; + return 1; + + case YAML_SCALAR_EVENT: + if (event->data.scalar.anchor) { + if (!yaml_emitter_analyze_anchor(emitter, + event->data.scalar.anchor, 0)) + return 0; + } + if (event->data.scalar.tag && (emitter->canonical || + (!event->data.scalar.plain_implicit + && !event->data.scalar.quoted_implicit))) { + if (!yaml_emitter_analyze_tag(emitter, event->data.scalar.tag)) + return 0; + } + if (!yaml_emitter_analyze_scalar(emitter, + event->data.scalar.value, event->data.scalar.length)) + return 0; + return 1; + + case YAML_SEQUENCE_START_EVENT: + if (event->data.sequence_start.anchor) { + if (!yaml_emitter_analyze_anchor(emitter, + event->data.sequence_start.anchor, 0)) + return 0; + } + if (event->data.sequence_start.tag && (emitter->canonical || + !event->data.sequence_start.implicit)) { + if (!yaml_emitter_analyze_tag(emitter, + event->data.sequence_start.tag)) + return 0; + } + return 1; + + case YAML_MAPPING_START_EVENT: + if (event->data.mapping_start.anchor) { + if (!yaml_emitter_analyze_anchor(emitter, + event->data.mapping_start.anchor, 0)) + return 0; + } + if (event->data.mapping_start.tag && (emitter->canonical || + !event->data.mapping_start.implicit)) { + if (!yaml_emitter_analyze_tag(emitter, + event->data.mapping_start.tag)) + return 0; + } + return 1; + + default: + return 1; + } +} + +/* + * Write the BOM character. + */ + +static int +yaml_emitter_write_bom(yaml_emitter_t *emitter) +{ + if (!FLUSH(emitter)) return 0; + + *(emitter->buffer.pointer++) = (yaml_char_t) '\xEF'; + *(emitter->buffer.pointer++) = (yaml_char_t) '\xBB'; + *(emitter->buffer.pointer++) = (yaml_char_t) '\xBF'; + + return 1; +} + +static int +yaml_emitter_write_indent(yaml_emitter_t *emitter) +{ + int indent = (emitter->indent >= 0) ? emitter->indent : 0; + + if (!emitter->indention || emitter->column > indent + || (emitter->column == indent && !emitter->whitespace)) { + if (!PUT_BREAK(emitter)) return 0; + } + + while (emitter->column < indent) { + if (!PUT(emitter, ' ')) return 0; + } + + emitter->whitespace = 1; + emitter->indention = 1; + + return 1; +} + +static int +yaml_emitter_write_indicator(yaml_emitter_t *emitter, + char *indicator, int need_whitespace, + int is_whitespace, int is_indention) +{ + size_t indicator_length; + yaml_string_t string; + + indicator_length = strlen(indicator); + STRING_ASSIGN(string, (yaml_char_t *)indicator, indicator_length); + + if (need_whitespace && !emitter->whitespace) { + if (!PUT(emitter, ' ')) return 0; + } + + while (string.pointer != string.end) { + if (!WRITE(emitter, string)) return 0; + } + + emitter->whitespace = is_whitespace; + emitter->indention = (emitter->indention && is_indention); + emitter->open_ended = 0; + + return 1; +} + +static int +yaml_emitter_write_anchor(yaml_emitter_t *emitter, + yaml_char_t *value, size_t length) +{ + yaml_string_t string; + STRING_ASSIGN(string, value, length); + + while (string.pointer != string.end) { + if (!WRITE(emitter, string)) return 0; + } + + emitter->whitespace = 0; + emitter->indention = 0; + + return 1; +} + +static int +yaml_emitter_write_tag_handle(yaml_emitter_t *emitter, + yaml_char_t *value, size_t length) +{ + yaml_string_t string; + STRING_ASSIGN(string, value, length); + + if (!emitter->whitespace) { + if (!PUT(emitter, ' ')) return 0; + } + + while (string.pointer != string.end) { + if (!WRITE(emitter, string)) return 0; + } + + emitter->whitespace = 0; + emitter->indention = 0; + + return 1; +} + +static int +yaml_emitter_write_tag_content(yaml_emitter_t *emitter, + yaml_char_t *value, size_t length, + int need_whitespace) +{ + yaml_string_t string; + STRING_ASSIGN(string, value, length); + + if (need_whitespace && !emitter->whitespace) { + if (!PUT(emitter, ' ')) return 0; + } + + while (string.pointer != string.end) { + if (IS_ALPHA(string) + || CHECK(string, ';') || CHECK(string, '/') + || CHECK(string, '?') || CHECK(string, ':') + || CHECK(string, '@') || CHECK(string, '&') + || CHECK(string, '=') || CHECK(string, '+') + || CHECK(string, '$') || CHECK(string, ',') + || CHECK(string, '_') || CHECK(string, '.') + || CHECK(string, '~') || CHECK(string, '*') + || CHECK(string, '\'') || CHECK(string, '(') + || CHECK(string, ')') || CHECK(string, '[') + || CHECK(string, ']')) { + if (!WRITE(emitter, string)) return 0; + } + else { + int width = WIDTH(string); + unsigned int value; + while (width --) { + value = *(string.pointer++); + if (!PUT(emitter, '%')) return 0; + if (!PUT(emitter, (value >> 4) + + ((value >> 4) < 10 ? '0' : 'A' - 10))) + return 0; + if (!PUT(emitter, (value & 0x0F) + + ((value & 0x0F) < 10 ? '0' : 'A' - 10))) + return 0; + } + } + } + + emitter->whitespace = 0; + emitter->indention = 0; + + return 1; +} + +static int +yaml_emitter_write_plain_scalar(yaml_emitter_t *emitter, + yaml_char_t *value, size_t length, int allow_breaks) +{ + yaml_string_t string; + int spaces = 0; + int breaks = 0; + + STRING_ASSIGN(string, value, length); + + if (!emitter->whitespace) { + if (!PUT(emitter, ' ')) return 0; + } + + while (string.pointer != string.end) + { + if (IS_SPACE(string)) + { + if (allow_breaks && !spaces + && emitter->column > emitter->best_width + && !IS_SPACE_AT(string, 1)) { + if (!yaml_emitter_write_indent(emitter)) return 0; + MOVE(string); + } + else { + if (!WRITE(emitter, string)) return 0; + } + spaces = 1; + } + else if (IS_BREAK(string)) + { + if (!breaks && CHECK(string, '\n')) { + if (!PUT_BREAK(emitter)) return 0; + } + if (!WRITE_BREAK(emitter, string)) return 0; + emitter->indention = 1; + breaks = 1; + } + else + { + if (breaks) { + if (!yaml_emitter_write_indent(emitter)) return 0; + } + if (!WRITE(emitter, string)) return 0; + emitter->indention = 0; + spaces = 0; + breaks = 0; + } + } + + emitter->whitespace = 0; + emitter->indention = 0; + if (emitter->root_context) + { + emitter->open_ended = 1; + } + + return 1; +} + +static int +yaml_emitter_write_single_quoted_scalar(yaml_emitter_t *emitter, + yaml_char_t *value, size_t length, int allow_breaks) +{ + yaml_string_t string; + int spaces = 0; + int breaks = 0; + + STRING_ASSIGN(string, value, length); + + if (!yaml_emitter_write_indicator(emitter, "'", 1, 0, 0)) + return 0; + + while (string.pointer != string.end) + { + if (IS_SPACE(string)) + { + if (allow_breaks && !spaces + && emitter->column > emitter->best_width + && string.pointer != string.start + && string.pointer != string.end - 1 + && !IS_SPACE_AT(string, 1)) { + if (!yaml_emitter_write_indent(emitter)) return 0; + MOVE(string); + } + else { + if (!WRITE(emitter, string)) return 0; + } + spaces = 1; + } + else if (IS_BREAK(string)) + { + if (!breaks && CHECK(string, '\n')) { + if (!PUT_BREAK(emitter)) return 0; + } + if (!WRITE_BREAK(emitter, string)) return 0; + emitter->indention = 1; + breaks = 1; + } + else + { + if (breaks) { + if (!yaml_emitter_write_indent(emitter)) return 0; + } + if (CHECK(string, '\'')) { + if (!PUT(emitter, '\'')) return 0; + } + if (!WRITE(emitter, string)) return 0; + emitter->indention = 0; + spaces = 0; + breaks = 0; + } + } + + if (!yaml_emitter_write_indicator(emitter, "'", 0, 0, 0)) + return 0; + + emitter->whitespace = 0; + emitter->indention = 0; + + return 1; +} + +static int +yaml_emitter_write_double_quoted_scalar(yaml_emitter_t *emitter, + yaml_char_t *value, size_t length, int allow_breaks) +{ + yaml_string_t string; + int spaces = 0; + + STRING_ASSIGN(string, value, length); + + if (!yaml_emitter_write_indicator(emitter, "\"", 1, 0, 0)) + return 0; + + while (string.pointer != string.end) + { + if (!IS_PRINTABLE(string) || (!emitter->unicode && !IS_ASCII(string)) + || IS_BOM(string) || IS_BREAK(string) + || CHECK(string, '"') || CHECK(string, '\\')) + { + unsigned char octet; + unsigned int width; + unsigned int value; + int k; + + octet = string.pointer[0]; + width = (octet & 0x80) == 0x00 ? 1 : + (octet & 0xE0) == 0xC0 ? 2 : + (octet & 0xF0) == 0xE0 ? 3 : + (octet & 0xF8) == 0xF0 ? 4 : 0; + value = (octet & 0x80) == 0x00 ? octet & 0x7F : + (octet & 0xE0) == 0xC0 ? octet & 0x1F : + (octet & 0xF0) == 0xE0 ? octet & 0x0F : + (octet & 0xF8) == 0xF0 ? octet & 0x07 : 0; + for (k = 1; k < (int)width; k ++) { + octet = string.pointer[k]; + value = (value << 6) + (octet & 0x3F); + } + string.pointer += width; + + if (!PUT(emitter, '\\')) return 0; + + switch (value) + { + case 0x00: + if (!PUT(emitter, '0')) return 0; + break; + + case 0x07: + if (!PUT(emitter, 'a')) return 0; + break; + + case 0x08: + if (!PUT(emitter, 'b')) return 0; + break; + + case 0x09: + if (!PUT(emitter, 't')) return 0; + break; + + case 0x0A: + if (!PUT(emitter, 'n')) return 0; + break; + + case 0x0B: + if (!PUT(emitter, 'v')) return 0; + break; + + case 0x0C: + if (!PUT(emitter, 'f')) return 0; + break; + + case 0x0D: + if (!PUT(emitter, 'r')) return 0; + break; + + case 0x1B: + if (!PUT(emitter, 'e')) return 0; + break; + + case 0x22: + if (!PUT(emitter, '\"')) return 0; + break; + + case 0x5C: + if (!PUT(emitter, '\\')) return 0; + break; + + case 0x85: + if (!PUT(emitter, 'N')) return 0; + break; + + case 0xA0: + if (!PUT(emitter, '_')) return 0; + break; + + case 0x2028: + if (!PUT(emitter, 'L')) return 0; + break; + + case 0x2029: + if (!PUT(emitter, 'P')) return 0; + break; + + default: + if (value <= 0xFF) { + if (!PUT(emitter, 'x')) return 0; + width = 2; + } + else if (value <= 0xFFFF) { + if (!PUT(emitter, 'u')) return 0; + width = 4; + } + else { + if (!PUT(emitter, 'U')) return 0; + width = 8; + } + for (k = (width-1)*4; k >= 0; k -= 4) { + int digit = (value >> k) & 0x0F; + if (!PUT(emitter, digit + (digit < 10 ? '0' : 'A'-10))) + return 0; + } + } + spaces = 0; + } + else if (IS_SPACE(string)) + { + if (allow_breaks && !spaces + && emitter->column > emitter->best_width + && string.pointer != string.start + && string.pointer != string.end - 1) { + if (!yaml_emitter_write_indent(emitter)) return 0; + if (IS_SPACE_AT(string, 1)) { + if (!PUT(emitter, '\\')) return 0; + } + MOVE(string); + } + else { + if (!WRITE(emitter, string)) return 0; + } + spaces = 1; + } + else + { + if (!WRITE(emitter, string)) return 0; + spaces = 0; + } + } + + if (!yaml_emitter_write_indicator(emitter, "\"", 0, 0, 0)) + return 0; + + emitter->whitespace = 0; + emitter->indention = 0; + + return 1; +} + +static int +yaml_emitter_write_block_scalar_hints(yaml_emitter_t *emitter, + yaml_string_t string) +{ + char indent_hint[2]; + char *chomp_hint = NULL; + + if (IS_SPACE(string) || IS_BREAK(string)) + { + indent_hint[0] = '0' + (char)emitter->best_indent; + indent_hint[1] = '\0'; + if (!yaml_emitter_write_indicator(emitter, indent_hint, 0, 0, 0)) + return 0; + } + + emitter->open_ended = 0; + + string.pointer = string.end; + if (string.start == string.pointer) + { + chomp_hint = "-"; + } + else + { + do { + string.pointer --; + } while ((*string.pointer & 0xC0) == 0x80); + if (!IS_BREAK(string)) + { + chomp_hint = "-"; + } + else if (string.start == string.pointer) + { + chomp_hint = "+"; + emitter->open_ended = 1; + } + else + { + do { + string.pointer --; + } while ((*string.pointer & 0xC0) == 0x80); + if (IS_BREAK(string)) + { + chomp_hint = "+"; + emitter->open_ended = 1; + } + } + } + + if (chomp_hint) + { + if (!yaml_emitter_write_indicator(emitter, chomp_hint, 0, 0, 0)) + return 0; + } + + return 1; +} + +static int +yaml_emitter_write_literal_scalar(yaml_emitter_t *emitter, + yaml_char_t *value, size_t length) +{ + yaml_string_t string; + int breaks = 1; + + STRING_ASSIGN(string, value, length); + + if (!yaml_emitter_write_indicator(emitter, "|", 1, 0, 0)) + return 0; + if (!yaml_emitter_write_block_scalar_hints(emitter, string)) + return 0; + if (!PUT_BREAK(emitter)) return 0; + emitter->indention = 1; + emitter->whitespace = 1; + + while (string.pointer != string.end) + { + if (IS_BREAK(string)) + { + if (!WRITE_BREAK(emitter, string)) return 0; + emitter->indention = 1; + breaks = 1; + } + else + { + if (breaks) { + if (!yaml_emitter_write_indent(emitter)) return 0; + } + if (!WRITE(emitter, string)) return 0; + emitter->indention = 0; + breaks = 0; + } + } + + return 1; +} + +static int +yaml_emitter_write_folded_scalar(yaml_emitter_t *emitter, + yaml_char_t *value, size_t length) +{ + yaml_string_t string; + int breaks = 1; + int leading_spaces = 1; + + STRING_ASSIGN(string, value, length); + + if (!yaml_emitter_write_indicator(emitter, ">", 1, 0, 0)) + return 0; + if (!yaml_emitter_write_block_scalar_hints(emitter, string)) + return 0; + if (!PUT_BREAK(emitter)) return 0; + emitter->indention = 1; + emitter->whitespace = 1; + + while (string.pointer != string.end) + { + if (IS_BREAK(string)) + { + if (!breaks && !leading_spaces && CHECK(string, '\n')) { + int k = 0; + while (IS_BREAK_AT(string, k)) { + k += WIDTH_AT(string, k); + } + if (!IS_BLANKZ_AT(string, k)) { + if (!PUT_BREAK(emitter)) return 0; + } + } + if (!WRITE_BREAK(emitter, string)) return 0; + emitter->indention = 1; + breaks = 1; + } + else + { + if (breaks) { + if (!yaml_emitter_write_indent(emitter)) return 0; + leading_spaces = IS_BLANK(string); + } + if (!breaks && IS_SPACE(string) && !IS_SPACE_AT(string, 1) + && emitter->column > emitter->best_width) { + if (!yaml_emitter_write_indent(emitter)) return 0; + MOVE(string); + } + else { + if (!WRITE(emitter, string)) return 0; + } + emitter->indention = 0; + breaks = 0; + } + } + + return 1; +} + diff --git a/libyaml/src/loader.c b/libyaml/src/loader.c new file mode 100644 index 00000000..871149ab --- /dev/null +++ b/libyaml/src/loader.c @@ -0,0 +1,444 @@ + +#include "yaml_private.h" + +/* + * API functions. + */ + +YAML_DECLARE(int) +yaml_parser_load(yaml_parser_t *parser, yaml_document_t *document); + +/* + * Error handling. + */ + +static int +yaml_parser_set_composer_error(yaml_parser_t *parser, + const char *problem, yaml_mark_t problem_mark); + +static int +yaml_parser_set_composer_error_context(yaml_parser_t *parser, + const char *context, yaml_mark_t context_mark, + const char *problem, yaml_mark_t problem_mark); + + +/* + * Alias handling. + */ + +static int +yaml_parser_register_anchor(yaml_parser_t *parser, + int index, yaml_char_t *anchor); + +/* + * Clean up functions. + */ + +static void +yaml_parser_delete_aliases(yaml_parser_t *parser); + +/* + * Composer functions. + */ + +static int +yaml_parser_load_document(yaml_parser_t *parser, yaml_event_t *first_event); + +static int +yaml_parser_load_node(yaml_parser_t *parser, yaml_event_t *first_event); + +static int +yaml_parser_load_alias(yaml_parser_t *parser, yaml_event_t *first_event); + +static int +yaml_parser_load_scalar(yaml_parser_t *parser, yaml_event_t *first_event); + +static int +yaml_parser_load_sequence(yaml_parser_t *parser, yaml_event_t *first_event); + +static int +yaml_parser_load_mapping(yaml_parser_t *parser, yaml_event_t *first_event); + +/* + * Load the next document of the stream. + */ + +YAML_DECLARE(int) +yaml_parser_load(yaml_parser_t *parser, yaml_document_t *document) +{ + yaml_event_t event; + + assert(parser); /* Non-NULL parser object is expected. */ + assert(document); /* Non-NULL document object is expected. */ + + memset(document, 0, sizeof(yaml_document_t)); + if (!STACK_INIT(parser, document->nodes, INITIAL_STACK_SIZE)) + goto error; + + if (!parser->stream_start_produced) { + if (!yaml_parser_parse(parser, &event)) goto error; + assert(event.type == YAML_STREAM_START_EVENT); + /* STREAM-START is expected. */ + } + + if (parser->stream_end_produced) { + return 1; + } + + if (!yaml_parser_parse(parser, &event)) goto error; + if (event.type == YAML_STREAM_END_EVENT) { + return 1; + } + + if (!STACK_INIT(parser, parser->aliases, INITIAL_STACK_SIZE)) + goto error; + + parser->document = document; + + if (!yaml_parser_load_document(parser, &event)) goto error; + + yaml_parser_delete_aliases(parser); + parser->document = NULL; + + return 1; + +error: + + yaml_parser_delete_aliases(parser); + yaml_document_delete(document); + parser->document = NULL; + + return 0; +} + +/* + * Set composer error. + */ + +static int +yaml_parser_set_composer_error(yaml_parser_t *parser, + const char *problem, yaml_mark_t problem_mark) +{ + parser->error = YAML_COMPOSER_ERROR; + parser->problem = problem; + parser->problem_mark = problem_mark; + + return 0; +} + +/* + * Set composer error with context. + */ + +static int +yaml_parser_set_composer_error_context(yaml_parser_t *parser, + const char *context, yaml_mark_t context_mark, + const char *problem, yaml_mark_t problem_mark) +{ + parser->error = YAML_COMPOSER_ERROR; + parser->context = context; + parser->context_mark = context_mark; + parser->problem = problem; + parser->problem_mark = problem_mark; + + return 0; +} + +/* + * Delete the stack of aliases. + */ + +static void +yaml_parser_delete_aliases(yaml_parser_t *parser) +{ + while (!STACK_EMPTY(parser, parser->aliases)) { + yaml_free(POP(parser, parser->aliases).anchor); + } + STACK_DEL(parser, parser->aliases); +} + +/* + * Compose a document object. + */ + +static int +yaml_parser_load_document(yaml_parser_t *parser, yaml_event_t *first_event) +{ + yaml_event_t event; + + assert(first_event->type == YAML_DOCUMENT_START_EVENT); + /* DOCUMENT-START is expected. */ + + parser->document->version_directive + = first_event->data.document_start.version_directive; + parser->document->tag_directives.start + = first_event->data.document_start.tag_directives.start; + parser->document->tag_directives.end + = first_event->data.document_start.tag_directives.end; + parser->document->start_implicit + = first_event->data.document_start.implicit; + parser->document->start_mark = first_event->start_mark; + + if (!yaml_parser_parse(parser, &event)) return 0; + + if (!yaml_parser_load_node(parser, &event)) return 0; + + if (!yaml_parser_parse(parser, &event)) return 0; + assert(event.type == YAML_DOCUMENT_END_EVENT); + /* DOCUMENT-END is expected. */ + + parser->document->end_implicit = event.data.document_end.implicit; + parser->document->end_mark = event.end_mark; + + return 1; +} + +/* + * Compose a node. + */ + +static int +yaml_parser_load_node(yaml_parser_t *parser, yaml_event_t *first_event) +{ + switch (first_event->type) { + case YAML_ALIAS_EVENT: + return yaml_parser_load_alias(parser, first_event); + case YAML_SCALAR_EVENT: + return yaml_parser_load_scalar(parser, first_event); + case YAML_SEQUENCE_START_EVENT: + return yaml_parser_load_sequence(parser, first_event); + case YAML_MAPPING_START_EVENT: + return yaml_parser_load_mapping(parser, first_event); + default: + assert(0); /* Could not happen. */ + return 0; + } + + return 0; +} + +/* + * Add an anchor. + */ + +static int +yaml_parser_register_anchor(yaml_parser_t *parser, + int index, yaml_char_t *anchor) +{ + yaml_alias_data_t data; + yaml_alias_data_t *alias_data; + + if (!anchor) return 1; + + data.anchor = anchor; + data.index = index; + data.mark = parser->document->nodes.start[index-1].start_mark; + + for (alias_data = parser->aliases.start; + alias_data != parser->aliases.top; alias_data ++) { + if (strcmp((char *)alias_data->anchor, (char *)anchor) == 0) { + yaml_free(anchor); + return yaml_parser_set_composer_error_context(parser, + "found duplicate anchor; first occurence", + alias_data->mark, "second occurence", data.mark); + } + } + + if (!PUSH(parser, parser->aliases, data)) { + yaml_free(anchor); + return 0; + } + + return 1; +} + +/* + * Compose a node corresponding to an alias. + */ + +static int +yaml_parser_load_alias(yaml_parser_t *parser, yaml_event_t *first_event) +{ + yaml_char_t *anchor = first_event->data.alias.anchor; + yaml_alias_data_t *alias_data; + + for (alias_data = parser->aliases.start; + alias_data != parser->aliases.top; alias_data ++) { + if (strcmp((char *)alias_data->anchor, (char *)anchor) == 0) { + yaml_free(anchor); + return alias_data->index; + } + } + + yaml_free(anchor); + return yaml_parser_set_composer_error(parser, "found undefined alias", + first_event->start_mark); +} + +/* + * Compose a scalar node. + */ + +static int +yaml_parser_load_scalar(yaml_parser_t *parser, yaml_event_t *first_event) +{ + yaml_node_t node; + int index; + yaml_char_t *tag = first_event->data.scalar.tag; + + if (!STACK_LIMIT(parser, parser->document->nodes, INT_MAX-1)) goto error; + + if (!tag || strcmp((char *)tag, "!") == 0) { + yaml_free(tag); + tag = yaml_strdup((yaml_char_t *)YAML_DEFAULT_SCALAR_TAG); + if (!tag) goto error; + } + + SCALAR_NODE_INIT(node, tag, first_event->data.scalar.value, + first_event->data.scalar.length, first_event->data.scalar.style, + first_event->start_mark, first_event->end_mark); + + if (!PUSH(parser, parser->document->nodes, node)) goto error; + + index = parser->document->nodes.top - parser->document->nodes.start; + + if (!yaml_parser_register_anchor(parser, index, + first_event->data.scalar.anchor)) return 0; + + return index; + +error: + yaml_free(tag); + yaml_free(first_event->data.scalar.anchor); + yaml_free(first_event->data.scalar.value); + return 0; +} + +/* + * Compose a sequence node. + */ + +static int +yaml_parser_load_sequence(yaml_parser_t *parser, yaml_event_t *first_event) +{ + yaml_event_t event; + yaml_node_t node; + struct { + yaml_node_item_t *start; + yaml_node_item_t *end; + yaml_node_item_t *top; + } items = { NULL, NULL, NULL }; + int index, item_index; + yaml_char_t *tag = first_event->data.sequence_start.tag; + + if (!STACK_LIMIT(parser, parser->document->nodes, INT_MAX-1)) goto error; + + if (!tag || strcmp((char *)tag, "!") == 0) { + yaml_free(tag); + tag = yaml_strdup((yaml_char_t *)YAML_DEFAULT_SEQUENCE_TAG); + if (!tag) goto error; + } + + if (!STACK_INIT(parser, items, INITIAL_STACK_SIZE)) goto error; + + SEQUENCE_NODE_INIT(node, tag, items.start, items.end, + first_event->data.sequence_start.style, + first_event->start_mark, first_event->end_mark); + + if (!PUSH(parser, parser->document->nodes, node)) goto error; + + index = parser->document->nodes.top - parser->document->nodes.start; + + if (!yaml_parser_register_anchor(parser, index, + first_event->data.sequence_start.anchor)) return 0; + + if (!yaml_parser_parse(parser, &event)) return 0; + + while (event.type != YAML_SEQUENCE_END_EVENT) { + if (!STACK_LIMIT(parser, + parser->document->nodes.start[index-1].data.sequence.items, + INT_MAX-1)) return 0; + item_index = yaml_parser_load_node(parser, &event); + if (!item_index) return 0; + if (!PUSH(parser, + parser->document->nodes.start[index-1].data.sequence.items, + item_index)) return 0; + if (!yaml_parser_parse(parser, &event)) return 0; + } + + parser->document->nodes.start[index-1].end_mark = event.end_mark; + + return index; + +error: + yaml_free(tag); + yaml_free(first_event->data.sequence_start.anchor); + return 0; +} + +/* + * Compose a mapping node. + */ + +static int +yaml_parser_load_mapping(yaml_parser_t *parser, yaml_event_t *first_event) +{ + yaml_event_t event; + yaml_node_t node; + struct { + yaml_node_pair_t *start; + yaml_node_pair_t *end; + yaml_node_pair_t *top; + } pairs = { NULL, NULL, NULL }; + int index; + yaml_node_pair_t pair; + yaml_char_t *tag = first_event->data.mapping_start.tag; + + if (!STACK_LIMIT(parser, parser->document->nodes, INT_MAX-1)) goto error; + + if (!tag || strcmp((char *)tag, "!") == 0) { + yaml_free(tag); + tag = yaml_strdup((yaml_char_t *)YAML_DEFAULT_MAPPING_TAG); + if (!tag) goto error; + } + + if (!STACK_INIT(parser, pairs, INITIAL_STACK_SIZE)) goto error; + + MAPPING_NODE_INIT(node, tag, pairs.start, pairs.end, + first_event->data.mapping_start.style, + first_event->start_mark, first_event->end_mark); + + if (!PUSH(parser, parser->document->nodes, node)) goto error; + + index = parser->document->nodes.top - parser->document->nodes.start; + + if (!yaml_parser_register_anchor(parser, index, + first_event->data.mapping_start.anchor)) return 0; + + if (!yaml_parser_parse(parser, &event)) return 0; + + while (event.type != YAML_MAPPING_END_EVENT) { + if (!STACK_LIMIT(parser, + parser->document->nodes.start[index-1].data.mapping.pairs, + INT_MAX-1)) return 0; + pair.key = yaml_parser_load_node(parser, &event); + if (!pair.key) return 0; + if (!yaml_parser_parse(parser, &event)) return 0; + pair.value = yaml_parser_load_node(parser, &event); + if (!pair.value) return 0; + if (!PUSH(parser, + parser->document->nodes.start[index-1].data.mapping.pairs, + pair)) return 0; + if (!yaml_parser_parse(parser, &event)) return 0; + } + + parser->document->nodes.start[index-1].end_mark = event.end_mark; + + return index; + +error: + yaml_free(tag); + yaml_free(first_event->data.mapping_start.anchor); + return 0; +} + diff --git a/libyaml/src/parser.c b/libyaml/src/parser.c new file mode 100644 index 00000000..eb2a2c79 --- /dev/null +++ b/libyaml/src/parser.c @@ -0,0 +1,1374 @@ + +/* + * The parser implements the following grammar: + * + * stream ::= STREAM-START implicit_document? explicit_document* STREAM-END + * implicit_document ::= block_node DOCUMENT-END* + * explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END* + * block_node_or_indentless_sequence ::= + * ALIAS + * | properties (block_content | indentless_block_sequence)? + * | block_content + * | indentless_block_sequence + * block_node ::= ALIAS + * | properties block_content? + * | block_content + * flow_node ::= ALIAS + * | properties flow_content? + * | flow_content + * properties ::= TAG ANCHOR? | ANCHOR TAG? + * block_content ::= block_collection | flow_collection | SCALAR + * flow_content ::= flow_collection | SCALAR + * block_collection ::= block_sequence | block_mapping + * flow_collection ::= flow_sequence | flow_mapping + * block_sequence ::= BLOCK-SEQUENCE-START (BLOCK-ENTRY block_node?)* BLOCK-END + * indentless_sequence ::= (BLOCK-ENTRY block_node?)+ + * block_mapping ::= BLOCK-MAPPING_START + * ((KEY block_node_or_indentless_sequence?)? + * (VALUE block_node_or_indentless_sequence?)?)* + * BLOCK-END + * flow_sequence ::= FLOW-SEQUENCE-START + * (flow_sequence_entry FLOW-ENTRY)* + * flow_sequence_entry? + * FLOW-SEQUENCE-END + * flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? + * flow_mapping ::= FLOW-MAPPING-START + * (flow_mapping_entry FLOW-ENTRY)* + * flow_mapping_entry? + * FLOW-MAPPING-END + * flow_mapping_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? + */ + +#include "yaml_private.h" + +/* + * Peek the next token in the token queue. + */ + +#define PEEK_TOKEN(parser) \ + ((parser->token_available || yaml_parser_fetch_more_tokens(parser)) ? \ + parser->tokens.head : NULL) + +/* + * Remove the next token from the queue (must be called after PEEK_TOKEN). + */ + +#define SKIP_TOKEN(parser) \ + (parser->token_available = 0, \ + parser->tokens_parsed ++, \ + parser->stream_end_produced = \ + (parser->tokens.head->type == YAML_STREAM_END_TOKEN), \ + parser->tokens.head ++) + +/* + * Public API declarations. + */ + +YAML_DECLARE(int) +yaml_parser_parse(yaml_parser_t *parser, yaml_event_t *event); + +/* + * Error handling. + */ + +static int +yaml_parser_set_parser_error(yaml_parser_t *parser, + const char *problem, yaml_mark_t problem_mark); + +static int +yaml_parser_set_parser_error_context(yaml_parser_t *parser, + const char *context, yaml_mark_t context_mark, + const char *problem, yaml_mark_t problem_mark); + +/* + * State functions. + */ + +static int +yaml_parser_state_machine(yaml_parser_t *parser, yaml_event_t *event); + +static int +yaml_parser_parse_stream_start(yaml_parser_t *parser, yaml_event_t *event); + +static int +yaml_parser_parse_document_start(yaml_parser_t *parser, yaml_event_t *event, + int implicit); + +static int +yaml_parser_parse_document_content(yaml_parser_t *parser, yaml_event_t *event); + +static int +yaml_parser_parse_document_end(yaml_parser_t *parser, yaml_event_t *event); + +static int +yaml_parser_parse_node(yaml_parser_t *parser, yaml_event_t *event, + int block, int indentless_sequence); + +static int +yaml_parser_parse_block_sequence_entry(yaml_parser_t *parser, + yaml_event_t *event, int first); + +static int +yaml_parser_parse_indentless_sequence_entry(yaml_parser_t *parser, + yaml_event_t *event); + +static int +yaml_parser_parse_block_mapping_key(yaml_parser_t *parser, + yaml_event_t *event, int first); + +static int +yaml_parser_parse_block_mapping_value(yaml_parser_t *parser, + yaml_event_t *event); + +static int +yaml_parser_parse_flow_sequence_entry(yaml_parser_t *parser, + yaml_event_t *event, int first); + +static int +yaml_parser_parse_flow_sequence_entry_mapping_key(yaml_parser_t *parser, + yaml_event_t *event); + +static int +yaml_parser_parse_flow_sequence_entry_mapping_value(yaml_parser_t *parser, + yaml_event_t *event); + +static int +yaml_parser_parse_flow_sequence_entry_mapping_end(yaml_parser_t *parser, + yaml_event_t *event); + +static int +yaml_parser_parse_flow_mapping_key(yaml_parser_t *parser, + yaml_event_t *event, int first); + +static int +yaml_parser_parse_flow_mapping_value(yaml_parser_t *parser, + yaml_event_t *event, int empty); + +/* + * Utility functions. + */ + +static int +yaml_parser_process_empty_scalar(yaml_parser_t *parser, + yaml_event_t *event, yaml_mark_t mark); + +static int +yaml_parser_process_directives(yaml_parser_t *parser, + yaml_version_directive_t **version_directive_ref, + yaml_tag_directive_t **tag_directives_start_ref, + yaml_tag_directive_t **tag_directives_end_ref); + +static int +yaml_parser_append_tag_directive(yaml_parser_t *parser, + yaml_tag_directive_t value, int allow_duplicates, yaml_mark_t mark); + +/* + * Get the next event. + */ + +YAML_DECLARE(int) +yaml_parser_parse(yaml_parser_t *parser, yaml_event_t *event) +{ + assert(parser); /* Non-NULL parser object is expected. */ + assert(event); /* Non-NULL event object is expected. */ + + /* Erase the event object. */ + + memset(event, 0, sizeof(yaml_event_t)); + + /* No events after the end of the stream or error. */ + + if (parser->stream_end_produced || parser->error || + parser->state == YAML_PARSE_END_STATE) { + return 1; + } + + /* Generate the next event. */ + + return yaml_parser_state_machine(parser, event); +} + +/* + * Set parser error. + */ + +static int +yaml_parser_set_parser_error(yaml_parser_t *parser, + const char *problem, yaml_mark_t problem_mark) +{ + parser->error = YAML_PARSER_ERROR; + parser->problem = problem; + parser->problem_mark = problem_mark; + + return 0; +} + +static int +yaml_parser_set_parser_error_context(yaml_parser_t *parser, + const char *context, yaml_mark_t context_mark, + const char *problem, yaml_mark_t problem_mark) +{ + parser->error = YAML_PARSER_ERROR; + parser->context = context; + parser->context_mark = context_mark; + parser->problem = problem; + parser->problem_mark = problem_mark; + + return 0; +} + + +/* + * State dispatcher. + */ + +static int +yaml_parser_state_machine(yaml_parser_t *parser, yaml_event_t *event) +{ + switch (parser->state) + { + case YAML_PARSE_STREAM_START_STATE: + return yaml_parser_parse_stream_start(parser, event); + + case YAML_PARSE_IMPLICIT_DOCUMENT_START_STATE: + return yaml_parser_parse_document_start(parser, event, 1); + + case YAML_PARSE_DOCUMENT_START_STATE: + return yaml_parser_parse_document_start(parser, event, 0); + + case YAML_PARSE_DOCUMENT_CONTENT_STATE: + return yaml_parser_parse_document_content(parser, event); + + case YAML_PARSE_DOCUMENT_END_STATE: + return yaml_parser_parse_document_end(parser, event); + + case YAML_PARSE_BLOCK_NODE_STATE: + return yaml_parser_parse_node(parser, event, 1, 0); + + case YAML_PARSE_BLOCK_NODE_OR_INDENTLESS_SEQUENCE_STATE: + return yaml_parser_parse_node(parser, event, 1, 1); + + case YAML_PARSE_FLOW_NODE_STATE: + return yaml_parser_parse_node(parser, event, 0, 0); + + case YAML_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE: + return yaml_parser_parse_block_sequence_entry(parser, event, 1); + + case YAML_PARSE_BLOCK_SEQUENCE_ENTRY_STATE: + return yaml_parser_parse_block_sequence_entry(parser, event, 0); + + case YAML_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE: + return yaml_parser_parse_indentless_sequence_entry(parser, event); + + case YAML_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE: + return yaml_parser_parse_block_mapping_key(parser, event, 1); + + case YAML_PARSE_BLOCK_MAPPING_KEY_STATE: + return yaml_parser_parse_block_mapping_key(parser, event, 0); + + case YAML_PARSE_BLOCK_MAPPING_VALUE_STATE: + return yaml_parser_parse_block_mapping_value(parser, event); + + case YAML_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE: + return yaml_parser_parse_flow_sequence_entry(parser, event, 1); + + case YAML_PARSE_FLOW_SEQUENCE_ENTRY_STATE: + return yaml_parser_parse_flow_sequence_entry(parser, event, 0); + + case YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE: + return yaml_parser_parse_flow_sequence_entry_mapping_key(parser, event); + + case YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE: + return yaml_parser_parse_flow_sequence_entry_mapping_value(parser, event); + + case YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE: + return yaml_parser_parse_flow_sequence_entry_mapping_end(parser, event); + + case YAML_PARSE_FLOW_MAPPING_FIRST_KEY_STATE: + return yaml_parser_parse_flow_mapping_key(parser, event, 1); + + case YAML_PARSE_FLOW_MAPPING_KEY_STATE: + return yaml_parser_parse_flow_mapping_key(parser, event, 0); + + case YAML_PARSE_FLOW_MAPPING_VALUE_STATE: + return yaml_parser_parse_flow_mapping_value(parser, event, 0); + + case YAML_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE: + return yaml_parser_parse_flow_mapping_value(parser, event, 1); + + default: + assert(1); /* Invalid state. */ + } + + return 0; +} + +/* + * Parse the production: + * stream ::= STREAM-START implicit_document? explicit_document* STREAM-END + * ************ + */ + +static int +yaml_parser_parse_stream_start(yaml_parser_t *parser, yaml_event_t *event) +{ + yaml_token_t *token; + + token = PEEK_TOKEN(parser); + if (!token) return 0; + + if (token->type != YAML_STREAM_START_TOKEN) { + return yaml_parser_set_parser_error(parser, + "did not find expected ", token->start_mark); + } + + parser->state = YAML_PARSE_IMPLICIT_DOCUMENT_START_STATE; + STREAM_START_EVENT_INIT(*event, token->data.stream_start.encoding, + token->start_mark, token->start_mark); + SKIP_TOKEN(parser); + + return 1; +} + +/* + * Parse the productions: + * implicit_document ::= block_node DOCUMENT-END* + * * + * explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END* + * ************************* + */ + +static int +yaml_parser_parse_document_start(yaml_parser_t *parser, yaml_event_t *event, + int implicit) +{ + yaml_token_t *token; + yaml_version_directive_t *version_directive = NULL; + struct { + yaml_tag_directive_t *start; + yaml_tag_directive_t *end; + } tag_directives = { NULL, NULL }; + + token = PEEK_TOKEN(parser); + if (!token) return 0; + + /* Parse extra document end indicators. */ + + if (!implicit) + { + while (token->type == YAML_DOCUMENT_END_TOKEN) { + SKIP_TOKEN(parser); + token = PEEK_TOKEN(parser); + if (!token) return 0; + } + } + + /* Parse an implicit document. */ + + if (implicit && token->type != YAML_VERSION_DIRECTIVE_TOKEN && + token->type != YAML_TAG_DIRECTIVE_TOKEN && + token->type != YAML_DOCUMENT_START_TOKEN && + token->type != YAML_STREAM_END_TOKEN) + { + if (!yaml_parser_process_directives(parser, NULL, NULL, NULL)) + return 0; + if (!PUSH(parser, parser->states, YAML_PARSE_DOCUMENT_END_STATE)) + return 0; + parser->state = YAML_PARSE_BLOCK_NODE_STATE; + DOCUMENT_START_EVENT_INIT(*event, NULL, NULL, NULL, 1, + token->start_mark, token->start_mark); + return 1; + } + + /* Parse an explicit document. */ + + else if (token->type != YAML_STREAM_END_TOKEN) + { + yaml_mark_t start_mark, end_mark; + start_mark = token->start_mark; + if (!yaml_parser_process_directives(parser, &version_directive, + &tag_directives.start, &tag_directives.end)) + return 0; + token = PEEK_TOKEN(parser); + if (!token) goto error; + if (token->type != YAML_DOCUMENT_START_TOKEN) { + yaml_parser_set_parser_error(parser, + "did not find expected ", token->start_mark); + goto error; + } + if (!PUSH(parser, parser->states, YAML_PARSE_DOCUMENT_END_STATE)) + goto error; + parser->state = YAML_PARSE_DOCUMENT_CONTENT_STATE; + end_mark = token->end_mark; + DOCUMENT_START_EVENT_INIT(*event, version_directive, + tag_directives.start, tag_directives.end, 0, + start_mark, end_mark); + SKIP_TOKEN(parser); + version_directive = NULL; + tag_directives.start = tag_directives.end = NULL; + return 1; + } + + /* Parse the stream end. */ + + else + { + parser->state = YAML_PARSE_END_STATE; + STREAM_END_EVENT_INIT(*event, token->start_mark, token->end_mark); + SKIP_TOKEN(parser); + return 1; + } + +error: + yaml_free(version_directive); + while (tag_directives.start != tag_directives.end) { + yaml_free(tag_directives.end[-1].handle); + yaml_free(tag_directives.end[-1].prefix); + tag_directives.end --; + } + yaml_free(tag_directives.start); + return 0; +} + +/* + * Parse the productions: + * explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END* + * *********** + */ + +static int +yaml_parser_parse_document_content(yaml_parser_t *parser, yaml_event_t *event) +{ + yaml_token_t *token; + + token = PEEK_TOKEN(parser); + if (!token) return 0; + + if (token->type == YAML_VERSION_DIRECTIVE_TOKEN || + token->type == YAML_TAG_DIRECTIVE_TOKEN || + token->type == YAML_DOCUMENT_START_TOKEN || + token->type == YAML_DOCUMENT_END_TOKEN || + token->type == YAML_STREAM_END_TOKEN) { + parser->state = POP(parser, parser->states); + return yaml_parser_process_empty_scalar(parser, event, + token->start_mark); + } + else { + return yaml_parser_parse_node(parser, event, 1, 0); + } +} + +/* + * Parse the productions: + * implicit_document ::= block_node DOCUMENT-END* + * ************* + * explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END* + * ************* + */ + +static int +yaml_parser_parse_document_end(yaml_parser_t *parser, yaml_event_t *event) +{ + yaml_token_t *token; + yaml_mark_t start_mark, end_mark; + int implicit = 1; + + token = PEEK_TOKEN(parser); + if (!token) return 0; + + start_mark = end_mark = token->start_mark; + + if (token->type == YAML_DOCUMENT_END_TOKEN) { + end_mark = token->end_mark; + SKIP_TOKEN(parser); + implicit = 0; + } + + while (!STACK_EMPTY(parser, parser->tag_directives)) { + yaml_tag_directive_t tag_directive = POP(parser, parser->tag_directives); + yaml_free(tag_directive.handle); + yaml_free(tag_directive.prefix); + } + + parser->state = YAML_PARSE_DOCUMENT_START_STATE; + DOCUMENT_END_EVENT_INIT(*event, implicit, start_mark, end_mark); + + return 1; +} + +/* + * Parse the productions: + * block_node_or_indentless_sequence ::= + * ALIAS + * ***** + * | properties (block_content | indentless_block_sequence)? + * ********** * + * | block_content | indentless_block_sequence + * * + * block_node ::= ALIAS + * ***** + * | properties block_content? + * ********** * + * | block_content + * * + * flow_node ::= ALIAS + * ***** + * | properties flow_content? + * ********** * + * | flow_content + * * + * properties ::= TAG ANCHOR? | ANCHOR TAG? + * ************************* + * block_content ::= block_collection | flow_collection | SCALAR + * ****** + * flow_content ::= flow_collection | SCALAR + * ****** + */ + +static int +yaml_parser_parse_node(yaml_parser_t *parser, yaml_event_t *event, + int block, int indentless_sequence) +{ + yaml_token_t *token; + yaml_char_t *anchor = NULL; + yaml_char_t *tag_handle = NULL; + yaml_char_t *tag_suffix = NULL; + yaml_char_t *tag = NULL; + yaml_mark_t start_mark, end_mark, tag_mark; + int implicit; + + token = PEEK_TOKEN(parser); + if (!token) return 0; + + if (token->type == YAML_ALIAS_TOKEN) + { + parser->state = POP(parser, parser->states); + ALIAS_EVENT_INIT(*event, token->data.alias.value, + token->start_mark, token->end_mark); + SKIP_TOKEN(parser); + return 1; + } + + else + { + start_mark = end_mark = token->start_mark; + + if (token->type == YAML_ANCHOR_TOKEN) + { + anchor = token->data.anchor.value; + start_mark = token->start_mark; + end_mark = token->end_mark; + SKIP_TOKEN(parser); + token = PEEK_TOKEN(parser); + if (!token) goto error; + if (token->type == YAML_TAG_TOKEN) + { + tag_handle = token->data.tag.handle; + tag_suffix = token->data.tag.suffix; + tag_mark = token->start_mark; + end_mark = token->end_mark; + SKIP_TOKEN(parser); + token = PEEK_TOKEN(parser); + if (!token) goto error; + } + } + else if (token->type == YAML_TAG_TOKEN) + { + tag_handle = token->data.tag.handle; + tag_suffix = token->data.tag.suffix; + start_mark = tag_mark = token->start_mark; + end_mark = token->end_mark; + SKIP_TOKEN(parser); + token = PEEK_TOKEN(parser); + if (!token) goto error; + if (token->type == YAML_ANCHOR_TOKEN) + { + anchor = token->data.anchor.value; + end_mark = token->end_mark; + SKIP_TOKEN(parser); + token = PEEK_TOKEN(parser); + if (!token) goto error; + } + } + + if (tag_handle) { + if (!*tag_handle) { + tag = tag_suffix; + yaml_free(tag_handle); + tag_handle = tag_suffix = NULL; + } + else { + yaml_tag_directive_t *tag_directive; + for (tag_directive = parser->tag_directives.start; + tag_directive != parser->tag_directives.top; + tag_directive ++) { + if (strcmp((char *)tag_directive->handle, (char *)tag_handle) == 0) { + size_t prefix_len = strlen((char *)tag_directive->prefix); + size_t suffix_len = strlen((char *)tag_suffix); + tag = yaml_malloc(prefix_len+suffix_len+1); + if (!tag) { + parser->error = YAML_MEMORY_ERROR; + goto error; + } + memcpy(tag, tag_directive->prefix, prefix_len); + memcpy(tag+prefix_len, tag_suffix, suffix_len); + tag[prefix_len+suffix_len] = '\0'; + yaml_free(tag_handle); + yaml_free(tag_suffix); + tag_handle = tag_suffix = NULL; + break; + } + } + if (!tag) { + yaml_parser_set_parser_error_context(parser, + "while parsing a node", start_mark, + "found undefined tag handle", tag_mark); + goto error; + } + } + } + + implicit = (!tag || !*tag); + if (indentless_sequence && token->type == YAML_BLOCK_ENTRY_TOKEN) { + end_mark = token->end_mark; + parser->state = YAML_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE; + SEQUENCE_START_EVENT_INIT(*event, anchor, tag, implicit, + YAML_BLOCK_SEQUENCE_STYLE, start_mark, end_mark); + return 1; + } + else { + if (token->type == YAML_SCALAR_TOKEN) { + int plain_implicit = 0; + int quoted_implicit = 0; + end_mark = token->end_mark; + if ((token->data.scalar.style == YAML_PLAIN_SCALAR_STYLE && !tag) + || (tag && strcmp((char *)tag, "!") == 0)) { + plain_implicit = 1; + } + else if (!tag) { + quoted_implicit = 1; + } + parser->state = POP(parser, parser->states); + SCALAR_EVENT_INIT(*event, anchor, tag, + token->data.scalar.value, token->data.scalar.length, + plain_implicit, quoted_implicit, + token->data.scalar.style, start_mark, end_mark); + SKIP_TOKEN(parser); + return 1; + } + else if (token->type == YAML_FLOW_SEQUENCE_START_TOKEN) { + end_mark = token->end_mark; + parser->state = YAML_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE; + SEQUENCE_START_EVENT_INIT(*event, anchor, tag, implicit, + YAML_FLOW_SEQUENCE_STYLE, start_mark, end_mark); + return 1; + } + else if (token->type == YAML_FLOW_MAPPING_START_TOKEN) { + end_mark = token->end_mark; + parser->state = YAML_PARSE_FLOW_MAPPING_FIRST_KEY_STATE; + MAPPING_START_EVENT_INIT(*event, anchor, tag, implicit, + YAML_FLOW_MAPPING_STYLE, start_mark, end_mark); + return 1; + } + else if (block && token->type == YAML_BLOCK_SEQUENCE_START_TOKEN) { + end_mark = token->end_mark; + parser->state = YAML_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE; + SEQUENCE_START_EVENT_INIT(*event, anchor, tag, implicit, + YAML_BLOCK_SEQUENCE_STYLE, start_mark, end_mark); + return 1; + } + else if (block && token->type == YAML_BLOCK_MAPPING_START_TOKEN) { + end_mark = token->end_mark; + parser->state = YAML_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE; + MAPPING_START_EVENT_INIT(*event, anchor, tag, implicit, + YAML_BLOCK_MAPPING_STYLE, start_mark, end_mark); + return 1; + } + else if (anchor || tag) { + yaml_char_t *value = yaml_malloc(1); + if (!value) { + parser->error = YAML_MEMORY_ERROR; + goto error; + } + value[0] = '\0'; + parser->state = POP(parser, parser->states); + SCALAR_EVENT_INIT(*event, anchor, tag, value, 0, + implicit, 0, YAML_PLAIN_SCALAR_STYLE, + start_mark, end_mark); + return 1; + } + else { + yaml_parser_set_parser_error_context(parser, + (block ? "while parsing a block node" + : "while parsing a flow node"), start_mark, + "did not find expected node content", token->start_mark); + goto error; + } + } + } + +error: + yaml_free(anchor); + yaml_free(tag_handle); + yaml_free(tag_suffix); + yaml_free(tag); + + return 0; +} + +/* + * Parse the productions: + * block_sequence ::= BLOCK-SEQUENCE-START (BLOCK-ENTRY block_node?)* BLOCK-END + * ******************** *********** * ********* + */ + +static int +yaml_parser_parse_block_sequence_entry(yaml_parser_t *parser, + yaml_event_t *event, int first) +{ + yaml_token_t *token; + + if (first) { + token = PEEK_TOKEN(parser); + if (!PUSH(parser, parser->marks, token->start_mark)) + return 0; + SKIP_TOKEN(parser); + } + + token = PEEK_TOKEN(parser); + if (!token) return 0; + + if (token->type == YAML_BLOCK_ENTRY_TOKEN) + { + yaml_mark_t mark = token->end_mark; + SKIP_TOKEN(parser); + token = PEEK_TOKEN(parser); + if (!token) return 0; + if (token->type != YAML_BLOCK_ENTRY_TOKEN && + token->type != YAML_BLOCK_END_TOKEN) { + if (!PUSH(parser, parser->states, + YAML_PARSE_BLOCK_SEQUENCE_ENTRY_STATE)) + return 0; + return yaml_parser_parse_node(parser, event, 1, 0); + } + else { + parser->state = YAML_PARSE_BLOCK_SEQUENCE_ENTRY_STATE; + return yaml_parser_process_empty_scalar(parser, event, mark); + } + } + + else if (token->type == YAML_BLOCK_END_TOKEN) + { + yaml_mark_t dummy_mark; /* Used to eliminate a compiler warning. */ + parser->state = POP(parser, parser->states); + dummy_mark = POP(parser, parser->marks); + SEQUENCE_END_EVENT_INIT(*event, token->start_mark, token->end_mark); + SKIP_TOKEN(parser); + return 1; + } + + else + { + return yaml_parser_set_parser_error_context(parser, + "while parsing a block collection", POP(parser, parser->marks), + "did not find expected '-' indicator", token->start_mark); + } +} + +/* + * Parse the productions: + * indentless_sequence ::= (BLOCK-ENTRY block_node?)+ + * *********** * + */ + +static int +yaml_parser_parse_indentless_sequence_entry(yaml_parser_t *parser, + yaml_event_t *event) +{ + yaml_token_t *token; + + token = PEEK_TOKEN(parser); + if (!token) return 0; + + if (token->type == YAML_BLOCK_ENTRY_TOKEN) + { + yaml_mark_t mark = token->end_mark; + SKIP_TOKEN(parser); + token = PEEK_TOKEN(parser); + if (!token) return 0; + if (token->type != YAML_BLOCK_ENTRY_TOKEN && + token->type != YAML_KEY_TOKEN && + token->type != YAML_VALUE_TOKEN && + token->type != YAML_BLOCK_END_TOKEN) { + if (!PUSH(parser, parser->states, + YAML_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE)) + return 0; + return yaml_parser_parse_node(parser, event, 1, 0); + } + else { + parser->state = YAML_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE; + return yaml_parser_process_empty_scalar(parser, event, mark); + } + } + + else + { + parser->state = POP(parser, parser->states); + SEQUENCE_END_EVENT_INIT(*event, token->start_mark, token->start_mark); + return 1; + } +} + +/* + * Parse the productions: + * block_mapping ::= BLOCK-MAPPING_START + * ******************* + * ((KEY block_node_or_indentless_sequence?)? + * *** * + * (VALUE block_node_or_indentless_sequence?)?)* + * + * BLOCK-END + * ********* + */ + +static int +yaml_parser_parse_block_mapping_key(yaml_parser_t *parser, + yaml_event_t *event, int first) +{ + yaml_token_t *token; + + if (first) { + token = PEEK_TOKEN(parser); + if (!PUSH(parser, parser->marks, token->start_mark)) + return 0; + SKIP_TOKEN(parser); + } + + token = PEEK_TOKEN(parser); + if (!token) return 0; + + if (token->type == YAML_KEY_TOKEN) + { + yaml_mark_t mark = token->end_mark; + SKIP_TOKEN(parser); + token = PEEK_TOKEN(parser); + if (!token) return 0; + if (token->type != YAML_KEY_TOKEN && + token->type != YAML_VALUE_TOKEN && + token->type != YAML_BLOCK_END_TOKEN) { + if (!PUSH(parser, parser->states, + YAML_PARSE_BLOCK_MAPPING_VALUE_STATE)) + return 0; + return yaml_parser_parse_node(parser, event, 1, 1); + } + else { + parser->state = YAML_PARSE_BLOCK_MAPPING_VALUE_STATE; + return yaml_parser_process_empty_scalar(parser, event, mark); + } + } + + else if (token->type == YAML_BLOCK_END_TOKEN) + { + yaml_mark_t dummy_mark; /* Used to eliminate a compiler warning. */ + parser->state = POP(parser, parser->states); + dummy_mark = POP(parser, parser->marks); + MAPPING_END_EVENT_INIT(*event, token->start_mark, token->end_mark); + SKIP_TOKEN(parser); + return 1; + } + + else + { + return yaml_parser_set_parser_error_context(parser, + "while parsing a block mapping", POP(parser, parser->marks), + "did not find expected key", token->start_mark); + } +} + +/* + * Parse the productions: + * block_mapping ::= BLOCK-MAPPING_START + * + * ((KEY block_node_or_indentless_sequence?)? + * + * (VALUE block_node_or_indentless_sequence?)?)* + * ***** * + * BLOCK-END + * + */ + +static int +yaml_parser_parse_block_mapping_value(yaml_parser_t *parser, + yaml_event_t *event) +{ + yaml_token_t *token; + + token = PEEK_TOKEN(parser); + if (!token) return 0; + + if (token->type == YAML_VALUE_TOKEN) + { + yaml_mark_t mark = token->end_mark; + SKIP_TOKEN(parser); + token = PEEK_TOKEN(parser); + if (!token) return 0; + if (token->type != YAML_KEY_TOKEN && + token->type != YAML_VALUE_TOKEN && + token->type != YAML_BLOCK_END_TOKEN) { + if (!PUSH(parser, parser->states, + YAML_PARSE_BLOCK_MAPPING_KEY_STATE)) + return 0; + return yaml_parser_parse_node(parser, event, 1, 1); + } + else { + parser->state = YAML_PARSE_BLOCK_MAPPING_KEY_STATE; + return yaml_parser_process_empty_scalar(parser, event, mark); + } + } + + else + { + parser->state = YAML_PARSE_BLOCK_MAPPING_KEY_STATE; + return yaml_parser_process_empty_scalar(parser, event, token->start_mark); + } +} + +/* + * Parse the productions: + * flow_sequence ::= FLOW-SEQUENCE-START + * ******************* + * (flow_sequence_entry FLOW-ENTRY)* + * * ********** + * flow_sequence_entry? + * * + * FLOW-SEQUENCE-END + * ***************** + * flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? + * * + */ + +static int +yaml_parser_parse_flow_sequence_entry(yaml_parser_t *parser, + yaml_event_t *event, int first) +{ + yaml_token_t *token; + yaml_mark_t dummy_mark; /* Used to eliminate a compiler warning. */ + + if (first) { + token = PEEK_TOKEN(parser); + if (!PUSH(parser, parser->marks, token->start_mark)) + return 0; + SKIP_TOKEN(parser); + } + + token = PEEK_TOKEN(parser); + if (!token) return 0; + + if (token->type != YAML_FLOW_SEQUENCE_END_TOKEN) + { + if (!first) { + if (token->type == YAML_FLOW_ENTRY_TOKEN) { + SKIP_TOKEN(parser); + token = PEEK_TOKEN(parser); + if (!token) return 0; + } + else { + return yaml_parser_set_parser_error_context(parser, + "while parsing a flow sequence", POP(parser, parser->marks), + "did not find expected ',' or ']'", token->start_mark); + } + } + + if (token->type == YAML_KEY_TOKEN) { + parser->state = YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE; + MAPPING_START_EVENT_INIT(*event, NULL, NULL, + 1, YAML_FLOW_MAPPING_STYLE, + token->start_mark, token->end_mark); + SKIP_TOKEN(parser); + return 1; + } + + else if (token->type != YAML_FLOW_SEQUENCE_END_TOKEN) { + if (!PUSH(parser, parser->states, + YAML_PARSE_FLOW_SEQUENCE_ENTRY_STATE)) + return 0; + return yaml_parser_parse_node(parser, event, 0, 0); + } + } + + parser->state = POP(parser, parser->states); + dummy_mark = POP(parser, parser->marks); + SEQUENCE_END_EVENT_INIT(*event, token->start_mark, token->end_mark); + SKIP_TOKEN(parser); + return 1; +} + +/* + * Parse the productions: + * flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? + * *** * + */ + +static int +yaml_parser_parse_flow_sequence_entry_mapping_key(yaml_parser_t *parser, + yaml_event_t *event) +{ + yaml_token_t *token; + + token = PEEK_TOKEN(parser); + if (!token) return 0; + + if (token->type != YAML_VALUE_TOKEN && token->type != YAML_FLOW_ENTRY_TOKEN + && token->type != YAML_FLOW_SEQUENCE_END_TOKEN) { + if (!PUSH(parser, parser->states, + YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE)) + return 0; + return yaml_parser_parse_node(parser, event, 0, 0); + } + else { + yaml_mark_t mark = token->end_mark; + SKIP_TOKEN(parser); + parser->state = YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE; + return yaml_parser_process_empty_scalar(parser, event, mark); + } +} + +/* + * Parse the productions: + * flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? + * ***** * + */ + +static int +yaml_parser_parse_flow_sequence_entry_mapping_value(yaml_parser_t *parser, + yaml_event_t *event) +{ + yaml_token_t *token; + + token = PEEK_TOKEN(parser); + if (!token) return 0; + + if (token->type == YAML_VALUE_TOKEN) { + SKIP_TOKEN(parser); + token = PEEK_TOKEN(parser); + if (!token) return 0; + if (token->type != YAML_FLOW_ENTRY_TOKEN + && token->type != YAML_FLOW_SEQUENCE_END_TOKEN) { + if (!PUSH(parser, parser->states, + YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE)) + return 0; + return yaml_parser_parse_node(parser, event, 0, 0); + } + } + parser->state = YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE; + return yaml_parser_process_empty_scalar(parser, event, token->start_mark); +} + +/* + * Parse the productions: + * flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? + * * + */ + +static int +yaml_parser_parse_flow_sequence_entry_mapping_end(yaml_parser_t *parser, + yaml_event_t *event) +{ + yaml_token_t *token; + + token = PEEK_TOKEN(parser); + if (!token) return 0; + + parser->state = YAML_PARSE_FLOW_SEQUENCE_ENTRY_STATE; + + MAPPING_END_EVENT_INIT(*event, token->start_mark, token->start_mark); + return 1; +} + +/* + * Parse the productions: + * flow_mapping ::= FLOW-MAPPING-START + * ****************** + * (flow_mapping_entry FLOW-ENTRY)* + * * ********** + * flow_mapping_entry? + * ****************** + * FLOW-MAPPING-END + * **************** + * flow_mapping_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? + * * *** * + */ + +static int +yaml_parser_parse_flow_mapping_key(yaml_parser_t *parser, + yaml_event_t *event, int first) +{ + yaml_token_t *token; + yaml_mark_t dummy_mark; /* Used to eliminate a compiler warning. */ + + if (first) { + token = PEEK_TOKEN(parser); + if (!PUSH(parser, parser->marks, token->start_mark)) + return 0; + SKIP_TOKEN(parser); + } + + token = PEEK_TOKEN(parser); + if (!token) return 0; + + if (token->type != YAML_FLOW_MAPPING_END_TOKEN) + { + if (!first) { + if (token->type == YAML_FLOW_ENTRY_TOKEN) { + SKIP_TOKEN(parser); + token = PEEK_TOKEN(parser); + if (!token) return 0; + } + else { + return yaml_parser_set_parser_error_context(parser, + "while parsing a flow mapping", POP(parser, parser->marks), + "did not find expected ',' or '}'", token->start_mark); + } + } + + if (token->type == YAML_KEY_TOKEN) { + SKIP_TOKEN(parser); + token = PEEK_TOKEN(parser); + if (!token) return 0; + if (token->type != YAML_VALUE_TOKEN + && token->type != YAML_FLOW_ENTRY_TOKEN + && token->type != YAML_FLOW_MAPPING_END_TOKEN) { + if (!PUSH(parser, parser->states, + YAML_PARSE_FLOW_MAPPING_VALUE_STATE)) + return 0; + return yaml_parser_parse_node(parser, event, 0, 0); + } + else { + parser->state = YAML_PARSE_FLOW_MAPPING_VALUE_STATE; + return yaml_parser_process_empty_scalar(parser, event, + token->start_mark); + } + } + else if (token->type != YAML_FLOW_MAPPING_END_TOKEN) { + if (!PUSH(parser, parser->states, + YAML_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE)) + return 0; + return yaml_parser_parse_node(parser, event, 0, 0); + } + } + + parser->state = POP(parser, parser->states); + dummy_mark = POP(parser, parser->marks); + MAPPING_END_EVENT_INIT(*event, token->start_mark, token->end_mark); + SKIP_TOKEN(parser); + return 1; +} + +/* + * Parse the productions: + * flow_mapping_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? + * * ***** * + */ + +static int +yaml_parser_parse_flow_mapping_value(yaml_parser_t *parser, + yaml_event_t *event, int empty) +{ + yaml_token_t *token; + + token = PEEK_TOKEN(parser); + if (!token) return 0; + + if (empty) { + parser->state = YAML_PARSE_FLOW_MAPPING_KEY_STATE; + return yaml_parser_process_empty_scalar(parser, event, + token->start_mark); + } + + if (token->type == YAML_VALUE_TOKEN) { + SKIP_TOKEN(parser); + token = PEEK_TOKEN(parser); + if (!token) return 0; + if (token->type != YAML_FLOW_ENTRY_TOKEN + && token->type != YAML_FLOW_MAPPING_END_TOKEN) { + if (!PUSH(parser, parser->states, + YAML_PARSE_FLOW_MAPPING_KEY_STATE)) + return 0; + return yaml_parser_parse_node(parser, event, 0, 0); + } + } + + parser->state = YAML_PARSE_FLOW_MAPPING_KEY_STATE; + return yaml_parser_process_empty_scalar(parser, event, token->start_mark); +} + +/* + * Generate an empty scalar event. + */ + +static int +yaml_parser_process_empty_scalar(yaml_parser_t *parser, yaml_event_t *event, + yaml_mark_t mark) +{ + yaml_char_t *value; + + value = yaml_malloc(1); + if (!value) { + parser->error = YAML_MEMORY_ERROR; + return 0; + } + value[0] = '\0'; + + SCALAR_EVENT_INIT(*event, NULL, NULL, value, 0, + 1, 0, YAML_PLAIN_SCALAR_STYLE, mark, mark); + + return 1; +} + +/* + * Parse directives. + */ + +static int +yaml_parser_process_directives(yaml_parser_t *parser, + yaml_version_directive_t **version_directive_ref, + yaml_tag_directive_t **tag_directives_start_ref, + yaml_tag_directive_t **tag_directives_end_ref) +{ + yaml_tag_directive_t default_tag_directives[] = { + {(yaml_char_t *)"!", (yaml_char_t *)"!"}, + {(yaml_char_t *)"!!", (yaml_char_t *)"tag:yaml.org,2002:"}, + {NULL, NULL} + }; + yaml_tag_directive_t *default_tag_directive; + yaml_version_directive_t *version_directive = NULL; + struct { + yaml_tag_directive_t *start; + yaml_tag_directive_t *end; + yaml_tag_directive_t *top; + } tag_directives = { NULL, NULL, NULL }; + yaml_token_t *token; + + if (!STACK_INIT(parser, tag_directives, INITIAL_STACK_SIZE)) + goto error; + + token = PEEK_TOKEN(parser); + if (!token) goto error; + + while (token->type == YAML_VERSION_DIRECTIVE_TOKEN || + token->type == YAML_TAG_DIRECTIVE_TOKEN) + { + if (token->type == YAML_VERSION_DIRECTIVE_TOKEN) { + if (version_directive) { + yaml_parser_set_parser_error(parser, + "found duplicate %YAML directive", token->start_mark); + goto error; + } + if (token->data.version_directive.major != 1 + || token->data.version_directive.minor != 1) { + yaml_parser_set_parser_error(parser, + "found incompatible YAML document", token->start_mark); + goto error; + } + version_directive = yaml_malloc(sizeof(yaml_version_directive_t)); + if (!version_directive) { + parser->error = YAML_MEMORY_ERROR; + goto error; + } + version_directive->major = token->data.version_directive.major; + version_directive->minor = token->data.version_directive.minor; + } + + else if (token->type == YAML_TAG_DIRECTIVE_TOKEN) { + yaml_tag_directive_t value; + value.handle = token->data.tag_directive.handle; + value.prefix = token->data.tag_directive.prefix; + + if (!yaml_parser_append_tag_directive(parser, value, 0, + token->start_mark)) + goto error; + if (!PUSH(parser, tag_directives, value)) + goto error; + } + + SKIP_TOKEN(parser); + token = PEEK_TOKEN(parser); + if (!token) goto error; + } + + for (default_tag_directive = default_tag_directives; + default_tag_directive->handle; default_tag_directive++) { + if (!yaml_parser_append_tag_directive(parser, *default_tag_directive, 1, + token->start_mark)) + goto error; + } + + if (version_directive_ref) { + *version_directive_ref = version_directive; + } + if (tag_directives_start_ref) { + if (STACK_EMPTY(parser, tag_directives)) { + *tag_directives_start_ref = *tag_directives_end_ref = NULL; + STACK_DEL(parser, tag_directives); + } + else { + *tag_directives_start_ref = tag_directives.start; + *tag_directives_end_ref = tag_directives.top; + } + } + else { + STACK_DEL(parser, tag_directives); + } + + return 1; + +error: + yaml_free(version_directive); + while (!STACK_EMPTY(parser, tag_directives)) { + yaml_tag_directive_t tag_directive = POP(parser, tag_directives); + yaml_free(tag_directive.handle); + yaml_free(tag_directive.prefix); + } + STACK_DEL(parser, tag_directives); + return 0; +} + +/* + * Append a tag directive to the directives stack. + */ + +static int +yaml_parser_append_tag_directive(yaml_parser_t *parser, + yaml_tag_directive_t value, int allow_duplicates, yaml_mark_t mark) +{ + yaml_tag_directive_t *tag_directive; + yaml_tag_directive_t copy = { NULL, NULL }; + + for (tag_directive = parser->tag_directives.start; + tag_directive != parser->tag_directives.top; tag_directive ++) { + if (strcmp((char *)value.handle, (char *)tag_directive->handle) == 0) { + if (allow_duplicates) + return 1; + return yaml_parser_set_parser_error(parser, + "found duplicate %TAG directive", mark); + } + } + + copy.handle = yaml_strdup(value.handle); + copy.prefix = yaml_strdup(value.prefix); + if (!copy.handle || !copy.prefix) { + parser->error = YAML_MEMORY_ERROR; + goto error; + } + + if (!PUSH(parser, parser->tag_directives, copy)) + goto error; + + return 1; + +error: + yaml_free(copy.handle); + yaml_free(copy.prefix); + return 0; +} + diff --git a/libyaml/src/reader.c b/libyaml/src/reader.c new file mode 100644 index 00000000..d47921ce --- /dev/null +++ b/libyaml/src/reader.c @@ -0,0 +1,469 @@ + +#include "yaml_private.h" + +/* + * Declarations. + */ + +static int +yaml_parser_set_reader_error(yaml_parser_t *parser, const char *problem, + size_t offset, int value); + +static int +yaml_parser_update_raw_buffer(yaml_parser_t *parser); + +static int +yaml_parser_determine_encoding(yaml_parser_t *parser); + +YAML_DECLARE(int) +yaml_parser_update_buffer(yaml_parser_t *parser, size_t length); + +/* + * Set the reader error and return 0. + */ + +static int +yaml_parser_set_reader_error(yaml_parser_t *parser, const char *problem, + size_t offset, int value) +{ + parser->error = YAML_READER_ERROR; + parser->problem = problem; + parser->problem_offset = offset; + parser->problem_value = value; + + return 0; +} + +/* + * Byte order marks. + */ + +#define BOM_UTF8 "\xef\xbb\xbf" +#define BOM_UTF16LE "\xff\xfe" +#define BOM_UTF16BE "\xfe\xff" + +/* + * Determine the input stream encoding by checking the BOM symbol. If no BOM is + * found, the UTF-8 encoding is assumed. Return 1 on success, 0 on failure. + */ + +static int +yaml_parser_determine_encoding(yaml_parser_t *parser) +{ + /* Ensure that we had enough bytes in the raw buffer. */ + + while (!parser->eof + && parser->raw_buffer.last - parser->raw_buffer.pointer < 3) { + if (!yaml_parser_update_raw_buffer(parser)) { + return 0; + } + } + + /* Determine the encoding. */ + + if (parser->raw_buffer.last - parser->raw_buffer.pointer >= 2 + && !memcmp(parser->raw_buffer.pointer, BOM_UTF16LE, 2)) { + parser->encoding = YAML_UTF16LE_ENCODING; + parser->raw_buffer.pointer += 2; + parser->offset += 2; + } + else if (parser->raw_buffer.last - parser->raw_buffer.pointer >= 2 + && !memcmp(parser->raw_buffer.pointer, BOM_UTF16BE, 2)) { + parser->encoding = YAML_UTF16BE_ENCODING; + parser->raw_buffer.pointer += 2; + parser->offset += 2; + } + else if (parser->raw_buffer.last - parser->raw_buffer.pointer >= 3 + && !memcmp(parser->raw_buffer.pointer, BOM_UTF8, 3)) { + parser->encoding = YAML_UTF8_ENCODING; + parser->raw_buffer.pointer += 3; + parser->offset += 3; + } + else { + parser->encoding = YAML_UTF8_ENCODING; + } + + return 1; +} + +/* + * Update the raw buffer. + */ + +static int +yaml_parser_update_raw_buffer(yaml_parser_t *parser) +{ + size_t size_read = 0; + + /* Return if the raw buffer is full. */ + + if (parser->raw_buffer.start == parser->raw_buffer.pointer + && parser->raw_buffer.last == parser->raw_buffer.end) + return 1; + + /* Return on EOF. */ + + if (parser->eof) return 1; + + /* Move the remaining bytes in the raw buffer to the beginning. */ + + if (parser->raw_buffer.start < parser->raw_buffer.pointer + && parser->raw_buffer.pointer < parser->raw_buffer.last) { + memmove(parser->raw_buffer.start, parser->raw_buffer.pointer, + parser->raw_buffer.last - parser->raw_buffer.pointer); + } + parser->raw_buffer.last -= + parser->raw_buffer.pointer - parser->raw_buffer.start; + parser->raw_buffer.pointer = parser->raw_buffer.start; + + /* Call the read handler to fill the buffer. */ + + if (!parser->read_handler(parser->read_handler_data, parser->raw_buffer.last, + parser->raw_buffer.end - parser->raw_buffer.last, &size_read)) { + return yaml_parser_set_reader_error(parser, "input error", + parser->offset, -1); + } + parser->raw_buffer.last += size_read; + if (!size_read) { + parser->eof = 1; + } + + return 1; +} + +/* + * Ensure that the buffer contains at least `length` characters. + * Return 1 on success, 0 on failure. + * + * The length is supposed to be significantly less that the buffer size. + */ + +YAML_DECLARE(int) +yaml_parser_update_buffer(yaml_parser_t *parser, size_t length) +{ + int first = 1; + + assert(parser->read_handler); /* Read handler must be set. */ + + /* If the EOF flag is set and the raw buffer is empty, do nothing. */ + + if (parser->eof && parser->raw_buffer.pointer == parser->raw_buffer.last) + return 1; + + /* Return if the buffer contains enough characters. */ + + if (parser->unread >= length) + return 1; + + /* Determine the input encoding if it is not known yet. */ + + if (!parser->encoding) { + if (!yaml_parser_determine_encoding(parser)) + return 0; + } + + /* Move the unread characters to the beginning of the buffer. */ + + if (parser->buffer.start < parser->buffer.pointer + && parser->buffer.pointer < parser->buffer.last) { + size_t size = parser->buffer.last - parser->buffer.pointer; + memmove(parser->buffer.start, parser->buffer.pointer, size); + parser->buffer.pointer = parser->buffer.start; + parser->buffer.last = parser->buffer.start + size; + } + else if (parser->buffer.pointer == parser->buffer.last) { + parser->buffer.pointer = parser->buffer.start; + parser->buffer.last = parser->buffer.start; + } + + /* Fill the buffer until it has enough characters. */ + + while (parser->unread < length) + { + /* Fill the raw buffer if necessary. */ + + if (!first || parser->raw_buffer.pointer == parser->raw_buffer.last) { + if (!yaml_parser_update_raw_buffer(parser)) return 0; + } + first = 0; + + /* Decode the raw buffer. */ + + while (parser->raw_buffer.pointer != parser->raw_buffer.last) + { + unsigned int value = 0, value2 = 0; + int incomplete = 0; + unsigned char octet; + unsigned int width = 0; + int low, high; + size_t k; + size_t raw_unread = parser->raw_buffer.last - parser->raw_buffer.pointer; + + /* Decode the next character. */ + + switch (parser->encoding) + { + case YAML_UTF8_ENCODING: + + /* + * Decode a UTF-8 character. Check RFC 3629 + * (http://www.ietf.org/rfc/rfc3629.txt) for more details. + * + * The following table (taken from the RFC) is used for + * decoding. + * + * Char. number range | UTF-8 octet sequence + * (hexadecimal) | (binary) + * --------------------+------------------------------------ + * 0000 0000-0000 007F | 0xxxxxxx + * 0000 0080-0000 07FF | 110xxxxx 10xxxxxx + * 0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx + * 0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx + * + * Additionally, the characters in the range 0xD800-0xDFFF + * are prohibited as they are reserved for use with UTF-16 + * surrogate pairs. + */ + + /* Determine the length of the UTF-8 sequence. */ + + octet = parser->raw_buffer.pointer[0]; + width = (octet & 0x80) == 0x00 ? 1 : + (octet & 0xE0) == 0xC0 ? 2 : + (octet & 0xF0) == 0xE0 ? 3 : + (octet & 0xF8) == 0xF0 ? 4 : 0; + + /* Check if the leading octet is valid. */ + + if (!width) + return yaml_parser_set_reader_error(parser, + "invalid leading UTF-8 octet", + parser->offset, octet); + + /* Check if the raw buffer contains an incomplete character. */ + + if (width > raw_unread) { + if (parser->eof) { + return yaml_parser_set_reader_error(parser, + "incomplete UTF-8 octet sequence", + parser->offset, -1); + } + incomplete = 1; + break; + } + + /* Decode the leading octet. */ + + value = (octet & 0x80) == 0x00 ? octet & 0x7F : + (octet & 0xE0) == 0xC0 ? octet & 0x1F : + (octet & 0xF0) == 0xE0 ? octet & 0x0F : + (octet & 0xF8) == 0xF0 ? octet & 0x07 : 0; + + /* Check and decode the trailing octets. */ + + for (k = 1; k < width; k ++) + { + octet = parser->raw_buffer.pointer[k]; + + /* Check if the octet is valid. */ + + if ((octet & 0xC0) != 0x80) + return yaml_parser_set_reader_error(parser, + "invalid trailing UTF-8 octet", + parser->offset+k, octet); + + /* Decode the octet. */ + + value = (value << 6) + (octet & 0x3F); + } + + /* Check the length of the sequence against the value. */ + + if (!((width == 1) || + (width == 2 && value >= 0x80) || + (width == 3 && value >= 0x800) || + (width == 4 && value >= 0x10000))) + return yaml_parser_set_reader_error(parser, + "invalid length of a UTF-8 sequence", + parser->offset, -1); + + /* Check the range of the value. */ + + if ((value >= 0xD800 && value <= 0xDFFF) || value > 0x10FFFF) + return yaml_parser_set_reader_error(parser, + "invalid Unicode character", + parser->offset, value); + + break; + + case YAML_UTF16LE_ENCODING: + case YAML_UTF16BE_ENCODING: + + low = (parser->encoding == YAML_UTF16LE_ENCODING ? 0 : 1); + high = (parser->encoding == YAML_UTF16LE_ENCODING ? 1 : 0); + + /* + * The UTF-16 encoding is not as simple as one might + * naively think. Check RFC 2781 + * (http://www.ietf.org/rfc/rfc2781.txt). + * + * Normally, two subsequent bytes describe a Unicode + * character. However a special technique (called a + * surrogate pair) is used for specifying character + * values larger than 0xFFFF. + * + * A surrogate pair consists of two pseudo-characters: + * high surrogate area (0xD800-0xDBFF) + * low surrogate area (0xDC00-0xDFFF) + * + * The following formulas are used for decoding + * and encoding characters using surrogate pairs: + * + * U = U' + 0x10000 (0x01 00 00 <= U <= 0x10 FF FF) + * U' = yyyyyyyyyyxxxxxxxxxx (0 <= U' <= 0x0F FF FF) + * W1 = 110110yyyyyyyyyy + * W2 = 110111xxxxxxxxxx + * + * where U is the character value, W1 is the high surrogate + * area, W2 is the low surrogate area. + */ + + /* Check for incomplete UTF-16 character. */ + + if (raw_unread < 2) { + if (parser->eof) { + return yaml_parser_set_reader_error(parser, + "incomplete UTF-16 character", + parser->offset, -1); + } + incomplete = 1; + break; + } + + /* Get the character. */ + + value = parser->raw_buffer.pointer[low] + + (parser->raw_buffer.pointer[high] << 8); + + /* Check for unexpected low surrogate area. */ + + if ((value & 0xFC00) == 0xDC00) + return yaml_parser_set_reader_error(parser, + "unexpected low surrogate area", + parser->offset, value); + + /* Check for a high surrogate area. */ + + if ((value & 0xFC00) == 0xD800) { + + width = 4; + + /* Check for incomplete surrogate pair. */ + + if (raw_unread < 4) { + if (parser->eof) { + return yaml_parser_set_reader_error(parser, + "incomplete UTF-16 surrogate pair", + parser->offset, -1); + } + incomplete = 1; + break; + } + + /* Get the next character. */ + + value2 = parser->raw_buffer.pointer[low+2] + + (parser->raw_buffer.pointer[high+2] << 8); + + /* Check for a low surrogate area. */ + + if ((value2 & 0xFC00) != 0xDC00) + return yaml_parser_set_reader_error(parser, + "expected low surrogate area", + parser->offset+2, value2); + + /* Generate the value of the surrogate pair. */ + + value = 0x10000 + ((value & 0x3FF) << 10) + (value2 & 0x3FF); + } + + else { + width = 2; + } + + break; + + default: + assert(1); /* Impossible. */ + } + + /* Check if the raw buffer contains enough bytes to form a character. */ + + if (incomplete) break; + + /* + * Check if the character is in the allowed range: + * #x9 | #xA | #xD | [#x20-#x7E] (8 bit) + * | #x85 | [#xA0-#xD7FF] | [#xE000-#xFFFD] (16 bit) + * | [#x10000-#x10FFFF] (32 bit) + */ + + if (! (value == 0x09 || value == 0x0A || value == 0x0D + || (value >= 0x20 && value <= 0x7E) + || (value == 0x85) || (value >= 0xA0 && value <= 0xD7FF) + || (value >= 0xE000 && value <= 0xFFFD) + || (value >= 0x10000 && value <= 0x10FFFF))) + return yaml_parser_set_reader_error(parser, + "control characters are not allowed", + parser->offset, value); + + /* Move the raw pointers. */ + + parser->raw_buffer.pointer += width; + parser->offset += width; + + /* Finally put the character into the buffer. */ + + /* 0000 0000-0000 007F -> 0xxxxxxx */ + if (value <= 0x7F) { + *(parser->buffer.last++) = value; + } + /* 0000 0080-0000 07FF -> 110xxxxx 10xxxxxx */ + else if (value <= 0x7FF) { + *(parser->buffer.last++) = 0xC0 + (value >> 6); + *(parser->buffer.last++) = 0x80 + (value & 0x3F); + } + /* 0000 0800-0000 FFFF -> 1110xxxx 10xxxxxx 10xxxxxx */ + else if (value <= 0xFFFF) { + *(parser->buffer.last++) = 0xE0 + (value >> 12); + *(parser->buffer.last++) = 0x80 + ((value >> 6) & 0x3F); + *(parser->buffer.last++) = 0x80 + (value & 0x3F); + } + /* 0001 0000-0010 FFFF -> 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx */ + else { + *(parser->buffer.last++) = 0xF0 + (value >> 18); + *(parser->buffer.last++) = 0x80 + ((value >> 12) & 0x3F); + *(parser->buffer.last++) = 0x80 + ((value >> 6) & 0x3F); + *(parser->buffer.last++) = 0x80 + (value & 0x3F); + } + + parser->unread ++; + } + + /* On EOF, put NUL into the buffer and return. */ + + if (parser->eof) { + *(parser->buffer.last++) = '\0'; + parser->unread ++; + return 1; + } + + } + + if (parser->offset >= PTRDIFF_MAX) + return yaml_parser_set_reader_error(parser, "input is too long", + PTRDIFF_MAX, -1); + + return 1; +} + diff --git a/libyaml/src/scanner.c b/libyaml/src/scanner.c new file mode 100644 index 00000000..8817de24 --- /dev/null +++ b/libyaml/src/scanner.c @@ -0,0 +1,3580 @@ + +/* + * Introduction + * ************ + * + * The following notes assume that you are familiar with the YAML specification + * (http://yaml.org/spec/cvs/current.html). We mostly follow it, although in + * some cases we are less restrictive that it requires. + * + * The process of transforming a YAML stream into a sequence of events is + * divided on two steps: Scanning and Parsing. + * + * The Scanner transforms the input stream into a sequence of tokens, while the + * parser transform the sequence of tokens produced by the Scanner into a + * sequence of parsing events. + * + * The Scanner is rather clever and complicated. The Parser, on the contrary, + * is a straightforward implementation of a recursive-descendant parser (or, + * LL(1) parser, as it is usually called). + * + * Actually there are two issues of Scanning that might be called "clever", the + * rest is quite straightforward. The issues are "block collection start" and + * "simple keys". Both issues are explained below in details. + * + * Here the Scanning step is explained and implemented. We start with the list + * of all the tokens produced by the Scanner together with short descriptions. + * + * Now, tokens: + * + * STREAM-START(encoding) # The stream start. + * STREAM-END # The stream end. + * VERSION-DIRECTIVE(major,minor) # The '%YAML' directive. + * TAG-DIRECTIVE(handle,prefix) # The '%TAG' directive. + * DOCUMENT-START # '---' + * DOCUMENT-END # '...' + * BLOCK-SEQUENCE-START # Indentation increase denoting a block + * BLOCK-MAPPING-START # sequence or a block mapping. + * BLOCK-END # Indentation decrease. + * FLOW-SEQUENCE-START # '[' + * FLOW-SEQUENCE-END # ']' + * BLOCK-SEQUENCE-START # '{' + * BLOCK-SEQUENCE-END # '}' + * BLOCK-ENTRY # '-' + * FLOW-ENTRY # ',' + * KEY # '?' or nothing (simple keys). + * VALUE # ':' + * ALIAS(anchor) # '*anchor' + * ANCHOR(anchor) # '&anchor' + * TAG(handle,suffix) # '!handle!suffix' + * SCALAR(value,style) # A scalar. + * + * The following two tokens are "virtual" tokens denoting the beginning and the + * end of the stream: + * + * STREAM-START(encoding) + * STREAM-END + * + * We pass the information about the input stream encoding with the + * STREAM-START token. + * + * The next two tokens are responsible for tags: + * + * VERSION-DIRECTIVE(major,minor) + * TAG-DIRECTIVE(handle,prefix) + * + * Example: + * + * %YAML 1.1 + * %TAG ! !foo + * %TAG !yaml! tag:yaml.org,2002: + * --- + * + * The correspoding sequence of tokens: + * + * STREAM-START(utf-8) + * VERSION-DIRECTIVE(1,1) + * TAG-DIRECTIVE("!","!foo") + * TAG-DIRECTIVE("!yaml","tag:yaml.org,2002:") + * DOCUMENT-START + * STREAM-END + * + * Note that the VERSION-DIRECTIVE and TAG-DIRECTIVE tokens occupy a whole + * line. + * + * The document start and end indicators are represented by: + * + * DOCUMENT-START + * DOCUMENT-END + * + * Note that if a YAML stream contains an implicit document (without '---' + * and '...' indicators), no DOCUMENT-START and DOCUMENT-END tokens will be + * produced. + * + * In the following examples, we present whole documents together with the + * produced tokens. + * + * 1. An implicit document: + * + * 'a scalar' + * + * Tokens: + * + * STREAM-START(utf-8) + * SCALAR("a scalar",single-quoted) + * STREAM-END + * + * 2. An explicit document: + * + * --- + * 'a scalar' + * ... + * + * Tokens: + * + * STREAM-START(utf-8) + * DOCUMENT-START + * SCALAR("a scalar",single-quoted) + * DOCUMENT-END + * STREAM-END + * + * 3. Several documents in a stream: + * + * 'a scalar' + * --- + * 'another scalar' + * --- + * 'yet another scalar' + * + * Tokens: + * + * STREAM-START(utf-8) + * SCALAR("a scalar",single-quoted) + * DOCUMENT-START + * SCALAR("another scalar",single-quoted) + * DOCUMENT-START + * SCALAR("yet another scalar",single-quoted) + * STREAM-END + * + * We have already introduced the SCALAR token above. The following tokens are + * used to describe aliases, anchors, tag, and scalars: + * + * ALIAS(anchor) + * ANCHOR(anchor) + * TAG(handle,suffix) + * SCALAR(value,style) + * + * The following series of examples illustrate the usage of these tokens: + * + * 1. A recursive sequence: + * + * &A [ *A ] + * + * Tokens: + * + * STREAM-START(utf-8) + * ANCHOR("A") + * FLOW-SEQUENCE-START + * ALIAS("A") + * FLOW-SEQUENCE-END + * STREAM-END + * + * 2. A tagged scalar: + * + * !!float "3.14" # A good approximation. + * + * Tokens: + * + * STREAM-START(utf-8) + * TAG("!!","float") + * SCALAR("3.14",double-quoted) + * STREAM-END + * + * 3. Various scalar styles: + * + * --- # Implicit empty plain scalars do not produce tokens. + * --- a plain scalar + * --- 'a single-quoted scalar' + * --- "a double-quoted scalar" + * --- |- + * a literal scalar + * --- >- + * a folded + * scalar + * + * Tokens: + * + * STREAM-START(utf-8) + * DOCUMENT-START + * DOCUMENT-START + * SCALAR("a plain scalar",plain) + * DOCUMENT-START + * SCALAR("a single-quoted scalar",single-quoted) + * DOCUMENT-START + * SCALAR("a double-quoted scalar",double-quoted) + * DOCUMENT-START + * SCALAR("a literal scalar",literal) + * DOCUMENT-START + * SCALAR("a folded scalar",folded) + * STREAM-END + * + * Now it's time to review collection-related tokens. We will start with + * flow collections: + * + * FLOW-SEQUENCE-START + * FLOW-SEQUENCE-END + * FLOW-MAPPING-START + * FLOW-MAPPING-END + * FLOW-ENTRY + * KEY + * VALUE + * + * The tokens FLOW-SEQUENCE-START, FLOW-SEQUENCE-END, FLOW-MAPPING-START, and + * FLOW-MAPPING-END represent the indicators '[', ']', '{', and '}' + * correspondingly. FLOW-ENTRY represent the ',' indicator. Finally the + * indicators '?' and ':', which are used for denoting mapping keys and values, + * are represented by the KEY and VALUE tokens. + * + * The following examples show flow collections: + * + * 1. A flow sequence: + * + * [item 1, item 2, item 3] + * + * Tokens: + * + * STREAM-START(utf-8) + * FLOW-SEQUENCE-START + * SCALAR("item 1",plain) + * FLOW-ENTRY + * SCALAR("item 2",plain) + * FLOW-ENTRY + * SCALAR("item 3",plain) + * FLOW-SEQUENCE-END + * STREAM-END + * + * 2. A flow mapping: + * + * { + * a simple key: a value, # Note that the KEY token is produced. + * ? a complex key: another value, + * } + * + * Tokens: + * + * STREAM-START(utf-8) + * FLOW-MAPPING-START + * KEY + * SCALAR("a simple key",plain) + * VALUE + * SCALAR("a value",plain) + * FLOW-ENTRY + * KEY + * SCALAR("a complex key",plain) + * VALUE + * SCALAR("another value",plain) + * FLOW-ENTRY + * FLOW-MAPPING-END + * STREAM-END + * + * A simple key is a key which is not denoted by the '?' indicator. Note that + * the Scanner still produce the KEY token whenever it encounters a simple key. + * + * For scanning block collections, the following tokens are used (note that we + * repeat KEY and VALUE here): + * + * BLOCK-SEQUENCE-START + * BLOCK-MAPPING-START + * BLOCK-END + * BLOCK-ENTRY + * KEY + * VALUE + * + * The tokens BLOCK-SEQUENCE-START and BLOCK-MAPPING-START denote indentation + * increase that precedes a block collection (cf. the INDENT token in Python). + * The token BLOCK-END denote indentation decrease that ends a block collection + * (cf. the DEDENT token in Python). However YAML has some syntax pecularities + * that makes detections of these tokens more complex. + * + * The tokens BLOCK-ENTRY, KEY, and VALUE are used to represent the indicators + * '-', '?', and ':' correspondingly. + * + * The following examples show how the tokens BLOCK-SEQUENCE-START, + * BLOCK-MAPPING-START, and BLOCK-END are emitted by the Scanner: + * + * 1. Block sequences: + * + * - item 1 + * - item 2 + * - + * - item 3.1 + * - item 3.2 + * - + * key 1: value 1 + * key 2: value 2 + * + * Tokens: + * + * STREAM-START(utf-8) + * BLOCK-SEQUENCE-START + * BLOCK-ENTRY + * SCALAR("item 1",plain) + * BLOCK-ENTRY + * SCALAR("item 2",plain) + * BLOCK-ENTRY + * BLOCK-SEQUENCE-START + * BLOCK-ENTRY + * SCALAR("item 3.1",plain) + * BLOCK-ENTRY + * SCALAR("item 3.2",plain) + * BLOCK-END + * BLOCK-ENTRY + * BLOCK-MAPPING-START + * KEY + * SCALAR("key 1",plain) + * VALUE + * SCALAR("value 1",plain) + * KEY + * SCALAR("key 2",plain) + * VALUE + * SCALAR("value 2",plain) + * BLOCK-END + * BLOCK-END + * STREAM-END + * + * 2. Block mappings: + * + * a simple key: a value # The KEY token is produced here. + * ? a complex key + * : another value + * a mapping: + * key 1: value 1 + * key 2: value 2 + * a sequence: + * - item 1 + * - item 2 + * + * Tokens: + * + * STREAM-START(utf-8) + * BLOCK-MAPPING-START + * KEY + * SCALAR("a simple key",plain) + * VALUE + * SCALAR("a value",plain) + * KEY + * SCALAR("a complex key",plain) + * VALUE + * SCALAR("another value",plain) + * KEY + * SCALAR("a mapping",plain) + * BLOCK-MAPPING-START + * KEY + * SCALAR("key 1",plain) + * VALUE + * SCALAR("value 1",plain) + * KEY + * SCALAR("key 2",plain) + * VALUE + * SCALAR("value 2",plain) + * BLOCK-END + * KEY + * SCALAR("a sequence",plain) + * VALUE + * BLOCK-SEQUENCE-START + * BLOCK-ENTRY + * SCALAR("item 1",plain) + * BLOCK-ENTRY + * SCALAR("item 2",plain) + * BLOCK-END + * BLOCK-END + * STREAM-END + * + * YAML does not always require to start a new block collection from a new + * line. If the current line contains only '-', '?', and ':' indicators, a new + * block collection may start at the current line. The following examples + * illustrate this case: + * + * 1. Collections in a sequence: + * + * - - item 1 + * - item 2 + * - key 1: value 1 + * key 2: value 2 + * - ? complex key + * : complex value + * + * Tokens: + * + * STREAM-START(utf-8) + * BLOCK-SEQUENCE-START + * BLOCK-ENTRY + * BLOCK-SEQUENCE-START + * BLOCK-ENTRY + * SCALAR("item 1",plain) + * BLOCK-ENTRY + * SCALAR("item 2",plain) + * BLOCK-END + * BLOCK-ENTRY + * BLOCK-MAPPING-START + * KEY + * SCALAR("key 1",plain) + * VALUE + * SCALAR("value 1",plain) + * KEY + * SCALAR("key 2",plain) + * VALUE + * SCALAR("value 2",plain) + * BLOCK-END + * BLOCK-ENTRY + * BLOCK-MAPPING-START + * KEY + * SCALAR("complex key") + * VALUE + * SCALAR("complex value") + * BLOCK-END + * BLOCK-END + * STREAM-END + * + * 2. Collections in a mapping: + * + * ? a sequence + * : - item 1 + * - item 2 + * ? a mapping + * : key 1: value 1 + * key 2: value 2 + * + * Tokens: + * + * STREAM-START(utf-8) + * BLOCK-MAPPING-START + * KEY + * SCALAR("a sequence",plain) + * VALUE + * BLOCK-SEQUENCE-START + * BLOCK-ENTRY + * SCALAR("item 1",plain) + * BLOCK-ENTRY + * SCALAR("item 2",plain) + * BLOCK-END + * KEY + * SCALAR("a mapping",plain) + * VALUE + * BLOCK-MAPPING-START + * KEY + * SCALAR("key 1",plain) + * VALUE + * SCALAR("value 1",plain) + * KEY + * SCALAR("key 2",plain) + * VALUE + * SCALAR("value 2",plain) + * BLOCK-END + * BLOCK-END + * STREAM-END + * + * YAML also permits non-indented sequences if they are included into a block + * mapping. In this case, the token BLOCK-SEQUENCE-START is not produced: + * + * key: + * - item 1 # BLOCK-SEQUENCE-START is NOT produced here. + * - item 2 + * + * Tokens: + * + * STREAM-START(utf-8) + * BLOCK-MAPPING-START + * KEY + * SCALAR("key",plain) + * VALUE + * BLOCK-ENTRY + * SCALAR("item 1",plain) + * BLOCK-ENTRY + * SCALAR("item 2",plain) + * BLOCK-END + */ + +#include "yaml_private.h" + +/* + * Ensure that the buffer contains the required number of characters. + * Return 1 on success, 0 on failure (reader error or memory error). + */ + +#define CACHE(parser,length) \ + (parser->unread >= (length) \ + ? 1 \ + : yaml_parser_update_buffer(parser, (length))) + +/* + * Advance the buffer pointer. + */ + +#define SKIP(parser) \ + (parser->mark.index ++, \ + parser->mark.column ++, \ + parser->unread --, \ + parser->buffer.pointer += WIDTH(parser->buffer)) + +#define SKIP_LINE(parser) \ + (IS_CRLF(parser->buffer) ? \ + (parser->mark.index += 2, \ + parser->mark.column = 0, \ + parser->mark.line ++, \ + parser->unread -= 2, \ + parser->buffer.pointer += 2) : \ + IS_BREAK(parser->buffer) ? \ + (parser->mark.index ++, \ + parser->mark.column = 0, \ + parser->mark.line ++, \ + parser->unread --, \ + parser->buffer.pointer += WIDTH(parser->buffer)) : 0) + +/* + * Copy a character to a string buffer and advance pointers. + */ + +#define READ(parser,string) \ + (STRING_EXTEND(parser,string) ? \ + (COPY(string,parser->buffer), \ + parser->mark.index ++, \ + parser->mark.column ++, \ + parser->unread --, \ + 1) : 0) + +/* + * Copy a line break character to a string buffer and advance pointers. + */ + +#define READ_LINE(parser,string) \ + (STRING_EXTEND(parser,string) ? \ + (((CHECK_AT(parser->buffer,'\r',0) \ + && CHECK_AT(parser->buffer,'\n',1)) ? /* CR LF -> LF */ \ + (*((string).pointer++) = (yaml_char_t) '\n', \ + parser->buffer.pointer += 2, \ + parser->mark.index += 2, \ + parser->mark.column = 0, \ + parser->mark.line ++, \ + parser->unread -= 2) : \ + (CHECK_AT(parser->buffer,'\r',0) \ + || CHECK_AT(parser->buffer,'\n',0)) ? /* CR|LF -> LF */ \ + (*((string).pointer++) = (yaml_char_t) '\n', \ + parser->buffer.pointer ++, \ + parser->mark.index ++, \ + parser->mark.column = 0, \ + parser->mark.line ++, \ + parser->unread --) : \ + (CHECK_AT(parser->buffer,'\xC2',0) \ + && CHECK_AT(parser->buffer,'\x85',1)) ? /* NEL -> LF */ \ + (*((string).pointer++) = (yaml_char_t) '\n', \ + parser->buffer.pointer += 2, \ + parser->mark.index ++, \ + parser->mark.column = 0, \ + parser->mark.line ++, \ + parser->unread --) : \ + (CHECK_AT(parser->buffer,'\xE2',0) && \ + CHECK_AT(parser->buffer,'\x80',1) && \ + (CHECK_AT(parser->buffer,'\xA8',2) || \ + CHECK_AT(parser->buffer,'\xA9',2))) ? /* LS|PS -> LS|PS */ \ + (*((string).pointer++) = *(parser->buffer.pointer++), \ + *((string).pointer++) = *(parser->buffer.pointer++), \ + *((string).pointer++) = *(parser->buffer.pointer++), \ + parser->mark.index ++, \ + parser->mark.column = 0, \ + parser->mark.line ++, \ + parser->unread --) : 0), \ + 1) : 0) + +/* + * Public API declarations. + */ + +YAML_DECLARE(int) +yaml_parser_scan(yaml_parser_t *parser, yaml_token_t *token); + +/* + * Error handling. + */ + +static int +yaml_parser_set_scanner_error(yaml_parser_t *parser, const char *context, + yaml_mark_t context_mark, const char *problem); + +/* + * High-level token API. + */ + +YAML_DECLARE(int) +yaml_parser_fetch_more_tokens(yaml_parser_t *parser); + +static int +yaml_parser_fetch_next_token(yaml_parser_t *parser); + +/* + * Potential simple keys. + */ + +static int +yaml_parser_stale_simple_keys(yaml_parser_t *parser); + +static int +yaml_parser_save_simple_key(yaml_parser_t *parser); + +static int +yaml_parser_remove_simple_key(yaml_parser_t *parser); + +static int +yaml_parser_increase_flow_level(yaml_parser_t *parser); + +static int +yaml_parser_decrease_flow_level(yaml_parser_t *parser); + +/* + * Indentation treatment. + */ + +static int +yaml_parser_roll_indent(yaml_parser_t *parser, ptrdiff_t column, + ptrdiff_t number, yaml_token_type_t type, yaml_mark_t mark); + +static int +yaml_parser_unroll_indent(yaml_parser_t *parser, ptrdiff_t column); + +/* + * Token fetchers. + */ + +static int +yaml_parser_fetch_stream_start(yaml_parser_t *parser); + +static int +yaml_parser_fetch_stream_end(yaml_parser_t *parser); + +static int +yaml_parser_fetch_directive(yaml_parser_t *parser); + +static int +yaml_parser_fetch_document_indicator(yaml_parser_t *parser, + yaml_token_type_t type); + +static int +yaml_parser_fetch_flow_collection_start(yaml_parser_t *parser, + yaml_token_type_t type); + +static int +yaml_parser_fetch_flow_collection_end(yaml_parser_t *parser, + yaml_token_type_t type); + +static int +yaml_parser_fetch_flow_entry(yaml_parser_t *parser); + +static int +yaml_parser_fetch_block_entry(yaml_parser_t *parser); + +static int +yaml_parser_fetch_key(yaml_parser_t *parser); + +static int +yaml_parser_fetch_value(yaml_parser_t *parser); + +static int +yaml_parser_fetch_anchor(yaml_parser_t *parser, yaml_token_type_t type); + +static int +yaml_parser_fetch_tag(yaml_parser_t *parser); + +static int +yaml_parser_fetch_block_scalar(yaml_parser_t *parser, int literal); + +static int +yaml_parser_fetch_flow_scalar(yaml_parser_t *parser, int single); + +static int +yaml_parser_fetch_plain_scalar(yaml_parser_t *parser); + +/* + * Token scanners. + */ + +static int +yaml_parser_scan_to_next_token(yaml_parser_t *parser); + +static int +yaml_parser_scan_directive(yaml_parser_t *parser, yaml_token_t *token); + +static int +yaml_parser_scan_directive_name(yaml_parser_t *parser, + yaml_mark_t start_mark, yaml_char_t **name); + +static int +yaml_parser_scan_version_directive_value(yaml_parser_t *parser, + yaml_mark_t start_mark, int *major, int *minor); + +static int +yaml_parser_scan_version_directive_number(yaml_parser_t *parser, + yaml_mark_t start_mark, int *number); + +static int +yaml_parser_scan_tag_directive_value(yaml_parser_t *parser, + yaml_mark_t mark, yaml_char_t **handle, yaml_char_t **prefix); + +static int +yaml_parser_scan_anchor(yaml_parser_t *parser, yaml_token_t *token, + yaml_token_type_t type); + +static int +yaml_parser_scan_tag(yaml_parser_t *parser, yaml_token_t *token); + +static int +yaml_parser_scan_tag_handle(yaml_parser_t *parser, int directive, + yaml_mark_t start_mark, yaml_char_t **handle); + +static int +yaml_parser_scan_tag_uri(yaml_parser_t *parser, int directive, + yaml_char_t *head, yaml_mark_t start_mark, yaml_char_t **uri); + +static int +yaml_parser_scan_uri_escapes(yaml_parser_t *parser, int directive, + yaml_mark_t start_mark, yaml_string_t *string); + +static int +yaml_parser_scan_block_scalar(yaml_parser_t *parser, yaml_token_t *token, + int literal); + +static int +yaml_parser_scan_block_scalar_breaks(yaml_parser_t *parser, + int *indent, yaml_string_t *breaks, + yaml_mark_t start_mark, yaml_mark_t *end_mark); + +static int +yaml_parser_scan_flow_scalar(yaml_parser_t *parser, yaml_token_t *token, + int single); + +static int +yaml_parser_scan_plain_scalar(yaml_parser_t *parser, yaml_token_t *token); + +/* + * Get the next token. + */ + +YAML_DECLARE(int) +yaml_parser_scan(yaml_parser_t *parser, yaml_token_t *token) +{ + assert(parser); /* Non-NULL parser object is expected. */ + assert(token); /* Non-NULL token object is expected. */ + + /* Erase the token object. */ + + memset(token, 0, sizeof(yaml_token_t)); + + /* No tokens after STREAM-END or error. */ + + if (parser->stream_end_produced || parser->error) { + return 1; + } + + /* Ensure that the tokens queue contains enough tokens. */ + + if (!parser->token_available) { + if (!yaml_parser_fetch_more_tokens(parser)) + return 0; + } + + /* Fetch the next token from the queue. */ + + *token = DEQUEUE(parser, parser->tokens); + parser->token_available = 0; + parser->tokens_parsed ++; + + if (token->type == YAML_STREAM_END_TOKEN) { + parser->stream_end_produced = 1; + } + + return 1; +} + +/* + * Set the scanner error and return 0. + */ + +static int +yaml_parser_set_scanner_error(yaml_parser_t *parser, const char *context, + yaml_mark_t context_mark, const char *problem) +{ + parser->error = YAML_SCANNER_ERROR; + parser->context = context; + parser->context_mark = context_mark; + parser->problem = problem; + parser->problem_mark = parser->mark; + + return 0; +} + +/* + * Ensure that the tokens queue contains at least one token which can be + * returned to the Parser. + */ + +YAML_DECLARE(int) +yaml_parser_fetch_more_tokens(yaml_parser_t *parser) +{ + int need_more_tokens; + + /* While we need more tokens to fetch, do it. */ + + while (1) + { + /* + * Check if we really need to fetch more tokens. + */ + + need_more_tokens = 0; + + if (parser->tokens.head == parser->tokens.tail) + { + /* Queue is empty. */ + + need_more_tokens = 1; + } + else + { + yaml_simple_key_t *simple_key; + + /* Check if any potential simple key may occupy the head position. */ + + if (!yaml_parser_stale_simple_keys(parser)) + return 0; + + for (simple_key = parser->simple_keys.start; + simple_key != parser->simple_keys.top; simple_key++) { + if (simple_key->possible + && simple_key->token_number == parser->tokens_parsed) { + need_more_tokens = 1; + break; + } + } + } + + /* We are finished. */ + + if (!need_more_tokens) + break; + + /* Fetch the next token. */ + + if (!yaml_parser_fetch_next_token(parser)) + return 0; + } + + parser->token_available = 1; + + return 1; +} + +/* + * The dispatcher for token fetchers. + */ + +static int +yaml_parser_fetch_next_token(yaml_parser_t *parser) +{ + /* Ensure that the buffer is initialized. */ + + if (!CACHE(parser, 1)) + return 0; + + /* Check if we just started scanning. Fetch STREAM-START then. */ + + if (!parser->stream_start_produced) + return yaml_parser_fetch_stream_start(parser); + + /* Eat whitespaces and comments until we reach the next token. */ + + if (!yaml_parser_scan_to_next_token(parser)) + return 0; + + /* Remove obsolete potential simple keys. */ + + if (!yaml_parser_stale_simple_keys(parser)) + return 0; + + /* Check the indentation level against the current column. */ + + if (!yaml_parser_unroll_indent(parser, parser->mark.column)) + return 0; + + /* + * Ensure that the buffer contains at least 4 characters. 4 is the length + * of the longest indicators ('--- ' and '... '). + */ + + if (!CACHE(parser, 4)) + return 0; + + /* Is it the end of the stream? */ + + if (IS_Z(parser->buffer)) + return yaml_parser_fetch_stream_end(parser); + + /* Is it a directive? */ + + if (parser->mark.column == 0 && CHECK(parser->buffer, '%')) + return yaml_parser_fetch_directive(parser); + + /* Is it the document start indicator? */ + + if (parser->mark.column == 0 + && CHECK_AT(parser->buffer, '-', 0) + && CHECK_AT(parser->buffer, '-', 1) + && CHECK_AT(parser->buffer, '-', 2) + && IS_BLANKZ_AT(parser->buffer, 3)) + return yaml_parser_fetch_document_indicator(parser, + YAML_DOCUMENT_START_TOKEN); + + /* Is it the document end indicator? */ + + if (parser->mark.column == 0 + && CHECK_AT(parser->buffer, '.', 0) + && CHECK_AT(parser->buffer, '.', 1) + && CHECK_AT(parser->buffer, '.', 2) + && IS_BLANKZ_AT(parser->buffer, 3)) + return yaml_parser_fetch_document_indicator(parser, + YAML_DOCUMENT_END_TOKEN); + + /* Is it the flow sequence start indicator? */ + + if (CHECK(parser->buffer, '[')) + return yaml_parser_fetch_flow_collection_start(parser, + YAML_FLOW_SEQUENCE_START_TOKEN); + + /* Is it the flow mapping start indicator? */ + + if (CHECK(parser->buffer, '{')) + return yaml_parser_fetch_flow_collection_start(parser, + YAML_FLOW_MAPPING_START_TOKEN); + + /* Is it the flow sequence end indicator? */ + + if (CHECK(parser->buffer, ']')) + return yaml_parser_fetch_flow_collection_end(parser, + YAML_FLOW_SEQUENCE_END_TOKEN); + + /* Is it the flow mapping end indicator? */ + + if (CHECK(parser->buffer, '}')) + return yaml_parser_fetch_flow_collection_end(parser, + YAML_FLOW_MAPPING_END_TOKEN); + + /* Is it the flow entry indicator? */ + + if (CHECK(parser->buffer, ',')) + return yaml_parser_fetch_flow_entry(parser); + + /* Is it the block entry indicator? */ + + if (CHECK(parser->buffer, '-') && IS_BLANKZ_AT(parser->buffer, 1)) + return yaml_parser_fetch_block_entry(parser); + + /* Is it the key indicator? */ + + if (CHECK(parser->buffer, '?') + && (parser->flow_level || IS_BLANKZ_AT(parser->buffer, 1))) + return yaml_parser_fetch_key(parser); + + /* Is it the value indicator? */ + + if (CHECK(parser->buffer, ':') + && (parser->flow_level || IS_BLANKZ_AT(parser->buffer, 1))) + return yaml_parser_fetch_value(parser); + + /* Is it an alias? */ + + if (CHECK(parser->buffer, '*')) + return yaml_parser_fetch_anchor(parser, YAML_ALIAS_TOKEN); + + /* Is it an anchor? */ + + if (CHECK(parser->buffer, '&')) + return yaml_parser_fetch_anchor(parser, YAML_ANCHOR_TOKEN); + + /* Is it a tag? */ + + if (CHECK(parser->buffer, '!')) + return yaml_parser_fetch_tag(parser); + + /* Is it a literal scalar? */ + + if (CHECK(parser->buffer, '|') && !parser->flow_level) + return yaml_parser_fetch_block_scalar(parser, 1); + + /* Is it a folded scalar? */ + + if (CHECK(parser->buffer, '>') && !parser->flow_level) + return yaml_parser_fetch_block_scalar(parser, 0); + + /* Is it a single-quoted scalar? */ + + if (CHECK(parser->buffer, '\'')) + return yaml_parser_fetch_flow_scalar(parser, 1); + + /* Is it a double-quoted scalar? */ + + if (CHECK(parser->buffer, '"')) + return yaml_parser_fetch_flow_scalar(parser, 0); + + /* + * Is it a plain scalar? + * + * A plain scalar may start with any non-blank characters except + * + * '-', '?', ':', ',', '[', ']', '{', '}', + * '#', '&', '*', '!', '|', '>', '\'', '\"', + * '%', '@', '`'. + * + * In the block context (and, for the '-' indicator, in the flow context + * too), it may also start with the characters + * + * '-', '?', ':' + * + * if it is followed by a non-space character. + * + * The last rule is more restrictive than the specification requires. + */ + + if (!(IS_BLANKZ(parser->buffer) || CHECK(parser->buffer, '-') + || CHECK(parser->buffer, '?') || CHECK(parser->buffer, ':') + || CHECK(parser->buffer, ',') || CHECK(parser->buffer, '[') + || CHECK(parser->buffer, ']') || CHECK(parser->buffer, '{') + || CHECK(parser->buffer, '}') || CHECK(parser->buffer, '#') + || CHECK(parser->buffer, '&') || CHECK(parser->buffer, '*') + || CHECK(parser->buffer, '!') || CHECK(parser->buffer, '|') + || CHECK(parser->buffer, '>') || CHECK(parser->buffer, '\'') + || CHECK(parser->buffer, '"') || CHECK(parser->buffer, '%') + || CHECK(parser->buffer, '@') || CHECK(parser->buffer, '`')) || + (CHECK(parser->buffer, '-') && !IS_BLANK_AT(parser->buffer, 1)) || + (!parser->flow_level && + (CHECK(parser->buffer, '?') || CHECK(parser->buffer, ':')) + && !IS_BLANKZ_AT(parser->buffer, 1))) + return yaml_parser_fetch_plain_scalar(parser); + + /* + * If we don't determine the token type so far, it is an error. + */ + + return yaml_parser_set_scanner_error(parser, + "while scanning for the next token", parser->mark, + "found character that cannot start any token"); +} + +/* + * Check the list of potential simple keys and remove the positions that + * cannot contain simple keys anymore. + */ + +static int +yaml_parser_stale_simple_keys(yaml_parser_t *parser) +{ + yaml_simple_key_t *simple_key; + + /* Check for a potential simple key for each flow level. */ + + for (simple_key = parser->simple_keys.start; + simple_key != parser->simple_keys.top; simple_key ++) + { + /* + * The specification requires that a simple key + * + * - is limited to a single line, + * - is shorter than 1024 characters. + */ + + if (simple_key->possible + && (simple_key->mark.line < parser->mark.line + || simple_key->mark.index+1024 < parser->mark.index)) { + + /* Check if the potential simple key to be removed is required. */ + + if (simple_key->required) { + return yaml_parser_set_scanner_error(parser, + "while scanning a simple key", simple_key->mark, + "could not find expected ':'"); + } + + simple_key->possible = 0; + } + } + + return 1; +} + +/* + * Check if a simple key may start at the current position and add it if + * needed. + */ + +static int +yaml_parser_save_simple_key(yaml_parser_t *parser) +{ + /* + * A simple key is required at the current position if the scanner is in + * the block context and the current column coincides with the indentation + * level. + */ + + int required = (!parser->flow_level + && parser->indent == (ptrdiff_t)parser->mark.column); + + /* + * A simple key is required only when it is the first token in the current + * line. Therefore it is always allowed. But we add a check anyway. + */ + + assert(parser->simple_key_allowed || !required); /* Impossible. */ + + /* + * If the current position may start a simple key, save it. + */ + + if (parser->simple_key_allowed) + { + yaml_simple_key_t simple_key; + simple_key.possible = 1; + simple_key.required = required; + simple_key.token_number = + parser->tokens_parsed + (parser->tokens.tail - parser->tokens.head); + simple_key.mark = parser->mark; + + if (!yaml_parser_remove_simple_key(parser)) return 0; + + *(parser->simple_keys.top-1) = simple_key; + } + + return 1; +} + +/* + * Remove a potential simple key at the current flow level. + */ + +static int +yaml_parser_remove_simple_key(yaml_parser_t *parser) +{ + yaml_simple_key_t *simple_key = parser->simple_keys.top-1; + + if (simple_key->possible) + { + /* If the key is required, it is an error. */ + + if (simple_key->required) { + return yaml_parser_set_scanner_error(parser, + "while scanning a simple key", simple_key->mark, + "could not find expected ':'"); + } + } + + /* Remove the key from the stack. */ + + simple_key->possible = 0; + + return 1; +} + +/* + * Increase the flow level and resize the simple key list if needed. + */ + +static int +yaml_parser_increase_flow_level(yaml_parser_t *parser) +{ + yaml_simple_key_t empty_simple_key = { 0, 0, 0, { 0, 0, 0 } }; + + /* Reset the simple key on the next level. */ + + if (!PUSH(parser, parser->simple_keys, empty_simple_key)) + return 0; + + /* Increase the flow level. */ + + if (parser->flow_level == INT_MAX) { + parser->error = YAML_MEMORY_ERROR; + return 0; + } + + parser->flow_level++; + + return 1; +} + +/* + * Decrease the flow level. + */ + +static int +yaml_parser_decrease_flow_level(yaml_parser_t *parser) +{ + yaml_simple_key_t dummy_key; /* Used to eliminate a compiler warning. */ + + if (parser->flow_level) { + parser->flow_level --; + dummy_key = POP(parser, parser->simple_keys); + } + + return 1; +} + +/* + * Push the current indentation level to the stack and set the new level + * the current column is greater than the indentation level. In this case, + * append or insert the specified token into the token queue. + * + */ + +static int +yaml_parser_roll_indent(yaml_parser_t *parser, ptrdiff_t column, + ptrdiff_t number, yaml_token_type_t type, yaml_mark_t mark) +{ + yaml_token_t token; + + /* In the flow context, do nothing. */ + + if (parser->flow_level) + return 1; + + if (parser->indent < column) + { + /* + * Push the current indentation level to the stack and set the new + * indentation level. + */ + + if (!PUSH(parser, parser->indents, parser->indent)) + return 0; + + if (column > INT_MAX) { + parser->error = YAML_MEMORY_ERROR; + return 0; + } + + parser->indent = column; + + /* Create a token and insert it into the queue. */ + + TOKEN_INIT(token, type, mark, mark); + + if (number == -1) { + if (!ENQUEUE(parser, parser->tokens, token)) + return 0; + } + else { + if (!QUEUE_INSERT(parser, + parser->tokens, number - parser->tokens_parsed, token)) + return 0; + } + } + + return 1; +} + +/* + * Pop indentation levels from the indents stack until the current level + * becomes less or equal to the column. For each intendation level, append + * the BLOCK-END token. + */ + + +static int +yaml_parser_unroll_indent(yaml_parser_t *parser, ptrdiff_t column) +{ + yaml_token_t token; + + /* In the flow context, do nothing. */ + + if (parser->flow_level) + return 1; + + /* Loop through the intendation levels in the stack. */ + + while (parser->indent > column) + { + /* Create a token and append it to the queue. */ + + TOKEN_INIT(token, YAML_BLOCK_END_TOKEN, parser->mark, parser->mark); + + if (!ENQUEUE(parser, parser->tokens, token)) + return 0; + + /* Pop the indentation level. */ + + parser->indent = POP(parser, parser->indents); + } + + return 1; +} + +/* + * Initialize the scanner and produce the STREAM-START token. + */ + +static int +yaml_parser_fetch_stream_start(yaml_parser_t *parser) +{ + yaml_simple_key_t simple_key = { 0, 0, 0, { 0, 0, 0 } }; + yaml_token_t token; + + /* Set the initial indentation. */ + + parser->indent = -1; + + /* Initialize the simple key stack. */ + + if (!PUSH(parser, parser->simple_keys, simple_key)) + return 0; + + /* A simple key is allowed at the beginning of the stream. */ + + parser->simple_key_allowed = 1; + + /* We have started. */ + + parser->stream_start_produced = 1; + + /* Create the STREAM-START token and append it to the queue. */ + + STREAM_START_TOKEN_INIT(token, parser->encoding, + parser->mark, parser->mark); + + if (!ENQUEUE(parser, parser->tokens, token)) + return 0; + + return 1; +} + +/* + * Produce the STREAM-END token and shut down the scanner. + */ + +static int +yaml_parser_fetch_stream_end(yaml_parser_t *parser) +{ + yaml_token_t token; + + /* Force new line. */ + + if (parser->mark.column != 0) { + parser->mark.column = 0; + parser->mark.line ++; + } + + /* Reset the indentation level. */ + + if (!yaml_parser_unroll_indent(parser, -1)) + return 0; + + /* Reset simple keys. */ + + if (!yaml_parser_remove_simple_key(parser)) + return 0; + + parser->simple_key_allowed = 0; + + /* Create the STREAM-END token and append it to the queue. */ + + STREAM_END_TOKEN_INIT(token, parser->mark, parser->mark); + + if (!ENQUEUE(parser, parser->tokens, token)) + return 0; + + return 1; +} + +/* + * Produce a VERSION-DIRECTIVE or TAG-DIRECTIVE token. + */ + +static int +yaml_parser_fetch_directive(yaml_parser_t *parser) +{ + yaml_token_t token; + + /* Reset the indentation level. */ + + if (!yaml_parser_unroll_indent(parser, -1)) + return 0; + + /* Reset simple keys. */ + + if (!yaml_parser_remove_simple_key(parser)) + return 0; + + parser->simple_key_allowed = 0; + + /* Create the YAML-DIRECTIVE or TAG-DIRECTIVE token. */ + + if (!yaml_parser_scan_directive(parser, &token)) + return 0; + + /* Append the token to the queue. */ + + if (!ENQUEUE(parser, parser->tokens, token)) { + yaml_token_delete(&token); + return 0; + } + + return 1; +} + +/* + * Produce the DOCUMENT-START or DOCUMENT-END token. + */ + +static int +yaml_parser_fetch_document_indicator(yaml_parser_t *parser, + yaml_token_type_t type) +{ + yaml_mark_t start_mark, end_mark; + yaml_token_t token; + + /* Reset the indentation level. */ + + if (!yaml_parser_unroll_indent(parser, -1)) + return 0; + + /* Reset simple keys. */ + + if (!yaml_parser_remove_simple_key(parser)) + return 0; + + parser->simple_key_allowed = 0; + + /* Consume the token. */ + + start_mark = parser->mark; + + SKIP(parser); + SKIP(parser); + SKIP(parser); + + end_mark = parser->mark; + + /* Create the DOCUMENT-START or DOCUMENT-END token. */ + + TOKEN_INIT(token, type, start_mark, end_mark); + + /* Append the token to the queue. */ + + if (!ENQUEUE(parser, parser->tokens, token)) + return 0; + + return 1; +} + +/* + * Produce the FLOW-SEQUENCE-START or FLOW-MAPPING-START token. + */ + +static int +yaml_parser_fetch_flow_collection_start(yaml_parser_t *parser, + yaml_token_type_t type) +{ + yaml_mark_t start_mark, end_mark; + yaml_token_t token; + + /* The indicators '[' and '{' may start a simple key. */ + + if (!yaml_parser_save_simple_key(parser)) + return 0; + + /* Increase the flow level. */ + + if (!yaml_parser_increase_flow_level(parser)) + return 0; + + /* A simple key may follow the indicators '[' and '{'. */ + + parser->simple_key_allowed = 1; + + /* Consume the token. */ + + start_mark = parser->mark; + SKIP(parser); + end_mark = parser->mark; + + /* Create the FLOW-SEQUENCE-START of FLOW-MAPPING-START token. */ + + TOKEN_INIT(token, type, start_mark, end_mark); + + /* Append the token to the queue. */ + + if (!ENQUEUE(parser, parser->tokens, token)) + return 0; + + return 1; +} + +/* + * Produce the FLOW-SEQUENCE-END or FLOW-MAPPING-END token. + */ + +static int +yaml_parser_fetch_flow_collection_end(yaml_parser_t *parser, + yaml_token_type_t type) +{ + yaml_mark_t start_mark, end_mark; + yaml_token_t token; + + /* Reset any potential simple key on the current flow level. */ + + if (!yaml_parser_remove_simple_key(parser)) + return 0; + + /* Decrease the flow level. */ + + if (!yaml_parser_decrease_flow_level(parser)) + return 0; + + /* No simple keys after the indicators ']' and '}'. */ + + parser->simple_key_allowed = 0; + + /* Consume the token. */ + + start_mark = parser->mark; + SKIP(parser); + end_mark = parser->mark; + + /* Create the FLOW-SEQUENCE-END of FLOW-MAPPING-END token. */ + + TOKEN_INIT(token, type, start_mark, end_mark); + + /* Append the token to the queue. */ + + if (!ENQUEUE(parser, parser->tokens, token)) + return 0; + + return 1; +} + +/* + * Produce the FLOW-ENTRY token. + */ + +static int +yaml_parser_fetch_flow_entry(yaml_parser_t *parser) +{ + yaml_mark_t start_mark, end_mark; + yaml_token_t token; + + /* Reset any potential simple keys on the current flow level. */ + + if (!yaml_parser_remove_simple_key(parser)) + return 0; + + /* Simple keys are allowed after ','. */ + + parser->simple_key_allowed = 1; + + /* Consume the token. */ + + start_mark = parser->mark; + SKIP(parser); + end_mark = parser->mark; + + /* Create the FLOW-ENTRY token and append it to the queue. */ + + TOKEN_INIT(token, YAML_FLOW_ENTRY_TOKEN, start_mark, end_mark); + + if (!ENQUEUE(parser, parser->tokens, token)) + return 0; + + return 1; +} + +/* + * Produce the BLOCK-ENTRY token. + */ + +static int +yaml_parser_fetch_block_entry(yaml_parser_t *parser) +{ + yaml_mark_t start_mark, end_mark; + yaml_token_t token; + + /* Check if the scanner is in the block context. */ + + if (!parser->flow_level) + { + /* Check if we are allowed to start a new entry. */ + + if (!parser->simple_key_allowed) { + return yaml_parser_set_scanner_error(parser, NULL, parser->mark, + "block sequence entries are not allowed in this context"); + } + + /* Add the BLOCK-SEQUENCE-START token if needed. */ + + if (!yaml_parser_roll_indent(parser, parser->mark.column, -1, + YAML_BLOCK_SEQUENCE_START_TOKEN, parser->mark)) + return 0; + } + else + { + /* + * It is an error for the '-' indicator to occur in the flow context, + * but we let the Parser detect and report about it because the Parser + * is able to point to the context. + */ + } + + /* Reset any potential simple keys on the current flow level. */ + + if (!yaml_parser_remove_simple_key(parser)) + return 0; + + /* Simple keys are allowed after '-'. */ + + parser->simple_key_allowed = 1; + + /* Consume the token. */ + + start_mark = parser->mark; + SKIP(parser); + end_mark = parser->mark; + + /* Create the BLOCK-ENTRY token and append it to the queue. */ + + TOKEN_INIT(token, YAML_BLOCK_ENTRY_TOKEN, start_mark, end_mark); + + if (!ENQUEUE(parser, parser->tokens, token)) + return 0; + + return 1; +} + +/* + * Produce the KEY token. + */ + +static int +yaml_parser_fetch_key(yaml_parser_t *parser) +{ + yaml_mark_t start_mark, end_mark; + yaml_token_t token; + + /* In the block context, additional checks are required. */ + + if (!parser->flow_level) + { + /* Check if we are allowed to start a new key (not nessesary simple). */ + + if (!parser->simple_key_allowed) { + return yaml_parser_set_scanner_error(parser, NULL, parser->mark, + "mapping keys are not allowed in this context"); + } + + /* Add the BLOCK-MAPPING-START token if needed. */ + + if (!yaml_parser_roll_indent(parser, parser->mark.column, -1, + YAML_BLOCK_MAPPING_START_TOKEN, parser->mark)) + return 0; + } + + /* Reset any potential simple keys on the current flow level. */ + + if (!yaml_parser_remove_simple_key(parser)) + return 0; + + /* Simple keys are allowed after '?' in the block context. */ + + parser->simple_key_allowed = (!parser->flow_level); + + /* Consume the token. */ + + start_mark = parser->mark; + SKIP(parser); + end_mark = parser->mark; + + /* Create the KEY token and append it to the queue. */ + + TOKEN_INIT(token, YAML_KEY_TOKEN, start_mark, end_mark); + + if (!ENQUEUE(parser, parser->tokens, token)) + return 0; + + return 1; +} + +/* + * Produce the VALUE token. + */ + +static int +yaml_parser_fetch_value(yaml_parser_t *parser) +{ + yaml_mark_t start_mark, end_mark; + yaml_token_t token; + yaml_simple_key_t *simple_key = parser->simple_keys.top-1; + + /* Have we found a simple key? */ + + if (simple_key->possible) + { + + /* Create the KEY token and insert it into the queue. */ + + TOKEN_INIT(token, YAML_KEY_TOKEN, simple_key->mark, simple_key->mark); + + if (!QUEUE_INSERT(parser, parser->tokens, + simple_key->token_number - parser->tokens_parsed, token)) + return 0; + + /* In the block context, we may need to add the BLOCK-MAPPING-START token. */ + + if (!yaml_parser_roll_indent(parser, simple_key->mark.column, + simple_key->token_number, + YAML_BLOCK_MAPPING_START_TOKEN, simple_key->mark)) + return 0; + + /* Remove the simple key. */ + + simple_key->possible = 0; + + /* A simple key cannot follow another simple key. */ + + parser->simple_key_allowed = 0; + } + else + { + /* The ':' indicator follows a complex key. */ + + /* In the block context, extra checks are required. */ + + if (!parser->flow_level) + { + /* Check if we are allowed to start a complex value. */ + + if (!parser->simple_key_allowed) { + return yaml_parser_set_scanner_error(parser, NULL, parser->mark, + "mapping values are not allowed in this context"); + } + + /* Add the BLOCK-MAPPING-START token if needed. */ + + if (!yaml_parser_roll_indent(parser, parser->mark.column, -1, + YAML_BLOCK_MAPPING_START_TOKEN, parser->mark)) + return 0; + } + + /* Simple keys after ':' are allowed in the block context. */ + + parser->simple_key_allowed = (!parser->flow_level); + } + + /* Consume the token. */ + + start_mark = parser->mark; + SKIP(parser); + end_mark = parser->mark; + + /* Create the VALUE token and append it to the queue. */ + + TOKEN_INIT(token, YAML_VALUE_TOKEN, start_mark, end_mark); + + if (!ENQUEUE(parser, parser->tokens, token)) + return 0; + + return 1; +} + +/* + * Produce the ALIAS or ANCHOR token. + */ + +static int +yaml_parser_fetch_anchor(yaml_parser_t *parser, yaml_token_type_t type) +{ + yaml_token_t token; + + /* An anchor or an alias could be a simple key. */ + + if (!yaml_parser_save_simple_key(parser)) + return 0; + + /* A simple key cannot follow an anchor or an alias. */ + + parser->simple_key_allowed = 0; + + /* Create the ALIAS or ANCHOR token and append it to the queue. */ + + if (!yaml_parser_scan_anchor(parser, &token, type)) + return 0; + + if (!ENQUEUE(parser, parser->tokens, token)) { + yaml_token_delete(&token); + return 0; + } + return 1; +} + +/* + * Produce the TAG token. + */ + +static int +yaml_parser_fetch_tag(yaml_parser_t *parser) +{ + yaml_token_t token; + + /* A tag could be a simple key. */ + + if (!yaml_parser_save_simple_key(parser)) + return 0; + + /* A simple key cannot follow a tag. */ + + parser->simple_key_allowed = 0; + + /* Create the TAG token and append it to the queue. */ + + if (!yaml_parser_scan_tag(parser, &token)) + return 0; + + if (!ENQUEUE(parser, parser->tokens, token)) { + yaml_token_delete(&token); + return 0; + } + + return 1; +} + +/* + * Produce the SCALAR(...,literal) or SCALAR(...,folded) tokens. + */ + +static int +yaml_parser_fetch_block_scalar(yaml_parser_t *parser, int literal) +{ + yaml_token_t token; + + /* Remove any potential simple keys. */ + + if (!yaml_parser_remove_simple_key(parser)) + return 0; + + /* A simple key may follow a block scalar. */ + + parser->simple_key_allowed = 1; + + /* Create the SCALAR token and append it to the queue. */ + + if (!yaml_parser_scan_block_scalar(parser, &token, literal)) + return 0; + + if (!ENQUEUE(parser, parser->tokens, token)) { + yaml_token_delete(&token); + return 0; + } + + return 1; +} + +/* + * Produce the SCALAR(...,single-quoted) or SCALAR(...,double-quoted) tokens. + */ + +static int +yaml_parser_fetch_flow_scalar(yaml_parser_t *parser, int single) +{ + yaml_token_t token; + + /* A plain scalar could be a simple key. */ + + if (!yaml_parser_save_simple_key(parser)) + return 0; + + /* A simple key cannot follow a flow scalar. */ + + parser->simple_key_allowed = 0; + + /* Create the SCALAR token and append it to the queue. */ + + if (!yaml_parser_scan_flow_scalar(parser, &token, single)) + return 0; + + if (!ENQUEUE(parser, parser->tokens, token)) { + yaml_token_delete(&token); + return 0; + } + + return 1; +} + +/* + * Produce the SCALAR(...,plain) token. + */ + +static int +yaml_parser_fetch_plain_scalar(yaml_parser_t *parser) +{ + yaml_token_t token; + + /* A plain scalar could be a simple key. */ + + if (!yaml_parser_save_simple_key(parser)) + return 0; + + /* A simple key cannot follow a flow scalar. */ + + parser->simple_key_allowed = 0; + + /* Create the SCALAR token and append it to the queue. */ + + if (!yaml_parser_scan_plain_scalar(parser, &token)) + return 0; + + if (!ENQUEUE(parser, parser->tokens, token)) { + yaml_token_delete(&token); + return 0; + } + + return 1; +} + +/* + * Eat whitespaces and comments until the next token is found. + */ + +static int +yaml_parser_scan_to_next_token(yaml_parser_t *parser) +{ + /* Until the next token is not found. */ + + while (1) + { + /* Allow the BOM mark to start a line. */ + + if (!CACHE(parser, 1)) return 0; + + if (parser->mark.column == 0 && IS_BOM(parser->buffer)) + SKIP(parser); + + /* + * Eat whitespaces. + * + * Tabs are allowed: + * + * - in the flow context; + * - in the block context, but not at the beginning of the line or + * after '-', '?', or ':' (complex value). + */ + + if (!CACHE(parser, 1)) return 0; + + while (CHECK(parser->buffer,' ') || + ((parser->flow_level || !parser->simple_key_allowed) && + CHECK(parser->buffer, '\t'))) { + SKIP(parser); + if (!CACHE(parser, 1)) return 0; + } + + /* Eat a comment until a line break. */ + + if (CHECK(parser->buffer, '#')) { + while (!IS_BREAKZ(parser->buffer)) { + SKIP(parser); + if (!CACHE(parser, 1)) return 0; + } + } + + /* If it is a line break, eat it. */ + + if (IS_BREAK(parser->buffer)) + { + if (!CACHE(parser, 2)) return 0; + SKIP_LINE(parser); + + /* In the block context, a new line may start a simple key. */ + + if (!parser->flow_level) { + parser->simple_key_allowed = 1; + } + } + else + { + /* We have found a token. */ + + break; + } + } + + return 1; +} + +/* + * Scan a YAML-DIRECTIVE or TAG-DIRECTIVE token. + * + * Scope: + * %YAML 1.1 # a comment \n + * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + * %TAG !yaml! tag:yaml.org,2002: \n + * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + */ + +int +yaml_parser_scan_directive(yaml_parser_t *parser, yaml_token_t *token) +{ + yaml_mark_t start_mark, end_mark; + yaml_char_t *name = NULL; + int major, minor; + yaml_char_t *handle = NULL, *prefix = NULL; + + /* Eat '%'. */ + + start_mark = parser->mark; + + SKIP(parser); + + /* Scan the directive name. */ + + if (!yaml_parser_scan_directive_name(parser, start_mark, &name)) + goto error; + + /* Is it a YAML directive? */ + + if (strcmp((char *)name, "YAML") == 0) + { + /* Scan the VERSION directive value. */ + + if (!yaml_parser_scan_version_directive_value(parser, start_mark, + &major, &minor)) + goto error; + + end_mark = parser->mark; + + /* Create a VERSION-DIRECTIVE token. */ + + VERSION_DIRECTIVE_TOKEN_INIT(*token, major, minor, + start_mark, end_mark); + } + + /* Is it a TAG directive? */ + + else if (strcmp((char *)name, "TAG") == 0) + { + /* Scan the TAG directive value. */ + + if (!yaml_parser_scan_tag_directive_value(parser, start_mark, + &handle, &prefix)) + goto error; + + end_mark = parser->mark; + + /* Create a TAG-DIRECTIVE token. */ + + TAG_DIRECTIVE_TOKEN_INIT(*token, handle, prefix, + start_mark, end_mark); + } + + /* Unknown directive. */ + + else + { + yaml_parser_set_scanner_error(parser, "while scanning a directive", + start_mark, "found uknown directive name"); + goto error; + } + + /* Eat the rest of the line including any comments. */ + + if (!CACHE(parser, 1)) goto error; + + while (IS_BLANK(parser->buffer)) { + SKIP(parser); + if (!CACHE(parser, 1)) goto error; + } + + if (CHECK(parser->buffer, '#')) { + while (!IS_BREAKZ(parser->buffer)) { + SKIP(parser); + if (!CACHE(parser, 1)) goto error; + } + } + + /* Check if we are at the end of the line. */ + + if (!IS_BREAKZ(parser->buffer)) { + yaml_parser_set_scanner_error(parser, "while scanning a directive", + start_mark, "did not find expected comment or line break"); + goto error; + } + + /* Eat a line break. */ + + if (IS_BREAK(parser->buffer)) { + if (!CACHE(parser, 2)) goto error; + SKIP_LINE(parser); + } + + yaml_free(name); + + return 1; + +error: + yaml_free(prefix); + yaml_free(handle); + yaml_free(name); + return 0; +} + +/* + * Scan the directive name. + * + * Scope: + * %YAML 1.1 # a comment \n + * ^^^^ + * %TAG !yaml! tag:yaml.org,2002: \n + * ^^^ + */ + +static int +yaml_parser_scan_directive_name(yaml_parser_t *parser, + yaml_mark_t start_mark, yaml_char_t **name) +{ + yaml_string_t string = NULL_STRING; + + if (!STRING_INIT(parser, string, INITIAL_STRING_SIZE)) goto error; + + /* Consume the directive name. */ + + if (!CACHE(parser, 1)) goto error; + + while (IS_ALPHA(parser->buffer)) + { + if (!READ(parser, string)) goto error; + if (!CACHE(parser, 1)) goto error; + } + + /* Check if the name is empty. */ + + if (string.start == string.pointer) { + yaml_parser_set_scanner_error(parser, "while scanning a directive", + start_mark, "could not find expected directive name"); + goto error; + } + + /* Check for an blank character after the name. */ + + if (!IS_BLANKZ(parser->buffer)) { + yaml_parser_set_scanner_error(parser, "while scanning a directive", + start_mark, "found unexpected non-alphabetical character"); + goto error; + } + + *name = string.start; + + return 1; + +error: + STRING_DEL(parser, string); + return 0; +} + +/* + * Scan the value of VERSION-DIRECTIVE. + * + * Scope: + * %YAML 1.1 # a comment \n + * ^^^^^^ + */ + +static int +yaml_parser_scan_version_directive_value(yaml_parser_t *parser, + yaml_mark_t start_mark, int *major, int *minor) +{ + /* Eat whitespaces. */ + + if (!CACHE(parser, 1)) return 0; + + while (IS_BLANK(parser->buffer)) { + SKIP(parser); + if (!CACHE(parser, 1)) return 0; + } + + /* Consume the major version number. */ + + if (!yaml_parser_scan_version_directive_number(parser, start_mark, major)) + return 0; + + /* Eat '.'. */ + + if (!CHECK(parser->buffer, '.')) { + return yaml_parser_set_scanner_error(parser, "while scanning a %YAML directive", + start_mark, "did not find expected digit or '.' character"); + } + + SKIP(parser); + + /* Consume the minor version number. */ + + if (!yaml_parser_scan_version_directive_number(parser, start_mark, minor)) + return 0; + + return 1; +} + +#define MAX_NUMBER_LENGTH 9 + +/* + * Scan the version number of VERSION-DIRECTIVE. + * + * Scope: + * %YAML 1.1 # a comment \n + * ^ + * %YAML 1.1 # a comment \n + * ^ + */ + +static int +yaml_parser_scan_version_directive_number(yaml_parser_t *parser, + yaml_mark_t start_mark, int *number) +{ + int value = 0; + size_t length = 0; + + /* Repeat while the next character is digit. */ + + if (!CACHE(parser, 1)) return 0; + + while (IS_DIGIT(parser->buffer)) + { + /* Check if the number is too long. */ + + if (++length > MAX_NUMBER_LENGTH) { + return yaml_parser_set_scanner_error(parser, "while scanning a %YAML directive", + start_mark, "found extremely long version number"); + } + + value = value*10 + AS_DIGIT(parser->buffer); + + SKIP(parser); + + if (!CACHE(parser, 1)) return 0; + } + + /* Check if the number was present. */ + + if (!length) { + return yaml_parser_set_scanner_error(parser, "while scanning a %YAML directive", + start_mark, "did not find expected version number"); + } + + *number = value; + + return 1; +} + +/* + * Scan the value of a TAG-DIRECTIVE token. + * + * Scope: + * %TAG !yaml! tag:yaml.org,2002: \n + * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + */ + +static int +yaml_parser_scan_tag_directive_value(yaml_parser_t *parser, + yaml_mark_t start_mark, yaml_char_t **handle, yaml_char_t **prefix) +{ + yaml_char_t *handle_value = NULL; + yaml_char_t *prefix_value = NULL; + + /* Eat whitespaces. */ + + if (!CACHE(parser, 1)) goto error; + + while (IS_BLANK(parser->buffer)) { + SKIP(parser); + if (!CACHE(parser, 1)) goto error; + } + + /* Scan a handle. */ + + if (!yaml_parser_scan_tag_handle(parser, 1, start_mark, &handle_value)) + goto error; + + /* Expect a whitespace. */ + + if (!CACHE(parser, 1)) goto error; + + if (!IS_BLANK(parser->buffer)) { + yaml_parser_set_scanner_error(parser, "while scanning a %TAG directive", + start_mark, "did not find expected whitespace"); + goto error; + } + + /* Eat whitespaces. */ + + while (IS_BLANK(parser->buffer)) { + SKIP(parser); + if (!CACHE(parser, 1)) goto error; + } + + /* Scan a prefix. */ + + if (!yaml_parser_scan_tag_uri(parser, 1, NULL, start_mark, &prefix_value)) + goto error; + + /* Expect a whitespace or line break. */ + + if (!CACHE(parser, 1)) goto error; + + if (!IS_BLANKZ(parser->buffer)) { + yaml_parser_set_scanner_error(parser, "while scanning a %TAG directive", + start_mark, "did not find expected whitespace or line break"); + goto error; + } + + *handle = handle_value; + *prefix = prefix_value; + + return 1; + +error: + yaml_free(handle_value); + yaml_free(prefix_value); + return 0; +} + +static int +yaml_parser_scan_anchor(yaml_parser_t *parser, yaml_token_t *token, + yaml_token_type_t type) +{ + int length = 0; + yaml_mark_t start_mark, end_mark; + yaml_string_t string = NULL_STRING; + + if (!STRING_INIT(parser, string, INITIAL_STRING_SIZE)) goto error; + + /* Eat the indicator character. */ + + start_mark = parser->mark; + + SKIP(parser); + + /* Consume the value. */ + + if (!CACHE(parser, 1)) goto error; + + while (IS_ALPHA(parser->buffer)) { + if (!READ(parser, string)) goto error; + if (!CACHE(parser, 1)) goto error; + length ++; + } + + end_mark = parser->mark; + + /* + * Check if length of the anchor is greater than 0 and it is followed by + * a whitespace character or one of the indicators: + * + * '?', ':', ',', ']', '}', '%', '@', '`'. + */ + + if (!length || !(IS_BLANKZ(parser->buffer) || CHECK(parser->buffer, '?') + || CHECK(parser->buffer, ':') || CHECK(parser->buffer, ',') + || CHECK(parser->buffer, ']') || CHECK(parser->buffer, '}') + || CHECK(parser->buffer, '%') || CHECK(parser->buffer, '@') + || CHECK(parser->buffer, '`'))) { + yaml_parser_set_scanner_error(parser, type == YAML_ANCHOR_TOKEN ? + "while scanning an anchor" : "while scanning an alias", start_mark, + "did not find expected alphabetic or numeric character"); + goto error; + } + + /* Create a token. */ + + if (type == YAML_ANCHOR_TOKEN) { + ANCHOR_TOKEN_INIT(*token, string.start, start_mark, end_mark); + } + else { + ALIAS_TOKEN_INIT(*token, string.start, start_mark, end_mark); + } + + return 1; + +error: + STRING_DEL(parser, string); + return 0; +} + +/* + * Scan a TAG token. + */ + +static int +yaml_parser_scan_tag(yaml_parser_t *parser, yaml_token_t *token) +{ + yaml_char_t *handle = NULL; + yaml_char_t *suffix = NULL; + yaml_mark_t start_mark, end_mark; + + start_mark = parser->mark; + + /* Check if the tag is in the canonical form. */ + + if (!CACHE(parser, 2)) goto error; + + if (CHECK_AT(parser->buffer, '<', 1)) + { + /* Set the handle to '' */ + + handle = yaml_malloc(1); + if (!handle) goto error; + handle[0] = '\0'; + + /* Eat '!<' */ + + SKIP(parser); + SKIP(parser); + + /* Consume the tag value. */ + + if (!yaml_parser_scan_tag_uri(parser, 0, NULL, start_mark, &suffix)) + goto error; + + /* Check for '>' and eat it. */ + + if (!CHECK(parser->buffer, '>')) { + yaml_parser_set_scanner_error(parser, "while scanning a tag", + start_mark, "did not find the expected '>'"); + goto error; + } + + SKIP(parser); + } + else + { + /* The tag has either the '!suffix' or the '!handle!suffix' form. */ + + /* First, try to scan a handle. */ + + if (!yaml_parser_scan_tag_handle(parser, 0, start_mark, &handle)) + goto error; + + /* Check if it is, indeed, handle. */ + + if (handle[0] == '!' && handle[1] != '\0' && handle[strlen((char *)handle)-1] == '!') + { + /* Scan the suffix now. */ + + if (!yaml_parser_scan_tag_uri(parser, 0, NULL, start_mark, &suffix)) + goto error; + } + else + { + /* It wasn't a handle after all. Scan the rest of the tag. */ + + if (!yaml_parser_scan_tag_uri(parser, 0, handle, start_mark, &suffix)) + goto error; + + /* Set the handle to '!'. */ + + yaml_free(handle); + handle = yaml_malloc(2); + if (!handle) goto error; + handle[0] = '!'; + handle[1] = '\0'; + + /* + * A special case: the '!' tag. Set the handle to '' and the + * suffix to '!'. + */ + + if (suffix[0] == '\0') { + yaml_char_t *tmp = handle; + handle = suffix; + suffix = tmp; + } + } + } + + /* Check the character which ends the tag. */ + + if (!CACHE(parser, 1)) goto error; + + if (!IS_BLANKZ(parser->buffer)) { + yaml_parser_set_scanner_error(parser, "while scanning a tag", + start_mark, "did not find expected whitespace or line break"); + goto error; + } + + end_mark = parser->mark; + + /* Create a token. */ + + TAG_TOKEN_INIT(*token, handle, suffix, start_mark, end_mark); + + return 1; + +error: + yaml_free(handle); + yaml_free(suffix); + return 0; +} + +/* + * Scan a tag handle. + */ + +static int +yaml_parser_scan_tag_handle(yaml_parser_t *parser, int directive, + yaml_mark_t start_mark, yaml_char_t **handle) +{ + yaml_string_t string = NULL_STRING; + + if (!STRING_INIT(parser, string, INITIAL_STRING_SIZE)) goto error; + + /* Check the initial '!' character. */ + + if (!CACHE(parser, 1)) goto error; + + if (!CHECK(parser->buffer, '!')) { + yaml_parser_set_scanner_error(parser, directive ? + "while scanning a tag directive" : "while scanning a tag", + start_mark, "did not find expected '!'"); + goto error; + } + + /* Copy the '!' character. */ + + if (!READ(parser, string)) goto error; + + /* Copy all subsequent alphabetical and numerical characters. */ + + if (!CACHE(parser, 1)) goto error; + + while (IS_ALPHA(parser->buffer)) + { + if (!READ(parser, string)) goto error; + if (!CACHE(parser, 1)) goto error; + } + + /* Check if the trailing character is '!' and copy it. */ + + if (CHECK(parser->buffer, '!')) + { + if (!READ(parser, string)) goto error; + } + else + { + /* + * It's either the '!' tag or not really a tag handle. If it's a %TAG + * directive, it's an error. If it's a tag token, it must be a part of + * URI. + */ + + if (directive && !(string.start[0] == '!' && string.start[1] == '\0')) { + yaml_parser_set_scanner_error(parser, "while parsing a tag directive", + start_mark, "did not find expected '!'"); + goto error; + } + } + + *handle = string.start; + + return 1; + +error: + STRING_DEL(parser, string); + return 0; +} + +/* + * Scan a tag. + */ + +static int +yaml_parser_scan_tag_uri(yaml_parser_t *parser, int directive, + yaml_char_t *head, yaml_mark_t start_mark, yaml_char_t **uri) +{ + size_t length = head ? strlen((char *)head) : 0; + yaml_string_t string = NULL_STRING; + + if (!STRING_INIT(parser, string, INITIAL_STRING_SIZE)) goto error; + + /* Resize the string to include the head. */ + + while ((size_t)(string.end - string.start) <= length) { + if (!yaml_string_extend(&string.start, &string.pointer, &string.end)) { + parser->error = YAML_MEMORY_ERROR; + goto error; + } + } + + /* + * Copy the head if needed. + * + * Note that we don't copy the leading '!' character. + */ + + if (length > 1) { + memcpy(string.start, head+1, length-1); + string.pointer += length-1; + } + + /* Scan the tag. */ + + if (!CACHE(parser, 1)) goto error; + + /* + * The set of characters that may appear in URI is as follows: + * + * '0'-'9', 'A'-'Z', 'a'-'z', '_', '-', ';', '/', '?', ':', '@', '&', + * '=', '+', '$', ',', '.', '!', '~', '*', '\'', '(', ')', '[', ']', + * '%'. + */ + + while (IS_ALPHA(parser->buffer) || CHECK(parser->buffer, ';') + || CHECK(parser->buffer, '/') || CHECK(parser->buffer, '?') + || CHECK(parser->buffer, ':') || CHECK(parser->buffer, '@') + || CHECK(parser->buffer, '&') || CHECK(parser->buffer, '=') + || CHECK(parser->buffer, '+') || CHECK(parser->buffer, '$') + || CHECK(parser->buffer, ',') || CHECK(parser->buffer, '.') + || CHECK(parser->buffer, '!') || CHECK(parser->buffer, '~') + || CHECK(parser->buffer, '*') || CHECK(parser->buffer, '\'') + || CHECK(parser->buffer, '(') || CHECK(parser->buffer, ')') + || CHECK(parser->buffer, '[') || CHECK(parser->buffer, ']') + || CHECK(parser->buffer, '%')) + { + /* Check if it is a URI-escape sequence. */ + + if (CHECK(parser->buffer, '%')) { + if (!yaml_parser_scan_uri_escapes(parser, + directive, start_mark, &string)) goto error; + } + else { + if (!READ(parser, string)) goto error; + } + + length ++; + if (!CACHE(parser, 1)) goto error; + } + + /* Check if the tag is non-empty. */ + + if (!length) { + if (!STRING_EXTEND(parser, string)) + goto error; + + yaml_parser_set_scanner_error(parser, directive ? + "while parsing a %TAG directive" : "while parsing a tag", + start_mark, "did not find expected tag URI"); + goto error; + } + + *uri = string.start; + + return 1; + +error: + STRING_DEL(parser, string); + return 0; +} + +/* + * Decode an URI-escape sequence corresponding to a single UTF-8 character. + */ + +static int +yaml_parser_scan_uri_escapes(yaml_parser_t *parser, int directive, + yaml_mark_t start_mark, yaml_string_t *string) +{ + int width = 0; + + /* Decode the required number of characters. */ + + do { + + unsigned char octet = 0; + + /* Check for a URI-escaped octet. */ + + if (!CACHE(parser, 3)) return 0; + + if (!(CHECK(parser->buffer, '%') + && IS_HEX_AT(parser->buffer, 1) + && IS_HEX_AT(parser->buffer, 2))) { + return yaml_parser_set_scanner_error(parser, directive ? + "while parsing a %TAG directive" : "while parsing a tag", + start_mark, "did not find URI escaped octet"); + } + + /* Get the octet. */ + + octet = (AS_HEX_AT(parser->buffer, 1) << 4) + AS_HEX_AT(parser->buffer, 2); + + /* If it is the leading octet, determine the length of the UTF-8 sequence. */ + + if (!width) + { + width = (octet & 0x80) == 0x00 ? 1 : + (octet & 0xE0) == 0xC0 ? 2 : + (octet & 0xF0) == 0xE0 ? 3 : + (octet & 0xF8) == 0xF0 ? 4 : 0; + if (!width) { + return yaml_parser_set_scanner_error(parser, directive ? + "while parsing a %TAG directive" : "while parsing a tag", + start_mark, "found an incorrect leading UTF-8 octet"); + } + } + else + { + /* Check if the trailing octet is correct. */ + + if ((octet & 0xC0) != 0x80) { + return yaml_parser_set_scanner_error(parser, directive ? + "while parsing a %TAG directive" : "while parsing a tag", + start_mark, "found an incorrect trailing UTF-8 octet"); + } + } + + /* Copy the octet and move the pointers. */ + + *(string->pointer++) = octet; + SKIP(parser); + SKIP(parser); + SKIP(parser); + + } while (--width); + + return 1; +} + +/* + * Scan a block scalar. + */ + +static int +yaml_parser_scan_block_scalar(yaml_parser_t *parser, yaml_token_t *token, + int literal) +{ + yaml_mark_t start_mark; + yaml_mark_t end_mark; + yaml_string_t string = NULL_STRING; + yaml_string_t leading_break = NULL_STRING; + yaml_string_t trailing_breaks = NULL_STRING; + int chomping = 0; + int increment = 0; + int indent = 0; + int leading_blank = 0; + int trailing_blank = 0; + + if (!STRING_INIT(parser, string, INITIAL_STRING_SIZE)) goto error; + if (!STRING_INIT(parser, leading_break, INITIAL_STRING_SIZE)) goto error; + if (!STRING_INIT(parser, trailing_breaks, INITIAL_STRING_SIZE)) goto error; + + /* Eat the indicator '|' or '>'. */ + + start_mark = parser->mark; + + SKIP(parser); + + /* Scan the additional block scalar indicators. */ + + if (!CACHE(parser, 1)) goto error; + + /* Check for a chomping indicator. */ + + if (CHECK(parser->buffer, '+') || CHECK(parser->buffer, '-')) + { + /* Set the chomping method and eat the indicator. */ + + chomping = CHECK(parser->buffer, '+') ? +1 : -1; + + SKIP(parser); + + /* Check for an indentation indicator. */ + + if (!CACHE(parser, 1)) goto error; + + if (IS_DIGIT(parser->buffer)) + { + /* Check that the intendation is greater than 0. */ + + if (CHECK(parser->buffer, '0')) { + yaml_parser_set_scanner_error(parser, "while scanning a block scalar", + start_mark, "found an intendation indicator equal to 0"); + goto error; + } + + /* Get the intendation level and eat the indicator. */ + + increment = AS_DIGIT(parser->buffer); + + SKIP(parser); + } + } + + /* Do the same as above, but in the opposite order. */ + + else if (IS_DIGIT(parser->buffer)) + { + if (CHECK(parser->buffer, '0')) { + yaml_parser_set_scanner_error(parser, "while scanning a block scalar", + start_mark, "found an intendation indicator equal to 0"); + goto error; + } + + increment = AS_DIGIT(parser->buffer); + + SKIP(parser); + + if (!CACHE(parser, 1)) goto error; + + if (CHECK(parser->buffer, '+') || CHECK(parser->buffer, '-')) { + chomping = CHECK(parser->buffer, '+') ? +1 : -1; + + SKIP(parser); + } + } + + /* Eat whitespaces and comments to the end of the line. */ + + if (!CACHE(parser, 1)) goto error; + + while (IS_BLANK(parser->buffer)) { + SKIP(parser); + if (!CACHE(parser, 1)) goto error; + } + + if (CHECK(parser->buffer, '#')) { + while (!IS_BREAKZ(parser->buffer)) { + SKIP(parser); + if (!CACHE(parser, 1)) goto error; + } + } + + /* Check if we are at the end of the line. */ + + if (!IS_BREAKZ(parser->buffer)) { + yaml_parser_set_scanner_error(parser, "while scanning a block scalar", + start_mark, "did not find expected comment or line break"); + goto error; + } + + /* Eat a line break. */ + + if (IS_BREAK(parser->buffer)) { + if (!CACHE(parser, 2)) goto error; + SKIP_LINE(parser); + } + + end_mark = parser->mark; + + /* Set the intendation level if it was specified. */ + + if (increment) { + indent = parser->indent >= 0 ? parser->indent+increment : increment; + } + + /* Scan the leading line breaks and determine the indentation level if needed. */ + + if (!yaml_parser_scan_block_scalar_breaks(parser, &indent, &trailing_breaks, + start_mark, &end_mark)) goto error; + + /* Scan the block scalar content. */ + + if (!CACHE(parser, 1)) goto error; + + while ((int)parser->mark.column == indent && !IS_Z(parser->buffer)) + { + /* + * We are at the beginning of a non-empty line. + */ + + /* Is it a trailing whitespace? */ + + trailing_blank = IS_BLANK(parser->buffer); + + /* Check if we need to fold the leading line break. */ + + if (!literal && (*leading_break.start == '\n') + && !leading_blank && !trailing_blank) + { + /* Do we need to join the lines by space? */ + + if (*trailing_breaks.start == '\0') { + if (!STRING_EXTEND(parser, string)) goto error; + *(string.pointer ++) = ' '; + } + + CLEAR(parser, leading_break); + } + else { + if (!JOIN(parser, string, leading_break)) goto error; + CLEAR(parser, leading_break); + } + + /* Append the remaining line breaks. */ + + if (!JOIN(parser, string, trailing_breaks)) goto error; + CLEAR(parser, trailing_breaks); + + /* Is it a leading whitespace? */ + + leading_blank = IS_BLANK(parser->buffer); + + /* Consume the current line. */ + + while (!IS_BREAKZ(parser->buffer)) { + if (!READ(parser, string)) goto error; + if (!CACHE(parser, 1)) goto error; + } + + /* Consume the line break. */ + + if (!CACHE(parser, 2)) goto error; + + if (!READ_LINE(parser, leading_break)) goto error; + + /* Eat the following intendation spaces and line breaks. */ + + if (!yaml_parser_scan_block_scalar_breaks(parser, + &indent, &trailing_breaks, start_mark, &end_mark)) goto error; + } + + /* Chomp the tail. */ + + if (chomping != -1) { + if (!JOIN(parser, string, leading_break)) goto error; + } + if (chomping == 1) { + if (!JOIN(parser, string, trailing_breaks)) goto error; + } + + /* Create a token. */ + + SCALAR_TOKEN_INIT(*token, string.start, string.pointer-string.start, + literal ? YAML_LITERAL_SCALAR_STYLE : YAML_FOLDED_SCALAR_STYLE, + start_mark, end_mark); + + STRING_DEL(parser, leading_break); + STRING_DEL(parser, trailing_breaks); + + return 1; + +error: + STRING_DEL(parser, string); + STRING_DEL(parser, leading_break); + STRING_DEL(parser, trailing_breaks); + + return 0; +} + +/* + * Scan intendation spaces and line breaks for a block scalar. Determine the + * intendation level if needed. + */ + +static int +yaml_parser_scan_block_scalar_breaks(yaml_parser_t *parser, + int *indent, yaml_string_t *breaks, + yaml_mark_t start_mark, yaml_mark_t *end_mark) +{ + int max_indent = 0; + + *end_mark = parser->mark; + + /* Eat the intendation spaces and line breaks. */ + + while (1) + { + /* Eat the intendation spaces. */ + + if (!CACHE(parser, 1)) return 0; + + while ((!*indent || (int)parser->mark.column < *indent) + && IS_SPACE(parser->buffer)) { + SKIP(parser); + if (!CACHE(parser, 1)) return 0; + } + + if ((int)parser->mark.column > max_indent) + max_indent = (int)parser->mark.column; + + /* Check for a tab character messing the intendation. */ + + if ((!*indent || (int)parser->mark.column < *indent) + && IS_TAB(parser->buffer)) { + return yaml_parser_set_scanner_error(parser, "while scanning a block scalar", + start_mark, "found a tab character where an intendation space is expected"); + } + + /* Have we found a non-empty line? */ + + if (!IS_BREAK(parser->buffer)) break; + + /* Consume the line break. */ + + if (!CACHE(parser, 2)) return 0; + if (!READ_LINE(parser, *breaks)) return 0; + *end_mark = parser->mark; + } + + /* Determine the indentation level if needed. */ + + if (!*indent) { + *indent = max_indent; + if (*indent < parser->indent + 1) + *indent = parser->indent + 1; + if (*indent < 1) + *indent = 1; + } + + return 1; +} + +/* + * Scan a quoted scalar. + */ + +static int +yaml_parser_scan_flow_scalar(yaml_parser_t *parser, yaml_token_t *token, + int single) +{ + yaml_mark_t start_mark; + yaml_mark_t end_mark; + yaml_string_t string = NULL_STRING; + yaml_string_t leading_break = NULL_STRING; + yaml_string_t trailing_breaks = NULL_STRING; + yaml_string_t whitespaces = NULL_STRING; + int leading_blanks; + + if (!STRING_INIT(parser, string, INITIAL_STRING_SIZE)) goto error; + if (!STRING_INIT(parser, leading_break, INITIAL_STRING_SIZE)) goto error; + if (!STRING_INIT(parser, trailing_breaks, INITIAL_STRING_SIZE)) goto error; + if (!STRING_INIT(parser, whitespaces, INITIAL_STRING_SIZE)) goto error; + + /* Eat the left quote. */ + + start_mark = parser->mark; + + SKIP(parser); + + /* Consume the content of the quoted scalar. */ + + while (1) + { + /* Check that there are no document indicators at the beginning of the line. */ + + if (!CACHE(parser, 4)) goto error; + + if (parser->mark.column == 0 && + ((CHECK_AT(parser->buffer, '-', 0) && + CHECK_AT(parser->buffer, '-', 1) && + CHECK_AT(parser->buffer, '-', 2)) || + (CHECK_AT(parser->buffer, '.', 0) && + CHECK_AT(parser->buffer, '.', 1) && + CHECK_AT(parser->buffer, '.', 2))) && + IS_BLANKZ_AT(parser->buffer, 3)) + { + yaml_parser_set_scanner_error(parser, "while scanning a quoted scalar", + start_mark, "found unexpected document indicator"); + goto error; + } + + /* Check for EOF. */ + + if (IS_Z(parser->buffer)) { + yaml_parser_set_scanner_error(parser, "while scanning a quoted scalar", + start_mark, "found unexpected end of stream"); + goto error; + } + + /* Consume non-blank characters. */ + + if (!CACHE(parser, 2)) goto error; + + leading_blanks = 0; + + while (!IS_BLANKZ(parser->buffer)) + { + /* Check for an escaped single quote. */ + + if (single && CHECK_AT(parser->buffer, '\'', 0) + && CHECK_AT(parser->buffer, '\'', 1)) + { + if (!STRING_EXTEND(parser, string)) goto error; + *(string.pointer++) = '\''; + SKIP(parser); + SKIP(parser); + } + + /* Check for the right quote. */ + + else if (CHECK(parser->buffer, single ? '\'' : '"')) + { + break; + } + + /* Check for an escaped line break. */ + + else if (!single && CHECK(parser->buffer, '\\') + && IS_BREAK_AT(parser->buffer, 1)) + { + if (!CACHE(parser, 3)) goto error; + SKIP(parser); + SKIP_LINE(parser); + leading_blanks = 1; + break; + } + + /* Check for an escape sequence. */ + + else if (!single && CHECK(parser->buffer, '\\')) + { + size_t code_length = 0; + + if (!STRING_EXTEND(parser, string)) goto error; + + /* Check the escape character. */ + + switch (parser->buffer.pointer[1]) + { + case '0': + *(string.pointer++) = '\0'; + break; + + case 'a': + *(string.pointer++) = '\x07'; + break; + + case 'b': + *(string.pointer++) = '\x08'; + break; + + case 't': + case '\t': + *(string.pointer++) = '\x09'; + break; + + case 'n': + *(string.pointer++) = '\x0A'; + break; + + case 'v': + *(string.pointer++) = '\x0B'; + break; + + case 'f': + *(string.pointer++) = '\x0C'; + break; + + case 'r': + *(string.pointer++) = '\x0D'; + break; + + case 'e': + *(string.pointer++) = '\x1B'; + break; + + case ' ': + *(string.pointer++) = '\x20'; + break; + + case '"': + *(string.pointer++) = '"'; + break; + + case '\'': + *(string.pointer++) = '\''; + break; + + case '\\': + *(string.pointer++) = '\\'; + break; + + case 'N': /* NEL (#x85) */ + *(string.pointer++) = '\xC2'; + *(string.pointer++) = '\x85'; + break; + + case '_': /* #xA0 */ + *(string.pointer++) = '\xC2'; + *(string.pointer++) = '\xA0'; + break; + + case 'L': /* LS (#x2028) */ + *(string.pointer++) = '\xE2'; + *(string.pointer++) = '\x80'; + *(string.pointer++) = '\xA8'; + break; + + case 'P': /* PS (#x2029) */ + *(string.pointer++) = '\xE2'; + *(string.pointer++) = '\x80'; + *(string.pointer++) = '\xA9'; + break; + + case 'x': + code_length = 2; + break; + + case 'u': + code_length = 4; + break; + + case 'U': + code_length = 8; + break; + + default: + yaml_parser_set_scanner_error(parser, "while parsing a quoted scalar", + start_mark, "found unknown escape character"); + goto error; + } + + SKIP(parser); + SKIP(parser); + + /* Consume an arbitrary escape code. */ + + if (code_length) + { + unsigned int value = 0; + size_t k; + + /* Scan the character value. */ + + if (!CACHE(parser, code_length)) goto error; + + for (k = 0; k < code_length; k ++) { + if (!IS_HEX_AT(parser->buffer, k)) { + yaml_parser_set_scanner_error(parser, "while parsing a quoted scalar", + start_mark, "did not find expected hexdecimal number"); + goto error; + } + value = (value << 4) + AS_HEX_AT(parser->buffer, k); + } + + /* Check the value and write the character. */ + + if ((value >= 0xD800 && value <= 0xDFFF) || value > 0x10FFFF) { + yaml_parser_set_scanner_error(parser, "while parsing a quoted scalar", + start_mark, "found invalid Unicode character escape code"); + goto error; + } + + if (value <= 0x7F) { + *(string.pointer++) = value; + } + else if (value <= 0x7FF) { + *(string.pointer++) = 0xC0 + (value >> 6); + *(string.pointer++) = 0x80 + (value & 0x3F); + } + else if (value <= 0xFFFF) { + *(string.pointer++) = 0xE0 + (value >> 12); + *(string.pointer++) = 0x80 + ((value >> 6) & 0x3F); + *(string.pointer++) = 0x80 + (value & 0x3F); + } + else { + *(string.pointer++) = 0xF0 + (value >> 18); + *(string.pointer++) = 0x80 + ((value >> 12) & 0x3F); + *(string.pointer++) = 0x80 + ((value >> 6) & 0x3F); + *(string.pointer++) = 0x80 + (value & 0x3F); + } + + /* Advance the pointer. */ + + for (k = 0; k < code_length; k ++) { + SKIP(parser); + } + } + } + + else + { + /* It is a non-escaped non-blank character. */ + + if (!READ(parser, string)) goto error; + } + + if (!CACHE(parser, 2)) goto error; + } + + /* Check if we are at the end of the scalar. */ + + if (CHECK(parser->buffer, single ? '\'' : '"')) + break; + + /* Consume blank characters. */ + + if (!CACHE(parser, 1)) goto error; + + while (IS_BLANK(parser->buffer) || IS_BREAK(parser->buffer)) + { + if (IS_BLANK(parser->buffer)) + { + /* Consume a space or a tab character. */ + + if (!leading_blanks) { + if (!READ(parser, whitespaces)) goto error; + } + else { + SKIP(parser); + } + } + else + { + if (!CACHE(parser, 2)) goto error; + + /* Check if it is a first line break. */ + + if (!leading_blanks) + { + CLEAR(parser, whitespaces); + if (!READ_LINE(parser, leading_break)) goto error; + leading_blanks = 1; + } + else + { + if (!READ_LINE(parser, trailing_breaks)) goto error; + } + } + if (!CACHE(parser, 1)) goto error; + } + + /* Join the whitespaces or fold line breaks. */ + + if (leading_blanks) + { + /* Do we need to fold line breaks? */ + + if (leading_break.start[0] == '\n') { + if (trailing_breaks.start[0] == '\0') { + if (!STRING_EXTEND(parser, string)) goto error; + *(string.pointer++) = ' '; + } + else { + if (!JOIN(parser, string, trailing_breaks)) goto error; + CLEAR(parser, trailing_breaks); + } + CLEAR(parser, leading_break); + } + else { + if (!JOIN(parser, string, leading_break)) goto error; + if (!JOIN(parser, string, trailing_breaks)) goto error; + CLEAR(parser, leading_break); + CLEAR(parser, trailing_breaks); + } + } + else + { + if (!JOIN(parser, string, whitespaces)) goto error; + CLEAR(parser, whitespaces); + } + } + + /* Eat the right quote. */ + + SKIP(parser); + + end_mark = parser->mark; + + /* Create a token. */ + + SCALAR_TOKEN_INIT(*token, string.start, string.pointer-string.start, + single ? YAML_SINGLE_QUOTED_SCALAR_STYLE : YAML_DOUBLE_QUOTED_SCALAR_STYLE, + start_mark, end_mark); + + STRING_DEL(parser, leading_break); + STRING_DEL(parser, trailing_breaks); + STRING_DEL(parser, whitespaces); + + return 1; + +error: + STRING_DEL(parser, string); + STRING_DEL(parser, leading_break); + STRING_DEL(parser, trailing_breaks); + STRING_DEL(parser, whitespaces); + + return 0; +} + +/* + * Scan a plain scalar. + */ + +static int +yaml_parser_scan_plain_scalar(yaml_parser_t *parser, yaml_token_t *token) +{ + yaml_mark_t start_mark; + yaml_mark_t end_mark; + yaml_string_t string = NULL_STRING; + yaml_string_t leading_break = NULL_STRING; + yaml_string_t trailing_breaks = NULL_STRING; + yaml_string_t whitespaces = NULL_STRING; + int leading_blanks = 0; + int indent = parser->indent+1; + + if (!STRING_INIT(parser, string, INITIAL_STRING_SIZE)) goto error; + if (!STRING_INIT(parser, leading_break, INITIAL_STRING_SIZE)) goto error; + if (!STRING_INIT(parser, trailing_breaks, INITIAL_STRING_SIZE)) goto error; + if (!STRING_INIT(parser, whitespaces, INITIAL_STRING_SIZE)) goto error; + + start_mark = end_mark = parser->mark; + + /* Consume the content of the plain scalar. */ + + while (1) + { + /* Check for a document indicator. */ + + if (!CACHE(parser, 4)) goto error; + + if (parser->mark.column == 0 && + ((CHECK_AT(parser->buffer, '-', 0) && + CHECK_AT(parser->buffer, '-', 1) && + CHECK_AT(parser->buffer, '-', 2)) || + (CHECK_AT(parser->buffer, '.', 0) && + CHECK_AT(parser->buffer, '.', 1) && + CHECK_AT(parser->buffer, '.', 2))) && + IS_BLANKZ_AT(parser->buffer, 3)) break; + + /* Check for a comment. */ + + if (CHECK(parser->buffer, '#')) + break; + + /* Consume non-blank characters. */ + + while (!IS_BLANKZ(parser->buffer)) + { + /* Check for 'x:x' in the flow context. TODO: Fix the test "spec-08-13". */ + + if (parser->flow_level + && CHECK(parser->buffer, ':') + && !IS_BLANKZ_AT(parser->buffer, 1)) { + yaml_parser_set_scanner_error(parser, "while scanning a plain scalar", + start_mark, "found unexpected ':'"); + goto error; + } + + /* Check for indicators that may end a plain scalar. */ + + if ((CHECK(parser->buffer, ':') && IS_BLANKZ_AT(parser->buffer, 1)) + || (parser->flow_level && + (CHECK(parser->buffer, ',') || CHECK(parser->buffer, ':') + || CHECK(parser->buffer, '?') || CHECK(parser->buffer, '[') + || CHECK(parser->buffer, ']') || CHECK(parser->buffer, '{') + || CHECK(parser->buffer, '}')))) + break; + + /* Check if we need to join whitespaces and breaks. */ + + if (leading_blanks || whitespaces.start != whitespaces.pointer) + { + if (leading_blanks) + { + /* Do we need to fold line breaks? */ + + if (leading_break.start[0] == '\n') { + if (trailing_breaks.start[0] == '\0') { + if (!STRING_EXTEND(parser, string)) goto error; + *(string.pointer++) = ' '; + } + else { + if (!JOIN(parser, string, trailing_breaks)) goto error; + CLEAR(parser, trailing_breaks); + } + CLEAR(parser, leading_break); + } + else { + if (!JOIN(parser, string, leading_break)) goto error; + if (!JOIN(parser, string, trailing_breaks)) goto error; + CLEAR(parser, leading_break); + CLEAR(parser, trailing_breaks); + } + + leading_blanks = 0; + } + else + { + if (!JOIN(parser, string, whitespaces)) goto error; + CLEAR(parser, whitespaces); + } + } + + /* Copy the character. */ + + if (!READ(parser, string)) goto error; + + end_mark = parser->mark; + + if (!CACHE(parser, 2)) goto error; + } + + /* Is it the end? */ + + if (!(IS_BLANK(parser->buffer) || IS_BREAK(parser->buffer))) + break; + + /* Consume blank characters. */ + + if (!CACHE(parser, 1)) goto error; + + while (IS_BLANK(parser->buffer) || IS_BREAK(parser->buffer)) + { + if (IS_BLANK(parser->buffer)) + { + /* Check for tab character that abuse intendation. */ + + if (leading_blanks && (int)parser->mark.column < indent + && IS_TAB(parser->buffer)) { + yaml_parser_set_scanner_error(parser, "while scanning a plain scalar", + start_mark, "found a tab character that violate intendation"); + goto error; + } + + /* Consume a space or a tab character. */ + + if (!leading_blanks) { + if (!READ(parser, whitespaces)) goto error; + } + else { + SKIP(parser); + } + } + else + { + if (!CACHE(parser, 2)) goto error; + + /* Check if it is a first line break. */ + + if (!leading_blanks) + { + CLEAR(parser, whitespaces); + if (!READ_LINE(parser, leading_break)) goto error; + leading_blanks = 1; + } + else + { + if (!READ_LINE(parser, trailing_breaks)) goto error; + } + } + if (!CACHE(parser, 1)) goto error; + } + + /* Check intendation level. */ + + if (!parser->flow_level && (int)parser->mark.column < indent) + break; + } + + /* Create a token. */ + + SCALAR_TOKEN_INIT(*token, string.start, string.pointer-string.start, + YAML_PLAIN_SCALAR_STYLE, start_mark, end_mark); + + /* Note that we change the 'simple_key_allowed' flag. */ + + if (leading_blanks) { + parser->simple_key_allowed = 1; + } + + STRING_DEL(parser, leading_break); + STRING_DEL(parser, trailing_breaks); + STRING_DEL(parser, whitespaces); + + return 1; + +error: + STRING_DEL(parser, string); + STRING_DEL(parser, leading_break); + STRING_DEL(parser, trailing_breaks); + STRING_DEL(parser, whitespaces); + + return 0; +} + diff --git a/libyaml/src/writer.c b/libyaml/src/writer.c new file mode 100644 index 00000000..b90019f5 --- /dev/null +++ b/libyaml/src/writer.c @@ -0,0 +1,141 @@ + +#include "yaml_private.h" + +/* + * Declarations. + */ + +static int +yaml_emitter_set_writer_error(yaml_emitter_t *emitter, const char *problem); + +YAML_DECLARE(int) +yaml_emitter_flush(yaml_emitter_t *emitter); + +/* + * Set the writer error and return 0. + */ + +static int +yaml_emitter_set_writer_error(yaml_emitter_t *emitter, const char *problem) +{ + emitter->error = YAML_WRITER_ERROR; + emitter->problem = problem; + + return 0; +} + +/* + * Flush the output buffer. + */ + +YAML_DECLARE(int) +yaml_emitter_flush(yaml_emitter_t *emitter) +{ + int low, high; + + assert(emitter); /* Non-NULL emitter object is expected. */ + assert(emitter->write_handler); /* Write handler must be set. */ + assert(emitter->encoding); /* Output encoding must be set. */ + + emitter->buffer.last = emitter->buffer.pointer; + emitter->buffer.pointer = emitter->buffer.start; + + /* Check if the buffer is empty. */ + + if (emitter->buffer.start == emitter->buffer.last) { + return 1; + } + + /* If the output encoding is UTF-8, we don't need to recode the buffer. */ + + if (emitter->encoding == YAML_UTF8_ENCODING) + { + if (emitter->write_handler(emitter->write_handler_data, + emitter->buffer.start, + emitter->buffer.last - emitter->buffer.start)) { + emitter->buffer.last = emitter->buffer.start; + emitter->buffer.pointer = emitter->buffer.start; + return 1; + } + else { + return yaml_emitter_set_writer_error(emitter, "write error"); + } + } + + /* Recode the buffer into the raw buffer. */ + + low = (emitter->encoding == YAML_UTF16LE_ENCODING ? 0 : 1); + high = (emitter->encoding == YAML_UTF16LE_ENCODING ? 1 : 0); + + while (emitter->buffer.pointer != emitter->buffer.last) + { + unsigned char octet; + unsigned int width; + unsigned int value; + size_t k; + + /* + * See the "reader.c" code for more details on UTF-8 encoding. Note + * that we assume that the buffer contains a valid UTF-8 sequence. + */ + + /* Read the next UTF-8 character. */ + + octet = emitter->buffer.pointer[0]; + + width = (octet & 0x80) == 0x00 ? 1 : + (octet & 0xE0) == 0xC0 ? 2 : + (octet & 0xF0) == 0xE0 ? 3 : + (octet & 0xF8) == 0xF0 ? 4 : 0; + + value = (octet & 0x80) == 0x00 ? octet & 0x7F : + (octet & 0xE0) == 0xC0 ? octet & 0x1F : + (octet & 0xF0) == 0xE0 ? octet & 0x0F : + (octet & 0xF8) == 0xF0 ? octet & 0x07 : 0; + + for (k = 1; k < width; k ++) { + octet = emitter->buffer.pointer[k]; + value = (value << 6) + (octet & 0x3F); + } + + emitter->buffer.pointer += width; + + /* Write the character. */ + + if (value < 0x10000) + { + emitter->raw_buffer.last[high] = value >> 8; + emitter->raw_buffer.last[low] = value & 0xFF; + + emitter->raw_buffer.last += 2; + } + else + { + /* Write the character using a surrogate pair (check "reader.c"). */ + + value -= 0x10000; + emitter->raw_buffer.last[high] = 0xD8 + (value >> 18); + emitter->raw_buffer.last[low] = (value >> 10) & 0xFF; + emitter->raw_buffer.last[high+2] = 0xDC + ((value >> 8) & 0xFF); + emitter->raw_buffer.last[low+2] = value & 0xFF; + + emitter->raw_buffer.last += 4; + } + } + + /* Write the raw buffer. */ + + if (emitter->write_handler(emitter->write_handler_data, + emitter->raw_buffer.start, + emitter->raw_buffer.last - emitter->raw_buffer.start)) { + emitter->buffer.last = emitter->buffer.start; + emitter->buffer.pointer = emitter->buffer.start; + emitter->raw_buffer.last = emitter->raw_buffer.start; + emitter->raw_buffer.pointer = emitter->raw_buffer.start; + return 1; + } + else { + return yaml_emitter_set_writer_error(emitter, "write error"); + } +} + diff --git a/libyaml/src/yaml_private.h b/libyaml/src/yaml_private.h new file mode 100644 index 00000000..9589e052 --- /dev/null +++ b/libyaml/src/yaml_private.h @@ -0,0 +1,657 @@ + +#if HAVE_CONFIG_H +#include +#endif + +#include + +#include +#include +#include + +#ifndef _MSC_VER +#include +#else +#ifdef _WIN64 +#define PTRDIFF_MAX _I64_MAX +#else +#define PTRDIFF_MAX INT_MAX +#endif +#endif + +/* + * Memory management. + */ + +YAML_DECLARE(void *) +yaml_malloc(size_t size); + +YAML_DECLARE(void *) +yaml_realloc(void *ptr, size_t size); + +YAML_DECLARE(void) +yaml_free(void *ptr); + +YAML_DECLARE(yaml_char_t *) +yaml_strdup(const yaml_char_t *); + +/* + * Reader: Ensure that the buffer contains at least `length` characters. + */ + +YAML_DECLARE(int) +yaml_parser_update_buffer(yaml_parser_t *parser, size_t length); + +/* + * Scanner: Ensure that the token stack contains at least one token ready. + */ + +YAML_DECLARE(int) +yaml_parser_fetch_more_tokens(yaml_parser_t *parser); + +/* + * The size of the input raw buffer. + */ + +#define INPUT_RAW_BUFFER_SIZE 16384 + +/* + * The size of the input buffer. + * + * It should be possible to decode the whole raw buffer. + */ + +#define INPUT_BUFFER_SIZE (INPUT_RAW_BUFFER_SIZE*3) + +/* + * The size of the output buffer. + */ + +#define OUTPUT_BUFFER_SIZE 16384 + +/* + * The size of the output raw buffer. + * + * It should be possible to encode the whole output buffer. + */ + +#define OUTPUT_RAW_BUFFER_SIZE (OUTPUT_BUFFER_SIZE*2+2) + +/* + * The size of other stacks and queues. + */ + +#define INITIAL_STACK_SIZE 16 +#define INITIAL_QUEUE_SIZE 16 +#define INITIAL_STRING_SIZE 16 + +/* + * Buffer management. + */ + +#define BUFFER_INIT(context,buffer,size) \ + (((buffer).start = yaml_malloc(size)) ? \ + ((buffer).last = (buffer).pointer = (buffer).start, \ + (buffer).end = (buffer).start+(size), \ + 1) : \ + ((context)->error = YAML_MEMORY_ERROR, \ + 0)) + +#define BUFFER_DEL(context,buffer) \ + (yaml_free((buffer).start), \ + (buffer).start = (buffer).pointer = (buffer).end = 0) + +/* + * String management. + */ + +typedef struct { + yaml_char_t *start; + yaml_char_t *end; + yaml_char_t *pointer; +} yaml_string_t; + +YAML_DECLARE(int) +yaml_string_extend(yaml_char_t **start, + yaml_char_t **pointer, yaml_char_t **end); + +YAML_DECLARE(int) +yaml_string_join( + yaml_char_t **a_start, yaml_char_t **a_pointer, yaml_char_t **a_end, + yaml_char_t **b_start, yaml_char_t **b_pointer, yaml_char_t **b_end); + +#define NULL_STRING { NULL, NULL, NULL } + +#define STRING(string,length) { (string), (string)+(length), (string) } + +#define STRING_ASSIGN(value,string,length) \ + ((value).start = (string), \ + (value).end = (string)+(length), \ + (value).pointer = (string)) + +#define STRING_INIT(context,string,size) \ + (((string).start = yaml_malloc(size)) ? \ + ((string).pointer = (string).start, \ + (string).end = (string).start+(size), \ + memset((string).start, 0, (size)), \ + 1) : \ + ((context)->error = YAML_MEMORY_ERROR, \ + 0)) + +#define STRING_DEL(context,string) \ + (yaml_free((string).start), \ + (string).start = (string).pointer = (string).end = 0) + +#define STRING_EXTEND(context,string) \ + (((string).pointer+5 < (string).end) \ + || yaml_string_extend(&(string).start, \ + &(string).pointer, &(string).end)) + +#define CLEAR(context,string) \ + ((string).pointer = (string).start, \ + memset((string).start, 0, (string).end-(string).start)) + +#define JOIN(context,string_a,string_b) \ + ((yaml_string_join(&(string_a).start, &(string_a).pointer, \ + &(string_a).end, &(string_b).start, \ + &(string_b).pointer, &(string_b).end)) ? \ + ((string_b).pointer = (string_b).start, \ + 1) : \ + ((context)->error = YAML_MEMORY_ERROR, \ + 0)) + +/* + * String check operations. + */ + +/* + * Check the octet at the specified position. + */ + +#define CHECK_AT(string,octet,offset) \ + ((string).pointer[offset] == (yaml_char_t)(octet)) + +/* + * Check the current octet in the buffer. + */ + +#define CHECK(string,octet) CHECK_AT((string),(octet),0) + +/* + * Check if the character at the specified position is an alphabetical + * character, a digit, '_', or '-'. + */ + +#define IS_ALPHA_AT(string,offset) \ + (((string).pointer[offset] >= (yaml_char_t) '0' && \ + (string).pointer[offset] <= (yaml_char_t) '9') || \ + ((string).pointer[offset] >= (yaml_char_t) 'A' && \ + (string).pointer[offset] <= (yaml_char_t) 'Z') || \ + ((string).pointer[offset] >= (yaml_char_t) 'a' && \ + (string).pointer[offset] <= (yaml_char_t) 'z') || \ + (string).pointer[offset] == '_' || \ + (string).pointer[offset] == '-') + +#define IS_ALPHA(string) IS_ALPHA_AT((string),0) + +/* + * Check if the character at the specified position is a digit. + */ + +#define IS_DIGIT_AT(string,offset) \ + (((string).pointer[offset] >= (yaml_char_t) '0' && \ + (string).pointer[offset] <= (yaml_char_t) '9')) + +#define IS_DIGIT(string) IS_DIGIT_AT((string),0) + +/* + * Get the value of a digit. + */ + +#define AS_DIGIT_AT(string,offset) \ + ((string).pointer[offset] - (yaml_char_t) '0') + +#define AS_DIGIT(string) AS_DIGIT_AT((string),0) + +/* + * Check if the character at the specified position is a hex-digit. + */ + +#define IS_HEX_AT(string,offset) \ + (((string).pointer[offset] >= (yaml_char_t) '0' && \ + (string).pointer[offset] <= (yaml_char_t) '9') || \ + ((string).pointer[offset] >= (yaml_char_t) 'A' && \ + (string).pointer[offset] <= (yaml_char_t) 'F') || \ + ((string).pointer[offset] >= (yaml_char_t) 'a' && \ + (string).pointer[offset] <= (yaml_char_t) 'f')) + +#define IS_HEX(string) IS_HEX_AT((string),0) + +/* + * Get the value of a hex-digit. + */ + +#define AS_HEX_AT(string,offset) \ + (((string).pointer[offset] >= (yaml_char_t) 'A' && \ + (string).pointer[offset] <= (yaml_char_t) 'F') ? \ + ((string).pointer[offset] - (yaml_char_t) 'A' + 10) : \ + ((string).pointer[offset] >= (yaml_char_t) 'a' && \ + (string).pointer[offset] <= (yaml_char_t) 'f') ? \ + ((string).pointer[offset] - (yaml_char_t) 'a' + 10) : \ + ((string).pointer[offset] - (yaml_char_t) '0')) + +#define AS_HEX(string) AS_HEX_AT((string),0) + +/* + * Check if the character is ASCII. + */ + +#define IS_ASCII_AT(string,offset) \ + ((string).pointer[offset] <= (yaml_char_t) '\x7F') + +#define IS_ASCII(string) IS_ASCII_AT((string),0) + +/* + * Check if the character can be printed unescaped. + */ + +#define IS_PRINTABLE_AT(string,offset) \ + (((string).pointer[offset] == 0x0A) /* . == #x0A */ \ + || ((string).pointer[offset] >= 0x20 /* #x20 <= . <= #x7E */ \ + && (string).pointer[offset] <= 0x7E) \ + || ((string).pointer[offset] == 0xC2 /* #0xA0 <= . <= #xD7FF */ \ + && (string).pointer[offset+1] >= 0xA0) \ + || ((string).pointer[offset] > 0xC2 \ + && (string).pointer[offset] < 0xED) \ + || ((string).pointer[offset] == 0xED \ + && (string).pointer[offset+1] < 0xA0) \ + || ((string).pointer[offset] == 0xEE) \ + || ((string).pointer[offset] == 0xEF /* #xE000 <= . <= #xFFFD */ \ + && !((string).pointer[offset+1] == 0xBB /* && . != #xFEFF */ \ + && (string).pointer[offset+2] == 0xBF) \ + && !((string).pointer[offset+1] == 0xBF \ + && ((string).pointer[offset+2] == 0xBE \ + || (string).pointer[offset+2] == 0xBF)))) + +#define IS_PRINTABLE(string) IS_PRINTABLE_AT((string),0) + +/* + * Check if the character at the specified position is NUL. + */ + +#define IS_Z_AT(string,offset) CHECK_AT((string),'\0',(offset)) + +#define IS_Z(string) IS_Z_AT((string),0) + +/* + * Check if the character at the specified position is BOM. + */ + +#define IS_BOM_AT(string,offset) \ + (CHECK_AT((string),'\xEF',(offset)) \ + && CHECK_AT((string),'\xBB',(offset)+1) \ + && CHECK_AT((string),'\xBF',(offset)+2)) /* BOM (#xFEFF) */ + +#define IS_BOM(string) IS_BOM_AT(string,0) + +/* + * Check if the character at the specified position is space. + */ + +#define IS_SPACE_AT(string,offset) CHECK_AT((string),' ',(offset)) + +#define IS_SPACE(string) IS_SPACE_AT((string),0) + +/* + * Check if the character at the specified position is tab. + */ + +#define IS_TAB_AT(string,offset) CHECK_AT((string),'\t',(offset)) + +#define IS_TAB(string) IS_TAB_AT((string),0) + +/* + * Check if the character at the specified position is blank (space or tab). + */ + +#define IS_BLANK_AT(string,offset) \ + (IS_SPACE_AT((string),(offset)) || IS_TAB_AT((string),(offset))) + +#define IS_BLANK(string) IS_BLANK_AT((string),0) + +/* + * Check if the character at the specified position is a line break. + */ + +#define IS_BREAK_AT(string,offset) \ + (CHECK_AT((string),'\r',(offset)) /* CR (#xD)*/ \ + || CHECK_AT((string),'\n',(offset)) /* LF (#xA) */ \ + || (CHECK_AT((string),'\xC2',(offset)) \ + && CHECK_AT((string),'\x85',(offset)+1)) /* NEL (#x85) */ \ + || (CHECK_AT((string),'\xE2',(offset)) \ + && CHECK_AT((string),'\x80',(offset)+1) \ + && CHECK_AT((string),'\xA8',(offset)+2)) /* LS (#x2028) */ \ + || (CHECK_AT((string),'\xE2',(offset)) \ + && CHECK_AT((string),'\x80',(offset)+1) \ + && CHECK_AT((string),'\xA9',(offset)+2))) /* PS (#x2029) */ + +#define IS_BREAK(string) IS_BREAK_AT((string),0) + +#define IS_CRLF_AT(string,offset) \ + (CHECK_AT((string),'\r',(offset)) && CHECK_AT((string),'\n',(offset)+1)) + +#define IS_CRLF(string) IS_CRLF_AT((string),0) + +/* + * Check if the character is a line break or NUL. + */ + +#define IS_BREAKZ_AT(string,offset) \ + (IS_BREAK_AT((string),(offset)) || IS_Z_AT((string),(offset))) + +#define IS_BREAKZ(string) IS_BREAKZ_AT((string),0) + +/* + * Check if the character is a line break, space, or NUL. + */ + +#define IS_SPACEZ_AT(string,offset) \ + (IS_SPACE_AT((string),(offset)) || IS_BREAKZ_AT((string),(offset))) + +#define IS_SPACEZ(string) IS_SPACEZ_AT((string),0) + +/* + * Check if the character is a line break, space, tab, or NUL. + */ + +#define IS_BLANKZ_AT(string,offset) \ + (IS_BLANK_AT((string),(offset)) || IS_BREAKZ_AT((string),(offset))) + +#define IS_BLANKZ(string) IS_BLANKZ_AT((string),0) + +/* + * Determine the width of the character. + */ + +#define WIDTH_AT(string,offset) \ + (((string).pointer[offset] & 0x80) == 0x00 ? 1 : \ + ((string).pointer[offset] & 0xE0) == 0xC0 ? 2 : \ + ((string).pointer[offset] & 0xF0) == 0xE0 ? 3 : \ + ((string).pointer[offset] & 0xF8) == 0xF0 ? 4 : 0) + +#define WIDTH(string) WIDTH_AT((string),0) + +/* + * Move the string pointer to the next character. + */ + +#define MOVE(string) ((string).pointer += WIDTH((string))) + +/* + * Copy a character and move the pointers of both strings. + */ + +#define COPY(string_a,string_b) \ + ((*(string_b).pointer & 0x80) == 0x00 ? \ + (*((string_a).pointer++) = *((string_b).pointer++)) : \ + (*(string_b).pointer & 0xE0) == 0xC0 ? \ + (*((string_a).pointer++) = *((string_b).pointer++), \ + *((string_a).pointer++) = *((string_b).pointer++)) : \ + (*(string_b).pointer & 0xF0) == 0xE0 ? \ + (*((string_a).pointer++) = *((string_b).pointer++), \ + *((string_a).pointer++) = *((string_b).pointer++), \ + *((string_a).pointer++) = *((string_b).pointer++)) : \ + (*(string_b).pointer & 0xF8) == 0xF0 ? \ + (*((string_a).pointer++) = *((string_b).pointer++), \ + *((string_a).pointer++) = *((string_b).pointer++), \ + *((string_a).pointer++) = *((string_b).pointer++), \ + *((string_a).pointer++) = *((string_b).pointer++)) : 0) + +/* + * Stack and queue management. + */ + +YAML_DECLARE(int) +yaml_stack_extend(void **start, void **top, void **end); + +YAML_DECLARE(int) +yaml_queue_extend(void **start, void **head, void **tail, void **end); + +#define STACK_INIT(context,stack,size) \ + (((stack).start = yaml_malloc((size)*sizeof(*(stack).start))) ? \ + ((stack).top = (stack).start, \ + (stack).end = (stack).start+(size), \ + 1) : \ + ((context)->error = YAML_MEMORY_ERROR, \ + 0)) + +#define STACK_DEL(context,stack) \ + (yaml_free((stack).start), \ + (stack).start = (stack).top = (stack).end = 0) + +#define STACK_EMPTY(context,stack) \ + ((stack).start == (stack).top) + +#define STACK_LIMIT(context,stack,size) \ + ((stack).top - (stack).start < (size) ? \ + 1 : \ + ((context)->error = YAML_MEMORY_ERROR, \ + 0)) + +#define PUSH(context,stack,value) \ + (((stack).top != (stack).end \ + || yaml_stack_extend((void **)&(stack).start, \ + (void **)&(stack).top, (void **)&(stack).end)) ? \ + (*((stack).top++) = value, \ + 1) : \ + ((context)->error = YAML_MEMORY_ERROR, \ + 0)) + +#define POP(context,stack) \ + (*(--(stack).top)) + +#define QUEUE_INIT(context,queue,size) \ + (((queue).start = yaml_malloc((size)*sizeof(*(queue).start))) ? \ + ((queue).head = (queue).tail = (queue).start, \ + (queue).end = (queue).start+(size), \ + 1) : \ + ((context)->error = YAML_MEMORY_ERROR, \ + 0)) + +#define QUEUE_DEL(context,queue) \ + (yaml_free((queue).start), \ + (queue).start = (queue).head = (queue).tail = (queue).end = 0) + +#define QUEUE_EMPTY(context,queue) \ + ((queue).head == (queue).tail) + +#define ENQUEUE(context,queue,value) \ + (((queue).tail != (queue).end \ + || yaml_queue_extend((void **)&(queue).start, (void **)&(queue).head, \ + (void **)&(queue).tail, (void **)&(queue).end)) ? \ + (*((queue).tail++) = value, \ + 1) : \ + ((context)->error = YAML_MEMORY_ERROR, \ + 0)) + +#define DEQUEUE(context,queue) \ + (*((queue).head++)) + +#define QUEUE_INSERT(context,queue,index,value) \ + (((queue).tail != (queue).end \ + || yaml_queue_extend((void **)&(queue).start, (void **)&(queue).head, \ + (void **)&(queue).tail, (void **)&(queue).end)) ? \ + (memmove((queue).head+(index)+1,(queue).head+(index), \ + ((queue).tail-(queue).head-(index))*sizeof(*(queue).start)), \ + *((queue).head+(index)) = value, \ + (queue).tail++, \ + 1) : \ + ((context)->error = YAML_MEMORY_ERROR, \ + 0)) + +/* + * Token initializers. + */ + +#define TOKEN_INIT(token,token_type,token_start_mark,token_end_mark) \ + (memset(&(token), 0, sizeof(yaml_token_t)), \ + (token).type = (token_type), \ + (token).start_mark = (token_start_mark), \ + (token).end_mark = (token_end_mark)) + +#define STREAM_START_TOKEN_INIT(token,token_encoding,start_mark,end_mark) \ + (TOKEN_INIT((token),YAML_STREAM_START_TOKEN,(start_mark),(end_mark)), \ + (token).data.stream_start.encoding = (token_encoding)) + +#define STREAM_END_TOKEN_INIT(token,start_mark,end_mark) \ + (TOKEN_INIT((token),YAML_STREAM_END_TOKEN,(start_mark),(end_mark))) + +#define ALIAS_TOKEN_INIT(token,token_value,start_mark,end_mark) \ + (TOKEN_INIT((token),YAML_ALIAS_TOKEN,(start_mark),(end_mark)), \ + (token).data.alias.value = (token_value)) + +#define ANCHOR_TOKEN_INIT(token,token_value,start_mark,end_mark) \ + (TOKEN_INIT((token),YAML_ANCHOR_TOKEN,(start_mark),(end_mark)), \ + (token).data.anchor.value = (token_value)) + +#define TAG_TOKEN_INIT(token,token_handle,token_suffix,start_mark,end_mark) \ + (TOKEN_INIT((token),YAML_TAG_TOKEN,(start_mark),(end_mark)), \ + (token).data.tag.handle = (token_handle), \ + (token).data.tag.suffix = (token_suffix)) + +#define SCALAR_TOKEN_INIT(token,token_value,token_length,token_style,start_mark,end_mark) \ + (TOKEN_INIT((token),YAML_SCALAR_TOKEN,(start_mark),(end_mark)), \ + (token).data.scalar.value = (token_value), \ + (token).data.scalar.length = (token_length), \ + (token).data.scalar.style = (token_style)) + +#define VERSION_DIRECTIVE_TOKEN_INIT(token,token_major,token_minor,start_mark,end_mark) \ + (TOKEN_INIT((token),YAML_VERSION_DIRECTIVE_TOKEN,(start_mark),(end_mark)), \ + (token).data.version_directive.major = (token_major), \ + (token).data.version_directive.minor = (token_minor)) + +#define TAG_DIRECTIVE_TOKEN_INIT(token,token_handle,token_prefix,start_mark,end_mark) \ + (TOKEN_INIT((token),YAML_TAG_DIRECTIVE_TOKEN,(start_mark),(end_mark)), \ + (token).data.tag_directive.handle = (token_handle), \ + (token).data.tag_directive.prefix = (token_prefix)) + +/* + * Event initializers. + */ + +#define EVENT_INIT(event,event_type,event_start_mark,event_end_mark) \ + (memset(&(event), 0, sizeof(yaml_event_t)), \ + (event).type = (event_type), \ + (event).start_mark = (event_start_mark), \ + (event).end_mark = (event_end_mark)) + +#define STREAM_START_EVENT_INIT(event,event_encoding,start_mark,end_mark) \ + (EVENT_INIT((event),YAML_STREAM_START_EVENT,(start_mark),(end_mark)), \ + (event).data.stream_start.encoding = (event_encoding)) + +#define STREAM_END_EVENT_INIT(event,start_mark,end_mark) \ + (EVENT_INIT((event),YAML_STREAM_END_EVENT,(start_mark),(end_mark))) + +#define DOCUMENT_START_EVENT_INIT(event,event_version_directive, \ + event_tag_directives_start,event_tag_directives_end,event_implicit,start_mark,end_mark) \ + (EVENT_INIT((event),YAML_DOCUMENT_START_EVENT,(start_mark),(end_mark)), \ + (event).data.document_start.version_directive = (event_version_directive), \ + (event).data.document_start.tag_directives.start = (event_tag_directives_start), \ + (event).data.document_start.tag_directives.end = (event_tag_directives_end), \ + (event).data.document_start.implicit = (event_implicit)) + +#define DOCUMENT_END_EVENT_INIT(event,event_implicit,start_mark,end_mark) \ + (EVENT_INIT((event),YAML_DOCUMENT_END_EVENT,(start_mark),(end_mark)), \ + (event).data.document_end.implicit = (event_implicit)) + +#define ALIAS_EVENT_INIT(event,event_anchor,start_mark,end_mark) \ + (EVENT_INIT((event),YAML_ALIAS_EVENT,(start_mark),(end_mark)), \ + (event).data.alias.anchor = (event_anchor)) + +#define SCALAR_EVENT_INIT(event,event_anchor,event_tag,event_value,event_length, \ + event_plain_implicit, event_quoted_implicit,event_style,start_mark,end_mark) \ + (EVENT_INIT((event),YAML_SCALAR_EVENT,(start_mark),(end_mark)), \ + (event).data.scalar.anchor = (event_anchor), \ + (event).data.scalar.tag = (event_tag), \ + (event).data.scalar.value = (event_value), \ + (event).data.scalar.length = (event_length), \ + (event).data.scalar.plain_implicit = (event_plain_implicit), \ + (event).data.scalar.quoted_implicit = (event_quoted_implicit), \ + (event).data.scalar.style = (event_style)) + +#define SEQUENCE_START_EVENT_INIT(event,event_anchor,event_tag, \ + event_implicit,event_style,start_mark,end_mark) \ + (EVENT_INIT((event),YAML_SEQUENCE_START_EVENT,(start_mark),(end_mark)), \ + (event).data.sequence_start.anchor = (event_anchor), \ + (event).data.sequence_start.tag = (event_tag), \ + (event).data.sequence_start.implicit = (event_implicit), \ + (event).data.sequence_start.style = (event_style)) + +#define SEQUENCE_END_EVENT_INIT(event,start_mark,end_mark) \ + (EVENT_INIT((event),YAML_SEQUENCE_END_EVENT,(start_mark),(end_mark))) + +#define MAPPING_START_EVENT_INIT(event,event_anchor,event_tag, \ + event_implicit,event_style,start_mark,end_mark) \ + (EVENT_INIT((event),YAML_MAPPING_START_EVENT,(start_mark),(end_mark)), \ + (event).data.mapping_start.anchor = (event_anchor), \ + (event).data.mapping_start.tag = (event_tag), \ + (event).data.mapping_start.implicit = (event_implicit), \ + (event).data.mapping_start.style = (event_style)) + +#define MAPPING_END_EVENT_INIT(event,start_mark,end_mark) \ + (EVENT_INIT((event),YAML_MAPPING_END_EVENT,(start_mark),(end_mark))) + +/* + * Document initializer. + */ + +#define DOCUMENT_INIT(document,document_nodes_start,document_nodes_end, \ + document_version_directive,document_tag_directives_start, \ + document_tag_directives_end,document_start_implicit, \ + document_end_implicit,document_start_mark,document_end_mark) \ + (memset(&(document), 0, sizeof(yaml_document_t)), \ + (document).nodes.start = (document_nodes_start), \ + (document).nodes.end = (document_nodes_end), \ + (document).nodes.top = (document_nodes_start), \ + (document).version_directive = (document_version_directive), \ + (document).tag_directives.start = (document_tag_directives_start), \ + (document).tag_directives.end = (document_tag_directives_end), \ + (document).start_implicit = (document_start_implicit), \ + (document).end_implicit = (document_end_implicit), \ + (document).start_mark = (document_start_mark), \ + (document).end_mark = (document_end_mark)) + +/* + * Node initializers. + */ + +#define NODE_INIT(node,node_type,node_tag,node_start_mark,node_end_mark) \ + (memset(&(node), 0, sizeof(yaml_node_t)), \ + (node).type = (node_type), \ + (node).tag = (node_tag), \ + (node).start_mark = (node_start_mark), \ + (node).end_mark = (node_end_mark)) + +#define SCALAR_NODE_INIT(node,node_tag,node_value,node_length, \ + node_style,start_mark,end_mark) \ + (NODE_INIT((node),YAML_SCALAR_NODE,(node_tag),(start_mark),(end_mark)), \ + (node).data.scalar.value = (node_value), \ + (node).data.scalar.length = (node_length), \ + (node).data.scalar.style = (node_style)) + +#define SEQUENCE_NODE_INIT(node,node_tag,node_items_start,node_items_end, \ + node_style,start_mark,end_mark) \ + (NODE_INIT((node),YAML_SEQUENCE_NODE,(node_tag),(start_mark),(end_mark)), \ + (node).data.sequence.items.start = (node_items_start), \ + (node).data.sequence.items.end = (node_items_end), \ + (node).data.sequence.items.top = (node_items_start), \ + (node).data.sequence.style = (node_style)) + +#define MAPPING_NODE_INIT(node,node_tag,node_pairs_start,node_pairs_end, \ + node_style,start_mark,end_mark) \ + (NODE_INIT((node),YAML_MAPPING_NODE,(node_tag),(start_mark),(end_mark)), \ + (node).data.mapping.pairs.start = (node_pairs_start), \ + (node).data.mapping.pairs.end = (node_pairs_end), \ + (node).data.mapping.pairs.top = (node_pairs_start), \ + (node).data.mapping.style = (node_style)) + diff --git a/libyaml/win32/config.h b/libyaml/win32/config.h new file mode 100644 index 00000000..c5515513 --- /dev/null +++ b/libyaml/win32/config.h @@ -0,0 +1,4 @@ +#define YAML_VERSION_MAJOR 0 +#define YAML_VERSION_MINOR 1 +#define YAML_VERSION_PATCH 5 +#define YAML_VERSION_STRING "0.1.5" diff --git a/libyaml/win32/yaml2008.vcproj b/libyaml/win32/yaml2008.vcproj new file mode 100644 index 00000000..1842c712 --- /dev/null +++ b/libyaml/win32/yaml2008.vcproj @@ -0,0 +1,215 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/source/AY8910.cpp b/source/AY8910.cpp index aa23ba1c..4305aa9b 100644 --- a/source/AY8910.cpp +++ b/source/AY8910.cpp @@ -33,6 +33,7 @@ #include "Applewin.h" // For g_fh #include "Mockingboard.h" // For g_uTimer1IrqCount +#include "YamlHelper.h" /* The AY white noise RNG algorithm is based on info from MAME's ay8910.c - * MAME's licence explicitly permits free use of info (even encourages it). @@ -947,6 +948,194 @@ sound_beeper( int is_tape, int on ) } #endif +// + +#define SS_YAML_KEY_AY8910 "AY8910" + +#define SS_YAML_KEY_TONE0_TICK "Tone0 Tick" +#define SS_YAML_KEY_TONE1_TICK "Tone1 Tick" +#define SS_YAML_KEY_TONE2_TICK "Tone2 Tick" +#define SS_YAML_KEY_TONE0_HIGH "Tone0 High" +#define SS_YAML_KEY_TONE1_HIGH "Tone1 High" +#define SS_YAML_KEY_TONE2_HIGH "Tone2 High" +#define SS_YAML_KEY_NOISE_TICK "Noise Tick" +#define SS_YAML_KEY_TONE_SUBCYCLES "Tone Subcycles" +#define SS_YAML_KEY_ENV_SUBCYCLES "Env Subcycles" +#define SS_YAML_KEY_ENV_INTERNAL_TICK "Env Internal Tick" +#define SS_YAML_KEY_ENV_TICK "Env Tick" +#define SS_YAML_KEY_TICK_INCR "Tick Incr" +#define SS_YAML_KEY_TONE0_PERIOD "Tone0 Period" +#define SS_YAML_KEY_TONE1_PERIOD "Tone1 Period" +#define SS_YAML_KEY_TONE2_PERIOD "Tone2 Period" +#define SS_YAML_KEY_NOISE_PERIOD "Noise Period" +#define SS_YAML_KEY_ENV_PERIOD "Env Period" +#define SS_YAML_KEY_RNG "RNG" +#define SS_YAML_KEY_NOISE_TOGGLE "Noise Toggle" +#define SS_YAML_KEY_ENV_FIRST "Env First" +#define SS_YAML_KEY_ENV_REV "Env Rev" +#define SS_YAML_KEY_ENV_COUNTER "Env Counter" + +#define SS_YAML_KEY_REGISTERS "Registers" +#define SS_YAML_KEY_REG_TONE0_PERIOD "Tone0 Period" +#define SS_YAML_KEY_REG_TONE1_PERIOD "Tone1 Period" +#define SS_YAML_KEY_REG_TONE2_PERIOD "Tone2 Period" +#define SS_YAML_KEY_REG_NOISE_PERIOD "Noise Period" +#define SS_YAML_KEY_REG_MIXER "Mixer" +#define SS_YAML_KEY_REG_VOL0 "Vol0" +#define SS_YAML_KEY_REG_VOL1 "Vol1" +#define SS_YAML_KEY_REG_VOL2 "Vol2" +#define SS_YAML_KEY_REG_ENV_PERIOD "Env Period" +#define SS_YAML_KEY_REG_ENV_SHAPE "Env Shape" +#define SS_YAML_KEY_REG_PORTA "PortA" +#define SS_YAML_KEY_REG_PORTB "PortB" + +#define SS_YAML_KEY_CHANGE "Change" +#define SS_YAML_VALUE_CHANGE_FORMAT "%d, %d, 0x%1X, 0x%02X" + +void CAY8910::SaveSnapshot(YamlSaveHelper& yamlSaveHelper, std::string& suffix) +{ + std::string unit = std::string(SS_YAML_KEY_AY8910) + suffix; + YamlSaveHelper::Label label(yamlSaveHelper, "%s:\n", unit.c_str()); + + yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_TONE0_TICK, ay_tone_tick[0]); + yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_TONE1_TICK, ay_tone_tick[1]); + yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_TONE2_TICK, ay_tone_tick[2]); + yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_TONE0_HIGH, ay_tone_high[0]); + yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_TONE1_HIGH, ay_tone_high[1]); + yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_TONE2_HIGH, ay_tone_high[2]); + yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_NOISE_TICK, ay_noise_tick); + yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_TONE_SUBCYCLES, ay_tone_subcycles); + yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_ENV_SUBCYCLES, ay_env_subcycles); + yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_ENV_INTERNAL_TICK, ay_env_internal_tick); + yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_ENV_TICK, ay_env_tick); + yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_TICK_INCR, ay_tick_incr); + yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_TONE0_PERIOD, ay_tone_period[0]); + yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_TONE1_PERIOD, ay_tone_period[1]); + yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_TONE2_PERIOD, ay_tone_period[2]); + yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_NOISE_PERIOD, ay_noise_period); + yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_RNG, rng); + yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_NOISE_TOGGLE, noise_toggle); + yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_ENV_FIRST, env_first); + yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_ENV_REV, env_rev); + yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_ENV_COUNTER, env_counter); + + // New label + { + YamlSaveHelper::Label registers(yamlSaveHelper, "%s:\n", SS_YAML_KEY_REGISTERS); + + yamlSaveHelper.Save("%s: 0x%03X\n", SS_YAML_KEY_REG_TONE0_PERIOD, (UINT)(sound_ay_registers[1]<<8) | sound_ay_registers[0]); + yamlSaveHelper.Save("%s: 0x%03X\n", SS_YAML_KEY_REG_TONE1_PERIOD, (UINT)(sound_ay_registers[3]<<8) | sound_ay_registers[2]); + yamlSaveHelper.Save("%s: 0x%03X\n", SS_YAML_KEY_REG_TONE2_PERIOD, (UINT)(sound_ay_registers[5]<<8) | sound_ay_registers[4]); + yamlSaveHelper.Save("%s: 0x%02X\n", SS_YAML_KEY_REG_NOISE_PERIOD, sound_ay_registers[6]); + yamlSaveHelper.Save("%s: 0x%02X\n", SS_YAML_KEY_REG_MIXER, sound_ay_registers[7]); + yamlSaveHelper.Save("%s: 0x%02X\n", SS_YAML_KEY_REG_VOL0, sound_ay_registers[8]); + yamlSaveHelper.Save("%s: 0x%02X\n", SS_YAML_KEY_REG_VOL1, sound_ay_registers[9]); + yamlSaveHelper.Save("%s: 0x%02X\n", SS_YAML_KEY_REG_VOL2, sound_ay_registers[10]); + yamlSaveHelper.Save("%s: 0x%04X\n", SS_YAML_KEY_REG_ENV_PERIOD, (UINT)(sound_ay_registers[12]<<8) | sound_ay_registers[11]); + yamlSaveHelper.Save("%s: 0x%01X\n", SS_YAML_KEY_REG_ENV_SHAPE, sound_ay_registers[13]); + yamlSaveHelper.Save("%s: 0x%02X\n", SS_YAML_KEY_REG_PORTA, sound_ay_registers[14]); + yamlSaveHelper.Save("%s: 0x%02X\n", SS_YAML_KEY_REG_PORTB, sound_ay_registers[15]); + } + + // New label + if (ay_change_count) + { + YamlSaveHelper::Label change(yamlSaveHelper, "%s:\n", SS_YAML_KEY_CHANGE); + + for (int i=0; i> 8) & 0xf; + period = (USHORT) yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_REG_TONE1_PERIOD); + sound_ay_registers[2] = period & 0xff; + sound_ay_registers[3] = (period >> 8) & 0xf; + period = (USHORT) yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_REG_TONE2_PERIOD); + sound_ay_registers[4] = period & 0xff; + sound_ay_registers[5] = (period >> 8) & 0xf; + sound_ay_registers[6] = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_REG_NOISE_PERIOD); + sound_ay_registers[7] = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_REG_MIXER); + sound_ay_registers[8] = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_REG_VOL0); + sound_ay_registers[9] = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_REG_VOL1); + sound_ay_registers[10] = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_REG_VOL2); + period = (USHORT) yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_REG_ENV_PERIOD); + sound_ay_registers[11] = period & 0xff; + sound_ay_registers[12] = period >> 8; + sound_ay_registers[13] = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_REG_ENV_SHAPE); + sound_ay_registers[14] = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_REG_PORTA); + sound_ay_registers[15] = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_REG_PORTB); + + yamlLoadHelper.PopMap(); + + ay_change_count = 0; + if (yamlLoadHelper.GetSubMap(SS_YAML_KEY_CHANGE)) + { + while(1) + { + char szIndex[7]; + sprintf_s(szIndex, sizeof(szIndex), "0x%04X", ay_change_count); + + bool bFound; + std::string value = yamlLoadHelper.GetMapValueSTRING_NoThrow(szIndex, bFound); + if (!bFound) + break; // done + + if(4 != sscanf_s(value.c_str(), SS_YAML_VALUE_CHANGE_FORMAT, + &ay_change[ay_change_count].tstates, + &ay_change[ay_change_count].ofs, + &ay_change[ay_change_count].reg, + &ay_change[ay_change_count].val)) + throw std::string("Card: AY8910: Failed to scanf change list"); + + ay_change_count++; + if (ay_change_count > AY_CHANGE_MAX) + throw std::string("Card: AY8910: Too many changes"); + } + + yamlLoadHelper.PopMap(); + } + + yamlLoadHelper.PopMap(); + + return true; +} + +// + // disable warning C4200: zero-sized array in struct/union #pragma warning(disable: 4200) @@ -1160,6 +1349,23 @@ BYTE* AY8910_GetRegsPtr(UINT uChip) return g_AY8910[uChip].GetAYRegsPtr(); } +UINT AY8910_SaveSnapshot(YamlSaveHelper& yamlSaveHelper, UINT uChip, std::string& suffix) +{ + if (uChip >= MAX_8910) + return 0; + + g_AY8910[uChip].SaveSnapshot(yamlSaveHelper, suffix); + return 1; +} + +UINT AY8910_LoadSnapshot(YamlLoadHelper& yamlLoadHelper, UINT uChip, std::string& suffix) +{ + if (uChip >= MAX_8910) + return 0; + + return g_AY8910[uChip].LoadSnapshot(yamlLoadHelper, suffix) ? 1 : 0; +} + UINT AY8910_GetSnapshot(const HANDLE hFile, UINT uChip) { if (uChip >= MAX_8910) diff --git a/source/AY8910.h b/source/AY8910.h index 0b7fd50f..f33e0630 100644 --- a/source/AY8910.h +++ b/source/AY8910.h @@ -17,6 +17,8 @@ BYTE* AY8910_GetRegsPtr(UINT uChip); void AY8910UpdateSetCycles(); +UINT AY8910_SaveSnapshot(class YamlSaveHelper& yamlSaveHelper, UINT uChip, std::string& suffix); +UINT AY8910_LoadSnapshot(class YamlLoadHelper& yamlLoadHelper, UINT uChip, std::string& suffix); UINT AY8910_GetSnapshot(const HANDLE hFile, UINT uChip); UINT AY8910_SetSnapshot(const HANDLE hFile, UINT uChip); @@ -46,6 +48,8 @@ public: void sound_frame( void ); BYTE* GetAYRegsPtr( void ) { return &sound_ay_registers[0]; } static void SetCLK( double CLK ) { m_fCurrentCLK_AY8910 = CLK; } + void SaveSnapshot(class YamlSaveHelper& yamlSaveHelper, std::string& suffix); + bool LoadSnapshot(class YamlLoadHelper& yamlLoadHelper, std::string& suffix); UINT GetSnapshot(const HANDLE hFile); UINT SetSnapshot(const HANDLE hFile); diff --git a/source/CPU.cpp b/source/CPU.cpp index 704285ef..f693f053 100644 --- a/source/CPU.cpp +++ b/source/CPU.cpp @@ -103,6 +103,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #include "Debugger\Debug.h" #include "SaveState_Structs_v2.h" +#include "YamlHelper.h" #define AF_SIGN 0x80 @@ -405,10 +406,17 @@ static __forceinline void CheckInterruptSources(ULONG uExecutedCycles) //=========================================================================== +static bool IsCpu6502(void) +{ + return IS_APPLE2 || + (g_Apple2Type == A2TYPE_APPLE2E) || + IS_CLONE(); // NB. All Pravets clones are 6502 (GH#307) +} + static DWORD InternalCpuExecute (DWORD uTotalCycles) { - if (IS_APPLE2 || (g_Apple2Type == A2TYPE_APPLE2E)) - return Cpu6502(uTotalCycles); // Apple ][, ][+, //e + if (IsCpu6502()) + return Cpu6502(uTotalCycles); // Apple ][, ][+, //e, Clones else return Cpu65C02(uTotalCycles); // Enhanced Apple //e } @@ -659,6 +667,61 @@ void CpuSetSnapshot_v1(const BYTE A, const BYTE X, const BYTE Y, const BYTE P, c // +#define SS_YAML_KEY_CPU_TYPE "Type" +#define SS_YAML_KEY_REGA "A" +#define SS_YAML_KEY_REGX "X" +#define SS_YAML_KEY_REGY "Y" +#define SS_YAML_KEY_REGP "P" +#define SS_YAML_KEY_REGS "S" +#define SS_YAML_KEY_REGPC "PC" +#define SS_YAML_KEY_CUMULATIVECYCLES "Cumulative Cycles" + +#define SS_YAML_VALUE_6502 "6502" +#define SS_YAML_VALUE_65C02 "65C02" + +static std::string CpuGetSnapshotStructName(void) +{ + static const std::string name("CPU"); + return name; +} + +void CpuSaveSnapshot(YamlSaveHelper& yamlSaveHelper) +{ + regs.ps |= (AF_RESERVED | AF_BREAK); + + YamlSaveHelper::Label state(yamlSaveHelper, "%s:\n", CpuGetSnapshotStructName().c_str()); + yamlSaveHelper.Save("%s: %s # NB. Currently ignored\n", SS_YAML_KEY_CPU_TYPE, IsCpu6502() ? SS_YAML_VALUE_6502 : SS_YAML_VALUE_65C02); + yamlSaveHelper.Save("%s: 0x%02X\n", SS_YAML_KEY_REGA, regs.a); + yamlSaveHelper.Save("%s: 0x%02X\n", SS_YAML_KEY_REGX, regs.x); + yamlSaveHelper.Save("%s: 0x%02X\n", SS_YAML_KEY_REGY, regs.y); + yamlSaveHelper.Save("%s: 0x%02X\n", SS_YAML_KEY_REGP, regs.ps); + yamlSaveHelper.Save("%s: 0x%02X\n", SS_YAML_KEY_REGS, (BYTE) regs.sp); + yamlSaveHelper.Save("%s: 0x%04X\n", SS_YAML_KEY_REGPC, regs.pc); + yamlSaveHelper.Save("%s: 0x%016llX\n", SS_YAML_KEY_CUMULATIVECYCLES, g_nCumulativeCycles); +} + +void CpuLoadSnapshot(YamlLoadHelper& yamlLoadHelper) +{ + if (!yamlLoadHelper.GetSubMap(CpuGetSnapshotStructName())) + return; + + yamlLoadHelper.GetMapValueSTRING(SS_YAML_KEY_CPU_TYPE); // consume - not currently used + regs.a = (BYTE) yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_REGA); + regs.x = (BYTE) yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_REGX); + regs.y = (BYTE) yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_REGY); + regs.ps = (BYTE) yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_REGP) | (AF_RESERVED | AF_BREAK); + regs.sp = (USHORT) ((yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_REGS) & 0xff) | 0x100); + regs.pc = (USHORT) yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_REGPC); + + CpuIrqReset(); + CpuNmiReset(); + g_nCumulativeCycles = yamlLoadHelper.GetMapValueUINT64(SS_YAML_KEY_CUMULATIVECYCLES); + + yamlLoadHelper.PopMap(); +} + +// + void CpuGetSnapshot(SS_CPU6502_v2& CPU) { regs.ps |= (AF_RESERVED | AF_BREAK); diff --git a/source/CPU.h b/source/CPU.h index 7b60cd7e..38c46917 100644 --- a/source/CPU.h +++ b/source/CPU.h @@ -28,6 +28,8 @@ void CpuNmiAssert(eIRQSRC Device); void CpuNmiDeassert(eIRQSRC Device); void CpuReset (); void CpuSetSnapshot_v1(const BYTE A, const BYTE X, const BYTE Y, const BYTE P, const BYTE SP, const USHORT PC, const unsigned __int64 CumulativeCycles); +void CpuSaveSnapshot(class YamlSaveHelper& yamlSaveHelper); +void CpuLoadSnapshot(class YamlLoadHelper& yamlLoadHelper); void CpuGetSnapshot(struct SS_CPU6502_v2& CPU); void CpuSetSnapshot(const struct SS_CPU6502_v2& CPU); diff --git a/source/Configuration/PropertySheetHelper.cpp b/source/Configuration/PropertySheetHelper.cpp index ee1e551b..5f684fc0 100644 --- a/source/Configuration/PropertySheetHelper.cpp +++ b/source/Configuration/PropertySheetHelper.cpp @@ -186,7 +186,7 @@ void CPropertySheetHelper::GetDiskBaseNameWithAWS(TCHAR* pszFilename) if (pDiskName && pDiskName[0]) { strcpy(pszFilename, pDiskName); - strcpy(&pszFilename[strlen(pDiskName)], ".aws"); + strcpy(&pszFilename[strlen(pDiskName)], ".aws.yaml"); } } @@ -230,9 +230,17 @@ int CPropertySheetHelper::SaveStateSelectImage(HWND hWindow, TCHAR* pszTitle, bo ofn.lStructSize = sizeof(OPENFILENAME); ofn.hwndOwner = hWindow; ofn.hInstance = g_hInstance; - ofn.lpstrFilter = TEXT("Save State files (*.aws)\0*.aws\0") - TEXT("All Files\0*.*\0"); - ofn.lpstrFile = szFilename; + if (bSave) + { + ofn.lpstrFilter = TEXT("Save State files (*.aws.yaml)\0*.aws.yaml\0"); + TEXT("All Files\0*.*\0"); + } + else + { + ofn.lpstrFilter = TEXT("Save State files (*.aws,*.aws.yaml)\0*.aws;*.aws.yaml\0"); + TEXT("All Files\0*.*\0"); + } + ofn.lpstrFile = szFilename; // Dialog strips the last .EXT from this string (eg. file.aws.yaml is displayed as: file.aws ofn.nMaxFile = MAX_PATH; ofn.lpstrInitialDir = szDirectory; ofn.Flags = OFN_PATHMUSTEXIST | OFN_HIDEREADONLY; @@ -245,11 +253,16 @@ int CPropertySheetHelper::SaveStateSelectImage(HWND hWindow, TCHAR* pszTitle, bo if (bSave) // Only for saving (allow loading of any file for backwards compatibility) { // Append .aws if it's not there - const char szAWS_EXT[] = ".aws"; + const char szAWS_EXT1[] = ".aws"; + const char szAWS_EXT2[] = ".aws.yaml"; + const char szAWS_EXT3[] = ".yaml"; const UINT uStrLenFile = strlen(&szFilename[ofn.nFileOffset]); - const UINT uStrLenExt = strlen(szAWS_EXT); - if ((uStrLenFile <= uStrLenExt) || (strcmp(&szFilename[ofn.nFileOffset+uStrLenFile-uStrLenExt], szAWS_EXT) != 0)) - strcpy(&szFilename[ofn.nFileOffset+uStrLenFile], szAWS_EXT); + const UINT uStrLenExt1 = strlen(szAWS_EXT1); + const UINT uStrLenExt2 = strlen(szAWS_EXT2); + if ((uStrLenFile <= uStrLenExt1) || (strcmp(&szFilename[ofn.nFileOffset+uStrLenFile-uStrLenExt1], szAWS_EXT1) == 0)) + strcpy(&szFilename[ofn.nFileOffset+uStrLenFile], szAWS_EXT3); // "file.aws" += ".yaml" + else if ((uStrLenFile <= uStrLenExt2) || (strcmp(&szFilename[ofn.nFileOffset+uStrLenFile-uStrLenExt2], szAWS_EXT2) != 0)) + strcpy(&szFilename[ofn.nFileOffset+uStrLenFile], szAWS_EXT2); // "file" += "aws.yaml" } strcpy(m_szSSNewFilename, &szFilename[ofn.nFileOffset]); diff --git a/source/Configuration/PropertySheetHelper.h b/source/Configuration/PropertySheetHelper.h index 42503688..52d08420 100644 --- a/source/Configuration/PropertySheetHelper.h +++ b/source/Configuration/PropertySheetHelper.h @@ -18,7 +18,6 @@ public: void SetSlot5(SS_CARDTYPE NewCardType); std::string BrowseToFile(HWND hWindow, TCHAR* pszTitle, TCHAR* REGVALUE,TCHAR* FILEMASKS); void SaveStateUpdate(); - void GetDiskBaseNameWithAWS(TCHAR* pszFilename); int SaveStateSelectImage(HWND hWindow, TCHAR* pszTitle, bool bSave); void PostMsgAfterClose(HWND hWnd, PAGETYPE page); @@ -49,6 +48,7 @@ private: void RestoreCurrentConfig(void); std::string GetSlot(const UINT uSlot); std::string GetCardName(const SS_CARDTYPE CardType); + void GetDiskBaseNameWithAWS(TCHAR* pszFilename); PAGETYPE m_LastPage; UINT32 m_bmPages; diff --git a/source/Disk.cpp b/source/Disk.cpp index f0541d5f..a6070338 100644 --- a/source/Disk.cpp +++ b/source/Disk.cpp @@ -40,6 +40,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #include "Memory.h" #include "Registry.h" #include "Video.h" +#include "YamlHelper.h" #include "..\resource\resource.h" @@ -547,7 +548,7 @@ void DiskInitialize(void) { int loop = NUM_DRIVES; while (loop--) - ZeroMemory(&g_aFloppyDisk[loop],sizeof(Disk_t )); + ZeroMemory(&g_aFloppyDisk[loop], sizeof(Disk_t)); TCHAR imagefilename[MAX_PATH]; _tcscpy(imagefilename,g_sProgramDir); @@ -1099,7 +1100,7 @@ int DiskSetSnapshot_v1(const SS_CARD_DISK2* const pSS) for(UINT i=0; i pNullTrack( new BYTE [NIBBLES_PER_TRACK] ); + memset(pNullTrack.get(), 0, NIBBLES_PER_TRACK); + LPBYTE pTrack = g_aFloppyDisk[unit].trackimage ? g_aFloppyDisk[unit].trackimage : pNullTrack.get(); + yamlSaveHelper.SaveMapValueMemory(pTrack, NIBBLES_PER_TRACK); + } +} + +void DiskSaveSnapshot(class YamlSaveHelper& yamlSaveHelper) +{ + YamlSaveHelper::Slot slot(yamlSaveHelper, DiskGetSnapshotCardName(), g_uSlot, 1); + + YamlSaveHelper::Label state(yamlSaveHelper, "%s:\n", SS_YAML_KEY_STATE); + yamlSaveHelper.Save("%s: 0x%1X\n", SS_YAML_KEY_PHASES, phases); + yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_CURRENT_DRIVE, currdrive); + yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_DISK_ACCESSED, diskaccessed); + yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_ENHANCE_DISK, enhancedisk); + yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_FLOPPY_LATCH, floppylatch); + yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_FLOPPY_MOTOR_ON, floppymotoron); + yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_FLOPPY_WRITE_MODE, floppywritemode); + + DiskSaveSnapshotDisk2Unit(yamlSaveHelper, DRIVE_1); + DiskSaveSnapshotDisk2Unit(yamlSaveHelper, DRIVE_2); +} + +static void DiskLoadSnapshotDriveUnit(YamlLoadHelper& yamlLoadHelper, UINT unit) +{ + std::string disk2UnitName = std::string(SS_YAML_KEY_DISK2UNIT) + (unit == DRIVE_1 ? std::string("0") : std::string("1")); + if (!yamlLoadHelper.GetSubMap(disk2UnitName)) + throw std::string("Card: Expected key: ") + disk2UnitName; + + bool bImageError = false; + + std::string filename = yamlLoadHelper.GetMapValueSTRING(SS_YAML_KEY_FILENAME).c_str(); + if (!filename.empty()) + { + DWORD dwAttributes = GetFileAttributes(filename.c_str()); + if(dwAttributes == INVALID_FILE_ATTRIBUTES) + { + // Get user to browse for file + DiskSelectImage(unit, filename.c_str()); + + dwAttributes = GetFileAttributes(filename.c_str()); + } + + bImageError = (dwAttributes == INVALID_FILE_ATTRIBUTES); + if (!bImageError) + { + if(DiskInsert(unit, filename.c_str(), dwAttributes & FILE_ATTRIBUTE_READONLY, IMAGE_DONT_CREATE) != eIMAGE_ERROR_NONE) + bImageError = true; + + // DiskInsert() zeros g_aFloppyDisk[unit], then sets up: + // . imagename + // . fullname + // . writeprotected + } + } + + g_aFloppyDisk[unit].track = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_TRACK); + g_aFloppyDisk[unit].phase = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_PHASE); + g_aFloppyDisk[unit].byte = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_BYTE); + yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_WRITE_PROTECTED); // Consume + g_aFloppyDisk[unit].spinning = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_SPINNING); + g_aFloppyDisk[unit].writelight = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_WRITE_LIGHT); + g_aFloppyDisk[unit].nibbles = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_NIBBLES); + g_aFloppyDisk[unit].trackimagedata = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_TRACK_IMAGE_DATA); + g_aFloppyDisk[unit].trackimagedirty = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_TRACK_IMAGE_DIRTY); + + if (!yamlLoadHelper.GetSubMap(SS_YAML_KEY_TRACK_IMAGE)) + throw disk2UnitName + std::string(": Missing: ") + std::string(SS_YAML_KEY_TRACK_IMAGE); + std::auto_ptr pTrack( new BYTE [NIBBLES_PER_TRACK] ); + yamlLoadHelper.GetMapValueMemory(pTrack.get(), NIBBLES_PER_TRACK); + + yamlLoadHelper.PopMap(); + yamlLoadHelper.PopMap(); + + // + + if (!filename.empty() && !bImageError) + { + if ((g_aFloppyDisk[unit].trackimage == NULL) && g_aFloppyDisk[unit].nibbles) + AllocTrack(unit); + + if (g_aFloppyDisk[unit].trackimage == NULL) + bImageError = true; + else + memcpy(g_aFloppyDisk[unit].trackimage, pTrack.get(), NIBBLES_PER_TRACK); + } + + if (bImageError) + { + g_aFloppyDisk[unit].trackimagedata = 0; + g_aFloppyDisk[unit].trackimagedirty = 0; + g_aFloppyDisk[unit].nibbles = 0; + } +} + +bool DiskLoadSnapshot(class YamlLoadHelper& yamlLoadHelper, UINT slot, UINT version) +{ + if (slot != 6) // fixme + throw std::string("Card: wrong slot"); + + if (version != 1) + throw std::string("Card: wrong version"); + + phases = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_PHASES); + currdrive = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_CURRENT_DRIVE); + diskaccessed = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_DISK_ACCESSED); + enhancedisk = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_ENHANCE_DISK); + floppylatch = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_FLOPPY_LATCH); + floppymotoron = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_FLOPPY_MOTOR_ON); + floppywritemode = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_FLOPPY_WRITE_MODE); + + // Eject all disks first in case Drive-2 contains disk to be inserted into Drive-1 + for(UINT i=0; i 0x7F || (activeAuxBank+1) > numAuxBanks) + throw std::string(SS_YAML_KEY_UNIT ": AuxSlot: Bad aux slot card state"); + } + else + { + // todo: support empty slot + throw std::string(SS_YAML_KEY_UNIT ": AuxSlot: Unknown card: " + card); + } + + g_uMaxExPages = numAuxBanks; + g_uActiveBank = activeAuxBank; + + // + + for(UINT uBank = 1; uBank <= g_uMaxExPages; uBank++) + { + LPBYTE pBank = MemGetBankPtr(uBank); + if (!pBank) + { + pBank = RWpages[uBank-1] = (LPBYTE) VirtualAlloc(NULL,_6502_MEM_END+1,MEM_COMMIT,PAGE_READWRITE); + if (!pBank) + throw std::string("Card: mem alloc failed"); + } + + // "Auxiliary Memory Bankxx" + char szBank[3]; + sprintf(szBank, "%02X", uBank-1); + std::string auxMemName = MemGetSnapshotAuxMemStructName() + szBank; + + if (!yamlLoadHelper.GetSubMap(auxMemName)) + throw std::string("Memory: Missing map name: " + auxMemName); + + yamlLoadHelper.GetMapValueMemory(pBank, _6502_MEM_END+1); + + yamlLoadHelper.PopMap(); + } + + memaux = RWpages[g_uActiveBank]; + // NB. MemUpdatePaging(TRUE) called at end of Snapshot_LoadState_v2() + + return true; +} + +// + void MemGetSnapshot(SS_BaseMemory_v2& Memory) { Memory.dwMemMode = memmode; diff --git a/source/Memory.h b/source/Memory.h index bdd4fb19..8e5ca745 100644 --- a/source/Memory.h +++ b/source/Memory.h @@ -55,6 +55,11 @@ void MemResetPaging (); void MemUpdatePaging(BOOL initialize); LPVOID MemGetSlotParameters (UINT uSlot); void MemSetSnapshot_v1(const DWORD MemMode, const BOOL LastWriteRam, const BYTE* const pMemMain, const BYTE* const pMemAux); +std::string MemGetSnapshotUnitAuxSlotName(void); +void MemSaveSnapshot(class YamlSaveHelper& yamlSaveHelper); +bool MemLoadSnapshot(class YamlLoadHelper& yamlLoadHelper); +void MemSaveSnapshotAux(class YamlSaveHelper& yamlSaveHelper); +bool MemLoadSnapshotAux(class YamlLoadHelper& yamlLoadHelper, UINT version); void MemGetSnapshot(struct SS_BaseMemory_v2& Memory); void MemSetSnapshot(const struct SS_BaseMemory_v2& Memory); void MemGetSnapshotAux(const HANDLE hFile); diff --git a/source/Mockingboard.cpp b/source/Mockingboard.cpp index fa2e5797..1f79bf35 100644 --- a/source/Mockingboard.cpp +++ b/source/Mockingboard.cpp @@ -85,6 +85,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #include "Memory.h" #include "Mockingboard.h" #include "SoundCore.h" +#include "YamlHelper.h" #include "AY8910.h" #include "SSI263Phonemes.h" @@ -539,7 +540,7 @@ void SSI263_Play(unsigned int nPhoneme); #if 0 typedef struct { - BYTE DurationPhonome; + BYTE DurationPhoneme; BYTE Inflection; // I10..I3 BYTE RateInflection; BYTE CtrlArtAmp; @@ -603,7 +604,7 @@ static void SSI263_Write(BYTE nDevice, BYTE nReg, BYTE nValue) } pMB->SpeechChip.CurrentMode &= ~1; // Clear SSI263's D7 pin - pMB->SpeechChip.DurationPhonome = nValue; + pMB->SpeechChip.DurationPhoneme = nValue; g_nSSI263Device = nDevice; @@ -635,7 +636,7 @@ static void SSI263_Write(BYTE nDevice, BYTE nReg, BYTE nValue) if(g_fh) fprintf(g_fh, "CTRL = %d, ART = 0x%02X, AMP=0x%02X\n", nValue>>7, (nValue&ARTICULATION_MASK)>>4, nValue&LITUDE_MASK); #endif if((pMB->SpeechChip.CtrlArtAmp & CONTROL_MASK) && !(nValue & CONTROL_MASK)) // H->L - pMB->SpeechChip.CurrentMode = pMB->SpeechChip.DurationPhonome & DURATION_MODE_MASK; + pMB->SpeechChip.CurrentMode = pMB->SpeechChip.DurationPhoneme & DURATION_MODE_MASK; pMB->SpeechChip.CtrlArtAmp = nValue; break; case SSI_FILFREQ: @@ -1833,7 +1834,7 @@ int MB_SetSnapshot_v1(const SS_CARD_MOCKINGBOARD_v1* const pSS, const DWORD /*dw // FIX THIS: // . Speech chip could be Votrax instead // . Is this IRQ compatible with Phasor? - if(pMB->SpeechChip.DurationPhonome) + if(pMB->SpeechChip.DurationPhoneme) { g_nSSI263Device = nDeviceNum; @@ -1889,6 +1890,325 @@ static UINT DoReadFile(const HANDLE hFile, void* const pData, const UINT Length) //=========================================================================== +const UINT NUM_MB_UNITS = 2; +const UINT NUM_PHASOR_UNITS = 2; + +#define SS_YAML_KEY_MB_UNIT "Unit" +#define SS_YAML_KEY_SY6522 "SY6522" +#define SS_YAML_KEY_SY6522_REG_ORB "ORB" +#define SS_YAML_KEY_SY6522_REG_ORA "ORA" +#define SS_YAML_KEY_SY6522_REG_DDRB "DDRB" +#define SS_YAML_KEY_SY6522_REG_DDRA "DDRA" +#define SS_YAML_KEY_SY6522_REG_T1_COUNTER "Timer1 Counter" +#define SS_YAML_KEY_SY6522_REG_T1_LATCH "Timer1 Latch" +#define SS_YAML_KEY_SY6522_REG_T2_COUNTER "Timer2 Counter" +#define SS_YAML_KEY_SY6522_REG_T2_LATCH "Timer2 Latch" +#define SS_YAML_KEY_SY6522_REG_SERIAL_SHIFT "Serial Shift" +#define SS_YAML_KEY_SY6522_REG_ACR "ACR" +#define SS_YAML_KEY_SY6522_REG_PCR "PCR" +#define SS_YAML_KEY_SY6522_REG_IFR "IFR" +#define SS_YAML_KEY_SY6522_REG_IER "IER" +#define SS_YAML_KEY_SSI263 "SSI263" +#define SS_YAML_KEY_SSI263_REG_DUR_PHON "Duration / Phoneme" +#define SS_YAML_KEY_SSI263_REG_INF "Inflection" +#define SS_YAML_KEY_SSI263_REG_RATE_INF "Rate / Inflection" +#define SS_YAML_KEY_SSI263_REG_CTRL_ART_AMP "Control / Articulation / Amplitude" +#define SS_YAML_KEY_SSI263_REG_FILTER_FREQ "Filter Frequency" +#define SS_YAML_KEY_SSI263_REG_CURRENT_MODE "Current Mode" +#define SS_YAML_KEY_AY_CURR_REG "AY Current Register" +#define SS_YAML_KEY_TIMER1_IRQ "Timer1 IRQ Pending" +#define SS_YAML_KEY_TIMER2_IRQ "Timer2 IRQ Pending" +#define SS_YAML_KEY_SPEECH_IRQ "Speech IRQ Pending" + +#define SS_YAML_KEY_PHASOR_UNIT "Unit" +#define SS_YAML_KEY_PHASOR_CLOCK_SCALE_FACTOR "Clock Scale Factor" +#define SS_YAML_KEY_PHASOR_MODE "Mode" + +std::string MB_GetSnapshotCardName(void) +{ + static const std::string name("Mockingboard C"); + return name; +} + +std::string Phasor_GetSnapshotCardName(void) +{ + static const std::string name("Phasor"); + return name; +} + +static void SaveSnapshotSY6522(YamlSaveHelper& yamlSaveHelper, SY6522& sy6522) +{ + YamlSaveHelper::Label label(yamlSaveHelper, "%s:\n", SS_YAML_KEY_SY6522); + + yamlSaveHelper.Save("%s: 0x%02X\n", SS_YAML_KEY_SY6522_REG_ORB, sy6522.ORB); + yamlSaveHelper.Save("%s: 0x%02X\n", SS_YAML_KEY_SY6522_REG_ORA, sy6522.ORA); + yamlSaveHelper.Save("%s: 0x%02X\n", SS_YAML_KEY_SY6522_REG_DDRB, sy6522.DDRB); + yamlSaveHelper.Save("%s: 0x%02X\n", SS_YAML_KEY_SY6522_REG_DDRA, sy6522.DDRA); + yamlSaveHelper.Save("%s: 0x%04X\n", SS_YAML_KEY_SY6522_REG_T1_COUNTER, sy6522.TIMER1_COUNTER); + yamlSaveHelper.Save("%s: 0x%04X\n", SS_YAML_KEY_SY6522_REG_T1_LATCH, sy6522.TIMER1_LATCH); + yamlSaveHelper.Save("%s: 0x%04X\n", SS_YAML_KEY_SY6522_REG_T2_COUNTER, sy6522.TIMER2_COUNTER); + yamlSaveHelper.Save("%s: 0x%04X\n", SS_YAML_KEY_SY6522_REG_T2_LATCH, sy6522.TIMER2_LATCH); + yamlSaveHelper.Save("%s: 0x%02X\n", SS_YAML_KEY_SY6522_REG_SERIAL_SHIFT, sy6522.SERIAL_SHIFT); + yamlSaveHelper.Save("%s: 0x%02X\n", SS_YAML_KEY_SY6522_REG_ACR, sy6522.ACR); + yamlSaveHelper.Save("%s: 0x%02X\n", SS_YAML_KEY_SY6522_REG_PCR, sy6522.PCR); + yamlSaveHelper.Save("%s: 0x%02X\n", SS_YAML_KEY_SY6522_REG_IFR, sy6522.IFR); + yamlSaveHelper.Save("%s: 0x%02X\n", SS_YAML_KEY_SY6522_REG_IER, sy6522.IER); + // NB. No need to write ORA_NO_HS, since same data as ORA, just without handshake +} + +static void SaveSnapshotSSI263(YamlSaveHelper& yamlSaveHelper, SSI263A& ssi263) +{ + YamlSaveHelper::Label label(yamlSaveHelper, "%s:\n", SS_YAML_KEY_SSI263); + + yamlSaveHelper.Save("%s: 0x%02X\n", SS_YAML_KEY_SSI263_REG_DUR_PHON, ssi263.DurationPhoneme); + yamlSaveHelper.Save("%s: 0x%02X\n", SS_YAML_KEY_SSI263_REG_INF, ssi263.Inflection); + yamlSaveHelper.Save("%s: 0x%02X\n", SS_YAML_KEY_SSI263_REG_RATE_INF, ssi263.RateInflection); + yamlSaveHelper.Save("%s: 0x%02X\n", SS_YAML_KEY_SSI263_REG_CTRL_ART_AMP, ssi263.CtrlArtAmp); + yamlSaveHelper.Save("%s: 0x%02X\n", SS_YAML_KEY_SSI263_REG_FILTER_FREQ, ssi263.FilterFreq); + yamlSaveHelper.Save("%s: 0x%02X\n", SS_YAML_KEY_SSI263_REG_CURRENT_MODE, ssi263.CurrentMode); +} + +void MB_SaveSnapshot(YamlSaveHelper& yamlSaveHelper, const UINT uSlot) +{ + const UINT nMbCardNum = uSlot - SLOT4; + UINT nDeviceNum = nMbCardNum*2; + SY6522_AY8910* pMB = &g_MB[nDeviceNum]; + + YamlSaveHelper::Slot slot(yamlSaveHelper, MB_GetSnapshotCardName(), uSlot, 1); // fixme: object should be just 1 Mockingboard card & it will know its slot + + YamlSaveHelper::Label state(yamlSaveHelper, "%s:\n", SS_YAML_KEY_STATE); + + for(UINT i=0; isy6522); + AY8910_SaveSnapshot(yamlSaveHelper, nDeviceNum, std::string("")); + SaveSnapshotSSI263(yamlSaveHelper, pMB->SpeechChip); + + yamlSaveHelper.Save("%s: 0x%1X\n", SS_YAML_KEY_AY_CURR_REG, pMB->nAYCurrentRegister); + yamlSaveHelper.Save("%s: %d # Not supported\n", SS_YAML_KEY_TIMER1_IRQ, 0); + yamlSaveHelper.Save("%s: %d # Not supported\n", SS_YAML_KEY_TIMER2_IRQ, 0); + yamlSaveHelper.Save("%s: %d # Not supported\n", SS_YAML_KEY_SPEECH_IRQ, 0); + + nDeviceNum++; + pMB++; + } +} + +static void LoadSnapshotSY6522(YamlLoadHelper& yamlLoadHelper, SY6522& sy6522) +{ + if (!yamlLoadHelper.GetSubMap(SS_YAML_KEY_SY6522)) + throw std::string("Card: Expected key: ") + std::string(SS_YAML_KEY_SY6522); + + sy6522.ORB = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_SY6522_REG_ORB); + sy6522.ORA = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_SY6522_REG_ORA); + sy6522.DDRB = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_SY6522_REG_DDRB); + sy6522.DDRA = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_SY6522_REG_DDRA); + sy6522.TIMER1_COUNTER.w = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_SY6522_REG_T1_COUNTER); + sy6522.TIMER1_LATCH.w = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_SY6522_REG_T1_LATCH); + sy6522.TIMER2_COUNTER.w = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_SY6522_REG_T2_COUNTER); + sy6522.TIMER2_LATCH.w = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_SY6522_REG_T2_LATCH); + sy6522.SERIAL_SHIFT = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_SY6522_REG_SERIAL_SHIFT); + sy6522.ACR = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_SY6522_REG_ACR); + sy6522.PCR = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_SY6522_REG_PCR); + sy6522.IFR = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_SY6522_REG_IFR); + sy6522.IER = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_SY6522_REG_IER); + sy6522.ORA_NO_HS = 0; // Not saved + + yamlLoadHelper.PopMap(); +} + +static void LoadSnapshotSSI263(YamlLoadHelper& yamlLoadHelper, SSI263A& ssi263) +{ + if (!yamlLoadHelper.GetSubMap(SS_YAML_KEY_SSI263)) + throw std::string("Card: Expected key: ") + std::string(SS_YAML_KEY_SSI263); + + ssi263.DurationPhoneme = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_SSI263_REG_DUR_PHON); + ssi263.Inflection = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_SSI263_REG_INF); + ssi263.RateInflection = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_SSI263_REG_RATE_INF); + ssi263.CtrlArtAmp = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_SSI263_REG_CTRL_ART_AMP); + ssi263.FilterFreq = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_SSI263_REG_FILTER_FREQ); + ssi263.CurrentMode = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_SSI263_REG_CURRENT_MODE); + + yamlLoadHelper.PopMap(); +} + +bool MB_LoadSnapshot(YamlLoadHelper& yamlLoadHelper, UINT slot, UINT version) +{ + if (slot != 4 && slot != 5) // fixme + throw std::string("Card: wrong slot"); + + if (version != 1) + throw std::string("Card: wrong version"); + + AY8910UpdateSetCycles(); + + const UINT nMbCardNum = slot - SLOT4; + UINT nDeviceNum = nMbCardNum*2; + SY6522_AY8910* pMB = &g_MB[nDeviceNum]; + + g_nSSI263Device = 0; + g_nCurrentActivePhoneme = -1; + + for(UINT i=0; isy6522); + AY8910_LoadSnapshot(yamlLoadHelper, nDeviceNum, std::string("")); + LoadSnapshotSSI263(yamlLoadHelper, pMB->SpeechChip); + + pMB->nAYCurrentRegister = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_AY_CURR_REG); + yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_TIMER1_IRQ); // Consume + yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_TIMER2_IRQ); // Consume + yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_SPEECH_IRQ); // Consume + + yamlLoadHelper.PopMap(); + + // + + StartTimer(pMB); // Attempt to start timer + + // Crude - currently only support a single speech chip + // FIX THIS: + // . Speech chip could be Votrax instead + // . Is this IRQ compatible with Phasor? + if(pMB->SpeechChip.DurationPhoneme) + { + g_nSSI263Device = nDeviceNum; + + if((pMB->SpeechChip.CurrentMode != MODE_IRQ_DISABLED) && (pMB->sy6522.PCR == 0x0C) && (pMB->sy6522.IER & IxR_PERIPHERAL)) + { + pMB->sy6522.IFR |= IxR_PERIPHERAL; + UpdateIFR(pMB); + pMB->SpeechChip.CurrentMode |= 1; // Set SSI263's D7 pin + } + } + + nDeviceNum++; + pMB++; + } + + AY8910_InitClock((int)CLK_6502); + + // Setup in MB_InitializeIO() -> MB_SetSoundcardType() + g_SoundcardType = CT_Empty; + g_bPhasorEnable = false; + + return true; +} + +void Phasor_SaveSnapshot(YamlSaveHelper& yamlSaveHelper, const UINT uSlot) +{ + if (uSlot != 4) + throw std::string("Card: Phasor only supported in slot-4"); + + UINT nDeviceNum = 0; + SY6522_AY8910* pMB = &g_MB[0]; // fixme: Phasor uses MB's slot4(2x6522), slot4(2xSSI263), but slot4+5(4xAY8910) + + YamlSaveHelper::Slot slot(yamlSaveHelper, Phasor_GetSnapshotCardName(), uSlot, 1); // fixme: object should be just 1 Mockingboard card & it will know its slot + + YamlSaveHelper::Label state(yamlSaveHelper, "%s:\n", SS_YAML_KEY_STATE); + + yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_PHASOR_CLOCK_SCALE_FACTOR, g_PhasorClockScaleFactor); + yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_PHASOR_MODE, g_nPhasorMode); + + for(UINT i=0; isy6522); + AY8910_SaveSnapshot(yamlSaveHelper, nDeviceNum+0, std::string("-A")); + AY8910_SaveSnapshot(yamlSaveHelper, nDeviceNum+1, std::string("-B")); + SaveSnapshotSSI263(yamlSaveHelper, pMB->SpeechChip); + + yamlSaveHelper.Save("%s: 0x%1X\n", SS_YAML_KEY_AY_CURR_REG, pMB->nAYCurrentRegister); + yamlSaveHelper.Save("%s: %d # Not supported\n", SS_YAML_KEY_TIMER1_IRQ, 0); + yamlSaveHelper.Save("%s: %d # Not supported\n", SS_YAML_KEY_TIMER2_IRQ, 0); + yamlSaveHelper.Save("%s: %d # Not supported\n", SS_YAML_KEY_SPEECH_IRQ, 0); + + nDeviceNum += 2; + pMB++; + } +} + +bool Phasor_LoadSnapshot(YamlLoadHelper& yamlLoadHelper, UINT slot, UINT version) +{ + if (slot != 4) // fixme + throw std::string("Card: wrong slot"); + + if (version != 1) + throw std::string("Card: wrong version"); + + g_PhasorClockScaleFactor = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_PHASOR_CLOCK_SCALE_FACTOR); + g_nPhasorMode = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_PHASOR_MODE); + + AY8910UpdateSetCycles(); + + UINT nDeviceNum = 0; + SY6522_AY8910* pMB = &g_MB[0]; + + g_nSSI263Device = 0; + g_nCurrentActivePhoneme = -1; + + for(UINT i=0; isy6522); + AY8910_LoadSnapshot(yamlLoadHelper, nDeviceNum+0, std::string("-A")); + AY8910_LoadSnapshot(yamlLoadHelper, nDeviceNum+1, std::string("-B")); + LoadSnapshotSSI263(yamlLoadHelper, pMB->SpeechChip); + + pMB->nAYCurrentRegister = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_AY_CURR_REG); + yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_TIMER1_IRQ); // Consume + yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_TIMER2_IRQ); // Consume + yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_SPEECH_IRQ); // Consume + + yamlLoadHelper.PopMap(); + + // + + StartTimer(pMB); // Attempt to start timer + + // Crude - currently only support a single speech chip + // FIX THIS: + // . Speech chip could be Votrax instead + // . Is this IRQ compatible with Phasor? + if(pMB->SpeechChip.DurationPhoneme) + { + g_nSSI263Device = nDeviceNum; + + if((pMB->SpeechChip.CurrentMode != MODE_IRQ_DISABLED) && (pMB->sy6522.PCR == 0x0C) && (pMB->sy6522.IER & IxR_PERIPHERAL)) + { + pMB->sy6522.IFR |= IxR_PERIPHERAL; + UpdateIFR(pMB); + pMB->SpeechChip.CurrentMode |= 1; // Set SSI263's D7 pin + } + } + + nDeviceNum += 2; + pMB++; + } + + AY8910_InitClock((int)(CLK_6502 * g_PhasorClockScaleFactor)); + + // Setup in MB_InitializeIO() -> MB_SetSoundcardType() + g_SoundcardType = CT_Empty; + g_bPhasorEnable = false; + + return true; +} + +//=========================================================================== + struct Mockingboard_Unit { SY6522 RegsSY6522; @@ -1900,8 +2220,6 @@ struct Mockingboard_Unit // SS_AY8910 AY8910; // Internal state of AY8910 }; -const UINT NUM_MB_UNITS = 2; - struct SS_CARD_MOCKINGBOARD { SS_CARD_HDR Hdr; @@ -1991,7 +2309,7 @@ void MB_SetSnapshot(const HANDLE hFile) // FIX THIS: // . Speech chip could be Votrax instead // . Is this IRQ compatible with Phasor? - if(pMB->SpeechChip.DurationPhonome) + if(pMB->SpeechChip.DurationPhoneme) { g_nSSI263Device = nDeviceNum; @@ -2033,8 +2351,6 @@ struct Phasor_Unit // SS_AY8910 AY8910[2]; // Internal state of AY8910 }; -const UINT NUM_PHASOR_UNITS = 2; - struct SS_CARD_PHASOR { SS_CARD_HDR Hdr; @@ -2132,7 +2448,7 @@ void Phasor_SetSnapshot(const HANDLE hFile) // FIX THIS: // . Speech chip could be Votrax instead // . Is this IRQ compatible with Phasor? - if(pMB->SpeechChip.DurationPhonome) + if(pMB->SpeechChip.DurationPhoneme) { g_nSSI263Device = nDeviceNum; diff --git a/source/Mockingboard.h b/source/Mockingboard.h index b87fe3c0..487463c2 100644 --- a/source/Mockingboard.h +++ b/source/Mockingboard.h @@ -25,8 +25,14 @@ void MB_SetVolume(DWORD dwVolume, DWORD dwVolumeMax); void MB_GetSnapshot_v1(struct SS_CARD_MOCKINGBOARD_v1* const pSS, const DWORD dwSlot); // For debugger int MB_SetSnapshot_v1(const struct SS_CARD_MOCKINGBOARD_v1* const pSS, const DWORD dwSlot); +std::string MB_GetSnapshotCardName(void); +void MB_SaveSnapshot(class YamlSaveHelper& yamlSaveHelper, const UINT uSlot); +bool MB_LoadSnapshot(class YamlLoadHelper& yamlLoadHelper, UINT slot, UINT version); void MB_GetSnapshot(const HANDLE hFile, const UINT uSlot); void MB_SetSnapshot(const HANDLE hFile); +std::string Phasor_GetSnapshotCardName(void); +void Phasor_SaveSnapshot(class YamlSaveHelper& yamlSaveHelper, const UINT uSlot); +bool Phasor_LoadSnapshot(class YamlLoadHelper& yamlLoadHelper, UINT slot, UINT version); void Phasor_GetSnapshot(const HANDLE hFile); void Phasor_SetSnapshot(const HANDLE hFile); diff --git a/source/MouseInterface.cpp b/source/MouseInterface.cpp index 442fed43..9a8f3921 100644 --- a/source/MouseInterface.cpp +++ b/source/MouseInterface.cpp @@ -50,6 +50,7 @@ Etc. #include "Memory.h" #include "MouseInterface.h" #include "SoundCore.h" // SAFE_RELEASE() +#include "YamlHelper.h" #include "..\resource\resource.h" @@ -598,6 +599,167 @@ void CMouseInterface::SetButton(eBUTTON Button, eBUTTONSTATE State) OnMouseEvent(); } +#define SS_YAML_VALUE_CARD_MOUSE "Mouse Card" + +#define SS_YAML_KEY_MC6821 "MC6821" +#define SS_YAML_KEY_PRA "PRA" +#define SS_YAML_KEY_DDRA "DDRA" +#define SS_YAML_KEY_CRA "CRA" +#define SS_YAML_KEY_PRB "PRB" +#define SS_YAML_KEY_DDRB "DDRB" +#define SS_YAML_KEY_CRB "CRB" +#define SS_YAML_KEY_IA "IA" +#define SS_YAML_KEY_IB "IB" + +#define SS_YAML_KEY_DATALEN "DataLen" +#define SS_YAML_KEY_MODE "Mode" +#define SS_YAML_KEY_6821B "6821B" +#define SS_YAML_KEY_6821A "6821A" +#define SS_YAML_KEY_BUFF "Buffer" +#define SS_YAML_KEY_BUFFPOS "Buffer Position" +#define SS_YAML_KEY_MOUSESTATE "State" +#define SS_YAML_KEY_X "X" +#define SS_YAML_KEY_Y "Y" +#define SS_YAML_KEY_BTN0 "Btn0" +#define SS_YAML_KEY_BTN1 "Btn1" +#define SS_YAML_KEY_VBL "VBL" +#define SS_YAML_KEY_IX "iX" +#define SS_YAML_KEY_IMINX "iMinX" +#define SS_YAML_KEY_IMAXX "iMaxX" +#define SS_YAML_KEY_IY "iY" +#define SS_YAML_KEY_IMINY "iMinY" +#define SS_YAML_KEY_IMAXY "iMaxY" +#define SS_YAML_KEY_BUTTON0 "Button0" +#define SS_YAML_KEY_BUTTON1 "Button1" +#define SS_YAML_KEY_ACTIVE "Active" +#define SS_YAML_KEY_ENABLED "Enabled" + +std::string CMouseInterface::GetSnapshotCardName(void) +{ + static const std::string name(SS_YAML_VALUE_CARD_MOUSE); + return name; +} + +void CMouseInterface::SaveSnapshotMC6821(YamlSaveHelper& yamlSaveHelper, std::string key) +{ + mc6821_t mc6821; + BYTE byIA; + BYTE byIB; + + m_6821.Get6821(mc6821, byIA, byIB); + + YamlSaveHelper::Label label(yamlSaveHelper, "%s:\n", key.c_str()); + yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_PRA, mc6821.pra); + yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_DDRA, mc6821.ddra); + yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_CRA, mc6821.cra); + yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_PRB, mc6821.prb); + yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_DDRB, mc6821.ddrb); + yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_CRB, mc6821.crb); + yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_IA, byIA); + yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_IB, byIB); +} + +void CMouseInterface::SaveSnapshot(class YamlSaveHelper& yamlSaveHelper) +{ + if (!m_bActive) + return; + + YamlSaveHelper::Slot slot(yamlSaveHelper, GetSnapshotCardName(), m_uSlot, 1); + + YamlSaveHelper::Label state(yamlSaveHelper, "%s:\n", SS_YAML_KEY_STATE); + SaveSnapshotMC6821(yamlSaveHelper, SS_YAML_KEY_MC6821); + yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_DATALEN, m_nDataLen); + yamlSaveHelper.Save("%s: 0x%02X\n", SS_YAML_KEY_MODE, m_byMode); + yamlSaveHelper.Save("%s: 0x%02X\n", SS_YAML_KEY_6821B, m_by6821B); + yamlSaveHelper.Save("%s: 0x%02X\n", SS_YAML_KEY_6821A, m_by6821A); + + // New label + { + YamlSaveHelper::Label buffer(yamlSaveHelper, "%s:\n", SS_YAML_KEY_BUFF); + yamlSaveHelper.SaveMapValueMemory(m_byBuff, sizeof(m_byBuff)); + } + + yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_BUFFPOS, m_nBuffPos); + yamlSaveHelper.Save("%s: 0x%02X\n", SS_YAML_KEY_MOUSESTATE, m_byState); + yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_X, m_nX); + yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_Y, m_nY); + yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_BTN0, m_bBtn0); + yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_BTN1, m_bBtn1); + yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_VBL, m_bVBL ? 1 : 0); + yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_IX, m_iX); + yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_IMINX, m_iMinX); + yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_IMAXX, m_iMaxX); + yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_IY, m_iY); + yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_IMINY, m_iMinY); + yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_IMAXY, m_iMaxY); + yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_BUTTON0, m_bButtons[0]); + yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_BUTTON1, m_bButtons[1]); + yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_ACTIVE, m_bActive ? 1 : 0); + yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_ENABLED, m_bEnabled ? 1 : 0); +} + +void CMouseInterface::LoadSnapshotMC6821(YamlLoadHelper& yamlLoadHelper, std::string key) +{ + if (!yamlLoadHelper.GetSubMap(key)) + throw std::string("Card: Expected key: ") + key; + + mc6821_t mc6821; + mc6821.pra = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_PRA); + mc6821.ddra = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_DDRA); + mc6821.cra = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_CRA); + mc6821.prb = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_PRB); + mc6821.ddrb = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_DDRB); + mc6821.crb = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_CRB); + + BYTE byIA = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_IA); + BYTE byIB = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_IB); + + m_6821.Set6821(mc6821, byIA, byIB); + + yamlLoadHelper.PopMap(); +} + +bool CMouseInterface::LoadSnapshot(class YamlLoadHelper& yamlLoadHelper, UINT slot, UINT version) +{ + if (slot != 4) // fixme + throw std::string("Card: wrong slot"); + + if (version != 1) + throw std::string("Card: wrong version"); + + LoadSnapshotMC6821(yamlLoadHelper, SS_YAML_KEY_MC6821); + + m_nDataLen = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_DATALEN); + m_byMode = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_MODE); + m_by6821B = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_6821B); + m_by6821A = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_6821A); + + if (!yamlLoadHelper.GetSubMap(SS_YAML_KEY_BUFF)) + throw std::string("Card: Expected key: "SS_YAML_KEY_BUFF); + yamlLoadHelper.GetMapValueMemory(m_byBuff, sizeof(m_byBuff)); + yamlLoadHelper.PopMap(); + + m_nBuffPos = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_BUFFPOS); + m_byState = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_MOUSESTATE); + m_nX = yamlLoadHelper.GetMapValueINT(SS_YAML_KEY_X); + m_nY = yamlLoadHelper.GetMapValueINT(SS_YAML_KEY_Y); + m_bBtn0 = yamlLoadHelper.GetMapValueBOOL(SS_YAML_KEY_BTN0); + m_bBtn1 = yamlLoadHelper.GetMapValueBOOL(SS_YAML_KEY_BTN1); + m_bVBL = yamlLoadHelper.GetMapValueBool(SS_YAML_KEY_VBL); + m_iX = yamlLoadHelper.GetMapValueINT(SS_YAML_KEY_IX); + m_iMinX = yamlLoadHelper.GetMapValueINT(SS_YAML_KEY_IMINX); + m_iMaxX = yamlLoadHelper.GetMapValueINT(SS_YAML_KEY_IMAXX); + m_iY = yamlLoadHelper.GetMapValueINT(SS_YAML_KEY_IY); + m_iMinY = yamlLoadHelper.GetMapValueINT(SS_YAML_KEY_IMINY); + m_iMaxY = yamlLoadHelper.GetMapValueINT(SS_YAML_KEY_IMAXY); + m_bButtons[0] = yamlLoadHelper.GetMapValueBOOL(SS_YAML_KEY_BUTTON0); + m_bButtons[1] = yamlLoadHelper.GetMapValueBOOL(SS_YAML_KEY_BUTTON1); + m_bActive = yamlLoadHelper.GetMapValueBool(SS_YAML_KEY_ACTIVE); + m_bEnabled = yamlLoadHelper.GetMapValueBool(SS_YAML_KEY_ENABLED); + + return true; +} + struct MouseCard_Unit { //6821 diff --git a/source/MouseInterface.h b/source/MouseInterface.h index 600b6321..54570ede 100644 --- a/source/MouseInterface.h +++ b/source/MouseInterface.h @@ -37,6 +37,9 @@ public: m_iY = iY; } + std::string GetSnapshotCardName(void); + void SaveSnapshot(class YamlSaveHelper& yamlSaveHelper); + bool LoadSnapshot(class YamlLoadHelper& yamlLoadHelper, UINT slot, UINT version); int GetSnapshot(const HANDLE hFile); void SetSnapshot(const HANDLE hFile); @@ -58,6 +61,8 @@ protected: void SetClampX(int iMinX, int iMaxX); void SetClampY(int iMinY, int iMaxY); + void SaveSnapshotMC6821(class YamlSaveHelper& yamlSaveHelper, std::string key); + void LoadSnapshotMC6821(class YamlLoadHelper& yamlLoadHelper, std::string key); C6821 m_6821; diff --git a/source/ParallelPrinter.cpp b/source/ParallelPrinter.cpp index a26498f4..85bbed2d 100644 --- a/source/ParallelPrinter.cpp +++ b/source/ParallelPrinter.cpp @@ -32,6 +32,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #include "Memory.h" #include "ParallelPrinter.h" #include "Registry.h" +#include "YamlHelper.h" #include "..\resource\resource.h" @@ -255,6 +256,75 @@ void Printer_SetIdleLimit(unsigned int Duration) //=========================================================================== +#define SS_YAML_VALUE_CARD_PRINTER "Generic Printer" + +#define SS_YAML_KEY_INACTIVITY "Inactivity" +#define SS_YAML_KEY_IDLELIMIT "Printer Idle Limit" +#define SS_YAML_KEY_FILENAME "Print Filename" +#define SS_YAML_KEY_FILEOPEN "Is File Open" +#define SS_YAML_KEY_DUMPTOPRINTER "Dump To Printer" +#define SS_YAML_KEY_CONVERTENCODING "Convert Encoding" +#define SS_YAML_KEY_FILTERUNPRINTABLE "Filter Unprintable" +#define SS_YAML_KEY_APPEND "Printer Append" +#define SS_YAML_KEY_DUMPTOREALPRINTER "Enable Dump To Real Printer" + +std::string Printer_GetSnapshotCardName(void) +{ + static const std::string name(SS_YAML_VALUE_CARD_PRINTER); + return name; +} + +void Printer_SaveSnapshot(class YamlSaveHelper& yamlSaveHelper) +{ + YamlSaveHelper::Slot slot(yamlSaveHelper, Printer_GetSnapshotCardName(), g_uSlot, 1); + + YamlSaveHelper::Label state(yamlSaveHelper, "%s:\n", SS_YAML_KEY_STATE); + yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_INACTIVITY, inactivity); + yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_IDLELIMIT, g_iPrinterIdleLimit); + yamlSaveHelper.Save("%s: %s\n", SS_YAML_KEY_FILENAME, yamlSaveHelper.GetSaveString(g_szPrintFilename).c_str()); + yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_FILEOPEN, (file != NULL) ? 1 : 0); + yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_DUMPTOPRINTER, g_bDumpToPrinter); + yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_CONVERTENCODING, g_bConvertEncoding); + yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_FILTERUNPRINTABLE, g_bFilterUnprintable); + yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_APPEND, g_bPrinterAppend); + yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_DUMPTOREALPRINTER, g_bEnableDumpToRealPrinter); +} + +bool Printer_LoadSnapshot(class YamlLoadHelper& yamlLoadHelper, UINT slot, UINT version) +{ + if (slot != 1) // fixme + throw std::string("Card: wrong slot"); + + if (version != 1) + throw std::string("Card: wrong version"); + + inactivity = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_INACTIVITY); + g_iPrinterIdleLimit = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_IDLELIMIT); + strncpy(g_szPrintFilename, yamlLoadHelper.GetMapValueSTRING(SS_YAML_KEY_FILENAME).c_str(), sizeof(g_szPrintFilename)); + + if (yamlLoadHelper.GetMapValueBool(SS_YAML_KEY_FILEOPEN)) + { + yamlLoadHelper.GetMapValueBool(SS_YAML_KEY_APPEND); // Consume + g_bPrinterAppend = true; // Re-open print-file in append mode + BOOL bRes = CheckPrint(); + if (!bRes) + throw std::string("Printer Card: Unable to resume printing to file"); + } + else + { + g_bPrinterAppend = yamlLoadHelper.GetMapValueBool(SS_YAML_KEY_APPEND); + } + + g_bDumpToPrinter = yamlLoadHelper.GetMapValueBool(SS_YAML_KEY_DUMPTOPRINTER); + g_bConvertEncoding = yamlLoadHelper.GetMapValueBool(SS_YAML_KEY_CONVERTENCODING); + g_bFilterUnprintable = yamlLoadHelper.GetMapValueBool(SS_YAML_KEY_FILTERUNPRINTABLE); + g_bEnableDumpToRealPrinter = yamlLoadHelper.GetMapValueBool(SS_YAML_KEY_DUMPTOREALPRINTER); + + return true; +} + +//--- + struct PrinterCard_Unit { DWORD Inactivity; diff --git a/source/ParallelPrinter.h b/source/ParallelPrinter.h index fc227231..87216bc0 100644 --- a/source/ParallelPrinter.h +++ b/source/ParallelPrinter.h @@ -9,6 +9,9 @@ char* Printer_GetFilename(); void Printer_SetIdleLimit(unsigned int Duration); unsigned int Printer_GetIdleLimit(); +std::string Printer_GetSnapshotCardName(void); +void Printer_SaveSnapshot(class YamlSaveHelper& yamlSaveHelper); +bool Printer_LoadSnapshot(class YamlLoadHelper& yamlLoadHelper, UINT slot, UINT version); void Printer_GetSnapshot(const HANDLE hFile); void Printer_SetSnapshot(const HANDLE hFile); diff --git a/source/SaveState.cpp b/source/SaveState.cpp index 2f06026e..2aab70f4 100644 --- a/source/SaveState.cpp +++ b/source/SaveState.cpp @@ -30,6 +30,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #include "SaveState_Structs_v1.h" #include "SaveState_Structs_v2.h" +#include "YamlHelper.h" #include "AppleWin.h" #include "CPU.h" @@ -52,7 +53,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #include "Configuration\IPropertySheet.h" -#define DEFAULT_SNAPSHOT_NAME "SaveState.aws" +#define DEFAULT_SNAPSHOT_NAME "SaveState.aws.yaml" bool g_bSaveStateOnExit = false; @@ -60,6 +61,8 @@ static std::string g_strSaveStateFilename; static std::string g_strSaveStatePathname; static std::string g_strSaveStatePath; +static YamlHelper yamlHelper; + //----------------------------------------------------------------------------- void Snapshot_SetFilename(std::string strPathname) @@ -490,6 +493,311 @@ static void LoadUnitConfig(DWORD Length, DWORD Version) sg_PropertySheet.SetTheFreezesF8Rom(Config.Cfg.IsUsingFreezesF8Rom); } +//--- + +static std::string GetSnapshotUnitApple2Name(void) +{ + static const std::string name("Apple2"); + return name; +} + +static std::string GetSnapshotUnitSlotsName(void) +{ + static const std::string name("Slots"); + return name; +} + +#define SS_YAML_KEY_MODEL "Model" + +#define SS_YAML_VALUE_APPLE2 "Apple][" +#define SS_YAML_VALUE_APPLE2PLUS "Apple][+" +#define SS_YAML_VALUE_APPLE2E "Apple//e" +#define SS_YAML_VALUE_APPLE2EENHANCED "Enhanced Apple//e" +#define SS_YAML_VALUE_APPLE2C "Apple2c" +#define SS_YAML_VALUE_PRAVETS82 "Pravets82" +#define SS_YAML_VALUE_PRAVETS8M "Pravets8M" +#define SS_YAML_VALUE_PRAVETS8A "Pravets8A" + +static eApple2Type ParseApple2Type(std::string type) +{ + if (type == SS_YAML_VALUE_APPLE2) return A2TYPE_APPLE2; + else if (type == SS_YAML_VALUE_APPLE2PLUS) return A2TYPE_APPLE2PLUS; + else if (type == SS_YAML_VALUE_APPLE2E) return A2TYPE_APPLE2E; + else if (type == SS_YAML_VALUE_APPLE2EENHANCED) return A2TYPE_APPLE2EENHANCED; + else if (type == SS_YAML_VALUE_APPLE2C) return A2TYPE_APPLE2C; + else if (type == SS_YAML_VALUE_PRAVETS82) return A2TYPE_PRAVETS82; + else if (type == SS_YAML_VALUE_PRAVETS8M) return A2TYPE_PRAVETS8M; + else if (type == SS_YAML_VALUE_PRAVETS8A) return A2TYPE_PRAVETS8A; + + throw std::string("Load: Unknown Apple2 type"); +} + +static std::string GetApple2Type(void) +{ + switch (g_Apple2Type) + { + case A2TYPE_APPLE2: return SS_YAML_VALUE_APPLE2; + case A2TYPE_APPLE2PLUS: return SS_YAML_VALUE_APPLE2PLUS; + case A2TYPE_APPLE2E: return SS_YAML_VALUE_APPLE2E; + case A2TYPE_APPLE2EENHANCED:return SS_YAML_VALUE_APPLE2EENHANCED; + case A2TYPE_APPLE2C: return SS_YAML_VALUE_APPLE2C; + case A2TYPE_PRAVETS82: return SS_YAML_VALUE_PRAVETS82; + case A2TYPE_PRAVETS8M: return SS_YAML_VALUE_PRAVETS8M; + case A2TYPE_PRAVETS8A: return SS_YAML_VALUE_PRAVETS8A; + default: + throw std::string("Save: Unknown Apple2 type"); + } +} + +//--- + +static UINT ParseFileHdr(void) +{ + std::string scalar; + if (!yamlHelper.GetScalar(scalar)) + throw std::string(SS_YAML_KEY_FILEHDR ": Failed to find scalar"); + + if (scalar != SS_YAML_KEY_FILEHDR) + throw std::string("Failed to find file header"); + + yamlHelper.GetMapStartEvent(); + + YamlLoadHelper yamlLoadHelper(yamlHelper); + + // + + std::string value = yamlLoadHelper.GetMapValueSTRING(SS_YAML_KEY_TAG); + if (value != SS_YAML_VALUE_AWSS) + { + //printf("%s: Bad tag (%s) - expected %s\n", SS_YAML_KEY_FILEHDR, value.c_str(), SS_YAML_VALUE_AWSS); + throw std::string(SS_YAML_KEY_FILEHDR ": Bad tag"); + } + + return yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_VERSION); +} + +//--- + +static void ParseUnitApple2(YamlLoadHelper& yamlLoadHelper, UINT version) +{ + if (version != UNIT_APPLE2_VER) + throw std::string(SS_YAML_KEY_UNIT ": Apple2: Version mismatch"); + + std::string model = yamlLoadHelper.GetMapValueSTRING(SS_YAML_KEY_MODEL); + g_Apple2Type = ParseApple2Type(model); + + CpuLoadSnapshot(yamlLoadHelper); + JoyLoadSnapshot(yamlLoadHelper); + KeybLoadSnapshot(yamlLoadHelper); + SpkrLoadSnapshot(yamlLoadHelper); + VideoLoadSnapshot(yamlLoadHelper); + MemLoadSnapshot(yamlLoadHelper); +} + +//--- + +static void ParseSlots(YamlLoadHelper& yamlLoadHelper, UINT version) +{ + if (version != UNIT_SLOTS_VER) + throw std::string(SS_YAML_KEY_UNIT ": Slots: Version mismatch"); + + while (1) + { + std::string scalar = yamlLoadHelper.GetMapNextSlotNumber(); + if (scalar.empty()) + break; // done all slots + + const int slot = strtoul(scalar.c_str(), NULL, 10); // NB. aux slot supported as a different "unit" + if (slot < 1 || slot > 7) + throw std::string("Slots: Invalid slot #: ") + scalar; + + yamlLoadHelper.GetSubMap(scalar); + + std::string card = yamlLoadHelper.GetMapValueSTRING(SS_YAML_KEY_CARD); + UINT version = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_VERSION); + + if (!yamlLoadHelper.GetSubMap(std::string(SS_YAML_KEY_STATE))) + throw std::string(SS_YAML_KEY_UNIT ": Expected sub-map name: " SS_YAML_KEY_STATE); + + bool bIsCardSupported = true; + SS_CARDTYPE type = CT_Empty; + bool bRes = false; + + if (card == Printer_GetSnapshotCardName()) + { + bRes = Printer_LoadSnapshot(yamlLoadHelper, slot, version); + type = CT_GenericPrinter; + } + else if (card == sg_SSC.GetSnapshotCardName()) + { + bRes = sg_SSC.LoadSnapshot(yamlLoadHelper, slot, version); + type = CT_SSC; + } + else if (card == sg_Mouse.GetSnapshotCardName()) + { + bRes = sg_Mouse.LoadSnapshot(yamlLoadHelper, slot, version); + type = CT_MouseInterface; + } + else if (card == Z80_GetSnapshotCardName()) + { + bRes = Z80_LoadSnapshot(yamlLoadHelper, slot, version); + type = CT_Z80; + } + else if (card == MB_GetSnapshotCardName()) + { + bRes = MB_LoadSnapshot(yamlLoadHelper, slot, version); + type = CT_MockingboardC; + } + else if (card == Phasor_GetSnapshotCardName()) + { + bRes = Phasor_LoadSnapshot(yamlLoadHelper, slot, version); + type = CT_Phasor; + } + else if (card == DiskGetSnapshotCardName()) + { + bRes = DiskLoadSnapshot(yamlLoadHelper, slot, version); + type = CT_Disk2; + } + else if (card == HD_GetSnapshotCardName()) + { + bRes = HD_LoadSnapshot(yamlLoadHelper, slot, version, g_strSaveStatePath); + m_ConfigNew.m_bEnableHDD = true; + type = CT_GenericHDD; + } + else + { + bIsCardSupported = false; + throw std::string("Slots: Unknown card: " + card); // todo: don't throw - just ignore & continue + } + + if (bRes && bIsCardSupported) + { + m_ConfigNew.m_Slot[slot] = type; + } + + yamlLoadHelper.PopMap(); + yamlLoadHelper.PopMap(); + } +} + +//--- + +static void ParseUnit(void) +{ + yamlHelper.GetMapStartEvent(); + + YamlLoadHelper yamlLoadHelper(yamlHelper); + + std::string unit = yamlLoadHelper.GetMapValueSTRING(SS_YAML_KEY_TYPE); + UINT version = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_VERSION); + + if (!yamlLoadHelper.GetSubMap(std::string(SS_YAML_KEY_STATE))) + throw std::string(SS_YAML_KEY_UNIT ": Expected sub-map name: " SS_YAML_KEY_STATE); + + if (unit == GetSnapshotUnitApple2Name()) + { + ParseUnitApple2(yamlLoadHelper, version); + } + else if (unit == MemGetSnapshotUnitAuxSlotName()) + { + MemLoadSnapshotAux(yamlLoadHelper, version); + } + else if (unit == GetSnapshotUnitSlotsName()) + { + ParseSlots(yamlLoadHelper, version); + } + else if (unit == SS_YAML_VALUE_UNIT_CONFIG) + { + //... + } + else + { + throw std::string(SS_YAML_KEY_UNIT ": Unknown type: " ) + unit; + } +} + +static void Snapshot_LoadState_v2(void) +{ + try + { + int res = yamlHelper.InitParser( g_strSaveStatePathname.c_str() ); + if (!res) + throw std::string("Failed to initialize parser or open file"); // TODO: disambiguate + + UINT version = ParseFileHdr(); + if (version != SS_FILE_VER) + throw std::string("Version mismatch"); + + // + + CConfigNeedingRestart ConfigOld; + ConfigOld.m_Slot[1] = CT_GenericPrinter; // fixme + ConfigOld.m_Slot[2] = CT_SSC; // fixme + //ConfigOld.m_Slot[3] = CT_Uthernet; // todo + ConfigOld.m_Slot[6] = CT_Disk2; // fixme + ConfigOld.m_Slot[7] = ConfigOld.m_bEnableHDD ? CT_GenericHDD : CT_Empty; // fixme + //ConfigOld.m_SlotAux = ?; // fixme + + for (UINT i=0; i #include #include +#include #include #include diff --git a/source/Video.cpp b/source/Video.cpp index 7030f290..27c49215 100644 --- a/source/Video.cpp +++ b/source/Video.cpp @@ -40,6 +40,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #include "Configuration\PropertySheet.h" #include "Debugger\Debugger_Color.h" // For NUM_DEBUG_COLORS #include "SaveState_Structs_v2.h" +#include "YamlHelper.h" #define HALF_PIXEL_SOLID 1 #define HALF_PIXEL_BLEED 0 @@ -2950,6 +2951,38 @@ void VideoSetSnapshot_v1(const UINT AltCharSet, const UINT VideoMode) // +#define SS_YAML_KEY_ALTCHARSET "Alt Char Set" +#define SS_YAML_KEY_VIDEOMODE "Video Mode" +#define SS_YAML_KEY_CYCLESTHISFRAME "Cycles This Frame" + +static std::string VideoGetSnapshotStructName(void) +{ + static const std::string name("Video"); + return name; +} + +void VideoSaveSnapshot(YamlSaveHelper& yamlSaveHelper) +{ + YamlSaveHelper::Label state(yamlSaveHelper, "%s:\n", VideoGetSnapshotStructName().c_str()); + yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_ALTCHARSET, g_nAltCharSetOffset ? 1 : 0); + yamlSaveHelper.Save("%s: 0x%08X\n", SS_YAML_KEY_VIDEOMODE, g_uVideoMode); + yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_CYCLESTHISFRAME, g_dwCyclesThisFrame); +} + +void VideoLoadSnapshot(YamlLoadHelper& yamlLoadHelper) +{ + if (!yamlLoadHelper.GetSubMap(VideoGetSnapshotStructName())) + return; + + g_nAltCharSetOffset = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_ALTCHARSET) ? 256 : 0; + g_uVideoMode = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_VIDEOMODE); + g_dwCyclesThisFrame = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_CYCLESTHISFRAME); + + yamlLoadHelper.PopMap(); +} + +// + void VideoGetSnapshot(SS_IO_Video_v2& Video) { Video.AltCharSet = !(g_nAltCharSetOffset == 0); diff --git a/source/Video.h b/source/Video.h index 93f179f5..02916344 100644 --- a/source/Video.h +++ b/source/Video.h @@ -86,6 +86,8 @@ bool VideoGetSWAltCharSet(void); void VideoSetForceFullRedraw(void); void VideoSetSnapshot_v1(const UINT AltCharSet, const UINT VideoMode); +void VideoSaveSnapshot(class YamlSaveHelper& yamlSaveHelper); +void VideoLoadSnapshot(class YamlLoadHelper& yamlLoadHelper); void VideoGetSnapshot(struct SS_IO_Video_v2& Video); void VideoSetSnapshot(const struct SS_IO_Video_v2& Video); diff --git a/source/YamlHelper.cpp b/source/YamlHelper.cpp new file mode 100644 index 00000000..9f2eea29 --- /dev/null +++ b/source/YamlHelper.cpp @@ -0,0 +1,421 @@ +/* +AppleWin : An Apple //e emulator for Windows + +Copyright (C) 1994-1996, Michael O'Brien +Copyright (C) 1999-2001, Oliver Schmidt +Copyright (C) 2002-2005, Tom Charlesworth +Copyright (C) 2006-2015, Tom Charlesworth, Michael Pohoreski + +AppleWin is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +AppleWin is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with AppleWin; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "StdAfx.h" + +#include "YamlHelper.h" + +int YamlHelper::InitParser(const char* pPathname) +{ + m_hFile = fopen(pPathname, "r"); + if (m_hFile == NULL) + { + return 0; + } + + if (!yaml_parser_initialize(&m_parser)) + { + return 0; + } + + yaml_parser_set_input_file(&m_parser, m_hFile); + + return 1; +} + +void YamlHelper::FinaliseParser(void) +{ + if (m_hFile) + fclose(m_hFile); + + m_hFile = NULL; +} + +void YamlHelper::GetNextEvent(bool bInMap /*= false*/) +{ + if (!yaml_parser_parse(&m_parser, &m_newEvent)) + { + //printf("Parser error %d\n", m_parser.error); + throw std::string("Parser error"); + } + + if (m_newEvent.type == YAML_MAPPING_START_EVENT) + { + MapState state = {m_mapName, bInMap}; + m_stackMapState.push(state); + } + else if (m_newEvent.type == YAML_MAPPING_END_EVENT) + { + MapState state = m_stackMapState.top(); + m_lastMapName = m_mapName; // For GetMapRemainder() + m_mapName = state.name; + // ? = state.isInMap; + m_stackMapState.pop(); + } +} + +int YamlHelper::GetScalar(std::string& scalar) +{ + int res = 1; + bool bDone = false; + + while (!bDone) + { + GetNextEvent(); + + switch(m_newEvent.type) + { + case YAML_SCALAR_EVENT: + scalar = m_scalarName = (const char*)m_newEvent.data.scalar.value; + res = 1; + bDone = true; + break; + case YAML_SEQUENCE_END_EVENT: + res = 0; + bDone = true; + break; + case YAML_MAPPING_END_EVENT: + res = 0; + bDone = true; + break; + case YAML_STREAM_END_EVENT: + res = 0; + bDone = true; + break; + } + } + + return res; +} + +void YamlHelper::GetListStartEvent(void) +{ + GetNextEvent(); + + if (m_newEvent.type != YAML_SEQUENCE_START_EVENT) + { + //printf("Unexpected yaml event (%d)\n", m_newEvent.type); + throw std::string("Unexpected yaml event"); + } +} + +//void YamlHelper::GetListEndEvent(void) +//{ +// GetNextEvent(); +// +// if (m_newEvent.type != YAML_SEQUENCE_END_EVENT) +// { +// //printf("Unexpected yaml event (%d)\n", m_newEvent.type); +// throw std::string("Unexpected yaml event"); +// } +//} + +void YamlHelper::GetMapStartEvent(void) +{ + GetNextEvent(); + + if (m_newEvent.type != YAML_MAPPING_START_EVENT) + { + //printf("Unexpected yaml event (%d)\n", m_newEvent.type); + throw std::string("Unexpected yaml event"); + } +} + +void YamlHelper::GetMapEndEvent(void) +{ + GetNextEvent(); + + if (m_newEvent.type != YAML_MAPPING_END_EVENT) + { + //printf("Unexpected yaml event (%d)\n", m_newEvent.type); + throw std::string("Unexpected yaml event"); + } +} + +int YamlHelper::GetMapStartOrListEndEvent(void) +{ + GetNextEvent(); + + if (m_newEvent.type != YAML_MAPPING_START_EVENT && m_newEvent.type != YAML_SEQUENCE_END_EVENT) + { + //printf("Unexpected yaml event (%d)\n", m_newEvent.type); + throw std::string("Unexpected yaml event"); + } + + return m_newEvent.type == YAML_MAPPING_START_EVENT ? 1 : 0; +} + +// + +int YamlHelper::ParseMap(MapYaml& mapYaml) +{ + mapYaml.clear(); + + const char*& pValue = (const char*&) m_newEvent.data.scalar.value; + + bool bKey = true; + char* pKey = NULL; + int res = 1; + bool bDone = false; + + while (!bDone) + { + GetNextEvent(true); + + switch(m_newEvent.type) + { + case YAML_STREAM_END_EVENT: + res = 0; + bDone = true; + break; + case YAML_MAPPING_START_EVENT: + { + MapValue mapValue; + mapValue.value = ""; + mapValue.subMap = new MapYaml; + mapYaml[std::string(pKey)] = mapValue; + res = ParseMap(*mapValue.subMap); + if (!res) + throw std::string("ParseMap: premature end of file during map parsing"); + bKey = true; // possibly more key,value pairs in this map + } + break; + case YAML_MAPPING_END_EVENT: + bDone = true; + break; + case YAML_SCALAR_EVENT: + if (bKey) + { + pKey = _strdup(pValue); + } + else + { + MapValue mapValue; + mapValue.value = pValue; + mapValue.subMap = NULL; + mapYaml[std::string(pKey)] = mapValue; + delete [] pKey; pKey = NULL; + } + + bKey = bKey ? false : true; + break; + case YAML_SEQUENCE_START_EVENT: + case YAML_SEQUENCE_END_EVENT: + throw std::string("ParseMap: Sequence event unsupported"); + } + } + + if (pKey) + delete [] pKey; + + return res; +} + +std::string YamlHelper::GetMapValue(MapYaml& mapYaml, const std::string key, bool& bFound) +{ + MapYaml::const_iterator iter = mapYaml.find(key); + if (iter == mapYaml.end() || iter->second.subMap != NULL) + { + bFound = false; // not found + return ""; + } + + std::string value = iter->second.value; + + mapYaml.erase(iter); + + bFound = true; + return value; +} + +bool YamlHelper::GetSubMap(MapYaml** mapYaml, const std::string key) +{ + MapYaml::const_iterator iter = (*mapYaml)->find(key); + if (iter == (*mapYaml)->end() || iter->second.subMap == NULL) + { + return false; // not found + } + + *mapYaml = iter->second.subMap; + return true; +} + +void YamlHelper::GetMapRemainder(MapYaml& mapYaml) +{ + for (MapYaml::iterator iter = mapYaml.begin(); iter != mapYaml.end(); ++iter) + { + if (iter->second.subMap) + { + GetMapRemainder(*iter->second.subMap); + delete iter->second.subMap; + } + else + { + const char* pKey = iter->first.c_str(); + char szDbg[100]; + sprintf(szDbg, "%s: Unknown key (%s)\n", m_lastMapName.c_str(), pKey); + OutputDebugString(szDbg); + } + } + + mapYaml.clear(); +} + +// + +void YamlHelper::MakeAsciiToHexTable(void) +{ + memset(m_AsciiToHex, -1, sizeof(m_AsciiToHex)); + + for (int i = '0'; i<= '9'; i++) + m_AsciiToHex[i] = i - '0'; + + for (int i = 'A'; i<= 'F'; i++) + m_AsciiToHex[i] = i - 'A' + 0xA; + + for (int i = 'a'; i<= 'f'; i++) + m_AsciiToHex[i] = i - 'a' + 0xA; +} + +void YamlHelper::GetMapValueMemory(MapYaml& mapYaml, const LPBYTE pMemBase, const size_t kAddrSpaceSize) +{ + for (MapYaml::iterator it = mapYaml.begin(); it != mapYaml.end(); ++it) + { + const char* pKey = it->first.c_str(); + UINT addr = strtoul(pKey, NULL, 16); + if (addr >= kAddrSpaceSize) + throw std::string("Memory: line address too big: " + it->first); + + LPBYTE pDst = (LPBYTE) (pMemBase + addr); + const LPBYTE pDstEnd = (LPBYTE) (pMemBase + kAddrSpaceSize); + + if (it->second.subMap) + throw std::string("Memory: unexpected sub-map"); + + const char* pValue = it->second.value.c_str(); + size_t len = strlen(pValue); + if (len & 1) + throw std::string("Memory: hex data must be an even number of nibbles on line address: " + it->first); + + for (UINT i = 0; i= pDstEnd) + throw std::string("Memory: hex data overflowed address space on line address: " + it->first); + + BYTE ah = m_AsciiToHex[ (BYTE)(*pValue++) ]; + BYTE al = m_AsciiToHex[ (BYTE)(*pValue++) ]; + if ((ah | al) & 0x80) + throw std::string("Memory: hex data contains illegal character on line address: " + it->first); + + *pDst++ = (ah<<4) | al; + } + } + + mapYaml.clear(); +} + +//------------------------------------- + +void YamlSaveHelper::Save(const char* format, ...) +{ + fwrite(m_szIndent, 1, m_indent, m_hFile); + + va_list vl; + va_start(vl, format); + vfprintf(m_hFile, format, vl); + va_end(vl); +} + +void YamlSaveHelper::FileHdr(UINT version) +{ + fprintf(m_hFile, "%s:\n", SS_YAML_KEY_FILEHDR); + m_indent = 2; + Save("%s: %s\n", SS_YAML_KEY_TAG, SS_YAML_VALUE_AWSS); + Save("%s: %d\n", SS_YAML_KEY_VERSION, version); +} + +void YamlSaveHelper::UnitHdr(std::string type, UINT version) +{ + fprintf(m_hFile, "\n%s:\n", SS_YAML_KEY_UNIT); + m_indent = 2; + Save("%s: %s\n", SS_YAML_KEY_TYPE, type.c_str()); + Save("%s: %d\n", SS_YAML_KEY_VERSION, version); +} + +void YamlSaveHelper::SaveMapValueMemory(const LPBYTE pMemBase, const UINT uMemSize) +{ + const UINT kIndent = m_indent; + + const UINT kStride = 64; + const char szHex[] = "0123456789ABCDEF"; + + size_t lineSize = kIndent+6+2*kStride+2; // "AAAA: 00010203...3F\n\00" = 6+ 2*64 +2 + char* const pLine = new char [lineSize]; + + for(DWORD dwOffset = 0x0000; dwOffset < uMemSize; dwOffset+=kStride) + { + char* pDst = pLine; + for (UINT i=0; i>12)&0xf ]; + *pDst++ = szHex[ (dwOffset>>8)&0xf ]; + *pDst++ = szHex[ (dwOffset>>4)&0xf ]; + *pDst++ = szHex[ dwOffset&0xf ]; + *pDst++ = ':'; + *pDst++ = ' '; + + LPBYTE pMem = pMemBase + dwOffset; + + for (UINT i=0; i= uMemSize) // Support short final line (still multiple of 8 bytes) + { + lineSize = lineSize - 2*kStride + 2*i; + break; + } + + BYTE d; + d = *pMem++; *pDst++ = szHex[d>>4]; *pDst++ = szHex[d&0xf]; + d = *pMem++; *pDst++ = szHex[d>>4]; *pDst++ = szHex[d&0xf]; + d = *pMem++; *pDst++ = szHex[d>>4]; *pDst++ = szHex[d&0xf]; + d = *pMem++; *pDst++ = szHex[d>>4]; *pDst++ = szHex[d&0xf]; + + d = *pMem++; *pDst++ = szHex[d>>4]; *pDst++ = szHex[d&0xf]; + d = *pMem++; *pDst++ = szHex[d>>4]; *pDst++ = szHex[d&0xf]; + d = *pMem++; *pDst++ = szHex[d>>4]; *pDst++ = szHex[d&0xf]; + d = *pMem++; *pDst++ = szHex[d>>4]; *pDst++ = szHex[d&0xf]; + } + + *pDst++ = '\n'; + *pDst = 0; // For debugger + + fwrite(pLine, 1, lineSize-1, m_hFile); // -1 so don't write null terminator + } + + delete [] pLine; +} + +std::string YamlSaveHelper::GetSaveString(const char* pValue) +{ + return (pValue[0] != 0) ? pValue : "\"\""; +} diff --git a/source/YamlHelper.h b/source/YamlHelper.h new file mode 100644 index 00000000..6fe2e935 --- /dev/null +++ b/source/YamlHelper.h @@ -0,0 +1,300 @@ +#pragma once + +#include "yaml.h" + +#define SS_YAML_KEY_FILEHDR "File_hdr" +#define SS_YAML_KEY_TAG "Tag" +#define SS_YAML_KEY_VERSION "Version" +#define SS_YAML_KEY_UNIT "Unit" +#define SS_YAML_KEY_UNIT_TYPE "Type" +#define SS_YAML_KEY_TYPE "Type" +#define SS_YAML_KEY_CARD "Card" +#define SS_YAML_KEY_STATE "State" + +#define SS_YAML_VALUE_AWSS "AppleWin Save State" +#define SS_YAML_VALUE_UNIT_CARD "Card" +#define SS_YAML_VALUE_UNIT_CONFIG "Config" + +struct MapValue; +typedef std::map MapYaml; + +struct MapValue +{ + std::string value; + MapYaml* subMap; +}; + +class YamlHelper +{ +friend class YamlLoadHelper; // YamlLoadHelper can access YamlHelper's private members + +public: + YamlHelper(void) : + m_hFile(NULL) + { + MakeAsciiToHexTable(); + } + + ~YamlHelper(void) + { + if (m_hFile) + fclose(m_hFile); + } + + int InitParser(const char* pPathname); + void FinaliseParser(void); + + void GetNextEvent(bool bInMap = false); + int GetScalar(std::string& scalar); + void GetListStartEvent(void); +// void GetListEndEvent(void); + void GetMapStartEvent(void); + void GetMapEndEvent(void); + int GetMapStartOrListEndEvent(void); + std::string GetMapName(void) { return m_mapName; } + +private: + int ParseMap(MapYaml& mapYaml); + std::string GetMapValue(MapYaml& mapYaml, const std::string key, bool& bFound); + void GetMapValueMemory(MapYaml& mapYaml, const LPBYTE pMemBase, const size_t kAddrSpaceSize); + bool GetSubMap(MapYaml** mapYaml, const std::string key); + void GetMapRemainder(MapYaml& mapYaml); + + void MakeAsciiToHexTable(void); + + yaml_parser_t m_parser; + yaml_event_t m_newEvent; + + std::string m_scalarName; + + FILE* m_hFile; + char m_AsciiToHex[256]; + + // + + std::string m_lastMapName; + std::string m_mapName; + + struct MapState + { + std::string name; + bool isInMap; + }; + + std::stack< MapState > m_stackMapState; + + MapYaml m_mapYaml; +}; + +// ----- + +class YamlLoadHelper +{ +public: + YamlLoadHelper(YamlHelper& yamlHelper) + : m_yamlHelper(yamlHelper), + m_pMapYaml(&yamlHelper.m_mapYaml), + m_bIteratingOverMap(false) + { + if (!m_yamlHelper.ParseMap(yamlHelper.m_mapYaml)) + throw std::string(m_yamlHelper.GetMapName() + ": Failed to parse map"); + } + + ~YamlLoadHelper(void) + { + m_yamlHelper.GetMapRemainder(m_yamlHelper.m_mapYaml); + } + + INT GetMapValueINT(const std::string key) + { + bool bFound; + std::string value = m_yamlHelper.GetMapValue(*m_pMapYaml, key, bFound); + if (value == "") throw std::string(m_yamlHelper.GetMapName() + ": Missing: " + key); + return strtol(value.c_str(), NULL, 0); + } + + UINT GetMapValueUINT(const std::string key) + { + bool bFound; + std::string value = m_yamlHelper.GetMapValue(*m_pMapYaml, key, bFound); + if (value == "") throw std::string(m_yamlHelper.GetMapName() + ": Missing: " + key); + return strtoul(value.c_str(), NULL, 0); + } + + UINT64 GetMapValueUINT64(const std::string key) + { + bool bFound; + std::string value = m_yamlHelper.GetMapValue(*m_pMapYaml, key, bFound); + if (value == "") throw std::string(m_yamlHelper.GetMapName() + ": Missing: " + key); + return _strtoui64(value.c_str(), NULL, 0); + } + + bool GetMapValueBool(const std::string key) + { + return GetMapValueUINT(key) ? true : false; + } + + BOOL GetMapValueBOOL(const std::string key) + { + return GetMapValueUINT(key) ? TRUE : FALSE; + } + + std::string GetMapValueSTRING_NoThrow(const std::string& key, bool& bFound) + { + std::string value = m_yamlHelper.GetMapValue(*m_pMapYaml, key, bFound); + return value; + } + + std::string GetMapValueSTRING(const std::string& key) + { + bool bFound; + std::string value = GetMapValueSTRING_NoThrow(key, bFound); + if (!bFound) throw std::string(m_yamlHelper.GetMapName() + ": Missing: " + key); + return value; + } + + void GetMapValueMemory(const LPBYTE pMemBase, const size_t size) + { + m_yamlHelper.GetMapValueMemory(*m_pMapYaml, pMemBase, size); + } + + bool GetSubMap(const std::string key) + { + m_stackMap.push(m_pMapYaml); + bool res = m_yamlHelper.GetSubMap(&m_pMapYaml, key); + if (!res) + m_stackMap.pop(); + return res; + } + + void PopMap(void) + { + if (m_stackMap.empty()) + return; + + m_pMapYaml = m_stackMap.top(); + m_stackMap.pop(); + } + + std::string GetMapNextSlotNumber(void) + { + if (!m_bIteratingOverMap) + { + m_iter = m_pMapYaml->begin(); + m_bIteratingOverMap = true; + } + + if (m_iter == m_pMapYaml->end()) + { + m_bIteratingOverMap = false; + return ""; + } + + std::string scalar = m_iter->first; + ++m_iter; + return scalar; + } + +private: + YamlHelper& m_yamlHelper; + MapYaml* m_pMapYaml; + std::stack m_stackMap; + + bool m_bIteratingOverMap; + MapYaml::iterator m_iter; +}; + +// ----- + +class YamlSaveHelper +{ +friend class Indent; // Indent can access YamlSaveHelper's private members +public: + YamlSaveHelper(std::string pathname) : + m_hFile(NULL), + m_indent(0) + { + m_hFile = fopen(pathname.c_str(), "wt"); + + // todo: handle ERROR_ALREADY_EXISTS - ask if user wants to replace existing file + // - at this point any old file will have been truncated to zero + + if(m_hFile == NULL) + throw std::string("Save error"); + + _tzset(); + time_t ltime; + time(<ime); + char timebuf[26]; + errno_t err = ctime_s(timebuf, sizeof(timebuf), <ime); // includes newline at end of string + fprintf(m_hFile, "# Date-stamp: %s\n", err == 0 ? timebuf : "Error: Datestamp\n\n"); + + fprintf(m_hFile, "---\n"); + + // + + memset(m_szIndent, ' ', kMaxIndent); + } + + ~YamlSaveHelper() + { + if (m_hFile) + { + fprintf(m_hFile, "...\n"); + fclose(m_hFile); + } + } + + void Save(const char* format, ...); + + class Label + { + public: + Label(YamlSaveHelper& rYamlSaveHelper, const char* format, ...) : + yamlSaveHelper(rYamlSaveHelper) + { + fwrite(yamlSaveHelper.m_szIndent, 1, yamlSaveHelper.m_indent, yamlSaveHelper.m_hFile); + + va_list vl; + va_start(vl, format); + vfprintf(yamlSaveHelper.m_hFile, format, vl); + va_end(vl); + + yamlSaveHelper.m_indent += 2; + _ASSERT(yamlSaveHelper.m_indent < yamlSaveHelper.kMaxIndent); + } + + ~Label(void) + { + yamlSaveHelper.m_indent -= 2; + _ASSERT(yamlSaveHelper.m_indent >= 0); + } + + YamlSaveHelper& yamlSaveHelper; + }; + + class Slot : public Label + { + public: + Slot(YamlSaveHelper& rYamlSaveHelper, std::string type, UINT slot, UINT version) : + Label(rYamlSaveHelper, "%d:\n", slot) + { + rYamlSaveHelper.Save("%s: %s\n", SS_YAML_KEY_CARD, type.c_str()); + rYamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_VERSION, version); + } + + ~Slot(void) {} + }; + + void FileHdr(UINT version); + void UnitHdr(std::string type, UINT version); + void SaveMapValueMemory(const LPBYTE pMemBase, const UINT uMemSize); + std::string GetSaveString(const char* pValue); + +private: + FILE* m_hFile; + + int m_indent; + static const UINT kMaxIndent = 50*2; + char m_szIndent[kMaxIndent]; +}; diff --git a/source/Z80VICE/z80.cpp b/source/Z80VICE/z80.cpp index 6b802f1d..21c7c885 100644 --- a/source/Z80VICE/z80.cpp +++ b/source/Z80VICE/z80.cpp @@ -29,6 +29,7 @@ #include "..\AppleWin.h" #include "..\CPU.h" #include "..\Memory.h" +#include "..\YamlHelper.h" #undef IN // Defined in windef.h @@ -6433,6 +6434,142 @@ void z80_WRMEM(WORD Addr, BYTE Value) //=========================================================================== +#define SS_YAML_VALUE_CARD_Z80 "Z80" + +#define SS_YAML_KEY_REGA "A" +#define SS_YAML_KEY_REGB "B" +#define SS_YAML_KEY_REGC "C" +#define SS_YAML_KEY_REGD "D" +#define SS_YAML_KEY_REGE "E" +#define SS_YAML_KEY_REGF "F" +#define SS_YAML_KEY_REGH "H" +#define SS_YAML_KEY_REGL "L" +#define SS_YAML_KEY_REGIX "IX" +#define SS_YAML_KEY_REGIY "IY" +#define SS_YAML_KEY_REGSP "SP" +#define SS_YAML_KEY_REGPC "PC" +#define SS_YAML_KEY_REGI "I" +#define SS_YAML_KEY_REGR "R" +#define SS_YAML_KEY_IFF1 "IFF1" +#define SS_YAML_KEY_IFF2 "IFF2" +#define SS_YAML_KEY_IM_MODE "IM Mode" +#define SS_YAML_KEY_REGA2 "A'" +#define SS_YAML_KEY_REGB2 "B'" +#define SS_YAML_KEY_REGC2 "C'" +#define SS_YAML_KEY_REGD2 "D'" +#define SS_YAML_KEY_REGE2 "E'" +#define SS_YAML_KEY_REGF2 "F'" +#define SS_YAML_KEY_REGH2 "H'" +#define SS_YAML_KEY_REGL2 "L'" +#define SS_YAML_KEY_ACTIVE "Active" + +std::string Z80_GetSnapshotCardName(void) +{ + static const std::string name(SS_YAML_VALUE_CARD_Z80); + return name; +} + +void Z80_SaveSnapshot(class YamlSaveHelper& yamlSaveHelper, const UINT uSlot) +{ + YamlSaveHelper::Slot slot(yamlSaveHelper, Z80_GetSnapshotCardName(), uSlot, 1); // fixme: object should know its slot + + YamlSaveHelper::Label state(yamlSaveHelper, "%s:\n", SS_YAML_KEY_STATE); + + // SoftCard SW & HW details: http://apple2info.net/images/f/f0/SC-SWHW.pdf + // . SoftCard uses the Apple II's DMA circuit to pause the 6502 (no CLK to 6502) + // . But: "In Apple II DMA, the 6502 CPU will die after approximately 15 clocks because it depends on the clock to refresh its internal registers." + // ref: Apple Tech Note: https://archive.org/stream/IIe_2523004_RDY_Line/IIe_2523004_RDY_Line_djvu.txt + // NB. Not for 65C02 which is a static processor. + // . SoftCard controls the 6502's RDY line to periodically allow only 1 memory fetch by 6502 (ie. the opcode fetch) + // + // So save /g_ActiveCPU/ to SS_CARD_Z80 (so RDY is like IRQ & NMI signals, ie. saved struct of the producer's card) + // + // NB. Save-state only occurs when message pump runs: + // . ie. at end of 1ms emulation burst + // Either 6502 or Z80 could be active. + // + + yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_ACTIVE, g_ActiveCPU == CPU_Z80 ? 1 : 0); + + yamlSaveHelper.Save("%s: 0x%02X\n", SS_YAML_KEY_REGA, reg_a); + yamlSaveHelper.Save("%s: 0x%02X\n", SS_YAML_KEY_REGB, reg_b); + yamlSaveHelper.Save("%s: 0x%02X\n", SS_YAML_KEY_REGC, reg_c); + yamlSaveHelper.Save("%s: 0x%02X\n", SS_YAML_KEY_REGD, reg_d); + yamlSaveHelper.Save("%s: 0x%02X\n", SS_YAML_KEY_REGE, reg_e); + yamlSaveHelper.Save("%s: 0x%02X\n", SS_YAML_KEY_REGF, reg_f); + yamlSaveHelper.Save("%s: 0x%02X\n", SS_YAML_KEY_REGH, reg_h); + yamlSaveHelper.Save("%s: 0x%02X\n", SS_YAML_KEY_REGL, reg_l); + yamlSaveHelper.Save("%s: 0x%04X\n", SS_YAML_KEY_REGIX, ((USHORT)reg_ixh<<8)|(USHORT)reg_ixl); + yamlSaveHelper.Save("%s: 0x%04X\n", SS_YAML_KEY_REGIY, ((USHORT)reg_iyh<<8)|(USHORT)reg_iyl); + yamlSaveHelper.Save("%s: 0x%04X\n", SS_YAML_KEY_REGSP, reg_sp); + yamlSaveHelper.Save("%s: 0x%04X\n", SS_YAML_KEY_REGPC, (USHORT)z80_reg_pc); + yamlSaveHelper.Save("%s: 0x%02X\n", SS_YAML_KEY_REGI, reg_i); + yamlSaveHelper.Save("%s: 0x%02X\n", SS_YAML_KEY_REGR, reg_r); + + yamlSaveHelper.Save("%s: 0x%02X\n", SS_YAML_KEY_IFF1, iff1); + yamlSaveHelper.Save("%s: 0x%02X\n", SS_YAML_KEY_IFF2, iff2); + yamlSaveHelper.Save("%s: 0x%02X\n", SS_YAML_KEY_IM_MODE, im_mode); + + yamlSaveHelper.Save("%s: 0x%02X\n", SS_YAML_KEY_REGA2, reg_a2); + yamlSaveHelper.Save("%s: 0x%02X\n", SS_YAML_KEY_REGB2, reg_b2); + yamlSaveHelper.Save("%s: 0x%02X\n", SS_YAML_KEY_REGC2, reg_c2); + yamlSaveHelper.Save("%s: 0x%02X\n", SS_YAML_KEY_REGD2, reg_d2); + yamlSaveHelper.Save("%s: 0x%02X\n", SS_YAML_KEY_REGE2, reg_e2); + yamlSaveHelper.Save("%s: 0x%02X\n", SS_YAML_KEY_REGF2, reg_f2); + yamlSaveHelper.Save("%s: 0x%02X\n", SS_YAML_KEY_REGH2, reg_h2); + yamlSaveHelper.Save("%s: 0x%02X\n", SS_YAML_KEY_REGL2, reg_l2); +} + +bool Z80_LoadSnapshot(class YamlLoadHelper& yamlLoadHelper, UINT uSlot, UINT version) +{ + if (uSlot != 4 && uSlot != 5) // fixme + throw std::string("Card: wrong slot"); + + if (version != 1) + throw std::string("Card: wrong version"); + + reg_a = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_REGA); + reg_b = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_REGB); + reg_c = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_REGC); + reg_d = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_REGD); + reg_e = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_REGE); + reg_f = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_REGF); + reg_h = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_REGH); + reg_l = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_REGL); + USHORT IX = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_REGIX); + reg_ixh = IX >> 8; + reg_ixl = IX & 0xFF; + USHORT IY = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_REGIY); + reg_iyh = IY >> 8; + reg_iyl = IY & 0xFF; + reg_sp = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_REGSP); + z80_reg_pc = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_REGPC); + reg_i = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_REGI); + reg_r = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_REGR); + + iff1 = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_IFF1); + iff2 = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_IFF2); + im_mode = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_IM_MODE); + + reg_a2 = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_REGA2); + reg_b2 = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_REGB2); + reg_c2 = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_REGC2); + reg_d2 = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_REGD2); + reg_e2 = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_REGE2); + reg_f2 = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_REGF2); + reg_h2 = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_REGH2); + reg_l2 = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_REGL2); + + export_registers(); + + if ( yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_ACTIVE) ) + g_ActiveCPU = CPU_Z80; // Support MS SoftCard in multiple slots (only one Z80 can be active at any one time) + + return true; +} + +//--- + struct Z80_Unit { BYTE reg_a; diff --git a/source/z80emu.h b/source/z80emu.h index 13e0b705..49fced1f 100644 --- a/source/z80emu.h +++ b/source/z80emu.h @@ -16,5 +16,8 @@ void ConfigureSoftcard(LPBYTE pCxRomPeripheral, UINT uSlot); // NB. These are in z80.cpp: +std::string Z80_GetSnapshotCardName(void); +void Z80_SaveSnapshot(class YamlSaveHelper& yamlSaveHelper, const UINT uSlot); +bool Z80_LoadSnapshot(class YamlLoadHelper& yamlLoadHelper, UINT uSlot, UINT version); void Z80_GetSnapshot(const HANDLE hFile, const UINT uZ80Slot); void Z80_SetSnapshot(const HANDLE hFile); diff --git a/test/TestCPU6502/stdafx.h b/test/TestCPU6502/stdafx.h index ca800fd6..47956f7e 100644 --- a/test/TestCPU6502/stdafx.h +++ b/test/TestCPU6502/stdafx.h @@ -9,3 +9,5 @@ #include #include + +#include From 37ad1ebd632291caaa21abf4450e74cc9dacd8c6 Mon Sep 17 00:00:00 2001 From: tomcw Date: Sun, 14 Feb 2016 16:01:30 +0000 Subject: [PATCH 10/20] Removed redundant binary v2 save-state code Also: . support new CpuType independently of Apple2Type . save-state: don't save disk track image if no disk . save-state: re-init AppleWin internals & UI to reflect changed Apple2Type --- ApplewinExpress9.00.vcproj | 4 - source/AY8910.cpp | 169 ------ source/AY8910.h | 2 - source/Applewin.cpp | 65 +- source/Applewin.h | 6 +- source/CPU.cpp | 100 ++-- source/CPU.h | 11 +- source/CPU/cpu6502.h | 2 +- source/CPU/cpu65C02.h | 2 +- source/CPU/cpu65d02.h | 2 +- source/Common.h | 1 + source/Configuration/Config.h | 7 +- source/Configuration/PageConfig.cpp | 1 + source/Configuration/PropertySheetHelper.cpp | 52 +- source/Configuration/PropertySheetHelper.h | 1 + source/Disk.cpp | 209 +------ source/Disk.h | 2 - source/Frame.cpp | 26 +- source/Frame.h | 1 + source/Harddisk.cpp | 156 ----- source/Harddisk.h | 2 - source/Joystick.cpp | 18 - source/Joystick.h | 2 - source/Keyboard.cpp | 12 - source/Keyboard.h | 2 - source/Memory.cpp | 158 ----- source/Memory.h | 4 - source/Mockingboard.cpp | 273 --------- source/Mockingboard.h | 4 - source/MouseInterface.cpp | 160 ----- source/MouseInterface.h | 2 - source/ParallelPrinter.cpp | 103 ---- source/ParallelPrinter.h | 2 - source/SaveState.cpp | 598 +------------------ source/SaveState_Structs_v2.h | 129 ---- source/SerialComms.cpp | 121 ---- source/SerialComms.h | 2 - source/Speaker.cpp | 12 - source/Speaker.h | 2 - source/Video.cpp | 17 - source/Video.h | 2 - source/YamlHelper.cpp | 73 +-- source/YamlHelper.h | 85 ++- source/Z80VICE/z80.cpp | 186 +----- source/z80emu.cpp | 3 +- source/z80emu.h | 2 - test/TestCPU6502/TestCPU6502.cpp | 8 +- 47 files changed, 302 insertions(+), 2499 deletions(-) delete mode 100644 source/SaveState_Structs_v2.h diff --git a/ApplewinExpress9.00.vcproj b/ApplewinExpress9.00.vcproj index b710ac63..0e4d70b8 100644 --- a/ApplewinExpress9.00.vcproj +++ b/ApplewinExpress9.00.vcproj @@ -782,10 +782,6 @@ RelativePath=".\source\SaveState_Structs_v1.h" >
- - diff --git a/source/AY8910.cpp b/source/AY8910.cpp index 4305aa9b..b40f26b0 100644 --- a/source/AY8910.cpp +++ b/source/AY8910.cpp @@ -1134,159 +1134,6 @@ bool CAY8910::LoadSnapshot(YamlLoadHelper& yamlLoadHelper, std::string& suffix) return true; } -// - -// disable warning C4200: zero-sized array in struct/union -#pragma warning(disable: 4200) - -struct SS_AY8910 -{ - unsigned int ay_tone_tick[3], ay_tone_high[3], ay_noise_tick; - unsigned int ay_tone_subcycles, ay_env_subcycles; - unsigned int ay_env_internal_tick, ay_env_tick; - unsigned int ay_tick_incr; - unsigned int ay_tone_period[3], ay_noise_period, ay_env_period; - - BYTE sound_ay_registers[16]; - - int rng; - int noise_toggle; - int env_first, env_rev, env_counter; - - int ay_change_count; - void* ay_change[0]; // real type is ay_change_tag (but this is private) -}; - -UINT CAY8910::GetSnapshot(const HANDLE hFile) -{ - const UINT uAYChangeLength = ay_change_count * sizeof(ay_change_tag); - const UINT uAYTotalLength = sizeof(SS_AY8910) + uAYChangeLength; - - if (hFile == NULL) - return uAYTotalLength; - - // - - SS_AY8910 ay_state; - - memcpy(ay_state.ay_tone_tick, ay_tone_tick, sizeof(ay_tone_tick)); - memcpy(ay_state.ay_tone_high, ay_tone_high, sizeof(ay_tone_high)); - ay_state.ay_noise_tick = ay_noise_tick; - ay_state.ay_tone_subcycles = ay_tone_subcycles; - ay_state.ay_env_subcycles = ay_env_subcycles; - ay_state.ay_env_internal_tick = ay_env_internal_tick; - ay_state.ay_env_tick = ay_env_tick; - ay_state.ay_tick_incr = ay_tick_incr; - memcpy(ay_state.ay_tone_period, ay_tone_period, sizeof(ay_tone_period)); - ay_state.ay_noise_period = ay_noise_period; - ay_state.ay_env_period = ay_env_period; - - memcpy(ay_state.sound_ay_registers, sound_ay_registers, sizeof(sound_ay_registers)); - - ay_state.rng = rng; - ay_state.noise_toggle = noise_toggle; - ay_state.env_first = env_first; - ay_state.env_rev = env_rev; - ay_state.env_counter = env_counter; - - ay_state.ay_change_count = ay_change_count; - - // - - DWORD dwBytesWritten; - BOOL bRes = WriteFile( hFile, - &ay_state, - sizeof(SS_AY8910), - &dwBytesWritten, - NULL); - - if(!bRes || (dwBytesWritten != sizeof(SS_AY8910))) - { - //dwError = GetLastError(); - throw std::string("Save error: AY8910"); - } - - // - - if (uAYChangeLength) - { - DWORD dwBytesWritten2; - BOOL bRes2 = WriteFile( hFile, - ay_change, - uAYChangeLength, - &dwBytesWritten2, - NULL); - - if(!bRes2 || (dwBytesWritten2 != uAYChangeLength)) - { - //dwError = GetLastError(); - throw std::string("Save error: AY8910"); - } - } - - return uAYTotalLength; -} - -UINT CAY8910::SetSnapshot(const HANDLE hFile) -{ - SS_AY8910 ay_state; - - DWORD dwBytesRead; - BOOL bRes = ReadFile( hFile, - &ay_state, - sizeof(SS_AY8910), - &dwBytesRead, - NULL); - - if (dwBytesRead != sizeof(SS_AY8910)) - throw std::string("Card: file corrupt"); - - if (ay_state.ay_change_count > AY_CHANGE_MAX) - throw std::string("Card: file corrupt"); - - // - - memcpy(ay_tone_tick, ay_state.ay_tone_tick, sizeof(ay_tone_tick)); - memcpy(ay_tone_high, ay_state.ay_tone_high, sizeof(ay_tone_high)); - ay_noise_tick = ay_state.ay_noise_tick; - ay_tone_subcycles = ay_state.ay_tone_subcycles; - ay_env_subcycles = ay_state.ay_env_subcycles; - ay_env_internal_tick = ay_state.ay_env_internal_tick; - ay_env_tick = ay_state.ay_env_tick; - ay_tick_incr = ay_state.ay_tick_incr; - memcpy(ay_tone_period, ay_state.ay_tone_period, sizeof(ay_tone_period)); - ay_noise_period = ay_state.ay_noise_period; - ay_env_period = ay_state.ay_env_period; - - memcpy(sound_ay_registers, ay_state.sound_ay_registers, sizeof(sound_ay_registers)); - - rng = ay_state.rng; - noise_toggle = ay_state.noise_toggle; - env_first = ay_state.env_first; - env_rev = ay_state.env_rev; - env_counter = ay_state.env_counter; - - ay_change_count = ay_state.ay_change_count; - - // - - const UINT uLength = ay_change_count * sizeof(ay_change_tag); - if (uLength) - { - DWORD dwBytesRead2; - BOOL bRes = ReadFile( hFile, - ay_change, - uLength, - &dwBytesRead2, - NULL); - - if (dwBytesRead2 != uLength) - throw std::string("Card: file corrupt"); - } - - return dwBytesRead+uLength; -} - /////////////////////////////////////////////////////////////////////////////// // AY8910 interface @@ -1365,19 +1212,3 @@ UINT AY8910_LoadSnapshot(YamlLoadHelper& yamlLoadHelper, UINT uChip, std::string return g_AY8910[uChip].LoadSnapshot(yamlLoadHelper, suffix) ? 1 : 0; } - -UINT AY8910_GetSnapshot(const HANDLE hFile, UINT uChip) -{ - if (uChip >= MAX_8910) - return 0; - - return g_AY8910[uChip].GetSnapshot(hFile); -} - -UINT AY8910_SetSnapshot(const HANDLE hFile, UINT uChip) -{ - if (uChip >= MAX_8910) - return 0; - - return g_AY8910[uChip].SetSnapshot(hFile); -} diff --git a/source/AY8910.h b/source/AY8910.h index f33e0630..ea2596e6 100644 --- a/source/AY8910.h +++ b/source/AY8910.h @@ -19,8 +19,6 @@ void AY8910UpdateSetCycles(); UINT AY8910_SaveSnapshot(class YamlSaveHelper& yamlSaveHelper, UINT uChip, std::string& suffix); UINT AY8910_LoadSnapshot(class YamlLoadHelper& yamlLoadHelper, UINT uChip, std::string& suffix); -UINT AY8910_GetSnapshot(const HANDLE hFile, UINT uChip); -UINT AY8910_SetSnapshot(const HANDLE hFile, UINT uChip); //------------------------------------- // FUSE stuff diff --git a/source/Applewin.cpp b/source/Applewin.cpp index 59e2284c..b8608c33 100644 --- a/source/Applewin.cpp +++ b/source/Applewin.cpp @@ -99,8 +99,6 @@ CMouseInterface sg_Mouse; SS_CARDTYPE g_Slot4 = CT_Empty; SS_CARDTYPE g_Slot5 = CT_Empty; -eCPU g_ActiveCPU = CPU_6502; - HANDLE g_hCustomRomF8 = INVALID_HANDLE_VALUE; // Cmd-line specified custom ROM at $F800..$FFFF static bool g_bCustomRomF8Failed = false; // Set if custom ROM file failed @@ -111,6 +109,17 @@ CSpeech g_Speech; //=========================================================================== +eApple2Type GetApple2Type(void) +{ + return g_Apple2Type; +} + +void SetApple2Type(eApple2Type type) +{ + g_Apple2Type = type; + SetMainCpuDefault(type); +} + const UINT16* GetAppleWinVersion(void) { return &g_AppleWinVersion[0]; @@ -375,17 +384,36 @@ static void LoadConfigOldJoystick(const UINT uJoyNum) JoySetJoyType(uJoyNum, uNewJoyType); } +//Sets the character set for the Apple model/clone +void SetCharsetType(void) +{ + switch ( GetApple2Type() ) + { + case A2TYPE_APPLE2: g_nCharsetType = 0; break; + case A2TYPE_APPLE2PLUS: g_nCharsetType = 0; break; + case A2TYPE_APPLE2E: g_nCharsetType = 0; break; + case A2TYPE_APPLE2EENHANCED:g_nCharsetType = 0; break; + case A2TYPE_PRAVETS82: g_nCharsetType = 1; break; + case A2TYPE_PRAVETS8A: g_nCharsetType = 2; break; + case A2TYPE_PRAVETS8M: g_nCharsetType = 3; break; //This charset has a very small difference with the PRAVETS82 one an probably has some misplaced characters. Still the Pravets82 charset is used, because setting charset to 3 results in some problems. + default: + _ASSERT(0); + g_nCharsetType = 0; + } +} + //Reads configuration from the registry entries void LoadConfiguration(void) { DWORD dwComputerType; + eApple2Type apple2Type = A2TYPE_APPLE2EENHANCED; if (REGLOAD(TEXT(REGVALUE_APPLE2_TYPE), &dwComputerType)) { if ((dwComputerType >= A2TYPE_MAX) || (dwComputerType >= A2TYPE_UNDEFINED && dwComputerType < A2TYPE_CLONE)) dwComputerType = A2TYPE_APPLE2EENHANCED; - g_Apple2Type = (eApple2Type) dwComputerType; + apple2Type = (eApple2Type) dwComputerType; } else // Support older AppleWin registry entries { @@ -393,24 +421,31 @@ void LoadConfiguration(void) switch (dwComputerType) { // NB. No A2TYPE_APPLE2E (this is correct) - case 0: g_Apple2Type = A2TYPE_APPLE2; - case 1: g_Apple2Type = A2TYPE_APPLE2PLUS; - case 2: g_Apple2Type = A2TYPE_APPLE2EENHANCED; - default: g_Apple2Type = A2TYPE_APPLE2EENHANCED; + case 0: apple2Type = A2TYPE_APPLE2; break; + case 1: apple2Type = A2TYPE_APPLE2PLUS; break; + case 2: apple2Type = A2TYPE_APPLE2EENHANCED; break; + default: apple2Type = A2TYPE_APPLE2EENHANCED; } } - switch (g_Apple2Type) //Sets the character set for the Apple model/clone + SetApple2Type(apple2Type); + SetCharsetType(); + + // + + DWORD dwCpuType; + eCpuType cpu = CPU_65C02; + + if (REGLOAD(TEXT(REGVALUE_CPU_TYPE), &dwCpuType)) { - case A2TYPE_APPLE2: g_nCharsetType = 0; break; - case A2TYPE_APPLE2PLUS: g_nCharsetType = 0; break; - case A2TYPE_APPLE2E: g_nCharsetType = 0; break; - case A2TYPE_APPLE2EENHANCED:g_nCharsetType = 0; break; - case A2TYPE_PRAVETS82: g_nCharsetType = 1; break; - case A2TYPE_PRAVETS8A: g_nCharsetType = 2; break; - case A2TYPE_PRAVETS8M: g_nCharsetType = 3; break; //This charset has a very small difference with the PRAVETS82 one an probably has some misplaced characters. Still the Pravets82 charset is used, because setting charset to 3 results in some problems. + if (dwCpuType != CPU_6502 && dwCpuType != CPU_65C02) + dwCpuType = CPU_65C02; + + cpu = (eCpuType) dwCpuType; } + SetMainCpu(cpu); + // DWORD dwJoyType; diff --git a/source/Applewin.h b/source/Applewin.h index a8313335..cb15246e 100644 --- a/source/Applewin.h +++ b/source/Applewin.h @@ -5,6 +5,7 @@ void SetCurrentCLK6502(); void SetCurrentImageDir(const char* pszImageDir); +void SetCharsetType(void); extern const UINT16* GetAppleWinVersion(void); extern char VERSIONSTRING[]; // Constructed in WinMain() @@ -12,6 +13,8 @@ extern char VERSIONSTRING[]; // Constructed in WinMain() extern TCHAR *g_pAppTitle; extern eApple2Type g_Apple2Type; +eApple2Type GetApple2Type(void); +void SetApple2Type(eApple2Type type); extern bool g_bFullSpeed; @@ -46,9 +49,6 @@ extern SS_CARDTYPE g_Slot5; // Mockingboard, Z80, in slot5 extern HANDLE g_hCustomRomF8; // NULL if no custom rom -enum eCPU {CPU_6502=1, CPU_Z80}; -extern eCPU g_ActiveCPU; - #ifdef USE_SPEECH_API class CSpeech; extern CSpeech g_Speech; diff --git a/source/CPU.cpp b/source/CPU.cpp index f693f053..e12e28a3 100644 --- a/source/CPU.cpp +++ b/source/CPU.cpp @@ -102,7 +102,6 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #include "Z80VICE\z80mem.h" #include "Debugger\Debug.h" -#include "SaveState_Structs_v2.h" #include "YamlHelper.h" @@ -147,6 +146,54 @@ static volatile UINT32 g_bmIRQ = 0; static volatile UINT32 g_bmNMI = 0; static volatile BOOL g_bNmiFlank = FALSE; // Positive going flank on NMI line +// + +static eCpuType g_MainCPU = CPU_65C02; +static eCpuType g_ActiveCPU = CPU_65C02; + +eCpuType GetMainCpu(void) +{ + return g_MainCPU; +} + +void SetMainCpu(eCpuType cpu) +{ + _ASSERT(cpu != CPU_Z80); + if (cpu == CPU_Z80) + return; + + g_MainCPU = cpu; +} + +static bool IsCpu6502(eApple2Type apple2Type) +{ + return IS_APPLE2 || + (apple2Type == A2TYPE_APPLE2E) || + IS_CLONE(); // NB. All Pravets clones are 6502 (GH#307) +} + +eCpuType ProbeMainCpuDefault(eApple2Type apple2Type) +{ + return IsCpu6502(apple2Type) ? CPU_6502 : CPU_65C02; +} + +void SetMainCpuDefault(eApple2Type apple2Type) +{ + SetMainCpu( ProbeMainCpuDefault(apple2Type) ); +} + +eCpuType GetActiveCpu(void) +{ + return g_ActiveCPU; +} + +void SetActiveCpu(eCpuType cpu) +{ + g_ActiveCPU = cpu; +} + +// + #include "cpu/cpu_general.inl" #include "cpu/cpu_instructions.inl" @@ -406,16 +453,9 @@ static __forceinline void CheckInterruptSources(ULONG uExecutedCycles) //=========================================================================== -static bool IsCpu6502(void) -{ - return IS_APPLE2 || - (g_Apple2Type == A2TYPE_APPLE2E) || - IS_CLONE(); // NB. All Pravets clones are 6502 (GH#307) -} - static DWORD InternalCpuExecute (DWORD uTotalCycles) { - if (IsCpu6502()) + if (GetMainCpu() == CPU_6502) return Cpu6502(uTotalCycles); // Apple ][, ][+, //e, Clones else return Cpu65C02(uTotalCycles); // Enhanced Apple //e @@ -645,7 +685,7 @@ void CpuReset() regs.bJammed = 0; - g_ActiveCPU = CPU_6502; + SetActiveCpu( GetMainCpu() ); z80_reset(); } @@ -690,7 +730,7 @@ void CpuSaveSnapshot(YamlSaveHelper& yamlSaveHelper) regs.ps |= (AF_RESERVED | AF_BREAK); YamlSaveHelper::Label state(yamlSaveHelper, "%s:\n", CpuGetSnapshotStructName().c_str()); - yamlSaveHelper.Save("%s: %s # NB. Currently ignored\n", SS_YAML_KEY_CPU_TYPE, IsCpu6502() ? SS_YAML_VALUE_6502 : SS_YAML_VALUE_65C02); + yamlSaveHelper.Save("%s: %s\n", SS_YAML_KEY_CPU_TYPE, GetMainCpu() == CPU_6502 ? SS_YAML_VALUE_6502 : SS_YAML_VALUE_65C02); yamlSaveHelper.Save("%s: 0x%02X\n", SS_YAML_KEY_REGA, regs.a); yamlSaveHelper.Save("%s: 0x%02X\n", SS_YAML_KEY_REGX, regs.x); yamlSaveHelper.Save("%s: 0x%02X\n", SS_YAML_KEY_REGY, regs.y); @@ -705,7 +745,13 @@ void CpuLoadSnapshot(YamlLoadHelper& yamlLoadHelper) if (!yamlLoadHelper.GetSubMap(CpuGetSnapshotStructName())) return; - yamlLoadHelper.GetMapValueSTRING(SS_YAML_KEY_CPU_TYPE); // consume - not currently used + std::string cpuType = yamlLoadHelper.GetMapValueSTRING(SS_YAML_KEY_CPU_TYPE); + eCpuType cpu; + if (cpuType == SS_YAML_VALUE_6502) cpu = CPU_6502; + else if (cpuType == SS_YAML_VALUE_65C02) cpu = CPU_65C02; + else throw std::string("Load: Unknown main CPU type"); + SetMainCpu(cpu); + regs.a = (BYTE) yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_REGA); regs.x = (BYTE) yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_REGX); regs.y = (BYTE) yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_REGY); @@ -719,33 +765,3 @@ void CpuLoadSnapshot(YamlLoadHelper& yamlLoadHelper) yamlLoadHelper.PopMap(); } - -// - -void CpuGetSnapshot(SS_CPU6502_v2& CPU) -{ - regs.ps |= (AF_RESERVED | AF_BREAK); - - CPU.A = regs.a; - CPU.X = regs.x; - CPU.Y = regs.y; - CPU.P = regs.ps; - CPU.S = (BYTE) regs.sp; - CPU.PC = regs.pc; - - CPU.CumulativeCycles = g_nCumulativeCycles; -} - -void CpuSetSnapshot(const SS_CPU6502_v2& CPU) -{ - regs.a = CPU.A; - regs.x = CPU.X; - regs.y = CPU.Y; - regs.ps = CPU.P | (AF_RESERVED | AF_BREAK); - regs.sp = ((USHORT)CPU.S) | 0x100; - regs.pc = CPU.PC; - - CpuIrqReset(); - CpuNmiReset(); - g_nCumulativeCycles = CPU.CumulativeCycles; -} diff --git a/source/CPU.h b/source/CPU.h index 38c46917..5086e9e1 100644 --- a/source/CPU.h +++ b/source/CPU.h @@ -30,10 +30,17 @@ void CpuReset (); void CpuSetSnapshot_v1(const BYTE A, const BYTE X, const BYTE Y, const BYTE P, const BYTE SP, const USHORT PC, const unsigned __int64 CumulativeCycles); void CpuSaveSnapshot(class YamlSaveHelper& yamlSaveHelper); void CpuLoadSnapshot(class YamlLoadHelper& yamlLoadHelper); -void CpuGetSnapshot(struct SS_CPU6502_v2& CPU); -void CpuSetSnapshot(const struct SS_CPU6502_v2& CPU); BYTE CpuRead(USHORT addr, ULONG uExecutedCycles); void CpuWrite(USHORT addr, BYTE a, ULONG uExecutedCycles); DWORD CpuGetEmulationTime_ms(void); + +enum eCpuType {CPU_6502=1, CPU_65C02, CPU_Z80}; // Don't change! Persisted to Registry + +eCpuType GetMainCpu(void); +void SetMainCpu(eCpuType cpu); +eCpuType ProbeMainCpuDefault(eApple2Type apple2Type); +void SetMainCpuDefault(eApple2Type apple2Type); +eCpuType GetActiveCpu(void); +void SetActiveCpu(eCpuType cpu); diff --git a/source/CPU/cpu6502.h b/source/CPU/cpu6502.h index 1815e941..3b58dd91 100644 --- a/source/CPU/cpu6502.h +++ b/source/CPU/cpu6502.h @@ -43,7 +43,7 @@ static DWORD Cpu6502 (DWORD uTotalCycles) UINT uExtraCycles = 0; BYTE iOpcode; - if (g_ActiveCPU == CPU_Z80) + if (GetActiveCpu() == CPU_Z80) { const UINT uZ80Cycles = z80_mainloop(uTotalCycles, uExecutedCycles); CYC(uZ80Cycles) } diff --git a/source/CPU/cpu65C02.h b/source/CPU/cpu65C02.h index 2cafc375..5d649b05 100644 --- a/source/CPU/cpu65C02.h +++ b/source/CPU/cpu65C02.h @@ -46,7 +46,7 @@ static DWORD Cpu65C02 (DWORD uTotalCycles) UINT uExtraCycles = 0; BYTE iOpcode; - if (g_ActiveCPU == CPU_Z80) + if (GetActiveCpu() == CPU_Z80) { const UINT uZ80Cycles = z80_mainloop(uTotalCycles, uExecutedCycles); CYC(uZ80Cycles) } diff --git a/source/CPU/cpu65d02.h b/source/CPU/cpu65d02.h index 0e01abdf..f036c139 100644 --- a/source/CPU/cpu65d02.h +++ b/source/CPU/cpu65d02.h @@ -120,7 +120,7 @@ static DWORD Cpu65D02 (DWORD uTotalCycles) UINT uExtraCycles = 0; BYTE iOpcode; - if (g_ActiveCPU == CPU_Z80) + if (GetActiveCpu() == CPU_Z80) { const UINT uZ80Cycles = z80_mainloop(uTotalCycles, uExecutedCycles); CYC(uZ80Cycles) } diff --git a/source/Common.h b/source/Common.h index b2f9ee22..19be87e0 100644 --- a/source/Common.h +++ b/source/Common.h @@ -69,6 +69,7 @@ enum AppMode_e // Configuration #define REG_CONFIG "Configuration" #define REGVALUE_APPLE2_TYPE "Apple2 Type" +#define REGVALUE_CPU_TYPE "CPU Type" #define REGVALUE_OLD_APPLE2_TYPE "Computer Emulation" // Deprecated #define REGVALUE_CONFIRM_REBOOT "Confirm Reboot" // Added at 1.24.1 PageConfig #define REGVALUE_SPKR_VOLUME "Speaker Volume" diff --git a/source/Configuration/Config.h b/source/Configuration/Config.h index 2724bf69..36be83af 100644 --- a/source/Configuration/Config.h +++ b/source/Configuration/Config.h @@ -1,6 +1,7 @@ #pragma once #include "..\AppleWin.h" +#include "..\CPU.h" #include "..\Disk.h" // BOOL enhancedisk #include "..\HardDisk.h" // HD_CardIsEnabled() @@ -8,7 +9,8 @@ class CConfigNeedingRestart { public: CConfigNeedingRestart(UINT bEnableTheFreezesF8Rom = false) : - m_Apple2Type(g_Apple2Type), + m_Apple2Type( GetApple2Type() ), + m_CpuType( GetMainCpu() ), m_bEnhanceDisk(enhancedisk), m_uSaveLoadStateMsg(0) { @@ -23,6 +25,7 @@ public: const CConfigNeedingRestart& operator= (const CConfigNeedingRestart& other) { m_Apple2Type = other.m_Apple2Type; + m_CpuType = other.m_CpuType; memcpy(m_Slot, other.m_Slot, sizeof(m_Slot)); m_bEnhanceDisk = other.m_bEnhanceDisk; m_bEnableHDD = other.m_bEnableHDD; @@ -34,6 +37,7 @@ public: bool operator== (const CConfigNeedingRestart& other) const { return m_Apple2Type == other.m_Apple2Type && + m_CpuType == other.m_CpuType && memcmp(m_Slot, other.m_Slot, sizeof(m_Slot)) == 0 && m_bEnhanceDisk == other.m_bEnhanceDisk && m_bEnableHDD == other.m_bEnableHDD && @@ -47,6 +51,7 @@ public: } eApple2Type m_Apple2Type; + eCpuType m_CpuType; SS_CARDTYPE m_Slot[NUM_SLOTS]; // 0..7 SS_CARDTYPE m_SlotAux; BOOL m_bEnhanceDisk; diff --git a/source/Configuration/PageConfig.cpp b/source/Configuration/PageConfig.cpp index 78ba4116..944420d6 100644 --- a/source/Configuration/PageConfig.cpp +++ b/source/Configuration/PageConfig.cpp @@ -129,6 +129,7 @@ BOOL CPageConfig::DlgProcInternal(HWND hWnd, UINT message, WPARAM wparam, LPARAM const DWORD NewComputerMenuItem = (DWORD) SendDlgItemMessage(hWnd, IDC_COMPUTER, CB_GETCURSEL, 0, 0); const eApple2Type NewApple2Type = GetApple2Type(NewComputerMenuItem); m_PropertySheetHelper.GetConfigNew().m_Apple2Type = NewApple2Type; + m_PropertySheetHelper.GetConfigNew().m_CpuType = ProbeMainCpuDefault(NewApple2Type); } break; diff --git a/source/Configuration/PropertySheetHelper.cpp b/source/Configuration/PropertySheetHelper.cpp index 5f684fc0..a6ec332a 100644 --- a/source/Configuration/PropertySheetHelper.cpp +++ b/source/Configuration/PropertySheetHelper.cpp @@ -102,6 +102,11 @@ void CPropertySheetHelper::SaveComputerType(eApple2Type NewApple2Type) REGSAVE(TEXT(REGVALUE_APPLE2_TYPE), NewApple2Type); } +void CPropertySheetHelper::SaveCpuType(eCpuType NewCpuType) +{ + REGSAVE(TEXT(REGVALUE_CPU_TYPE), NewCpuType); +} + void CPropertySheetHelper::SetSlot4(SS_CARDTYPE NewCardType) { g_Slot4 = NewCardType; @@ -252,17 +257,34 @@ int CPropertySheetHelper::SaveStateSelectImage(HWND hWindow, TCHAR* pszTitle, bo { if (bSave) // Only for saving (allow loading of any file for backwards compatibility) { - // Append .aws if it's not there + // Append .aws.yaml if it's not there const char szAWS_EXT1[] = ".aws"; - const char szAWS_EXT2[] = ".aws.yaml"; - const char szAWS_EXT3[] = ".yaml"; - const UINT uStrLenFile = strlen(&szFilename[ofn.nFileOffset]); + const char szAWS_EXT2[] = ".yaml"; + const char szAWS_EXT3[] = ".aws.yaml"; + const UINT uStrLenFile = strlen(&szFilename[ofn.nFileOffset]); const UINT uStrLenExt1 = strlen(szAWS_EXT1); const UINT uStrLenExt2 = strlen(szAWS_EXT2); - if ((uStrLenFile <= uStrLenExt1) || (strcmp(&szFilename[ofn.nFileOffset+uStrLenFile-uStrLenExt1], szAWS_EXT1) == 0)) - strcpy(&szFilename[ofn.nFileOffset+uStrLenFile], szAWS_EXT3); // "file.aws" += ".yaml" - else if ((uStrLenFile <= uStrLenExt2) || (strcmp(&szFilename[ofn.nFileOffset+uStrLenFile-uStrLenExt2], szAWS_EXT2) != 0)) - strcpy(&szFilename[ofn.nFileOffset+uStrLenFile], szAWS_EXT2); // "file" += "aws.yaml" + const UINT uStrLenExt3 = strlen(szAWS_EXT3); + if (uStrLenFile <= uStrLenExt1) + { + strcpy(&szFilename[ofn.nFileOffset+uStrLenFile], szAWS_EXT3); // "file" += ".aws.yaml" + } + else if (uStrLenFile <= uStrLenExt2) + { + if (strcmp(&szFilename[ofn.nFileOffset+uStrLenFile-uStrLenExt1], szAWS_EXT1) == 0) + strcpy(&szFilename[ofn.nFileOffset+uStrLenFile-uStrLenExt1], szAWS_EXT3); // "file.aws" -> "file" + ".aws.yaml" + else + strcpy(&szFilename[ofn.nFileOffset+uStrLenFile], szAWS_EXT3); // "file" += ".aws.yaml" + } + else if ((uStrLenFile <= uStrLenExt3) || (strcmp(&szFilename[ofn.nFileOffset+uStrLenFile-uStrLenExt3], szAWS_EXT3) != 0)) + { + if (strcmp(&szFilename[ofn.nFileOffset+uStrLenFile-uStrLenExt1], szAWS_EXT1) == 0) + strcpy(&szFilename[ofn.nFileOffset+uStrLenFile-uStrLenExt1], szAWS_EXT3); // "file.aws" -> "file" + ".aws.yaml" + else if (strcmp(&szFilename[ofn.nFileOffset+uStrLenFile-uStrLenExt2], szAWS_EXT2) == 0) + strcpy(&szFilename[ofn.nFileOffset+uStrLenFile-uStrLenExt2], szAWS_EXT3); // "file.yaml" -> "file" + ".aws.yaml" + else + strcpy(&szFilename[ofn.nFileOffset+uStrLenFile], szAWS_EXT3); // "file" += ".aws.yaml" + } } strcpy(m_szSSNewFilename, &szFilename[ofn.nFileOffset]); @@ -342,6 +364,11 @@ void CPropertySheetHelper::ApplyNewConfig(const CConfigNeedingRestart& ConfigNew SaveComputerType(ConfigNew.m_Apple2Type); } + if (CONFIG_CHANGED_LOCAL(m_CpuType)) + { + SaveCpuType(ConfigNew.m_CpuType); + } + if (CONFIG_CHANGED_LOCAL(m_Slot[4])) SetSlot4(ConfigNew.m_Slot[4]); @@ -370,7 +397,8 @@ void CPropertySheetHelper::ApplyNewConfig(void) void CPropertySheetHelper::SaveCurrentConfig(void) { // NB. clone-type is encoded in g_Apple2Type - m_ConfigOld.m_Apple2Type = g_Apple2Type; + m_ConfigOld.m_Apple2Type = GetApple2Type(); + m_ConfigOld.m_CpuType = GetMainCpu(); m_ConfigOld.m_Slot[4] = g_Slot4; m_ConfigOld.m_Slot[5] = g_Slot5; m_ConfigOld.m_bEnhanceDisk = enhancedisk; @@ -388,7 +416,8 @@ void CPropertySheetHelper::SaveCurrentConfig(void) void CPropertySheetHelper::RestoreCurrentConfig(void) { // NB. clone-type is encoded in g_Apple2Type - g_Apple2Type = m_ConfigOld.m_Apple2Type; + SetApple2Type(m_ConfigOld.m_Apple2Type); + SetMainCpu(m_ConfigOld.m_CpuType); g_Slot4 = m_ConfigOld.m_Slot[4]; g_Slot5 = m_ConfigOld.m_Slot[5]; enhancedisk = m_ConfigOld.m_bEnhanceDisk; @@ -441,6 +470,9 @@ bool CPropertySheetHelper::HardwareConfigChanged(HWND hWnd) if (CONFIG_CHANGED(m_Apple2Type)) strMsgMain += ". Emulated computer has changed\n"; + if (CONFIG_CHANGED(m_CpuType)) + strMsgMain += ". Emulated main CPU has changed\n"; + if (CONFIG_CHANGED(m_Slot[4])) strMsgMain += GetSlot(4); diff --git a/source/Configuration/PropertySheetHelper.h b/source/Configuration/PropertySheetHelper.h index 52d08420..5fd83fd4 100644 --- a/source/Configuration/PropertySheetHelper.h +++ b/source/Configuration/PropertySheetHelper.h @@ -42,6 +42,7 @@ private: bool IsOkToSaveLoadState(HWND hWnd, const bool bConfigChanged); bool IsOkToRestart(HWND hWnd); void SaveComputerType(eApple2Type NewApple2Type); + void SaveCpuType(eCpuType NewCpuType); bool HardwareConfigChanged(HWND hWnd); bool CheckChangesForRestart(HWND hWnd); void ApplyNewConfig(void); diff --git a/source/Disk.cpp b/source/Disk.cpp index a6070338..5ec21ba4 100644 --- a/source/Disk.cpp +++ b/source/Disk.cpp @@ -1213,14 +1213,10 @@ static void DiskSaveSnapshotDisk2Unit(YamlSaveHelper& yamlSaveHelper, UINT unit) yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_TRACK_IMAGE_DATA, g_aFloppyDisk[unit].trackimagedata); yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_TRACK_IMAGE_DIRTY, g_aFloppyDisk[unit].trackimagedirty); - // New label + if (g_aFloppyDisk[unit].trackimage) { YamlSaveHelper::Label image(yamlSaveHelper, "%s:\n", SS_YAML_KEY_TRACK_IMAGE); - - std::auto_ptr pNullTrack( new BYTE [NIBBLES_PER_TRACK] ); - memset(pNullTrack.get(), 0, NIBBLES_PER_TRACK); - LPBYTE pTrack = g_aFloppyDisk[unit].trackimage ? g_aFloppyDisk[unit].trackimage : pNullTrack.get(); - yamlSaveHelper.SaveMapValueMemory(pTrack, NIBBLES_PER_TRACK); + yamlSaveHelper.SaveMapValueMemory(g_aFloppyDisk[unit].trackimage, NIBBLES_PER_TRACK); } } @@ -1284,12 +1280,14 @@ static void DiskLoadSnapshotDriveUnit(YamlLoadHelper& yamlLoadHelper, UINT unit) g_aFloppyDisk[unit].trackimagedata = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_TRACK_IMAGE_DATA); g_aFloppyDisk[unit].trackimagedirty = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_TRACK_IMAGE_DIRTY); - if (!yamlLoadHelper.GetSubMap(SS_YAML_KEY_TRACK_IMAGE)) - throw disk2UnitName + std::string(": Missing: ") + std::string(SS_YAML_KEY_TRACK_IMAGE); std::auto_ptr pTrack( new BYTE [NIBBLES_PER_TRACK] ); - yamlLoadHelper.GetMapValueMemory(pTrack.get(), NIBBLES_PER_TRACK); + memset(pTrack.get(), 0, NIBBLES_PER_TRACK); + if (yamlLoadHelper.GetSubMap(SS_YAML_KEY_TRACK_IMAGE)) + { + yamlLoadHelper.GetMapValueMemory(pTrack.get(), NIBBLES_PER_TRACK); + yamlLoadHelper.PopMap(); + } - yamlLoadHelper.PopMap(); yamlLoadHelper.PopMap(); // @@ -1343,194 +1341,3 @@ bool DiskLoadSnapshot(class YamlLoadHelper& yamlLoadHelper, UINT slot, UINT vers return true; } - -//--- - -struct DISK2_Unit_v2 -{ - char szFileName[MAX_PATH]; - UINT Track; - UINT Phase; - UINT Byte; - BOOL WriteProtected; - BOOL TrackImageData; - BOOL TrackImageDirty; - DWORD Spinning; - DWORD WriteLight; - UINT Nibbles; - BYTE TrackImage[NIBBLES_PER_TRACK]; -}; - -struct SS_CARD_DISK2_v2 -{ - SS_CARD_HDR Hdr; - DISK2_Unit_v2 Unit[2]; - WORD Phases; - WORD CurrDrive; - BOOL DiskAccessed; - BOOL EnhanceDisk; - BYTE FloppyLatch; - BOOL FloppyMotorOn; - BOOL FloppyWriteMode; -}; - -void DiskGetSnapshot(const HANDLE hFile) -{ - SS_CARD_DISK2_v2 CardDisk2; - - SS_CARD_DISK2_v2* const pSS = &CardDisk2; - - pSS->Hdr.UnitHdr.hdr.v2.Length = sizeof(SS_CARD_DISK2); - pSS->Hdr.UnitHdr.hdr.v2.Type = UT_Card; - pSS->Hdr.UnitHdr.hdr.v2.Version = 1; - - pSS->Hdr.Slot = g_uSlot; - pSS->Hdr.Type = CT_Disk2; - - pSS->Phases = phases; - pSS->CurrDrive = currdrive; - pSS->DiskAccessed = diskaccessed; - pSS->EnhanceDisk = enhancedisk; - pSS->FloppyLatch = floppylatch; - pSS->FloppyMotorOn = floppymotoron; - pSS->FloppyWriteMode = floppywritemode; - - for(UINT i=0; iUnit[i].szFileName, g_aFloppyDisk[i].fullname); - pSS->Unit[i].Track = g_aFloppyDisk[i].track; - pSS->Unit[i].Phase = g_aFloppyDisk[i].phase; - pSS->Unit[i].Byte = g_aFloppyDisk[i].byte; - pSS->Unit[i].WriteProtected = g_aFloppyDisk[i].bWriteProtected ? TRUE : FALSE; - pSS->Unit[i].TrackImageData = g_aFloppyDisk[i].trackimagedata; - pSS->Unit[i].TrackImageDirty = g_aFloppyDisk[i].trackimagedirty; - pSS->Unit[i].Spinning = g_aFloppyDisk[i].spinning; - pSS->Unit[i].WriteLight = g_aFloppyDisk[i].writelight; - pSS->Unit[i].Nibbles = g_aFloppyDisk[i].nibbles; - - if(g_aFloppyDisk[i].trackimage) - memcpy(pSS->Unit[i].TrackImage, g_aFloppyDisk[i].trackimage, NIBBLES_PER_TRACK); - else - memset(pSS->Unit[i].TrackImage, 0, NIBBLES_PER_TRACK); - } - - // - - DWORD dwBytesWritten; - BOOL bRes = WriteFile( hFile, - &CardDisk2, - CardDisk2.Hdr.UnitHdr.hdr.v2.Length, - &dwBytesWritten, - NULL); - - if(!bRes || (dwBytesWritten != CardDisk2.Hdr.UnitHdr.hdr.v2.Length)) - { - //dwError = GetLastError(); - throw std::string("Save error: Disk]["); - } -} - -void DiskSetSnapshot(const HANDLE hFile) -{ - SS_CARD_DISK2_v2 CardDisk2; - - DWORD dwBytesRead; - BOOL bRes = ReadFile( hFile, - &CardDisk2, - sizeof(CardDisk2), - &dwBytesRead, - NULL); - - if (dwBytesRead != sizeof(CardDisk2)) - throw std::string("Card: file corrupt"); - - if (CardDisk2.Hdr.Slot != 6) // fixme - throw std::string("Card: wrong slot"); - - if (CardDisk2.Hdr.UnitHdr.hdr.v2.Version > 1) - throw std::string("Card: wrong version"); - - if (CardDisk2.Hdr.UnitHdr.hdr.v2.Length != sizeof(SS_CARD_DISK2_v2)) - throw std::string("Card: unit size mismatch"); - - const SS_CARD_DISK2_v2* const pSS = &CardDisk2; - - phases = pSS->Phases; - currdrive = pSS->CurrDrive; - diskaccessed = pSS->DiskAccessed; - enhancedisk = pSS->EnhanceDisk; - floppylatch = pSS->FloppyLatch; - floppymotoron = pSS->FloppyMotorOn; - floppywritemode = pSS->FloppyWriteMode; - - // Eject all disks first in case Drive-2 contains disk to be inserted into Drive-1 - for(UINT i=0; iUnit[i].szFileName[0] == 0x00) - continue; - - DWORD dwAttributes = GetFileAttributes(pSS->Unit[i].szFileName); - if(dwAttributes == INVALID_FILE_ATTRIBUTES) - { - // Get user to browse for file - bResSelectImage = DiskSelectImage(i, pSS->Unit[i].szFileName); - - dwAttributes = GetFileAttributes(pSS->Unit[i].szFileName); - } - - bool bImageError = (dwAttributes == INVALID_FILE_ATTRIBUTES); - if (!bImageError) - { - if(DiskInsert(i, pSS->Unit[i].szFileName, dwAttributes & FILE_ATTRIBUTE_READONLY, IMAGE_DONT_CREATE) != eIMAGE_ERROR_NONE) - bImageError = true; - - // DiskInsert() sets up: - // . imagename - // . fullname - // . writeprotected - } - - // - -// strcpy(g_aFloppyDisk[i].fullname, pSS->Unit[i].szFileName); - g_aFloppyDisk[i].track = pSS->Unit[i].Track; - g_aFloppyDisk[i].phase = pSS->Unit[i].Phase; - g_aFloppyDisk[i].byte = pSS->Unit[i].Byte; -// g_aFloppyDisk[i].writeprotected = pSS->Unit[i].WriteProtected; - g_aFloppyDisk[i].trackimagedata = pSS->Unit[i].TrackImageData; - g_aFloppyDisk[i].trackimagedirty = pSS->Unit[i].TrackImageDirty; - g_aFloppyDisk[i].spinning = pSS->Unit[i].Spinning; - g_aFloppyDisk[i].writelight = pSS->Unit[i].WriteLight; - g_aFloppyDisk[i].nibbles = pSS->Unit[i].Nibbles; - - // - - if(!bImageError) - { - if((g_aFloppyDisk[i].trackimage == NULL) && g_aFloppyDisk[i].nibbles) - AllocTrack(i); - - if(g_aFloppyDisk[i].trackimage == NULL) - bImageError = true; - else - memcpy(g_aFloppyDisk[i].trackimage, pSS->Unit[i].TrackImage, NIBBLES_PER_TRACK); - } - - if(bImageError) - { - g_aFloppyDisk[i].trackimagedata = 0; - g_aFloppyDisk[i].trackimagedirty = 0; - g_aFloppyDisk[i].nibbles = 0; - } - } - - FrameRefreshStatus(DRAW_LEDS | DRAW_BUTTON_DRIVES); -} diff --git a/source/Disk.h b/source/Disk.h index 1bcbd786..f759bf2f 100644 --- a/source/Disk.h +++ b/source/Disk.h @@ -75,8 +75,6 @@ int DiskSetSnapshot_v1(const struct SS_CARD_DISK2* const pSS); std::string DiskGetSnapshotCardName(void); void DiskSaveSnapshot(class YamlSaveHelper& yamlSaveHelper); bool DiskLoadSnapshot(class YamlLoadHelper& yamlLoadHelper, UINT slot, UINT version); -void DiskGetSnapshot(const HANDLE hFile); -void DiskSetSnapshot(const HANDLE hFile); void Disk_LoadLastDiskImage(const int iDrive); void Disk_SaveLastDiskImage(const int iDrive); diff --git a/source/Frame.cpp b/source/Frame.cpp index 2089d264..d4d9a49d 100644 --- a/source/Frame.cpp +++ b/source/Frame.cpp @@ -178,7 +178,7 @@ static bool g_bFullScreen32Bit = true; // Updates g_pAppTitle // ==================================================================== -void GetAppleWindowTitle() +static void GetAppleWindowTitle() { g_pAppTitle = g_pAppleWindowTitle; @@ -764,6 +764,14 @@ void FrameDrawDiskStatus( HDC passdc ) //=========================================================================== static void DrawStatusArea (HDC passdc, int drawflags) { + if (g_hFrameWindow == NULL) + { + // TC: Fix drawing of drive buttons before frame created: + // . Main init loop: LoadConfiguration() called before FrameCreateWindow(), eg: + // LoadConfiguration() -> Disk_LoadLastDiskImage() -> DiskInsert() -> FrameRefreshStatus() + return; + } + FrameReleaseDC(); HDC dc = (passdc ? passdc : GetDC(g_hFrameWindow)); int x = buttonx; @@ -2010,7 +2018,7 @@ void ResetMachineState () MB_Reset(); SpkrReset(); sg_Mouse.Reset(); - g_ActiveCPU = CPU_6502; + SetActiveCpu( GetMainCpu() ); #ifdef USE_SPEECH_API g_Speech.Reset(); #endif @@ -2634,3 +2642,17 @@ void GetViewportCXCY(int& nViewportCX, int& nViewportCY) nViewportCX = g_nViewportCX; nViewportCY = g_nViewportCY; } + +// Call all funcs with dependency on g_Apple2Type +void FrameUpdateApple2Type(void) +{ + DeleteGdiObjects(); + CreateGdiObjects(); + + // DRAW_TITLE : calls GetAppleWindowTitle() + // DRAW_LEDS : update LEDs (eg. CapsLock varies on Apple2 type) + DrawStatusArea( (HDC)0, DRAW_TITLE|DRAW_LEDS ); + + // Draw buttons & call DrawStatusArea(DRAW_BACKGROUND | DRAW_LEDS | DRAW_DISK_STATUS) + DrawFrameWindow(); +} diff --git a/source/Frame.h b/source/Frame.h index 322820b7..e9149f78 100644 --- a/source/Frame.h +++ b/source/Frame.h @@ -48,6 +48,7 @@ void GetViewportCXCY(int& nViewportCX, int& nViewportCY); bool GetFullScreen32Bit(void); void SetFullScreen32Bit(bool b32Bit); + void FrameUpdateApple2Type(void); void FrameDrawDiskLEDS( HDC hdc ); void FrameDrawDiskStatus( HDC hdc ); diff --git a/source/Harddisk.cpp b/source/Harddisk.cpp index 7c69f96e..a4c70f2a 100644 --- a/source/Harddisk.cpp +++ b/source/Harddisk.cpp @@ -804,159 +804,3 @@ bool HD_LoadSnapshot(YamlLoadHelper& yamlLoadHelper, UINT slot, UINT version, co return true; } - -//--- - -struct HDD_Unit -{ - char szFilename[MAX_PATH]; - BYTE error; - WORD memblock; - UINT diskblock; - WORD buf_ptr; - BOOL imageloaded; - BYTE buf[HD_BLOCK_SIZE]; - UINT status_next; - UINT status_prev; -}; - -struct SS_CARD_HDD -{ - SS_CARD_HDR Hdr; - HDD_Unit Unit[NUM_HARDDISKS]; - BYTE CurrUnit; - BYTE Command; -}; - -void HD_GetSnapshot(const HANDLE hFile) -{ - if (!HD_CardIsEnabled()) - return; - - SS_CARD_HDD CardHDD; - - CardHDD.Hdr.UnitHdr.hdr.v2.Length = sizeof(SS_CARD_HDD); - CardHDD.Hdr.UnitHdr.hdr.v2.Type = UT_Card; - CardHDD.Hdr.UnitHdr.hdr.v2.Version = 1; - - CardHDD.Hdr.Slot = g_uSlot; - CardHDD.Hdr.Type = CT_GenericHDD; - - CardHDD.CurrUnit = g_nHD_UnitNum; - CardHDD.Command = g_nHD_Command; - - for (UINT i=0; i 1) - throw std::string("Card: wrong version"); - - if (CardHDD.Hdr.UnitHdr.hdr.v2.Length != sizeof(SS_CARD_HDD)) - throw std::string("Card: unit size mismatch"); - - g_nHD_UnitNum = CardHDD.CurrUnit; - g_nHD_Command = CardHDD.Command; - - // Unplug all HDDs first in case HDD-2 is to be plugged in as HDD-1 - for (UINT i=0; iHdr.UnitHdr.hdr.v2.Length = uSize; - pSS->Hdr.UnitHdr.hdr.v2.Type = UT_Card; - pSS->Hdr.UnitHdr.hdr.v2.Version = 1; - - pSS->Hdr.Slot = kSLOT_AUX; - pSS->Hdr.Type = g_uMaxExPages == 0 ? CT_80Col : - g_uMaxExPages == 1 ? CT_Extended80Col : - CT_RamWorksIII; - - pSS->ActiveAuxBank = g_uActiveBank; - pSS->NumAuxBanks = g_uMaxExPages; - - for(UINT uBank = 1; uBank <= g_uMaxExPages; uBank++) - { - memcpy(pSS->MemAux+(uBank-1)*(_6502_MEM_END+1), MemGetBankPtr(uBank), _6502_MEM_END+1); - } - - // - - DWORD dwBytesWritten; - BOOL bRes = WriteFile( hFile, - pSS, - pSS->Hdr.UnitHdr.hdr.v2.Length, - &dwBytesWritten, - NULL); - - delete [] pSS; - - if(!bRes || (dwBytesWritten != uSize)) - { - //dwError = GetLastError(); - throw std::string("Save error: 80COL_AUX_MEMORY card"); - } - -} - -void MemSetSnapshotAux(const HANDLE hFile) -{ - SS_CARD_80COL_AUX_MEMORY Card; - - DWORD dwBytesRead; - BOOL bRes = ReadFile( hFile, - &Card, - sizeof(Card), - &dwBytesRead, - NULL); - - if (dwBytesRead != sizeof(Card)) - throw std::string("Card: file corrupt"); - - if (Card.Hdr.Slot != kSLOT_AUX) - throw std::string("Card: wrong slot"); - - if (Card.Hdr.UnitHdr.hdr.v2.Version > 1) - throw std::string("Card: wrong version"); - - if (Card.Hdr.UnitHdr.hdr.v2.Length < sizeof(SS_CARD_80COL_AUX_MEMORY)) - throw std::string("Card: unit size mismatch"); - - if (Card.NumAuxBanks > kMaxExMemoryBanks) - throw std::string("Card: file corrupt"); - - if (Card.ActiveAuxBank >= Card.NumAuxBanks) - throw std::string("Card: file corrupt"); - - g_uActiveBank = Card.ActiveAuxBank; - g_uMaxExPages = Card.NumAuxBanks; - - for(UINT uBank = 1; uBank <= g_uMaxExPages; uBank++) - { - LPBYTE pBank = MemGetBankPtr(uBank); - if (!pBank) - { - pBank = RWpages[uBank-1] = (LPBYTE) VirtualAlloc(NULL,_6502_MEM_END+1,MEM_COMMIT,PAGE_READWRITE); - if (!pBank) - throw std::string("Card: mem alloc failed"); - } - - bRes = ReadFile( hFile, - pBank, - _6502_MEM_END+1, - &dwBytesRead, - NULL); - - if (dwBytesRead != _6502_MEM_END+1) - throw std::string("Card: file corrupt"); - } - - memaux = RWpages[g_uActiveBank]; - // NB. MemUpdatePaging(TRUE) called at end of Snapshot_LoadState_v2() -} diff --git a/source/Memory.h b/source/Memory.h index 8e5ca745..3a104755 100644 --- a/source/Memory.h +++ b/source/Memory.h @@ -60,10 +60,6 @@ void MemSaveSnapshot(class YamlSaveHelper& yamlSaveHelper); bool MemLoadSnapshot(class YamlLoadHelper& yamlLoadHelper); void MemSaveSnapshotAux(class YamlSaveHelper& yamlSaveHelper); bool MemLoadSnapshotAux(class YamlLoadHelper& yamlLoadHelper, UINT version); -void MemGetSnapshot(struct SS_BaseMemory_v2& Memory); -void MemSetSnapshot(const struct SS_BaseMemory_v2& Memory); -void MemGetSnapshotAux(const HANDLE hFile); -void MemSetSnapshotAux(const HANDLE hFile); BYTE __stdcall IO_Null(WORD programcounter, WORD address, BYTE write, BYTE value, ULONG nCycles); diff --git a/source/Mockingboard.cpp b/source/Mockingboard.cpp index 1f79bf35..c52d69b9 100644 --- a/source/Mockingboard.cpp +++ b/source/Mockingboard.cpp @@ -2206,276 +2206,3 @@ bool Phasor_LoadSnapshot(YamlLoadHelper& yamlLoadHelper, UINT slot, UINT version return true; } - -//=========================================================================== - -struct Mockingboard_Unit -{ - SY6522 RegsSY6522; - SSI263A RegsSSI263; - BYTE AYCurrentRegister; - bool bTimer1IrqPending; - bool bTimer2IrqPending; - bool bSpeechIrqPending; -// SS_AY8910 AY8910; // Internal state of AY8910 -}; - -struct SS_CARD_MOCKINGBOARD -{ - SS_CARD_HDR Hdr; - Mockingboard_Unit Unit[NUM_MB_UNITS]; -}; - -void MB_GetSnapshot(const HANDLE hFile, const UINT uSlot) -{ - SS_CARD_MOCKINGBOARD Card; - - Card.Hdr.UnitHdr.hdr.v2.Length = sizeof(SS_CARD_MOCKINGBOARD); - Card.Hdr.UnitHdr.hdr.v2.Type = UT_Card; - Card.Hdr.UnitHdr.hdr.v2.Version = 1; - - Card.Hdr.Slot = uSlot; // fixme: object should be just 1 Mockingboard card & it will know its slot - Card.Hdr.Type = CT_MockingboardC; - - const UINT nMbCardNum = uSlot - SLOT4; - Card.Hdr.UnitHdr.hdr.v2.Length += AY8910_GetSnapshot(NULL, nMbCardNum*2+0); - Card.Hdr.UnitHdr.hdr.v2.Length += AY8910_GetSnapshot(NULL, nMbCardNum*2+1); - - UINT uTotalWriteSize = DoWriteFile(hFile, &Card, (UINT)&Card.Unit-(UINT)&Card); - - // - - UINT nDeviceNum = nMbCardNum*2; - SY6522_AY8910* pMB = &g_MB[nDeviceNum]; - - for(UINT i=0; isy6522, sizeof(SY6522)); - memcpy(&Card.Unit[i].RegsSSI263, &pMB->SpeechChip, sizeof(SSI263A)); - Card.Unit[i].AYCurrentRegister = pMB->nAYCurrentRegister; - Card.Unit[i].bTimer1IrqPending = false; - Card.Unit[i].bTimer2IrqPending = false; - Card.Unit[i].bSpeechIrqPending = false; - uTotalWriteSize += DoWriteFile(hFile, &Card.Unit[i], sizeof(Card.Unit[0])); - - uTotalWriteSize += AY8910_GetSnapshot(hFile, nDeviceNum); - - nDeviceNum++; - pMB++; - } - - _ASSERT(uTotalWriteSize == Card.Hdr.UnitHdr.hdr.v2.Length); - if (uTotalWriteSize != Card.Hdr.UnitHdr.hdr.v2.Length) - throw std::string("Card: unit size mismatch"); -} - -void MB_SetSnapshot(const HANDLE hFile) -{ - SS_CARD_MOCKINGBOARD Card; - - UINT uTotalReadSize = DoReadFile(hFile, &Card, (UINT)&Card.Unit-(UINT)&Card); - - if (Card.Hdr.Slot != 4 && Card.Hdr.Slot != 5) // fixme - throw std::string("Card: wrong slot"); - - if (Card.Hdr.UnitHdr.hdr.v2.Version > 1) - throw std::string("Card: wrong version"); - - if (Card.Hdr.UnitHdr.hdr.v2.Length <= sizeof(SS_CARD_MOCKINGBOARD)) - throw std::string("Card: unit size mismatch"); - - AY8910UpdateSetCycles(); - - const UINT nMbCardNum = Card.Hdr.Slot - SLOT4; - UINT nDeviceNum = nMbCardNum*2; - SY6522_AY8910* pMB = &g_MB[nDeviceNum]; - - g_nSSI263Device = 0; - g_nCurrentActivePhoneme = -1; - - for(UINT i=0; isy6522, &Card.Unit[i].RegsSY6522, sizeof(SY6522)); - memcpy(&pMB->SpeechChip, &Card.Unit[i].RegsSSI263, sizeof(SSI263A)); - pMB->nAYCurrentRegister = Card.Unit[i].AYCurrentRegister; - - StartTimer(pMB); // Attempt to start timer - - // - - // Crude - currently only support a single speech chip - // FIX THIS: - // . Speech chip could be Votrax instead - // . Is this IRQ compatible with Phasor? - if(pMB->SpeechChip.DurationPhoneme) - { - g_nSSI263Device = nDeviceNum; - - if((pMB->SpeechChip.CurrentMode != MODE_IRQ_DISABLED) && (pMB->sy6522.PCR == 0x0C) && (pMB->sy6522.IER & IxR_PERIPHERAL)) - { - pMB->sy6522.IFR |= IxR_PERIPHERAL; - UpdateIFR(pMB); - pMB->SpeechChip.CurrentMode |= 1; // Set SSI263's D7 pin - } - } - - uTotalReadSize += AY8910_SetSnapshot(hFile, nDeviceNum); - - nDeviceNum++; - pMB++; - } - - _ASSERT(uTotalReadSize == Card.Hdr.UnitHdr.hdr.v2.Length); - if (uTotalReadSize != Card.Hdr.UnitHdr.hdr.v2.Length) - throw std::string("Card: unit size mismatch"); - - AY8910_InitClock((int)CLK_6502); - - // Setup in MB_InitializeIO() -> MB_SetSoundcardType() - g_SoundcardType = CT_Empty; - g_bPhasorEnable = false; -} - -//=========================================================================== - -struct Phasor_Unit -{ - SY6522 RegsSY6522; - SSI263A RegsSSI263; - BYTE AYCurrentRegister; - bool bTimer1IrqPending; - bool bTimer2IrqPending; - bool bSpeechIrqPending; -// SS_AY8910 AY8910[2]; // Internal state of AY8910 -}; - -struct SS_CARD_PHASOR -{ - SS_CARD_HDR Hdr; - UINT ClockScaleFactor; - UINT Mode; - Phasor_Unit Unit[NUM_PHASOR_UNITS]; -}; - -void Phasor_GetSnapshot(const HANDLE hFile) -{ - SS_CARD_PHASOR Card; - - Card.Hdr.UnitHdr.hdr.v2.Length = sizeof(SS_CARD_PHASOR); - Card.Hdr.UnitHdr.hdr.v2.Type = UT_Card; - Card.Hdr.UnitHdr.hdr.v2.Version = 1; - - const UINT uSlot = 4; // fixme - Card.Hdr.Slot = uSlot; // fixme: object should just be Phasor card & it will know its slot - Card.Hdr.Type = CT_Phasor; - - Card.ClockScaleFactor = g_PhasorClockScaleFactor; - Card.Mode = g_nPhasorMode; - - for (UINT i=0; i<4; i++) - Card.Hdr.UnitHdr.hdr.v2.Length += AY8910_GetSnapshot(NULL, i); - - UINT uTotalWriteSize = DoWriteFile(hFile, &Card, (UINT)&Card.Unit-(UINT)&Card); - - // - - UINT nDeviceNum = 0; - SY6522_AY8910* pMB = &g_MB[0]; // fixme: Phasor uses MB's slot4(2x6522), slot4(2xSSI263), but slot4+5(4xAY8910) - - for(UINT i=0; isy6522, sizeof(SY6522)); - memcpy(&Card.Unit[i].RegsSSI263, &pMB->SpeechChip, sizeof(SSI263A)); - Card.Unit[i].AYCurrentRegister = pMB->nAYCurrentRegister; - Card.Unit[i].bTimer1IrqPending = false; - Card.Unit[i].bTimer2IrqPending = false; - Card.Unit[i].bSpeechIrqPending = false; - uTotalWriteSize += DoWriteFile(hFile, &Card.Unit[i], sizeof(Card.Unit[0])); - - uTotalWriteSize += AY8910_GetSnapshot(hFile, nDeviceNum+0); - uTotalWriteSize += AY8910_GetSnapshot(hFile, nDeviceNum+1); - - nDeviceNum += 2; - pMB++; - } - - _ASSERT(uTotalWriteSize == Card.Hdr.UnitHdr.hdr.v2.Length); - if (uTotalWriteSize != Card.Hdr.UnitHdr.hdr.v2.Length) - throw std::string("Card: unit size mismatch"); -} - -void Phasor_SetSnapshot(const HANDLE hFile) -{ - SS_CARD_PHASOR Card; - - UINT uTotalReadSize = DoReadFile(hFile, &Card, (UINT)&Card.Unit-(UINT)&Card); - - if (Card.Hdr.Slot != 4) // fixme - throw std::string("Card: wrong slot"); - - if (Card.Hdr.UnitHdr.hdr.v2.Version > 1) - throw std::string("Card: wrong version"); - - if (Card.Hdr.UnitHdr.hdr.v2.Length <= sizeof(SS_CARD_PHASOR)) - throw std::string("Card: unit size mismatch"); - - g_PhasorClockScaleFactor = Card.ClockScaleFactor; - g_nPhasorMode = Card.Mode; - - AY8910UpdateSetCycles(); - - UINT nDeviceNum = 0; - SY6522_AY8910* pMB = &g_MB[0]; - - g_nSSI263Device = 0; - g_nCurrentActivePhoneme = -1; - - for(UINT i=0; isy6522, &Card.Unit[i].RegsSY6522, sizeof(SY6522)); - memcpy(&pMB->SpeechChip, &Card.Unit[i].RegsSSI263, sizeof(SSI263A)); - pMB->nAYCurrentRegister = Card.Unit[i].AYCurrentRegister; - - StartTimer(pMB); // Attempt to start timer - - // - - // Crude - currently only support a single speech chip - // FIX THIS: - // . Speech chip could be Votrax instead - // . Is this IRQ compatible with Phasor? - if(pMB->SpeechChip.DurationPhoneme) - { - g_nSSI263Device = nDeviceNum; - - if((pMB->SpeechChip.CurrentMode != MODE_IRQ_DISABLED) && (pMB->sy6522.PCR == 0x0C) && (pMB->sy6522.IER & IxR_PERIPHERAL)) - { - pMB->sy6522.IFR |= IxR_PERIPHERAL; - UpdateIFR(pMB); - pMB->SpeechChip.CurrentMode |= 1; // Set SSI263's D7 pin - } - } - - // - - uTotalReadSize += AY8910_SetSnapshot(hFile, nDeviceNum+0); - uTotalReadSize += AY8910_SetSnapshot(hFile, nDeviceNum+1); - - nDeviceNum += 2; - pMB++; - } - - _ASSERT(uTotalReadSize == Card.Hdr.UnitHdr.hdr.v2.Length); - if (uTotalReadSize != Card.Hdr.UnitHdr.hdr.v2.Length) - throw std::string("Card: unit size mismatch"); - - AY8910_InitClock((int)(CLK_6502 * g_PhasorClockScaleFactor)); - - // Setup in MB_InitializeIO() -> MB_SetSoundcardType() - g_SoundcardType = CT_Empty; - g_bPhasorEnable = false; -} diff --git a/source/Mockingboard.h b/source/Mockingboard.h index 487463c2..901a9e41 100644 --- a/source/Mockingboard.h +++ b/source/Mockingboard.h @@ -28,11 +28,7 @@ int MB_SetSnapshot_v1(const struct SS_CARD_MOCKINGBOARD_v1* const pSS, const std::string MB_GetSnapshotCardName(void); void MB_SaveSnapshot(class YamlSaveHelper& yamlSaveHelper, const UINT uSlot); bool MB_LoadSnapshot(class YamlLoadHelper& yamlLoadHelper, UINT slot, UINT version); -void MB_GetSnapshot(const HANDLE hFile, const UINT uSlot); -void MB_SetSnapshot(const HANDLE hFile); std::string Phasor_GetSnapshotCardName(void); void Phasor_SaveSnapshot(class YamlSaveHelper& yamlSaveHelper, const UINT uSlot); bool Phasor_LoadSnapshot(class YamlLoadHelper& yamlLoadHelper, UINT slot, UINT version); -void Phasor_GetSnapshot(const HANDLE hFile); -void Phasor_SetSnapshot(const HANDLE hFile); diff --git a/source/MouseInterface.cpp b/source/MouseInterface.cpp index 9a8f3921..d6bee8ed 100644 --- a/source/MouseInterface.cpp +++ b/source/MouseInterface.cpp @@ -760,166 +760,6 @@ bool CMouseInterface::LoadSnapshot(class YamlLoadHelper& yamlLoadHelper, UINT sl return true; } -struct MouseCard_Unit -{ - //6821 - mc6821_t mc6821; - BYTE byIA; - BYTE byIB; - - //MouseCard - int nDataLen; - BYTE byMode; - - BYTE by6821B; - BYTE by6821A; - BYTE byBuff[8]; - int nBuffPos; - - BYTE byState; - int nX; - int nY; - BOOL bBtn0; - BOOL bBtn1; - - bool bVBL; - - // - - int iX; - int iMinX; - int iMaxX; - int iY; - int iMinY; - int iMaxY; - - BOOL bButtons[2]; - - // - - bool bActive; // Mouse h/w is active within the Apple][ VM - bool bEnabled; // Windows' mouse events get passed to Apple]['s mouse h/w -}; - -struct SS_CARD_MOUSECARD -{ - SS_CARD_HDR Hdr; - MouseCard_Unit Unit; -}; - -// Post: -// 0 = No mouse card -// >0 = Mouse card saved OK from slot n -// -1 = File error -int CMouseInterface::GetSnapshot(const HANDLE hFile) -{ - if (!m_bActive) - return 0; - - SS_CARD_MOUSECARD CardMouseCard; - - CardMouseCard.Hdr.UnitHdr.hdr.v2.Length = sizeof(SS_CARD_MOUSECARD); - CardMouseCard.Hdr.UnitHdr.hdr.v2.Type = UT_Card; - CardMouseCard.Hdr.UnitHdr.hdr.v2.Version = 1; - - CardMouseCard.Hdr.Slot = m_uSlot; - CardMouseCard.Hdr.Type = CT_MouseInterface; - - MouseCard_Unit& Unit = CardMouseCard.Unit; - - m_6821.Get6821(Unit.mc6821, Unit.byIA, Unit.byIB); - - Unit.nDataLen = m_nDataLen; - Unit.byMode = m_byMode; - Unit.by6821B = m_by6821B; - Unit.by6821A = m_by6821A; - memcpy(Unit.byBuff, m_byBuff, sizeof(Unit.byBuff)); - Unit.nBuffPos = m_nBuffPos; - Unit.byState = m_byState; - Unit.nX = m_nX; - Unit.nY = m_nY; - Unit.bBtn0 = m_bBtn0; - Unit.bBtn1 = m_bBtn1; - Unit.bVBL = m_bVBL; - Unit.iX = m_iX; - Unit.iMinX = m_iMinX; - Unit.iMaxX = m_iMaxX; - Unit.iY = m_iY; - Unit.iMinY = m_iMinY; - Unit.iMaxY = m_iMaxY; - Unit.bButtons[0] = m_bButtons[0]; - Unit.bButtons[1] = m_bButtons[1]; - Unit.bActive = m_bActive; - Unit.bEnabled = m_bEnabled; - - // - - DWORD dwBytesWritten; - BOOL bRes = WriteFile( hFile, - &CardMouseCard, - CardMouseCard.Hdr.UnitHdr.hdr.v2.Length, - &dwBytesWritten, - NULL); - - if(!bRes || (dwBytesWritten != CardMouseCard.Hdr.UnitHdr.hdr.v2.Length)) - throw std::string("Save error: Mouse"); - - return m_uSlot; -} - -void CMouseInterface::SetSnapshot(const HANDLE hFile) -{ - SS_CARD_MOUSECARD CardMouseCard; - - DWORD dwBytesRead; - BOOL bRes = ReadFile( hFile, - &CardMouseCard, - sizeof(CardMouseCard), - &dwBytesRead, - NULL); - - if (dwBytesRead != sizeof(CardMouseCard)) - throw std::string("Card: file corrupt"); - - if (CardMouseCard.Hdr.Slot != 4) // fixme - throw std::string("Card: wrong slot"); - - if (CardMouseCard.Hdr.UnitHdr.hdr.v2.Version > 1) - throw std::string("Card: wrong version"); - - if (CardMouseCard.Hdr.UnitHdr.hdr.v2.Length != sizeof(SS_CARD_MOUSECARD)) - throw std::string("Card: unit size mismatch"); - - const MouseCard_Unit& Unit = CardMouseCard.Unit; - - m_6821.Set6821(Unit.mc6821, Unit.byIA, Unit.byIB); - - m_nDataLen = Unit.nDataLen; - m_byMode = Unit.byMode; - m_by6821B = Unit.by6821B; - m_by6821A = Unit.by6821A; - memcpy(m_byBuff, Unit.byBuff, sizeof(Unit.byBuff)); - m_nBuffPos = Unit.nBuffPos; - m_byState = Unit.byState; - m_nX = Unit.nX; - m_nY = Unit.nY; - m_bBtn0 = Unit.bBtn0; - m_bBtn1 = Unit.bBtn1; - m_bVBL = Unit.bVBL; - m_iX = Unit.iX; - m_iMinX = Unit.iMinX; - m_iMaxX = Unit.iMaxX; - m_iY = Unit.iY; - m_iMinY = Unit.iMinY; - m_iMaxY = Unit.iMaxY; - m_bButtons[0] = Unit.bButtons[0]; - m_bButtons[1] = Unit.bButtons[1]; - - m_bActive = Unit.bActive; - //m_bEnabled = Unit.bEnabled; - //m_uSlot = CardMouseCard.Hdr.Slot; -} - //============================================================================= // DirectInput interface //============================================================================= diff --git a/source/MouseInterface.h b/source/MouseInterface.h index 54570ede..edb62ca8 100644 --- a/source/MouseInterface.h +++ b/source/MouseInterface.h @@ -40,8 +40,6 @@ public: std::string GetSnapshotCardName(void); void SaveSnapshot(class YamlSaveHelper& yamlSaveHelper); bool LoadSnapshot(class YamlLoadHelper& yamlLoadHelper, UINT slot, UINT version); - int GetSnapshot(const HANDLE hFile); - void SetSnapshot(const HANDLE hFile); protected: void SetSlotRom(); diff --git a/source/ParallelPrinter.cpp b/source/ParallelPrinter.cpp index 85bbed2d..79df8242 100644 --- a/source/ParallelPrinter.cpp +++ b/source/ParallelPrinter.cpp @@ -322,106 +322,3 @@ bool Printer_LoadSnapshot(class YamlLoadHelper& yamlLoadHelper, UINT slot, UINT return true; } - -//--- - -struct PrinterCard_Unit -{ - DWORD Inactivity; - UINT PrinterIdleLimit; - char PrintFilename[MAX_PATH]; - BOOL IsFileOpen; - BOOL DumpToPrinter; - BOOL ConvertEncoding; - BOOL FilterUnprintable; - BOOL PrinterAppend; - BOOL EnableDumpToRealPrinter; -}; - -struct SS_CARD_PRINTER -{ - SS_CARD_HDR Hdr; - PrinterCard_Unit Unit; -}; - -void Printer_GetSnapshot(const HANDLE hFile) -{ - SS_CARD_PRINTER CardPrinter; - - SS_CARD_PRINTER* const pSS = &CardPrinter; - - pSS->Hdr.UnitHdr.hdr.v2.Length = sizeof(SS_CARD_PRINTER); - pSS->Hdr.UnitHdr.hdr.v2.Type = UT_Card; - pSS->Hdr.UnitHdr.hdr.v2.Version = 1; - - pSS->Hdr.Slot = g_uSlot; - pSS->Hdr.Type = CT_GenericPrinter; - - CardPrinter.Unit.Inactivity = inactivity; - CardPrinter.Unit.PrinterIdleLimit = g_iPrinterIdleLimit; - memcpy(CardPrinter.Unit.PrintFilename, g_szPrintFilename, sizeof(CardPrinter.Unit.PrintFilename)); - CardPrinter.Unit.IsFileOpen = (file != NULL); - CardPrinter.Unit.DumpToPrinter = g_bDumpToPrinter; - CardPrinter.Unit.ConvertEncoding = g_bConvertEncoding; - CardPrinter.Unit.FilterUnprintable = g_bFilterUnprintable; - CardPrinter.Unit.PrinterAppend = g_bPrinterAppend; - CardPrinter.Unit.EnableDumpToRealPrinter = g_bEnableDumpToRealPrinter; - - // - - DWORD dwBytesWritten; - BOOL bRes = WriteFile( hFile, - &CardPrinter, - CardPrinter.Hdr.UnitHdr.hdr.v2.Length, - &dwBytesWritten, - NULL); - - if(!bRes || (dwBytesWritten != CardPrinter.Hdr.UnitHdr.hdr.v2.Length)) - { - //dwError = GetLastError(); - throw std::string("Save error: Printer Card"); - } -} - -void Printer_SetSnapshot(const HANDLE hFile) -{ - SS_CARD_PRINTER CardPrinter; - - DWORD dwBytesRead; - BOOL bRes = ReadFile( hFile, - &CardPrinter, - sizeof(CardPrinter), - &dwBytesRead, - NULL); - - if (dwBytesRead != sizeof(CardPrinter)) - throw std::string("Card: file corrupt"); - - if (CardPrinter.Hdr.Slot != 1) // fixme - throw std::string("Card: wrong slot"); - - if (CardPrinter.Hdr.UnitHdr.hdr.v2.Version > 1) - throw std::string("Card: wrong version"); - - if (CardPrinter.Hdr.UnitHdr.hdr.v2.Length != sizeof(SS_CARD_PRINTER)) - throw std::string("Card: unit size mismatch"); - - ClosePrint(); // Close current print session (and close file handle) - - inactivity = CardPrinter.Unit.Inactivity; - g_iPrinterIdleLimit = CardPrinter.Unit.PrinterIdleLimit; - memcpy(g_szPrintFilename, CardPrinter.Unit.PrintFilename, sizeof(g_szPrintFilename)); - if (CardPrinter.Unit.IsFileOpen) - { - g_bPrinterAppend = true; // Re-open print-file in append mode - BOOL bRes = CheckPrint(); - if (!bRes) - throw std::string("Printer Card: Unable to resume printing to file"); - } - - g_bDumpToPrinter = CardPrinter.Unit.DumpToPrinter == TRUE; - g_bConvertEncoding = CardPrinter.Unit.ConvertEncoding == TRUE; - g_bFilterUnprintable = CardPrinter.Unit.FilterUnprintable == TRUE; - g_bPrinterAppend = CardPrinter.Unit.PrinterAppend == TRUE; - g_bEnableDumpToRealPrinter = CardPrinter.Unit.EnableDumpToRealPrinter == TRUE; -} diff --git a/source/ParallelPrinter.h b/source/ParallelPrinter.h index 87216bc0..d2b96bdb 100644 --- a/source/ParallelPrinter.h +++ b/source/ParallelPrinter.h @@ -12,8 +12,6 @@ unsigned int Printer_GetIdleLimit(); std::string Printer_GetSnapshotCardName(void); void Printer_SaveSnapshot(class YamlSaveHelper& yamlSaveHelper); bool Printer_LoadSnapshot(class YamlLoadHelper& yamlLoadHelper, UINT slot, UINT version); -void Printer_GetSnapshot(const HANDLE hFile); -void Printer_SetSnapshot(const HANDLE hFile); extern bool g_bDumpToPrinter; extern bool g_bConvertEncoding; diff --git a/source/SaveState.cpp b/source/SaveState.cpp index 2aab70f4..2dd77a3b 100644 --- a/source/SaveState.cpp +++ b/source/SaveState.cpp @@ -29,7 +29,6 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #include "StdAfx.h" #include "SaveState_Structs_v1.h" -#include "SaveState_Structs_v2.h" #include "YamlHelper.h" #include "AppleWin.h" @@ -63,6 +62,11 @@ static std::string g_strSaveStatePath; static YamlHelper yamlHelper; +#define SS_FILE_VER 2 + +#define UNIT_APPLE2_VER 1 +#define UNIT_SLOTS_VER 1 + //----------------------------------------------------------------------------- void Snapshot_SetFilename(std::string strPathname) @@ -225,276 +229,6 @@ static void Snapshot_LoadState_v1() // .aws v1.0.0.1, up to (and including) Appl static HANDLE m_hFile = INVALID_HANDLE_VALUE; static CConfigNeedingRestart m_ConfigNew; -static void Snapshot_LoadState_FileHdr(SS_FILE_HDR& Hdr) -{ - try - { - m_hFile = CreateFile( g_strSaveStatePathname.c_str(), - GENERIC_READ, - 0, - NULL, - OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL, - NULL); - - if(m_hFile == INVALID_HANDLE_VALUE) - throw std::string("File not found: ") + g_strSaveStatePathname; - - DWORD dwBytesRead; - BOOL bRes = ReadFile( m_hFile, - &Hdr, - sizeof(Hdr), - &dwBytesRead, - NULL); - - if(!bRes || (dwBytesRead != sizeof(Hdr))) - throw std::string("File size mismatch"); - - if(Hdr.dwTag != AW_SS_TAG) - throw std::string("File corrupt"); - } - catch(std::string szMessage) - { - MessageBox( g_hFrameWindow, - szMessage.c_str(), - TEXT("Load State"), - MB_ICONEXCLAMATION | MB_SETFOREGROUND); - - if(m_hFile == INVALID_HANDLE_VALUE) - { - CloseHandle(m_hFile); - m_hFile = INVALID_HANDLE_VALUE; - } - } -} - -static void LoadUnitApple2(DWORD Length, DWORD Version) -{ - if (Version != UNIT_APPLE2_VER) - throw std::string("Apple2: Version mismatch"); - - if (Length != sizeof(SS_APPLE2_Unit_v2)) - throw std::string("Apple2: Length mismatch"); - - if (SetFilePointer(m_hFile, -(LONG)sizeof(SS_UNIT_HDR), NULL, FILE_CURRENT) == INVALID_SET_FILE_POINTER) - throw std::string("Apple2: file corrupt"); - - SS_APPLE2_Unit_v2 Apple2Unit; - DWORD dwBytesRead; - BOOL bRes = ReadFile( m_hFile, - &Apple2Unit, - Length, - &dwBytesRead, - NULL); - - if (dwBytesRead != Length) - throw std::string("Apple2: file corrupt"); - - g_Apple2Type = (eApple2Type) Apple2Unit.Apple2Type; - m_ConfigNew.m_Apple2Type = g_Apple2Type; - - CpuSetSnapshot(Apple2Unit.CPU6502); - JoySetSnapshot(Apple2Unit.Joystick.JoyCntrResetCycle, &Apple2Unit.Joystick.Joystick0Trim[0], &Apple2Unit.Joystick.Joystick1Trim[0]); - KeybSetSnapshot(Apple2Unit.Keyboard.LastKey); - SpkrSetSnapshot(Apple2Unit.Speaker.SpkrLastCycle); - VideoSetSnapshot(Apple2Unit.Video); - MemSetSnapshot(Apple2Unit.Memory); -} - -//=== - -static void LoadCardDisk2(void) -{ - DiskSetSnapshot(m_hFile); -} - -static void LoadCardMockingboardC(void) -{ - MB_SetSnapshot(m_hFile); -} - -static void LoadCardMouseInterface(void) -{ - sg_Mouse.SetSnapshot(m_hFile); -} - -static void LoadCardSSC(void) -{ - sg_SSC.SetSnapshot(m_hFile); -} - -static void LoadCardPrinter(void) -{ - Printer_SetSnapshot(m_hFile); -} - -static void LoadCardHDD(void) -{ - HD_SetSnapshot(m_hFile, g_strSaveStatePath); - m_ConfigNew.m_bEnableHDD = true; -} - -static void LoadCardPhasor(void) -{ - Phasor_SetSnapshot(m_hFile); -} - -static void LoadCardZ80(void) -{ - Z80_SetSnapshot(m_hFile); -} - -static void LoadCard80ColAuxMem(void) -{ - MemSetSnapshotAux(m_hFile); -} - -//=== - -static void LoadUnitCard(DWORD Length, DWORD Version) -{ - SS_CARD_HDR Card; - - if (Version != UNIT_APPLE2_VER) - throw std::string("Card: Version mismatch"); - - if (Length < sizeof(Card)) - throw std::string("Card: file corrupt"); - - if (SetFilePointer(m_hFile, -(LONG)sizeof(Card.UnitHdr), NULL, FILE_CURRENT) == INVALID_SET_FILE_POINTER) - throw std::string("Card: file corrupt"); - - DWORD dwBytesRead; - BOOL bRes = ReadFile( m_hFile, - &Card, - sizeof(Card), - &dwBytesRead, - NULL); - - if (dwBytesRead != sizeof(Card)) - throw std::string("Card: file corrupt"); - - //currently cards are changed by restarting machine (ie. all slot empty) then adding cards (most of which are hardcoded to specific slots) - - if (SetFilePointer(m_hFile, -(LONG)sizeof(SS_CARD_HDR), NULL, FILE_CURRENT) == INVALID_SET_FILE_POINTER) - throw std::string("Card: file corrupt"); - - bool bIsCardSupported = true; - - switch(Card.Type) - { - case CT_Empty: - throw std::string("Card: todo"); - break; - case CT_Disk2: - LoadCardDisk2(); - break; - case CT_SSC: - LoadCardSSC(); - break; - case CT_MockingboardC: - LoadCardMockingboardC(); - break; - case CT_GenericPrinter: - LoadCardPrinter(); - break; - case CT_GenericHDD: - LoadCardHDD(); - break; - case CT_MouseInterface: - LoadCardMouseInterface(); - break; - case CT_Z80: - LoadCardZ80(); - break; - case CT_Phasor: - LoadCardPhasor(); - break; - case CT_80Col: - case CT_Extended80Col: - case CT_RamWorksIII: - LoadCard80ColAuxMem(); - break; - default: - //throw std::string("Card: unsupported"); - bIsCardSupported = false; - if (SetFilePointer(m_hFile, Card.UnitHdr.hdr.v2.Length, NULL, FILE_CURRENT) == INVALID_SET_FILE_POINTER) - throw std::string("Card: failed to skip unsupported card"); - } - - if (bIsCardSupported) - { - if (Card.Slot <= 7) - m_ConfigNew.m_Slot[Card.Slot] = (SS_CARDTYPE) Card.Type; - else - m_ConfigNew.m_SlotAux = (SS_CARDTYPE) Card.Type; - } -} - -// Todo: -// . Should this newly loaded config state be persisted to the Registry? -// - NB. it will get saved if the user opens the Config dialog + makes a change. Is this confusing to the user? -// Notes: -// . WindowScale - don't think this needs restoring (eg. like FullScreen) - -static void LoadUnitConfig(DWORD Length, DWORD Version) -{ - SS_APPLEWIN_CONFIG Config; - - if (Version != UNIT_CONFIG_VER) - throw std::string("Config: Version mismatch"); - - if (Length != sizeof(Config)) - throw std::string("Config: Length mismatch"); - - if (SetFilePointer(m_hFile, -(LONG)sizeof(Config.UnitHdr), NULL, FILE_CURRENT) == INVALID_SET_FILE_POINTER) - throw std::string("Config: file corrupt"); - - DWORD dwBytesRead; - BOOL bRes = ReadFile( m_hFile, - &Config, - Length, - &dwBytesRead, - NULL); - - if (dwBytesRead != Length) - throw std::string("Config: file corrupt"); - - // Restore all config state - - //Config.Cfg.AppleWinVersion // Nothing to do - g_eVideoType = Config.Cfg.VideoMode; - g_uHalfScanLines = Config.Cfg.IsHalfScanLines; - g_bConfirmReboot = Config.Cfg.IsConfirmReboot; - monochrome = Config.Cfg.MonochromeColor; - //Config.Cfg.WindowScale // NB. Just calling SetViewportScale() is no good. Use PostMessage() instead. - - g_dwSpeed = Config.Cfg.CpuSpeed; - SetCurrentCLK6502(); - - JoySetJoyType(JN_JOYSTICK0, Config.Cfg.JoystickType[0]); - JoySetJoyType(JN_JOYSTICK1, Config.Cfg.JoystickType[1]); - sg_PropertySheet.SetJoystickCursorControl(Config.Cfg.IsAllowCursorsToBeRead); - sg_PropertySheet.SetAutofire(Config.Cfg.IsAutofire); - sg_PropertySheet.SetJoystickCenteringControl(Config.Cfg.IsKeyboardAutocentering); - //Config.Cfg.IsSwapButton0and1; // TBD: not implemented yet - sg_PropertySheet.SetScrollLockToggle(Config.Cfg.IsScrollLockToggle); - sg_PropertySheet.SetMouseShowCrosshair(Config.Cfg.IsMouseShowCrosshair); - sg_PropertySheet.SetMouseRestrictToWindow(Config.Cfg.IsMouseRestrictToWindow); - - soundtype = Config.Cfg.SoundType; - SpkrSetVolume(Config.Cfg.SpeakerVolume, sg_PropertySheet.GetVolumeMax()); - MB_SetVolume(Config.Cfg.MockingboardVolume, sg_PropertySheet.GetVolumeMax()); - - enhancedisk = Config.Cfg.IsEnhancedDiskSpeed; - g_bSaveStateOnExit = Config.Cfg.IsSaveStateOnExit ? true : false; - - g_bPrinterAppend = Config.Cfg.IsAppendToFile ? true : false; - sg_PropertySheet.SetTheFreezesF8Rom(Config.Cfg.IsUsingFreezesF8Rom); -} - -//--- - static std::string GetSnapshotUnitApple2Name(void) { static const std::string name("Apple2"); @@ -532,9 +266,9 @@ static eApple2Type ParseApple2Type(std::string type) throw std::string("Load: Unknown Apple2 type"); } -static std::string GetApple2Type(void) +static std::string GetApple2TypeAsString(void) { - switch (g_Apple2Type) + switch ( GetApple2Type() ) { case A2TYPE_APPLE2: return SS_YAML_VALUE_APPLE2; case A2TYPE_APPLE2PLUS: return SS_YAML_VALUE_APPLE2PLUS; @@ -584,9 +318,12 @@ static void ParseUnitApple2(YamlLoadHelper& yamlLoadHelper, UINT version) throw std::string(SS_YAML_KEY_UNIT ": Apple2: Version mismatch"); std::string model = yamlLoadHelper.GetMapValueSTRING(SS_YAML_KEY_MODEL); - g_Apple2Type = ParseApple2Type(model); + SetApple2Type( ParseApple2Type(model) ); // NB. Sets default main CPU type + m_ConfigNew.m_Apple2Type = GetApple2Type(); + + CpuLoadSnapshot(yamlLoadHelper); // NB. Overrides default main CPU type + m_ConfigNew.m_CpuType = GetMainCpu(); - CpuLoadSnapshot(yamlLoadHelper); JoyLoadSnapshot(yamlLoadHelper); KeybLoadSnapshot(yamlLoadHelper); SpkrLoadSnapshot(yamlLoadHelper); @@ -706,10 +443,6 @@ static void ParseUnit(void) { ParseSlots(yamlLoadHelper, version); } - else if (unit == SS_YAML_VALUE_UNIT_CONFIG) - { - //... - } else { throw std::string(SS_YAML_KEY_UNIT ": Unknown type: " ) + unit; @@ -758,12 +491,9 @@ static void Snapshot_LoadState_v2(void) sg_Mouse.Reset(); HD_SetEnabled(false); - while(1) + std::string scalar; + while(yamlHelper.GetScalar(scalar)) { - std::string scalar; - if (!yamlHelper.GetScalar(scalar)) - break; - if (scalar == SS_YAML_KEY_UNIT) ParseUnit(); else @@ -784,6 +514,11 @@ static void Snapshot_LoadState_v2(void) MemInitializeIO(); MemUpdatePaging(TRUE); + + // g_Apple2Type may've changed: so redraw frame (title, buttons, leds, etc) + SetCharsetType(); + VideoReinitialize(); // g_CharsetType changed + FrameUpdateApple2Type(); } catch(std::string szMessage) { @@ -798,199 +533,24 @@ static void Snapshot_LoadState_v2(void) yamlHelper.FinaliseParser(); } -static void Snapshot_LoadState_v2(DWORD dwVersion) -{ - try - { - if (dwVersion != MAKE_VERSION(2,0,0,0)) - throw std::string("Version mismatch"); - - CConfigNeedingRestart ConfigOld; - ConfigOld.m_Slot[1] = CT_GenericPrinter; // fixme - ConfigOld.m_Slot[2] = CT_SSC; // fixme - //ConfigOld.m_Slot[3] = CT_Uthernet; // todo - ConfigOld.m_Slot[6] = CT_Disk2; // fixme - ConfigOld.m_Slot[7] = ConfigOld.m_bEnableHDD ? CT_GenericHDD : CT_Empty; // fixme - //ConfigOld.m_SlotAux = ?; // fixme - - for (UINT i=0; isecond.subMap) { - GetMapRemainder(*iter->second.subMap); + std::string subMapName(iter->first); + GetMapRemainder(subMapName, *iter->second.subMap); delete iter->second.subMap; } else { const char* pKey = iter->first.c_str(); - char szDbg[100]; - sprintf(szDbg, "%s: Unknown key (%s)\n", m_lastMapName.c_str(), pKey); - OutputDebugString(szDbg); + LogOutput("%s: Unknown key (%s)\n", mapName.c_str(), pKey); + LogFileOutput("%s: Unknown key (%s)\n", mapName.c_str(), pKey); } } diff --git a/source/YamlHelper.h b/source/YamlHelper.h index 6fe2e935..cc45ff0a 100644 --- a/source/YamlHelper.h +++ b/source/YamlHelper.h @@ -6,14 +6,11 @@ #define SS_YAML_KEY_TAG "Tag" #define SS_YAML_KEY_VERSION "Version" #define SS_YAML_KEY_UNIT "Unit" -#define SS_YAML_KEY_UNIT_TYPE "Type" #define SS_YAML_KEY_TYPE "Type" #define SS_YAML_KEY_CARD "Card" #define SS_YAML_KEY_STATE "State" #define SS_YAML_VALUE_AWSS "AppleWin Save State" -#define SS_YAML_VALUE_UNIT_CARD "Card" -#define SS_YAML_VALUE_UNIT_CONFIG "Config" struct MapValue; typedef std::map MapYaml; @@ -44,21 +41,16 @@ public: int InitParser(const char* pPathname); void FinaliseParser(void); - void GetNextEvent(bool bInMap = false); int GetScalar(std::string& scalar); - void GetListStartEvent(void); -// void GetListEndEvent(void); void GetMapStartEvent(void); - void GetMapEndEvent(void); - int GetMapStartOrListEndEvent(void); - std::string GetMapName(void) { return m_mapName; } private: + void GetNextEvent(bool bInMap = false); int ParseMap(MapYaml& mapYaml); std::string GetMapValue(MapYaml& mapYaml, const std::string key, bool& bFound); void GetMapValueMemory(MapYaml& mapYaml, const LPBYTE pMemBase, const size_t kAddrSpaceSize); bool GetSubMap(MapYaml** mapYaml, const std::string key); - void GetMapRemainder(MapYaml& mapYaml); + void GetMapRemainder(std::string& mapName, MapYaml& mapYaml); void MakeAsciiToHexTable(void); @@ -70,19 +62,6 @@ private: FILE* m_hFile; char m_AsciiToHex[256]; - // - - std::string m_lastMapName; - std::string m_mapName; - - struct MapState - { - std::string name; - bool isInMap; - }; - - std::stack< MapState > m_stackMapState; - MapYaml m_mapYaml; }; @@ -94,22 +73,33 @@ public: YamlLoadHelper(YamlHelper& yamlHelper) : m_yamlHelper(yamlHelper), m_pMapYaml(&yamlHelper.m_mapYaml), - m_bIteratingOverMap(false) + m_bIteratingOverMap(false), + m_bDoGetMapRemainder(true), + m_topLevelMapName(yamlHelper.m_scalarName), + m_currentMapName(m_topLevelMapName) { if (!m_yamlHelper.ParseMap(yamlHelper.m_mapYaml)) - throw std::string(m_yamlHelper.GetMapName() + ": Failed to parse map"); + { + m_bDoGetMapRemainder = false; + throw std::string(m_currentMapName + ": Failed to parse map"); + } } ~YamlLoadHelper(void) { - m_yamlHelper.GetMapRemainder(m_yamlHelper.m_mapYaml); + if (m_bDoGetMapRemainder) + m_yamlHelper.GetMapRemainder(m_topLevelMapName, m_yamlHelper.m_mapYaml); } INT GetMapValueINT(const std::string key) { bool bFound; std::string value = m_yamlHelper.GetMapValue(*m_pMapYaml, key, bFound); - if (value == "") throw std::string(m_yamlHelper.GetMapName() + ": Missing: " + key); + if (value == "") + { + m_bDoGetMapRemainder = false; + throw std::string(m_currentMapName + ": Missing: " + key); + } return strtol(value.c_str(), NULL, 0); } @@ -117,7 +107,11 @@ public: { bool bFound; std::string value = m_yamlHelper.GetMapValue(*m_pMapYaml, key, bFound); - if (value == "") throw std::string(m_yamlHelper.GetMapName() + ": Missing: " + key); + if (value == "") + { + m_bDoGetMapRemainder = false; + throw std::string(m_currentMapName + ": Missing: " + key); + } return strtoul(value.c_str(), NULL, 0); } @@ -125,7 +119,11 @@ public: { bool bFound; std::string value = m_yamlHelper.GetMapValue(*m_pMapYaml, key, bFound); - if (value == "") throw std::string(m_yamlHelper.GetMapName() + ": Missing: " + key); + if (value == "") + { + m_bDoGetMapRemainder = false; + throw std::string(m_currentMapName + ": Missing: " + key); + } return _strtoui64(value.c_str(), NULL, 0); } @@ -149,7 +147,11 @@ public: { bool bFound; std::string value = GetMapValueSTRING_NoThrow(key, bFound); - if (!bFound) throw std::string(m_yamlHelper.GetMapName() + ": Missing: " + key); + if (!bFound) + { + m_bDoGetMapRemainder = false; + throw std::string(m_currentMapName + ": Missing: " + key); + } return value; } @@ -160,10 +162,13 @@ public: bool GetSubMap(const std::string key) { - m_stackMap.push(m_pMapYaml); + YamlStackItem item = {m_pMapYaml, m_currentMapName}; + m_stackMap.push(item); bool res = m_yamlHelper.GetSubMap(&m_pMapYaml, key); if (!res) m_stackMap.pop(); + else + m_currentMapName = key; return res; } @@ -172,8 +177,11 @@ public: if (m_stackMap.empty()) return; - m_pMapYaml = m_stackMap.top(); + YamlStackItem item = m_stackMap.top(); m_stackMap.pop(); + + m_pMapYaml = item.pMapYaml; + m_currentMapName = item.mapName; } std::string GetMapNextSlotNumber(void) @@ -198,7 +206,17 @@ public: private: YamlHelper& m_yamlHelper; MapYaml* m_pMapYaml; - std::stack m_stackMap; + bool m_bDoGetMapRemainder; + + struct YamlStackItem + { + MapYaml* pMapYaml; + std::string mapName; + }; + std::stack m_stackMap; + + std::string m_topLevelMapName; + std::string m_currentMapName; bool m_bIteratingOverMap; MapYaml::iterator m_iter; @@ -209,6 +227,7 @@ private: class YamlSaveHelper { friend class Indent; // Indent can access YamlSaveHelper's private members + public: YamlSaveHelper(std::string pathname) : m_hFile(NULL), diff --git a/source/Z80VICE/z80.cpp b/source/Z80VICE/z80.cpp index 21c7c885..3b43dc89 100644 --- a/source/Z80VICE/z80.cpp +++ b/source/Z80VICE/z80.cpp @@ -6339,7 +6339,7 @@ DWORD z80_mainloop(ULONG uTotalCycles, ULONG uExecutedCycles) //cpu_int_status->num_dma_per_opcode = 0; // [AppleWin-TC] Not used - if (g_ActiveCPU != CPU_Z80) // [AppleWin-TC] + if (GetActiveCpu() != CPU_Z80) // [AppleWin-TC] break; //} while (!dma_request); @@ -6482,14 +6482,14 @@ void Z80_SaveSnapshot(class YamlSaveHelper& yamlSaveHelper, const UINT uSlot) // NB. Not for 65C02 which is a static processor. // . SoftCard controls the 6502's RDY line to periodically allow only 1 memory fetch by 6502 (ie. the opcode fetch) // - // So save /g_ActiveCPU/ to SS_CARD_Z80 (so RDY is like IRQ & NMI signals, ie. saved struct of the producer's card) + // So save ActiveCPU to SS_CARD_Z80 (so RDY is like IRQ & NMI signals, ie. saved struct of the producer's card) // // NB. Save-state only occurs when message pump runs: // . ie. at end of 1ms emulation burst // Either 6502 or Z80 could be active. // - yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_ACTIVE, g_ActiveCPU == CPU_Z80 ? 1 : 0); + yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_ACTIVE, GetActiveCpu() == CPU_Z80 ? 1 : 0); yamlSaveHelper.Save("%s: 0x%02X\n", SS_YAML_KEY_REGA, reg_a); yamlSaveHelper.Save("%s: 0x%02X\n", SS_YAML_KEY_REGB, reg_b); @@ -6563,185 +6563,7 @@ bool Z80_LoadSnapshot(class YamlLoadHelper& yamlLoadHelper, UINT uSlot, UINT ver export_registers(); if ( yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_ACTIVE) ) - g_ActiveCPU = CPU_Z80; // Support MS SoftCard in multiple slots (only one Z80 can be active at any one time) + SetActiveCpu(CPU_Z80); // Support MS SoftCard in multiple slots (only one Z80 can be active at any one time) return true; } - -//--- - -struct Z80_Unit -{ - BYTE reg_a; - BYTE reg_b; - BYTE reg_c; - BYTE reg_d; - BYTE reg_e; - BYTE reg_f; - BYTE reg_h; - BYTE reg_l; - BYTE reg_ixh; - BYTE reg_ixl; - BYTE reg_iyh; - BYTE reg_iyl; - WORD reg_sp; - DWORD z80_reg_pc; - BYTE reg_i; - BYTE reg_r; - - BYTE iff1; - BYTE iff2; - BYTE im_mode; - - BYTE reg_a2; - BYTE reg_b2; - BYTE reg_c2; - BYTE reg_d2; - BYTE reg_e2; - BYTE reg_f2; - BYTE reg_h2; - BYTE reg_l2; -}; - -struct SS_CARD_Z80 -{ - SS_CARD_HDR Hdr; - Z80_Unit Unit; - UINT Active; -}; - -void Z80_GetSnapshot(const HANDLE hFile, const UINT uZ80Slot) -{ - SS_CARD_Z80 Card; - - SS_CARD_Z80* const pSS = &Card; - - pSS->Hdr.UnitHdr.hdr.v2.Length = sizeof(SS_CARD_Z80); - pSS->Hdr.UnitHdr.hdr.v2.Type = UT_Card; - pSS->Hdr.UnitHdr.hdr.v2.Version = 1; - - pSS->Hdr.Slot = uZ80Slot; // fixme: object should know its slot - pSS->Hdr.Type = CT_Z80; - - pSS->Unit.reg_a = reg_a; - pSS->Unit.reg_b = reg_b; - pSS->Unit.reg_c = reg_c; - pSS->Unit.reg_d = reg_d; - pSS->Unit.reg_e = reg_e; - pSS->Unit.reg_f = reg_f; - pSS->Unit.reg_h = reg_h; - pSS->Unit.reg_l = reg_l; - pSS->Unit.reg_ixh = reg_ixh; - pSS->Unit.reg_ixl = reg_ixl; - pSS->Unit.reg_iyh = reg_iyh; - pSS->Unit.reg_iyl = reg_iyl; - pSS->Unit.reg_sp = reg_sp; - pSS->Unit.z80_reg_pc = z80_reg_pc; - pSS->Unit.reg_i = reg_i; - pSS->Unit.reg_r = reg_r; - - pSS->Unit.iff1 = iff1; - pSS->Unit.iff2 = iff2; - pSS->Unit.im_mode = im_mode; - - pSS->Unit.reg_a2 = reg_a2; - pSS->Unit.reg_b2 = reg_b2; - pSS->Unit.reg_c2 = reg_c2; - pSS->Unit.reg_d2 = reg_d2; - pSS->Unit.reg_e2 = reg_e2; - pSS->Unit.reg_f2 = reg_f2; - pSS->Unit.reg_h2 = reg_h2; - pSS->Unit.reg_l2 = reg_l2; - - // SoftCard SW & HW details: http://apple2info.net/images/f/f0/SC-SWHW.pdf - // . SoftCard uses the Apple II's DMA circuit to pause the 6502 (no CLK to 6502) - // . But: "In Apple II DMA, the 6502 CPU will die after approximately 15 clocks because it depends on the clock to refresh its internal registers." - // ref: Apple Tech Note: https://archive.org/stream/IIe_2523004_RDY_Line/IIe_2523004_RDY_Line_djvu.txt - // NB. Not for 65C02 which is a static processor. - // . SoftCard controls the 6502's RDY line to periodically allow only 1 memory fetch by 6502 (ie. the opcode fetch) - // - // So save /g_ActiveCPU/ to SS_CARD_Z80 (so RDY is like IRQ & NMI signals, ie. saved struct of the producer's card) - // - // NB. Save-state only occurs when message pump runs: - // . ie. at end of 1ms emulation burst - // Either 6502 or Z80 could be active. - // - - pSS->Active = g_ActiveCPU == CPU_Z80 ? 1 : 0; - - // - - DWORD dwBytesWritten; - BOOL bRes = WriteFile( hFile, - &Card, - Card.Hdr.UnitHdr.hdr.v2.Length, - &dwBytesWritten, - NULL); - - if(!bRes || (dwBytesWritten != Card.Hdr.UnitHdr.hdr.v2.Length)) - { - //dwError = GetLastError(); - throw std::string("Save error: Z80"); - } -} - -void Z80_SetSnapshot(const HANDLE hFile) -{ - SS_CARD_Z80 Card; - - DWORD dwBytesRead; - BOOL bRes = ReadFile( hFile, - &Card, - sizeof(Card), - &dwBytesRead, - NULL); - - if (dwBytesRead != sizeof(Card)) - throw std::string("Card: file corrupt"); - - if (Card.Hdr.Slot != 4 && Card.Hdr.Slot != 5) // fixme - throw std::string("Card: wrong slot"); - - if (Card.Hdr.UnitHdr.hdr.v2.Version > 1) - throw std::string("Card: wrong version"); - - if (Card.Hdr.UnitHdr.hdr.v2.Length != sizeof(SS_CARD_Z80)) - throw std::string("Card: unit size mismatch"); - - SS_CARD_Z80* pSS = &Card; - - reg_a = pSS->Unit.reg_a; - reg_b = pSS->Unit.reg_b; - reg_c = pSS->Unit.reg_c; - reg_d = pSS->Unit.reg_d; - reg_e = pSS->Unit.reg_e; - reg_f = pSS->Unit.reg_f; - reg_h = pSS->Unit.reg_h; - reg_l = pSS->Unit.reg_l; - reg_ixh = pSS->Unit.reg_ixh; - reg_ixl = pSS->Unit.reg_ixl; - reg_iyh = pSS->Unit.reg_iyh; - reg_iyl = pSS->Unit.reg_iyl; - reg_sp = pSS->Unit.reg_sp; - z80_reg_pc = pSS->Unit.z80_reg_pc; - reg_i = pSS->Unit.reg_i; - reg_r = pSS->Unit.reg_r; - - iff1 = pSS->Unit.iff1; - iff2 = pSS->Unit.iff2; - im_mode = pSS->Unit.im_mode; - - reg_a2 = pSS->Unit.reg_a2; - reg_b2 = pSS->Unit.reg_b2; - reg_c2 = pSS->Unit.reg_c2; - reg_d2 = pSS->Unit.reg_d2; - reg_e2 = pSS->Unit.reg_e2; - reg_f2 = pSS->Unit.reg_f2; - reg_h2 = pSS->Unit.reg_h2; - reg_l2 = pSS->Unit.reg_l2; - - export_registers(); - - if (pSS->Active) - g_ActiveCPU = CPU_Z80; // Support MS SoftCard in multiple slots (only one Z80 can be active at any one time) -} diff --git a/source/z80emu.cpp b/source/z80emu.cpp index 932711e3..01542099 100644 --- a/source/z80emu.cpp +++ b/source/z80emu.cpp @@ -16,6 +16,7 @@ #include "StdAfx.h" #include "AppleWin.h" +#include "CPU.h" #include "Memory.h" #include "z80emu.h" @@ -30,7 +31,7 @@ BYTE __stdcall CPMZ80_IONull(WORD PC, WORD uAddr, BYTE bWrite, BYTE uValue, ULON BYTE __stdcall CPMZ80_IOWrite(WORD PC, WORD uAddr, BYTE bWrite, BYTE uValue, ULONG nCyclesLeft) { if ((uAddr & 0xFF00) == (0xC000 + (g_uCPMZ80Slot << 8))) - g_ActiveCPU = (g_ActiveCPU == CPU_6502) ? CPU_Z80 : CPU_6502; + SetActiveCpu( GetActiveCpu() == CPU_Z80 ? GetMainCpu() : CPU_Z80 ); return IO_Null(PC, uAddr, bWrite, uValue, nCyclesLeft); } diff --git a/source/z80emu.h b/source/z80emu.h index 49fced1f..3b256f0a 100644 --- a/source/z80emu.h +++ b/source/z80emu.h @@ -19,5 +19,3 @@ void ConfigureSoftcard(LPBYTE pCxRomPeripheral, UINT uSlot); std::string Z80_GetSnapshotCardName(void); void Z80_SaveSnapshot(class YamlSaveHelper& yamlSaveHelper, const UINT uSlot); bool Z80_LoadSnapshot(class YamlLoadHelper& yamlLoadHelper, UINT uSlot, UINT version); -void Z80_GetSnapshot(const HANDLE hFile, const UINT uZ80Slot); -void Z80_SetSnapshot(const HANDLE hFile); diff --git a/test/TestCPU6502/TestCPU6502.cpp b/test/TestCPU6502/TestCPU6502.cpp index 30147f82..30088ceb 100644 --- a/test/TestCPU6502/TestCPU6502.cpp +++ b/test/TestCPU6502/TestCPU6502.cpp @@ -4,7 +4,6 @@ #include "../../source/CPU.h" // From Applewin.cpp -eCPU g_ActiveCPU = CPU_6502; enum AppMode_e g_nAppMode = MODE_RUNNING; // From Memory.cpp @@ -38,6 +37,13 @@ regsrec regs; static const int IRQ_CHECK_TIMEOUT = 128; static signed int g_nIrqCheckTimeout = IRQ_CHECK_TIMEOUT; +static eCpuType g_ActiveCPU = CPU_65C02; + +eCpuType GetActiveCpu(void) +{ + return g_ActiveCPU; +} + static __forceinline int Fetch(BYTE& iOpcode, ULONG uExecutedCycles) { iOpcode = *(mem+regs.pc); From 13e7a6cc655014adbff7eab6f2f5a5f362194e84 Mon Sep 17 00:00:00 2001 From: tomcw Date: Sun, 14 Feb 2016 17:25:58 +0000 Subject: [PATCH 11/20] Fix for probing CpuType from Apple2Type --- source/CPU.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/source/CPU.cpp b/source/CPU.cpp index e12e28a3..e0ecf3a4 100644 --- a/source/CPU.cpp +++ b/source/CPU.cpp @@ -165,16 +165,15 @@ void SetMainCpu(eCpuType cpu) g_MainCPU = cpu; } -static bool IsCpu6502(eApple2Type apple2Type) +static bool IsCpu65C02(eApple2Type apple2Type) { - return IS_APPLE2 || - (apple2Type == A2TYPE_APPLE2E) || - IS_CLONE(); // NB. All Pravets clones are 6502 (GH#307) + // NB. All Pravets clones are 6502 (GH#307) + return (apple2Type == A2TYPE_APPLE2EENHANCED) || (apple2Type & A2TYPE_APPLE2C); } eCpuType ProbeMainCpuDefault(eApple2Type apple2Type) { - return IsCpu6502(apple2Type) ? CPU_6502 : CPU_65C02; + return IsCpu65C02(apple2Type) ? CPU_65C02 : CPU_6502; } void SetMainCpuDefault(eApple2Type apple2Type) From ccac0a562ddcb0474f7cc0a4abaf70049b01ceb4 Mon Sep 17 00:00:00 2001 From: tomcw Date: Mon, 15 Feb 2016 22:33:38 +0000 Subject: [PATCH 12/20] Save-state: standardise on Unit0/Unit1 for Disk2 and HDD --- source/Disk.cpp | 4 ++-- source/Harddisk.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/source/Disk.cpp b/source/Disk.cpp index 5ec21ba4..cceb3357 100644 --- a/source/Disk.cpp +++ b/source/Disk.cpp @@ -1180,7 +1180,7 @@ int DiskSetSnapshot_v1(const SS_CARD_DISK2* const pSS) #define SS_YAML_KEY_FLOPPY_MOTOR_ON "Floppy Motor On" #define SS_YAML_KEY_FLOPPY_WRITE_MODE "Floppy Write Mode" -#define SS_YAML_KEY_DISK2UNIT "Disk][ Unit" +#define SS_YAML_KEY_DISK2UNIT "Unit" #define SS_YAML_KEY_FILENAME "Filename" #define SS_YAML_KEY_TRACK "Track" #define SS_YAML_KEY_PHASE "Phase" @@ -1229,7 +1229,7 @@ void DiskSaveSnapshot(class YamlSaveHelper& yamlSaveHelper) yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_CURRENT_DRIVE, currdrive); yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_DISK_ACCESSED, diskaccessed); yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_ENHANCE_DISK, enhancedisk); - yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_FLOPPY_LATCH, floppylatch); + yamlSaveHelper.Save("%s: 0x%02X\n", SS_YAML_KEY_FLOPPY_LATCH, floppylatch); yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_FLOPPY_MOTOR_ON, floppymotoron); yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_FLOPPY_WRITE_MODE, floppywritemode); diff --git a/source/Harddisk.cpp b/source/Harddisk.cpp index a4c70f2a..7d18c1f7 100644 --- a/source/Harddisk.cpp +++ b/source/Harddisk.cpp @@ -668,7 +668,7 @@ void HD_GetLightStatus (Disk_Status_e *pDisk1Status_) #define SS_YAML_KEY_CURRENT_UNIT "Current Unit" #define SS_YAML_KEY_COMMAND "Command" -#define SS_YAML_KEY_HDDUNIT "HDD Unit" +#define SS_YAML_KEY_HDDUNIT "Unit" #define SS_YAML_KEY_FILENAME "Filename" #define SS_YAML_KEY_ERROR "Error" #define SS_YAML_KEY_MEMBLOCK "MemBlock" From 7f50288bd998be34ea3b37f0690e032eb39f6b85 Mon Sep 17 00:00:00 2001 From: tomcw Date: Tue, 16 Feb 2016 22:11:19 +0000 Subject: [PATCH 13/20] Remove old functions from header --- source/AY8910.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/source/AY8910.h b/source/AY8910.h index ea2596e6..31ad9a15 100644 --- a/source/AY8910.h +++ b/source/AY8910.h @@ -48,8 +48,6 @@ public: static void SetCLK( double CLK ) { m_fCurrentCLK_AY8910 = CLK; } void SaveSnapshot(class YamlSaveHelper& yamlSaveHelper, std::string& suffix); bool LoadSnapshot(class YamlLoadHelper& yamlLoadHelper, std::string& suffix); - UINT GetSnapshot(const HANDLE hFile); - UINT SetSnapshot(const HANDLE hFile); private: void init( void ); From 8524f914953074fbd44faf7ec801f8afdc68cd91 Mon Sep 17 00:00:00 2001 From: tomcw Date: Sat, 20 Feb 2016 17:57:23 +0000 Subject: [PATCH 14/20] Save-state: Yaml: Removed GetMapValueBOOL() --- source/Harddisk.cpp | 11 ++++++----- source/MouseInterface.cpp | 20 +++++++++----------- source/MouseInterface.h | 6 +++--- source/YamlHelper.h | 7 ------- 4 files changed, 18 insertions(+), 26 deletions(-) diff --git a/source/Harddisk.cpp b/source/Harddisk.cpp index 7d18c1f7..9df3d33f 100644 --- a/source/Harddisk.cpp +++ b/source/Harddisk.cpp @@ -125,7 +125,7 @@ struct HDD WORD hd_memblock; UINT hd_diskblock; WORD hd_buf_ptr; - BOOL hd_imageloaded; + bool hd_imageloaded; BYTE hd_buf[HD_BLOCK_SIZE+1]; // Why +1? Probably for erroreous reads beyond the block size (ie. reads from I/O addr 0xC0F8) #if HD_LED @@ -443,7 +443,7 @@ void HD_Unplug(const int iDrive) bool HD_IsDriveUnplugged(const int iDrive) { - return g_HardDisk[iDrive].hd_imageloaded == FALSE; + return g_HardDisk[iDrive].hd_imageloaded == false; } //----------------------------------------------------------------------------- @@ -726,12 +726,13 @@ static bool HD_LoadSnapshotHDDUnit(YamlLoadHelper& yamlLoadHelper, UINT unit) throw std::string("Card: Expected key: ") + hddUnitName; std::string filename = yamlLoadHelper.GetMapValueSTRING(SS_YAML_KEY_FILENAME).c_str(); - //strcpy_s(g_HardDisk[Unit].fullname, sizeof(g_HardDisk[unit].fullname), filename.c_str()); + g_HardDisk[unit].fullname[0] = 0; + g_HardDisk[unit].imagename[0] = 0; g_HardDisk[unit].hd_error = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_ERROR); g_HardDisk[unit].hd_memblock = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_MEMBLOCK); g_HardDisk[unit].hd_diskblock = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_DISKBLOCK); - yamlLoadHelper.GetMapValueBOOL(SS_YAML_KEY_IMAGELOADED); // Consume - g_HardDisk[unit].hd_imageloaded = FALSE; // Default to FALSE (until image is successfully loaded below) + yamlLoadHelper.GetMapValueBool(SS_YAML_KEY_IMAGELOADED); // Consume + g_HardDisk[unit].hd_imageloaded = false; // Default to false (until image is successfully loaded below) g_HardDisk[unit].hd_status_next = (Disk_Status_e) yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_STATUS_NEXT); g_HardDisk[unit].hd_status_prev = (Disk_Status_e) yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_STATUS_PREV); g_HardDisk[unit].hd_buf_ptr = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_BUF_PTR); diff --git a/source/MouseInterface.cpp b/source/MouseInterface.cpp index d6bee8ed..b44e8784 100644 --- a/source/MouseInterface.cpp +++ b/source/MouseInterface.cpp @@ -211,7 +211,7 @@ void CMouseInterface::Reset() m_iMinY = 0; m_iMaxY = 1023; - m_bButtons[0] = m_bButtons[1] = FALSE; + m_bButtons[0] = m_bButtons[1] = false; // @@ -448,15 +448,13 @@ void CMouseInterface::OnMouseEvent(bool bEventVBL) if ( !( m_byMode & MODE_MOUSE_ON ) ) // Mouse Off return; - BOOL bBtn0 = m_bButtons[0]; - BOOL bBtn1 = m_bButtons[1]; if ( m_nX != m_iX || m_nY != m_iY ) { byState |= STAT_INT_MOVEMENT|STAT_MOVEMENT_SINCE_READMOUSE; // X/Y moved since last READMOUSE | Movement interrupt m_byState |= STAT_MOVEMENT_SINCE_READMOUSE; // [TC] Used by CopyII+9.1 and ProTERM3.1 } - if ( m_bBtn0 != bBtn0 || m_bBtn1 != bBtn1 ) + if ( m_bBtn0 != m_bButtons[0] || m_bBtn1 != m_bButtons[1] ) byState |= STAT_INT_BUTTON; // Button 0/1 interrupt if ( bEventVBL ) byState |= STAT_INT_VBL; @@ -496,8 +494,8 @@ void CMouseInterface::Clear() m_byState = 0; m_nX = 0; m_nY = 0; - m_bBtn0 = 0; - m_bBtn1 = 0; + m_bBtn0 = false; + m_bBtn1 = false; SetPositionAbs( 0, 0 ); // CpuIrqDeassert(IS_MOUSE); @@ -595,7 +593,7 @@ void CMouseInterface::SetPositionRel(long dX, long dY, int* pOutOfBoundsX, int* void CMouseInterface::SetButton(eBUTTON Button, eBUTTONSTATE State) { - m_bButtons[Button]= (State == BUTTON_DOWN) ? TRUE : FALSE; + m_bButtons[Button] = (State == BUTTON_DOWN); OnMouseEvent(); } @@ -743,8 +741,8 @@ bool CMouseInterface::LoadSnapshot(class YamlLoadHelper& yamlLoadHelper, UINT sl m_byState = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_MOUSESTATE); m_nX = yamlLoadHelper.GetMapValueINT(SS_YAML_KEY_X); m_nY = yamlLoadHelper.GetMapValueINT(SS_YAML_KEY_Y); - m_bBtn0 = yamlLoadHelper.GetMapValueBOOL(SS_YAML_KEY_BTN0); - m_bBtn1 = yamlLoadHelper.GetMapValueBOOL(SS_YAML_KEY_BTN1); + m_bBtn0 = yamlLoadHelper.GetMapValueBool(SS_YAML_KEY_BTN0); + m_bBtn1 = yamlLoadHelper.GetMapValueBool(SS_YAML_KEY_BTN1); m_bVBL = yamlLoadHelper.GetMapValueBool(SS_YAML_KEY_VBL); m_iX = yamlLoadHelper.GetMapValueINT(SS_YAML_KEY_IX); m_iMinX = yamlLoadHelper.GetMapValueINT(SS_YAML_KEY_IMINX); @@ -752,8 +750,8 @@ bool CMouseInterface::LoadSnapshot(class YamlLoadHelper& yamlLoadHelper, UINT sl m_iY = yamlLoadHelper.GetMapValueINT(SS_YAML_KEY_IY); m_iMinY = yamlLoadHelper.GetMapValueINT(SS_YAML_KEY_IMINY); m_iMaxY = yamlLoadHelper.GetMapValueINT(SS_YAML_KEY_IMAXY); - m_bButtons[0] = yamlLoadHelper.GetMapValueBOOL(SS_YAML_KEY_BUTTON0); - m_bButtons[1] = yamlLoadHelper.GetMapValueBOOL(SS_YAML_KEY_BUTTON1); + m_bButtons[0] = yamlLoadHelper.GetMapValueBool(SS_YAML_KEY_BUTTON0); + m_bButtons[1] = yamlLoadHelper.GetMapValueBool(SS_YAML_KEY_BUTTON1); m_bActive = yamlLoadHelper.GetMapValueBool(SS_YAML_KEY_ACTIVE); m_bEnabled = yamlLoadHelper.GetMapValueBool(SS_YAML_KEY_ENABLED); diff --git a/source/MouseInterface.h b/source/MouseInterface.h index edb62ca8..b98fdc83 100644 --- a/source/MouseInterface.h +++ b/source/MouseInterface.h @@ -75,8 +75,8 @@ protected: BYTE m_byState; int m_nX; int m_nY; - BOOL m_bBtn0; - BOOL m_bBtn1; + bool m_bBtn0; + bool m_bBtn1; bool m_bVBL; @@ -89,7 +89,7 @@ protected: int m_iMinY; int m_iMaxY; - BOOL m_bButtons[2]; + bool m_bButtons[2]; // diff --git a/source/YamlHelper.h b/source/YamlHelper.h index cc45ff0a..610ffd42 100644 --- a/source/YamlHelper.h +++ b/source/YamlHelper.h @@ -132,11 +132,6 @@ public: return GetMapValueUINT(key) ? true : false; } - BOOL GetMapValueBOOL(const std::string key) - { - return GetMapValueUINT(key) ? TRUE : FALSE; - } - std::string GetMapValueSTRING_NoThrow(const std::string& key, bool& bFound) { std::string value = m_yamlHelper.GetMapValue(*m_pMapYaml, key, bFound); @@ -226,8 +221,6 @@ private: class YamlSaveHelper { -friend class Indent; // Indent can access YamlSaveHelper's private members - public: YamlSaveHelper(std::string pathname) : m_hFile(NULL), From 6b07fd665f132e8ad20f57df658076d973e5c983 Mon Sep 17 00:00:00 2001 From: tomcw Date: Wed, 24 Feb 2016 21:51:20 +0000 Subject: [PATCH 15/20] Save-state: Added save-type functions to YamlSaveHelper & use wherever saving state. Also added new cmd-line option: -load-state. --- source/AY8910.cpp | 66 ++++++++++++++++++------------------ source/Applewin.cpp | 28 ++++++++++++++-- source/CPU.cpp | 16 ++++----- source/Disk.cpp | 38 +++++++++++---------- source/Harddisk.cpp | 34 ++++++++++++------- source/Joystick.cpp | 14 ++++---- source/Keyboard.cpp | 2 +- source/Memory.cpp | 16 ++++----- source/Mockingboard.cpp | 46 ++++++++++++------------- source/MouseInterface.cpp | 69 ++++++++++++++++++-------------------- source/MouseInterface.h | 8 +++-- source/ParallelPrinter.cpp | 26 +++++++------- source/SerialComms.cpp | 40 +++++++++++----------- source/Speaker.cpp | 2 +- source/Video.cpp | 6 ++-- source/YamlHelper.cpp | 63 +++++++++++++++++++++++++++++----- source/YamlHelper.h | 12 ++++++- source/Z80VICE/z80.cpp | 50 +++++++++++++-------------- 18 files changed, 313 insertions(+), 223 deletions(-) diff --git a/source/AY8910.cpp b/source/AY8910.cpp index b40f26b0..fc4328ac 100644 --- a/source/AY8910.cpp +++ b/source/AY8910.cpp @@ -997,44 +997,44 @@ void CAY8910::SaveSnapshot(YamlSaveHelper& yamlSaveHelper, std::string& suffix) std::string unit = std::string(SS_YAML_KEY_AY8910) + suffix; YamlSaveHelper::Label label(yamlSaveHelper, "%s:\n", unit.c_str()); - yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_TONE0_TICK, ay_tone_tick[0]); - yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_TONE1_TICK, ay_tone_tick[1]); - yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_TONE2_TICK, ay_tone_tick[2]); - yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_TONE0_HIGH, ay_tone_high[0]); - yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_TONE1_HIGH, ay_tone_high[1]); - yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_TONE2_HIGH, ay_tone_high[2]); - yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_NOISE_TICK, ay_noise_tick); - yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_TONE_SUBCYCLES, ay_tone_subcycles); - yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_ENV_SUBCYCLES, ay_env_subcycles); - yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_ENV_INTERNAL_TICK, ay_env_internal_tick); - yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_ENV_TICK, ay_env_tick); - yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_TICK_INCR, ay_tick_incr); - yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_TONE0_PERIOD, ay_tone_period[0]); - yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_TONE1_PERIOD, ay_tone_period[1]); - yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_TONE2_PERIOD, ay_tone_period[2]); - yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_NOISE_PERIOD, ay_noise_period); - yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_RNG, rng); - yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_NOISE_TOGGLE, noise_toggle); - yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_ENV_FIRST, env_first); - yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_ENV_REV, env_rev); - yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_ENV_COUNTER, env_counter); + yamlSaveHelper.SaveUint(SS_YAML_KEY_TONE0_TICK, ay_tone_tick[0]); + yamlSaveHelper.SaveUint(SS_YAML_KEY_TONE1_TICK, ay_tone_tick[1]); + yamlSaveHelper.SaveUint(SS_YAML_KEY_TONE2_TICK, ay_tone_tick[2]); + yamlSaveHelper.SaveUint(SS_YAML_KEY_TONE0_HIGH, ay_tone_high[0]); + yamlSaveHelper.SaveUint(SS_YAML_KEY_TONE1_HIGH, ay_tone_high[1]); + yamlSaveHelper.SaveUint(SS_YAML_KEY_TONE2_HIGH, ay_tone_high[2]); + yamlSaveHelper.SaveUint(SS_YAML_KEY_NOISE_TICK, ay_noise_tick); + yamlSaveHelper.SaveUint(SS_YAML_KEY_TONE_SUBCYCLES, ay_tone_subcycles); + yamlSaveHelper.SaveUint(SS_YAML_KEY_ENV_SUBCYCLES, ay_env_subcycles); + yamlSaveHelper.SaveUint(SS_YAML_KEY_ENV_INTERNAL_TICK, ay_env_internal_tick); + yamlSaveHelper.SaveUint(SS_YAML_KEY_ENV_TICK, ay_env_tick); + yamlSaveHelper.SaveUint(SS_YAML_KEY_TICK_INCR, ay_tick_incr); + yamlSaveHelper.SaveUint(SS_YAML_KEY_TONE0_PERIOD, ay_tone_period[0]); + yamlSaveHelper.SaveUint(SS_YAML_KEY_TONE1_PERIOD, ay_tone_period[1]); + yamlSaveHelper.SaveUint(SS_YAML_KEY_TONE2_PERIOD, ay_tone_period[2]); + yamlSaveHelper.SaveUint(SS_YAML_KEY_NOISE_PERIOD, ay_noise_period); + yamlSaveHelper.SaveUint(SS_YAML_KEY_RNG, rng); + yamlSaveHelper.SaveUint(SS_YAML_KEY_NOISE_TOGGLE, noise_toggle); + yamlSaveHelper.SaveUint(SS_YAML_KEY_ENV_FIRST, env_first); + yamlSaveHelper.SaveUint(SS_YAML_KEY_ENV_REV, env_rev); + yamlSaveHelper.SaveUint(SS_YAML_KEY_ENV_COUNTER, env_counter); // New label { YamlSaveHelper::Label registers(yamlSaveHelper, "%s:\n", SS_YAML_KEY_REGISTERS); - yamlSaveHelper.Save("%s: 0x%03X\n", SS_YAML_KEY_REG_TONE0_PERIOD, (UINT)(sound_ay_registers[1]<<8) | sound_ay_registers[0]); - yamlSaveHelper.Save("%s: 0x%03X\n", SS_YAML_KEY_REG_TONE1_PERIOD, (UINT)(sound_ay_registers[3]<<8) | sound_ay_registers[2]); - yamlSaveHelper.Save("%s: 0x%03X\n", SS_YAML_KEY_REG_TONE2_PERIOD, (UINT)(sound_ay_registers[5]<<8) | sound_ay_registers[4]); - yamlSaveHelper.Save("%s: 0x%02X\n", SS_YAML_KEY_REG_NOISE_PERIOD, sound_ay_registers[6]); - yamlSaveHelper.Save("%s: 0x%02X\n", SS_YAML_KEY_REG_MIXER, sound_ay_registers[7]); - yamlSaveHelper.Save("%s: 0x%02X\n", SS_YAML_KEY_REG_VOL0, sound_ay_registers[8]); - yamlSaveHelper.Save("%s: 0x%02X\n", SS_YAML_KEY_REG_VOL1, sound_ay_registers[9]); - yamlSaveHelper.Save("%s: 0x%02X\n", SS_YAML_KEY_REG_VOL2, sound_ay_registers[10]); - yamlSaveHelper.Save("%s: 0x%04X\n", SS_YAML_KEY_REG_ENV_PERIOD, (UINT)(sound_ay_registers[12]<<8) | sound_ay_registers[11]); - yamlSaveHelper.Save("%s: 0x%01X\n", SS_YAML_KEY_REG_ENV_SHAPE, sound_ay_registers[13]); - yamlSaveHelper.Save("%s: 0x%02X\n", SS_YAML_KEY_REG_PORTA, sound_ay_registers[14]); - yamlSaveHelper.Save("%s: 0x%02X\n", SS_YAML_KEY_REG_PORTB, sound_ay_registers[15]); + yamlSaveHelper.SaveHex12(SS_YAML_KEY_REG_TONE0_PERIOD, (UINT)(sound_ay_registers[1]<<8) | sound_ay_registers[0]); + yamlSaveHelper.SaveHex12(SS_YAML_KEY_REG_TONE1_PERIOD, (UINT)(sound_ay_registers[3]<<8) | sound_ay_registers[2]); + yamlSaveHelper.SaveHex12(SS_YAML_KEY_REG_TONE2_PERIOD, (UINT)(sound_ay_registers[5]<<8) | sound_ay_registers[4]); + yamlSaveHelper.SaveHex8(SS_YAML_KEY_REG_NOISE_PERIOD, sound_ay_registers[6]); + yamlSaveHelper.SaveHex8(SS_YAML_KEY_REG_MIXER, sound_ay_registers[7]); + yamlSaveHelper.SaveHex8(SS_YAML_KEY_REG_VOL0, sound_ay_registers[8]); + yamlSaveHelper.SaveHex8(SS_YAML_KEY_REG_VOL1, sound_ay_registers[9]); + yamlSaveHelper.SaveHex8(SS_YAML_KEY_REG_VOL2, sound_ay_registers[10]); + yamlSaveHelper.SaveHex16(SS_YAML_KEY_REG_ENV_PERIOD, (UINT)(sound_ay_registers[12]<<8) | sound_ay_registers[11]); + yamlSaveHelper.SaveHex4(SS_YAML_KEY_REG_ENV_SHAPE, sound_ay_registers[13]); + yamlSaveHelper.SaveHex8(SS_YAML_KEY_REG_PORTA, sound_ay_registers[14]); + yamlSaveHelper.SaveHex8(SS_YAML_KEY_REG_PORTB, sound_ay_registers[15]); } // New label diff --git a/source/Applewin.cpp b/source/Applewin.cpp index b8608c33..4d3a8ee0 100644 --- a/source/Applewin.cpp +++ b/source/Applewin.cpp @@ -784,6 +784,7 @@ int APIENTRY WinMain(HINSTANCE passinstance, HINSTANCE, LPSTR lpCmdLine, int) bool bBoot = false; LPSTR szImageName_drive1 = NULL; LPSTR szImageName_drive2 = NULL; + LPSTR szSnapshotName = NULL; const std::string strCmdLine(lpCmdLine); // Keep a copy for log ouput while (*lpCmdLine) @@ -815,6 +816,12 @@ int APIENTRY WinMain(HINSTANCE passinstance, HINSTANCE, LPSTR lpCmdLine, int) lpNextArg = GetNextArg(lpNextArg); szImageName_drive2 = lpCmdLine; } + else if (strcmp(lpCmdLine, "-load-state") == 0) + { + lpCmdLine = GetCurrArg(lpNextArg); + lpNextArg = GetNextArg(lpNextArg); + szSnapshotName = lpCmdLine; + } else if (strcmp(lpCmdLine, "-f") == 0) { bSetFullScreen = true; @@ -1075,8 +1082,25 @@ int APIENTRY WinMain(HINSTANCE passinstance, HINSTANCE, LPSTR lpCmdLine, int) tfe_init(); LogFileOutput("Main: tfe_init()\n"); - Snapshot_Startup(); // Do this after everything has been init'ed - LogFileOutput("Main: Snapshot_Startup()\n"); + if (szSnapshotName) + { + // Override value just loaded from Registry by LoadConfiguration() + // . NB. Registry value is not updated with this cmd-line value + Snapshot_SetFilename(szSnapshotName); + Snapshot_LoadState(); + bBoot = true; +#if _DEBUG && 0 // Debug/test: Save a duplicate of the save-state file in tmp folder + std::string saveName = std::string("tmp\\") + std::string(szSnapshotName); + Snapshot_SetFilename(saveName); + g_bSaveStateOnExit = true; + bShutdown = true; +#endif + } + else + { + Snapshot_Startup(); // Do this after everything has been init'ed + LogFileOutput("Main: Snapshot_Startup()\n"); + } if (bShutdown) { diff --git a/source/CPU.cpp b/source/CPU.cpp index e0ecf3a4..9422d378 100644 --- a/source/CPU.cpp +++ b/source/CPU.cpp @@ -729,14 +729,14 @@ void CpuSaveSnapshot(YamlSaveHelper& yamlSaveHelper) regs.ps |= (AF_RESERVED | AF_BREAK); YamlSaveHelper::Label state(yamlSaveHelper, "%s:\n", CpuGetSnapshotStructName().c_str()); - yamlSaveHelper.Save("%s: %s\n", SS_YAML_KEY_CPU_TYPE, GetMainCpu() == CPU_6502 ? SS_YAML_VALUE_6502 : SS_YAML_VALUE_65C02); - yamlSaveHelper.Save("%s: 0x%02X\n", SS_YAML_KEY_REGA, regs.a); - yamlSaveHelper.Save("%s: 0x%02X\n", SS_YAML_KEY_REGX, regs.x); - yamlSaveHelper.Save("%s: 0x%02X\n", SS_YAML_KEY_REGY, regs.y); - yamlSaveHelper.Save("%s: 0x%02X\n", SS_YAML_KEY_REGP, regs.ps); - yamlSaveHelper.Save("%s: 0x%02X\n", SS_YAML_KEY_REGS, (BYTE) regs.sp); - yamlSaveHelper.Save("%s: 0x%04X\n", SS_YAML_KEY_REGPC, regs.pc); - yamlSaveHelper.Save("%s: 0x%016llX\n", SS_YAML_KEY_CUMULATIVECYCLES, g_nCumulativeCycles); + yamlSaveHelper.SaveString(SS_YAML_KEY_CPU_TYPE, GetMainCpu() == CPU_6502 ? SS_YAML_VALUE_6502 : SS_YAML_VALUE_65C02); + yamlSaveHelper.SaveHex8(SS_YAML_KEY_REGA, regs.a); + yamlSaveHelper.SaveHex8(SS_YAML_KEY_REGX, regs.x); + yamlSaveHelper.SaveHex8(SS_YAML_KEY_REGY, regs.y); + yamlSaveHelper.SaveHex8(SS_YAML_KEY_REGP, regs.ps); + yamlSaveHelper.SaveHex8(SS_YAML_KEY_REGS, (BYTE) regs.sp); + yamlSaveHelper.SaveHex16(SS_YAML_KEY_REGPC, regs.pc); + yamlSaveHelper.SaveHex64(SS_YAML_KEY_CUMULATIVECYCLES, g_nCumulativeCycles); } void CpuLoadSnapshot(YamlLoadHelper& yamlLoadHelper) diff --git a/source/Disk.cpp b/source/Disk.cpp index cceb3357..7d2a49f5 100644 --- a/source/Disk.cpp +++ b/source/Disk.cpp @@ -1202,16 +1202,16 @@ std::string DiskGetSnapshotCardName(void) static void DiskSaveSnapshotDisk2Unit(YamlSaveHelper& yamlSaveHelper, UINT unit) { YamlSaveHelper::Label label(yamlSaveHelper, "%s%d:\n", SS_YAML_KEY_DISK2UNIT, unit); - yamlSaveHelper.Save("%s: %s\n", SS_YAML_KEY_FILENAME, yamlSaveHelper.GetSaveString(g_aFloppyDisk[unit].fullname).c_str()); - yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_TRACK, g_aFloppyDisk[unit].track); - yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_PHASE, g_aFloppyDisk[unit].phase); - yamlSaveHelper.Save("%s: 0x%04X\n", SS_YAML_KEY_BYTE, g_aFloppyDisk[unit].byte); - yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_WRITE_PROTECTED, g_aFloppyDisk[unit].bWriteProtected); - yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_SPINNING, g_aFloppyDisk[unit].spinning); - yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_WRITE_LIGHT, g_aFloppyDisk[unit].writelight); - yamlSaveHelper.Save("%s: 0x%04X\n", SS_YAML_KEY_NIBBLES, g_aFloppyDisk[unit].nibbles); - yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_TRACK_IMAGE_DATA, g_aFloppyDisk[unit].trackimagedata); - yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_TRACK_IMAGE_DIRTY, g_aFloppyDisk[unit].trackimagedirty); + yamlSaveHelper.SaveString(SS_YAML_KEY_FILENAME, g_aFloppyDisk[unit].fullname); + yamlSaveHelper.SaveUint(SS_YAML_KEY_TRACK, g_aFloppyDisk[unit].track); + yamlSaveHelper.SaveUint(SS_YAML_KEY_PHASE, g_aFloppyDisk[unit].phase); + yamlSaveHelper.SaveHex16(SS_YAML_KEY_BYTE, g_aFloppyDisk[unit].byte); + yamlSaveHelper.SaveUint(SS_YAML_KEY_WRITE_PROTECTED, g_aFloppyDisk[unit].bWriteProtected); + yamlSaveHelper.SaveUint(SS_YAML_KEY_SPINNING, g_aFloppyDisk[unit].spinning); + yamlSaveHelper.SaveUint(SS_YAML_KEY_WRITE_LIGHT, g_aFloppyDisk[unit].writelight); + yamlSaveHelper.SaveHex16(SS_YAML_KEY_NIBBLES, g_aFloppyDisk[unit].nibbles); + yamlSaveHelper.SaveUint(SS_YAML_KEY_TRACK_IMAGE_DATA, g_aFloppyDisk[unit].trackimagedata); + yamlSaveHelper.SaveUint(SS_YAML_KEY_TRACK_IMAGE_DIRTY, g_aFloppyDisk[unit].trackimagedirty); if (g_aFloppyDisk[unit].trackimage) { @@ -1225,13 +1225,13 @@ void DiskSaveSnapshot(class YamlSaveHelper& yamlSaveHelper) YamlSaveHelper::Slot slot(yamlSaveHelper, DiskGetSnapshotCardName(), g_uSlot, 1); YamlSaveHelper::Label state(yamlSaveHelper, "%s:\n", SS_YAML_KEY_STATE); - yamlSaveHelper.Save("%s: 0x%1X\n", SS_YAML_KEY_PHASES, phases); - yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_CURRENT_DRIVE, currdrive); - yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_DISK_ACCESSED, diskaccessed); - yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_ENHANCE_DISK, enhancedisk); - yamlSaveHelper.Save("%s: 0x%02X\n", SS_YAML_KEY_FLOPPY_LATCH, floppylatch); - yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_FLOPPY_MOTOR_ON, floppymotoron); - yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_FLOPPY_WRITE_MODE, floppywritemode); + yamlSaveHelper.SaveHex4(SS_YAML_KEY_PHASES, phases); + yamlSaveHelper.SaveUint(SS_YAML_KEY_CURRENT_DRIVE, currdrive); + yamlSaveHelper.SaveUint(SS_YAML_KEY_DISK_ACCESSED, diskaccessed); + yamlSaveHelper.SaveUint(SS_YAML_KEY_ENHANCE_DISK, enhancedisk); + yamlSaveHelper.SaveHex8(SS_YAML_KEY_FLOPPY_LATCH, floppylatch); + yamlSaveHelper.SaveUint(SS_YAML_KEY_FLOPPY_MOTOR_ON, floppymotoron); + yamlSaveHelper.SaveUint(SS_YAML_KEY_FLOPPY_WRITE_MODE, floppywritemode); DiskSaveSnapshotDisk2Unit(yamlSaveHelper, DRIVE_1); DiskSaveSnapshotDisk2Unit(yamlSaveHelper, DRIVE_2); @@ -1245,6 +1245,10 @@ static void DiskLoadSnapshotDriveUnit(YamlLoadHelper& yamlLoadHelper, UINT unit) bool bImageError = false; + g_aFloppyDisk[unit].fullname[0] = 0; + g_aFloppyDisk[unit].imagename[0] = 0; + g_aFloppyDisk[unit].bWriteProtected = false; // Default to false (until image is successfully loaded below) + std::string filename = yamlLoadHelper.GetMapValueSTRING(SS_YAML_KEY_FILENAME).c_str(); if (!filename.empty()) { diff --git a/source/Harddisk.cpp b/source/Harddisk.cpp index 9df3d33f..0674ad43 100644 --- a/source/Harddisk.cpp +++ b/source/Harddisk.cpp @@ -688,14 +688,14 @@ std::string HD_GetSnapshotCardName(void) static void HD_SaveSnapshotHDDUnit(YamlSaveHelper& yamlSaveHelper, UINT unit) { YamlSaveHelper::Label label(yamlSaveHelper, "%s%d:\n", SS_YAML_KEY_HDDUNIT, unit); - yamlSaveHelper.Save("%s: %s\n", SS_YAML_KEY_FILENAME, yamlSaveHelper.GetSaveString(g_HardDisk[unit].fullname).c_str()); - yamlSaveHelper.Save("%s: 0x%02X\n", SS_YAML_KEY_ERROR, g_HardDisk[unit].hd_error); - yamlSaveHelper.Save("%s: 0x%04X\n", SS_YAML_KEY_MEMBLOCK, g_HardDisk[unit].hd_memblock); - yamlSaveHelper.Save("%s: 0x%08X\n", SS_YAML_KEY_DISKBLOCK, g_HardDisk[unit].hd_diskblock); - yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_IMAGELOADED, g_HardDisk[unit].hd_imageloaded); - yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_STATUS_NEXT, g_HardDisk[unit].hd_status_next); - yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_STATUS_PREV, g_HardDisk[unit].hd_status_prev); - yamlSaveHelper.Save("%s: 0x%04X\n", SS_YAML_KEY_BUF_PTR, g_HardDisk[unit].hd_buf_ptr); + yamlSaveHelper.SaveString(SS_YAML_KEY_FILENAME, g_HardDisk[unit].fullname); + yamlSaveHelper.SaveHex8(SS_YAML_KEY_ERROR, g_HardDisk[unit].hd_error); + yamlSaveHelper.SaveHex16(SS_YAML_KEY_MEMBLOCK, g_HardDisk[unit].hd_memblock); + yamlSaveHelper.SaveHex32(SS_YAML_KEY_DISKBLOCK, g_HardDisk[unit].hd_diskblock); + yamlSaveHelper.SaveUint(SS_YAML_KEY_IMAGELOADED, g_HardDisk[unit].hd_imageloaded); + yamlSaveHelper.SaveUint(SS_YAML_KEY_STATUS_NEXT, g_HardDisk[unit].hd_status_next); + yamlSaveHelper.SaveUint(SS_YAML_KEY_STATUS_PREV, g_HardDisk[unit].hd_status_prev); + yamlSaveHelper.SaveHex16(SS_YAML_KEY_BUF_PTR, g_HardDisk[unit].hd_buf_ptr); // New label { @@ -713,7 +713,7 @@ void HD_SaveSnapshot(YamlSaveHelper& yamlSaveHelper) YamlSaveHelper::Label state(yamlSaveHelper, "%s:\n", SS_YAML_KEY_STATE); yamlSaveHelper.Save("%s: %d # b7=unit\n", SS_YAML_KEY_CURRENT_UNIT, g_nHD_UnitNum); - yamlSaveHelper.Save("%s: 0x%02X\n", SS_YAML_KEY_COMMAND, g_nHD_Command); + yamlSaveHelper.SaveHex8(SS_YAML_KEY_COMMAND, g_nHD_Command); HD_SaveSnapshotHDDUnit(yamlSaveHelper, HARDDISK_1); HD_SaveSnapshotHDDUnit(yamlSaveHelper, HARDDISK_2); @@ -725,16 +725,19 @@ static bool HD_LoadSnapshotHDDUnit(YamlLoadHelper& yamlLoadHelper, UINT unit) if (!yamlLoadHelper.GetSubMap(hddUnitName)) throw std::string("Card: Expected key: ") + hddUnitName; - std::string filename = yamlLoadHelper.GetMapValueSTRING(SS_YAML_KEY_FILENAME).c_str(); g_HardDisk[unit].fullname[0] = 0; g_HardDisk[unit].imagename[0] = 0; + g_HardDisk[unit].hd_imageloaded = false; // Default to false (until image is successfully loaded below) + g_HardDisk[unit].hd_status_next = DISK_STATUS_OFF; + g_HardDisk[unit].hd_status_prev = DISK_STATUS_OFF; + + std::string filename = yamlLoadHelper.GetMapValueSTRING(SS_YAML_KEY_FILENAME).c_str(); g_HardDisk[unit].hd_error = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_ERROR); g_HardDisk[unit].hd_memblock = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_MEMBLOCK); g_HardDisk[unit].hd_diskblock = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_DISKBLOCK); yamlLoadHelper.GetMapValueBool(SS_YAML_KEY_IMAGELOADED); // Consume - g_HardDisk[unit].hd_imageloaded = false; // Default to false (until image is successfully loaded below) - g_HardDisk[unit].hd_status_next = (Disk_Status_e) yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_STATUS_NEXT); - g_HardDisk[unit].hd_status_prev = (Disk_Status_e) yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_STATUS_PREV); + Disk_Status_e diskStatusNext = (Disk_Status_e) yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_STATUS_NEXT); + Disk_Status_e diskStatusPrev = (Disk_Status_e) yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_STATUS_PREV); g_HardDisk[unit].hd_buf_ptr = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_BUF_PTR); if (!yamlLoadHelper.GetSubMap(SS_YAML_KEY_BUF)) @@ -769,6 +772,11 @@ static bool HD_LoadSnapshotHDDUnit(YamlLoadHelper& yamlLoadHelper, UINT unit) // . imagename // . fullname // . hd_imageloaded + // . hd_status_next = DISK_STATUS_OFF + // . hd_status_prev = DISK_STATUS_OFF + + g_HardDisk[unit].hd_status_next = diskStatusNext; + g_HardDisk[unit].hd_status_prev = diskStatusPrev; } } diff --git a/source/Joystick.cpp b/source/Joystick.cpp index 796c7a81..3039fe81 100644 --- a/source/Joystick.cpp +++ b/source/Joystick.cpp @@ -871,9 +871,9 @@ static std::string JoyGetSnapshotStructName(void) void JoySaveSnapshot(YamlSaveHelper& yamlSaveHelper) { YamlSaveHelper::Label state(yamlSaveHelper, "%s:\n", JoyGetSnapshotStructName().c_str()); - yamlSaveHelper.Save("%s: 0x%016llX\n", SS_YAML_KEY_COUNTERRESETCYCLE, g_nJoyCntrResetCycle); - yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_JOY0TRIMX, JoyGetTrim(true)); - yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_JOY0TRIMY, JoyGetTrim(false)); + yamlSaveHelper.SaveHex64(SS_YAML_KEY_COUNTERRESETCYCLE, g_nJoyCntrResetCycle); + yamlSaveHelper.SaveInt(SS_YAML_KEY_JOY0TRIMX, JoyGetTrim(true)); + yamlSaveHelper.SaveInt(SS_YAML_KEY_JOY0TRIMY, JoyGetTrim(false)); yamlSaveHelper.Save("%s: %d # not implemented yet\n", SS_YAML_KEY_JOY1TRIMX, 0); // not implemented yet yamlSaveHelper.Save("%s: %d # not implemented yet\n", SS_YAML_KEY_JOY1TRIMY, 0); // not implemented yet } @@ -884,10 +884,10 @@ void JoyLoadSnapshot(YamlLoadHelper& yamlLoadHelper) return; g_nJoyCntrResetCycle = yamlLoadHelper.GetMapValueUINT64(SS_YAML_KEY_COUNTERRESETCYCLE); - JoySetTrim(yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_JOY0TRIMX), true); - JoySetTrim(yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_JOY0TRIMY), false); - yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_JOY1TRIMX); // dump value - yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_JOY1TRIMY); // dump value + JoySetTrim(yamlLoadHelper.GetMapValueINT(SS_YAML_KEY_JOY0TRIMX), true); + JoySetTrim(yamlLoadHelper.GetMapValueINT(SS_YAML_KEY_JOY0TRIMY), false); + yamlLoadHelper.GetMapValueINT(SS_YAML_KEY_JOY1TRIMX); // dump value + yamlLoadHelper.GetMapValueINT(SS_YAML_KEY_JOY1TRIMY); // dump value yamlLoadHelper.PopMap(); } diff --git a/source/Keyboard.cpp b/source/Keyboard.cpp index 7db89425..b56f6946 100644 --- a/source/Keyboard.cpp +++ b/source/Keyboard.cpp @@ -519,7 +519,7 @@ static std::string KeybGetSnapshotStructName(void) void KeybSaveSnapshot(YamlSaveHelper& yamlSaveHelper) { YamlSaveHelper::Label state(yamlSaveHelper, "%s:\n", KeybGetSnapshotStructName().c_str()); - yamlSaveHelper.Save("%s: 0x%02X\n", SS_YAML_KEY_LASTKEY, g_nLastKey); + yamlSaveHelper.SaveHex8(SS_YAML_KEY_LASTKEY, g_nLastKey); } void KeybLoadSnapshot(YamlLoadHelper& yamlLoadHelper) diff --git a/source/Memory.cpp b/source/Memory.cpp index 59e333eb..62bc263e 100644 --- a/source/Memory.cpp +++ b/source/Memory.cpp @@ -1745,12 +1745,12 @@ void MemSaveSnapshot(YamlSaveHelper& yamlSaveHelper) // Scope so that "Memory" & "Main Memory" are at same indent level { YamlSaveHelper::Label state(yamlSaveHelper, "%s:\n", MemGetSnapshotStructName().c_str()); - yamlSaveHelper.Save("%s: 0x%08X\n", SS_YAML_KEY_MEMORYMODE, memmode); - yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_LASTRAMWRITE, lastwriteram ? 1 : 0); - yamlSaveHelper.Save("%s: 0x%02X\n", SS_YAML_KEY_IOSELECT, IO_SELECT); - yamlSaveHelper.Save("%s: 0x%02X\n", SS_YAML_KEY_IOSELECT_INT, IO_SELECT_InternalROM); - yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_EXPANSIONROMTYPE, (UINT) g_eExpansionRomType); - yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_PERIPHERALROMSLOT, g_uPeripheralRomSlot); + yamlSaveHelper.SaveHex32(SS_YAML_KEY_MEMORYMODE, memmode); + yamlSaveHelper.SaveUint(SS_YAML_KEY_LASTRAMWRITE, lastwriteram ? 1 : 0); + yamlSaveHelper.SaveHex8(SS_YAML_KEY_IOSELECT, IO_SELECT); + yamlSaveHelper.SaveHex8(SS_YAML_KEY_IOSELECT_INT, IO_SELECT_InternalROM); + yamlSaveHelper.SaveUint(SS_YAML_KEY_EXPANSIONROMTYPE, (UINT) g_eExpansionRomType); + yamlSaveHelper.SaveUint(SS_YAML_KEY_PERIPHERALROMSLOT, g_uPeripheralRomSlot); } MemSaveSnapshotMemory(yamlSaveHelper, true); @@ -1762,7 +1762,7 @@ bool MemLoadSnapshot(YamlLoadHelper& yamlLoadHelper) return false; SetMemMode( yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_MEMORYMODE) ); - lastwriteram = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_LASTRAMWRITE) ? 1 : 0; + lastwriteram = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_LASTRAMWRITE) ? TRUE : FALSE; IO_SELECT = (BYTE) yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_IOSELECT); IO_SELECT_InternalROM = (BYTE) yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_IOSELECT_INT); g_eExpansionRomType = (eExpansionRomType) yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_EXPANSIONROMTYPE); @@ -1807,7 +1807,7 @@ void MemSaveSnapshotAux(YamlSaveHelper& yamlSaveHelper) std::string card = g_uMaxExPages == 0 ? SS_YAML_VALUE_CARD_80COL : // todo: support empty slot g_uMaxExPages == 1 ? SS_YAML_VALUE_CARD_EXTENDED80COL : SS_YAML_VALUE_CARD_RAMWORKSIII; - yamlSaveHelper.Save("%s: %s\n", SS_YAML_KEY_CARD, card.c_str()); + yamlSaveHelper.SaveString(SS_YAML_KEY_CARD, card.c_str()); yamlSaveHelper.Save("%s: %02X # [0,1..7F] 0=no aux mem, 1=128K system, etc\n", SS_YAML_KEY_NUMAUXBANKS, g_uMaxExPages); yamlSaveHelper.Save("%s: %02X # [ 0..7E] 0=memaux\n", SS_YAML_KEY_ACTIVEAUXBANK, g_uActiveBank); diff --git a/source/Mockingboard.cpp b/source/Mockingboard.cpp index c52d69b9..ea97f240 100644 --- a/source/Mockingboard.cpp +++ b/source/Mockingboard.cpp @@ -1940,19 +1940,19 @@ static void SaveSnapshotSY6522(YamlSaveHelper& yamlSaveHelper, SY6522& sy6522) { YamlSaveHelper::Label label(yamlSaveHelper, "%s:\n", SS_YAML_KEY_SY6522); - yamlSaveHelper.Save("%s: 0x%02X\n", SS_YAML_KEY_SY6522_REG_ORB, sy6522.ORB); - yamlSaveHelper.Save("%s: 0x%02X\n", SS_YAML_KEY_SY6522_REG_ORA, sy6522.ORA); - yamlSaveHelper.Save("%s: 0x%02X\n", SS_YAML_KEY_SY6522_REG_DDRB, sy6522.DDRB); - yamlSaveHelper.Save("%s: 0x%02X\n", SS_YAML_KEY_SY6522_REG_DDRA, sy6522.DDRA); - yamlSaveHelper.Save("%s: 0x%04X\n", SS_YAML_KEY_SY6522_REG_T1_COUNTER, sy6522.TIMER1_COUNTER); - yamlSaveHelper.Save("%s: 0x%04X\n", SS_YAML_KEY_SY6522_REG_T1_LATCH, sy6522.TIMER1_LATCH); - yamlSaveHelper.Save("%s: 0x%04X\n", SS_YAML_KEY_SY6522_REG_T2_COUNTER, sy6522.TIMER2_COUNTER); - yamlSaveHelper.Save("%s: 0x%04X\n", SS_YAML_KEY_SY6522_REG_T2_LATCH, sy6522.TIMER2_LATCH); - yamlSaveHelper.Save("%s: 0x%02X\n", SS_YAML_KEY_SY6522_REG_SERIAL_SHIFT, sy6522.SERIAL_SHIFT); - yamlSaveHelper.Save("%s: 0x%02X\n", SS_YAML_KEY_SY6522_REG_ACR, sy6522.ACR); - yamlSaveHelper.Save("%s: 0x%02X\n", SS_YAML_KEY_SY6522_REG_PCR, sy6522.PCR); - yamlSaveHelper.Save("%s: 0x%02X\n", SS_YAML_KEY_SY6522_REG_IFR, sy6522.IFR); - yamlSaveHelper.Save("%s: 0x%02X\n", SS_YAML_KEY_SY6522_REG_IER, sy6522.IER); + yamlSaveHelper.SaveHex8(SS_YAML_KEY_SY6522_REG_ORB, sy6522.ORB); + yamlSaveHelper.SaveHex8(SS_YAML_KEY_SY6522_REG_ORA, sy6522.ORA); + yamlSaveHelper.SaveHex8(SS_YAML_KEY_SY6522_REG_DDRB, sy6522.DDRB); + yamlSaveHelper.SaveHex8(SS_YAML_KEY_SY6522_REG_DDRA, sy6522.DDRA); + yamlSaveHelper.SaveHex16(SS_YAML_KEY_SY6522_REG_T1_COUNTER, sy6522.TIMER1_COUNTER.w); + yamlSaveHelper.SaveHex16(SS_YAML_KEY_SY6522_REG_T1_LATCH, sy6522.TIMER1_LATCH.w); + yamlSaveHelper.SaveHex16(SS_YAML_KEY_SY6522_REG_T2_COUNTER, sy6522.TIMER2_COUNTER.w); + yamlSaveHelper.SaveHex16(SS_YAML_KEY_SY6522_REG_T2_LATCH, sy6522.TIMER2_LATCH.w); + yamlSaveHelper.SaveHex8(SS_YAML_KEY_SY6522_REG_SERIAL_SHIFT, sy6522.SERIAL_SHIFT); + yamlSaveHelper.SaveHex8(SS_YAML_KEY_SY6522_REG_ACR, sy6522.ACR); + yamlSaveHelper.SaveHex8(SS_YAML_KEY_SY6522_REG_PCR, sy6522.PCR); + yamlSaveHelper.SaveHex8(SS_YAML_KEY_SY6522_REG_IFR, sy6522.IFR); + yamlSaveHelper.SaveHex8(SS_YAML_KEY_SY6522_REG_IER, sy6522.IER); // NB. No need to write ORA_NO_HS, since same data as ORA, just without handshake } @@ -1960,12 +1960,12 @@ static void SaveSnapshotSSI263(YamlSaveHelper& yamlSaveHelper, SSI263A& ssi263) { YamlSaveHelper::Label label(yamlSaveHelper, "%s:\n", SS_YAML_KEY_SSI263); - yamlSaveHelper.Save("%s: 0x%02X\n", SS_YAML_KEY_SSI263_REG_DUR_PHON, ssi263.DurationPhoneme); - yamlSaveHelper.Save("%s: 0x%02X\n", SS_YAML_KEY_SSI263_REG_INF, ssi263.Inflection); - yamlSaveHelper.Save("%s: 0x%02X\n", SS_YAML_KEY_SSI263_REG_RATE_INF, ssi263.RateInflection); - yamlSaveHelper.Save("%s: 0x%02X\n", SS_YAML_KEY_SSI263_REG_CTRL_ART_AMP, ssi263.CtrlArtAmp); - yamlSaveHelper.Save("%s: 0x%02X\n", SS_YAML_KEY_SSI263_REG_FILTER_FREQ, ssi263.FilterFreq); - yamlSaveHelper.Save("%s: 0x%02X\n", SS_YAML_KEY_SSI263_REG_CURRENT_MODE, ssi263.CurrentMode); + yamlSaveHelper.SaveHex8(SS_YAML_KEY_SSI263_REG_DUR_PHON, ssi263.DurationPhoneme); + yamlSaveHelper.SaveHex8(SS_YAML_KEY_SSI263_REG_INF, ssi263.Inflection); + yamlSaveHelper.SaveHex8(SS_YAML_KEY_SSI263_REG_RATE_INF, ssi263.RateInflection); + yamlSaveHelper.SaveHex8(SS_YAML_KEY_SSI263_REG_CTRL_ART_AMP, ssi263.CtrlArtAmp); + yamlSaveHelper.SaveHex8(SS_YAML_KEY_SSI263_REG_FILTER_FREQ, ssi263.FilterFreq); + yamlSaveHelper.SaveHex8(SS_YAML_KEY_SSI263_REG_CURRENT_MODE, ssi263.CurrentMode); } void MB_SaveSnapshot(YamlSaveHelper& yamlSaveHelper, const UINT uSlot) @@ -1986,7 +1986,7 @@ void MB_SaveSnapshot(YamlSaveHelper& yamlSaveHelper, const UINT uSlot) AY8910_SaveSnapshot(yamlSaveHelper, nDeviceNum, std::string("")); SaveSnapshotSSI263(yamlSaveHelper, pMB->SpeechChip); - yamlSaveHelper.Save("%s: 0x%1X\n", SS_YAML_KEY_AY_CURR_REG, pMB->nAYCurrentRegister); + yamlSaveHelper.SaveHex4(SS_YAML_KEY_AY_CURR_REG, pMB->nAYCurrentRegister); yamlSaveHelper.Save("%s: %d # Not supported\n", SS_YAML_KEY_TIMER1_IRQ, 0); yamlSaveHelper.Save("%s: %d # Not supported\n", SS_YAML_KEY_TIMER2_IRQ, 0); yamlSaveHelper.Save("%s: %d # Not supported\n", SS_YAML_KEY_SPEECH_IRQ, 0); @@ -2114,8 +2114,8 @@ void Phasor_SaveSnapshot(YamlSaveHelper& yamlSaveHelper, const UINT uSlot) YamlSaveHelper::Label state(yamlSaveHelper, "%s:\n", SS_YAML_KEY_STATE); - yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_PHASOR_CLOCK_SCALE_FACTOR, g_PhasorClockScaleFactor); - yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_PHASOR_MODE, g_nPhasorMode); + yamlSaveHelper.SaveUint(SS_YAML_KEY_PHASOR_CLOCK_SCALE_FACTOR, g_PhasorClockScaleFactor); + yamlSaveHelper.SaveUint(SS_YAML_KEY_PHASOR_MODE, g_nPhasorMode); for(UINT i=0; iSpeechChip); - yamlSaveHelper.Save("%s: 0x%1X\n", SS_YAML_KEY_AY_CURR_REG, pMB->nAYCurrentRegister); + yamlSaveHelper.SaveHex4(SS_YAML_KEY_AY_CURR_REG, pMB->nAYCurrentRegister); yamlSaveHelper.Save("%s: %d # Not supported\n", SS_YAML_KEY_TIMER1_IRQ, 0); yamlSaveHelper.Save("%s: %d # Not supported\n", SS_YAML_KEY_TIMER2_IRQ, 0); yamlSaveHelper.Save("%s: %d # Not supported\n", SS_YAML_KEY_SPEECH_IRQ, 0); diff --git a/source/MouseInterface.cpp b/source/MouseInterface.cpp index b44e8784..5c33d03d 100644 --- a/source/MouseInterface.cpp +++ b/source/MouseInterface.cpp @@ -629,7 +629,6 @@ void CMouseInterface::SetButton(eBUTTON Button, eBUTTONSTATE State) #define SS_YAML_KEY_IMAXY "iMaxY" #define SS_YAML_KEY_BUTTON0 "Button0" #define SS_YAML_KEY_BUTTON1 "Button1" -#define SS_YAML_KEY_ACTIVE "Active" #define SS_YAML_KEY_ENABLED "Enabled" std::string CMouseInterface::GetSnapshotCardName(void) @@ -647,14 +646,14 @@ void CMouseInterface::SaveSnapshotMC6821(YamlSaveHelper& yamlSaveHelper, std::st m_6821.Get6821(mc6821, byIA, byIB); YamlSaveHelper::Label label(yamlSaveHelper, "%s:\n", key.c_str()); - yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_PRA, mc6821.pra); - yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_DDRA, mc6821.ddra); - yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_CRA, mc6821.cra); - yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_PRB, mc6821.prb); - yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_DDRB, mc6821.ddrb); - yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_CRB, mc6821.crb); - yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_IA, byIA); - yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_IB, byIB); + yamlSaveHelper.SaveUint(SS_YAML_KEY_PRA, mc6821.pra); + yamlSaveHelper.SaveUint(SS_YAML_KEY_DDRA, mc6821.ddra); + yamlSaveHelper.SaveUint(SS_YAML_KEY_CRA, mc6821.cra); + yamlSaveHelper.SaveUint(SS_YAML_KEY_PRB, mc6821.prb); + yamlSaveHelper.SaveUint(SS_YAML_KEY_DDRB, mc6821.ddrb); + yamlSaveHelper.SaveUint(SS_YAML_KEY_CRB, mc6821.crb); + yamlSaveHelper.SaveUint(SS_YAML_KEY_IA, byIA); + yamlSaveHelper.SaveUint(SS_YAML_KEY_IB, byIB); } void CMouseInterface::SaveSnapshot(class YamlSaveHelper& yamlSaveHelper) @@ -667,9 +666,9 @@ void CMouseInterface::SaveSnapshot(class YamlSaveHelper& yamlSaveHelper) YamlSaveHelper::Label state(yamlSaveHelper, "%s:\n", SS_YAML_KEY_STATE); SaveSnapshotMC6821(yamlSaveHelper, SS_YAML_KEY_MC6821); yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_DATALEN, m_nDataLen); - yamlSaveHelper.Save("%s: 0x%02X\n", SS_YAML_KEY_MODE, m_byMode); - yamlSaveHelper.Save("%s: 0x%02X\n", SS_YAML_KEY_6821B, m_by6821B); - yamlSaveHelper.Save("%s: 0x%02X\n", SS_YAML_KEY_6821A, m_by6821A); + yamlSaveHelper.SaveHex8(SS_YAML_KEY_MODE, m_byMode); + yamlSaveHelper.SaveHex8(SS_YAML_KEY_6821B, m_by6821B); + yamlSaveHelper.SaveHex8(SS_YAML_KEY_6821A, m_by6821A); // New label { @@ -678,22 +677,21 @@ void CMouseInterface::SaveSnapshot(class YamlSaveHelper& yamlSaveHelper) } yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_BUFFPOS, m_nBuffPos); - yamlSaveHelper.Save("%s: 0x%02X\n", SS_YAML_KEY_MOUSESTATE, m_byState); - yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_X, m_nX); - yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_Y, m_nY); - yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_BTN0, m_bBtn0); - yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_BTN1, m_bBtn1); - yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_VBL, m_bVBL ? 1 : 0); - yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_IX, m_iX); - yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_IMINX, m_iMinX); - yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_IMAXX, m_iMaxX); - yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_IY, m_iY); - yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_IMINY, m_iMinY); - yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_IMAXY, m_iMaxY); - yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_BUTTON0, m_bButtons[0]); - yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_BUTTON1, m_bButtons[1]); - yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_ACTIVE, m_bActive ? 1 : 0); - yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_ENABLED, m_bEnabled ? 1 : 0); + yamlSaveHelper.SaveHex8(SS_YAML_KEY_MOUSESTATE, m_byState); + yamlSaveHelper.SaveUint(SS_YAML_KEY_X, m_nX); + yamlSaveHelper.SaveUint(SS_YAML_KEY_Y, m_nY); + yamlSaveHelper.SaveBool(SS_YAML_KEY_BTN0, m_bBtn0); + yamlSaveHelper.SaveBool(SS_YAML_KEY_BTN1, m_bBtn1); + yamlSaveHelper.SaveBool(SS_YAML_KEY_VBL, m_bVBL); + yamlSaveHelper.SaveUint(SS_YAML_KEY_IX, m_iX); + yamlSaveHelper.SaveUint(SS_YAML_KEY_IMINX, m_iMinX); + yamlSaveHelper.SaveUint(SS_YAML_KEY_IMAXX, m_iMaxX); + yamlSaveHelper.SaveUint(SS_YAML_KEY_IY, m_iY); + yamlSaveHelper.SaveUint(SS_YAML_KEY_IMINY, m_iMinY); + yamlSaveHelper.SaveUint(SS_YAML_KEY_IMAXY, m_iMaxY); + yamlSaveHelper.SaveBool(SS_YAML_KEY_BUTTON0, m_bButtons[0]); + yamlSaveHelper.SaveBool(SS_YAML_KEY_BUTTON1, m_bButtons[1]); + yamlSaveHelper.SaveBool(SS_YAML_KEY_ENABLED, m_bEnabled); } void CMouseInterface::LoadSnapshotMC6821(YamlLoadHelper& yamlLoadHelper, std::string key) @@ -702,15 +700,15 @@ void CMouseInterface::LoadSnapshotMC6821(YamlLoadHelper& yamlLoadHelper, std::st throw std::string("Card: Expected key: ") + key; mc6821_t mc6821; - mc6821.pra = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_PRA); + mc6821.pra = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_PRA); mc6821.ddra = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_DDRA); - mc6821.cra = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_CRA); - mc6821.prb = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_PRB); + mc6821.cra = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_CRA); + mc6821.prb = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_PRB); mc6821.ddrb = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_DDRB); - mc6821.crb = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_CRB); + mc6821.crb = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_CRB); - BYTE byIA = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_IA); - BYTE byIB = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_IB); + BYTE byIA = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_IA); + BYTE byIB = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_IB); m_6821.Set6821(mc6821, byIA, byIB); @@ -752,8 +750,7 @@ bool CMouseInterface::LoadSnapshot(class YamlLoadHelper& yamlLoadHelper, UINT sl m_iMaxY = yamlLoadHelper.GetMapValueINT(SS_YAML_KEY_IMAXY); m_bButtons[0] = yamlLoadHelper.GetMapValueBool(SS_YAML_KEY_BUTTON0); m_bButtons[1] = yamlLoadHelper.GetMapValueBool(SS_YAML_KEY_BUTTON1); - m_bActive = yamlLoadHelper.GetMapValueBool(SS_YAML_KEY_ACTIVE); - m_bEnabled = yamlLoadHelper.GetMapValueBool(SS_YAML_KEY_ENABLED); + m_bEnabled = yamlLoadHelper.GetMapValueBool(SS_YAML_KEY_ENABLED); // MemInitializeIO() calls Initialize() which sets true return true; } diff --git a/source/MouseInterface.h b/source/MouseInterface.h index b98fdc83..2b48f0f0 100644 --- a/source/MouseInterface.h +++ b/source/MouseInterface.h @@ -18,8 +18,8 @@ public: void SetPositionRel(long dx, long dy, int* pOutOfBoundsX, int* pOutOfBoundsY); void SetButton(eBUTTON Button, eBUTTONSTATE State); bool IsActive() { return m_bActive; } - bool IsEnabled() { return m_bEnabled; } - bool IsActiveAndEnabled() { return IsActive() && IsEnabled(); } + bool IsEnabled() { return m_bEnabled; } // NB. m_bEnabled == true implies that m_bActive == true + bool IsActiveAndEnabled() { return IsActive() && IsEnabled(); } // todo: just use IsEnabled() void SetEnabled(bool bEnabled) { m_bEnabled = bEnabled; } void SetVBlank(bool bVBL); void GetXY(int& iX, int& iMinX, int& iMaxX, int& iY, int& iMinY, int& iMaxY) @@ -93,8 +93,10 @@ protected: // + // todo: remove m_bActive: + // - instantiate CMouseInterface object when active (and delete when inactive) bool m_bActive; // Mouse h/w is active within the Apple][ VM - bool m_bEnabled; // Windows' mouse events get passed to Apple]['s mouse h/w + bool m_bEnabled; // Windows' mouse events get passed to Apple]['s mouse h/w (m_bEnabled == true implies that m_bActive == true) LPBYTE m_pSlotRom; UINT m_uSlot; }; diff --git a/source/ParallelPrinter.cpp b/source/ParallelPrinter.cpp index 79df8242..0dcf5846 100644 --- a/source/ParallelPrinter.cpp +++ b/source/ParallelPrinter.cpp @@ -37,7 +37,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #include "..\resource\resource.h" static DWORD inactivity = 0; -static int g_iPrinterIdleLimit = 10; +static unsigned int g_PrinterIdleLimit = 10; static FILE* file = NULL; DWORD const PRINTDRVR_SIZE = APPLE_SLOT_SIZE; #define DEFAULT_PRINT_FILENAME "Printer.txt" @@ -246,12 +246,12 @@ void Printer_SetFilename(char* prtFilename) unsigned int Printer_GetIdleLimit() { - return g_iPrinterIdleLimit; + return g_PrinterIdleLimit; } void Printer_SetIdleLimit(unsigned int Duration) { - g_iPrinterIdleLimit = Duration; + g_PrinterIdleLimit = Duration; } //=========================================================================== @@ -279,15 +279,15 @@ void Printer_SaveSnapshot(class YamlSaveHelper& yamlSaveHelper) YamlSaveHelper::Slot slot(yamlSaveHelper, Printer_GetSnapshotCardName(), g_uSlot, 1); YamlSaveHelper::Label state(yamlSaveHelper, "%s:\n", SS_YAML_KEY_STATE); - yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_INACTIVITY, inactivity); - yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_IDLELIMIT, g_iPrinterIdleLimit); - yamlSaveHelper.Save("%s: %s\n", SS_YAML_KEY_FILENAME, yamlSaveHelper.GetSaveString(g_szPrintFilename).c_str()); - yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_FILEOPEN, (file != NULL) ? 1 : 0); - yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_DUMPTOPRINTER, g_bDumpToPrinter); - yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_CONVERTENCODING, g_bConvertEncoding); - yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_FILTERUNPRINTABLE, g_bFilterUnprintable); - yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_APPEND, g_bPrinterAppend); - yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_DUMPTOREALPRINTER, g_bEnableDumpToRealPrinter); + yamlSaveHelper.SaveUint(SS_YAML_KEY_INACTIVITY, inactivity); + yamlSaveHelper.SaveUint(SS_YAML_KEY_IDLELIMIT, g_PrinterIdleLimit); + yamlSaveHelper.SaveString(SS_YAML_KEY_FILENAME, g_szPrintFilename); + yamlSaveHelper.SaveUint(SS_YAML_KEY_FILEOPEN, (file != NULL) ? 1 : 0); + yamlSaveHelper.SaveBool(SS_YAML_KEY_DUMPTOPRINTER, g_bDumpToPrinter); + yamlSaveHelper.SaveBool(SS_YAML_KEY_CONVERTENCODING, g_bConvertEncoding); + yamlSaveHelper.SaveBool(SS_YAML_KEY_FILTERUNPRINTABLE, g_bFilterUnprintable); + yamlSaveHelper.SaveBool(SS_YAML_KEY_APPEND, g_bPrinterAppend); + yamlSaveHelper.SaveBool(SS_YAML_KEY_DUMPTOREALPRINTER, g_bEnableDumpToRealPrinter); } bool Printer_LoadSnapshot(class YamlLoadHelper& yamlLoadHelper, UINT slot, UINT version) @@ -299,7 +299,7 @@ bool Printer_LoadSnapshot(class YamlLoadHelper& yamlLoadHelper, UINT slot, UINT throw std::string("Card: wrong version"); inactivity = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_INACTIVITY); - g_iPrinterIdleLimit = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_IDLELIMIT); + g_PrinterIdleLimit = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_IDLELIMIT); strncpy(g_szPrintFilename, yamlLoadHelper.GetMapValueSTRING(SS_YAML_KEY_FILENAME).c_str(), sizeof(g_szPrintFilename)); if (yamlLoadHelper.GetMapValueBool(SS_YAML_KEY_FILEOPEN)) diff --git a/source/SerialComms.cpp b/source/SerialComms.cpp index 39f4ca10..4e4e8a87 100644 --- a/source/SerialComms.cpp +++ b/source/SerialComms.cpp @@ -1349,13 +1349,13 @@ std::string CSuperSerialCard::GetSnapshotCardName(void) void CSuperSerialCard::SaveSnapshotDIPSW(YamlSaveHelper& yamlSaveHelper, std::string key, SSC_DIPSW& dipsw) { YamlSaveHelper::Label label(yamlSaveHelper, "%s:\n", key.c_str()); - yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_BAUDRATE, dipsw.uBaudRate); - yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_FWMODE, dipsw.eFirmwareMode); - yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_STOPBITS, dipsw.uStopBits); - yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_BYTESIZE, dipsw.uByteSize); - yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_PARITY, dipsw.uParity); - yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_LINEFEED, dipsw.bLinefeed); - yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_INTERRUPTS, dipsw.bInterrupts); + yamlSaveHelper.SaveUint(SS_YAML_KEY_BAUDRATE, dipsw.uBaudRate); + yamlSaveHelper.SaveUint(SS_YAML_KEY_FWMODE, dipsw.eFirmwareMode); + yamlSaveHelper.SaveUint(SS_YAML_KEY_STOPBITS, dipsw.uStopBits); + yamlSaveHelper.SaveUint(SS_YAML_KEY_BYTESIZE, dipsw.uByteSize); + yamlSaveHelper.SaveUint(SS_YAML_KEY_PARITY, dipsw.uParity); + yamlSaveHelper.SaveBool(SS_YAML_KEY_LINEFEED, dipsw.bLinefeed); + yamlSaveHelper.SaveBool(SS_YAML_KEY_INTERRUPTS, dipsw.bInterrupts); } void CSuperSerialCard::SaveSnapshot(YamlSaveHelper& yamlSaveHelper) @@ -1365,19 +1365,19 @@ void CSuperSerialCard::SaveSnapshot(YamlSaveHelper& yamlSaveHelper) YamlSaveHelper::Label unit(yamlSaveHelper, "%s:\n", SS_YAML_KEY_STATE); SaveSnapshotDIPSW(yamlSaveHelper, SS_YAML_KEY_DIPSWDEFAULT, m_DIPSWDefault); SaveSnapshotDIPSW(yamlSaveHelper, SS_YAML_KEY_DIPSWCURRENT, m_DIPSWCurrent); - yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_BAUDRATE, m_uBaudRate); - yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_STOPBITS, m_uStopBits); - yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_BYTESIZE, m_uByteSize); - yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_PARITY, m_uParity); - yamlSaveHelper.Save("%s: 0x%02X\n", SS_YAML_KEY_CONTROL, m_uControlByte); - yamlSaveHelper.Save("%s: 0x%02X\n", SS_YAML_KEY_COMMAND, m_uCommandByte); - yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_INACTIVITY, m_dwCommInactivity); - yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_TXIRQENABLED, m_bTxIrqEnabled); - yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_RXIRQENABLED, m_bRxIrqEnabled); - yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_TXIRQPENDING, m_vbTxIrqPending); - yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_RXIRQPENDING, m_vbRxIrqPending); - yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_WRITTENTX, m_bWrittenTx); - yamlSaveHelper.Save("%s: %s\n", SS_YAML_KEY_SERIALPORTNAME, yamlSaveHelper.GetSaveString(GetSerialPortName()).c_str()); + yamlSaveHelper.SaveUint(SS_YAML_KEY_BAUDRATE, m_uBaudRate); + yamlSaveHelper.SaveUint(SS_YAML_KEY_STOPBITS, m_uStopBits); + yamlSaveHelper.SaveUint(SS_YAML_KEY_BYTESIZE, m_uByteSize); + yamlSaveHelper.SaveUint(SS_YAML_KEY_PARITY, m_uParity); + yamlSaveHelper.SaveHex8(SS_YAML_KEY_CONTROL, m_uControlByte); + yamlSaveHelper.SaveHex8(SS_YAML_KEY_COMMAND, m_uCommandByte); + yamlSaveHelper.SaveUint(SS_YAML_KEY_INACTIVITY, m_dwCommInactivity); + yamlSaveHelper.SaveBool(SS_YAML_KEY_TXIRQENABLED, m_bTxIrqEnabled); + yamlSaveHelper.SaveBool(SS_YAML_KEY_RXIRQENABLED, m_bRxIrqEnabled); + yamlSaveHelper.SaveBool(SS_YAML_KEY_TXIRQPENDING, m_vbTxIrqPending); + yamlSaveHelper.SaveBool(SS_YAML_KEY_RXIRQPENDING, m_vbRxIrqPending); + yamlSaveHelper.SaveBool(SS_YAML_KEY_WRITTENTX, m_bWrittenTx); + yamlSaveHelper.SaveString(SS_YAML_KEY_SERIALPORTNAME, GetSerialPortName()); } void CSuperSerialCard::LoadSnapshotDIPSW(YamlLoadHelper& yamlLoadHelper, std::string key, SSC_DIPSW& dipsw) diff --git a/source/Speaker.cpp b/source/Speaker.cpp index 95189113..327c33d6 100644 --- a/source/Speaker.cpp +++ b/source/Speaker.cpp @@ -1111,7 +1111,7 @@ static std::string SpkrGetSnapshotStructName(void) void SpkrSaveSnapshot(YamlSaveHelper& yamlSaveHelper) { YamlSaveHelper::Label state(yamlSaveHelper, "%s:\n", SpkrGetSnapshotStructName().c_str()); - yamlSaveHelper.Save("%s: 0x%016llX\n", SS_YAML_KEY_LASTCYCLE, g_nSpkrLastCycle); + yamlSaveHelper.SaveHex64(SS_YAML_KEY_LASTCYCLE, g_nSpkrLastCycle); } void SpkrLoadSnapshot(YamlLoadHelper& yamlLoadHelper) diff --git a/source/Video.cpp b/source/Video.cpp index f8aaa0aa..f3ab19b7 100644 --- a/source/Video.cpp +++ b/source/Video.cpp @@ -2963,9 +2963,9 @@ static std::string VideoGetSnapshotStructName(void) void VideoSaveSnapshot(YamlSaveHelper& yamlSaveHelper) { YamlSaveHelper::Label state(yamlSaveHelper, "%s:\n", VideoGetSnapshotStructName().c_str()); - yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_ALTCHARSET, g_nAltCharSetOffset ? 1 : 0); - yamlSaveHelper.Save("%s: 0x%08X\n", SS_YAML_KEY_VIDEOMODE, g_uVideoMode); - yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_CYCLESTHISFRAME, g_dwCyclesThisFrame); + yamlSaveHelper.SaveUint(SS_YAML_KEY_ALTCHARSET, g_nAltCharSetOffset ? 1 : 0); + yamlSaveHelper.SaveHex32(SS_YAML_KEY_VIDEOMODE, g_uVideoMode); + yamlSaveHelper.SaveUint(SS_YAML_KEY_CYCLESTHISFRAME, g_dwCyclesThisFrame); } void VideoLoadSnapshot(YamlLoadHelper& yamlLoadHelper) diff --git a/source/YamlHelper.cpp b/source/YamlHelper.cpp index 672d371d..1b947d15 100644 --- a/source/YamlHelper.cpp +++ b/source/YamlHelper.cpp @@ -285,20 +285,70 @@ void YamlSaveHelper::Save(const char* format, ...) va_end(vl); } +void YamlSaveHelper::SaveInt(const char* key, int value) +{ + Save("%s: %d\n", key, value); +} + +void YamlSaveHelper::SaveUint(const char* key, UINT value) +{ + Save("%s: %u\n", key, value); +} + +void YamlSaveHelper::SaveHex4(const char* key, UINT value) +{ + Save("%s: 0x%01X\n", key, value); +} + +void YamlSaveHelper::SaveHex8(const char* key, UINT value) +{ + Save("%s: 0x%02X\n", key, value); +} + +void YamlSaveHelper::SaveHex12(const char* key, UINT value) +{ + Save("%s: 0x%03X\n", key, value); +} + +void YamlSaveHelper::SaveHex16(const char* key, UINT value) +{ + Save("%s: 0x%04X\n", key, value); +} + +void YamlSaveHelper::SaveHex32(const char* key, UINT value) +{ + Save("%s: 0x%08X\n", key, value); +} + +void YamlSaveHelper::SaveHex64(const char* key, UINT64 value) +{ + Save("%s: 0x%016llX\n", key, value); +} + +void YamlSaveHelper::SaveBool(const char* key, bool value) +{ + SaveUint(key, value ? 1 : 0); +} + +void YamlSaveHelper::SaveString(const char* key, const char* value) +{ + Save("%s: %s\n", key, (value[0] != 0) ? value : "\"\""); +} + void YamlSaveHelper::FileHdr(UINT version) { fprintf(m_hFile, "%s:\n", SS_YAML_KEY_FILEHDR); m_indent = 2; - Save("%s: %s\n", SS_YAML_KEY_TAG, SS_YAML_VALUE_AWSS); - Save("%s: %d\n", SS_YAML_KEY_VERSION, version); + SaveString(SS_YAML_KEY_TAG, SS_YAML_VALUE_AWSS); + SaveInt(SS_YAML_KEY_VERSION, version); } void YamlSaveHelper::UnitHdr(std::string type, UINT version) { fprintf(m_hFile, "\n%s:\n", SS_YAML_KEY_UNIT); m_indent = 2; - Save("%s: %s\n", SS_YAML_KEY_TYPE, type.c_str()); - Save("%s: %d\n", SS_YAML_KEY_VERSION, version); + SaveString(SS_YAML_KEY_TYPE, type.c_str()); + SaveInt(SS_YAML_KEY_VERSION, version); } void YamlSaveHelper::SaveMapValueMemory(const LPBYTE pMemBase, const UINT uMemSize) @@ -353,8 +403,3 @@ void YamlSaveHelper::SaveMapValueMemory(const LPBYTE pMemBase, const UINT uMemSi delete [] pLine; } - -std::string YamlSaveHelper::GetSaveString(const char* pValue) -{ - return (pValue[0] != 0) ? pValue : "\"\""; -} diff --git a/source/YamlHelper.h b/source/YamlHelper.h index 610ffd42..ce5752c0 100644 --- a/source/YamlHelper.h +++ b/source/YamlHelper.h @@ -259,6 +259,17 @@ public: void Save(const char* format, ...); + void SaveInt(const char* key, int value); + void SaveUint(const char* key, UINT value); + void SaveHex4(const char* key, UINT value); + void SaveHex8(const char* key, UINT value); + void SaveHex12(const char* key, UINT value); + void SaveHex16(const char* key, UINT value); + void SaveHex32(const char* key, UINT value); + void SaveHex64(const char* key, UINT64 value); + void SaveBool(const char* key, bool value); + void SaveString(const char* key, const char* value); + class Label { public: @@ -301,7 +312,6 @@ public: void FileHdr(UINT version); void UnitHdr(std::string type, UINT version); void SaveMapValueMemory(const LPBYTE pMemBase, const UINT uMemSize); - std::string GetSaveString(const char* pValue); private: FILE* m_hFile; diff --git a/source/Z80VICE/z80.cpp b/source/Z80VICE/z80.cpp index 3b43dc89..a91440ec 100644 --- a/source/Z80VICE/z80.cpp +++ b/source/Z80VICE/z80.cpp @@ -6491,33 +6491,33 @@ void Z80_SaveSnapshot(class YamlSaveHelper& yamlSaveHelper, const UINT uSlot) yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_ACTIVE, GetActiveCpu() == CPU_Z80 ? 1 : 0); - yamlSaveHelper.Save("%s: 0x%02X\n", SS_YAML_KEY_REGA, reg_a); - yamlSaveHelper.Save("%s: 0x%02X\n", SS_YAML_KEY_REGB, reg_b); - yamlSaveHelper.Save("%s: 0x%02X\n", SS_YAML_KEY_REGC, reg_c); - yamlSaveHelper.Save("%s: 0x%02X\n", SS_YAML_KEY_REGD, reg_d); - yamlSaveHelper.Save("%s: 0x%02X\n", SS_YAML_KEY_REGE, reg_e); - yamlSaveHelper.Save("%s: 0x%02X\n", SS_YAML_KEY_REGF, reg_f); - yamlSaveHelper.Save("%s: 0x%02X\n", SS_YAML_KEY_REGH, reg_h); - yamlSaveHelper.Save("%s: 0x%02X\n", SS_YAML_KEY_REGL, reg_l); - yamlSaveHelper.Save("%s: 0x%04X\n", SS_YAML_KEY_REGIX, ((USHORT)reg_ixh<<8)|(USHORT)reg_ixl); - yamlSaveHelper.Save("%s: 0x%04X\n", SS_YAML_KEY_REGIY, ((USHORT)reg_iyh<<8)|(USHORT)reg_iyl); - yamlSaveHelper.Save("%s: 0x%04X\n", SS_YAML_KEY_REGSP, reg_sp); - yamlSaveHelper.Save("%s: 0x%04X\n", SS_YAML_KEY_REGPC, (USHORT)z80_reg_pc); - yamlSaveHelper.Save("%s: 0x%02X\n", SS_YAML_KEY_REGI, reg_i); - yamlSaveHelper.Save("%s: 0x%02X\n", SS_YAML_KEY_REGR, reg_r); + yamlSaveHelper.SaveHex8(SS_YAML_KEY_REGA, reg_a); + yamlSaveHelper.SaveHex8(SS_YAML_KEY_REGB, reg_b); + yamlSaveHelper.SaveHex8(SS_YAML_KEY_REGC, reg_c); + yamlSaveHelper.SaveHex8(SS_YAML_KEY_REGD, reg_d); + yamlSaveHelper.SaveHex8(SS_YAML_KEY_REGE, reg_e); + yamlSaveHelper.SaveHex8(SS_YAML_KEY_REGF, reg_f); + yamlSaveHelper.SaveHex8(SS_YAML_KEY_REGH, reg_h); + yamlSaveHelper.SaveHex8(SS_YAML_KEY_REGL, reg_l); + yamlSaveHelper.SaveHex16(SS_YAML_KEY_REGIX, ((USHORT)reg_ixh<<8)|(USHORT)reg_ixl); + yamlSaveHelper.SaveHex16(SS_YAML_KEY_REGIY, ((USHORT)reg_iyh<<8)|(USHORT)reg_iyl); + yamlSaveHelper.SaveHex16(SS_YAML_KEY_REGSP, reg_sp); + yamlSaveHelper.SaveHex16(SS_YAML_KEY_REGPC, (USHORT)z80_reg_pc); + yamlSaveHelper.SaveHex8(SS_YAML_KEY_REGI, reg_i); + yamlSaveHelper.SaveHex8(SS_YAML_KEY_REGR, reg_r); - yamlSaveHelper.Save("%s: 0x%02X\n", SS_YAML_KEY_IFF1, iff1); - yamlSaveHelper.Save("%s: 0x%02X\n", SS_YAML_KEY_IFF2, iff2); - yamlSaveHelper.Save("%s: 0x%02X\n", SS_YAML_KEY_IM_MODE, im_mode); + yamlSaveHelper.SaveHex8(SS_YAML_KEY_IFF1, iff1); + yamlSaveHelper.SaveHex8(SS_YAML_KEY_IFF2, iff2); + yamlSaveHelper.SaveHex8(SS_YAML_KEY_IM_MODE, im_mode); - yamlSaveHelper.Save("%s: 0x%02X\n", SS_YAML_KEY_REGA2, reg_a2); - yamlSaveHelper.Save("%s: 0x%02X\n", SS_YAML_KEY_REGB2, reg_b2); - yamlSaveHelper.Save("%s: 0x%02X\n", SS_YAML_KEY_REGC2, reg_c2); - yamlSaveHelper.Save("%s: 0x%02X\n", SS_YAML_KEY_REGD2, reg_d2); - yamlSaveHelper.Save("%s: 0x%02X\n", SS_YAML_KEY_REGE2, reg_e2); - yamlSaveHelper.Save("%s: 0x%02X\n", SS_YAML_KEY_REGF2, reg_f2); - yamlSaveHelper.Save("%s: 0x%02X\n", SS_YAML_KEY_REGH2, reg_h2); - yamlSaveHelper.Save("%s: 0x%02X\n", SS_YAML_KEY_REGL2, reg_l2); + yamlSaveHelper.SaveHex8(SS_YAML_KEY_REGA2, reg_a2); + yamlSaveHelper.SaveHex8(SS_YAML_KEY_REGB2, reg_b2); + yamlSaveHelper.SaveHex8(SS_YAML_KEY_REGC2, reg_c2); + yamlSaveHelper.SaveHex8(SS_YAML_KEY_REGD2, reg_d2); + yamlSaveHelper.SaveHex8(SS_YAML_KEY_REGE2, reg_e2); + yamlSaveHelper.SaveHex8(SS_YAML_KEY_REGF2, reg_f2); + yamlSaveHelper.SaveHex8(SS_YAML_KEY_REGH2, reg_h2); + yamlSaveHelper.SaveHex8(SS_YAML_KEY_REGL2, reg_l2); } bool Z80_LoadSnapshot(class YamlLoadHelper& yamlLoadHelper, UINT uSlot, UINT version) From 11789c90235386b4887556697f30d72011f2aab2 Mon Sep 17 00:00:00 2001 From: tomcw Date: Wed, 24 Feb 2016 22:38:59 +0000 Subject: [PATCH 16/20] Save-state: Renamed YamlLoadHelper load-type functions to be more consistent with YamlSaveHelper functions --- source/AY8910.cpp | 68 +++++++++++++++++------------------ source/CPU.cpp | 16 ++++----- source/Disk.cpp | 36 +++++++++---------- source/Harddisk.cpp | 22 ++++++------ source/Joystick.cpp | 10 +++--- source/Keyboard.cpp | 2 +- source/Memory.cpp | 22 ++++++------ source/Mockingboard.cpp | 58 +++++++++++++++--------------- source/MouseInterface.cpp | 58 +++++++++++++++--------------- source/ParallelPrinter.cpp | 20 +++++------ source/SaveState.cpp | 14 ++++---- source/SerialComms.cpp | 40 ++++++++++----------- source/Speaker.cpp | 2 +- source/Video.cpp | 6 ++-- source/YamlHelper.cpp | 68 ++++++++++++++++++++++++++++++++++- source/YamlHelper.h | 72 +++++--------------------------------- source/Z80VICE/z80.cpp | 52 +++++++++++++-------------- 17 files changed, 288 insertions(+), 278 deletions(-) diff --git a/source/AY8910.cpp b/source/AY8910.cpp index fc4328ac..bc41cfe5 100644 --- a/source/AY8910.cpp +++ b/source/AY8910.cpp @@ -1053,51 +1053,51 @@ bool CAY8910::LoadSnapshot(YamlLoadHelper& yamlLoadHelper, std::string& suffix) if (!yamlLoadHelper.GetSubMap(unit)) throw std::string("Card: Expected key: ") + unit; - ay_tone_tick[0] = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_TONE0_TICK); - ay_tone_tick[1] = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_TONE1_TICK); - ay_tone_tick[2] = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_TONE2_TICK); - ay_tone_high[0] = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_TONE0_HIGH); - ay_tone_high[1] = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_TONE1_HIGH); - ay_tone_high[2] = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_TONE2_HIGH); - ay_noise_tick = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_NOISE_TICK); - ay_tone_subcycles = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_TONE_SUBCYCLES); - ay_env_subcycles = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_ENV_SUBCYCLES); - ay_env_internal_tick = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_ENV_INTERNAL_TICK); - ay_env_tick = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_ENV_TICK); - ay_tick_incr = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_TICK_INCR); - ay_tone_period[0] = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_TONE0_PERIOD); - ay_tone_period[1] = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_TONE1_PERIOD); - ay_tone_period[2] = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_TONE2_PERIOD); - ay_noise_period = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_NOISE_PERIOD); - rng = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_RNG); - noise_toggle = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_NOISE_TOGGLE); - env_first = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_ENV_FIRST); - env_rev = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_ENV_REV); - env_counter = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_ENV_COUNTER); + ay_tone_tick[0] = yamlLoadHelper.LoadUint(SS_YAML_KEY_TONE0_TICK); + ay_tone_tick[1] = yamlLoadHelper.LoadUint(SS_YAML_KEY_TONE1_TICK); + ay_tone_tick[2] = yamlLoadHelper.LoadUint(SS_YAML_KEY_TONE2_TICK); + ay_tone_high[0] = yamlLoadHelper.LoadUint(SS_YAML_KEY_TONE0_HIGH); + ay_tone_high[1] = yamlLoadHelper.LoadUint(SS_YAML_KEY_TONE1_HIGH); + ay_tone_high[2] = yamlLoadHelper.LoadUint(SS_YAML_KEY_TONE2_HIGH); + ay_noise_tick = yamlLoadHelper.LoadUint(SS_YAML_KEY_NOISE_TICK); + ay_tone_subcycles = yamlLoadHelper.LoadUint(SS_YAML_KEY_TONE_SUBCYCLES); + ay_env_subcycles = yamlLoadHelper.LoadUint(SS_YAML_KEY_ENV_SUBCYCLES); + ay_env_internal_tick = yamlLoadHelper.LoadUint(SS_YAML_KEY_ENV_INTERNAL_TICK); + ay_env_tick = yamlLoadHelper.LoadUint(SS_YAML_KEY_ENV_TICK); + ay_tick_incr = yamlLoadHelper.LoadUint(SS_YAML_KEY_TICK_INCR); + ay_tone_period[0] = yamlLoadHelper.LoadUint(SS_YAML_KEY_TONE0_PERIOD); + ay_tone_period[1] = yamlLoadHelper.LoadUint(SS_YAML_KEY_TONE1_PERIOD); + ay_tone_period[2] = yamlLoadHelper.LoadUint(SS_YAML_KEY_TONE2_PERIOD); + ay_noise_period = yamlLoadHelper.LoadUint(SS_YAML_KEY_NOISE_PERIOD); + rng = yamlLoadHelper.LoadUint(SS_YAML_KEY_RNG); + noise_toggle = yamlLoadHelper.LoadUint(SS_YAML_KEY_NOISE_TOGGLE); + env_first = yamlLoadHelper.LoadUint(SS_YAML_KEY_ENV_FIRST); + env_rev = yamlLoadHelper.LoadUint(SS_YAML_KEY_ENV_REV); + env_counter = yamlLoadHelper.LoadUint(SS_YAML_KEY_ENV_COUNTER); if (!yamlLoadHelper.GetSubMap(SS_YAML_KEY_REGISTERS)) throw std::string("Card: Expected key: ") + SS_YAML_KEY_REGISTERS; - USHORT period = (USHORT) yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_REG_TONE0_PERIOD); + USHORT period = (USHORT) yamlLoadHelper.LoadUint(SS_YAML_KEY_REG_TONE0_PERIOD); sound_ay_registers[0] = period & 0xff; sound_ay_registers[1] = (period >> 8) & 0xf; - period = (USHORT) yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_REG_TONE1_PERIOD); + period = (USHORT) yamlLoadHelper.LoadUint(SS_YAML_KEY_REG_TONE1_PERIOD); sound_ay_registers[2] = period & 0xff; sound_ay_registers[3] = (period >> 8) & 0xf; - period = (USHORT) yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_REG_TONE2_PERIOD); + period = (USHORT) yamlLoadHelper.LoadUint(SS_YAML_KEY_REG_TONE2_PERIOD); sound_ay_registers[4] = period & 0xff; sound_ay_registers[5] = (period >> 8) & 0xf; - sound_ay_registers[6] = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_REG_NOISE_PERIOD); - sound_ay_registers[7] = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_REG_MIXER); - sound_ay_registers[8] = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_REG_VOL0); - sound_ay_registers[9] = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_REG_VOL1); - sound_ay_registers[10] = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_REG_VOL2); - period = (USHORT) yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_REG_ENV_PERIOD); + sound_ay_registers[6] = yamlLoadHelper.LoadUint(SS_YAML_KEY_REG_NOISE_PERIOD); + sound_ay_registers[7] = yamlLoadHelper.LoadUint(SS_YAML_KEY_REG_MIXER); + sound_ay_registers[8] = yamlLoadHelper.LoadUint(SS_YAML_KEY_REG_VOL0); + sound_ay_registers[9] = yamlLoadHelper.LoadUint(SS_YAML_KEY_REG_VOL1); + sound_ay_registers[10] = yamlLoadHelper.LoadUint(SS_YAML_KEY_REG_VOL2); + period = (USHORT) yamlLoadHelper.LoadUint(SS_YAML_KEY_REG_ENV_PERIOD); sound_ay_registers[11] = period & 0xff; sound_ay_registers[12] = period >> 8; - sound_ay_registers[13] = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_REG_ENV_SHAPE); - sound_ay_registers[14] = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_REG_PORTA); - sound_ay_registers[15] = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_REG_PORTB); + sound_ay_registers[13] = yamlLoadHelper.LoadUint(SS_YAML_KEY_REG_ENV_SHAPE); + sound_ay_registers[14] = yamlLoadHelper.LoadUint(SS_YAML_KEY_REG_PORTA); + sound_ay_registers[15] = yamlLoadHelper.LoadUint(SS_YAML_KEY_REG_PORTB); yamlLoadHelper.PopMap(); @@ -1110,7 +1110,7 @@ bool CAY8910::LoadSnapshot(YamlLoadHelper& yamlLoadHelper, std::string& suffix) sprintf_s(szIndex, sizeof(szIndex), "0x%04X", ay_change_count); bool bFound; - std::string value = yamlLoadHelper.GetMapValueSTRING_NoThrow(szIndex, bFound); + std::string value = yamlLoadHelper.LoadString_NoThrow(szIndex, bFound); if (!bFound) break; // done diff --git a/source/CPU.cpp b/source/CPU.cpp index 9422d378..c0cfed32 100644 --- a/source/CPU.cpp +++ b/source/CPU.cpp @@ -744,23 +744,23 @@ void CpuLoadSnapshot(YamlLoadHelper& yamlLoadHelper) if (!yamlLoadHelper.GetSubMap(CpuGetSnapshotStructName())) return; - std::string cpuType = yamlLoadHelper.GetMapValueSTRING(SS_YAML_KEY_CPU_TYPE); + std::string cpuType = yamlLoadHelper.LoadString(SS_YAML_KEY_CPU_TYPE); eCpuType cpu; if (cpuType == SS_YAML_VALUE_6502) cpu = CPU_6502; else if (cpuType == SS_YAML_VALUE_65C02) cpu = CPU_65C02; else throw std::string("Load: Unknown main CPU type"); SetMainCpu(cpu); - regs.a = (BYTE) yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_REGA); - regs.x = (BYTE) yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_REGX); - regs.y = (BYTE) yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_REGY); - regs.ps = (BYTE) yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_REGP) | (AF_RESERVED | AF_BREAK); - regs.sp = (USHORT) ((yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_REGS) & 0xff) | 0x100); - regs.pc = (USHORT) yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_REGPC); + regs.a = (BYTE) yamlLoadHelper.LoadUint(SS_YAML_KEY_REGA); + regs.x = (BYTE) yamlLoadHelper.LoadUint(SS_YAML_KEY_REGX); + regs.y = (BYTE) yamlLoadHelper.LoadUint(SS_YAML_KEY_REGY); + regs.ps = (BYTE) yamlLoadHelper.LoadUint(SS_YAML_KEY_REGP) | (AF_RESERVED | AF_BREAK); + regs.sp = (USHORT) ((yamlLoadHelper.LoadUint(SS_YAML_KEY_REGS) & 0xff) | 0x100); + regs.pc = (USHORT) yamlLoadHelper.LoadUint(SS_YAML_KEY_REGPC); CpuIrqReset(); CpuNmiReset(); - g_nCumulativeCycles = yamlLoadHelper.GetMapValueUINT64(SS_YAML_KEY_CUMULATIVECYCLES); + g_nCumulativeCycles = yamlLoadHelper.LoadUint64(SS_YAML_KEY_CUMULATIVECYCLES); yamlLoadHelper.PopMap(); } diff --git a/source/Disk.cpp b/source/Disk.cpp index 7d2a49f5..8c7cef97 100644 --- a/source/Disk.cpp +++ b/source/Disk.cpp @@ -1249,7 +1249,7 @@ static void DiskLoadSnapshotDriveUnit(YamlLoadHelper& yamlLoadHelper, UINT unit) g_aFloppyDisk[unit].imagename[0] = 0; g_aFloppyDisk[unit].bWriteProtected = false; // Default to false (until image is successfully loaded below) - std::string filename = yamlLoadHelper.GetMapValueSTRING(SS_YAML_KEY_FILENAME).c_str(); + std::string filename = yamlLoadHelper.LoadString(SS_YAML_KEY_FILENAME); if (!filename.empty()) { DWORD dwAttributes = GetFileAttributes(filename.c_str()); @@ -1274,21 +1274,21 @@ static void DiskLoadSnapshotDriveUnit(YamlLoadHelper& yamlLoadHelper, UINT unit) } } - g_aFloppyDisk[unit].track = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_TRACK); - g_aFloppyDisk[unit].phase = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_PHASE); - g_aFloppyDisk[unit].byte = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_BYTE); - yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_WRITE_PROTECTED); // Consume - g_aFloppyDisk[unit].spinning = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_SPINNING); - g_aFloppyDisk[unit].writelight = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_WRITE_LIGHT); - g_aFloppyDisk[unit].nibbles = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_NIBBLES); - g_aFloppyDisk[unit].trackimagedata = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_TRACK_IMAGE_DATA); - g_aFloppyDisk[unit].trackimagedirty = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_TRACK_IMAGE_DIRTY); + g_aFloppyDisk[unit].track = yamlLoadHelper.LoadUint(SS_YAML_KEY_TRACK); + g_aFloppyDisk[unit].phase = yamlLoadHelper.LoadUint(SS_YAML_KEY_PHASE); + g_aFloppyDisk[unit].byte = yamlLoadHelper.LoadUint(SS_YAML_KEY_BYTE); + yamlLoadHelper.LoadUint(SS_YAML_KEY_WRITE_PROTECTED); // Consume + g_aFloppyDisk[unit].spinning = yamlLoadHelper.LoadUint(SS_YAML_KEY_SPINNING); + g_aFloppyDisk[unit].writelight = yamlLoadHelper.LoadUint(SS_YAML_KEY_WRITE_LIGHT); + g_aFloppyDisk[unit].nibbles = yamlLoadHelper.LoadUint(SS_YAML_KEY_NIBBLES); + g_aFloppyDisk[unit].trackimagedata = yamlLoadHelper.LoadUint(SS_YAML_KEY_TRACK_IMAGE_DATA); + g_aFloppyDisk[unit].trackimagedirty = yamlLoadHelper.LoadUint(SS_YAML_KEY_TRACK_IMAGE_DIRTY); std::auto_ptr pTrack( new BYTE [NIBBLES_PER_TRACK] ); memset(pTrack.get(), 0, NIBBLES_PER_TRACK); if (yamlLoadHelper.GetSubMap(SS_YAML_KEY_TRACK_IMAGE)) { - yamlLoadHelper.GetMapValueMemory(pTrack.get(), NIBBLES_PER_TRACK); + yamlLoadHelper.LoadMemory(pTrack.get(), NIBBLES_PER_TRACK); yamlLoadHelper.PopMap(); } @@ -1323,13 +1323,13 @@ bool DiskLoadSnapshot(class YamlLoadHelper& yamlLoadHelper, UINT slot, UINT vers if (version != 1) throw std::string("Card: wrong version"); - phases = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_PHASES); - currdrive = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_CURRENT_DRIVE); - diskaccessed = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_DISK_ACCESSED); - enhancedisk = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_ENHANCE_DISK); - floppylatch = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_FLOPPY_LATCH); - floppymotoron = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_FLOPPY_MOTOR_ON); - floppywritemode = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_FLOPPY_WRITE_MODE); + phases = yamlLoadHelper.LoadUint(SS_YAML_KEY_PHASES); + currdrive = yamlLoadHelper.LoadUint(SS_YAML_KEY_CURRENT_DRIVE); + diskaccessed = yamlLoadHelper.LoadUint(SS_YAML_KEY_DISK_ACCESSED); + enhancedisk = yamlLoadHelper.LoadUint(SS_YAML_KEY_ENHANCE_DISK); + floppylatch = yamlLoadHelper.LoadUint(SS_YAML_KEY_FLOPPY_LATCH); + floppymotoron = yamlLoadHelper.LoadUint(SS_YAML_KEY_FLOPPY_MOTOR_ON); + floppywritemode = yamlLoadHelper.LoadUint(SS_YAML_KEY_FLOPPY_WRITE_MODE); // Eject all disks first in case Drive-2 contains disk to be inserted into Drive-1 for(UINT i=0; iSpeechChip); - pMB->nAYCurrentRegister = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_AY_CURR_REG); - yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_TIMER1_IRQ); // Consume - yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_TIMER2_IRQ); // Consume - yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_SPEECH_IRQ); // Consume + pMB->nAYCurrentRegister = yamlLoadHelper.LoadUint(SS_YAML_KEY_AY_CURR_REG); + yamlLoadHelper.LoadUint(SS_YAML_KEY_TIMER1_IRQ); // Consume + yamlLoadHelper.LoadUint(SS_YAML_KEY_TIMER2_IRQ); // Consume + yamlLoadHelper.LoadUint(SS_YAML_KEY_SPEECH_IRQ); // Consume yamlLoadHelper.PopMap(); @@ -2144,8 +2144,8 @@ bool Phasor_LoadSnapshot(YamlLoadHelper& yamlLoadHelper, UINT slot, UINT version if (version != 1) throw std::string("Card: wrong version"); - g_PhasorClockScaleFactor = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_PHASOR_CLOCK_SCALE_FACTOR); - g_nPhasorMode = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_PHASOR_MODE); + g_PhasorClockScaleFactor = yamlLoadHelper.LoadUint(SS_YAML_KEY_PHASOR_CLOCK_SCALE_FACTOR); + g_nPhasorMode = yamlLoadHelper.LoadUint(SS_YAML_KEY_PHASOR_MODE); AY8910UpdateSetCycles(); @@ -2167,10 +2167,10 @@ bool Phasor_LoadSnapshot(YamlLoadHelper& yamlLoadHelper, UINT slot, UINT version AY8910_LoadSnapshot(yamlLoadHelper, nDeviceNum+1, std::string("-B")); LoadSnapshotSSI263(yamlLoadHelper, pMB->SpeechChip); - pMB->nAYCurrentRegister = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_AY_CURR_REG); - yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_TIMER1_IRQ); // Consume - yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_TIMER2_IRQ); // Consume - yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_SPEECH_IRQ); // Consume + pMB->nAYCurrentRegister = yamlLoadHelper.LoadUint(SS_YAML_KEY_AY_CURR_REG); + yamlLoadHelper.LoadUint(SS_YAML_KEY_TIMER1_IRQ); // Consume + yamlLoadHelper.LoadUint(SS_YAML_KEY_TIMER2_IRQ); // Consume + yamlLoadHelper.LoadUint(SS_YAML_KEY_SPEECH_IRQ); // Consume yamlLoadHelper.PopMap(); diff --git a/source/MouseInterface.cpp b/source/MouseInterface.cpp index 5c33d03d..009f8494 100644 --- a/source/MouseInterface.cpp +++ b/source/MouseInterface.cpp @@ -700,15 +700,15 @@ void CMouseInterface::LoadSnapshotMC6821(YamlLoadHelper& yamlLoadHelper, std::st throw std::string("Card: Expected key: ") + key; mc6821_t mc6821; - mc6821.pra = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_PRA); - mc6821.ddra = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_DDRA); - mc6821.cra = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_CRA); - mc6821.prb = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_PRB); - mc6821.ddrb = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_DDRB); - mc6821.crb = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_CRB); + mc6821.pra = yamlLoadHelper.LoadUint(SS_YAML_KEY_PRA); + mc6821.ddra = yamlLoadHelper.LoadUint(SS_YAML_KEY_DDRA); + mc6821.cra = yamlLoadHelper.LoadUint(SS_YAML_KEY_CRA); + mc6821.prb = yamlLoadHelper.LoadUint(SS_YAML_KEY_PRB); + mc6821.ddrb = yamlLoadHelper.LoadUint(SS_YAML_KEY_DDRB); + mc6821.crb = yamlLoadHelper.LoadUint(SS_YAML_KEY_CRB); - BYTE byIA = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_IA); - BYTE byIB = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_IB); + BYTE byIA = yamlLoadHelper.LoadUint(SS_YAML_KEY_IA); + BYTE byIB = yamlLoadHelper.LoadUint(SS_YAML_KEY_IB); m_6821.Set6821(mc6821, byIA, byIB); @@ -725,32 +725,32 @@ bool CMouseInterface::LoadSnapshot(class YamlLoadHelper& yamlLoadHelper, UINT sl LoadSnapshotMC6821(yamlLoadHelper, SS_YAML_KEY_MC6821); - m_nDataLen = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_DATALEN); - m_byMode = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_MODE); - m_by6821B = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_6821B); - m_by6821A = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_6821A); + m_nDataLen = yamlLoadHelper.LoadUint(SS_YAML_KEY_DATALEN); + m_byMode = yamlLoadHelper.LoadUint(SS_YAML_KEY_MODE); + m_by6821B = yamlLoadHelper.LoadUint(SS_YAML_KEY_6821B); + m_by6821A = yamlLoadHelper.LoadUint(SS_YAML_KEY_6821A); if (!yamlLoadHelper.GetSubMap(SS_YAML_KEY_BUFF)) throw std::string("Card: Expected key: "SS_YAML_KEY_BUFF); - yamlLoadHelper.GetMapValueMemory(m_byBuff, sizeof(m_byBuff)); + yamlLoadHelper.LoadMemory(m_byBuff, sizeof(m_byBuff)); yamlLoadHelper.PopMap(); - m_nBuffPos = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_BUFFPOS); - m_byState = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_MOUSESTATE); - m_nX = yamlLoadHelper.GetMapValueINT(SS_YAML_KEY_X); - m_nY = yamlLoadHelper.GetMapValueINT(SS_YAML_KEY_Y); - m_bBtn0 = yamlLoadHelper.GetMapValueBool(SS_YAML_KEY_BTN0); - m_bBtn1 = yamlLoadHelper.GetMapValueBool(SS_YAML_KEY_BTN1); - m_bVBL = yamlLoadHelper.GetMapValueBool(SS_YAML_KEY_VBL); - m_iX = yamlLoadHelper.GetMapValueINT(SS_YAML_KEY_IX); - m_iMinX = yamlLoadHelper.GetMapValueINT(SS_YAML_KEY_IMINX); - m_iMaxX = yamlLoadHelper.GetMapValueINT(SS_YAML_KEY_IMAXX); - m_iY = yamlLoadHelper.GetMapValueINT(SS_YAML_KEY_IY); - m_iMinY = yamlLoadHelper.GetMapValueINT(SS_YAML_KEY_IMINY); - m_iMaxY = yamlLoadHelper.GetMapValueINT(SS_YAML_KEY_IMAXY); - m_bButtons[0] = yamlLoadHelper.GetMapValueBool(SS_YAML_KEY_BUTTON0); - m_bButtons[1] = yamlLoadHelper.GetMapValueBool(SS_YAML_KEY_BUTTON1); - m_bEnabled = yamlLoadHelper.GetMapValueBool(SS_YAML_KEY_ENABLED); // MemInitializeIO() calls Initialize() which sets true + m_nBuffPos = yamlLoadHelper.LoadUint(SS_YAML_KEY_BUFFPOS); + m_byState = yamlLoadHelper.LoadUint(SS_YAML_KEY_MOUSESTATE); + m_nX = yamlLoadHelper.LoadInt(SS_YAML_KEY_X); + m_nY = yamlLoadHelper.LoadInt(SS_YAML_KEY_Y); + m_bBtn0 = yamlLoadHelper.LoadBool(SS_YAML_KEY_BTN0); + m_bBtn1 = yamlLoadHelper.LoadBool(SS_YAML_KEY_BTN1); + m_bVBL = yamlLoadHelper.LoadBool(SS_YAML_KEY_VBL); + m_iX = yamlLoadHelper.LoadInt(SS_YAML_KEY_IX); + m_iMinX = yamlLoadHelper.LoadInt(SS_YAML_KEY_IMINX); + m_iMaxX = yamlLoadHelper.LoadInt(SS_YAML_KEY_IMAXX); + m_iY = yamlLoadHelper.LoadInt(SS_YAML_KEY_IY); + m_iMinY = yamlLoadHelper.LoadInt(SS_YAML_KEY_IMINY); + m_iMaxY = yamlLoadHelper.LoadInt(SS_YAML_KEY_IMAXY); + m_bButtons[0] = yamlLoadHelper.LoadBool(SS_YAML_KEY_BUTTON0); + m_bButtons[1] = yamlLoadHelper.LoadBool(SS_YAML_KEY_BUTTON1); + m_bEnabled = yamlLoadHelper.LoadBool(SS_YAML_KEY_ENABLED); // MemInitializeIO() calls Initialize() which sets true return true; } diff --git a/source/ParallelPrinter.cpp b/source/ParallelPrinter.cpp index 0dcf5846..f295c958 100644 --- a/source/ParallelPrinter.cpp +++ b/source/ParallelPrinter.cpp @@ -298,13 +298,13 @@ bool Printer_LoadSnapshot(class YamlLoadHelper& yamlLoadHelper, UINT slot, UINT if (version != 1) throw std::string("Card: wrong version"); - inactivity = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_INACTIVITY); - g_PrinterIdleLimit = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_IDLELIMIT); - strncpy(g_szPrintFilename, yamlLoadHelper.GetMapValueSTRING(SS_YAML_KEY_FILENAME).c_str(), sizeof(g_szPrintFilename)); + inactivity = yamlLoadHelper.LoadUint(SS_YAML_KEY_INACTIVITY); + g_PrinterIdleLimit = yamlLoadHelper.LoadUint(SS_YAML_KEY_IDLELIMIT); + strncpy(g_szPrintFilename, yamlLoadHelper.LoadString(SS_YAML_KEY_FILENAME).c_str(), sizeof(g_szPrintFilename)); - if (yamlLoadHelper.GetMapValueBool(SS_YAML_KEY_FILEOPEN)) + if (yamlLoadHelper.LoadBool(SS_YAML_KEY_FILEOPEN)) { - yamlLoadHelper.GetMapValueBool(SS_YAML_KEY_APPEND); // Consume + yamlLoadHelper.LoadBool(SS_YAML_KEY_APPEND); // Consume g_bPrinterAppend = true; // Re-open print-file in append mode BOOL bRes = CheckPrint(); if (!bRes) @@ -312,13 +312,13 @@ bool Printer_LoadSnapshot(class YamlLoadHelper& yamlLoadHelper, UINT slot, UINT } else { - g_bPrinterAppend = yamlLoadHelper.GetMapValueBool(SS_YAML_KEY_APPEND); + g_bPrinterAppend = yamlLoadHelper.LoadBool(SS_YAML_KEY_APPEND); } - g_bDumpToPrinter = yamlLoadHelper.GetMapValueBool(SS_YAML_KEY_DUMPTOPRINTER); - g_bConvertEncoding = yamlLoadHelper.GetMapValueBool(SS_YAML_KEY_CONVERTENCODING); - g_bFilterUnprintable = yamlLoadHelper.GetMapValueBool(SS_YAML_KEY_FILTERUNPRINTABLE); - g_bEnableDumpToRealPrinter = yamlLoadHelper.GetMapValueBool(SS_YAML_KEY_DUMPTOREALPRINTER); + g_bDumpToPrinter = yamlLoadHelper.LoadBool(SS_YAML_KEY_DUMPTOPRINTER); + g_bConvertEncoding = yamlLoadHelper.LoadBool(SS_YAML_KEY_CONVERTENCODING); + g_bFilterUnprintable = yamlLoadHelper.LoadBool(SS_YAML_KEY_FILTERUNPRINTABLE); + g_bEnableDumpToRealPrinter = yamlLoadHelper.LoadBool(SS_YAML_KEY_DUMPTOREALPRINTER); return true; } diff --git a/source/SaveState.cpp b/source/SaveState.cpp index 2dd77a3b..3a771cd8 100644 --- a/source/SaveState.cpp +++ b/source/SaveState.cpp @@ -300,14 +300,14 @@ static UINT ParseFileHdr(void) // - std::string value = yamlLoadHelper.GetMapValueSTRING(SS_YAML_KEY_TAG); + std::string value = yamlLoadHelper.LoadString(SS_YAML_KEY_TAG); if (value != SS_YAML_VALUE_AWSS) { //printf("%s: Bad tag (%s) - expected %s\n", SS_YAML_KEY_FILEHDR, value.c_str(), SS_YAML_VALUE_AWSS); throw std::string(SS_YAML_KEY_FILEHDR ": Bad tag"); } - return yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_VERSION); + return yamlLoadHelper.LoadUint(SS_YAML_KEY_VERSION); } //--- @@ -317,7 +317,7 @@ static void ParseUnitApple2(YamlLoadHelper& yamlLoadHelper, UINT version) if (version != UNIT_APPLE2_VER) throw std::string(SS_YAML_KEY_UNIT ": Apple2: Version mismatch"); - std::string model = yamlLoadHelper.GetMapValueSTRING(SS_YAML_KEY_MODEL); + std::string model = yamlLoadHelper.LoadString(SS_YAML_KEY_MODEL); SetApple2Type( ParseApple2Type(model) ); // NB. Sets default main CPU type m_ConfigNew.m_Apple2Type = GetApple2Type(); @@ -350,8 +350,8 @@ static void ParseSlots(YamlLoadHelper& yamlLoadHelper, UINT version) yamlLoadHelper.GetSubMap(scalar); - std::string card = yamlLoadHelper.GetMapValueSTRING(SS_YAML_KEY_CARD); - UINT version = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_VERSION); + std::string card = yamlLoadHelper.LoadString(SS_YAML_KEY_CARD); + UINT version = yamlLoadHelper.LoadUint(SS_YAML_KEY_VERSION); if (!yamlLoadHelper.GetSubMap(std::string(SS_YAML_KEY_STATE))) throw std::string(SS_YAML_KEY_UNIT ": Expected sub-map name: " SS_YAML_KEY_STATE); @@ -425,8 +425,8 @@ static void ParseUnit(void) YamlLoadHelper yamlLoadHelper(yamlHelper); - std::string unit = yamlLoadHelper.GetMapValueSTRING(SS_YAML_KEY_TYPE); - UINT version = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_VERSION); + std::string unit = yamlLoadHelper.LoadString(SS_YAML_KEY_TYPE); + UINT version = yamlLoadHelper.LoadUint(SS_YAML_KEY_VERSION); if (!yamlLoadHelper.GetSubMap(std::string(SS_YAML_KEY_STATE))) throw std::string(SS_YAML_KEY_UNIT ": Expected sub-map name: " SS_YAML_KEY_STATE); diff --git a/source/SerialComms.cpp b/source/SerialComms.cpp index 4e4e8a87..83660262 100644 --- a/source/SerialComms.cpp +++ b/source/SerialComms.cpp @@ -1385,13 +1385,13 @@ void CSuperSerialCard::LoadSnapshotDIPSW(YamlLoadHelper& yamlLoadHelper, std::st if (!yamlLoadHelper.GetSubMap(key)) throw std::string("Card: Expected key: " + key); - dipsw.uBaudRate = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_BAUDRATE); - dipsw.eFirmwareMode = (eFWMODE) yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_FWMODE); - dipsw.uStopBits = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_STOPBITS); - dipsw.uByteSize = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_BYTESIZE); - dipsw.uParity = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_PARITY); - dipsw.bLinefeed = yamlLoadHelper.GetMapValueBool(SS_YAML_KEY_LINEFEED); - dipsw.bInterrupts = yamlLoadHelper.GetMapValueBool(SS_YAML_KEY_INTERRUPTS); + dipsw.uBaudRate = yamlLoadHelper.LoadUint(SS_YAML_KEY_BAUDRATE); + dipsw.eFirmwareMode = (eFWMODE) yamlLoadHelper.LoadUint(SS_YAML_KEY_FWMODE); + dipsw.uStopBits = yamlLoadHelper.LoadUint(SS_YAML_KEY_STOPBITS); + dipsw.uByteSize = yamlLoadHelper.LoadUint(SS_YAML_KEY_BYTESIZE); + dipsw.uParity = yamlLoadHelper.LoadUint(SS_YAML_KEY_PARITY); + dipsw.bLinefeed = yamlLoadHelper.LoadBool(SS_YAML_KEY_LINEFEED); + dipsw.bInterrupts = yamlLoadHelper.LoadBool(SS_YAML_KEY_INTERRUPTS); yamlLoadHelper.PopMap(); } @@ -1407,20 +1407,20 @@ bool CSuperSerialCard::LoadSnapshot(YamlLoadHelper& yamlLoadHelper, UINT slot, U LoadSnapshotDIPSW(yamlLoadHelper, SS_YAML_KEY_DIPSWDEFAULT, m_DIPSWDefault); LoadSnapshotDIPSW(yamlLoadHelper, SS_YAML_KEY_DIPSWCURRENT, m_DIPSWCurrent); - m_uBaudRate = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_BAUDRATE); - m_uStopBits = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_STOPBITS); - m_uByteSize = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_BYTESIZE); - m_uParity = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_PARITY); - m_uControlByte = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_CONTROL); - m_uCommandByte = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_COMMAND); - m_dwCommInactivity = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_INACTIVITY); - m_bTxIrqEnabled = yamlLoadHelper.GetMapValueBool(SS_YAML_KEY_TXIRQENABLED); - m_bRxIrqEnabled = yamlLoadHelper.GetMapValueBool(SS_YAML_KEY_RXIRQENABLED); - m_vbTxIrqPending = yamlLoadHelper.GetMapValueBool(SS_YAML_KEY_TXIRQPENDING); - m_vbRxIrqPending = yamlLoadHelper.GetMapValueBool(SS_YAML_KEY_RXIRQPENDING); - m_bWrittenTx = yamlLoadHelper.GetMapValueBool(SS_YAML_KEY_WRITTENTX); + m_uBaudRate = yamlLoadHelper.LoadUint(SS_YAML_KEY_BAUDRATE); + m_uStopBits = yamlLoadHelper.LoadUint(SS_YAML_KEY_STOPBITS); + m_uByteSize = yamlLoadHelper.LoadUint(SS_YAML_KEY_BYTESIZE); + m_uParity = yamlLoadHelper.LoadUint(SS_YAML_KEY_PARITY); + m_uControlByte = yamlLoadHelper.LoadUint(SS_YAML_KEY_CONTROL); + m_uCommandByte = yamlLoadHelper.LoadUint(SS_YAML_KEY_COMMAND); + m_dwCommInactivity = yamlLoadHelper.LoadUint(SS_YAML_KEY_INACTIVITY); + m_bTxIrqEnabled = yamlLoadHelper.LoadBool(SS_YAML_KEY_TXIRQENABLED); + m_bRxIrqEnabled = yamlLoadHelper.LoadBool(SS_YAML_KEY_RXIRQENABLED); + m_vbTxIrqPending = yamlLoadHelper.LoadBool(SS_YAML_KEY_TXIRQPENDING); + m_vbRxIrqPending = yamlLoadHelper.LoadBool(SS_YAML_KEY_RXIRQPENDING); + m_bWrittenTx = yamlLoadHelper.LoadBool(SS_YAML_KEY_WRITTENTX); - std::string serialPortName = yamlLoadHelper.GetMapValueSTRING(SS_YAML_KEY_SERIALPORTNAME); + std::string serialPortName = yamlLoadHelper.LoadString(SS_YAML_KEY_SERIALPORTNAME); SetSerialPortName(serialPortName.c_str()); return true; diff --git a/source/Speaker.cpp b/source/Speaker.cpp index 327c33d6..0a90f963 100644 --- a/source/Speaker.cpp +++ b/source/Speaker.cpp @@ -1119,7 +1119,7 @@ void SpkrLoadSnapshot(YamlLoadHelper& yamlLoadHelper) if (!yamlLoadHelper.GetSubMap(SpkrGetSnapshotStructName())) return; - g_nSpkrLastCycle = yamlLoadHelper.GetMapValueUINT64(SS_YAML_KEY_LASTCYCLE); + g_nSpkrLastCycle = yamlLoadHelper.LoadUint64(SS_YAML_KEY_LASTCYCLE); yamlLoadHelper.PopMap(); } diff --git a/source/Video.cpp b/source/Video.cpp index f3ab19b7..e391ae0c 100644 --- a/source/Video.cpp +++ b/source/Video.cpp @@ -2973,9 +2973,9 @@ void VideoLoadSnapshot(YamlLoadHelper& yamlLoadHelper) if (!yamlLoadHelper.GetSubMap(VideoGetSnapshotStructName())) return; - g_nAltCharSetOffset = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_ALTCHARSET) ? 256 : 0; - g_uVideoMode = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_VIDEOMODE); - g_dwCyclesThisFrame = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_CYCLESTHISFRAME); + g_nAltCharSetOffset = yamlLoadHelper.LoadUint(SS_YAML_KEY_ALTCHARSET) ? 256 : 0; + g_uVideoMode = yamlLoadHelper.LoadUint(SS_YAML_KEY_VIDEOMODE); + g_dwCyclesThisFrame = yamlLoadHelper.LoadUint(SS_YAML_KEY_CYCLESTHISFRAME); yamlLoadHelper.PopMap(); } diff --git a/source/YamlHelper.cpp b/source/YamlHelper.cpp index 1b947d15..5679d44d 100644 --- a/source/YamlHelper.cpp +++ b/source/YamlHelper.cpp @@ -236,7 +236,7 @@ void YamlHelper::MakeAsciiToHexTable(void) m_AsciiToHex[i] = i - 'a' + 0xA; } -void YamlHelper::GetMapValueMemory(MapYaml& mapYaml, const LPBYTE pMemBase, const size_t kAddrSpaceSize) +void YamlHelper::LoadMemory(MapYaml& mapYaml, const LPBYTE pMemBase, const size_t kAddrSpaceSize) { for (MapYaml::iterator it = mapYaml.begin(); it != mapYaml.end(); ++it) { @@ -275,6 +275,72 @@ void YamlHelper::GetMapValueMemory(MapYaml& mapYaml, const LPBYTE pMemBase, cons //------------------------------------- +INT YamlLoadHelper::LoadInt(const std::string key) +{ + bool bFound; + std::string value = m_yamlHelper.GetMapValue(*m_pMapYaml, key, bFound); + if (value == "") + { + m_bDoGetMapRemainder = false; + throw std::string(m_currentMapName + ": Missing: " + key); + } + return strtol(value.c_str(), NULL, 0); +} + +UINT YamlLoadHelper::LoadUint(const std::string key) +{ + bool bFound; + std::string value = m_yamlHelper.GetMapValue(*m_pMapYaml, key, bFound); + if (value == "") + { + m_bDoGetMapRemainder = false; + throw std::string(m_currentMapName + ": Missing: " + key); + } + return strtoul(value.c_str(), NULL, 0); +} + +UINT64 YamlLoadHelper::LoadUint64(const std::string key) +{ + bool bFound; + std::string value = m_yamlHelper.GetMapValue(*m_pMapYaml, key, bFound); + if (value == "") + { + m_bDoGetMapRemainder = false; + throw std::string(m_currentMapName + ": Missing: " + key); + } + return _strtoui64(value.c_str(), NULL, 0); +} + +bool YamlLoadHelper::LoadBool(const std::string key) +{ + return LoadUint(key) ? true : false; +} + +std::string YamlLoadHelper::LoadString_NoThrow(const std::string& key, bool& bFound) +{ + std::string value = m_yamlHelper.GetMapValue(*m_pMapYaml, key, bFound); + return value; +} + +std::string YamlLoadHelper::LoadString(const std::string& key) +{ + bool bFound; + std::string value = LoadString_NoThrow(key, bFound); + if (!bFound) + { + m_bDoGetMapRemainder = false; + throw std::string(m_currentMapName + ": Missing: " + key); + } + return value; +} + +void YamlLoadHelper::LoadMemory(const LPBYTE pMemBase, const size_t size) +{ + m_yamlHelper.LoadMemory(*m_pMapYaml, pMemBase, size); +} + +//------------------------------------- + void YamlSaveHelper::Save(const char* format, ...) { fwrite(m_szIndent, 1, m_indent, m_hFile); diff --git a/source/YamlHelper.h b/source/YamlHelper.h index ce5752c0..463c1608 100644 --- a/source/YamlHelper.h +++ b/source/YamlHelper.h @@ -48,7 +48,7 @@ private: void GetNextEvent(bool bInMap = false); int ParseMap(MapYaml& mapYaml); std::string GetMapValue(MapYaml& mapYaml, const std::string key, bool& bFound); - void GetMapValueMemory(MapYaml& mapYaml, const LPBYTE pMemBase, const size_t kAddrSpaceSize); + void LoadMemory(MapYaml& mapYaml, const LPBYTE pMemBase, const size_t kAddrSpaceSize); bool GetSubMap(MapYaml** mapYaml, const std::string key); void GetMapRemainder(std::string& mapName, MapYaml& mapYaml); @@ -91,69 +91,13 @@ public: m_yamlHelper.GetMapRemainder(m_topLevelMapName, m_yamlHelper.m_mapYaml); } - INT GetMapValueINT(const std::string key) - { - bool bFound; - std::string value = m_yamlHelper.GetMapValue(*m_pMapYaml, key, bFound); - if (value == "") - { - m_bDoGetMapRemainder = false; - throw std::string(m_currentMapName + ": Missing: " + key); - } - return strtol(value.c_str(), NULL, 0); - } - - UINT GetMapValueUINT(const std::string key) - { - bool bFound; - std::string value = m_yamlHelper.GetMapValue(*m_pMapYaml, key, bFound); - if (value == "") - { - m_bDoGetMapRemainder = false; - throw std::string(m_currentMapName + ": Missing: " + key); - } - return strtoul(value.c_str(), NULL, 0); - } - - UINT64 GetMapValueUINT64(const std::string key) - { - bool bFound; - std::string value = m_yamlHelper.GetMapValue(*m_pMapYaml, key, bFound); - if (value == "") - { - m_bDoGetMapRemainder = false; - throw std::string(m_currentMapName + ": Missing: " + key); - } - return _strtoui64(value.c_str(), NULL, 0); - } - - bool GetMapValueBool(const std::string key) - { - return GetMapValueUINT(key) ? true : false; - } - - std::string GetMapValueSTRING_NoThrow(const std::string& key, bool& bFound) - { - std::string value = m_yamlHelper.GetMapValue(*m_pMapYaml, key, bFound); - return value; - } - - std::string GetMapValueSTRING(const std::string& key) - { - bool bFound; - std::string value = GetMapValueSTRING_NoThrow(key, bFound); - if (!bFound) - { - m_bDoGetMapRemainder = false; - throw std::string(m_currentMapName + ": Missing: " + key); - } - return value; - } - - void GetMapValueMemory(const LPBYTE pMemBase, const size_t size) - { - m_yamlHelper.GetMapValueMemory(*m_pMapYaml, pMemBase, size); - } + INT LoadInt(const std::string key); + UINT LoadUint(const std::string key); + UINT64 LoadUint64(const std::string key); + bool LoadBool(const std::string key); + std::string LoadString_NoThrow(const std::string& key, bool& bFound); + std::string LoadString(const std::string& key); + void LoadMemory(const LPBYTE pMemBase, const size_t size); bool GetSubMap(const std::string key) { diff --git a/source/Z80VICE/z80.cpp b/source/Z80VICE/z80.cpp index a91440ec..c84d51e0 100644 --- a/source/Z80VICE/z80.cpp +++ b/source/Z80VICE/z80.cpp @@ -6528,41 +6528,41 @@ bool Z80_LoadSnapshot(class YamlLoadHelper& yamlLoadHelper, UINT uSlot, UINT ver if (version != 1) throw std::string("Card: wrong version"); - reg_a = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_REGA); - reg_b = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_REGB); - reg_c = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_REGC); - reg_d = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_REGD); - reg_e = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_REGE); - reg_f = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_REGF); - reg_h = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_REGH); - reg_l = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_REGL); - USHORT IX = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_REGIX); + reg_a = yamlLoadHelper.LoadUint(SS_YAML_KEY_REGA); + reg_b = yamlLoadHelper.LoadUint(SS_YAML_KEY_REGB); + reg_c = yamlLoadHelper.LoadUint(SS_YAML_KEY_REGC); + reg_d = yamlLoadHelper.LoadUint(SS_YAML_KEY_REGD); + reg_e = yamlLoadHelper.LoadUint(SS_YAML_KEY_REGE); + reg_f = yamlLoadHelper.LoadUint(SS_YAML_KEY_REGF); + reg_h = yamlLoadHelper.LoadUint(SS_YAML_KEY_REGH); + reg_l = yamlLoadHelper.LoadUint(SS_YAML_KEY_REGL); + USHORT IX = yamlLoadHelper.LoadUint(SS_YAML_KEY_REGIX); reg_ixh = IX >> 8; reg_ixl = IX & 0xFF; - USHORT IY = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_REGIY); + USHORT IY = yamlLoadHelper.LoadUint(SS_YAML_KEY_REGIY); reg_iyh = IY >> 8; reg_iyl = IY & 0xFF; - reg_sp = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_REGSP); - z80_reg_pc = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_REGPC); - reg_i = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_REGI); - reg_r = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_REGR); + reg_sp = yamlLoadHelper.LoadUint(SS_YAML_KEY_REGSP); + z80_reg_pc = yamlLoadHelper.LoadUint(SS_YAML_KEY_REGPC); + reg_i = yamlLoadHelper.LoadUint(SS_YAML_KEY_REGI); + reg_r = yamlLoadHelper.LoadUint(SS_YAML_KEY_REGR); - iff1 = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_IFF1); - iff2 = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_IFF2); - im_mode = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_IM_MODE); + iff1 = yamlLoadHelper.LoadUint(SS_YAML_KEY_IFF1); + iff2 = yamlLoadHelper.LoadUint(SS_YAML_KEY_IFF2); + im_mode = yamlLoadHelper.LoadUint(SS_YAML_KEY_IM_MODE); - reg_a2 = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_REGA2); - reg_b2 = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_REGB2); - reg_c2 = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_REGC2); - reg_d2 = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_REGD2); - reg_e2 = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_REGE2); - reg_f2 = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_REGF2); - reg_h2 = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_REGH2); - reg_l2 = yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_REGL2); + reg_a2 = yamlLoadHelper.LoadUint(SS_YAML_KEY_REGA2); + reg_b2 = yamlLoadHelper.LoadUint(SS_YAML_KEY_REGB2); + reg_c2 = yamlLoadHelper.LoadUint(SS_YAML_KEY_REGC2); + reg_d2 = yamlLoadHelper.LoadUint(SS_YAML_KEY_REGD2); + reg_e2 = yamlLoadHelper.LoadUint(SS_YAML_KEY_REGE2); + reg_f2 = yamlLoadHelper.LoadUint(SS_YAML_KEY_REGF2); + reg_h2 = yamlLoadHelper.LoadUint(SS_YAML_KEY_REGH2); + reg_l2 = yamlLoadHelper.LoadUint(SS_YAML_KEY_REGL2); export_registers(); - if ( yamlLoadHelper.GetMapValueUINT(SS_YAML_KEY_ACTIVE) ) + if ( yamlLoadHelper.LoadUint(SS_YAML_KEY_ACTIVE) ) SetActiveCpu(CPU_Z80); // Support MS SoftCard in multiple slots (only one Z80 can be active at any one time) return true; From 18feddceef20c712368250933688d7305123b35f Mon Sep 17 00:00:00 2001 From: tomcw Date: Wed, 24 Feb 2016 22:54:53 +0000 Subject: [PATCH 17/20] Save-state: renamed SaveMapValueMemory() to SaveMemory() --- source/Disk.cpp | 2 +- source/Harddisk.cpp | 2 +- source/Memory.cpp | 4 ++-- source/MouseInterface.cpp | 2 +- source/YamlHelper.cpp | 34 +++++++++++++++++----------------- source/YamlHelper.h | 2 +- 6 files changed, 23 insertions(+), 23 deletions(-) diff --git a/source/Disk.cpp b/source/Disk.cpp index 8c7cef97..357e9ee2 100644 --- a/source/Disk.cpp +++ b/source/Disk.cpp @@ -1216,7 +1216,7 @@ static void DiskSaveSnapshotDisk2Unit(YamlSaveHelper& yamlSaveHelper, UINT unit) if (g_aFloppyDisk[unit].trackimage) { YamlSaveHelper::Label image(yamlSaveHelper, "%s:\n", SS_YAML_KEY_TRACK_IMAGE); - yamlSaveHelper.SaveMapValueMemory(g_aFloppyDisk[unit].trackimage, NIBBLES_PER_TRACK); + yamlSaveHelper.SaveMemory(g_aFloppyDisk[unit].trackimage, NIBBLES_PER_TRACK); } } diff --git a/source/Harddisk.cpp b/source/Harddisk.cpp index feffa5f7..6e4eeaf3 100644 --- a/source/Harddisk.cpp +++ b/source/Harddisk.cpp @@ -700,7 +700,7 @@ static void HD_SaveSnapshotHDDUnit(YamlSaveHelper& yamlSaveHelper, UINT unit) // New label { YamlSaveHelper::Label buffer(yamlSaveHelper, "%s:\n", SS_YAML_KEY_BUF); - yamlSaveHelper.SaveMapValueMemory(g_HardDisk[unit].hd_buf, HD_BLOCK_SIZE); + yamlSaveHelper.SaveMemory(g_HardDisk[unit].hd_buf, HD_BLOCK_SIZE); } } diff --git a/source/Memory.cpp b/source/Memory.cpp index 271a9a6b..f66a0855 100644 --- a/source/Memory.cpp +++ b/source/Memory.cpp @@ -1731,12 +1731,12 @@ static void MemSaveSnapshotMemory(YamlSaveHelper& yamlSaveHelper, bool bIsMainMe if (bIsMainMem) { YamlSaveHelper::Label state(yamlSaveHelper, "%s:\n", MemGetSnapshotMainMemStructName().c_str()); - yamlSaveHelper.SaveMapValueMemory(pMemBase, 64*1024); + yamlSaveHelper.SaveMemory(pMemBase, 64*1024); } else { YamlSaveHelper::Label state(yamlSaveHelper, "%s%02X:\n", MemGetSnapshotAuxMemStructName().c_str(), bank-1); - yamlSaveHelper.SaveMapValueMemory(pMemBase, 64*1024); + yamlSaveHelper.SaveMemory(pMemBase, 64*1024); } } diff --git a/source/MouseInterface.cpp b/source/MouseInterface.cpp index 009f8494..b94bd73f 100644 --- a/source/MouseInterface.cpp +++ b/source/MouseInterface.cpp @@ -673,7 +673,7 @@ void CMouseInterface::SaveSnapshot(class YamlSaveHelper& yamlSaveHelper) // New label { YamlSaveHelper::Label buffer(yamlSaveHelper, "%s:\n", SS_YAML_KEY_BUFF); - yamlSaveHelper.SaveMapValueMemory(m_byBuff, sizeof(m_byBuff)); + yamlSaveHelper.SaveMemory(m_byBuff, sizeof(m_byBuff)); } yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_BUFFPOS, m_nBuffPos); diff --git a/source/YamlHelper.cpp b/source/YamlHelper.cpp index 5679d44d..4a415f3b 100644 --- a/source/YamlHelper.cpp +++ b/source/YamlHelper.cpp @@ -401,23 +401,7 @@ void YamlSaveHelper::SaveString(const char* key, const char* value) Save("%s: %s\n", key, (value[0] != 0) ? value : "\"\""); } -void YamlSaveHelper::FileHdr(UINT version) -{ - fprintf(m_hFile, "%s:\n", SS_YAML_KEY_FILEHDR); - m_indent = 2; - SaveString(SS_YAML_KEY_TAG, SS_YAML_VALUE_AWSS); - SaveInt(SS_YAML_KEY_VERSION, version); -} - -void YamlSaveHelper::UnitHdr(std::string type, UINT version) -{ - fprintf(m_hFile, "\n%s:\n", SS_YAML_KEY_UNIT); - m_indent = 2; - SaveString(SS_YAML_KEY_TYPE, type.c_str()); - SaveInt(SS_YAML_KEY_VERSION, version); -} - -void YamlSaveHelper::SaveMapValueMemory(const LPBYTE pMemBase, const UINT uMemSize) +void YamlSaveHelper::SaveMemory(const LPBYTE pMemBase, const UINT uMemSize) { const UINT kIndent = m_indent; @@ -469,3 +453,19 @@ void YamlSaveHelper::SaveMapValueMemory(const LPBYTE pMemBase, const UINT uMemSi delete [] pLine; } + +void YamlSaveHelper::FileHdr(UINT version) +{ + fprintf(m_hFile, "%s:\n", SS_YAML_KEY_FILEHDR); + m_indent = 2; + SaveString(SS_YAML_KEY_TAG, SS_YAML_VALUE_AWSS); + SaveInt(SS_YAML_KEY_VERSION, version); +} + +void YamlSaveHelper::UnitHdr(std::string type, UINT version) +{ + fprintf(m_hFile, "\n%s:\n", SS_YAML_KEY_UNIT); + m_indent = 2; + SaveString(SS_YAML_KEY_TYPE, type.c_str()); + SaveInt(SS_YAML_KEY_VERSION, version); +} diff --git a/source/YamlHelper.h b/source/YamlHelper.h index 463c1608..6cdb0fb2 100644 --- a/source/YamlHelper.h +++ b/source/YamlHelper.h @@ -213,6 +213,7 @@ public: void SaveHex64(const char* key, UINT64 value); void SaveBool(const char* key, bool value); void SaveString(const char* key, const char* value); + void SaveMemory(const LPBYTE pMemBase, const UINT uMemSize); class Label { @@ -255,7 +256,6 @@ public: void FileHdr(UINT version); void UnitHdr(std::string type, UINT version); - void SaveMapValueMemory(const LPBYTE pMemBase, const UINT uMemSize); private: FILE* m_hFile; From 33ee34b96ca28b4b63343cf7d6c3e0c9c884b2e0 Mon Sep 17 00:00:00 2001 From: tomcw Date: Tue, 1 Mar 2016 22:31:17 +0000 Subject: [PATCH 18/20] Save-state: SaveBool() / LoadBool() persists true,false values --- source/Disk.cpp | 20 ++++++++++---------- source/Harddisk.cpp | 2 +- source/Mockingboard.cpp | 24 ++++++++++++------------ source/ParallelPrinter.cpp | 2 +- source/Video.cpp | 4 ++-- source/YamlHelper.cpp | 15 +++++++++++++-- 6 files changed, 39 insertions(+), 28 deletions(-) diff --git a/source/Disk.cpp b/source/Disk.cpp index 357e9ee2..96a029a7 100644 --- a/source/Disk.cpp +++ b/source/Disk.cpp @@ -1206,7 +1206,7 @@ static void DiskSaveSnapshotDisk2Unit(YamlSaveHelper& yamlSaveHelper, UINT unit) yamlSaveHelper.SaveUint(SS_YAML_KEY_TRACK, g_aFloppyDisk[unit].track); yamlSaveHelper.SaveUint(SS_YAML_KEY_PHASE, g_aFloppyDisk[unit].phase); yamlSaveHelper.SaveHex16(SS_YAML_KEY_BYTE, g_aFloppyDisk[unit].byte); - yamlSaveHelper.SaveUint(SS_YAML_KEY_WRITE_PROTECTED, g_aFloppyDisk[unit].bWriteProtected); + yamlSaveHelper.SaveBool(SS_YAML_KEY_WRITE_PROTECTED, g_aFloppyDisk[unit].bWriteProtected); yamlSaveHelper.SaveUint(SS_YAML_KEY_SPINNING, g_aFloppyDisk[unit].spinning); yamlSaveHelper.SaveUint(SS_YAML_KEY_WRITE_LIGHT, g_aFloppyDisk[unit].writelight); yamlSaveHelper.SaveHex16(SS_YAML_KEY_NIBBLES, g_aFloppyDisk[unit].nibbles); @@ -1227,11 +1227,11 @@ void DiskSaveSnapshot(class YamlSaveHelper& yamlSaveHelper) YamlSaveHelper::Label state(yamlSaveHelper, "%s:\n", SS_YAML_KEY_STATE); yamlSaveHelper.SaveHex4(SS_YAML_KEY_PHASES, phases); yamlSaveHelper.SaveUint(SS_YAML_KEY_CURRENT_DRIVE, currdrive); - yamlSaveHelper.SaveUint(SS_YAML_KEY_DISK_ACCESSED, diskaccessed); - yamlSaveHelper.SaveUint(SS_YAML_KEY_ENHANCE_DISK, enhancedisk); + yamlSaveHelper.SaveBool(SS_YAML_KEY_DISK_ACCESSED, diskaccessed == TRUE); + yamlSaveHelper.SaveBool(SS_YAML_KEY_ENHANCE_DISK, enhancedisk == TRUE); yamlSaveHelper.SaveHex8(SS_YAML_KEY_FLOPPY_LATCH, floppylatch); - yamlSaveHelper.SaveUint(SS_YAML_KEY_FLOPPY_MOTOR_ON, floppymotoron); - yamlSaveHelper.SaveUint(SS_YAML_KEY_FLOPPY_WRITE_MODE, floppywritemode); + yamlSaveHelper.SaveBool(SS_YAML_KEY_FLOPPY_MOTOR_ON, floppymotoron == TRUE); + yamlSaveHelper.SaveBool(SS_YAML_KEY_FLOPPY_WRITE_MODE, floppywritemode == TRUE); DiskSaveSnapshotDisk2Unit(yamlSaveHelper, DRIVE_1); DiskSaveSnapshotDisk2Unit(yamlSaveHelper, DRIVE_2); @@ -1277,7 +1277,7 @@ static void DiskLoadSnapshotDriveUnit(YamlLoadHelper& yamlLoadHelper, UINT unit) g_aFloppyDisk[unit].track = yamlLoadHelper.LoadUint(SS_YAML_KEY_TRACK); g_aFloppyDisk[unit].phase = yamlLoadHelper.LoadUint(SS_YAML_KEY_PHASE); g_aFloppyDisk[unit].byte = yamlLoadHelper.LoadUint(SS_YAML_KEY_BYTE); - yamlLoadHelper.LoadUint(SS_YAML_KEY_WRITE_PROTECTED); // Consume + yamlLoadHelper.LoadBool(SS_YAML_KEY_WRITE_PROTECTED); // Consume g_aFloppyDisk[unit].spinning = yamlLoadHelper.LoadUint(SS_YAML_KEY_SPINNING); g_aFloppyDisk[unit].writelight = yamlLoadHelper.LoadUint(SS_YAML_KEY_WRITE_LIGHT); g_aFloppyDisk[unit].nibbles = yamlLoadHelper.LoadUint(SS_YAML_KEY_NIBBLES); @@ -1325,11 +1325,11 @@ bool DiskLoadSnapshot(class YamlLoadHelper& yamlLoadHelper, UINT slot, UINT vers phases = yamlLoadHelper.LoadUint(SS_YAML_KEY_PHASES); currdrive = yamlLoadHelper.LoadUint(SS_YAML_KEY_CURRENT_DRIVE); - diskaccessed = yamlLoadHelper.LoadUint(SS_YAML_KEY_DISK_ACCESSED); - enhancedisk = yamlLoadHelper.LoadUint(SS_YAML_KEY_ENHANCE_DISK); + diskaccessed = yamlLoadHelper.LoadBool(SS_YAML_KEY_DISK_ACCESSED); + enhancedisk = yamlLoadHelper.LoadBool(SS_YAML_KEY_ENHANCE_DISK); floppylatch = yamlLoadHelper.LoadUint(SS_YAML_KEY_FLOPPY_LATCH); - floppymotoron = yamlLoadHelper.LoadUint(SS_YAML_KEY_FLOPPY_MOTOR_ON); - floppywritemode = yamlLoadHelper.LoadUint(SS_YAML_KEY_FLOPPY_WRITE_MODE); + floppymotoron = yamlLoadHelper.LoadBool(SS_YAML_KEY_FLOPPY_MOTOR_ON); + floppywritemode = yamlLoadHelper.LoadBool(SS_YAML_KEY_FLOPPY_WRITE_MODE); // Eject all disks first in case Drive-2 contains disk to be inserted into Drive-1 for(UINT i=0; iSpeechChip); yamlSaveHelper.SaveHex4(SS_YAML_KEY_AY_CURR_REG, pMB->nAYCurrentRegister); - yamlSaveHelper.Save("%s: %d # Not supported\n", SS_YAML_KEY_TIMER1_IRQ, 0); - yamlSaveHelper.Save("%s: %d # Not supported\n", SS_YAML_KEY_TIMER2_IRQ, 0); - yamlSaveHelper.Save("%s: %d # Not supported\n", SS_YAML_KEY_SPEECH_IRQ, 0); + yamlSaveHelper.Save("%s: %s # Not supported\n", SS_YAML_KEY_TIMER1_IRQ, "false"); + yamlSaveHelper.Save("%s: %s # Not supported\n", SS_YAML_KEY_TIMER2_IRQ, "false"); + yamlSaveHelper.Save("%s: %s # Not supported\n", SS_YAML_KEY_SPEECH_IRQ, "false"); nDeviceNum++; pMB++; @@ -2063,9 +2063,9 @@ bool MB_LoadSnapshot(YamlLoadHelper& yamlLoadHelper, UINT slot, UINT version) LoadSnapshotSSI263(yamlLoadHelper, pMB->SpeechChip); pMB->nAYCurrentRegister = yamlLoadHelper.LoadUint(SS_YAML_KEY_AY_CURR_REG); - yamlLoadHelper.LoadUint(SS_YAML_KEY_TIMER1_IRQ); // Consume - yamlLoadHelper.LoadUint(SS_YAML_KEY_TIMER2_IRQ); // Consume - yamlLoadHelper.LoadUint(SS_YAML_KEY_SPEECH_IRQ); // Consume + yamlLoadHelper.LoadBool(SS_YAML_KEY_TIMER1_IRQ); // Consume + yamlLoadHelper.LoadBool(SS_YAML_KEY_TIMER2_IRQ); // Consume + yamlLoadHelper.LoadBool(SS_YAML_KEY_SPEECH_IRQ); // Consume yamlLoadHelper.PopMap(); @@ -2127,9 +2127,9 @@ void Phasor_SaveSnapshot(YamlSaveHelper& yamlSaveHelper, const UINT uSlot) SaveSnapshotSSI263(yamlSaveHelper, pMB->SpeechChip); yamlSaveHelper.SaveHex4(SS_YAML_KEY_AY_CURR_REG, pMB->nAYCurrentRegister); - yamlSaveHelper.Save("%s: %d # Not supported\n", SS_YAML_KEY_TIMER1_IRQ, 0); - yamlSaveHelper.Save("%s: %d # Not supported\n", SS_YAML_KEY_TIMER2_IRQ, 0); - yamlSaveHelper.Save("%s: %d # Not supported\n", SS_YAML_KEY_SPEECH_IRQ, 0); + yamlSaveHelper.Save("%s: %s # Not supported\n", SS_YAML_KEY_TIMER1_IRQ, "false"); + yamlSaveHelper.Save("%s: %s # Not supported\n", SS_YAML_KEY_TIMER2_IRQ, "false"); + yamlSaveHelper.Save("%s: %s # Not supported\n", SS_YAML_KEY_SPEECH_IRQ, "false"); nDeviceNum += 2; pMB++; @@ -2168,9 +2168,9 @@ bool Phasor_LoadSnapshot(YamlLoadHelper& yamlLoadHelper, UINT slot, UINT version LoadSnapshotSSI263(yamlLoadHelper, pMB->SpeechChip); pMB->nAYCurrentRegister = yamlLoadHelper.LoadUint(SS_YAML_KEY_AY_CURR_REG); - yamlLoadHelper.LoadUint(SS_YAML_KEY_TIMER1_IRQ); // Consume - yamlLoadHelper.LoadUint(SS_YAML_KEY_TIMER2_IRQ); // Consume - yamlLoadHelper.LoadUint(SS_YAML_KEY_SPEECH_IRQ); // Consume + yamlLoadHelper.LoadBool(SS_YAML_KEY_TIMER1_IRQ); // Consume + yamlLoadHelper.LoadBool(SS_YAML_KEY_TIMER2_IRQ); // Consume + yamlLoadHelper.LoadBool(SS_YAML_KEY_SPEECH_IRQ); // Consume yamlLoadHelper.PopMap(); diff --git a/source/ParallelPrinter.cpp b/source/ParallelPrinter.cpp index f295c958..f17609db 100644 --- a/source/ParallelPrinter.cpp +++ b/source/ParallelPrinter.cpp @@ -282,7 +282,7 @@ void Printer_SaveSnapshot(class YamlSaveHelper& yamlSaveHelper) yamlSaveHelper.SaveUint(SS_YAML_KEY_INACTIVITY, inactivity); yamlSaveHelper.SaveUint(SS_YAML_KEY_IDLELIMIT, g_PrinterIdleLimit); yamlSaveHelper.SaveString(SS_YAML_KEY_FILENAME, g_szPrintFilename); - yamlSaveHelper.SaveUint(SS_YAML_KEY_FILEOPEN, (file != NULL) ? 1 : 0); + yamlSaveHelper.SaveBool(SS_YAML_KEY_FILEOPEN, (file != NULL) ? true : false); yamlSaveHelper.SaveBool(SS_YAML_KEY_DUMPTOPRINTER, g_bDumpToPrinter); yamlSaveHelper.SaveBool(SS_YAML_KEY_CONVERTENCODING, g_bConvertEncoding); yamlSaveHelper.SaveBool(SS_YAML_KEY_FILTERUNPRINTABLE, g_bFilterUnprintable); diff --git a/source/Video.cpp b/source/Video.cpp index e391ae0c..02d3720e 100644 --- a/source/Video.cpp +++ b/source/Video.cpp @@ -2963,7 +2963,7 @@ static std::string VideoGetSnapshotStructName(void) void VideoSaveSnapshot(YamlSaveHelper& yamlSaveHelper) { YamlSaveHelper::Label state(yamlSaveHelper, "%s:\n", VideoGetSnapshotStructName().c_str()); - yamlSaveHelper.SaveUint(SS_YAML_KEY_ALTCHARSET, g_nAltCharSetOffset ? 1 : 0); + yamlSaveHelper.SaveBool(SS_YAML_KEY_ALTCHARSET, g_nAltCharSetOffset ? true : false); yamlSaveHelper.SaveHex32(SS_YAML_KEY_VIDEOMODE, g_uVideoMode); yamlSaveHelper.SaveUint(SS_YAML_KEY_CYCLESTHISFRAME, g_dwCyclesThisFrame); } @@ -2973,7 +2973,7 @@ void VideoLoadSnapshot(YamlLoadHelper& yamlLoadHelper) if (!yamlLoadHelper.GetSubMap(VideoGetSnapshotStructName())) return; - g_nAltCharSetOffset = yamlLoadHelper.LoadUint(SS_YAML_KEY_ALTCHARSET) ? 256 : 0; + g_nAltCharSetOffset = yamlLoadHelper.LoadBool(SS_YAML_KEY_ALTCHARSET) ? 256 : 0; g_uVideoMode = yamlLoadHelper.LoadUint(SS_YAML_KEY_VIDEOMODE); g_dwCyclesThisFrame = yamlLoadHelper.LoadUint(SS_YAML_KEY_CYCLESTHISFRAME); diff --git a/source/YamlHelper.cpp b/source/YamlHelper.cpp index 4a415f3b..bc304b6d 100644 --- a/source/YamlHelper.cpp +++ b/source/YamlHelper.cpp @@ -313,7 +313,14 @@ UINT64 YamlLoadHelper::LoadUint64(const std::string key) bool YamlLoadHelper::LoadBool(const std::string key) { - return LoadUint(key) ? true : false; + bool bFound; + std::string value = m_yamlHelper.GetMapValue(*m_pMapYaml, key, bFound); + if (value == "true") + return true; + else if (value == "false") + return false; + m_bDoGetMapRemainder = false; + throw std::string(m_currentMapName + ": Missing: " + key); } std::string YamlLoadHelper::LoadString_NoThrow(const std::string& key, bool& bFound) @@ -393,7 +400,7 @@ void YamlSaveHelper::SaveHex64(const char* key, UINT64 value) void YamlSaveHelper::SaveBool(const char* key, bool value) { - SaveUint(key, value ? 1 : 0); + Save("%s: %s\n", key, value ? "true" : "false"); } void YamlSaveHelper::SaveString(const char* key, const char* value) @@ -401,8 +408,12 @@ void YamlSaveHelper::SaveString(const char* key, const char* value) Save("%s: %s\n", key, (value[0] != 0) ? value : "\"\""); } +// Pre: uMemSize must be multiple of 8 void YamlSaveHelper::SaveMemory(const LPBYTE pMemBase, const UINT uMemSize) { + if (uMemSize & 7) + throw std::string("Memory: size must be multiple of 8"); + const UINT kIndent = m_indent; const UINT kStride = 64; From d0243c71d7f3a7deaf73e754063c332e2809dc53 Mon Sep 17 00:00:00 2001 From: tomcw Date: Fri, 4 Mar 2016 21:26:14 +0000 Subject: [PATCH 19/20] Save-state: rename SaveHex{4|8|12|16...64} to SaveHexUint{4|8|12|16...64} --- source/AY8910.cpp | 24 +++++++++---------- source/Applewin.cpp | 2 +- source/CPU.cpp | 14 +++++------ source/Disk.cpp | 8 +++---- source/Harddisk.cpp | 10 ++++---- source/Joystick.cpp | 2 +- source/Keyboard.cpp | 2 +- source/Memory.cpp | 6 ++--- source/Mockingboard.cpp | 42 ++++++++++++++++---------------- source/MouseInterface.cpp | 8 +++---- source/SerialComms.cpp | 4 ++-- source/Speaker.cpp | 2 +- source/Video.cpp | 2 +- source/YamlHelper.cpp | 12 +++++----- source/YamlHelper.h | 12 +++++----- source/Z80VICE/z80.cpp | 50 +++++++++++++++++++-------------------- 16 files changed, 100 insertions(+), 100 deletions(-) diff --git a/source/AY8910.cpp b/source/AY8910.cpp index bc41cfe5..e742e407 100644 --- a/source/AY8910.cpp +++ b/source/AY8910.cpp @@ -1023,18 +1023,18 @@ void CAY8910::SaveSnapshot(YamlSaveHelper& yamlSaveHelper, std::string& suffix) { YamlSaveHelper::Label registers(yamlSaveHelper, "%s:\n", SS_YAML_KEY_REGISTERS); - yamlSaveHelper.SaveHex12(SS_YAML_KEY_REG_TONE0_PERIOD, (UINT)(sound_ay_registers[1]<<8) | sound_ay_registers[0]); - yamlSaveHelper.SaveHex12(SS_YAML_KEY_REG_TONE1_PERIOD, (UINT)(sound_ay_registers[3]<<8) | sound_ay_registers[2]); - yamlSaveHelper.SaveHex12(SS_YAML_KEY_REG_TONE2_PERIOD, (UINT)(sound_ay_registers[5]<<8) | sound_ay_registers[4]); - yamlSaveHelper.SaveHex8(SS_YAML_KEY_REG_NOISE_PERIOD, sound_ay_registers[6]); - yamlSaveHelper.SaveHex8(SS_YAML_KEY_REG_MIXER, sound_ay_registers[7]); - yamlSaveHelper.SaveHex8(SS_YAML_KEY_REG_VOL0, sound_ay_registers[8]); - yamlSaveHelper.SaveHex8(SS_YAML_KEY_REG_VOL1, sound_ay_registers[9]); - yamlSaveHelper.SaveHex8(SS_YAML_KEY_REG_VOL2, sound_ay_registers[10]); - yamlSaveHelper.SaveHex16(SS_YAML_KEY_REG_ENV_PERIOD, (UINT)(sound_ay_registers[12]<<8) | sound_ay_registers[11]); - yamlSaveHelper.SaveHex4(SS_YAML_KEY_REG_ENV_SHAPE, sound_ay_registers[13]); - yamlSaveHelper.SaveHex8(SS_YAML_KEY_REG_PORTA, sound_ay_registers[14]); - yamlSaveHelper.SaveHex8(SS_YAML_KEY_REG_PORTB, sound_ay_registers[15]); + yamlSaveHelper.SaveHexUint12(SS_YAML_KEY_REG_TONE0_PERIOD, (UINT)(sound_ay_registers[1]<<8) | sound_ay_registers[0]); + yamlSaveHelper.SaveHexUint12(SS_YAML_KEY_REG_TONE1_PERIOD, (UINT)(sound_ay_registers[3]<<8) | sound_ay_registers[2]); + yamlSaveHelper.SaveHexUint12(SS_YAML_KEY_REG_TONE2_PERIOD, (UINT)(sound_ay_registers[5]<<8) | sound_ay_registers[4]); + yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_REG_NOISE_PERIOD, sound_ay_registers[6]); + yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_REG_MIXER, sound_ay_registers[7]); + yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_REG_VOL0, sound_ay_registers[8]); + yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_REG_VOL1, sound_ay_registers[9]); + yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_REG_VOL2, sound_ay_registers[10]); + yamlSaveHelper.SaveHexUint16(SS_YAML_KEY_REG_ENV_PERIOD, (UINT)(sound_ay_registers[12]<<8) | sound_ay_registers[11]); + yamlSaveHelper.SaveHexUint4(SS_YAML_KEY_REG_ENV_SHAPE, sound_ay_registers[13]); + yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_REG_PORTA, sound_ay_registers[14]); + yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_REG_PORTB, sound_ay_registers[15]); } // New label diff --git a/source/Applewin.cpp b/source/Applewin.cpp index 4d3a8ee0..76eb67a6 100644 --- a/source/Applewin.cpp +++ b/source/Applewin.cpp @@ -1089,7 +1089,7 @@ int APIENTRY WinMain(HINSTANCE passinstance, HINSTANCE, LPSTR lpCmdLine, int) Snapshot_SetFilename(szSnapshotName); Snapshot_LoadState(); bBoot = true; -#if _DEBUG && 0 // Debug/test: Save a duplicate of the save-state file in tmp folder +#if _DEBUG && 1 // Debug/test: Save a duplicate of the save-state file in tmp folder std::string saveName = std::string("tmp\\") + std::string(szSnapshotName); Snapshot_SetFilename(saveName); g_bSaveStateOnExit = true; diff --git a/source/CPU.cpp b/source/CPU.cpp index c0cfed32..3c998c14 100644 --- a/source/CPU.cpp +++ b/source/CPU.cpp @@ -730,13 +730,13 @@ void CpuSaveSnapshot(YamlSaveHelper& yamlSaveHelper) YamlSaveHelper::Label state(yamlSaveHelper, "%s:\n", CpuGetSnapshotStructName().c_str()); yamlSaveHelper.SaveString(SS_YAML_KEY_CPU_TYPE, GetMainCpu() == CPU_6502 ? SS_YAML_VALUE_6502 : SS_YAML_VALUE_65C02); - yamlSaveHelper.SaveHex8(SS_YAML_KEY_REGA, regs.a); - yamlSaveHelper.SaveHex8(SS_YAML_KEY_REGX, regs.x); - yamlSaveHelper.SaveHex8(SS_YAML_KEY_REGY, regs.y); - yamlSaveHelper.SaveHex8(SS_YAML_KEY_REGP, regs.ps); - yamlSaveHelper.SaveHex8(SS_YAML_KEY_REGS, (BYTE) regs.sp); - yamlSaveHelper.SaveHex16(SS_YAML_KEY_REGPC, regs.pc); - yamlSaveHelper.SaveHex64(SS_YAML_KEY_CUMULATIVECYCLES, g_nCumulativeCycles); + yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_REGA, regs.a); + yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_REGX, regs.x); + yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_REGY, regs.y); + yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_REGP, regs.ps); + yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_REGS, (BYTE) regs.sp); + yamlSaveHelper.SaveHexUint16(SS_YAML_KEY_REGPC, regs.pc); + yamlSaveHelper.SaveHexUint64(SS_YAML_KEY_CUMULATIVECYCLES, g_nCumulativeCycles); } void CpuLoadSnapshot(YamlLoadHelper& yamlLoadHelper) diff --git a/source/Disk.cpp b/source/Disk.cpp index 96a029a7..a239e1c8 100644 --- a/source/Disk.cpp +++ b/source/Disk.cpp @@ -1205,11 +1205,11 @@ static void DiskSaveSnapshotDisk2Unit(YamlSaveHelper& yamlSaveHelper, UINT unit) yamlSaveHelper.SaveString(SS_YAML_KEY_FILENAME, g_aFloppyDisk[unit].fullname); yamlSaveHelper.SaveUint(SS_YAML_KEY_TRACK, g_aFloppyDisk[unit].track); yamlSaveHelper.SaveUint(SS_YAML_KEY_PHASE, g_aFloppyDisk[unit].phase); - yamlSaveHelper.SaveHex16(SS_YAML_KEY_BYTE, g_aFloppyDisk[unit].byte); + yamlSaveHelper.SaveHexUint16(SS_YAML_KEY_BYTE, g_aFloppyDisk[unit].byte); yamlSaveHelper.SaveBool(SS_YAML_KEY_WRITE_PROTECTED, g_aFloppyDisk[unit].bWriteProtected); yamlSaveHelper.SaveUint(SS_YAML_KEY_SPINNING, g_aFloppyDisk[unit].spinning); yamlSaveHelper.SaveUint(SS_YAML_KEY_WRITE_LIGHT, g_aFloppyDisk[unit].writelight); - yamlSaveHelper.SaveHex16(SS_YAML_KEY_NIBBLES, g_aFloppyDisk[unit].nibbles); + yamlSaveHelper.SaveHexUint16(SS_YAML_KEY_NIBBLES, g_aFloppyDisk[unit].nibbles); yamlSaveHelper.SaveUint(SS_YAML_KEY_TRACK_IMAGE_DATA, g_aFloppyDisk[unit].trackimagedata); yamlSaveHelper.SaveUint(SS_YAML_KEY_TRACK_IMAGE_DIRTY, g_aFloppyDisk[unit].trackimagedirty); @@ -1225,11 +1225,11 @@ void DiskSaveSnapshot(class YamlSaveHelper& yamlSaveHelper) YamlSaveHelper::Slot slot(yamlSaveHelper, DiskGetSnapshotCardName(), g_uSlot, 1); YamlSaveHelper::Label state(yamlSaveHelper, "%s:\n", SS_YAML_KEY_STATE); - yamlSaveHelper.SaveHex4(SS_YAML_KEY_PHASES, phases); + yamlSaveHelper.SaveHexUint4(SS_YAML_KEY_PHASES, phases); yamlSaveHelper.SaveUint(SS_YAML_KEY_CURRENT_DRIVE, currdrive); yamlSaveHelper.SaveBool(SS_YAML_KEY_DISK_ACCESSED, diskaccessed == TRUE); yamlSaveHelper.SaveBool(SS_YAML_KEY_ENHANCE_DISK, enhancedisk == TRUE); - yamlSaveHelper.SaveHex8(SS_YAML_KEY_FLOPPY_LATCH, floppylatch); + yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_FLOPPY_LATCH, floppylatch); yamlSaveHelper.SaveBool(SS_YAML_KEY_FLOPPY_MOTOR_ON, floppymotoron == TRUE); yamlSaveHelper.SaveBool(SS_YAML_KEY_FLOPPY_WRITE_MODE, floppywritemode == TRUE); diff --git a/source/Harddisk.cpp b/source/Harddisk.cpp index 83c0b953..90b3a0bc 100644 --- a/source/Harddisk.cpp +++ b/source/Harddisk.cpp @@ -689,13 +689,13 @@ static void HD_SaveSnapshotHDDUnit(YamlSaveHelper& yamlSaveHelper, UINT unit) { YamlSaveHelper::Label label(yamlSaveHelper, "%s%d:\n", SS_YAML_KEY_HDDUNIT, unit); yamlSaveHelper.SaveString(SS_YAML_KEY_FILENAME, g_HardDisk[unit].fullname); - yamlSaveHelper.SaveHex8(SS_YAML_KEY_ERROR, g_HardDisk[unit].hd_error); - yamlSaveHelper.SaveHex16(SS_YAML_KEY_MEMBLOCK, g_HardDisk[unit].hd_memblock); - yamlSaveHelper.SaveHex32(SS_YAML_KEY_DISKBLOCK, g_HardDisk[unit].hd_diskblock); + yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_ERROR, g_HardDisk[unit].hd_error); + yamlSaveHelper.SaveHexUint16(SS_YAML_KEY_MEMBLOCK, g_HardDisk[unit].hd_memblock); + yamlSaveHelper.SaveHexUint32(SS_YAML_KEY_DISKBLOCK, g_HardDisk[unit].hd_diskblock); yamlSaveHelper.SaveBool(SS_YAML_KEY_IMAGELOADED, g_HardDisk[unit].hd_imageloaded); yamlSaveHelper.SaveUint(SS_YAML_KEY_STATUS_NEXT, g_HardDisk[unit].hd_status_next); yamlSaveHelper.SaveUint(SS_YAML_KEY_STATUS_PREV, g_HardDisk[unit].hd_status_prev); - yamlSaveHelper.SaveHex16(SS_YAML_KEY_BUF_PTR, g_HardDisk[unit].hd_buf_ptr); + yamlSaveHelper.SaveHexUint16(SS_YAML_KEY_BUF_PTR, g_HardDisk[unit].hd_buf_ptr); // New label { @@ -713,7 +713,7 @@ void HD_SaveSnapshot(YamlSaveHelper& yamlSaveHelper) YamlSaveHelper::Label state(yamlSaveHelper, "%s:\n", SS_YAML_KEY_STATE); yamlSaveHelper.Save("%s: %d # b7=unit\n", SS_YAML_KEY_CURRENT_UNIT, g_nHD_UnitNum); - yamlSaveHelper.SaveHex8(SS_YAML_KEY_COMMAND, g_nHD_Command); + yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_COMMAND, g_nHD_Command); HD_SaveSnapshotHDDUnit(yamlSaveHelper, HARDDISK_1); HD_SaveSnapshotHDDUnit(yamlSaveHelper, HARDDISK_2); diff --git a/source/Joystick.cpp b/source/Joystick.cpp index f1357cd1..79c14764 100644 --- a/source/Joystick.cpp +++ b/source/Joystick.cpp @@ -871,7 +871,7 @@ static std::string JoyGetSnapshotStructName(void) void JoySaveSnapshot(YamlSaveHelper& yamlSaveHelper) { YamlSaveHelper::Label state(yamlSaveHelper, "%s:\n", JoyGetSnapshotStructName().c_str()); - yamlSaveHelper.SaveHex64(SS_YAML_KEY_COUNTERRESETCYCLE, g_nJoyCntrResetCycle); + yamlSaveHelper.SaveHexUint64(SS_YAML_KEY_COUNTERRESETCYCLE, g_nJoyCntrResetCycle); yamlSaveHelper.SaveInt(SS_YAML_KEY_JOY0TRIMX, JoyGetTrim(true)); yamlSaveHelper.SaveInt(SS_YAML_KEY_JOY0TRIMY, JoyGetTrim(false)); yamlSaveHelper.Save("%s: %d # not implemented yet\n", SS_YAML_KEY_JOY1TRIMX, 0); // not implemented yet diff --git a/source/Keyboard.cpp b/source/Keyboard.cpp index 00c9f6d0..936eb63b 100644 --- a/source/Keyboard.cpp +++ b/source/Keyboard.cpp @@ -519,7 +519,7 @@ static std::string KeybGetSnapshotStructName(void) void KeybSaveSnapshot(YamlSaveHelper& yamlSaveHelper) { YamlSaveHelper::Label state(yamlSaveHelper, "%s:\n", KeybGetSnapshotStructName().c_str()); - yamlSaveHelper.SaveHex8(SS_YAML_KEY_LASTKEY, g_nLastKey); + yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_LASTKEY, g_nLastKey); } void KeybLoadSnapshot(YamlLoadHelper& yamlLoadHelper) diff --git a/source/Memory.cpp b/source/Memory.cpp index f66a0855..4cf056cf 100644 --- a/source/Memory.cpp +++ b/source/Memory.cpp @@ -1745,10 +1745,10 @@ void MemSaveSnapshot(YamlSaveHelper& yamlSaveHelper) // Scope so that "Memory" & "Main Memory" are at same indent level { YamlSaveHelper::Label state(yamlSaveHelper, "%s:\n", MemGetSnapshotStructName().c_str()); - yamlSaveHelper.SaveHex32(SS_YAML_KEY_MEMORYMODE, memmode); + yamlSaveHelper.SaveHexUint32(SS_YAML_KEY_MEMORYMODE, memmode); yamlSaveHelper.SaveUint(SS_YAML_KEY_LASTRAMWRITE, lastwriteram ? 1 : 0); - yamlSaveHelper.SaveHex8(SS_YAML_KEY_IOSELECT, IO_SELECT); - yamlSaveHelper.SaveHex8(SS_YAML_KEY_IOSELECT_INT, IO_SELECT_InternalROM); + yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_IOSELECT, IO_SELECT); + yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_IOSELECT_INT, IO_SELECT_InternalROM); yamlSaveHelper.SaveUint(SS_YAML_KEY_EXPANSIONROMTYPE, (UINT) g_eExpansionRomType); yamlSaveHelper.SaveUint(SS_YAML_KEY_PERIPHERALROMSLOT, g_uPeripheralRomSlot); } diff --git a/source/Mockingboard.cpp b/source/Mockingboard.cpp index 0451dc65..0143f8e9 100644 --- a/source/Mockingboard.cpp +++ b/source/Mockingboard.cpp @@ -1940,19 +1940,19 @@ static void SaveSnapshotSY6522(YamlSaveHelper& yamlSaveHelper, SY6522& sy6522) { YamlSaveHelper::Label label(yamlSaveHelper, "%s:\n", SS_YAML_KEY_SY6522); - yamlSaveHelper.SaveHex8(SS_YAML_KEY_SY6522_REG_ORB, sy6522.ORB); - yamlSaveHelper.SaveHex8(SS_YAML_KEY_SY6522_REG_ORA, sy6522.ORA); - yamlSaveHelper.SaveHex8(SS_YAML_KEY_SY6522_REG_DDRB, sy6522.DDRB); - yamlSaveHelper.SaveHex8(SS_YAML_KEY_SY6522_REG_DDRA, sy6522.DDRA); - yamlSaveHelper.SaveHex16(SS_YAML_KEY_SY6522_REG_T1_COUNTER, sy6522.TIMER1_COUNTER.w); - yamlSaveHelper.SaveHex16(SS_YAML_KEY_SY6522_REG_T1_LATCH, sy6522.TIMER1_LATCH.w); - yamlSaveHelper.SaveHex16(SS_YAML_KEY_SY6522_REG_T2_COUNTER, sy6522.TIMER2_COUNTER.w); - yamlSaveHelper.SaveHex16(SS_YAML_KEY_SY6522_REG_T2_LATCH, sy6522.TIMER2_LATCH.w); - yamlSaveHelper.SaveHex8(SS_YAML_KEY_SY6522_REG_SERIAL_SHIFT, sy6522.SERIAL_SHIFT); - yamlSaveHelper.SaveHex8(SS_YAML_KEY_SY6522_REG_ACR, sy6522.ACR); - yamlSaveHelper.SaveHex8(SS_YAML_KEY_SY6522_REG_PCR, sy6522.PCR); - yamlSaveHelper.SaveHex8(SS_YAML_KEY_SY6522_REG_IFR, sy6522.IFR); - yamlSaveHelper.SaveHex8(SS_YAML_KEY_SY6522_REG_IER, sy6522.IER); + yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_SY6522_REG_ORB, sy6522.ORB); + yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_SY6522_REG_ORA, sy6522.ORA); + yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_SY6522_REG_DDRB, sy6522.DDRB); + yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_SY6522_REG_DDRA, sy6522.DDRA); + yamlSaveHelper.SaveHexUint16(SS_YAML_KEY_SY6522_REG_T1_COUNTER, sy6522.TIMER1_COUNTER.w); + yamlSaveHelper.SaveHexUint16(SS_YAML_KEY_SY6522_REG_T1_LATCH, sy6522.TIMER1_LATCH.w); + yamlSaveHelper.SaveHexUint16(SS_YAML_KEY_SY6522_REG_T2_COUNTER, sy6522.TIMER2_COUNTER.w); + yamlSaveHelper.SaveHexUint16(SS_YAML_KEY_SY6522_REG_T2_LATCH, sy6522.TIMER2_LATCH.w); + yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_SY6522_REG_SERIAL_SHIFT, sy6522.SERIAL_SHIFT); + yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_SY6522_REG_ACR, sy6522.ACR); + yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_SY6522_REG_PCR, sy6522.PCR); + yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_SY6522_REG_IFR, sy6522.IFR); + yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_SY6522_REG_IER, sy6522.IER); // NB. No need to write ORA_NO_HS, since same data as ORA, just without handshake } @@ -1960,12 +1960,12 @@ static void SaveSnapshotSSI263(YamlSaveHelper& yamlSaveHelper, SSI263A& ssi263) { YamlSaveHelper::Label label(yamlSaveHelper, "%s:\n", SS_YAML_KEY_SSI263); - yamlSaveHelper.SaveHex8(SS_YAML_KEY_SSI263_REG_DUR_PHON, ssi263.DurationPhoneme); - yamlSaveHelper.SaveHex8(SS_YAML_KEY_SSI263_REG_INF, ssi263.Inflection); - yamlSaveHelper.SaveHex8(SS_YAML_KEY_SSI263_REG_RATE_INF, ssi263.RateInflection); - yamlSaveHelper.SaveHex8(SS_YAML_KEY_SSI263_REG_CTRL_ART_AMP, ssi263.CtrlArtAmp); - yamlSaveHelper.SaveHex8(SS_YAML_KEY_SSI263_REG_FILTER_FREQ, ssi263.FilterFreq); - yamlSaveHelper.SaveHex8(SS_YAML_KEY_SSI263_REG_CURRENT_MODE, ssi263.CurrentMode); + yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_SSI263_REG_DUR_PHON, ssi263.DurationPhoneme); + yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_SSI263_REG_INF, ssi263.Inflection); + yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_SSI263_REG_RATE_INF, ssi263.RateInflection); + yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_SSI263_REG_CTRL_ART_AMP, ssi263.CtrlArtAmp); + yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_SSI263_REG_FILTER_FREQ, ssi263.FilterFreq); + yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_SSI263_REG_CURRENT_MODE, ssi263.CurrentMode); } void MB_SaveSnapshot(YamlSaveHelper& yamlSaveHelper, const UINT uSlot) @@ -1986,7 +1986,7 @@ void MB_SaveSnapshot(YamlSaveHelper& yamlSaveHelper, const UINT uSlot) AY8910_SaveSnapshot(yamlSaveHelper, nDeviceNum, std::string("")); SaveSnapshotSSI263(yamlSaveHelper, pMB->SpeechChip); - yamlSaveHelper.SaveHex4(SS_YAML_KEY_AY_CURR_REG, pMB->nAYCurrentRegister); + yamlSaveHelper.SaveHexUint4(SS_YAML_KEY_AY_CURR_REG, pMB->nAYCurrentRegister); yamlSaveHelper.Save("%s: %s # Not supported\n", SS_YAML_KEY_TIMER1_IRQ, "false"); yamlSaveHelper.Save("%s: %s # Not supported\n", SS_YAML_KEY_TIMER2_IRQ, "false"); yamlSaveHelper.Save("%s: %s # Not supported\n", SS_YAML_KEY_SPEECH_IRQ, "false"); @@ -2126,7 +2126,7 @@ void Phasor_SaveSnapshot(YamlSaveHelper& yamlSaveHelper, const UINT uSlot) AY8910_SaveSnapshot(yamlSaveHelper, nDeviceNum+1, std::string("-B")); SaveSnapshotSSI263(yamlSaveHelper, pMB->SpeechChip); - yamlSaveHelper.SaveHex4(SS_YAML_KEY_AY_CURR_REG, pMB->nAYCurrentRegister); + yamlSaveHelper.SaveHexUint4(SS_YAML_KEY_AY_CURR_REG, pMB->nAYCurrentRegister); yamlSaveHelper.Save("%s: %s # Not supported\n", SS_YAML_KEY_TIMER1_IRQ, "false"); yamlSaveHelper.Save("%s: %s # Not supported\n", SS_YAML_KEY_TIMER2_IRQ, "false"); yamlSaveHelper.Save("%s: %s # Not supported\n", SS_YAML_KEY_SPEECH_IRQ, "false"); diff --git a/source/MouseInterface.cpp b/source/MouseInterface.cpp index b94bd73f..34b25788 100644 --- a/source/MouseInterface.cpp +++ b/source/MouseInterface.cpp @@ -666,9 +666,9 @@ void CMouseInterface::SaveSnapshot(class YamlSaveHelper& yamlSaveHelper) YamlSaveHelper::Label state(yamlSaveHelper, "%s:\n", SS_YAML_KEY_STATE); SaveSnapshotMC6821(yamlSaveHelper, SS_YAML_KEY_MC6821); yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_DATALEN, m_nDataLen); - yamlSaveHelper.SaveHex8(SS_YAML_KEY_MODE, m_byMode); - yamlSaveHelper.SaveHex8(SS_YAML_KEY_6821B, m_by6821B); - yamlSaveHelper.SaveHex8(SS_YAML_KEY_6821A, m_by6821A); + yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_MODE, m_byMode); + yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_6821B, m_by6821B); + yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_6821A, m_by6821A); // New label { @@ -677,7 +677,7 @@ void CMouseInterface::SaveSnapshot(class YamlSaveHelper& yamlSaveHelper) } yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_BUFFPOS, m_nBuffPos); - yamlSaveHelper.SaveHex8(SS_YAML_KEY_MOUSESTATE, m_byState); + yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_MOUSESTATE, m_byState); yamlSaveHelper.SaveUint(SS_YAML_KEY_X, m_nX); yamlSaveHelper.SaveUint(SS_YAML_KEY_Y, m_nY); yamlSaveHelper.SaveBool(SS_YAML_KEY_BTN0, m_bBtn0); diff --git a/source/SerialComms.cpp b/source/SerialComms.cpp index 83660262..5aa1f209 100644 --- a/source/SerialComms.cpp +++ b/source/SerialComms.cpp @@ -1369,8 +1369,8 @@ void CSuperSerialCard::SaveSnapshot(YamlSaveHelper& yamlSaveHelper) yamlSaveHelper.SaveUint(SS_YAML_KEY_STOPBITS, m_uStopBits); yamlSaveHelper.SaveUint(SS_YAML_KEY_BYTESIZE, m_uByteSize); yamlSaveHelper.SaveUint(SS_YAML_KEY_PARITY, m_uParity); - yamlSaveHelper.SaveHex8(SS_YAML_KEY_CONTROL, m_uControlByte); - yamlSaveHelper.SaveHex8(SS_YAML_KEY_COMMAND, m_uCommandByte); + yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_CONTROL, m_uControlByte); + yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_COMMAND, m_uCommandByte); yamlSaveHelper.SaveUint(SS_YAML_KEY_INACTIVITY, m_dwCommInactivity); yamlSaveHelper.SaveBool(SS_YAML_KEY_TXIRQENABLED, m_bTxIrqEnabled); yamlSaveHelper.SaveBool(SS_YAML_KEY_RXIRQENABLED, m_bRxIrqEnabled); diff --git a/source/Speaker.cpp b/source/Speaker.cpp index 0a90f963..fcf1dd9f 100644 --- a/source/Speaker.cpp +++ b/source/Speaker.cpp @@ -1111,7 +1111,7 @@ static std::string SpkrGetSnapshotStructName(void) void SpkrSaveSnapshot(YamlSaveHelper& yamlSaveHelper) { YamlSaveHelper::Label state(yamlSaveHelper, "%s:\n", SpkrGetSnapshotStructName().c_str()); - yamlSaveHelper.SaveHex64(SS_YAML_KEY_LASTCYCLE, g_nSpkrLastCycle); + yamlSaveHelper.SaveHexUint64(SS_YAML_KEY_LASTCYCLE, g_nSpkrLastCycle); } void SpkrLoadSnapshot(YamlLoadHelper& yamlLoadHelper) diff --git a/source/Video.cpp b/source/Video.cpp index 02d3720e..6b82c5ff 100644 --- a/source/Video.cpp +++ b/source/Video.cpp @@ -2964,7 +2964,7 @@ void VideoSaveSnapshot(YamlSaveHelper& yamlSaveHelper) { YamlSaveHelper::Label state(yamlSaveHelper, "%s:\n", VideoGetSnapshotStructName().c_str()); yamlSaveHelper.SaveBool(SS_YAML_KEY_ALTCHARSET, g_nAltCharSetOffset ? true : false); - yamlSaveHelper.SaveHex32(SS_YAML_KEY_VIDEOMODE, g_uVideoMode); + yamlSaveHelper.SaveHexUint32(SS_YAML_KEY_VIDEOMODE, g_uVideoMode); yamlSaveHelper.SaveUint(SS_YAML_KEY_CYCLESTHISFRAME, g_dwCyclesThisFrame); } diff --git a/source/YamlHelper.cpp b/source/YamlHelper.cpp index bc304b6d..883e5982 100644 --- a/source/YamlHelper.cpp +++ b/source/YamlHelper.cpp @@ -368,32 +368,32 @@ void YamlSaveHelper::SaveUint(const char* key, UINT value) Save("%s: %u\n", key, value); } -void YamlSaveHelper::SaveHex4(const char* key, UINT value) +void YamlSaveHelper::SaveHexUint4(const char* key, UINT value) { Save("%s: 0x%01X\n", key, value); } -void YamlSaveHelper::SaveHex8(const char* key, UINT value) +void YamlSaveHelper::SaveHexUint8(const char* key, UINT value) { Save("%s: 0x%02X\n", key, value); } -void YamlSaveHelper::SaveHex12(const char* key, UINT value) +void YamlSaveHelper::SaveHexUint12(const char* key, UINT value) { Save("%s: 0x%03X\n", key, value); } -void YamlSaveHelper::SaveHex16(const char* key, UINT value) +void YamlSaveHelper::SaveHexUint16(const char* key, UINT value) { Save("%s: 0x%04X\n", key, value); } -void YamlSaveHelper::SaveHex32(const char* key, UINT value) +void YamlSaveHelper::SaveHexUint32(const char* key, UINT value) { Save("%s: 0x%08X\n", key, value); } -void YamlSaveHelper::SaveHex64(const char* key, UINT64 value) +void YamlSaveHelper::SaveHexUint64(const char* key, UINT64 value) { Save("%s: 0x%016llX\n", key, value); } diff --git a/source/YamlHelper.h b/source/YamlHelper.h index 6cdb0fb2..31e871ca 100644 --- a/source/YamlHelper.h +++ b/source/YamlHelper.h @@ -205,12 +205,12 @@ public: void SaveInt(const char* key, int value); void SaveUint(const char* key, UINT value); - void SaveHex4(const char* key, UINT value); - void SaveHex8(const char* key, UINT value); - void SaveHex12(const char* key, UINT value); - void SaveHex16(const char* key, UINT value); - void SaveHex32(const char* key, UINT value); - void SaveHex64(const char* key, UINT64 value); + void SaveHexUint4(const char* key, UINT value); + void SaveHexUint8(const char* key, UINT value); + void SaveHexUint12(const char* key, UINT value); + void SaveHexUint16(const char* key, UINT value); + void SaveHexUint32(const char* key, UINT value); + void SaveHexUint64(const char* key, UINT64 value); void SaveBool(const char* key, bool value); void SaveString(const char* key, const char* value); void SaveMemory(const LPBYTE pMemBase, const UINT uMemSize); diff --git a/source/Z80VICE/z80.cpp b/source/Z80VICE/z80.cpp index c84d51e0..7738cb40 100644 --- a/source/Z80VICE/z80.cpp +++ b/source/Z80VICE/z80.cpp @@ -6491,33 +6491,33 @@ void Z80_SaveSnapshot(class YamlSaveHelper& yamlSaveHelper, const UINT uSlot) yamlSaveHelper.Save("%s: %d\n", SS_YAML_KEY_ACTIVE, GetActiveCpu() == CPU_Z80 ? 1 : 0); - yamlSaveHelper.SaveHex8(SS_YAML_KEY_REGA, reg_a); - yamlSaveHelper.SaveHex8(SS_YAML_KEY_REGB, reg_b); - yamlSaveHelper.SaveHex8(SS_YAML_KEY_REGC, reg_c); - yamlSaveHelper.SaveHex8(SS_YAML_KEY_REGD, reg_d); - yamlSaveHelper.SaveHex8(SS_YAML_KEY_REGE, reg_e); - yamlSaveHelper.SaveHex8(SS_YAML_KEY_REGF, reg_f); - yamlSaveHelper.SaveHex8(SS_YAML_KEY_REGH, reg_h); - yamlSaveHelper.SaveHex8(SS_YAML_KEY_REGL, reg_l); - yamlSaveHelper.SaveHex16(SS_YAML_KEY_REGIX, ((USHORT)reg_ixh<<8)|(USHORT)reg_ixl); - yamlSaveHelper.SaveHex16(SS_YAML_KEY_REGIY, ((USHORT)reg_iyh<<8)|(USHORT)reg_iyl); - yamlSaveHelper.SaveHex16(SS_YAML_KEY_REGSP, reg_sp); - yamlSaveHelper.SaveHex16(SS_YAML_KEY_REGPC, (USHORT)z80_reg_pc); - yamlSaveHelper.SaveHex8(SS_YAML_KEY_REGI, reg_i); - yamlSaveHelper.SaveHex8(SS_YAML_KEY_REGR, reg_r); + yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_REGA, reg_a); + yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_REGB, reg_b); + yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_REGC, reg_c); + yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_REGD, reg_d); + yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_REGE, reg_e); + yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_REGF, reg_f); + yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_REGH, reg_h); + yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_REGL, reg_l); + yamlSaveHelper.SaveHexUint16(SS_YAML_KEY_REGIX, ((USHORT)reg_ixh<<8)|(USHORT)reg_ixl); + yamlSaveHelper.SaveHexUint16(SS_YAML_KEY_REGIY, ((USHORT)reg_iyh<<8)|(USHORT)reg_iyl); + yamlSaveHelper.SaveHexUint16(SS_YAML_KEY_REGSP, reg_sp); + yamlSaveHelper.SaveHexUint16(SS_YAML_KEY_REGPC, (USHORT)z80_reg_pc); + yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_REGI, reg_i); + yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_REGR, reg_r); - yamlSaveHelper.SaveHex8(SS_YAML_KEY_IFF1, iff1); - yamlSaveHelper.SaveHex8(SS_YAML_KEY_IFF2, iff2); - yamlSaveHelper.SaveHex8(SS_YAML_KEY_IM_MODE, im_mode); + yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_IFF1, iff1); + yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_IFF2, iff2); + yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_IM_MODE, im_mode); - yamlSaveHelper.SaveHex8(SS_YAML_KEY_REGA2, reg_a2); - yamlSaveHelper.SaveHex8(SS_YAML_KEY_REGB2, reg_b2); - yamlSaveHelper.SaveHex8(SS_YAML_KEY_REGC2, reg_c2); - yamlSaveHelper.SaveHex8(SS_YAML_KEY_REGD2, reg_d2); - yamlSaveHelper.SaveHex8(SS_YAML_KEY_REGE2, reg_e2); - yamlSaveHelper.SaveHex8(SS_YAML_KEY_REGF2, reg_f2); - yamlSaveHelper.SaveHex8(SS_YAML_KEY_REGH2, reg_h2); - yamlSaveHelper.SaveHex8(SS_YAML_KEY_REGL2, reg_l2); + yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_REGA2, reg_a2); + yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_REGB2, reg_b2); + yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_REGC2, reg_c2); + yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_REGD2, reg_d2); + yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_REGE2, reg_e2); + yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_REGF2, reg_f2); + yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_REGH2, reg_h2); + yamlSaveHelper.SaveHexUint8(SS_YAML_KEY_REGL2, reg_l2); } bool Z80_LoadSnapshot(class YamlLoadHelper& yamlLoadHelper, UINT uSlot, UINT version) From 8462426ccda4eb8d52915a3323549340e013d9e4 Mon Sep 17 00:00:00 2001 From: tomcw Date: Sat, 5 Mar 2016 18:31:42 +0000 Subject: [PATCH 20/20] Update VS2013 sln/proj for yaml and TestCPU65C02 --- AppleWinExpress2013.sln | 26 ++++- AppleWinExpress2013.vcxproj | 52 +++++++-- AppleWinExpress2013.vcxproj.filters | 15 ++- libyaml/win32/yaml2013.vcxproj | 100 ++++++++++++++++++ libyaml/win32/yaml2013.vcxproj.filters | 54 ++++++++++ source/Applewin.cpp | 2 +- test/TestCPU6502/TestCPU6502-vs2013.vcxproj | 89 ++++++++++++++++ .../TestCPU6502-vs2013.vcxproj.filters | 22 ++++ 8 files changed, 346 insertions(+), 14 deletions(-) create mode 100644 libyaml/win32/yaml2013.vcxproj create mode 100644 libyaml/win32/yaml2013.vcxproj.filters create mode 100644 test/TestCPU6502/TestCPU6502-vs2013.vcxproj create mode 100644 test/TestCPU6502/TestCPU6502-vs2013.vcxproj.filters diff --git a/AppleWinExpress2013.sln b/AppleWinExpress2013.sln index e4ea32bb..10dc5eb9 100644 --- a/AppleWinExpress2013.sln +++ b/AppleWinExpress2013.sln @@ -1,8 +1,12 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Express 2012 for Windows Desktop +# Visual Studio 2013 +VisualStudioVersion = 12.0.31101.0 +MinimumVisualStudioVersion = 10.0.40219.1 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AppleWin", "AppleWinExpress2013.vcxproj", "{0A960136-A00A-4D4B-805F-664D9950D2CA}" ProjectSection(ProjectDependencies) = postProject + {CF5A49BF-62A5-41BB-B10C-F34D556A7A45} = {CF5A49BF-62A5-41BB-B10C-F34D556A7A45} + {0212E0DF-06DA-4080-BD1D-F3B01599F70F} = {0212E0DF-06DA-4080-BD1D-F3B01599F70F} {509739E7-0AF3-4C09-A1A9-F0B1BC31B39D} = {509739E7-0AF3-4C09-A1A9-F0B1BC31B39D} {9B32A6E7-1237-4F36-8903-A3FD51DF9C4E} = {9B32A6E7-1237-4F36-8903-A3FD51DF9C4E} EndProjectSection @@ -11,6 +15,10 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zip_lib", "zip_lib\zip_lib2 EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlib", "zlib\zlib-Express2013.vcxproj", "{9B32A6E7-1237-4F36-8903-A3FD51DF9C4E}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "yaml", "libyaml\win32\yaml2013.vcxproj", "{0212E0DF-06DA-4080-BD1D-F3B01599F70F}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TestCPU6502", "test\TestCPU6502\TestCPU6502-vs2013.vcxproj", "{CF5A49BF-62A5-41BB-B10C-F34D556A7A45}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug NoDX|Win32 = Debug NoDX|Win32 @@ -43,6 +51,22 @@ Global {9B32A6E7-1237-4F36-8903-A3FD51DF9C4E}.Release NoDX|Win32.Build.0 = Release|Win32 {9B32A6E7-1237-4F36-8903-A3FD51DF9C4E}.Release|Win32.ActiveCfg = Release|Win32 {9B32A6E7-1237-4F36-8903-A3FD51DF9C4E}.Release|Win32.Build.0 = Release|Win32 + {0212E0DF-06DA-4080-BD1D-F3B01599F70F}.Debug NoDX|Win32.ActiveCfg = Debug|Win32 + {0212E0DF-06DA-4080-BD1D-F3B01599F70F}.Debug NoDX|Win32.Build.0 = Debug|Win32 + {0212E0DF-06DA-4080-BD1D-F3B01599F70F}.Debug|Win32.ActiveCfg = Debug|Win32 + {0212E0DF-06DA-4080-BD1D-F3B01599F70F}.Debug|Win32.Build.0 = Debug|Win32 + {0212E0DF-06DA-4080-BD1D-F3B01599F70F}.Release NoDX|Win32.ActiveCfg = Release|Win32 + {0212E0DF-06DA-4080-BD1D-F3B01599F70F}.Release NoDX|Win32.Build.0 = Release|Win32 + {0212E0DF-06DA-4080-BD1D-F3B01599F70F}.Release|Win32.ActiveCfg = Release|Win32 + {0212E0DF-06DA-4080-BD1D-F3B01599F70F}.Release|Win32.Build.0 = Release|Win32 + {CF5A49BF-62A5-41BB-B10C-F34D556A7A45}.Debug NoDX|Win32.ActiveCfg = Debug|Win32 + {CF5A49BF-62A5-41BB-B10C-F34D556A7A45}.Debug NoDX|Win32.Build.0 = Debug|Win32 + {CF5A49BF-62A5-41BB-B10C-F34D556A7A45}.Debug|Win32.ActiveCfg = Debug|Win32 + {CF5A49BF-62A5-41BB-B10C-F34D556A7A45}.Debug|Win32.Build.0 = Debug|Win32 + {CF5A49BF-62A5-41BB-B10C-F34D556A7A45}.Release NoDX|Win32.ActiveCfg = Release|Win32 + {CF5A49BF-62A5-41BB-B10C-F34D556A7A45}.Release NoDX|Win32.Build.0 = Release|Win32 + {CF5A49BF-62A5-41BB-B10C-F34D556A7A45}.Release|Win32.ActiveCfg = Release|Win32 + {CF5A49BF-62A5-41BB-B10C-F34D556A7A45}.Release|Win32.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/AppleWinExpress2013.vcxproj b/AppleWinExpress2013.vcxproj index b3b56a50..54bad663 100644 --- a/AppleWinExpress2013.vcxproj +++ b/AppleWinExpress2013.vcxproj @@ -80,13 +80,14 @@ + + - @@ -98,6 +99,7 @@ + @@ -193,6 +195,7 @@ NotUsing
+ NotUsing @@ -239,6 +242,9 @@ {9b32a6e7-1237-4f36-8903-a3fd51df9c4e} + + {0212e0df-06da-4080-bd1d-f3b01599f70f} + @@ -345,9 +351,9 @@ Use Level3 Disabled - WIN32;_DEBUG;_WINDOWS;_CRT_SECURE_NO_DEPRECATE;NO_DSHOW_STRSAFE;%(PreprocessorDefinitions) + WIN32;_DEBUG;_WINDOWS;_CRT_SECURE_NO_DEPRECATE;NO_DSHOW_STRSAFE;YAML_DECLARE_STATIC;%(PreprocessorDefinitions) true - source\cpu;source\emulator;source\debugger;zlib;zip_lib;%(AdditionalIncludeDirectories) + source\cpu;source\emulator;source\debugger;zlib;zip_lib;libyaml\include;%(AdditionalIncludeDirectories) MultiThreadedDebug @@ -356,15 +362,22 @@ htmlhelp.lib;comctl32.lib;ddraw.lib;winmm.lib;dsound.lib;dxguid.lib;version.lib;strmiids.lib;dinput8.lib;user32.lib;gdi32.lib;Advapi32.lib;shell32.lib;Comdlg32.lib;ole32.lib;wsock32.lib;%(AdditionalDependencies) "type='Win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='X86' publicKeyToken='6595b64144ccf1df' language='*'" + + echo Performing unit-test: TestCPU6502 +.\Debug\TestCPU6502.exe + + + Performing unit-test: TestCPU6502 + Use Level3 Disabled - WIN32;_DEBUG;_WINDOWS;_CRT_SECURE_NO_DEPRECATE;NO_DSHOW_STRSAFE;NO_DIRECT_X;%(PreprocessorDefinitions) + WIN32;_DEBUG;_WINDOWS;_CRT_SECURE_NO_DEPRECATE;NO_DSHOW_STRSAFE;NO_DIRECT_X;YAML_DECLARE_STATIC;%(PreprocessorDefinitions) true - source\cpu;source\emulator;source\debugger;zlib;zip_lib;%(AdditionalIncludeDirectories) + source\cpu;source\emulator;source\debugger;zlib;zip_lib;libyaml\include;%(AdditionalIncludeDirectories) MultiThreadedDebug @@ -373,6 +386,13 @@ htmlhelp.lib;comctl32.lib;ddraw.lib;winmm.lib;dsound.lib;dxguid.lib;version.lib;strmiids.lib;dinput8.lib;user32.lib;gdi32.lib;Advapi32.lib;shell32.lib;Comdlg32.lib;ole32.lib;wsock32.lib;%(AdditionalDependencies) "type='Win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='X86' publicKeyToken='6595b64144ccf1df' language='*'" + + echo Performing unit-test: TestCPU6502 +.\Debug\TestCPU6502.exe + + + Performing unit-test: TestCPU6502 + @@ -381,9 +401,9 @@ MaxSpeed true true - WIN32;NDEBUG;_WINDOWS;_CRT_SECURE_NO_DEPRECATE;NO_DSHOW_STRSAFE;%(PreprocessorDefinitions) + WIN32;NDEBUG;_WINDOWS;_CRT_SECURE_NO_DEPRECATE;NO_DSHOW_STRSAFE;YAML_DECLARE_STATIC;%(PreprocessorDefinitions) true - source\cpu;source\emulator;source\debugger;zlib;zip_lib;%(AdditionalIncludeDirectories) + source\cpu;source\emulator;source\debugger;zlib;zip_lib;libyaml\include;%(AdditionalIncludeDirectories) MultiThreaded Speed @@ -396,6 +416,13 @@ UseLinkTimeCodeGeneration "type='Win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='X86' publicKeyToken='6595b64144ccf1df' language='*'" + + echo Performing unit-test: TestCPU6502 +.\Release\TestCPU6502.exe + + + Performing unit-test: TestCPU6502 + @@ -404,9 +431,9 @@ MaxSpeed true true - WIN32;NDEBUG;_WINDOWS;_CRT_SECURE_NO_DEPRECATE;NO_DSHOW_STRSAFE;NO_DIRECT_X;%(PreprocessorDefinitions) + WIN32;NDEBUG;_WINDOWS;_CRT_SECURE_NO_DEPRECATE;NO_DSHOW_STRSAFE;NO_DIRECT_X;YAML_DECLARE_STATIC;%(PreprocessorDefinitions) true - source\cpu;source\emulator;source\debugger;zlib;zip_lib;%(AdditionalIncludeDirectories) + source\cpu;source\emulator;source\debugger;zlib;zip_lib;libyaml\include;%(AdditionalIncludeDirectories) MultiThreaded Speed @@ -419,6 +446,13 @@ UseLinkTimeCodeGeneration "type='Win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='X86' publicKeyToken='6595b64144ccf1df' language='*'" + + echo Performing unit-test: TestCPU6502 +.\Release\TestCPU6502.exe + + + Performing unit-test: TestCPU6502 + diff --git a/AppleWinExpress2013.vcxproj.filters b/AppleWinExpress2013.vcxproj.filters index d6bec9a5..1655702c 100644 --- a/AppleWinExpress2013.vcxproj.filters +++ b/AppleWinExpress2013.vcxproj.filters @@ -175,6 +175,9 @@ Source Files\Emulator + + Source Files\Emulator + @@ -375,9 +378,6 @@ Source Files - - Source Files\_Headers - Source Files\Emulator @@ -429,6 +429,15 @@ Source Files\Emulator + + Source Files\Emulator + + + Source Files\_Headers + + + Source Files\_Headers + diff --git a/libyaml/win32/yaml2013.vcxproj b/libyaml/win32/yaml2013.vcxproj new file mode 100644 index 00000000..5c510090 --- /dev/null +++ b/libyaml/win32/yaml2013.vcxproj @@ -0,0 +1,100 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + + + + + + + + + + + + + + + + + + + + {0212E0DF-06DA-4080-BD1D-F3B01599F70F} + Win32Proj + yaml2013 + yaml + + + + StaticLibrary + true + v120 + MultiByte + + + StaticLibrary + false + v120 + true + MultiByte + + + + + + + + + + + + + + + + + Level3 + Disabled + WIN32;_DEBUG;_LIB;HAVE_CONFIG_H;YAML_DECLARE_STATIC;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + .;../include + MultiThreadedDebug + + + Windows + true + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_LIB;HAVE_CONFIG_H;YAML_DECLARE_STATIC;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + .;../include + MultiThreaded + + + Windows + true + true + true + + + + + + \ No newline at end of file diff --git a/libyaml/win32/yaml2013.vcxproj.filters b/libyaml/win32/yaml2013.vcxproj.filters new file mode 100644 index 00000000..2446a756 --- /dev/null +++ b/libyaml/win32/yaml2013.vcxproj.filters @@ -0,0 +1,54 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;xsd + + + + + + + + + Header Files + + + Header Files + + + Header Files + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + \ No newline at end of file diff --git a/source/Applewin.cpp b/source/Applewin.cpp index 76eb67a6..4d3a8ee0 100644 --- a/source/Applewin.cpp +++ b/source/Applewin.cpp @@ -1089,7 +1089,7 @@ int APIENTRY WinMain(HINSTANCE passinstance, HINSTANCE, LPSTR lpCmdLine, int) Snapshot_SetFilename(szSnapshotName); Snapshot_LoadState(); bBoot = true; -#if _DEBUG && 1 // Debug/test: Save a duplicate of the save-state file in tmp folder +#if _DEBUG && 0 // Debug/test: Save a duplicate of the save-state file in tmp folder std::string saveName = std::string("tmp\\") + std::string(szSnapshotName); Snapshot_SetFilename(saveName); g_bSaveStateOnExit = true; diff --git a/test/TestCPU6502/TestCPU6502-vs2013.vcxproj b/test/TestCPU6502/TestCPU6502-vs2013.vcxproj new file mode 100644 index 00000000..3e2fbeb3 --- /dev/null +++ b/test/TestCPU6502/TestCPU6502-vs2013.vcxproj @@ -0,0 +1,89 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + + + + + + + + {CF5A49BF-62A5-41BB-B10C-F34D556A7A45} + Win32Proj + TestCPU6502vs2013 + TestCPU6502 + + + + Application + true + v120 + Unicode + + + Application + false + v120 + true + Unicode + + + + + + + + + + + + + true + + + false + + + + + + Level3 + Disabled + WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) + + + Console + true + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) + + + Console + true + true + true + + + + + + \ No newline at end of file diff --git a/test/TestCPU6502/TestCPU6502-vs2013.vcxproj.filters b/test/TestCPU6502/TestCPU6502-vs2013.vcxproj.filters new file mode 100644 index 00000000..71e4100b --- /dev/null +++ b/test/TestCPU6502/TestCPU6502-vs2013.vcxproj.filters @@ -0,0 +1,22 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + + + Source Files + + + Source Files + + + + + Source Files + + + \ No newline at end of file