mirror of
https://github.com/github/codeql.git
synced 2025-12-16 16:53:25 +01:00
1461 lines
37 KiB
C++
1461 lines
37 KiB
C++
namespace {
|
|
template<typename T> T source();
|
|
template<typename T> T* indirect_source();
|
|
void sink(...);
|
|
}
|
|
|
|
typedef unsigned int UINT;
|
|
typedef long LONG;
|
|
typedef void* LPVOID;
|
|
typedef void* PVOID;
|
|
typedef bool BOOL;
|
|
typedef char* PSTR, *LPSTR;
|
|
typedef const char* LPCTSTR;
|
|
typedef const wchar_t* LPCWSTR;
|
|
typedef unsigned short WORD;
|
|
typedef unsigned long DWORD;
|
|
typedef void* HANDLE;
|
|
typedef LONG HRESULT;
|
|
typedef unsigned long ULONG;
|
|
typedef const char* LPCSTR;
|
|
typedef wchar_t OLECHAR;
|
|
typedef OLECHAR* LPOLESTR;
|
|
typedef const LPOLESTR LPCOLESTR;
|
|
typedef OLECHAR* BSTR;
|
|
typedef wchar_t* LPWSTR, *PWSTR;
|
|
typedef BSTR* LPBSTR;
|
|
typedef unsigned short USHORT;
|
|
typedef char *LPTSTR;
|
|
struct __POSITION { int unused; };
|
|
typedef __POSITION* POSITION;
|
|
typedef WORD ATL_URL_PORT;
|
|
|
|
using HINSTANCE = void*;
|
|
using size_t = decltype(sizeof(int));
|
|
using SIZE_T = size_t;
|
|
|
|
#define NULL nullptr
|
|
|
|
namespace ATL {
|
|
enum ATL_URL_SCHEME{
|
|
ATL_URL_SCHEME_UNKNOWN = -1,
|
|
ATL_URL_SCHEME_FTP = 0,
|
|
ATL_URL_SCHEME_GOPHER = 1,
|
|
ATL_URL_SCHEME_HTTP = 2,
|
|
ATL_URL_SCHEME_HTTPS = 3,
|
|
ATL_URL_SCHEME_FILE = 4,
|
|
ATL_URL_SCHEME_NEWS = 5,
|
|
ATL_URL_SCHEME_MAILTO = 6,
|
|
ATL_URL_SCHEME_SOCKS = 7
|
|
};
|
|
|
|
typedef struct tagSAFEARRAYBOUND {
|
|
ULONG cElements;
|
|
LONG lLbound;
|
|
} SAFEARRAYBOUND, *LPSAFEARRAYBOUND;
|
|
|
|
typedef struct tagVARIANT {
|
|
/* ... */
|
|
} VARIANT;
|
|
|
|
typedef struct tagSAFEARRAY {
|
|
USHORT cDims;
|
|
USHORT fFeatures;
|
|
ULONG cbElements;
|
|
ULONG cLocks;
|
|
PVOID pvData;
|
|
SAFEARRAYBOUND rgsabound[1];
|
|
} SAFEARRAY, *LPSAFEARRAY;
|
|
|
|
struct _U_STRINGorID {
|
|
_U_STRINGorID(UINT nID);
|
|
_U_STRINGorID(LPCTSTR lpString);
|
|
|
|
LPCTSTR m_lpstr;
|
|
};
|
|
|
|
void test__U_STRINGorID() {
|
|
{
|
|
UINT x = source<UINT>();
|
|
_U_STRINGorID u(x);
|
|
sink(u.m_lpstr); // $ ir
|
|
}
|
|
|
|
{
|
|
LPCTSTR y = indirect_source<const char>();
|
|
_U_STRINGorID u(y);
|
|
sink(u.m_lpstr); // $ ir
|
|
}
|
|
}
|
|
|
|
template <int t_nBufferLength>
|
|
struct CA2AEX {
|
|
LPSTR m_psz;
|
|
char m_szBuffer[t_nBufferLength];
|
|
|
|
CA2AEX(LPCSTR psz, UINT nCodePage);
|
|
CA2AEX(LPCSTR psz);
|
|
|
|
~CA2AEX();
|
|
|
|
operator LPSTR() const throw();
|
|
};
|
|
|
|
void test_CA2AEX() {
|
|
{
|
|
LPSTR x = indirect_source<char>();
|
|
CA2AEX<128> a(x);
|
|
sink(static_cast<LPSTR>(a)); // $ ir
|
|
sink(a.m_psz); // $ ir
|
|
sink(a.m_szBuffer); // $ ir
|
|
}
|
|
|
|
{
|
|
LPSTR x = indirect_source<char>();
|
|
CA2AEX<128> a(x, 0);
|
|
sink(static_cast<LPSTR>(a)); // $ ir
|
|
sink(a.m_psz); // $ ir
|
|
sink(a.m_szBuffer); // $ ir
|
|
}
|
|
}
|
|
|
|
template<int t_nBufferLength>
|
|
struct CA2CAEX {
|
|
CA2CAEX(LPCSTR psz, UINT nCodePage) ;
|
|
CA2CAEX(LPCSTR psz) ;
|
|
~CA2CAEX() throw();
|
|
operator LPCSTR() const throw();
|
|
LPCSTR m_psz;
|
|
};
|
|
|
|
void test_CA2CAEX() {
|
|
LPCSTR x = indirect_source<char>();
|
|
{
|
|
CA2CAEX<128> a(x);
|
|
sink(static_cast<LPCSTR>(a)); // $ ir
|
|
sink(a.m_psz); // $ ir
|
|
sink(a.m_psz); // $ ir
|
|
}
|
|
{
|
|
CA2CAEX<128> a(x, 0);
|
|
sink(static_cast<LPCSTR>(a)); // $ ir
|
|
sink(a.m_psz); // $ ir
|
|
sink(a.m_psz); // $ ir
|
|
}
|
|
}
|
|
|
|
template <int t_nBufferLength>
|
|
struct CA2WEX {
|
|
CA2WEX(LPCSTR psz, UINT nCodePage) ;
|
|
CA2WEX(LPCSTR psz) ;
|
|
~CA2WEX() throw();
|
|
operator LPWSTR() const throw();
|
|
LPWSTR m_psz;
|
|
wchar_t m_szBuffer[t_nBufferLength];
|
|
};
|
|
|
|
void test_CA2WEX() {
|
|
LPCSTR x = indirect_source<char>();
|
|
{
|
|
CA2WEX<128> a(x);
|
|
sink(static_cast<LPWSTR>(a)); // $ ir
|
|
sink(a.m_psz); // $ ir
|
|
sink(a.m_psz); // $ ir
|
|
}
|
|
{
|
|
CA2WEX<128> a(x, 0);
|
|
sink(static_cast<LPWSTR>(a)); // $ ir
|
|
sink(a.m_psz); // $ ir
|
|
sink(a.m_psz); // $ ir
|
|
}
|
|
}
|
|
|
|
template<typename T>
|
|
struct CElementTraitsBase {
|
|
typedef const T& INARGTYPE;
|
|
typedef T& OUTARGTYPE;
|
|
|
|
static void CopyElements(T* pDest, const T* pSrc, size_t nElements);
|
|
static void RelocateElements(T* pDest, T* pSrc, size_t nElements);
|
|
};
|
|
|
|
template <typename T>
|
|
struct CDefaultElementTraits : public CElementTraitsBase<T> {};
|
|
|
|
template<typename T>
|
|
struct CElementTraits : public CDefaultElementTraits<T> {};
|
|
|
|
template<typename E, class ETraits = CElementTraits<E>>
|
|
struct CAtlArray {
|
|
using INARGTYPE = typename ETraits::INARGTYPE;
|
|
using OUTARGTYPE = typename ETraits::OUTARGTYPE;
|
|
|
|
CAtlArray() throw();
|
|
~CAtlArray() throw();
|
|
|
|
size_t Add(INARGTYPE element);
|
|
size_t Add();
|
|
size_t Append(const CAtlArray<E, ETraits>& aSrc);
|
|
void Copy(const CAtlArray<E, ETraits>& aSrc);
|
|
const E& GetAt(size_t iElement) const throw();
|
|
E& GetAt(size_t iElement) throw();
|
|
size_t GetCount() const throw();
|
|
E* GetData() throw();
|
|
const E* GetData() const throw();
|
|
void InsertArrayAt(size_t iStart, const CAtlArray<E, ETraits>* paNew);
|
|
void InsertAt(size_t iElement, INARGTYPE element, size_t nCount);
|
|
bool IsEmpty() const throw();
|
|
void RemoveAll() throw();
|
|
void RemoveAt(size_t iElement, size_t nCount);
|
|
void SetAt(size_t iElement, INARGTYPE element);
|
|
void SetAtGrow(size_t iElement, INARGTYPE element);
|
|
bool SetCount(size_t nNewSize, int nGrowBy);
|
|
E& operator[](size_t ielement) throw();
|
|
const E& operator[](size_t ielement) const throw();
|
|
};
|
|
|
|
void test_CAtlArray() {
|
|
int x = source<int>();
|
|
|
|
{
|
|
CAtlArray<int> a;
|
|
a.Add(x);
|
|
sink(a[0]); // $ ir
|
|
a.Add(0);
|
|
sink(a[0]); // $ ir
|
|
|
|
CAtlArray<int> a2;
|
|
sink(a2[0]);
|
|
a2.Append(a);
|
|
sink(a2[0]); // $ ir
|
|
|
|
CAtlArray<int> a3;
|
|
sink(a3[0]);
|
|
a3.Copy(a2);
|
|
sink(a3[0]); // $ ir
|
|
|
|
sink(a3.GetAt(0)); // $ ir
|
|
sink(*a3.GetData()); // $ ir
|
|
|
|
CAtlArray<int> a4;
|
|
sink(a4.GetAt(0));
|
|
a4.InsertArrayAt(0, &a3);
|
|
sink(a4.GetAt(0)); // $ ir
|
|
}
|
|
{
|
|
CAtlArray<int> a5;
|
|
a5.InsertAt(0, source<int>(), 1);
|
|
sink(a5[0]); // $ ir
|
|
|
|
CAtlArray<int> a6;
|
|
a6.SetAtGrow(0, source<int>());
|
|
sink(a6[0]); // $ ir
|
|
}
|
|
}
|
|
|
|
template<typename E, class ETraits = CElementTraits<E>>
|
|
struct CAtlList {
|
|
using INARGTYPE = typename ETraits::INARGTYPE;
|
|
CAtlList(UINT nBlockSize) throw();
|
|
~CAtlList() throw();
|
|
POSITION AddHead();
|
|
POSITION AddHead(INARGTYPE element);
|
|
void AddHeadList(const CAtlList<E, ETraits>* plNew);
|
|
POSITION AddTail();
|
|
POSITION AddTail(INARGTYPE element);
|
|
void AddTailList(const CAtlList<E, ETraits>* plNew);
|
|
POSITION Find(INARGTYPE element, POSITION posStartAfter) const throw();
|
|
POSITION FindIndex(size_t iElement) const throw();
|
|
E& GetAt(POSITION pos) throw();
|
|
const E& GetAt(POSITION pos) const throw();
|
|
size_t GetCount() const throw();
|
|
E& GetHead() throw();
|
|
const E& GetHead() const throw();
|
|
POSITION GetHeadPosition() const throw();
|
|
E& GetNext(POSITION& pos) throw();
|
|
const E& GetNext(POSITION& pos) const throw();
|
|
E& GetPrev(POSITION& pos) throw();
|
|
const E& GetPrev(POSITION& pos) const throw();
|
|
E& GetTail() throw();
|
|
const E& GetTail() const throw();
|
|
POSITION GetTailPosition() const throw();
|
|
POSITION InsertAfter(POSITION pos, INARGTYPE element);
|
|
POSITION InsertBefore(POSITION pos, INARGTYPE element);
|
|
bool IsEmpty() const throw();
|
|
void MoveToHead(POSITION pos) throw();
|
|
void MoveToTail(POSITION pos) throw();
|
|
void RemoveAll() throw();
|
|
void RemoveAt(POSITION pos) throw();
|
|
E RemoveHead();
|
|
void RemoveHeadNoReturn() throw();
|
|
E RemoveTail();
|
|
void RemoveTailNoReturn() throw();
|
|
void SetAt(POSITION pos, INARGTYPE element);
|
|
void SwapElements(POSITION pos1, POSITION pos2) throw();
|
|
};
|
|
|
|
void test_CAtlList() {
|
|
int x = source<int>();
|
|
{
|
|
CAtlList<int> list(10);
|
|
sink(list.GetHead());
|
|
list.AddHead(x);
|
|
sink(list.GetHead()); // $ ir
|
|
|
|
CAtlList<int> list2(10);
|
|
list2.AddHeadList(&list);
|
|
sink(list2.GetHead()); // $ ir
|
|
|
|
CAtlList<int> list3(10);
|
|
list3.AddTail(x);
|
|
sink(list3.GetHead()); // $ ir
|
|
|
|
CAtlList<int> list4(10);
|
|
list4.AddTailList(&list3);
|
|
sink(list4.GetHead()); // $ ir
|
|
|
|
{
|
|
CAtlList<int> list5(10);
|
|
auto pos = list5.Find(x, list5.GetHeadPosition());
|
|
sink(list5.GetAt(pos)); // $ MISSING: ir
|
|
}
|
|
|
|
{
|
|
CAtlList<int> list6(10);
|
|
list6.AddHead(x);
|
|
auto pos = list6.FindIndex(0);
|
|
sink(list6.GetAt(pos)); // $ ir
|
|
}
|
|
|
|
{
|
|
CAtlList<int> list7(10);
|
|
auto pos = list7.GetTailPosition();
|
|
list7.InsertAfter(pos, x);
|
|
sink(list7.GetHead()); // $ ir
|
|
}
|
|
|
|
{
|
|
CAtlList<int> list8(10);
|
|
auto pos = list8.GetTailPosition();
|
|
list8.InsertBefore(pos, x);
|
|
sink(list8.GetHead()); // $ ir
|
|
}
|
|
{
|
|
CAtlList<int> list9(10);
|
|
list9.SetAt(list9.GetHeadPosition(), x);
|
|
sink(list9.GetHead()); // $ ir
|
|
}
|
|
}
|
|
|
|
int* p = indirect_source<int>();
|
|
{
|
|
CAtlList<int*> list(10);
|
|
sink(list.GetHead());
|
|
list.AddHead(p);
|
|
sink(list.GetHead()); // $ ir
|
|
|
|
CAtlList<int*> list2(10);
|
|
list2.AddHeadList(&list);
|
|
sink(list2.GetHead()); // $ ir
|
|
|
|
CAtlList<int*> list3(10);
|
|
list3.AddTail(p);
|
|
sink(list3.GetHead()); // $ ir
|
|
|
|
CAtlList<int*> list4(10);
|
|
list4.AddTailList(&list3);
|
|
sink(list4.GetHead()); // $ ir
|
|
|
|
{
|
|
CAtlList<int*> list5(10);
|
|
auto pos = list5.Find(p, list5.GetHeadPosition());
|
|
sink(list5.GetAt(pos)); // $ MISSING: ir
|
|
}
|
|
|
|
{
|
|
CAtlList<int*> list6(10);
|
|
list6.AddHead(p);
|
|
auto pos = list6.FindIndex(0);
|
|
sink(list6.GetAt(pos)); // $ ir
|
|
}
|
|
|
|
{
|
|
CAtlList<int*> list7(10);
|
|
auto pos = list7.GetTailPosition();
|
|
list7.InsertAfter(pos, p);
|
|
sink(list7.GetHead()); // $ ir
|
|
}
|
|
|
|
{
|
|
CAtlList<int*> list8(10);
|
|
auto pos = list8.GetTailPosition();
|
|
list8.InsertBefore(pos, p);
|
|
sink(list8.GetHead()); // $ ir
|
|
}
|
|
{
|
|
CAtlList<int*> list9(10);
|
|
list9.SetAt(list9.GetHeadPosition(), p);
|
|
sink(list9.GetHead()); // $ ir
|
|
}
|
|
}
|
|
}
|
|
|
|
struct IUnknown { };
|
|
|
|
struct ISequentialStream : public IUnknown { };
|
|
|
|
struct IStream : public ISequentialStream { };
|
|
|
|
struct CComBSTR {
|
|
CComBSTR() throw();
|
|
CComBSTR(const CComBSTR& src);
|
|
CComBSTR(int nSize);
|
|
CComBSTR(int nSize, LPCOLESTR sz);
|
|
CComBSTR(int nSize, LPCSTR sz);
|
|
CComBSTR(LPCOLESTR pSrc);
|
|
CComBSTR(LPCSTR pSrc);
|
|
CComBSTR(CComBSTR&& src) throw();
|
|
~CComBSTR();
|
|
|
|
HRESULT Append(const CComBSTR& bstrSrc) throw();
|
|
HRESULT Append(wchar_t ch) throw();
|
|
HRESULT Append(char ch) throw();
|
|
HRESULT Append(LPCOLESTR lpsz) throw();
|
|
HRESULT Append(LPCSTR lpsz) throw();
|
|
HRESULT Append(LPCOLESTR lpsz, int nLen) throw();
|
|
HRESULT AppendBSTR(BSTR p) throw();
|
|
HRESULT AppendBytes(const char* lpsz, int nLen) throw();
|
|
HRESULT ArrayToBSTR(const SAFEARRAY* pSrc) throw();
|
|
HRESULT AssignBSTR(const BSTR bstrSrc) throw();
|
|
void Attach(BSTR src) throw();
|
|
HRESULT BSTRToArray(LPSAFEARRAY* ppArray) throw();
|
|
unsigned int ByteLength() const throw();
|
|
BSTR Copy() const throw();
|
|
HRESULT CopyTo(BSTR* pbstr) throw();
|
|
|
|
HRESULT CopyTo(VARIANT* pvarDest) throw();
|
|
BSTR Detach() throw();
|
|
void Empty() throw();
|
|
unsigned int Length() const throw();
|
|
bool LoadString(HINSTANCE hInst, UINT nID) throw();
|
|
bool LoadString(UINT nID) throw();
|
|
HRESULT ReadFromStream(IStream* pStream) throw();
|
|
HRESULT ToUpper() throw();
|
|
HRESULT WriteToStream(IStream* pStream) throw();
|
|
|
|
operator BSTR() const throw();
|
|
BSTR* operator&() throw();
|
|
|
|
CComBSTR& operator+= (const CComBSTR& bstrSrc);
|
|
CComBSTR& operator+= (const LPCOLESTR pszSrc);
|
|
|
|
BSTR m_str;
|
|
};
|
|
|
|
LPSAFEARRAY getSafeArray() {
|
|
SAFEARRAY* safe = new SAFEARRAY;
|
|
safe->pvData = indirect_source<char>();
|
|
return safe;
|
|
}
|
|
|
|
void test_CComBSTR() {
|
|
char* x = indirect_source<char>();
|
|
{
|
|
CComBSTR b(x);
|
|
sink(b.m_str); // $ ir
|
|
|
|
CComBSTR b2(b);
|
|
sink(b2.m_str); // $ ir
|
|
}
|
|
{
|
|
CComBSTR b(10, x);
|
|
sink(b.m_str); // $ ir
|
|
}
|
|
{
|
|
CComBSTR b(x);
|
|
|
|
CComBSTR b2;
|
|
sink(b2.m_str);
|
|
b2 += b;
|
|
sink(b2.m_str); // $ ir
|
|
|
|
CComBSTR b3;
|
|
b3 += x;
|
|
sink(b3.m_str); // $ ir
|
|
sink(static_cast<BSTR>(b3)); // $ ir
|
|
sink(**&b3); // $ ir
|
|
|
|
CComBSTR b4;
|
|
b4.Append(source<char>());
|
|
sink(b4.m_str); // $ ir
|
|
|
|
CComBSTR b5;
|
|
b5.AppendBSTR(b4.m_str);
|
|
sink(b5.m_str); // $ ir
|
|
|
|
CComBSTR b6;
|
|
b6.AppendBytes(x, 10);
|
|
sink(b6.m_str); // $ ir
|
|
|
|
CComBSTR b7;
|
|
b7.ArrayToBSTR(getSafeArray());
|
|
sink(b7.m_str); // $ ir
|
|
|
|
CComBSTR b8;
|
|
b8.AssignBSTR(b7.m_str);
|
|
sink(b8.m_str); // $ ir
|
|
|
|
CComBSTR b9;
|
|
LPSAFEARRAY safe;
|
|
b9.Append(source<char>());
|
|
b9.BSTRToArray(&safe);
|
|
sink(safe->pvData); // $ ir
|
|
|
|
sink(b9.Copy()); // $ ir
|
|
}
|
|
|
|
wchar_t* w = indirect_source<wchar_t>();
|
|
{
|
|
CComBSTR b(w);
|
|
sink(b.m_str); // $ ir
|
|
|
|
CComBSTR b2;
|
|
b2.Attach(w);
|
|
sink(b2.m_str); // $ ir
|
|
}
|
|
{
|
|
CComBSTR b(10, w);
|
|
sink(b.m_str); // $ ir
|
|
}
|
|
}
|
|
|
|
template <typename T>
|
|
struct CComSafeArray {
|
|
CComSafeArray();
|
|
CComSafeArray(const SAFEARRAYBOUND& bound);
|
|
CComSafeArray(ULONG ulCount, LONG lLBound);
|
|
CComSafeArray(const SAFEARRAYBOUND* pBound, UINT uDims);
|
|
CComSafeArray(const CComSafeArray& saSrc);
|
|
CComSafeArray(const SAFEARRAY& saSrc);
|
|
CComSafeArray(const SAFEARRAY* psaSrc);
|
|
|
|
~CComSafeArray() throw();
|
|
|
|
HRESULT Add(const SAFEARRAY* psaSrc);
|
|
HRESULT Add(ULONG ulCount, const T* pT, BOOL bCopy);
|
|
HRESULT Add(const T& t, BOOL bCopy);
|
|
HRESULT Attach(const SAFEARRAY* psaSrc);
|
|
HRESULT CopyFrom(LPSAFEARRAY* ppArray);
|
|
HRESULT CopyTo(LPSAFEARRAY* ppArray);
|
|
HRESULT Create(const SAFEARRAYBOUND* pBound, UINT uDims);
|
|
HRESULT Create(ULONG ulCount, LONG lLBound);
|
|
HRESULT Destroy();
|
|
LPSAFEARRAY Detach();
|
|
T& GetAt(LONG lIndex) const;
|
|
ULONG GetCount(UINT uDim) const;
|
|
UINT GetDimensions() const;
|
|
LONG GetLowerBound(UINT uDim) const;
|
|
LPSAFEARRAY GetSafeArrayPtr() throw();
|
|
LONG GetUpperBound(UINT uDim) const;
|
|
bool IsSizable() const;
|
|
HRESULT MultiDimGetAt(const LONG* alIndex, T& t);
|
|
HRESULT MultiDimSetAt(const LONG* alIndex, const T& t);
|
|
HRESULT Resize(const SAFEARRAYBOUND* pBound);
|
|
HRESULT Resize(ULONG ulCount, LONG lLBound);
|
|
HRESULT SetAt(LONG lIndex, const T& t, BOOL bCopy);
|
|
operator LPSAFEARRAY() const;
|
|
T& operator[](long lindex) const;
|
|
T& operator[](int nindex) const;
|
|
|
|
LPSAFEARRAY m_psa;
|
|
};
|
|
|
|
void test_CComSafeArray() {
|
|
LPSAFEARRAY safe = getSafeArray();
|
|
sink(safe->pvData); // $ ir
|
|
{
|
|
CComSafeArray<int> c(safe);
|
|
sink(c[0]); // $ ir
|
|
sink(c.GetAt(0)); // $ ir
|
|
sink(c.GetSafeArrayPtr()->pvData); // $ ir
|
|
sink(c.m_psa->pvData); // $ ir
|
|
}
|
|
{
|
|
CComSafeArray<int> c;
|
|
sink(c[0]);
|
|
sink(c.GetAt(0));
|
|
sink(c.GetSafeArrayPtr()->pvData);
|
|
c.Add(safe);
|
|
sink(c[0]); // $ ir
|
|
sink(c.GetAt(0)); // $ ir
|
|
sink(c.GetSafeArrayPtr()->pvData); // $ ir
|
|
sink(static_cast<LPSAFEARRAY>(c)->pvData); // $ ir
|
|
}
|
|
{
|
|
CComSafeArray<int> c;
|
|
c.Add(source<int>(), true);
|
|
sink(c[0]); // $ ir
|
|
sink(c.GetAt(0)); // $ ir
|
|
sink(c.GetSafeArrayPtr()->pvData); // $ ir
|
|
}
|
|
{
|
|
CComSafeArray<int> c;
|
|
c.SetAt(0, source<int>(), true);
|
|
sink(c[0]); // $ ir
|
|
sink(c[0L]); // $ ir
|
|
}
|
|
}
|
|
|
|
template <typename StringType>
|
|
struct CPathT {
|
|
typedef StringType PCXSTR; // simplified
|
|
CPathT(PCXSTR pszPath);
|
|
CPathT(const CPathT<StringType>& path);
|
|
CPathT() throw();
|
|
|
|
void AddBackslash();
|
|
BOOL AddExtension(PCXSTR pszExtension);
|
|
BOOL Append(PCXSTR pszMore);
|
|
void BuildRoot(int iDrive);
|
|
void Canonicalize();
|
|
void Combine(PCXSTR pszDir, PCXSTR pszFile);
|
|
CPathT<StringType> CommonPrefix(PCXSTR pszOther);
|
|
BOOL CompactPathEx(UINT nMaxChars, DWORD dwFlags);
|
|
BOOL FileExists() const;
|
|
int FindExtension() const;
|
|
int FindFileName() const;
|
|
int GetDriveNumber() const;
|
|
StringType GetExtension() const;
|
|
BOOL IsDirectory() const;
|
|
BOOL IsFileSpec() const;
|
|
BOOL IsPrefix(PCXSTR pszPrefix) const;
|
|
BOOL IsRelative() const;
|
|
BOOL IsRoot() const;
|
|
BOOL IsSameRoot(PCXSTR pszOther) const;
|
|
BOOL IsUNC() const;
|
|
BOOL IsUNCServer() const;
|
|
BOOL IsUNCServerShare() const;
|
|
BOOL MakePretty();
|
|
BOOL MatchSpec(PCXSTR pszSpec) const;
|
|
void QuoteSpaces();
|
|
BOOL RelativePathTo(
|
|
PCXSTR pszFrom,
|
|
DWORD dwAttrFrom,
|
|
PCXSTR pszTo,
|
|
DWORD dwAttrTo);
|
|
void RemoveArgs();
|
|
void RemoveBackslash();
|
|
void RemoveBlanks();
|
|
void RemoveExtension();
|
|
BOOL RemoveFileSpec();
|
|
BOOL RenameExtension(PCXSTR pszExtension);
|
|
int SkipRoot() const;
|
|
void StripPath();
|
|
BOOL StripToRoot();
|
|
void UnquoteSpaces();
|
|
operator const StringType&() const throw();
|
|
operator PCXSTR() const throw();
|
|
operator StringType&() throw();
|
|
CPathT<StringType>& operator+=(PCXSTR pszMore);
|
|
|
|
StringType m_strPath;
|
|
};
|
|
|
|
using CPath = CPathT<char*>;
|
|
|
|
void test_CPathT() {
|
|
char* x = indirect_source<char>();
|
|
CPath p(x);
|
|
sink(static_cast<char*>(p)); // $ MISSING: ir
|
|
sink(p.m_strPath); // $ ir
|
|
|
|
CPath p2(p);
|
|
sink(p2.m_strPath); // $ ir
|
|
|
|
{
|
|
CPath p;
|
|
p.AddExtension(x);
|
|
sink(p.m_strPath); // $ ir
|
|
}
|
|
{
|
|
CPath p;
|
|
p.Append(x);
|
|
sink(p.m_strPath); // $ ir
|
|
|
|
CPath p2;
|
|
p2 += p;
|
|
sink(p2.m_strPath); // $ MISSING: ir // this requires flow through `operator StringType&()` which we can't yet model in MaD
|
|
|
|
CPath p3;
|
|
p3 += x;
|
|
sink(p3.m_strPath); // $ ir
|
|
}
|
|
|
|
{
|
|
CPath p;
|
|
p.Combine(x, nullptr);
|
|
sink(p.m_strPath); // $ ir
|
|
}
|
|
{
|
|
CPath p;
|
|
p.Combine(nullptr, x);
|
|
sink(p.m_strPath); // $ ir
|
|
}
|
|
|
|
{
|
|
CPath p;
|
|
auto p2 = p.CommonPrefix(x);
|
|
sink(p2.m_strPath); // $ ir
|
|
sink(p2.GetExtension()); // $ ir
|
|
}
|
|
}
|
|
|
|
template <class T>
|
|
struct CSimpleArray {
|
|
CSimpleArray(const CSimpleArray<T>& src);
|
|
CSimpleArray();
|
|
~CSimpleArray();
|
|
|
|
BOOL Add(const T& t);
|
|
int Find(const T& t) const;
|
|
T* GetData() const;
|
|
int GetSize() const;
|
|
BOOL Remove(const T& t);
|
|
void RemoveAll();
|
|
BOOL RemoveAt(int nIndex);
|
|
|
|
BOOL SetAtIndex(
|
|
int nIndex,
|
|
const T& t);
|
|
|
|
T& operator[](int nindex);
|
|
CSimpleArray<T> & operator=(const CSimpleArray<T>& src);
|
|
};
|
|
|
|
void test_CSimpleArray() {
|
|
int x = source<int>();
|
|
{
|
|
CSimpleArray<int> a;
|
|
a.Add(x);
|
|
sink(a[0]); // $ ir
|
|
a.Add(0);
|
|
sink(a[0]); // $ ir
|
|
|
|
CSimpleArray<int> a2;
|
|
sink(a2[0]);
|
|
a2 = a;
|
|
sink(a2[0]); // $ ir
|
|
}
|
|
{
|
|
CSimpleArray<int> a;
|
|
a.Add(x);
|
|
sink(a.GetData()); // $ ir
|
|
|
|
CSimpleArray<int> a2;
|
|
int pos = a2.Find(x);
|
|
sink(a2[pos]); // $ MISSING: ir
|
|
}
|
|
}
|
|
|
|
template <class TKey, class TVal>
|
|
struct CSimpleMap {
|
|
CSimpleMap();
|
|
~CSimpleMap();
|
|
|
|
BOOL Add(const TKey& key, const TVal& val);
|
|
int FindKey(const TKey& key) const;
|
|
int FindVal(const TVal& val) const;
|
|
TKey& GetKeyAt(int nIndex) const;
|
|
int GetSize() const;
|
|
TVal& GetValueAt(int nIndex) const;
|
|
TVal Lookup(const TKey& key) const;
|
|
BOOL Remove(const TKey& key);
|
|
void RemoveAll();
|
|
BOOL RemoveAt(int nIndex);
|
|
TKey ReverseLookup(const TVal& val) const;
|
|
BOOL SetAt(const TKey& key, const TVal& val);
|
|
BOOL SetAtIndex(int nIndex, const TKey& key, const TVal& val);
|
|
};
|
|
|
|
void test_CSimpleMap() {
|
|
wchar_t* x = source<wchar_t*>();
|
|
{
|
|
CSimpleMap<char*, wchar_t*> a;
|
|
a.Add("hello", x);
|
|
sink(a.Lookup("hello")); // $ ir
|
|
}
|
|
{
|
|
CSimpleMap<char*, wchar_t*> a;
|
|
auto pos = a.FindKey("hello");
|
|
sink(a.GetValueAt(pos)); // clean
|
|
}
|
|
{
|
|
CSimpleMap<char*, wchar_t*> a;
|
|
auto pos = a.FindVal(x);
|
|
sink(a.GetValueAt(pos)); // $ MISSING: ir
|
|
}
|
|
{
|
|
CSimpleMap<char*, wchar_t*> a;
|
|
auto key = a.ReverseLookup(x);
|
|
sink(key);
|
|
sink(a.Lookup(key)); // $ MISSING: ir
|
|
}
|
|
{
|
|
CSimpleMap<char*, wchar_t*> a;
|
|
a.SetAt("hello", x);
|
|
sink(a.Lookup("hello")); // $ ir
|
|
}
|
|
{
|
|
CSimpleMap<char*, wchar_t*> a;
|
|
a.SetAtIndex(0, "hello", x);
|
|
sink(a.Lookup("hello")); // $ ir
|
|
}
|
|
}
|
|
|
|
struct CUrl {
|
|
CUrl& operator= (const CUrl& urlThat) throw();
|
|
CUrl() throw();
|
|
CUrl(const CUrl& urlThat) throw();
|
|
~CUrl() throw();
|
|
|
|
inline BOOL Canonicalize(DWORD dwFlags) throw();
|
|
inline void Clear() throw();
|
|
|
|
BOOL CrackUrl(LPCTSTR lpszUrl, DWORD dwFlags) throw();
|
|
inline BOOL CreateUrl(LPTSTR lpszUrl, DWORD* pdwMaxLength, DWORD dwFlags) const throw();
|
|
|
|
inline LPCTSTR GetExtraInfo() const throw();
|
|
inline DWORD GetExtraInfoLength() const throw();
|
|
inline LPCTSTR GetHostName() const throw();
|
|
inline DWORD GetHostNameLength() const throw();
|
|
inline LPCTSTR GetPassword() const throw();
|
|
inline DWORD GetPasswordLength() const throw();
|
|
inline ATL_URL_PORT GetPortNumber() const throw();
|
|
inline ATL_URL_SCHEME GetScheme() const throw();
|
|
inline LPCTSTR GetSchemeName() const throw();
|
|
inline DWORD GetSchemeNameLength() const throw();
|
|
inline DWORD GetUrlLength() const throw();
|
|
inline LPCTSTR GetUrlPath() const throw();
|
|
inline DWORD GetUrlPathLength() const throw();
|
|
inline LPCTSTR GetUserName() const throw();
|
|
inline DWORD GetUserNameLength() const throw();
|
|
inline BOOL SetExtraInfo(LPCTSTR lpszInfo) throw();
|
|
inline BOOL SetHostName(LPCTSTR lpszHost) throw();
|
|
inline BOOL SetPassword(LPCTSTR lpszPass) throw();
|
|
inline BOOL SetPortNumber(ATL_URL_PORT nPrt) throw();
|
|
inline BOOL SetScheme(ATL_URL_SCHEME nScheme) throw();
|
|
inline BOOL SetSchemeName(LPCTSTR lpszSchm) throw();
|
|
inline BOOL SetUrlPath(LPCTSTR lpszPath) throw();
|
|
inline BOOL SetUserName(LPCTSTR lpszUser) throw();
|
|
};
|
|
|
|
void test_CUrl() {
|
|
char* x = indirect_source<char>();
|
|
CUrl url;
|
|
url.CrackUrl(x, 0);
|
|
sink(url); // $ ir
|
|
sink(url.GetExtraInfo()); // $ ir
|
|
sink(url.GetHostName()); // $ ir
|
|
sink(url.GetPassword()); // $ ir
|
|
sink(url.GetSchemeName()); // $ ir
|
|
sink(url.GetUrlPath()); // $ ir
|
|
sink(url.GetUserName()); // $ ir
|
|
|
|
{
|
|
CUrl url2;
|
|
DWORD len;
|
|
char buffer[1024];
|
|
url2.CrackUrl(x, 0);
|
|
url2.CreateUrl(buffer, &len, 0);
|
|
sink(buffer); // $ ast ir
|
|
}
|
|
{
|
|
CUrl url2;
|
|
url2.SetExtraInfo(x);
|
|
sink(url2); // $ ir
|
|
}
|
|
{
|
|
CUrl url2;
|
|
url2.SetHostName(x);
|
|
sink(url2); // $ ir
|
|
}
|
|
{
|
|
CUrl url2;
|
|
url2.SetPassword(x);
|
|
sink(url2); // $ ir
|
|
}
|
|
{
|
|
CUrl url2;
|
|
url2.SetSchemeName(x);
|
|
sink(url2); // $ ir
|
|
}
|
|
{
|
|
CUrl url2;
|
|
url2.SetUrlPath(x);
|
|
sink(url2); // $ ir
|
|
}
|
|
{
|
|
CUrl url2;
|
|
url2.SetUserName(x);
|
|
sink(url2); // $ ir
|
|
}
|
|
}
|
|
|
|
struct IAtlStringMgr {}; // simplified
|
|
|
|
using XCHAR = char;
|
|
using YCHAR = wchar_t;
|
|
|
|
template <typename BaseType>
|
|
struct CSimpleStringT {
|
|
using PCXSTR = const BaseType*; // simplified
|
|
using PXSTR = BaseType*; // simplified
|
|
|
|
CSimpleStringT() throw();
|
|
CSimpleStringT(const XCHAR* pchSrc, int nLength, IAtlStringMgr* pStringMgr);
|
|
CSimpleStringT(PCXSTR pszSrc, IAtlStringMgr* pStringMgr);
|
|
CSimpleStringT(const CSimpleStringT& strSrc);
|
|
|
|
~CSimpleStringT() throw();
|
|
|
|
void Append(const CSimpleStringT& strSrc);
|
|
void Append(PCXSTR pszSrc, int nLength);
|
|
void Append(PCXSTR pszSrc);
|
|
|
|
void AppendChar(XCHAR ch);
|
|
|
|
static void CopyChars(XCHAR* pchDest, const XCHAR* pchSrc, int nChars) throw();
|
|
static void CopyChars(XCHAR* pchDest, size_t nDestLen, const XCHAR* pchSrc, int nChars) throw();
|
|
static void CopyCharsOverlapped(XCHAR* pchDest, const XCHAR* pchSrc, int nChars) throw();
|
|
|
|
XCHAR GetAt(int iChar) const;
|
|
PXSTR GetBuffer(int nMinBufferLength);
|
|
PXSTR GetBuffer();
|
|
PXSTR GetBufferSetLength(int nLength);
|
|
|
|
PCXSTR GetString() const throw();
|
|
PXSTR LockBuffer();
|
|
void SetAt(int iChar, XCHAR ch);
|
|
void SetString(PCXSTR pszSrc, int nLength);
|
|
void SetString(PCXSTR pszSrc);
|
|
operator PCXSTR() const throw();
|
|
XCHAR operator[](int iChar) const;
|
|
|
|
CSimpleStringT& operator+=(PCXSTR pszSrc);
|
|
CSimpleStringT& operator+=(const CSimpleStringT& strSrc);
|
|
CSimpleStringT& operator+=(char ch);
|
|
CSimpleStringT& operator+=(unsigned char ch);
|
|
CSimpleStringT& operator+=(wchar_t ch);
|
|
|
|
CSimpleStringT& operator=(PCXSTR pszSrc);
|
|
CSimpleStringT& operator=(const CSimpleStringT& strSrc);
|
|
};
|
|
|
|
void test_CSimpleStringT() {
|
|
char* x = indirect_source<char>();
|
|
|
|
CSimpleStringT<char> s1(x, 10, nullptr);
|
|
sink(s1.GetString()); // $ ir
|
|
|
|
CSimpleStringT<char> s2(x, nullptr);
|
|
sink(s2.GetString()); // $ ir
|
|
|
|
CSimpleStringT<char> s3(s2);
|
|
sink(s3.GetString()); // $ ir
|
|
|
|
CSimpleStringT<char> s4;
|
|
s4.Append(indirect_source<char>());
|
|
sink(s4.GetString()); // $ ir
|
|
|
|
CSimpleStringT<char> s5;
|
|
s5.Append(s4);
|
|
sink(s5.GetString()); // $ ir
|
|
|
|
CSimpleStringT<char> s6;
|
|
s6.Append(indirect_source<char>(), 42);
|
|
sink(s6.GetString()); // $ ir
|
|
|
|
char buffer1[128];
|
|
CSimpleStringT<char>::CopyChars(buffer1, x, 10);
|
|
sink(buffer1); // $ ast ir
|
|
|
|
char buffer2[128];
|
|
CSimpleStringT<char>::CopyChars(buffer2, 128, x, 10);
|
|
sink(buffer2); // $ ast ir
|
|
|
|
char buffer3[128];
|
|
CSimpleStringT<char>::CopyCharsOverlapped(buffer3, x, 10);
|
|
sink(buffer3); // $ ast ir
|
|
|
|
sink(s4.GetAt(0)); // $ ir
|
|
sink(s4.GetBuffer(10)); // $ ir
|
|
sink(s4.GetBuffer()); // $ ir
|
|
sink(s4.GetBufferSetLength(10)); // $ ir
|
|
|
|
sink(s4.LockBuffer()); // $ ir
|
|
|
|
CSimpleStringT<char> s7;
|
|
s7.SetAt(0, source<char>());
|
|
sink(s7.GetAt(0)); // $ ir
|
|
|
|
CSimpleStringT<char> s8;
|
|
s8.SetString(indirect_source<char>());
|
|
sink(s8.GetAt(0)); // $ ir
|
|
|
|
CSimpleStringT<char> s9;
|
|
s9.SetString(indirect_source<char>(), 1024);
|
|
sink(s9.GetAt(0)); // $ ir
|
|
|
|
sink(static_cast<CSimpleStringT<char>::PCXSTR>(s1)); // $ ir
|
|
|
|
sink(s1[0]); // $ ir
|
|
}
|
|
|
|
template<typename T>
|
|
struct MakeOther {};
|
|
|
|
template<>
|
|
struct MakeOther<char> {
|
|
using other_t = wchar_t;
|
|
};
|
|
|
|
template<>
|
|
struct MakeOther<wchar_t> {
|
|
using other_t = char;
|
|
};
|
|
|
|
template<typename BaseType>
|
|
struct CStringT : public CSimpleStringT<BaseType> {
|
|
using XCHAR = BaseType; // simplified
|
|
using YCHAR = typename MakeOther<BaseType>::other_t; // simplified
|
|
using PCXSTR = typename CSimpleStringT<BaseType>::PCXSTR;
|
|
using PXSTR = typename CSimpleStringT<BaseType>::PXSTR;
|
|
CStringT() throw();
|
|
|
|
CStringT(IAtlStringMgr* pStringMgr) throw();
|
|
CStringT(const VARIANT& varSrc);
|
|
CStringT(const VARIANT& varSrc, IAtlStringMgr* pStringMgr);
|
|
CStringT(const CStringT& strSrc);
|
|
CStringT(const CSimpleStringT<BaseType>& strSrc);
|
|
CStringT(const XCHAR* pszSrc);
|
|
CStringT(const YCHAR* pszSrc);
|
|
CStringT(LPCSTR pszSrc, IAtlStringMgr* pStringMgr);
|
|
CStringT(LPCWSTR pszSrc, IAtlStringMgr* pStringMgr);
|
|
CStringT(const unsigned char* pszSrc);
|
|
CStringT(char* pszSrc);
|
|
CStringT(unsigned char* pszSrc);
|
|
CStringT(wchar_t* pszSrc);
|
|
CStringT(const unsigned char* pszSrc, IAtlStringMgr* pStringMgr);
|
|
CStringT(char ch, int nLength = 1);
|
|
CStringT(wchar_t ch, int nLength = 1);
|
|
CStringT(const XCHAR* pch, int nLength);
|
|
CStringT(const YCHAR* pch, int nLength);
|
|
CStringT(const XCHAR* pch, int nLength, IAtlStringMgr* pStringMgr);
|
|
CStringT(const YCHAR* pch, int nLength, IAtlStringMgr* pStringMgr);
|
|
|
|
operator CSimpleStringT<BaseType> &();
|
|
|
|
~CStringT() throw();
|
|
|
|
BSTR AllocSysString() const;
|
|
void AppendFormat(PCXSTR pszFormat, ...);
|
|
void AppendFormat(UINT nFormatID, ...);
|
|
int Delete(int iIndex, int nCount = 1);
|
|
int Find(PCXSTR pszSub, int iStart=0) const throw();
|
|
int Find(XCHAR ch, int iStart=0) const throw();
|
|
int FindOneOf(PCXSTR pszCharSet) const throw();
|
|
void Format(UINT nFormatID, ...);
|
|
void Format(PCXSTR pszFormat, ...);
|
|
BOOL GetEnvironmentVariable(PCXSTR pszVar);
|
|
int Insert(int iIndex, PCXSTR psz);
|
|
int Insert(int iIndex, XCHAR ch);
|
|
CStringT Left(int nCount) const;
|
|
BOOL LoadString(HINSTANCE hInstance, UINT nID, WORD wLanguageID);
|
|
BOOL LoadString(HINSTANCE hInstance, UINT nID);
|
|
BOOL LoadString(UINT nID);
|
|
CStringT& MakeLower();
|
|
CStringT& MakeReverse();
|
|
CStringT& MakeUpper();
|
|
CStringT Mid(int iFirst, int nCount) const;
|
|
CStringT Mid(int iFirst) const;
|
|
int Replace(PCXSTR pszOld, PCXSTR pszNew);
|
|
int Replace(XCHAR chOld, XCHAR chNew);
|
|
CStringT Right(int nCount) const;
|
|
BSTR SetSysString(BSTR* pbstr) const;
|
|
CStringT SpanExcluding(PCXSTR pszCharSet) const;
|
|
CStringT SpanIncluding(PCXSTR pszCharSet) const;
|
|
CStringT Tokenize(PCXSTR pszTokens, int& iStart) const;
|
|
CStringT& Trim(XCHAR chTarget);
|
|
CStringT& Trim(PCXSTR pszTargets);
|
|
CStringT& Trim();
|
|
CStringT& TrimLeft(XCHAR chTarget);
|
|
CStringT& TrimLeft(PCXSTR pszTargets);
|
|
CStringT& TrimLeft();
|
|
CStringT& TrimRight(XCHAR chTarget);
|
|
CStringT& TrimRight(PCXSTR pszTargets);
|
|
CStringT& TrimRight();
|
|
};
|
|
|
|
void test_CStringT() {
|
|
VARIANT v = source<VARIANT>();
|
|
|
|
CStringT<char> s1(v);
|
|
sink(s1.GetString()); // $ ir
|
|
|
|
CStringT<char> s2(v, nullptr);
|
|
sink(s2.GetString()); // $ ir
|
|
|
|
CStringT<char> s3(s2);
|
|
sink(s3.GetString()); // $ ir
|
|
|
|
char* x = indirect_source<char>();
|
|
CStringT<char> s4(x);
|
|
sink(s4.GetString()); // $ ir
|
|
|
|
wchar_t* y = indirect_source<wchar_t>();
|
|
CStringT<wchar_t> s5(y);
|
|
sink(s5.GetString()); // $ ir
|
|
|
|
CStringT<char> s6(x, nullptr);
|
|
sink(s6.GetString()); // $ ir
|
|
|
|
CStringT<wchar_t> s7(y, nullptr);
|
|
sink(s7.GetString()); // $ ir
|
|
|
|
unsigned char* ucs = indirect_source<unsigned char>();
|
|
CStringT<char> s8(ucs);
|
|
sink(s8.GetString()); // $ ir
|
|
|
|
char c = source<char>();
|
|
CStringT<char> s9(c);
|
|
sink(s9.GetString()); // $ ir
|
|
|
|
wchar_t wc = source<wchar_t>();
|
|
CStringT<wchar_t> s10(wc);
|
|
sink(s10.GetString()); // $ ir
|
|
|
|
sink(static_cast<CSimpleStringT<char>&>(s1)); // $ ast ir
|
|
|
|
auto bstr = s1.AllocSysString();
|
|
sink(bstr); // $ ir
|
|
|
|
CStringT<char> s11;
|
|
s11.AppendFormat("%d", source<int>());
|
|
sink(s11.GetString()); // $ ir
|
|
|
|
CStringT<char> s12;
|
|
s12.AppendFormat(indirect_source<char>());
|
|
sink(s12.GetString()); // $ ir
|
|
|
|
CStringT<char> s13;
|
|
s13.AppendFormat(source<UINT>());
|
|
sink(s13.GetString()); // $ ir
|
|
|
|
CStringT<char> s14;
|
|
s14.AppendFormat(42, source<char>());
|
|
sink(s14.GetString()); // $ ir
|
|
|
|
CStringT<char> s15;
|
|
s15.AppendFormat(42, indirect_source<char>());
|
|
sink(s15.GetString()); // $ ir
|
|
|
|
CStringT<char> s16;
|
|
s16.AppendFormat("%s", indirect_source<char>());
|
|
|
|
CStringT<char> s17;
|
|
s17.Insert(0, x);
|
|
sink(s17.GetString()); // $ ir
|
|
|
|
CStringT<char> s18;
|
|
s18.Insert(0, source<char>());
|
|
sink(s18.GetString()); // $ ir
|
|
|
|
sink(s1.Left(42).GetString()); // $ ir
|
|
|
|
CStringT<char> s20;
|
|
s20.LoadString(source<UINT>());
|
|
sink(s20.GetString()); // $ ir
|
|
|
|
sink(s1.MakeLower().GetString()); // $ ir
|
|
sink(s1.MakeReverse().GetString()); // $ ir
|
|
sink(s1.MakeUpper().GetString()); // $ ir
|
|
sink(s1.Mid(0, 42).GetString()); // $ ir
|
|
|
|
CStringT<char> s21;
|
|
s21.Replace("abc", x);
|
|
sink(s21.GetString()); // $ ir
|
|
|
|
CStringT<char> s22;
|
|
s22.Replace('\n', source<char>());
|
|
sink(s22.GetString()); // $ ir
|
|
|
|
sink(s2.Right(42).GetString()); // $ ir
|
|
|
|
BSTR bstr2;
|
|
s1.SetSysString(&bstr2);
|
|
sink(bstr2); // $ ast ir
|
|
|
|
sink(s1.SpanExcluding("abc").GetString()); // $ ir
|
|
sink(s1.SpanIncluding("abc").GetString()); // $ ir
|
|
|
|
int start = 0;
|
|
sink(s1.Tokenize("abc", start).GetString()); // $ ir
|
|
|
|
sink(s1.Trim('a').GetString()); // $ ir
|
|
sink(s1.Trim("abc").GetString()); // $ ir
|
|
sink(s1.Trim().GetString()); // $ ir
|
|
sink(s1.TrimLeft('a').GetString()); // $ ir
|
|
sink(s1.TrimLeft("abc").GetString()); // $ ir
|
|
sink(s1.TrimLeft().GetString()); // $ ir
|
|
sink(s1.TrimRight('a').GetString()); // $ ir
|
|
sink(s1.TrimRight("abc").GetString()); // $ ir
|
|
sink(s1.TrimRight().GetString()); // $ ir
|
|
}
|
|
|
|
struct CStringData {
|
|
void* data() throw();
|
|
};
|
|
|
|
void test_CStringData() {
|
|
CStringData d = source<CStringData>();
|
|
sink(d.data()); // $ ir
|
|
}
|
|
|
|
template<typename TCharType>
|
|
struct CStrBufT {
|
|
typedef CSimpleStringT<TCharType> StringType;
|
|
|
|
using PCXSTR = typename StringType::PCXSTR;
|
|
using PXSTR = typename StringType::PXSTR;
|
|
|
|
CStrBufT(StringType& str, int nMinLength, DWORD dwFlags);
|
|
CStrBufT(StringType& str);
|
|
|
|
operator PCXSTR() const throw();
|
|
operator PXSTR() throw();
|
|
};
|
|
|
|
void test_CStrBufT() {
|
|
CStringT<char> s = source<CStringT<char>>();
|
|
CStrBufT<char> b(s, 42, 0);
|
|
sink(static_cast<CStrBufT<char>::PCXSTR>(b)); // $ ir
|
|
sink(static_cast<CStrBufT<char>::PXSTR>(b)); // $ ir
|
|
}
|
|
}
|
|
|
|
namespace Microsoft {
|
|
namespace WRL {
|
|
template <typename T>
|
|
class ComPtr;
|
|
|
|
struct GUID;
|
|
|
|
typedef GUID IID;
|
|
|
|
typedef IID *REFIID;
|
|
|
|
class IUnknown;
|
|
|
|
class WeakRef;
|
|
|
|
namespace Details {
|
|
template <typename T>
|
|
class ComPtrRef {
|
|
public:
|
|
using InterfaceType = T;
|
|
|
|
ComPtrRef(T*);
|
|
|
|
InterfaceType* const * GetAddressOf() const;
|
|
InterfaceType** ReleaseAndGetAddressOf();
|
|
|
|
operator InterfaceType**();
|
|
operator T*();
|
|
operator void**() const;
|
|
InterfaceType* operator *();
|
|
};
|
|
}
|
|
|
|
template <typename T>
|
|
class ComPtr
|
|
{
|
|
public:
|
|
using InterfaceType = T;
|
|
|
|
ComPtr();
|
|
ComPtr(const ComPtr &);
|
|
ComPtr(ComPtr &&);
|
|
|
|
template <typename U>
|
|
ComPtr(U *);
|
|
|
|
~ComPtr();
|
|
|
|
template <typename U>
|
|
HRESULT As(ComPtr<U> *p) const;
|
|
|
|
HRESULT AsWeak(WeakRef *);
|
|
|
|
void Attach(InterfaceType *);
|
|
|
|
HRESULT CopyTo(InterfaceType **);
|
|
|
|
HRESULT CopyTo(REFIID, void **) const;
|
|
|
|
template <typename U>
|
|
HRESULT CopyTo(U **) const;
|
|
|
|
T *Detach();
|
|
|
|
T *Get() const;
|
|
|
|
T *const *GetAddressOf() const;
|
|
T **GetAddressOf();
|
|
|
|
T **ReleaseAndGetAddressOf();
|
|
|
|
unsigned long Reset();
|
|
|
|
void Swap(ComPtr &&r);
|
|
|
|
void Swap(ComPtr &r);
|
|
|
|
Details::ComPtrRef<ComPtr<T>> operator&();
|
|
const Details::ComPtrRef<const ComPtr<T>> operator&() const;
|
|
|
|
InterfaceType* operator->() const; // return type simplified from Microsoft::WRL::Details::RemoveIUnknown<InterfaceType>*
|
|
|
|
ComPtr& operator=(T *);
|
|
template <typename U>
|
|
ComPtr& operator=(U *);
|
|
ComPtr& operator=(const ComPtr &);
|
|
template<class U>
|
|
ComPtr& operator=(const ComPtr<U>&);
|
|
ComPtr& operator=(ComPtr &&);
|
|
template<class U>
|
|
ComPtr& operator=(ComPtr<U>&&);
|
|
};
|
|
|
|
}
|
|
}
|
|
|
|
namespace std {
|
|
template<class T> T&& move(T& t) noexcept; // simplified signature
|
|
}
|
|
|
|
void test_constructor()
|
|
{
|
|
Microsoft::WRL::ComPtr<int> p0;
|
|
sink(*p0.Get()); // clean
|
|
|
|
int x = source<int>();
|
|
Microsoft::WRL::ComPtr<int> p1(new int(x));
|
|
sink(*p1.Get()); // $ ir MISSING: ast
|
|
sink(*p1.Detach()); // $ ir MISSING: ast
|
|
|
|
Microsoft::WRL::ComPtr<int> p2(p1);
|
|
sink(*p2.Get()); // $ ir MISSING: ast
|
|
|
|
Microsoft::WRL::ComPtr<int> p3(std::move(p1));
|
|
sink(*p3.Get()); // $ ir MISSING: ast
|
|
}
|
|
|
|
void test_As()
|
|
{
|
|
int x = source<int>();
|
|
Microsoft::WRL::ComPtr<int> p1(new int(x));
|
|
Microsoft::WRL::ComPtr<int>* p2;
|
|
p1.As(p2);
|
|
sink(*p2->Get()); // $ ir MISSING: ast
|
|
}
|
|
|
|
void test_CopyTo()
|
|
{
|
|
int x = source<int>();
|
|
Microsoft::WRL::ComPtr<int> p1(new int(x));
|
|
int *raw = nullptr;
|
|
p1.CopyTo(&raw);
|
|
sink(*raw); // $ ir MISSING: ast
|
|
|
|
Microsoft::WRL::ComPtr<int> p2;
|
|
p1.CopyTo(nullptr, (void**)&raw);
|
|
sink(*raw); // $ ir MISSING: ast
|
|
|
|
Microsoft::WRL::ComPtr<int> p3(new int(x));
|
|
|
|
int* raw2 = nullptr;
|
|
p3.CopyTo<int>(&raw2);
|
|
sink(*raw2); // $ ir MISSING: ast
|
|
}
|
|
|
|
void test_Swap()
|
|
{
|
|
int x = source<int>();
|
|
Microsoft::WRL::ComPtr<int> p1(new int(x));
|
|
Microsoft::WRL::ComPtr<int> p2;
|
|
p1.Swap(p2);
|
|
sink(*p2.Get()); // $ ir MISSING: ast
|
|
sink(*p1.Get()); // $ SPURIOUS: ir
|
|
}
|
|
|
|
void test_GetAddressOf()
|
|
{
|
|
int x = source<int>();
|
|
Microsoft::WRL::ComPtr<int> p1(new int(x));
|
|
sink(**p1.GetAddressOf()); // $ ir MISSING: ast
|
|
|
|
const Microsoft::WRL::ComPtr<int> p2(new int(x));
|
|
sink(**p2.GetAddressOf()); // $ ir MISSING: ast
|
|
|
|
Microsoft::WRL::ComPtr<int> p3(new int(x));
|
|
int **pp = p3.ReleaseAndGetAddressOf();
|
|
sink(**pp); // $ ir MISSING: ast
|
|
}
|
|
|
|
struct S {
|
|
int x;
|
|
};
|
|
|
|
void test_address_of_deref_operators() {
|
|
int x = source<int>();
|
|
Microsoft::WRL::ComPtr<int> p1(new int(x));
|
|
Microsoft::WRL::Details::ComPtrRef<Microsoft::WRL::ComPtr<int>> pp = &p1;
|
|
Microsoft::WRL::ComPtr<int>* qq = *pp;
|
|
sink(*qq->Get()); // $ MISSING: ast,ir
|
|
|
|
const Microsoft::WRL::ComPtr<int> p2(new int(x));
|
|
Microsoft::WRL::Details::ComPtrRef<const Microsoft::WRL::ComPtr<int>> pp2 = &p2;
|
|
const Microsoft::WRL::ComPtr<int>* qq2 = *pp2;
|
|
sink(*qq2->Get()); // $ MISSING: ast,ir
|
|
|
|
S s;
|
|
s.x = source<int>();
|
|
Microsoft::WRL::ComPtr<S> p3(&s);
|
|
sink(p3->x); // $ MISSING: ast,ir
|
|
}
|
|
|
|
void test_assignments() {
|
|
Microsoft::WRL::ComPtr<int> p1;
|
|
p1 = new int(source<int>());
|
|
sink(*p1.Get()); // $ MISSING: ast,ir
|
|
|
|
Microsoft::WRL::ComPtr<int> p2;
|
|
p2 = new long(source<long>());
|
|
sink(*p2.Get()); // $ MISSING: ast,ir
|
|
|
|
Microsoft::WRL::ComPtr<int> p3;
|
|
p3 = p1;
|
|
sink(*p3.Get()); // $ MISSING: ast,ir
|
|
|
|
Microsoft::WRL::ComPtr<long> p4;
|
|
p4 = p1;
|
|
sink(*p4.Get()); // $ MISSING: ast,ir
|
|
|
|
Microsoft::WRL::ComPtr<int> p5;
|
|
p5 = std::move(p1);
|
|
sink(*p5.Get()); // $ MISSING: ast,ir
|
|
|
|
Microsoft::WRL::ComPtr<long> p6;
|
|
p6 = std::move(p1);
|
|
sink(*p6.Get()); // $ MISSING: ast,ir
|
|
} |