<commit_before>//
// ImageLayer.cpp
//
// Copyright (c) 2002-2003 Virtual Terrain Project
// Free for all uses, see license.txt for details.
//

#include "wx/wxprec.h"

#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif

#include "ogr_spatialref.h"
#include "gdal_priv.h"
#include "ScaledView.h"
#include "ImageLayer.h"
#include "Helper.h"

vtImageLayer::vtImageLayer() : vtLayer(LT_IMAGE)
{
	m_pImage = NULL;
	m_pBitmap = NULL;
}

vtImageLayer::~vtImageLayer()
{
	if (NULL != m_pImage)
		delete m_pImage;
	if (NULL != m_pBitmap)
		delete m_pBitmap;
}

bool vtImageLayer::GetExtent(DRECT &rect)
{
	rect = m_Area;
	return true;
}

void vtImageLayer::DrawLayer(wxDC* pDC, vtScaledView *pView)
{
	if (NULL == m_pImage)
		return;
	if (!m_pImage->Ok())
		return;

	wxRect screenrect = pView->WorldToCanvas(m_Area);
	wxRect destRect = screenrect;
	wxRect srcRect(0, 0, m_pImage->GetWidth(), m_pImage->GetHeight());

	double ratio_x = (float) srcRect.GetWidth() / destRect.GetWidth();
	double ratio_y = (float) srcRect.GetHeight() / destRect.GetHeight();

	// scale and draw the bitmap
	// must use SetUserScale since StretchBlt is not supported
	double scale_x = 1.0/ratio_x;
	double scale_y = 1.0/ratio_y;
	pDC->SetUserScale(scale_x, scale_y);
#if WIN32
	::SetStretchBltMode((HDC) (pDC->GetHDC()), HALFTONE );
#endif
	pDC->DrawBitmap(*m_pBitmap, (int) (destRect.x/scale_x),
		(int) (destRect.y/scale_y), false);

	// restore
	pDC->SetUserScale(1.0, 1.0);
}

bool vtImageLayer::ConvertProjection(vtProjection &proj)
{
	return false;
}

bool vtImageLayer::OnSave()
{
	return false;
}

bool vtImageLayer::OnLoad()
{
	return LoadFromGDAL();
}

bool vtImageLayer::AppendDataFrom(vtLayer *pL)
{
	return false;
}

void vtImageLayer::GetProjection(vtProjection &proj)
{
	proj = m_Proj;
}

void vtImageLayer::SetProjection(const vtProjection &proj)
{
	m_Proj = proj;
}

bool vtImageLayer::LoadFromGDAL()
{
	GDALDataset *pDataset = NULL;
	OGRErr err;
	const char *pProjectionString;
	double affineTransform[6];
	OGRSpatialReference SpatialReference;
	double linearConversionFactor;
	GDALRasterBand *pBand;
	GDALColorTable *pTable;
	GDALColorEntry Ent;
	int i;
	int iRasterCount;
	bool bRet = true;
	unsigned char *pData;
	int xBlockSize, yBlockSize;
	int nxBlocks, nyBlocks;
	int ixBlock, iyBlock;
	int nxValid, nyValid;
	CPLErr Err;
	char *pScanline = NULL;
	char *pRedline = NULL;
	char *pGreenline = NULL;
	char *pBlueline = NULL;
	GDALRasterBand *pRed = NULL;
	GDALRasterBand *pGreen = NULL;
	GDALRasterBand *pBlue = NULL;
	int x, y;
	int iPixelHeight;
	int iPixelWidth;
	double TLGeoX, TLGeoY, BRGeoX, BRGeoY;

	try
	{
		GDALAllRegister();

		pDataset = (GDALDataset *) GDALOpen(m_strFilename.mb_str(), GA_ReadOnly);
		if(pDataset == NULL )
			throw "Couldn't open that file.";

		iPixelWidth = pDataset->GetRasterXSize();
		iPixelHeight = pDataset->GetRasterYSize();

		if (NULL == (pProjectionString = pDataset->GetProjectionRef()))
			throw "Unknown coordinate system.";

		err = SpatialReference.importFromWkt((char**)&pProjectionString);
		if (err != OGRERR_NONE)
			throw "Unknown coordinate system.";

		if (CE_None != pDataset->GetGeoTransform(affineTransform))
			throw "Dataset does not contain a valid affine transform.";

		if (SpatialReference.IsGeographic())
		{
			// More work needed...
			// Try to convert to projected
			OGRCoordinateTransformation *pCoordTransform;
			OGRSpatialReference NewSpatialReference;
			double Lat, Long;

			NewSpatialReference.SetWellKnownGeogCS("WGS84");

			// Get GEO coords of centre of image
			Long = affineTransform[0] + affineTransform[1] * iPixelWidth / 2 + affineTransform[2] * iPixelHeight / 2;
			Lat = affineTransform[3] + affineTransform[4] * iPixelWidth / 2 + affineTransform[5] * iPixelHeight / 2;

			// Set UTM projection
			NewSpatialReference.SetUTM((int)(Long + 180)/6 + 1, Lat > 0 ? 1 : 0);

			// Convert top left and bottom right to UTM
			if (NULL == (pCoordTransform = OGRCreateCoordinateTransformation(&SpatialReference, &NewSpatialReference)))
				throw "Couldn't create coordinate conversion.";
			// Calculate image size in metres
			TLGeoX = affineTransform[0];
			TLGeoY = affineTransform[3];
			BRGeoX = affineTransform[0] + affineTransform[1] * iPixelWidth + affineTransform[2] * iPixelHeight;
			BRGeoY = affineTransform[3] + affineTransform[4] * iPixelWidth + affineTransform[5] * iPixelHeight;
			if (!pCoordTransform->Transform(1, &TLGeoX, &TLGeoY))
				throw "Couldn't transform coordinates.";
			if (!pCoordTransform->Transform(1, &BRGeoX, &BRGeoY))
				throw "Couldn't transform coordinates.";
			m_Area.top = TLGeoY;
			m_Area.bottom = BRGeoY;
			m_Area.left = TLGeoX;
			m_Area.right = BRGeoX;
			m_Proj.SetSpatialReference(&NewSpatialReference);
		}
		else
		{
			linearConversionFactor = SpatialReference.GetLinearUnits();

			// Compute extent using the top left and bottom right image co-ordinates
			m_Area.left = (affineTransform[0] /*+ affineTransform[1] * 0*/ + affineTransform[2] * iPixelHeight) * linearConversionFactor;
			m_Area.right = (affineTransform[0] + affineTransform[1] * iPixelWidth /*+ affineTransform[2] * 0*/) * linearConversionFactor;
			m_Area.top = (affineTransform[3] /*+ affineTransform[4] * 0*/ + affineTransform[5] * iPixelHeight) * linearConversionFactor;
			m_Area.bottom = (affineTransform[3] + affineTransform[4] * iPixelWidth /*+ affineTransform[5] * 0*/) * linearConversionFactor;
			m_Proj.SetSpatialReference(&SpatialReference);
		}

		// Set up bitmap
		if (NULL == (m_pImage = new wxImage(iPixelWidth, iPixelHeight)))
			throw "Couldn't create image.";

		pData = m_pImage->GetData();

		// Raster count should be 3 for colour images (assume RGB)
		iRasterCount = pDataset->GetRasterCount();
		if (iRasterCount == 1)
		{
			pBand = pDataset->GetRasterBand(1);
			// Check data type - it's either integer or float
			if (GDT_Byte != pBand->GetRasterDataType())
				throw "Raster is not of type byte.";
			if (GCI_PaletteIndex != pBand->GetColorInterpretation())
				throw "Couldn't get palette.";
			if (NULL == (pTable = pBand->GetColorTable()))
				throw "Couldn't get color table.";

			pBand->FlushBlock(0, 0);

			pBand->GetBlockSize(&xBlockSize, &yBlockSize);
			nxBlocks = (iPixelWidth + xBlockSize - 1) / xBlockSize;
			nyBlocks = (iPixelHeight + yBlockSize - 1) / yBlockSize;
			if (NULL == (pScanline = new char[xBlockSize * yBlockSize]))
				throw "Couldnt allocate scan line.";
			// Read the data
			// Convert to rgb and write to image
			for( iyBlock = 0; iyBlock < nyBlocks; iyBlock++ )
			{
				progress_callback(iyBlock * 100 / nyBlocks);
				for( ixBlock = 0; ixBlock < nxBlocks; ixBlock++ )
				{
					Err = pBand->ReadBlock(ixBlock, iyBlock, pScanline);
					if (Err != CE_None)
						return false;

					// Compute the portion of the block that is valid
					// for partial edge blocks.
					if ((ixBlock+1) * xBlockSize > iPixelWidth)
						nxValid = iPixelWidth - ixBlock * xBlockSize;
					else
						nxValid = xBlockSize;

					if( (iyBlock+1) * yBlockSize > iPixelHeight)
						nyValid = iPixelHeight - iyBlock * yBlockSize;
					else
						nyValid = yBlockSize;

					for( int iY = 0; iY < nyValid; iY++ )
					{
						y = (iyBlock * yBlockSize + iY);
						for( int iX = 0; iX < nxValid; iX++ )
						{
							x = (ixBlock * xBlockSize) + iX;
							pTable->GetColorEntryAsRGB(pScanline[iY * xBlockSize + iX], &Ent);
							m_pImage->SetRGB(x, y, Ent.c1, Ent.c2, Ent.c3);
//							*(pData + (y * iPixelWidth) + x) = Ent.c1;
//							*(pData + (y * iPixelWidth) + x + 1) = Ent.c2;
//							*(pData + (y * iPixelWidth) + x + 2) = Ent.c3;
						}
					}
				}
			}
		}
		else if (iRasterCount == 3)
		{
			for (i = 1; i <= 3; i++)
			{
				pBand = pDataset->GetRasterBand(i);
				// Check data type - it's either integer or float
				if (GDT_Byte != pBand->GetRasterDataType())
					throw "Three rasters, but not of type byte.";
				// I assume that the bands are in order RGB
				// I know "could do better"... but
				switch(pBand->GetColorInterpretation())
				{
				case GCI_RedBand:
					pRed = pBand;
					break;
				case GCI_GreenBand:
					pGreen = pBand;
					break;
				case GCI_BlueBand:
					pBlue = pBand;
					break;
				}
			}
			if ((NULL == pRed) || (NULL == pGreen) || (NULL == pBlue))
				throw "Couldn't find bands for Red, Green, Blue.";

			pRed->GetBlockSize(&xBlockSize, &yBlockSize);
			nxBlocks = (iPixelWidth + xBlockSize - 1) / xBlockSize;
			nyBlocks = (iPixelHeight + yBlockSize - 1) / yBlockSize;
			pRed->FlushBlock(0, 0);
			pGreen->FlushBlock(0, 0);
			pBlue->FlushBlock(0, 0);
			pRedline = new char[xBlockSize * yBlockSize];
			pGreenline = new char[xBlockSize * yBlockSize];
			pBlueline = new char[xBlockSize * yBlockSize];

			for( iyBlock = 0; iyBlock < nyBlocks; iyBlock++ )
			{
				progress_callback(iyBlock * 100 / nyBlocks);
				for( ixBlock = 0; ixBlock < nxBlocks; ixBlock++ )
				{
					Err = pRed->ReadBlock(ixBlock, iyBlock, pRedline);
					if (Err != CE_None)
						return false;
					Err = pGreen->ReadBlock(ixBlock, iyBlock, pGreenline);
					if (Err != CE_None)
						return false;
					Err = pBlue->ReadBlock(ixBlock, iyBlock, pBlueline);
					if (Err != CE_None)
						return false;

					// Compute the portion of the block that is valid
					// for partial edge blocks.
					if ((ixBlock+1) * xBlockSize > iPixelWidth)
						nxValid = iPixelWidth - ixBlock * xBlockSize;
					else
						nxValid = xBlockSize;

					if( (iyBlock+1) * yBlockSize > iPixelHeight)
						nyValid = iPixelHeight - iyBlock * yBlockSize;
					else
						nyValid = yBlockSize;

					for( int iY = 0; iY < nyValid; iY++ )
					{
						y = (iyBlock * yBlockSize + iY);
						for( int iX = 0; iX < nxValid; iX++ )
						{
							x = (ixBlock * xBlockSize) + iX;
							m_pImage->SetRGB(x, y,
								pRedline[iY * xBlockSize + iX],
								pGreenline[iY * xBlockSize + iX],
								pBlueline[iY * xBlockSize + iX]);
//							*(pData + (y * iPixelWidth) + x) = pRedline[iY * xBlockSize + iX];
//							*(pData + (y * iPixelWidth) + x + 1) = pGreenline[iY * xBlockSize + iX];
//							*(pData + (y * iPixelWidth) + x + 2) = pBlueline[iY * xBlockSize + iX];
						}
					}
				}
			}
		}
		else
			throw "Image does not have 1 or 3 bands.";
	}

	catch (const char *msg)
	{
		wxString2 str = msg;
		wxMessageBox(str);
		bRet = false;
	}

	if (NULL != pDataset)
		GDALClose(pDataset);
	if (NULL != pScanline)
		delete pScanline;
	if (NULL != pRedline)
		delete pRedline;
	if (NULL != pGreenline)
		delete pGreenline;
	if (NULL != pBlueline)
		delete pBlueline;

	if (bRet == true)
	{
		m_pBitmap = new wxBitmap(m_pImage->ConvertToBitmap());
		if (!m_pBitmap || (m_pBitmap && !m_pBitmap->Ok()))
		{
			wxString str;
			str.Printf(_T("Couldn't create bitmap of size %d x %d"), iPixelWidth, iPixelHeight);
			wxMessageBox(str);
			bRet = false;
			delete m_pBitmap;
			m_pBitmap = NULL;
		}
	}
	if (bRet == false)
	{
		// Tidy up
		if (NULL != m_pImage)
		{
			delete m_pImage;
			m_pImage = NULL;
		}
	}
	return bRet;
}

<commit_msg>added support for using .prj files with image files that lack a built-in CS<commit_after>//
// ImageLayer.cpp
//
// Copyright (c) 2002-2003 Virtual Terrain Project
// Free for all uses, see license.txt for details.
//

#include "wx/wxprec.h"

#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif

#include "ogr_spatialref.h"
#include "gdal_priv.h"
#include "ScaledView.h"
#include "ImageLayer.h"
#include "Helper.h"

vtImageLayer::vtImageLayer() : vtLayer(LT_IMAGE)
{
	m_pImage = NULL;
	m_pBitmap = NULL;
}

vtImageLayer::~vtImageLayer()
{
	if (NULL != m_pImage)
		delete m_pImage;
	if (NULL != m_pBitmap)
		delete m_pBitmap;
}

bool vtImageLayer::GetExtent(DRECT &rect)
{
	rect = m_Area;
	return true;
}

void vtImageLayer::DrawLayer(wxDC* pDC, vtScaledView *pView)
{
	if (NULL == m_pImage)
		return;
	if (!m_pImage->Ok())
		return;

	wxRect screenrect = pView->WorldToCanvas(m_Area);
	wxRect destRect = screenrect;
	wxRect srcRect(0, 0, m_pImage->GetWidth(), m_pImage->GetHeight());

	double ratio_x = (float) srcRect.GetWidth() / destRect.GetWidth();
	double ratio_y = (float) srcRect.GetHeight() / destRect.GetHeight();

	// scale and draw the bitmap
	// must use SetUserScale since StretchBlt is not supported
	double scale_x = 1.0/ratio_x;
	double scale_y = 1.0/ratio_y;
	pDC->SetUserScale(scale_x, scale_y);
#if WIN32
	::SetStretchBltMode((HDC) (pDC->GetHDC()), HALFTONE );
#endif
	pDC->DrawBitmap(*m_pBitmap, (int) (destRect.x/scale_x),
		(int) (destRect.y/scale_y), false);

	// restore
	pDC->SetUserScale(1.0, 1.0);
}

bool vtImageLayer::ConvertProjection(vtProjection &proj)
{
	return false;
}

bool vtImageLayer::OnSave()
{
	return false;
}

bool vtImageLayer::OnLoad()
{
	return LoadFromGDAL();
}

bool vtImageLayer::AppendDataFrom(vtLayer *pL)
{
	return false;
}

void vtImageLayer::GetProjection(vtProjection &proj)
{
	proj = m_Proj;
}

void vtImageLayer::SetProjection(const vtProjection &proj)
{
	m_Proj = proj;
}

bool vtImageLayer::LoadFromGDAL()
{
	GDALDataset *pDataset = NULL;
	OGRErr err;
	const char *pProjectionString;
	double affineTransform[6];
	vtProjection SpatialReference;
	double linearConversionFactor;
	GDALRasterBand *pBand;
	GDALColorTable *pTable;
	GDALColorEntry Ent;
	int i;
	int iRasterCount;
	bool bRet = true;
	unsigned char *pData;
	int xBlockSize, yBlockSize;
	int nxBlocks, nyBlocks;
	int ixBlock, iyBlock;
	int nxValid, nyValid;
	CPLErr Err;
	char *pScanline = NULL;
	char *pRedline = NULL;
	char *pGreenline = NULL;
	char *pBlueline = NULL;
	GDALRasterBand *pRed = NULL;
	GDALRasterBand *pGreen = NULL;
	GDALRasterBand *pBlue = NULL;
	int x, y;
	int iPixelHeight;
	int iPixelWidth;
	double TLGeoX, TLGeoY, BRGeoX, BRGeoY;

	try
	{
		GDALAllRegister();

		pDataset = (GDALDataset *) GDALOpen(m_strFilename.mb_str(), GA_ReadOnly);
		if(pDataset == NULL )
			throw "Couldn't open that file.";

		iPixelWidth = pDataset->GetRasterXSize();
		iPixelHeight = pDataset->GetRasterYSize();

		if (NULL == (pProjectionString = pDataset->GetProjectionRef()))
		{
			// check for existence of .prj file
			bool bSuccess = SpatialReference.ReadProjFile(m_strFilename.mb_str());

			if (!bSuccess)
				throw "Unknown coordinate system.";
		}

		err = SpatialReference.importFromWkt((char**)&pProjectionString);
		if (err != OGRERR_NONE)
		{
			// check for existence of .prj file
			bool bSuccess = SpatialReference.ReadProjFile(m_strFilename.mb_str());

			if (!bSuccess)
				throw "Unknown coordinate system.";
		}

		if (CE_None != pDataset->GetGeoTransform(affineTransform))
			throw "Dataset does not contain a valid affine transform.";

		if (SpatialReference.IsGeographic())
		{
			// More work needed...
			// Try to convert to projected
			OGRCoordinateTransformation *pCoordTransform;
			OGRSpatialReference NewSpatialReference;
			double Lat, Long;

			NewSpatialReference.SetWellKnownGeogCS("WGS84");

			// Get GEO coords of centre of image
			Long = affineTransform[0] + affineTransform[1] * iPixelWidth / 2 + affineTransform[2] * iPixelHeight / 2;
			Lat = affineTransform[3] + affineTransform[4] * iPixelWidth / 2 + affineTransform[5] * iPixelHeight / 2;

			// Set UTM projection
			NewSpatialReference.SetUTM((int)(Long + 180)/6 + 1, Lat > 0 ? 1 : 0);

			// Convert top left and bottom right to UTM
			if (NULL == (pCoordTransform = OGRCreateCoordinateTransformation(&SpatialReference, &NewSpatialReference)))
				throw "Couldn't create coordinate conversion.";
			// Calculate image size in metres
			TLGeoX = affineTransform[0];
			TLGeoY = affineTransform[3];
			BRGeoX = affineTransform[0] + affineTransform[1] * iPixelWidth + affineTransform[2] * iPixelHeight;
			BRGeoY = affineTransform[3] + affineTransform[4] * iPixelWidth + affineTransform[5] * iPixelHeight;
			if (!pCoordTransform->Transform(1, &TLGeoX, &TLGeoY))
				throw "Couldn't transform coordinates.";
			if (!pCoordTransform->Transform(1, &BRGeoX, &BRGeoY))
				throw "Couldn't transform coordinates.";
			m_Area.top = TLGeoY;
			m_Area.bottom = BRGeoY;
			m_Area.left = TLGeoX;
			m_Area.right = BRGeoX;
			m_Proj.SetSpatialReference(&NewSpatialReference);
		}
		else
		{
			linearConversionFactor = SpatialReference.GetLinearUnits();

			// Compute extent using the top left and bottom right image co-ordinates
			m_Area.left = (affineTransform[0] /*+ affineTransform[1] * 0*/ + affineTransform[2] * iPixelHeight) * linearConversionFactor;
			m_Area.right = (affineTransform[0] + affineTransform[1] * iPixelWidth /*+ affineTransform[2] * 0*/) * linearConversionFactor;
			m_Area.top = (affineTransform[3] /*+ affineTransform[4] * 0*/ + affineTransform[5] * iPixelHeight) * linearConversionFactor;
			m_Area.bottom = (affineTransform[3] + affineTransform[4] * iPixelWidth /*+ affineTransform[5] * 0*/) * linearConversionFactor;
			m_Proj.SetSpatialReference(&SpatialReference);
		}

		// Set up bitmap
		if (NULL == (m_pImage = new wxImage(iPixelWidth, iPixelHeight)))
			throw "Couldn't create image.";

		pData = m_pImage->GetData();

		// Raster count should be 3 for colour images (assume RGB)
		iRasterCount = pDataset->GetRasterCount();
		if (iRasterCount == 1)
		{
			pBand = pDataset->GetRasterBand(1);
			// Check data type - it's either integer or float
			if (GDT_Byte != pBand->GetRasterDataType())
				throw "Raster is not of type byte.";
			if (GCI_PaletteIndex != pBand->GetColorInterpretation())
				throw "Couldn't get palette.";
			if (NULL == (pTable = pBand->GetColorTable()))
				throw "Couldn't get color table.";

			pBand->FlushBlock(0, 0);

			pBand->GetBlockSize(&xBlockSize, &yBlockSize);
			nxBlocks = (iPixelWidth + xBlockSize - 1) / xBlockSize;
			nyBlocks = (iPixelHeight + yBlockSize - 1) / yBlockSize;
			if (NULL == (pScanline = new char[xBlockSize * yBlockSize]))
				throw "Couldnt allocate scan line.";
			// Read the data
			// Convert to rgb and write to image
			for( iyBlock = 0; iyBlock < nyBlocks; iyBlock++ )
			{
				progress_callback(iyBlock * 100 / nyBlocks);
				for( ixBlock = 0; ixBlock < nxBlocks; ixBlock++ )
				{
					Err = pBand->ReadBlock(ixBlock, iyBlock, pScanline);
					if (Err != CE_None)
						return false;

					// Compute the portion of the block that is valid
					// for partial edge blocks.
					if ((ixBlock+1) * xBlockSize > iPixelWidth)
						nxValid = iPixelWidth - ixBlock * xBlockSize;
					else
						nxValid = xBlockSize;

					if( (iyBlock+1) * yBlockSize > iPixelHeight)
						nyValid = iPixelHeight - iyBlock * yBlockSize;
					else
						nyValid = yBlockSize;

					for( int iY = 0; iY < nyValid; iY++ )
					{
						y = (iyBlock * yBlockSize + iY);
						for( int iX = 0; iX < nxValid; iX++ )
						{
							x = (ixBlock * xBlockSize) + iX;
							pTable->GetColorEntryAsRGB(pScanline[iY * xBlockSize + iX], &Ent);
							m_pImage->SetRGB(x, y, Ent.c1, Ent.c2, Ent.c3);
//							*(pData + (y * iPixelWidth) + x) = Ent.c1;
//							*(pData + (y * iPixelWidth) + x + 1) = Ent.c2;
//							*(pData + (y * iPixelWidth) + x + 2) = Ent.c3;
						}
					}
				}
			}
		}
		else if (iRasterCount == 3)
		{
			for (i = 1; i <= 3; i++)
			{
				pBand = pDataset->GetRasterBand(i);
				// Check data type - it's either integer or float
				if (GDT_Byte != pBand->GetRasterDataType())
					throw "Three rasters, but not of type byte.";
				// I assume that the bands are in order RGB
				// I know "could do better"... but
				switch(pBand->GetColorInterpretation())
				{
				case GCI_RedBand:
					pRed = pBand;
					break;
				case GCI_GreenBand:
					pGreen = pBand;
					break;
				case GCI_BlueBand:
					pBlue = pBand;
					break;
				}
			}
			if ((NULL == pRed) || (NULL == pGreen) || (NULL == pBlue))
				throw "Couldn't find bands for Red, Green, Blue.";

			pRed->GetBlockSize(&xBlockSize, &yBlockSize);
			nxBlocks = (iPixelWidth + xBlockSize - 1) / xBlockSize;
			nyBlocks = (iPixelHeight + yBlockSize - 1) / yBlockSize;
			pRed->FlushBlock(0, 0);
			pGreen->FlushBlock(0, 0);
			pBlue->FlushBlock(0, 0);
			pRedline = new char[xBlockSize * yBlockSize];
			pGreenline = new char[xBlockSize * yBlockSize];
			pBlueline = new char[xBlockSize * yBlockSize];

			for( iyBlock = 0; iyBlock < nyBlocks; iyBlock++ )
			{
				progress_callback(iyBlock * 100 / nyBlocks);
				for( ixBlock = 0; ixBlock < nxBlocks; ixBlock++ )
				{
					Err = pRed->ReadBlock(ixBlock, iyBlock, pRedline);
					if (Err != CE_None)
						return false;
					Err = pGreen->ReadBlock(ixBlock, iyBlock, pGreenline);
					if (Err != CE_None)
						return false;
					Err = pBlue->ReadBlock(ixBlock, iyBlock, pBlueline);
					if (Err != CE_None)
						return false;

					// Compute the portion of the block that is valid
					// for partial edge blocks.
					if ((ixBlock+1) * xBlockSize > iPixelWidth)
						nxValid = iPixelWidth - ixBlock * xBlockSize;
					else
						nxValid = xBlockSize;

					if( (iyBlock+1) * yBlockSize > iPixelHeight)
						nyValid = iPixelHeight - iyBlock * yBlockSize;
					else
						nyValid = yBlockSize;

					for( int iY = 0; iY < nyValid; iY++ )
					{
						y = (iyBlock * yBlockSize + iY);
						for( int iX = 0; iX < nxValid; iX++ )
						{
							x = (ixBlock * xBlockSize) + iX;
							m_pImage->SetRGB(x, y,
								pRedline[iY * xBlockSize + iX],
								pGreenline[iY * xBlockSize + iX],
								pBlueline[iY * xBlockSize + iX]);
//							*(pData + (y * iPixelWidth) + x) = pRedline[iY * xBlockSize + iX];
//							*(pData + (y * iPixelWidth) + x + 1) = pGreenline[iY * xBlockSize + iX];
//							*(pData + (y * iPixelWidth) + x + 2) = pBlueline[iY * xBlockSize + iX];
						}
					}
				}
			}
		}
		else
			throw "Image does not have 1 or 3 bands.";
	}

	catch (const char *msg)
	{
		wxString2 str = msg;
		wxMessageBox(str);
		bRet = false;
	}

	if (NULL != pDataset)
		GDALClose(pDataset);
	if (NULL != pScanline)
		delete pScanline;
	if (NULL != pRedline)
		delete pRedline;
	if (NULL != pGreenline)
		delete pGreenline;
	if (NULL != pBlueline)
		delete pBlueline;

	if (bRet == true)
	{
		m_pBitmap = new wxBitmap(m_pImage->ConvertToBitmap());
		if (!m_pBitmap || (m_pBitmap && !m_pBitmap->Ok()))
		{
			wxString str;
			str.Printf(_T("Couldn't create bitmap of size %d x %d"), iPixelWidth, iPixelHeight);
			wxMessageBox(str);
			bRet = false;
			delete m_pBitmap;
			m_pBitmap = NULL;
		}
	}
	if (bRet == false)
	{
		// Tidy up
		if (NULL != m_pImage)
		{
			delete m_pImage;
			m_pImage = NULL;
		}
	}
	return bRet;
}

<|endoftext|>


<commit_before>#ifdef STAN_OPENCL
#include <stan/math/opencl/rev.hpp>
#include <stan/math.hpp>
#include <gtest/gtest.h>
#include <test/unit/math/opencl/util.hpp>
#include <vector>

TEST(ProbDistributionsGamma, error_checking) {
  int N = 3;

  Eigen::VectorXd y(N);
  y << -2.0, 0.5, 1;
  Eigen::VectorXd y_size(N - 1);
  y_size << 0.1, 0.5;
  Eigen::VectorXd y_value(N);
  y_value << NAN, 0.5, 0.99;

  Eigen::VectorXd alpha(N);
  alpha << 0.3, 0.8, 1.0;
  Eigen::VectorXd alpha_size(N - 1);
  alpha_size << 0.3, 0.8;
  Eigen::VectorXd alpha_value1(N);
  alpha_value1 << 0.3, -0.8, 0.5;
  Eigen::VectorXd alpha_value2(N);
  alpha_value2 << 0.3, INFINITY, 0.5;

  Eigen::VectorXd beta(N);
  beta << 0.3, 0.8, 1.0;
  Eigen::VectorXd beta_size(N - 1);
  beta_size << 0.3, 0.8;
  Eigen::VectorXd beta_value1(N);
  beta_value1 << 0.3, -0.8, 0.5;
  Eigen::VectorXd beta_value2(N);
  beta_value2 << 0.3, INFINITY, 0.5;

  stan::math::matrix_cl<double> y_cl(y);
  stan::math::matrix_cl<double> y_size_cl(y_size);
  stan::math::matrix_cl<double> y_value_cl(y_value);

  stan::math::matrix_cl<double> alpha_cl(alpha);
  stan::math::matrix_cl<double> alpha_size_cl(alpha_size);
  stan::math::matrix_cl<double> alpha_value1_cl(alpha_value1);
  stan::math::matrix_cl<double> alpha_value2_cl(alpha_value2);

  stan::math::matrix_cl<double> beta_cl(beta);
  stan::math::matrix_cl<double> beta_size_cl(beta_size);
  stan::math::matrix_cl<double> beta_value1_cl(beta_value1);
  stan::math::matrix_cl<double> beta_value2_cl(beta_value2);

  EXPECT_NO_THROW(stan::math::gamma_lpdf(y_cl, alpha_cl, beta_cl));

  EXPECT_THROW(stan::math::gamma_lpdf(y_size_cl, alpha_cl, beta_cl),
               std::invalid_argument);
  EXPECT_THROW(stan::math::gamma_lpdf(y_cl, alpha_size_cl, beta_cl),
               std::invalid_argument);
  EXPECT_THROW(stan::math::gamma_lpdf(y_cl, alpha_cl, beta_size_cl),
               std::invalid_argument);

  EXPECT_THROW(stan::math::gamma_lpdf(y_value_cl, alpha_cl, beta_cl),
               std::domain_error);
  EXPECT_THROW(stan::math::gamma_lpdf(y_cl, alpha_value1_cl, beta_cl),
               std::domain_error);
  EXPECT_THROW(stan::math::gamma_lpdf(y_cl, alpha_cl, beta_value1_cl),
               std::domain_error);
  EXPECT_THROW(stan::math::gamma_lpdf(y_cl, alpha_value2_cl, beta_cl),
               std::domain_error);
  EXPECT_THROW(stan::math::gamma_lpdf(y_cl, alpha_cl, beta_value2_cl),
               std::domain_error);
}

auto gamma_lpdf_functor
    = [](const auto& y, const auto& alpha, const auto& beta) {
        return stan::math::gamma_lpdf(y, alpha, beta);
      };
auto gamma_lpdf_functor_propto
    = [](const auto& y, const auto& alpha, const auto& beta) {
        return stan::math::gamma_lpdf<true>(y, alpha, beta);
      };

TEST(ProbDistributionsGamma, opencl_matches_cpu_small) {
  int N = 3;

  Eigen::VectorXd y(N);
  y << 0, 0.5, 1;
  Eigen::VectorXd alpha(N);
  alpha << 0.3, 0.8, 1.0;
  Eigen::VectorXd beta(N);
  beta << 0.3, 0.8, 1.0;

  stan::math::test::compare_cpu_opencl_prim_rev(gamma_lpdf_functor, y, alpha,
                                                beta);
  stan::math::test::compare_cpu_opencl_prim_rev(gamma_lpdf_functor_propto, y,
                                                alpha, beta);
  stan::math::test::compare_cpu_opencl_prim_rev(
      gamma_lpdf_functor, y.transpose().eval(), alpha.transpose().eval(),
      beta.transpose().eval());
  stan::math::test::compare_cpu_opencl_prim_rev(
      gamma_lpdf_functor_propto, y.transpose().eval(), alpha.transpose().eval(),
      beta.transpose().eval());
}
TEST(ProbDistributionsGamma, opencl_matches_cpu_small_negative_y) {
  int N = 3;

  Eigen::VectorXd y(N);
  y << -10, 0.5, 1;
  Eigen::VectorXd alpha(N);
  alpha << 0.3, 0.8, 1.0;
  Eigen::VectorXd beta(N);
  beta << 0.3, 0.8, 1.0;

  stan::math::test::compare_cpu_opencl_prim_rev(gamma_lpdf_functor, y, alpha,
                                                beta);
  stan::math::test::compare_cpu_opencl_prim_rev(gamma_lpdf_functor_propto, y,
                                                alpha, beta);
}

TEST(ProbDistributionsGamma, opencl_broadcast_y) {
  int N = 3;

  double y = 0.3;
  Eigen::VectorXd alpha(N);
  alpha << 0.3, 0.8, 1.0;
  Eigen::VectorXd beta(N);
  beta << 0.3, 0.8, 1.0;

  stan::math::test::test_opencl_broadcasting_prim_rev<0>(gamma_lpdf_functor, y,
                                                         alpha, beta);
  stan::math::test::test_opencl_broadcasting_prim_rev<0>(
      gamma_lpdf_functor_propto, y, alpha, beta);
  stan::math::test::test_opencl_broadcasting_prim_rev<0>(
      gamma_lpdf_functor, y, alpha.transpose().eval(), beta);
  stan::math::test::test_opencl_broadcasting_prim_rev<0>(
      gamma_lpdf_functor_propto, y, alpha, beta.transpose().eval());
}

TEST(ProbDistributionsGamma, opencl_broadcast_alpha) {
  int N = 3;

  Eigen::VectorXd y(N);
  y << 0.3, 0.8, 1.0;
  double alpha = 0.3;
  Eigen::VectorXd beta(N);
  beta << 0.3, 0.8, 1.0;

  stan::math::test::test_opencl_broadcasting_prim_rev<1>(gamma_lpdf_functor, y,
                                                         alpha, beta);
  stan::math::test::test_opencl_broadcasting_prim_rev<1>(
      gamma_lpdf_functor_propto, y, alpha, beta);
  stan::math::test::test_opencl_broadcasting_prim_rev<1>(
      gamma_lpdf_functor, y.transpose().eval(), alpha, beta);
  stan::math::test::test_opencl_broadcasting_prim_rev<1>(
      gamma_lpdf_functor_propto, y, alpha, beta.transpose().eval());
}

TEST(ProbDistributionsGamma, opencl_broadcast_beta) {
  int N = 3;

  Eigen::VectorXd y(N);
  y << 0.3, 0.8, 1.0;
  Eigen::VectorXd alpha(N);
  alpha << 0.3, 0.8, 1.0;
  double beta = 0.3;

  stan::math::test::test_opencl_broadcasting_prim_rev<2>(gamma_lpdf_functor, y,
                                                         alpha, beta);
  stan::math::test::test_opencl_broadcasting_prim_rev<2>(
      gamma_lpdf_functor_propto, y, alpha, beta);
  stan::math::test::test_opencl_broadcasting_prim_rev<2>(
      gamma_lpdf_functor, y.transpose().eval(), alpha, beta);
  stan::math::test::test_opencl_broadcasting_prim_rev<2>(
      gamma_lpdf_functor_propto, y, alpha.transpose().eval(), beta);
}

TEST(ProbDistributionsGamma, opencl_matches_cpu_big) {
  int N = 153;

  Eigen::Matrix<double, Eigen::Dynamic, 1> y
      = Eigen::Array<double, Eigen::Dynamic, 1>::Random(N, 1).abs();
  Eigen::Matrix<double, Eigen::Dynamic, 1> alpha
      = Eigen::Array<double, Eigen::Dynamic, 1>::Random(N, 1).abs();
  Eigen::Matrix<double, Eigen::Dynamic, 1> beta
      = Eigen::Array<double, Eigen::Dynamic, 1>::Random(N, 1).abs();

  stan::math::test::compare_cpu_opencl_prim_rev(gamma_lpdf_functor, y, alpha,
                                                beta);
  stan::math::test::compare_cpu_opencl_prim_rev(gamma_lpdf_functor_propto, y,
                                                alpha, beta);
  stan::math::test::compare_cpu_opencl_prim_rev(
      gamma_lpdf_functor, y.transpose().eval(), alpha.transpose().eval(),
      beta.transpose().eval());
  stan::math::test::compare_cpu_opencl_prim_rev(
      gamma_lpdf_functor_propto, y.transpose().eval(), alpha.transpose().eval(),
      beta.transpose().eval());
}

#endif
<commit_msg>fix opencl tests<commit_after>#ifdef STAN_OPENCL
#include <stan/math/opencl/rev.hpp>
#include <stan/math.hpp>
#include <gtest/gtest.h>
#include <test/unit/math/opencl/util.hpp>
#include <vector>

TEST(ProbDistributionsGamma, error_checking) {
  int N = 3;

  Eigen::VectorXd y(N);
  y << 2.0, 0.5, 1;
  Eigen::VectorXd y_size(N - 1);
  y_size << 0.1, 0.5;
  Eigen::VectorXd y_value(N);
  y_value << NAN, 0.5, 0.99;

  Eigen::VectorXd alpha(N);
  alpha << 0.3, 0.8, 1.0;
  Eigen::VectorXd alpha_size(N - 1);
  alpha_size << 0.3, 0.8;
  Eigen::VectorXd alpha_value1(N);
  alpha_value1 << 0.3, -0.8, 0.5;
  Eigen::VectorXd alpha_value2(N);
  alpha_value2 << 0.3, INFINITY, 0.5;

  Eigen::VectorXd beta(N);
  beta << 0.3, 0.8, 1.0;
  Eigen::VectorXd beta_size(N - 1);
  beta_size << 0.3, 0.8;
  Eigen::VectorXd beta_value1(N);
  beta_value1 << 0.3, -0.8, 0.5;
  Eigen::VectorXd beta_value2(N);
  beta_value2 << 0.3, INFINITY, 0.5;

  stan::math::matrix_cl<double> y_cl(y);
  stan::math::matrix_cl<double> y_size_cl(y_size);
  stan::math::matrix_cl<double> y_value_cl(y_value);

  stan::math::matrix_cl<double> alpha_cl(alpha);
  stan::math::matrix_cl<double> alpha_size_cl(alpha_size);
  stan::math::matrix_cl<double> alpha_value1_cl(alpha_value1);
  stan::math::matrix_cl<double> alpha_value2_cl(alpha_value2);

  stan::math::matrix_cl<double> beta_cl(beta);
  stan::math::matrix_cl<double> beta_size_cl(beta_size);
  stan::math::matrix_cl<double> beta_value1_cl(beta_value1);
  stan::math::matrix_cl<double> beta_value2_cl(beta_value2);

  EXPECT_NO_THROW(stan::math::gamma_lpdf(y_cl, alpha_cl, beta_cl));

  EXPECT_THROW(stan::math::gamma_lpdf(y_size_cl, alpha_cl, beta_cl),
               std::invalid_argument);
  EXPECT_THROW(stan::math::gamma_lpdf(y_cl, alpha_size_cl, beta_cl),
               std::invalid_argument);
  EXPECT_THROW(stan::math::gamma_lpdf(y_cl, alpha_cl, beta_size_cl),
               std::invalid_argument);

  EXPECT_THROW(stan::math::gamma_lpdf(y_value_cl, alpha_cl, beta_cl),
               std::domain_error);
  EXPECT_THROW(stan::math::gamma_lpdf(y_cl, alpha_value1_cl, beta_cl),
               std::domain_error);
  EXPECT_THROW(stan::math::gamma_lpdf(y_cl, alpha_cl, beta_value1_cl),
               std::domain_error);
  EXPECT_THROW(stan::math::gamma_lpdf(y_cl, alpha_value2_cl, beta_cl),
               std::domain_error);
  EXPECT_THROW(stan::math::gamma_lpdf(y_cl, alpha_cl, beta_value2_cl),
               std::domain_error);
}

auto gamma_lpdf_functor
    = [](const auto& y, const auto& alpha, const auto& beta) {
        return stan::math::gamma_lpdf(y, alpha, beta);
      };
auto gamma_lpdf_functor_propto
    = [](const auto& y, const auto& alpha, const auto& beta) {
        return stan::math::gamma_lpdf<true>(y, alpha, beta);
      };

TEST(ProbDistributionsGamma, opencl_matches_cpu_small) {
  int N = 3;

  Eigen::VectorXd y(N);
  y << 0.1, 0.5, 1;
  Eigen::VectorXd alpha(N);
  alpha << 0.3, 0.8, 1.0;
  Eigen::VectorXd beta(N);
  beta << 0.3, 0.8, 1.0;

  stan::math::test::compare_cpu_opencl_prim_rev(gamma_lpdf_functor, y, alpha,
                                                beta);
  stan::math::test::compare_cpu_opencl_prim_rev(gamma_lpdf_functor_propto, y,
                                                alpha, beta);
  stan::math::test::compare_cpu_opencl_prim_rev(
      gamma_lpdf_functor, y.transpose().eval(), alpha.transpose().eval(),
      beta.transpose().eval());
  stan::math::test::compare_cpu_opencl_prim_rev(
      gamma_lpdf_functor_propto, y.transpose().eval(), alpha.transpose().eval(),
      beta.transpose().eval());
}

TEST(ProbDistributionsGamma, opencl_broadcast_y) {
  int N = 3;

  double y = 0.3;
  Eigen::VectorXd alpha(N);
  alpha << 0.3, 0.8, 1.0;
  Eigen::VectorXd beta(N);
  beta << 0.3, 0.8, 1.0;

  stan::math::test::test_opencl_broadcasting_prim_rev<0>(gamma_lpdf_functor, y,
                                                         alpha, beta);
  stan::math::test::test_opencl_broadcasting_prim_rev<0>(
      gamma_lpdf_functor_propto, y, alpha, beta);
  stan::math::test::test_opencl_broadcasting_prim_rev<0>(
      gamma_lpdf_functor, y, alpha.transpose().eval(), beta);
  stan::math::test::test_opencl_broadcasting_prim_rev<0>(
      gamma_lpdf_functor_propto, y, alpha, beta.transpose().eval());
}

TEST(ProbDistributionsGamma, opencl_broadcast_alpha) {
  int N = 3;

  Eigen::VectorXd y(N);
  y << 0.3, 0.8, 1.0;
  double alpha = 0.3;
  Eigen::VectorXd beta(N);
  beta << 0.3, 0.8, 1.0;

  stan::math::test::test_opencl_broadcasting_prim_rev<1>(gamma_lpdf_functor, y,
                                                         alpha, beta);
  stan::math::test::test_opencl_broadcasting_prim_rev<1>(
      gamma_lpdf_functor_propto, y, alpha, beta);
  stan::math::test::test_opencl_broadcasting_prim_rev<1>(
      gamma_lpdf_functor, y.transpose().eval(), alpha, beta);
  stan::math::test::test_opencl_broadcasting_prim_rev<1>(
      gamma_lpdf_functor_propto, y, alpha, beta.transpose().eval());
}

TEST(ProbDistributionsGamma, opencl_broadcast_beta) {
  int N = 3;

  Eigen::VectorXd y(N);
  y << 0.3, 0.8, 1.0;
  Eigen::VectorXd alpha(N);
  alpha << 0.3, 0.8, 1.0;
  double beta = 0.3;

  stan::math::test::test_opencl_broadcasting_prim_rev<2>(gamma_lpdf_functor, y,
                                                         alpha, beta);
  stan::math::test::test_opencl_broadcasting_prim_rev<2>(
      gamma_lpdf_functor_propto, y, alpha, beta);
  stan::math::test::test_opencl_broadcasting_prim_rev<2>(
      gamma_lpdf_functor, y.transpose().eval(), alpha, beta);
  stan::math::test::test_opencl_broadcasting_prim_rev<2>(
      gamma_lpdf_functor_propto, y, alpha.transpose().eval(), beta);
}

TEST(ProbDistributionsGamma, opencl_matches_cpu_big) {
  int N = 153;

  Eigen::Matrix<double, Eigen::Dynamic, 1> y
      = Eigen::Array<double, Eigen::Dynamic, 1>::Random(N, 1).abs();
  Eigen::Matrix<double, Eigen::Dynamic, 1> alpha
      = Eigen::Array<double, Eigen::Dynamic, 1>::Random(N, 1).abs();
  Eigen::Matrix<double, Eigen::Dynamic, 1> beta
      = Eigen::Array<double, Eigen::Dynamic, 1>::Random(N, 1).abs();

  stan::math::test::compare_cpu_opencl_prim_rev(gamma_lpdf_functor, y, alpha,
                                                beta);
  stan::math::test::compare_cpu_opencl_prim_rev(gamma_lpdf_functor_propto, y,
                                                alpha, beta);
  stan::math::test::compare_cpu_opencl_prim_rev(
      gamma_lpdf_functor, y.transpose().eval(), alpha.transpose().eval(),
      beta.transpose().eval());
  stan::math::test::compare_cpu_opencl_prim_rev(
      gamma_lpdf_functor_propto, y.transpose().eval(), alpha.transpose().eval(),
      beta.transpose().eval());
}

#endif
<|endoftext|>


<commit_before>/*
-----------------------------------------------------------------------------
This source file is part of OGRE
    (Object-oriented Graphics Rendering Engine)
For the latest info, see http://www.ogre3d.org/

Copyright (c) 2000-2014 Torus Knot Software Ltd

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.
-----------------------------------------------------------------------------
*/

#include "OgreException.h"
#include "OgreLogManager.h"
#include "OgreMaterialManager.h"
#include "OgreCompositorManager.h"
#include "OgreHighLevelGpuProgramManager.h"
#include "OgreGpuProgramManager.h"
#include "OgreLodStrategyManager.h"

#include "UnitTestSuite.h"

template<> UnitTestSuite* Ogre::Singleton<UnitTestSuite>::msSingleton = 0;

//--------------------------------------------------------------------------
void UnitTestSuite::setUpSuite()
{
    Ogre::LogManager* logMgr = new Ogre::LogManager();
    logMgr->createLog("OgreTest.log", true, true);
    logMgr->setLogDetail(Ogre::LL_BOREME);
    Ogre::LogManager::getSingletonPtr()->logMessage("----------------------------------------------------------------------------------------------------");
    logMgr->logMessage("##> Ogre3D Unit Test Suite successfully set up.");
    Ogre::LogManager::getSingletonPtr()->logMessage("----------------------------------------------------------------------------------------------------");
}
//--------------------------------------------------------------------------
void UnitTestSuite::tearDownSuite()
{
    // Shutdown and release managers that might have been created
    if(Ogre::HighLevelGpuProgramManager::getSingletonPtr())
        delete Ogre::HighLevelGpuProgramManager::getSingletonPtr();
    if(Ogre::GpuProgramManager::getSingletonPtr())
        delete Ogre::GpuProgramManager::getSingletonPtr();
    if(Ogre::CompositorManager::getSingletonPtr())
        delete Ogre::CompositorManager::getSingletonPtr();
    if(Ogre::MaterialManager::getSingletonPtr())
        delete Ogre::MaterialManager::getSingletonPtr();
    if(Ogre::ResourceGroupManager::getSingletonPtr())
        delete Ogre::ResourceGroupManager::getSingletonPtr();

    if(Ogre::ResourceGroupManager::getSingletonPtr())
        delete Ogre::ResourceGroupManager::getSingletonPtr();
    if(Ogre::LodStrategyManager::getSingletonPtr())
        delete Ogre::LodStrategyManager::getSingletonPtr();

    Ogre::LogManager::getSingletonPtr()->logMessage("----------------------------------------------------------------------------------------------------");
    Ogre::LogManager::getSingletonPtr()->logMessage("##> Ogre3D Unit Test Suite successfully shut down.");
    Ogre::LogManager::getSingletonPtr()->logMessage("----------------------------------------------------------------------------------------------------");

    if(Ogre::LogManager::getSingletonPtr())
        delete Ogre::LogManager::getSingletonPtr();
}
//--------------------------------------------------------------------------
void UnitTestSuite::startTestSetup(const std::string testName)
{
    Ogre::LogManager::getSingletonPtr()->logMessage("----------------------------------------------------------------------------------------------------");
    Ogre::LogManager::getSingletonPtr()->logMessage("||--> Starting Setup of Unit Test [" + testName + "]:");
}
//--------------------------------------------------------------------------
void UnitTestSuite::startTestMethod(const std::string testName)
{
    Ogre::LogManager::getSingletonPtr()->logMessage("||--> Starting Unit Test [" + testName + "]:");
}
//--------------------------------------------------------------------------

<commit_msg>UnitTestSuite: fix double free<commit_after>/*
-----------------------------------------------------------------------------
This source file is part of OGRE
    (Object-oriented Graphics Rendering Engine)
For the latest info, see http://www.ogre3d.org/

Copyright (c) 2000-2014 Torus Knot Software Ltd

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.
-----------------------------------------------------------------------------
*/

#include "OgreException.h"
#include "OgreLogManager.h"
#include "OgreMaterialManager.h"
#include "OgreCompositorManager.h"
#include "OgreHighLevelGpuProgramManager.h"
#include "OgreGpuProgramManager.h"
#include "OgreLodStrategyManager.h"

#include "UnitTestSuite.h"

template<> UnitTestSuite* Ogre::Singleton<UnitTestSuite>::msSingleton = 0;

//--------------------------------------------------------------------------
void UnitTestSuite::setUpSuite()
{
    Ogre::LogManager* logMgr = new Ogre::LogManager();
    logMgr->createLog("OgreTest.log", true, true);
    logMgr->setLogDetail(Ogre::LL_BOREME);
    Ogre::LogManager::getSingletonPtr()->logMessage("----------------------------------------------------------------------------------------------------");
    logMgr->logMessage("##> Ogre3D Unit Test Suite successfully set up.");
    Ogre::LogManager::getSingletonPtr()->logMessage("----------------------------------------------------------------------------------------------------");
}
//--------------------------------------------------------------------------
void UnitTestSuite::tearDownSuite()
{
    // Shutdown and release managers that might have been created
    if(Ogre::HighLevelGpuProgramManager::getSingletonPtr())
        delete Ogre::HighLevelGpuProgramManager::getSingletonPtr();
    if(Ogre::GpuProgramManager::getSingletonPtr())
        delete Ogre::GpuProgramManager::getSingletonPtr();
    if(Ogre::CompositorManager::getSingletonPtr())
        delete Ogre::CompositorManager::getSingletonPtr();
    if(Ogre::MaterialManager::getSingletonPtr())
        delete Ogre::MaterialManager::getSingletonPtr();
    if(Ogre::ResourceGroupManager::getSingletonPtr())
        delete Ogre::ResourceGroupManager::getSingletonPtr();
    if(Ogre::LodStrategyManager::getSingletonPtr())
        delete Ogre::LodStrategyManager::getSingletonPtr();

    Ogre::LogManager::getSingletonPtr()->logMessage("----------------------------------------------------------------------------------------------------");
    Ogre::LogManager::getSingletonPtr()->logMessage("##> Ogre3D Unit Test Suite successfully shut down.");
    Ogre::LogManager::getSingletonPtr()->logMessage("----------------------------------------------------------------------------------------------------");

    if(Ogre::LogManager::getSingletonPtr())
        delete Ogre::LogManager::getSingletonPtr();
}
//--------------------------------------------------------------------------
void UnitTestSuite::startTestSetup(const std::string testName)
{
    Ogre::LogManager::getSingletonPtr()->logMessage("----------------------------------------------------------------------------------------------------");
    Ogre::LogManager::getSingletonPtr()->logMessage("||--> Starting Setup of Unit Test [" + testName + "]:");
}
//--------------------------------------------------------------------------
void UnitTestSuite::startTestMethod(const std::string testName)
{
    Ogre::LogManager::getSingletonPtr()->logMessage("||--> Starting Unit Test [" + testName + "]:");
}
//--------------------------------------------------------------------------

<|endoftext|>


<commit_before>/* Copyright (c) 2008-2020 the MRtrix3 contributors.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * Covered Software is provided under this License on an "as is"
 * basis, without warranty of any kind, either expressed, implied, or
 * statutory, including, without limitation, warranties that the
 * Covered Software is free of defects, merchantable, fit for a
 * particular purpose or non-infringing.
 * See the Mozilla Public License v. 2.0 for more details.
 *
 * For more details, see http://www.mrtrix.org/.
 */

#include <complex>

#include "command.h"
#include "mrtrix.h"
#include "types.h"

using namespace MR;
using namespace App;

void usage ()
{
  AUTHOR = "J-Donald Tournier (jdtournier@gmail.com)";

  SYNOPSIS = "Test the parse_ints (std::string) function";

  REQUIRES_AT_LEAST_ONE_ARGUMENT = false;
}

vector<std::string> failures;

void run ()
{

  struct Test {
    const char* str;
    std::vector<int> result;
  } tests[] = {

    { "1", { 1 } },
    { "1,3,4", { 1,3,4 } },
    { "5:9", { 5,6,7,8,9 } },
    { "2:2:10", { 2,4,6,8,10 } },
    { "6:3:-6", { 6,3,0,-3,-6 } },
    { "1:3,5:7", { 1,2,3,5,6,7 } },
    { "1:2:10,20:5:-7", { 1,3,5,7,9,20,15,10,5,0,-5 } },
    { "abc", { } },
    { "a,b,c", { } },
    { "1,3,c", { } },
    { "1:3,c", { } },
    { "1, 5, 7", { 1,5,7 } },
    { "1 5 7", { 1,5,7 } },
    { "1,\t   5\t7", { 1,5,7 } },
    { "1:  5, 7", { 1,2,3,4,5,7 } },
    { "1: 5 7", { 1,2,3,4,5,7 } },
    { "1 :5 7", { 1,2,3,4,5,7 } },
    { "1 : 2 : 5 7", { 1,3,5,7 } },
    { "1 :2 :-5 7", { 1,-1,-3,-5,7 } },
    { "1 : 2: 11 20: 3 :30", { 1,3,5,7,9,11,20,23,26,29 } },

  };

  for (const auto& t : tests) {
    try {
      if (parse_ints (t.str) != t.result)
        failures.push_back ("\"" + std::string (t.str) + "\" to " + str(t.result) + " failed (produced " + str(parse_ints(t.str)) + ")");
    }
    catch (Exception& e) {
      if (t.result.size())
        failures.push_back ("\"" + std::string (t.str) + "\" to " + str(t.result) + " failed: " + e[0]);
    }
  }

  if (failures.size()) {
    Exception e (str(failures.size()) + " of " + str(sizeof(tests)/sizeof(Test)) + " tests failed:");
    for (const auto& s : failures)
      e.push_back (s);
    throw e;
  }

  CONSOLE ("All tests passed OK");

}

<commit_msg>Fix parse_ints() unit test<commit_after>/* Copyright (c) 2008-2020 the MRtrix3 contributors.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * Covered Software is provided under this License on an "as is"
 * basis, without warranty of any kind, either expressed, implied, or
 * statutory, including, without limitation, warranties that the
 * Covered Software is free of defects, merchantable, fit for a
 * particular purpose or non-infringing.
 * See the Mozilla Public License v. 2.0 for more details.
 *
 * For more details, see http://www.mrtrix.org/.
 */

#include <complex>

#include "command.h"
#include "mrtrix.h"
#include "types.h"

using namespace MR;
using namespace App;

void usage ()
{
  AUTHOR = "J-Donald Tournier (jdtournier@gmail.com)";

  SYNOPSIS = "Test the parse_ints (std::string) function";

  REQUIRES_AT_LEAST_ONE_ARGUMENT = false;
}

vector<std::string> failures;

void run ()
{

  struct Test {
    const char* str;
    std::vector<int> result;
  } tests[] = {

    { "1", { 1 } },
    { "1,3,4", { 1,3,4 } },
    { "5:9", { 5,6,7,8,9 } },
    { "2:2:10", { 2,4,6,8,10 } },
    { "6:3:-6", { 6,3,0,-3,-6 } },
    { "1:3,5:7", { 1,2,3,5,6,7 } },
    { "1:2:10,20:5:-7", { 1,3,5,7,9,20,15,10,5,0,-5 } },
    { "abc", { } },
    { "a,b,c", { } },
    { "1,3,c", { } },
    { "1:3,c", { } },
    { "1, 5, 7", { 1,5,7 } },
    { "1 5 7", { 1,5,7 } },
    { "1,\t   5\t7", { 1,5,7 } },
    { "1:  5, 7", { 1,2,3,4,5,7 } },
    { "1: 5 7", { 1,2,3,4,5,7 } },
    { "1 :5 7", { 1,2,3,4,5,7 } },
    { "1 : 2 : 5 7", { 1,3,5,7 } },
    { "1 :2 :-5 7", { 1,-1,-3,-5,7 } },
    { "1 : 2: 11 20: 3 :30", { 1,3,5,7,9,11,20,23,26,29 } },

  };

  for (const auto& t : tests) {
    try {
      if (parse_ints<int> (t.str) != t.result)
        failures.push_back ("\"" + std::string (t.str) + "\" to " + str(t.result) + " failed (produced " + str(parse_ints<int>(t.str)) + ")");
    }
    catch (Exception& e) {
      if (t.result.size())
        failures.push_back ("\"" + std::string (t.str) + "\" to " + str(t.result) + " failed: " + e[0]);
    }
  }

  if (failures.size()) {
    Exception e (str(failures.size()) + " of " + str(sizeof(tests)/sizeof(Test)) + " tests failed:");
    for (const auto& s : failures)
      e.push_back (s);
    throw e;
  }

  CONSOLE ("All tests passed OK");

}

<|endoftext|>


<commit_before>/*
Copyright (c) 2022 Advanced Micro Devices, Inc. All rights reserved.

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.
*/

/*
 Run through few sanity tests to verify different attributes of hipPointerGetAttribute
*/
#include <hip_test_common.hh>
#include <vector>
#include <iostream>
#include <string>

// Run few simple cases including  host pointer arithmetic:
TEST_CASE("Unit_hipPtrGetAttribute_Simple") {
  HIP_CHECK(hipSetDevice(0));
  size_t Nbytes = 0;
  constexpr size_t N {1000000};
  Nbytes = N * sizeof(char);
  printf("\n");

  int numDevices = 0;
  HIP_CHECK(hipGetDeviceCount(&numDevices));
  char* A_d;
  char* A_Pinned_h;
  char* A_Hmm;

  HIP_CHECK(hipMalloc(&A_d, Nbytes));
  HIP_CHECK(hipHostMalloc(reinterpret_cast<void**>(&A_Pinned_h), Nbytes,
                         hipHostMallocDefault));
  HIP_CHECK(hipMallocManaged(&A_Hmm, Nbytes));

  size_t free, total;
  HIP_CHECK(hipMemGetInfo(&free, &total));
  printf("hipMemGetInfo: free=%zu (%4.2f) Nbytes=%lu total=%zu (%4.2f)\n", free,
         (free / 1024.0 / 1024.0), Nbytes, total,
         (total / 1024.0 / 1024.0));
  REQUIRE(free + Nbytes <= total);

  hipDeviceptr_t data = 0;

  // Device memory
  printf("\nDevice memory (hipMalloc)\n");
  HIP_CHECK(hipPointerGetAttribute(&data, HIP_POINTER_ATTRIBUTE_DEVICE_POINTER,
            reinterpret_cast<hipDeviceptr_t>(A_d)));
  char *ptr1 = reinterpret_cast<char *>(data);

  // Check pointer arithmetic cases:
  HIP_CHECK(hipPointerGetAttribute(&data, HIP_POINTER_ATTRIBUTE_DEVICE_POINTER,
            reinterpret_cast<hipDeviceptr_t>(A_d + 100)));
  char *ptr2 = reinterpret_cast<char*>(data);
  REQUIRE(ptr2 == ptr1+100);

  // Corner case at end of array:
  HIP_CHECK(hipPointerGetAttribute(&data, HIP_POINTER_ATTRIBUTE_DEVICE_POINTER,
            reinterpret_cast<hipDeviceptr_t>(A_d + Nbytes - 1)));
  ptr2 = reinterpret_cast<char*>(data);
  REQUIRE(ptr2 == (ptr1 + Nbytes -1));

  // Device-visible host memory
  printf("\nDevice-visible host memory (hipHostMalloc)\n");
  HIP_CHECK(hipPointerGetAttribute(&data, HIP_POINTER_ATTRIBUTE_HOST_POINTER,
            reinterpret_cast<hipDeviceptr_t>(A_Pinned_h)));
  ptr1 = reinterpret_cast<char *>(data);

  // Check pointer arithmetic cases:
  HIP_CHECK(hipPointerGetAttribute(&data, HIP_POINTER_ATTRIBUTE_HOST_POINTER,
            reinterpret_cast<hipDeviceptr_t>(A_Pinned_h + 100)));
  ptr2 = reinterpret_cast<char*>(data);
  REQUIRE(ptr2 == ptr1+100);

  // Corner case at end of array:
  HIP_CHECK(hipPointerGetAttribute(&data, HIP_POINTER_ATTRIBUTE_HOST_POINTER,
            reinterpret_cast<hipDeviceptr_t>(A_Pinned_h + Nbytes - 1)));
  ptr2 = reinterpret_cast<char*>(data);
  REQUIRE(ptr2 == (ptr1 + Nbytes -1));

  // HIP_POINTER_ATTRIBUTE_MEMORY_TYPE
  unsigned int datatype;
  HIP_CHECK(hipPointerGetAttribute(&datatype, HIP_POINTER_ATTRIBUTE_MEMORY_TYPE,
            reinterpret_cast<hipDeviceptr_t>(A_d)));
#ifdef __HIP_PLATFORM_NVCC__
  REQUIRE(datatype == CU_MEMORYTYPE_DEVICE);
#else
  REQUIRE(datatype == hipMemoryTypeDevice);
#endif

  HIP_CHECK(hipPointerGetAttribute(&datatype, HIP_POINTER_ATTRIBUTE_MEMORY_TYPE,
            reinterpret_cast<hipDeviceptr_t>(A_Pinned_h)));
#ifdef __HIP_PLATFORM_NVCC__
  REQUIRE(datatype == CU_MEMORYTYPE_HOST);
#else
  REQUIRE(datatype == hipMemoryTypeHost);
#endif

  // HIP_POINTER_ATTRIBUTE_IS_MANAGED
  bool isHmm;
  HIP_CHECK(hipPointerGetAttribute(&isHmm, HIP_POINTER_ATTRIBUTE_IS_MANAGED,
            reinterpret_cast<hipDeviceptr_t>(A_Hmm)));
  REQUIRE(isHmm == 1);

  HIP_CHECK(hipPointerGetAttribute(&isHmm, HIP_POINTER_ATTRIBUTE_IS_MANAGED,
            reinterpret_cast<hipDeviceptr_t>(A_Pinned_h)));
  REQUIRE(isHmm == 0);

  // HIP_POINTER_ATTRIBUTE_DEVICE_ORDINAL
  if (numDevices > 1) {
    HIP_CHECK(hipSetDevice(1));
    HIP_CHECK(hipPointerGetAttribute(&datatype, HIP_POINTER_ATTRIBUTE_DEVICE_ORDINAL,
              reinterpret_cast<hipDeviceptr_t>(A_d)));
    REQUIRE(datatype == 0);
  }

  // HIP_POINTER_ATTRIBUTE_MAPPED
  bool isMapped;
  HIP_CHECK(hipPointerGetAttribute(&isMapped, HIP_POINTER_ATTRIBUTE_MAPPED,
            reinterpret_cast<hipDeviceptr_t>(A_d)));
  REQUIRE(isMapped == 1);

  // HIP_POINTER_ATTRIBUTE_RANGE_START_ADDR
  HIP_CHECK(hipPointerGetAttribute(&data, HIP_POINTER_ATTRIBUTE_RANGE_START_ADDR,
            reinterpret_cast<hipDeviceptr_t>(A_d+2)));
  char *ptr3 = reinterpret_cast<char *>(data);
  REQUIRE(ptr3 == A_d);

  // HIP_POINTER_ATTRIBUTE_RANGE_SIZE
  HIP_CHECK(hipPointerGetAttribute(&datatype, HIP_POINTER_ATTRIBUTE_RANGE_SIZE,
            reinterpret_cast<hipDeviceptr_t>(A_d)));
  REQUIRE(datatype == Nbytes);

  unsigned int bufId1, bufId2;
  // HIP_POINTER_ATTRIBUTE_BUFFER_ID
  HIP_CHECK(hipPointerGetAttribute(&bufId1, HIP_POINTER_ATTRIBUTE_BUFFER_ID,
            reinterpret_cast<hipDeviceptr_t>(A_d)));
  HIP_CHECK(hipPointerGetAttribute(&bufId2, HIP_POINTER_ATTRIBUTE_BUFFER_ID,
            reinterpret_cast<hipDeviceptr_t>(A_Pinned_h)));
  REQUIRE(bufId1 != bufId2);

}
<commit_msg>SWDEV-339742 - Check can access before set device to 1. (#2758)<commit_after>/*
Copyright (c) 2022 Advanced Micro Devices, Inc. All rights reserved.

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.
*/

/*
 Run through few sanity tests to verify different attributes of hipPointerGetAttribute
*/
#include <hip_test_common.hh>
#include <vector>
#include <iostream>
#include <string>

// Run few simple cases including  host pointer arithmetic:
TEST_CASE("Unit_hipPtrGetAttribute_Simple") {
  HIP_CHECK(hipSetDevice(0));
  size_t Nbytes = 0;
  constexpr size_t N {1000000};
  Nbytes = N * sizeof(char);
  printf("\n");

  int numDevices = 0;
  HIP_CHECK(hipGetDeviceCount(&numDevices));
  char* A_d;
  char* A_Pinned_h;
  char* A_Hmm;

  HIP_CHECK(hipMalloc(&A_d, Nbytes));
  HIP_CHECK(hipHostMalloc(reinterpret_cast<void**>(&A_Pinned_h), Nbytes,
                         hipHostMallocDefault));
  HIP_CHECK(hipMallocManaged(&A_Hmm, Nbytes));

  size_t free, total;
  HIP_CHECK(hipMemGetInfo(&free, &total));
  printf("hipMemGetInfo: free=%zu (%4.2f) Nbytes=%lu total=%zu (%4.2f)\n", free,
         (free / 1024.0 / 1024.0), Nbytes, total,
         (total / 1024.0 / 1024.0));
  REQUIRE(free + Nbytes <= total);

  hipDeviceptr_t data = 0;

  // Device memory
  printf("\nDevice memory (hipMalloc)\n");
  HIP_CHECK(hipPointerGetAttribute(&data, HIP_POINTER_ATTRIBUTE_DEVICE_POINTER,
            reinterpret_cast<hipDeviceptr_t>(A_d)));
  char *ptr1 = reinterpret_cast<char *>(data);

  // Check pointer arithmetic cases:
  HIP_CHECK(hipPointerGetAttribute(&data, HIP_POINTER_ATTRIBUTE_DEVICE_POINTER,
            reinterpret_cast<hipDeviceptr_t>(A_d + 100)));
  char *ptr2 = reinterpret_cast<char*>(data);
  REQUIRE(ptr2 == ptr1+100);

  // Corner case at end of array:
  HIP_CHECK(hipPointerGetAttribute(&data, HIP_POINTER_ATTRIBUTE_DEVICE_POINTER,
            reinterpret_cast<hipDeviceptr_t>(A_d + Nbytes - 1)));
  ptr2 = reinterpret_cast<char*>(data);
  REQUIRE(ptr2 == (ptr1 + Nbytes -1));

  // Device-visible host memory
  printf("\nDevice-visible host memory (hipHostMalloc)\n");
  HIP_CHECK(hipPointerGetAttribute(&data, HIP_POINTER_ATTRIBUTE_HOST_POINTER,
            reinterpret_cast<hipDeviceptr_t>(A_Pinned_h)));
  ptr1 = reinterpret_cast<char *>(data);

  // Check pointer arithmetic cases:
  HIP_CHECK(hipPointerGetAttribute(&data, HIP_POINTER_ATTRIBUTE_HOST_POINTER,
            reinterpret_cast<hipDeviceptr_t>(A_Pinned_h + 100)));
  ptr2 = reinterpret_cast<char*>(data);
  REQUIRE(ptr2 == ptr1+100);

  // Corner case at end of array:
  HIP_CHECK(hipPointerGetAttribute(&data, HIP_POINTER_ATTRIBUTE_HOST_POINTER,
            reinterpret_cast<hipDeviceptr_t>(A_Pinned_h + Nbytes - 1)));
  ptr2 = reinterpret_cast<char*>(data);
  REQUIRE(ptr2 == (ptr1 + Nbytes -1));

  // HIP_POINTER_ATTRIBUTE_MEMORY_TYPE
  unsigned int datatype;
  HIP_CHECK(hipPointerGetAttribute(&datatype, HIP_POINTER_ATTRIBUTE_MEMORY_TYPE,
            reinterpret_cast<hipDeviceptr_t>(A_d)));
#ifdef __HIP_PLATFORM_NVCC__
  REQUIRE(datatype == CU_MEMORYTYPE_DEVICE);
#else
  REQUIRE(datatype == hipMemoryTypeDevice);
#endif

  HIP_CHECK(hipPointerGetAttribute(&datatype, HIP_POINTER_ATTRIBUTE_MEMORY_TYPE,
            reinterpret_cast<hipDeviceptr_t>(A_Pinned_h)));
#ifdef __HIP_PLATFORM_NVCC__
  REQUIRE(datatype == CU_MEMORYTYPE_HOST);
#else
  REQUIRE(datatype == hipMemoryTypeHost);
#endif

  // HIP_POINTER_ATTRIBUTE_IS_MANAGED
  bool isHmm;
  HIP_CHECK(hipPointerGetAttribute(&isHmm, HIP_POINTER_ATTRIBUTE_IS_MANAGED,
            reinterpret_cast<hipDeviceptr_t>(A_Hmm)));
  REQUIRE(isHmm == 1);

  HIP_CHECK(hipPointerGetAttribute(&isHmm, HIP_POINTER_ATTRIBUTE_IS_MANAGED,
            reinterpret_cast<hipDeviceptr_t>(A_Pinned_h)));
  REQUIRE(isHmm == 0);

  // HIP_POINTER_ATTRIBUTE_DEVICE_ORDINAL
  if (numDevices > 1) {
    int canAccess = -1;
    HIP_CHECK(hipDeviceCanAccessPeer(&canAccess, 1, 0));
    if (canAccess == 1) {
      HIP_CHECK(hipSetDevice(1));
      HIP_CHECK(hipPointerGetAttribute(&datatype, HIP_POINTER_ATTRIBUTE_DEVICE_ORDINAL,
                reinterpret_cast<hipDeviceptr_t>(A_d)));
      REQUIRE(datatype == 0);
    }
  }

  // HIP_POINTER_ATTRIBUTE_MAPPED
  bool isMapped;
  HIP_CHECK(hipPointerGetAttribute(&isMapped, HIP_POINTER_ATTRIBUTE_MAPPED,
            reinterpret_cast<hipDeviceptr_t>(A_d)));
  REQUIRE(isMapped == 1);

  // HIP_POINTER_ATTRIBUTE_RANGE_START_ADDR
  HIP_CHECK(hipPointerGetAttribute(&data, HIP_POINTER_ATTRIBUTE_RANGE_START_ADDR,
            reinterpret_cast<hipDeviceptr_t>(A_d+2)));
  char *ptr3 = reinterpret_cast<char *>(data);
  REQUIRE(ptr3 == A_d);

  // HIP_POINTER_ATTRIBUTE_RANGE_SIZE
  HIP_CHECK(hipPointerGetAttribute(&datatype, HIP_POINTER_ATTRIBUTE_RANGE_SIZE,
            reinterpret_cast<hipDeviceptr_t>(A_d)));
  REQUIRE(datatype == Nbytes);

  unsigned int bufId1, bufId2;
  // HIP_POINTER_ATTRIBUTE_BUFFER_ID
  HIP_CHECK(hipPointerGetAttribute(&bufId1, HIP_POINTER_ATTRIBUTE_BUFFER_ID,
            reinterpret_cast<hipDeviceptr_t>(A_d)));
  HIP_CHECK(hipPointerGetAttribute(&bufId2, HIP_POINTER_ATTRIBUTE_BUFFER_ID,
            reinterpret_cast<hipDeviceptr_t>(A_Pinned_h)));
  REQUIRE(bufId1 != bufId2);

}
<|endoftext|>


<commit_before>/**************************************************************************
** This file is part of LiteIDE
**
** Copyright (c) 2011-2015 LiteIDE Team. All rights reserved.
**
** This library is free software; you can redistribute it and/or
** modify it under the terms of the GNU Lesser General Public
** License as published by the Free Software Foundation; either
** version 2.1 of the License, or (at your option) any later version.
**
** This library 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
** Lesser General Public License for more details.
**
** In addition, as a special exception,  that plugins developed for LiteIDE,
** are allowed to remain closed sourced and can be distributed under any license .
** These rights are included in the file LGPL_EXCEPTION.txt in this package.
**
**************************************************************************/
// Module: jsonedit.cpp
// Creator: visualfc <visualfc@gmail.com>

#include "jsonedit.h"
#include "liteenvapi/liteenvapi.h"
#include "editorutil/editorutil.h"
#include <qjson/include/QJson/Parser>
#include <qjson/include/QJson/Serializer>
#include <QPlainTextEdit>
#include <QProcess>
#include <QToolBar>
#include <QToolButton>
#include <QMenu>
#include <QDebug>
//lite_memory_check_begin
#if defined(WIN32) && defined(_MSC_VER) &&  defined(_DEBUG)
     #define _CRTDBG_MAP_ALLOC
     #include <stdlib.h>
     #include <crtdbg.h>
     #define DEBUG_NEW new( _NORMAL_BLOCK, __FILE__, __LINE__ )
     #define new DEBUG_NEW
#endif
//lite_memory_check_end

JsonEdit::JsonEdit(LiteApi::IApplication *app, QObject *parent)
    : QObject(parent), m_liteApp(app)
{
    LiteApi::IActionContext *actionContext = m_liteApp->actionManager()->getActionContext(this,"JsonEdit");

    m_verifyAct = new QAction(tr("Verify"),this);
    actionContext->regAction(m_verifyAct,"VerifyJson","");
    m_formatAct = new QAction(tr("Format Json"),this);
    actionContext->regAction(m_formatAct,"FormatJson","Ctrl+I");
    m_compactAct = new QAction(tr("Compact Json"),this);
    actionContext->regAction(m_compactAct,"CompactJson","");

    connect(m_liteApp->editorManager(),SIGNAL(editorCreated(LiteApi::IEditor*)),this,SLOT(editorCreated(LiteApi::IEditor*)));
    connect(m_liteApp->editorManager(),SIGNAL(editorSaved(LiteApi::IEditor*)),this,SLOT(editorSaved(LiteApi::IEditor*)));
    connect(m_verifyAct,SIGNAL(triggered()),this,SLOT(verify()));
    connect(m_formatAct,SIGNAL(triggered()),this,SLOT(format()));
    connect(m_compactAct,SIGNAL(triggered()),this,SLOT(compact()));
}

//void JsonEdit::indentNone()
//{
//    format(QJson::IndentNone);
//}

//void JsonEdit::indentCompact()
//{
//    format(QJson::IndentCompact);
//}

//void JsonEdit::indentMinimum()
//{
//    format(QJson::IndentMinimum);
//}

//void JsonEdit::indentMedium()
//{
//    format(QJson::IndentMedium);
//}
//void JsonEdit::indentFull()
//{
//    format(QJson::IndentFull);
//}

bool JsonEdit::verifyJson(LiteApi::IEditor *editor)
{
    LiteApi::ILiteEditor *ed = LiteApi::getLiteEditor(editor);
    if (!ed) {
        return false;
    }
    QJson::Parser parser;
    bool ok = true;
    parser.parse(ed->utf8Data(),&ok);
    if (!ok) {
        ed->setNavigateHead(LiteApi::EditorNavigateError,"json verify error");
        if (parser.errorLine() > 0) {
            ed->insertNavigateMark(parser.errorLine()-1,LiteApi::EditorNavigateError,parser.errorString(),"Json");
        }
    } else {
        ed->setNavigateHead(LiteApi::EditorNavigateNormal,"json verify success");
        ed->clearAllNavigateMark(LiteApi::EditorNavigateError,"Json");
    }
    return ok;
}

void JsonEdit::verify()
{
    LiteApi::IEditor *editor = m_liteApp->editorManager()->currentEditor();
    if (!editor || editor->mimeType() != "application/json") {
        return;
    }
    verifyJson(editor);
}

void JsonEdit::format()
{
    LiteApi::IEditor *editor = m_liteApp->editorManager()->currentEditor();
    if (!editor || editor->mimeType() != "application/json") {
        return;
    }
    if (!verifyJson(editor)) {
        return;
    }
    fmtEditor(editor,false,false,true,1000);
}

void JsonEdit::compact()
{
    LiteApi::IEditor *editor = m_liteApp->editorManager()->currentEditor();
    if (!editor || editor->mimeType() != "application/json") {
        return;
    }
    if (!verifyJson(editor)) {
        return;
    }
    fmtEditor(editor,true,false,true,1000);
}

void JsonEdit::fmtEditor(LiteApi::IEditor *editor, bool compact, bool tabs, bool diff,int timeout)
{
    LiteApi::ITextEditor *textEditor = LiteApi::getTextEditor(editor);
    if (!textEditor) {
        return;
    }
    bool save = !editor->isModified();

    QPlainTextEdit *ed = LiteApi::findExtensionObject<QPlainTextEdit*>(editor,"LiteApi.QPlainTextEdit");
    if (!ed) {
        return;
    }

    QString text = ed->toPlainText();
    if (text.isEmpty()) {
        return;
    }

    QProcess process;
    process.setEnvironment(LiteApi::getGoEnvironment(m_liteApp).toStringList());

    QStringList args;

    args << "jsonfmt";
    if (compact) {
        args << "-c";
    }
    if (tabs) {
        args << "-tabs";
    }
    if (diff) {
        args << "-d";
    }
    QString cmd = LiteApi::getGotools(m_liteApp);
    process.start(cmd,args);
    if (!process.waitForStarted(timeout)) {
        m_liteApp->appendLog("jsonfmt",QString("Timed out after %1ms when starting json format").arg(timeout),false);
        return;
    }
    process.write(text.toUtf8());
    process.closeWriteChannel();
    if (!process.waitForFinished(timeout*4)) {
        m_liteApp->appendLog("jsonfmt",QString("Timed out after %1ms while running json format").arg(timeout*4),false);
        return;
    }
    LiteApi::ILiteEditor *liteEditor = LiteApi::getLiteEditor(editor);
    liteEditor->clearAllNavigateMark(LiteApi::EditorNavigateBad, "Json");
    QTextCodec *codec = QTextCodec::codecForName("utf-8");

    if (process.exitCode() != 0) {
        m_liteApp->appendLog("jsonfmt",QString::fromUtf8(process.readAll()),true);
        return;
    }

    QByteArray data = process.readAllStandardOutput();
    /*
    int vpos = -1;
    QScrollBar *bar = ed->verticalScrollBar();
    if (bar) {
        vpos = bar->sliderPosition();
    }
    */
    QByteArray state = editor->saveState();
    QTextCursor cur = ed->textCursor();
    //int pos = cur.position();
    cur.beginEditBlock();
    if (diff) {
        EditorUtil::loadDiff(cur,codec->toUnicode(data));
    } else {
        cur.select(QTextCursor::Document);
        cur.removeSelectedText();
        cur.insertText(codec->toUnicode(data));
    }
    //cur.setPosition(pos);
    cur.endEditBlock();
    ed->setTextCursor(cur);
    editor->restoreState(state);

    //ed->setTextCursor(cur);
    //if (vpos != -1) {
    //    bar->setSliderPosition(vpos);
    //}
    if (save) {
        m_liteApp->editorManager()->saveEditor(editor,false);
    }
}

void JsonEdit::editorCreated(LiteApi::IEditor *editor)
{
    if (editor->mimeType() != "application/json") {
        return;
    }
    LiteApi::ILiteEditor *ed = LiteApi::getLiteEditor(editor);
    if (!ed) {
        return;
    }
    ed->setWordWrap(true);
    ed->setEnableAutoIndentAction(false);

    QMenu *menu = LiteApi::getContextMenu(editor);
    if (menu) {
        menu->addSeparator();
        menu->addAction(m_verifyAct);
        menu->addAction(m_formatAct);
        menu->addAction(m_compactAct);
    }
    menu = LiteApi::getEditMenu(editor);
    if (menu) {
        menu->addSeparator();
        menu->addAction(m_verifyAct);
        menu->addAction(m_formatAct);
        menu->addAction(m_compactAct);
    }
}

void JsonEdit::editorSaved(LiteApi::IEditor *editor)
{
    if (editor->mimeType() != "application/json") {
        return;
    }
    verifyJson(editor);
}

//void JsonEdit::format(QJson::IndentMode mode)
//{
//    QJson::Parser parser;
//    bool ok = true;
//    QVariant json = parser.parse(m_editor->utf8Data(),&ok);
//    if (!ok) {
//        return;
//    }
//    QJson::Serializer stream;
//    stream.setIndentMode(mode);
//    QByteArray data = stream.serialize(json);
//    QPlainTextEdit *ed = LiteApi::getPlainTextEdit(m_editor);
//    if (ed) {
//        QTextCursor cursor = ed->textCursor();
//        cursor.beginEditBlock();
//        cursor.select(QTextCursor::Document);
//        cursor.removeSelectedText();
//        cursor.insertText(QString::fromUtf8(data));
//        cursor.endEditBlock();
//        ed->setTextCursor(cursor);
//    }
//}
<commit_msg>update build<commit_after>/**************************************************************************
** This file is part of LiteIDE
**
** Copyright (c) 2011-2015 LiteIDE Team. All rights reserved.
**
** This library is free software; you can redistribute it and/or
** modify it under the terms of the GNU Lesser General Public
** License as published by the Free Software Foundation; either
** version 2.1 of the License, or (at your option) any later version.
**
** This library 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
** Lesser General Public License for more details.
**
** In addition, as a special exception,  that plugins developed for LiteIDE,
** are allowed to remain closed sourced and can be distributed under any license .
** These rights are included in the file LGPL_EXCEPTION.txt in this package.
**
**************************************************************************/
// Module: jsonedit.cpp
// Creator: visualfc <visualfc@gmail.com>

#include "jsonedit.h"
#include "liteenvapi/liteenvapi.h"
#include "editorutil/editorutil.h"
#include <qjson/include/QJson/Parser>
#include <qjson/include/QJson/Serializer>
#include <QPlainTextEdit>
#include <QProcess>
#include <QToolBar>
#include <QToolButton>
#include <QTextCodec>
#include <QMenu>
#include <QDebug>
//lite_memory_check_begin
#if defined(WIN32) && defined(_MSC_VER) &&  defined(_DEBUG)
     #define _CRTDBG_MAP_ALLOC
     #include <stdlib.h>
     #include <crtdbg.h>
     #define DEBUG_NEW new( _NORMAL_BLOCK, __FILE__, __LINE__ )
     #define new DEBUG_NEW
#endif
//lite_memory_check_end

JsonEdit::JsonEdit(LiteApi::IApplication *app, QObject *parent)
    : QObject(parent), m_liteApp(app)
{
    LiteApi::IActionContext *actionContext = m_liteApp->actionManager()->getActionContext(this,"JsonEdit");

    m_verifyAct = new QAction(tr("Verify"),this);
    actionContext->regAction(m_verifyAct,"VerifyJson","");
    m_formatAct = new QAction(tr("Format Json"),this);
    actionContext->regAction(m_formatAct,"FormatJson","Ctrl+I");
    m_compactAct = new QAction(tr("Compact Json"),this);
    actionContext->regAction(m_compactAct,"CompactJson","");

    connect(m_liteApp->editorManager(),SIGNAL(editorCreated(LiteApi::IEditor*)),this,SLOT(editorCreated(LiteApi::IEditor*)));
    connect(m_liteApp->editorManager(),SIGNAL(editorSaved(LiteApi::IEditor*)),this,SLOT(editorSaved(LiteApi::IEditor*)));
    connect(m_verifyAct,SIGNAL(triggered()),this,SLOT(verify()));
    connect(m_formatAct,SIGNAL(triggered()),this,SLOT(format()));
    connect(m_compactAct,SIGNAL(triggered()),this,SLOT(compact()));
}

//void JsonEdit::indentNone()
//{
//    format(QJson::IndentNone);
//}

//void JsonEdit::indentCompact()
//{
//    format(QJson::IndentCompact);
//}

//void JsonEdit::indentMinimum()
//{
//    format(QJson::IndentMinimum);
//}

//void JsonEdit::indentMedium()
//{
//    format(QJson::IndentMedium);
//}
//void JsonEdit::indentFull()
//{
//    format(QJson::IndentFull);
//}

bool JsonEdit::verifyJson(LiteApi::IEditor *editor)
{
    LiteApi::ILiteEditor *ed = LiteApi::getLiteEditor(editor);
    if (!ed) {
        return false;
    }
    QJson::Parser parser;
    bool ok = true;
    parser.parse(ed->utf8Data(),&ok);
    if (!ok) {
        ed->setNavigateHead(LiteApi::EditorNavigateError,"json verify error");
        if (parser.errorLine() > 0) {
            ed->insertNavigateMark(parser.errorLine()-1,LiteApi::EditorNavigateError,parser.errorString(),"Json");
        }
    } else {
        ed->setNavigateHead(LiteApi::EditorNavigateNormal,"json verify success");
        ed->clearAllNavigateMark(LiteApi::EditorNavigateError,"Json");
    }
    return ok;
}

void JsonEdit::verify()
{
    LiteApi::IEditor *editor = m_liteApp->editorManager()->currentEditor();
    if (!editor || editor->mimeType() != "application/json") {
        return;
    }
    verifyJson(editor);
}

void JsonEdit::format()
{
    LiteApi::IEditor *editor = m_liteApp->editorManager()->currentEditor();
    if (!editor || editor->mimeType() != "application/json") {
        return;
    }
    if (!verifyJson(editor)) {
        return;
    }
    fmtEditor(editor,false,false,true,1000);
}

void JsonEdit::compact()
{
    LiteApi::IEditor *editor = m_liteApp->editorManager()->currentEditor();
    if (!editor || editor->mimeType() != "application/json") {
        return;
    }
    if (!verifyJson(editor)) {
        return;
    }
    fmtEditor(editor,true,false,true,1000);
}

void JsonEdit::fmtEditor(LiteApi::IEditor *editor, bool compact, bool tabs, bool diff,int timeout)
{
    LiteApi::ITextEditor *textEditor = LiteApi::getTextEditor(editor);
    if (!textEditor) {
        return;
    }
    bool save = !editor->isModified();

    QPlainTextEdit *ed = LiteApi::findExtensionObject<QPlainTextEdit*>(editor,"LiteApi.QPlainTextEdit");
    if (!ed) {
        return;
    }

    QString text = ed->toPlainText();
    if (text.isEmpty()) {
        return;
    }

    QProcess process;
    process.setEnvironment(LiteApi::getGoEnvironment(m_liteApp).toStringList());

    QStringList args;

    args << "jsonfmt";
    if (compact) {
        args << "-c";
    }
    if (tabs) {
        args << "-tabs";
    }
    if (diff) {
        args << "-d";
    }
    QString cmd = LiteApi::getGotools(m_liteApp);
    process.start(cmd,args);
    if (!process.waitForStarted(timeout)) {
        m_liteApp->appendLog("jsonfmt",QString("Timed out after %1ms when starting json format").arg(timeout),false);
        return;
    }
    process.write(text.toUtf8());
    process.closeWriteChannel();
    if (!process.waitForFinished(timeout*4)) {
        m_liteApp->appendLog("jsonfmt",QString("Timed out after %1ms while running json format").arg(timeout*4),false);
        return;
    }
    LiteApi::ILiteEditor *liteEditor = LiteApi::getLiteEditor(editor);
    liteEditor->clearAllNavigateMark(LiteApi::EditorNavigateBad, "Json");
    QTextCodec *codec = QTextCodec::codecForName("utf-8");

    if (process.exitCode() != 0) {
        m_liteApp->appendLog("jsonfmt",QString::fromUtf8(process.readAll()),true);
        return;
    }

    QByteArray data = process.readAllStandardOutput();
    /*
    int vpos = -1;
    QScrollBar *bar = ed->verticalScrollBar();
    if (bar) {
        vpos = bar->sliderPosition();
    }
    */
    QByteArray state = editor->saveState();
    QTextCursor cur = ed->textCursor();
    //int pos = cur.position();
    cur.beginEditBlock();
    if (diff) {
        EditorUtil::loadDiff(cur,codec->toUnicode(data));
    } else {
        cur.select(QTextCursor::Document);
        cur.removeSelectedText();
        cur.insertText(codec->toUnicode(data));
    }
    //cur.setPosition(pos);
    cur.endEditBlock();
    ed->setTextCursor(cur);
    editor->restoreState(state);

    //ed->setTextCursor(cur);
    //if (vpos != -1) {
    //    bar->setSliderPosition(vpos);
    //}
    if (save) {
        m_liteApp->editorManager()->saveEditor(editor,false);
    }
}

void JsonEdit::editorCreated(LiteApi::IEditor *editor)
{
    if (editor->mimeType() != "application/json") {
        return;
    }
    LiteApi::ILiteEditor *ed = LiteApi::getLiteEditor(editor);
    if (!ed) {
        return;
    }
    ed->setWordWrap(true);
    ed->setEnableAutoIndentAction(false);

    QMenu *menu = LiteApi::getContextMenu(editor);
    if (menu) {
        menu->addSeparator();
        menu->addAction(m_verifyAct);
        menu->addAction(m_formatAct);
        menu->addAction(m_compactAct);
    }
    menu = LiteApi::getEditMenu(editor);
    if (menu) {
        menu->addSeparator();
        menu->addAction(m_verifyAct);
        menu->addAction(m_formatAct);
        menu->addAction(m_compactAct);
    }
}

void JsonEdit::editorSaved(LiteApi::IEditor *editor)
{
    if (editor->mimeType() != "application/json") {
        return;
    }
    verifyJson(editor);
}

//void JsonEdit::format(QJson::IndentMode mode)
//{
//    QJson::Parser parser;
//    bool ok = true;
//    QVariant json = parser.parse(m_editor->utf8Data(),&ok);
//    if (!ok) {
//        return;
//    }
//    QJson::Serializer stream;
//    stream.setIndentMode(mode);
//    QByteArray data = stream.serialize(json);
//    QPlainTextEdit *ed = LiteApi::getPlainTextEdit(m_editor);
//    if (ed) {
//        QTextCursor cursor = ed->textCursor();
//        cursor.beginEditBlock();
//        cursor.select(QTextCursor::Document);
//        cursor.removeSelectedText();
//        cursor.insertText(QString::fromUtf8(data));
//        cursor.endEditBlock();
//        ed->setTextCursor(cursor);
//    }
//}
<|endoftext|>


<commit_before>/**************************************************************************
** This file is part of LiteIDE
**
** Copyright (c) 2011-2020 LiteIDE. All rights reserved.
**
** This library is free software; you can redistribute it and/or
** modify it under the terms of the GNU Lesser General Public
** License as published by the Free Software Foundation; either
** version 2.1 of the License, or (at your option) any later version.
**
** This library 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
** Lesser General Public License for more details.
**
** In addition, as a special exception,  that plugins developed for LiteIDE,
** are allowed to remain closed sourced and can be distributed under any license .
** These rights are included in the file LGPL_EXCEPTION.txt in this package.
**
**************************************************************************/
// Module: terminal.cpp
// Creator: visualfc <visualfc@gmail.com>

#include "terminal.h"
#include "vterm/vtermwidget.h"
#include "vterm/vtermcolor.h"
#include "liteenvapi/liteenvapi.h"
#include <QTabWidget>
#include <QFileInfo>
#include <QDir>
#include <QTime>
#include <QFontMetrics>

#define TERMINAL_CURCMD "terminal/curcmd"
#define TERMINAL_DARKMODE "terminal/darkmode"

#ifdef Q_OS_WIN
static QString checkFile(const QStringList &dirList, const QString &filePath)
{
    foreach (QString root, dirList) {
        QFileInfo info(root,filePath);
        if (info.exists()) {
            return QDir::toNativeSeparators(info.filePath());
        }
    }
    return QString();
}

static QString GetWindowGitBash()
{
    QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
    QStringList dirList;
    dirList << env.value("ProgramW6432","C:\\Program Files");
    dirList << env.value("ProgramFiles","C:\\Program Files");
    return checkFile(dirList,"Git\\bin\\bash.exe");
}

static QString GetWindowPowerShell()
{
    QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
    QStringList dirList;
    dirList << env.value("windir","C:\\Windows");
    return checkFile(dirList,"System32\\WindowsPowerShell\\v1.0\\powershell.exe");
}

static QString GetWindowsShell()
{
    QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
    QString windir = env.value("windir","C:\\Windows");
    QFileInfo info(windir,"System32\\cmd.exe");
    return QDir::toNativeSeparators(info.filePath());
}
#endif

Terminal::Terminal(LiteApi::IApplication *app, QObject *parent) : QObject(parent),
    m_liteApp(app), m_indexId(0)
{
    m_tab = new QTabWidget;
    m_tab->setDocumentMode(true);
    m_tab->setTabsClosable(true);
    m_tab->setUsesScrollButtons(true);

    m_newTabAct = new QAction("New",this);
    connect(m_newTabAct,SIGNAL(triggered()),this,SLOT(newTerminal()));
    m_closeTabAct = new QAction("Terminate",this);
    connect(m_closeTabAct,SIGNAL(triggered()),this,SLOT(closeCurrenTab()));

    QList<QAction*> actions;
    m_filterMenu = new QMenu(tr("Filter"));
    m_filterMenu->setIcon(QIcon("icon:images/filter.png"));
#ifdef Q_OS_WIN
    QString bash = GetWindowGitBash();
    QString powershell = GetWindowPowerShell();
    QString cmd = GetWindowsShell();
    m_cmdList.append(Command("cmd",cmd));
    if (!powershell.isEmpty()) {
        m_cmdList.append(Command("powershell",powershell));
    }
    if (!bash.isEmpty()) {
        m_cmdList.append(Command("bash",bash));
    }
#else
    m_cmdList.append(Command("bash","/bin/bash",QStringList() << "-i" << "-l"));
    m_cmdList.append(Command("bash(2)","/bin/bash"));
#endif
    m_curName = m_liteApp->settings()->value(TERMINAL_CURCMD,m_cmdList[0].name).toString();
    m_darkMode = m_liteApp->settings()->value(TERMINAL_DARKMODE,false).toBool();

    m_darkModeAct = new QAction(tr("Dark Mode"),this);
    m_darkModeAct->setCheckable(true);
    m_darkModeAct->setChecked(m_darkMode);

    connect(m_darkModeAct,SIGNAL(toggled(bool)),this,SLOT(toggledDarkMode(bool)));
    m_filterMenu->addAction(m_darkModeAct);

    if (m_cmdList.size() > 1) {
        QActionGroup *group = new QActionGroup(this);
        foreach (Command cmd, m_cmdList) {
            QString info = cmd.name+"\t"+cmd.path;
            if (!cmd.args.isEmpty()) {
                info += " "+cmd.args.join(" ");
            }
            QAction *act = new QAction(info,this);
            act->setData(cmd.name);
            act->setCheckable(true);
            act->setToolTip(cmd.path);
            if (m_curName == cmd.name) {
                act->setChecked(true);
            }
            group->addAction(act);
        }
        connect(group,SIGNAL(triggered(QAction*)),this,SLOT(triggeredCmd(QAction*)));
        m_filterMenu->addSeparator();
        m_filterMenu->addActions(group->actions());
        actions << m_filterMenu->menuAction();
    }

    actions << m_newTabAct << m_closeTabAct;
    m_toolWindowAct = m_liteApp->toolWindowManager()->addToolWindow(Qt::BottomDockWidgetArea,m_tab,"Terminal",tr("Terminal"),true,actions);
    connect(m_toolWindowAct,SIGNAL(toggled(bool)),this,SLOT(visibilityChanged(bool)));
    connect(m_tab,SIGNAL(tabCloseRequested(int)),this,SLOT(tabCloseRequested(int)));
}

void Terminal::newTerminal()
{
    VTermWidget *term = new VTermWidget(m_tab);
    int index = m_tab->addTab(term,QString("terminal %1").arg(++m_indexId));
    m_tab->setCurrentIndex(index);
    term->setFocus();
    term->updateGeometry();
    term->setDarkMode(m_darkMode);

    QString dir;
    LiteApi::IEditor *editor = m_liteApp->editorManager()->currentEditor();
    if (editor && !editor->filePath().isEmpty()) {
        dir = QFileInfo(editor->filePath()).path();
    }
    if (dir.isEmpty()) {
        dir = QDir::homePath();
    }
    dir = QDir::toNativeSeparators(dir);
    QProcessEnvironment env = LiteApi::getGoEnvironment(m_liteApp);
    QString info = QString("%1: %2").arg(QTime::currentTime().toString("hh:mm:ss")).arg(dir);
    term->inputWrite(colored(info,TERM_COLOR_DEFAULT,TERM_COLOR_DEFAULT,TERM_ATTR_BOLD).toUtf8());
    term->inputWrite("\r\n");

    Command cmd = m_cmdList[0];
    if (m_cmdList.size() > 1) {
        foreach (Command c, m_cmdList) {
            if (m_curName == c.name) {
                cmd = c;
                break;
            }
        }
    }
    term->start(cmd.path,cmd.args,dir,env.toStringList());

    connect(term,SIGNAL(titleChanged(QString)),this,SLOT(termTitleChanged(QString)));
    connect(term,SIGNAL(exited()),this,SLOT(termExited()));
}

void Terminal::visibilityChanged(bool b)
{
    if (b && m_tab->count() == 0) {
        newTerminal();
    }
    QWidget *widget = m_tab->currentWidget();
    if (widget) {
        widget->setFocus();
    }
}

void Terminal::termExited()
{
    VTermWidget *widget = static_cast<VTermWidget*>(sender());
    int index = m_tab->indexOf(widget);
    if (index >= 0) {
        m_tab->removeTab(index);
    }
    widget->deleteLater();
}

void Terminal::termTitleChanged(QString title)
{
    VTermWidget *widget = static_cast<VTermWidget*>(sender());
    int index = m_tab->indexOf(widget);
    if (index >= 0) {
        m_tab->setTabToolTip(index,title);
    }
}

void Terminal::tabCloseRequested(int index)
{
    VTermWidget *widget = static_cast<VTermWidget*>(m_tab->widget(index));
    widget->deleteLater();
}

void Terminal::closeCurrenTab()
{
    int index = m_tab->currentIndex();
    if (index >= 0) {
        tabCloseRequested(index);
    }
}

void Terminal::triggeredCmd(QAction *act)
{
    m_curName = act->data().toString();
    m_liteApp->settings()->setValue(TERMINAL_CURCMD,m_curName);
}

void Terminal::toggledDarkMode(bool checked)
{
    m_darkMode = checked;
    m_liteApp->settings()->setValue(TERMINAL_DARKMODE,m_darkMode);
}
<commit_msg>terminal: update tab name by cur cmd name<commit_after>/**************************************************************************
** This file is part of LiteIDE
**
** Copyright (c) 2011-2020 LiteIDE. All rights reserved.
**
** This library is free software; you can redistribute it and/or
** modify it under the terms of the GNU Lesser General Public
** License as published by the Free Software Foundation; either
** version 2.1 of the License, or (at your option) any later version.
**
** This library 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
** Lesser General Public License for more details.
**
** In addition, as a special exception,  that plugins developed for LiteIDE,
** are allowed to remain closed sourced and can be distributed under any license .
** These rights are included in the file LGPL_EXCEPTION.txt in this package.
**
**************************************************************************/
// Module: terminal.cpp
// Creator: visualfc <visualfc@gmail.com>

#include "terminal.h"
#include "vterm/vtermwidget.h"
#include "vterm/vtermcolor.h"
#include "liteenvapi/liteenvapi.h"
#include <QTabWidget>
#include <QFileInfo>
#include <QDir>
#include <QTime>
#include <QFontMetrics>

#define TERMINAL_CURCMD "terminal/curcmd"
#define TERMINAL_DARKMODE "terminal/darkmode"

#ifdef Q_OS_WIN
static QString checkFile(const QStringList &dirList, const QString &filePath)
{
    foreach (QString root, dirList) {
        QFileInfo info(root,filePath);
        if (info.exists()) {
            return QDir::toNativeSeparators(info.filePath());
        }
    }
    return QString();
}

static QString GetWindowGitBash()
{
    QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
    QStringList dirList;
    dirList << env.value("ProgramW6432","C:\\Program Files");
    dirList << env.value("ProgramFiles","C:\\Program Files");
    return checkFile(dirList,"Git\\bin\\bash.exe");
}

static QString GetWindowPowerShell()
{
    QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
    QStringList dirList;
    dirList << env.value("windir","C:\\Windows");
    return checkFile(dirList,"System32\\WindowsPowerShell\\v1.0\\powershell.exe");
}

static QString GetWindowsShell()
{
    QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
    QString windir = env.value("windir","C:\\Windows");
    QFileInfo info(windir,"System32\\cmd.exe");
    return QDir::toNativeSeparators(info.filePath());
}
#endif

Terminal::Terminal(LiteApi::IApplication *app, QObject *parent) : QObject(parent),
    m_liteApp(app), m_indexId(0)
{
    m_tab = new QTabWidget;
    m_tab->setDocumentMode(true);
    m_tab->setTabsClosable(true);
    m_tab->setUsesScrollButtons(true);

    m_newTabAct = new QAction("New",this);
    connect(m_newTabAct,SIGNAL(triggered()),this,SLOT(newTerminal()));
    m_closeTabAct = new QAction("Terminate",this);
    connect(m_closeTabAct,SIGNAL(triggered()),this,SLOT(closeCurrenTab()));

    QList<QAction*> actions;
    m_filterMenu = new QMenu(tr("Filter"));
    m_filterMenu->setIcon(QIcon("icon:images/filter.png"));
#ifdef Q_OS_WIN
    QString bash = GetWindowGitBash();
    QString powershell = GetWindowPowerShell();
    QString cmd = GetWindowsShell();
    m_cmdList.append(Command("cmd",cmd));
    if (!powershell.isEmpty()) {
        m_cmdList.append(Command("powershell",powershell));
    }
    if (!bash.isEmpty()) {
        m_cmdList.append(Command("bash",bash));
    }
#else
    m_cmdList.append(Command("bash","/bin/bash",QStringList() << "-i" << "-l"));
    m_cmdList.append(Command("bash(2)","/bin/bash"));
#endif
    m_curName = m_liteApp->settings()->value(TERMINAL_CURCMD,m_cmdList[0].name).toString();
    m_darkMode = m_liteApp->settings()->value(TERMINAL_DARKMODE,false).toBool();

    m_darkModeAct = new QAction(tr("Dark Mode"),this);
    m_darkModeAct->setCheckable(true);
    m_darkModeAct->setChecked(m_darkMode);

    connect(m_darkModeAct,SIGNAL(toggled(bool)),this,SLOT(toggledDarkMode(bool)));
    m_filterMenu->addAction(m_darkModeAct);

    if (m_cmdList.size() > 1) {
        QActionGroup *group = new QActionGroup(this);
        foreach (Command cmd, m_cmdList) {
            QString info = cmd.name+"\t"+cmd.path;
            if (!cmd.args.isEmpty()) {
                info += " "+cmd.args.join(" ");
            }
            QAction *act = new QAction(info,this);
            act->setData(cmd.name);
            act->setCheckable(true);
            act->setToolTip(cmd.path);
            if (m_curName == cmd.name) {
                act->setChecked(true);
            }
            group->addAction(act);
        }
        connect(group,SIGNAL(triggered(QAction*)),this,SLOT(triggeredCmd(QAction*)));
        m_filterMenu->addSeparator();
        m_filterMenu->addActions(group->actions());
        actions << m_filterMenu->menuAction();
    }

    actions << m_newTabAct << m_closeTabAct;
    m_toolWindowAct = m_liteApp->toolWindowManager()->addToolWindow(Qt::BottomDockWidgetArea,m_tab,"Terminal",tr("Terminal"),true,actions);
    connect(m_toolWindowAct,SIGNAL(toggled(bool)),this,SLOT(visibilityChanged(bool)));
    connect(m_tab,SIGNAL(tabCloseRequested(int)),this,SLOT(tabCloseRequested(int)));
}

void Terminal::newTerminal()
{
    VTermWidget *term = new VTermWidget(m_tab);
    int index = m_tab->addTab(term,QString("%1 %2").arg(m_curName).arg(++m_indexId));
    m_tab->setCurrentIndex(index);
    term->setFocus();
    term->updateGeometry();
    term->setDarkMode(m_darkMode);

    QString dir;
    LiteApi::IEditor *editor = m_liteApp->editorManager()->currentEditor();
    if (editor && !editor->filePath().isEmpty()) {
        dir = QFileInfo(editor->filePath()).path();
    }
    if (dir.isEmpty()) {
        dir = QDir::homePath();
    }
    dir = QDir::toNativeSeparators(dir);
    QProcessEnvironment env = LiteApi::getGoEnvironment(m_liteApp);
    QString info = QString("%1: %2").arg(QTime::currentTime().toString("hh:mm:ss")).arg(dir);
    term->inputWrite(colored(info,TERM_COLOR_DEFAULT,TERM_COLOR_DEFAULT,TERM_ATTR_BOLD).toUtf8());
    term->inputWrite("\r\n");

    Command cmd = m_cmdList[0];
    if (m_cmdList.size() > 1) {
        foreach (Command c, m_cmdList) {
            if (m_curName == c.name) {
                cmd = c;
                break;
            }
        }
    }
    term->start(cmd.path,cmd.args,dir,env.toStringList());

    connect(term,SIGNAL(titleChanged(QString)),this,SLOT(termTitleChanged(QString)));
    connect(term,SIGNAL(exited()),this,SLOT(termExited()));
}

void Terminal::visibilityChanged(bool b)
{
    if (b && m_tab->count() == 0) {
        newTerminal();
    }
    QWidget *widget = m_tab->currentWidget();
    if (widget) {
        widget->setFocus();
    }
}

void Terminal::termExited()
{
    VTermWidget *widget = static_cast<VTermWidget*>(sender());
    int index = m_tab->indexOf(widget);
    if (index >= 0) {
        m_tab->removeTab(index);
    }
    widget->deleteLater();
}

void Terminal::termTitleChanged(QString title)
{
    VTermWidget *widget = static_cast<VTermWidget*>(sender());
    int index = m_tab->indexOf(widget);
    if (index >= 0) {
        m_tab->setTabToolTip(index,title);
    }
}

void Terminal::tabCloseRequested(int index)
{
    VTermWidget *widget = static_cast<VTermWidget*>(m_tab->widget(index));
    widget->deleteLater();
}

void Terminal::closeCurrenTab()
{
    int index = m_tab->currentIndex();
    if (index >= 0) {
        tabCloseRequested(index);
    }
}

void Terminal::triggeredCmd(QAction *act)
{
    m_curName = act->data().toString();
    m_liteApp->settings()->setValue(TERMINAL_CURCMD,m_curName);
}

void Terminal::toggledDarkMode(bool checked)
{
    m_darkMode = checked;
    m_liteApp->settings()->setValue(TERMINAL_DARKMODE,m_darkMode);
}
<|endoftext|>