#include "exports.h" #include "program_files.h" #include "pic-processor.h" #include "cod.h" #include "hexutils.h" #include "cmd_gpsim.h" /** * RegisterProgramFileType * Exported function for external modules to register their * file types. */ void LIBGPSIM_EXPORT RegisterProgramFileType(ProgramFileType * pPFT) { ProgramFileTypeList::GetList().push_back(pPFT); } void ProgramFileType::DisplayError(int err, const char *pProgFilename, const char *pLstFile) { int iMessage; const char * pArg = ""; switch(err) { case ERR_UNRECOGNIZED_PROCESSOR: iMessage = IDS_PROGRAM_FILE_PROCESSOR_NOT_KNOWN; break; case ERR_FILE_NOT_FOUND: iMessage = IDS_FILE_NOT_FOUND; pArg = pProgFilename; break; case ERR_FILE_NAME_TOO_LONG: iMessage = IDS_FILE_NAME_TOO_LONG; pArg = pProgFilename; break; case ERR_LST_FILE_NOT_FOUND: if(pLstFile == NULL) { iMessage = IDS_LIST_FILE_NOT_FOUND; pArg = pProgFilename; } else { iMessage = IDS_FILE_NOT_FOUND; pArg = pLstFile; } break; case ERR_BAD_FILE: iMessage = IDS_FILE_BAD_FORMAT; pArg = pProgFilename; break; case ERR_NO_PROCESSOR_SPECIFIED: iMessage = IDS_NO_PROCESSOR_SPECIFIED; break; case ERR_PROCESSOR_INIT_FAILED: iMessage = IDS_PROCESSOR_INIT_FAILED; break; case ERR_NEED_PROCESSOR_SPECIFIED: iMessage = IDS_FILE_NEED_PROCESSOR_SPECIFIED; break; default: iMessage = SUCCESS; break; } if(iMessage != SUCCESS) GetUserInterface().DisplayMessage(iMessage, pArg); } /** * ProgramFileTypeList * Singleton class to manage the many (as of now three) file types. */ ProgramFileTypeList * ProgramFileTypeList::s_ProgramFileTypeList = new ProgramFileTypeList(); // We will instantiate g_HexFileType and g_CodFileType here to be sure // they are instantiated after s_ProgramFileTypeList. The objects will // move should the PIC code moved to its own external module. static IntelHexProgramFileType g_HexFileType; static PicCodProgramFileType g_CodFileType; ProgramFileTypeList &ProgramFileTypeList::GetList() { return *s_ProgramFileTypeList; } ProgramFileTypeList::ProgramFileTypeList() { reserve(5); } ProgramFileTypeList::~ProgramFileTypeList() { } bool ProgramFileTypeList::LoadProgramFile(Processor **pProcessor, const char *pFilename, FILE *pFile, const char *pProcessorName) { iterator it; iterator itLast; iterator itEnd = end(); int iReturn = ProgramFileType::SUCCESS; for(it = begin(); it != itEnd; it++) { itLast = it; fseek(pFile, 0, SEEK_SET); get_symbol_table().clear(); if((iReturn = (*it)->LoadProgramFile(pProcessor, pFilename, pFile, pProcessorName)) == ProgramFileType::SUCCESS) { return true; } if(IsErrorDisplayableInLoop(iReturn)) { (*it)->DisplayError(iReturn, pFilename, NULL); } } if(!IsErrorDisplayableInLoop(iReturn)) { (*itLast)->DisplayError(iReturn, pFilename, NULL); } return false; } bool ProgramFileTypeList::IsErrorDisplayableInLoop(int iError) { return iError != ProgramFileType::SUCCESS && iError != ProgramFileType::ERR_BAD_FILE && iError != ProgramFileType::ERR_NEED_PROCESSOR_SPECIFIED && iError != ProgramFileType::ERR_LST_FILE_NOT_FOUND; } /// /// ProgramFileBuf /// Used to wrap the FILE pointer to the program file /// for libraries that use istreams. ///////////////////////////////////////////////////// ProgramFileBuf::ProgramFileBuf(FILE *pFile) { m_pFile = pFile; setg(m_Buffer + 4, m_Buffer + 4, m_Buffer + 4); } ProgramFileBuf::int_type ProgramFileBuf::underflow( ) { if(gptr() < egptr()) { return *gptr(); } int numPutback; numPutback = gptr() - eback(); if (numPutback > 4) { numPutback = 4; } std::memcpy (m_Buffer+(4-numPutback), gptr() - numPutback, numPutback); int num; if((num = ::fread((void*)( m_Buffer + 4), 1, m_iBufferSize - 4, m_pFile)) <= 0) { if(errno != 0) printf("%s\n", strerror(errno)); return (int_type )traits_type::eof(); } setg(m_Buffer + (4 - numPutback), m_Buffer + 4, m_Buffer + 4 + num); return *gptr(); } streamsize ProgramFileBuf::xsgetn( char_type *_Ptr, streamsize _Count) { return ::fread(_Ptr, _Count, 1, m_pFile); }