2
Copyright (c) 2008, 2009 Jussi Pakkanen
4
����������� ��������� ��������������� � ������������� ��� � ���� ��������� ����,
5
��� � � �������� �����, � ����������� ��� ���, ��� ���������� ��������� �������:
7
* ��� ��������� ��������������� ��������� ���� ������ ���������� ���������
8
���� ����������� �� ��������� �����, ���� ������ ������� � �����������
10
* ��� ��������� ��������������� ��������� ���� � ������������ �/��� �
11
������ ����������, ������������ ��� ���������������, ������ �����������
12
��������� ���� ���������� �� ��������� �����, ���� ������ ������� �
13
����������� ����� �� ��������.
14
* �� �������� Cognitive Technologies, �� ����� �� ����������� �� �����
15
���� ������������ � �������� �������� ��������� �/��� �����������
16
���������, ���������� �� ���� ��, ��� ���������������� �����������
19
��� ��������� ������������� ����������� ��������� ���� �/��� ������� ������ "���
20
��� ����" ��� ������-���� ���� ��������, ���������� ���� ��� ���������������,
21
������� �������� ������������ �������� � ����������� ��� ���������� ����, �� ��
22
������������� ���. �� �������� ��������� ���� � �� ���� ������ ����, �������
23
����� �������� �/��� �������� �������������� ���������, �� � ���� ������ ��
24
��Ѩ� ���������������, ������� ����� �����, ���������, ����������� ���
25
������������� ������, ��������� � �������������� ��� ���������� ����������
26
������������� ������������� ��������� (������� ������ ������, ��� ������,
27
������� ���������, ��� ������ �/��� ������ �������, ���������� ��-�� ��������
28
������� ��� �/��� ������ ��������� �������� ��������� � ������� �����������,
29
�� �� ������������� ����� ��������), �� �� ������������� ���, ���� ���� �����
30
�������� ��� ������ ���� ���� �������� � ����������� ����� ������� � ������.
32
Redistribution and use in source and binary forms, with or without modification,
33
are permitted provided that the following conditions are met:
35
* Redistributions of source code must retain the above copyright notice,
36
this list of conditions and the following disclaimer.
37
* Redistributions in binary form must reproduce the above copyright notice,
38
this list of conditions and the following disclaimer in the documentation
39
and/or other materials provided with the distribution.
40
* Neither the name of the Cognitive Technologies nor the names of its
41
contributors may be used to endorse or promote products derived from this
42
software without specific prior written permission.
44
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
45
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
46
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
47
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
48
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
49
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
50
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
51
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
52
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
53
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
57
#include <sys/types.h>
66
/* Minimal implementations of win32-functionality.
67
* Eventually these should be rewritten in standard POSIX.
69
* At the end of the file are some helper functions, which should be used
75
#include <sys/types.h>
83
#if defined(__APPLE__) && defined(__MACH__)
84
#include <malloc/malloc.h>
85
#define malloc_usable_size(a) malloc_size(a)
87
#elif defined(__FreeBSD__)
88
#include <malloc_np.h>
95
#include "compat_defs.h"
97
WINDUMMY_FUNC(int) HFILE_ERROR;
99
int LoadString(HINSTANCE hInstance, UINT uID, LPTSTR lpBuffer, int nBufferMax) {
103
int CreateDirectory(const char *dir, void *dummy) {
104
if(!mkdir(dir,0755)) return TRUE;
108
DWORD GetTempPath(DWORD nBufferLength, LPTSTR lpBuffer) {
109
strcpy(lpBuffer, "/tmp");
110
return strlen(lpBuffer);
113
int RemoveDirectory(const char *d) {
117
void* GlobalAlloc(UINT uFlags, int dwBytes) {
118
if(uFlags & GMEM_ZEROINIT)
119
return calloc(dwBytes, 1);
120
return malloc(dwBytes);
123
HGLOBAL GlobalFree(void *f) {
128
void* GlobalReAlloc(void* hMem, int dwBytes, UINT uFlags) {
129
return realloc(hMem, dwBytes); // Should init to zero on uFlags & GMEM_ZEROINIT.
132
int GetTempFileName(LPCTSTR lpPathName, LPCTSTR lpPrefixString,
133
UINT uUnique, LPTSTR lpTempFileName) {
142
DWORD GetModuleFileName(HMODULE hModule, LPTSTR lpFilename, DWORD nSize) {
143
lpFilename[0] = '.'; /* Currently all modules must be in the directory pumatest was run in. */
144
lpFilename[1] = '\0';
148
BOOL CloseHandle(HANDLE hObject) {
152
HANDLE CreateFile(LPCTSTR lpFileName, DWORD dwDesiredAccess,
153
DWORD dwShareMode, void* lpSecurityAttributes,
154
DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile) {
158
HWND FindWindow(LPCTSTR lpClassName, LPCTSTR lpWindowName) {
162
UINT RegisterWindowMessage(LPCTSTR lpString) {
166
int _findclose(long handle);
167
long _findfirst(const char *filespec, struct _finddata_t *fileinfo);
168
int _findnext(long handle, struct _finddata_t *fileinfo);
169
long _tell(int handle) {
170
return lseek(handle, 0, SEEK_CUR);
173
BOOL GetComputerName(LPTSTR lpBuffer, long unsigned int *lpnSize) {
174
strncpy(lpBuffer, "CompName", *lpnSize);
175
*lpnSize = strlen(lpBuffer);
179
LONG RegOpenKeyEx(HKEY hKey, LPCTSTR lpSubKey, DWORD ulOptions,
180
REGSAM samDesired, PHKEY phkResult) {
184
LONG RegQueryValueEx(HKEY hKey, LPCTSTR lpValueName,
185
LPDWORD lpReserved, LPDWORD lpType, LPBYTE lpData,
190
BOOL GetClientRect(HWND hWnd, LPRECT lpRect) {
194
BOOL WritePrivateProfileString(LPCTSTR lpAppName,
195
LPCTSTR lpKeyName, LPCTSTR lpString, LPCTSTR lpFileName) {
199
DWORD GetPrivateProfileString(LPCTSTR lpAppName, LPCTSTR lpKeyName,
200
LPCTSTR lpDefault, LPTSTR lpReturnedString, DWORD nSize, LPCTSTR lpFileName) {
204
UINT GetPrivateProfileInt(LPCTSTR lpAppName,
205
LPCTSTR lpKeyName, INT nDefault, LPCTSTR lpFileName) {
209
int WideCharToMultiByte(UINT CodePage, DWORD dwFlags, const wchar_t *lpWideCharStr,
210
int cchWideChar, LPSTR lpMultiByteStr, int cbMultiByte,
211
LPCSTR lpDefaultChar, LPBOOL lpUsedDefaultChar) {
214
BOOL ShowWindow(HWND hWnd, int nCmdShow) {
218
long _filelength(int fd) {
220
if(fstat(fd, &foo) != 0) {
226
long filelength(int fd) {
227
return _filelength(fd);
231
long _msize(void *memblock) {
232
return malloc_usable_size(memblock);
235
/* All uses in Cuneiform just check if the file exists. Ignoring all other
238
int _access(const char *filename, int mode) {
241
return stat(filename, &foo);
244
BOOL SetWindowText(HWND hWnd,LPCTSTR lpString) {
248
int ReleaseDC(HWND hWnd, HDC hDC) {
252
BOOL IsIconic(HWND hWnd) {
256
HDC GetDC(HWND hWnd) {
260
BOOL EndPaint(HWND hWnd, ...) {
264
HDC BeginPaint(HWND hwnd,...) {
268
LRESULT SendMessage(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) {
272
void strlwr(char *foo) {
273
// FIXME: this is probably actually used somewhere.
278
LPCTSTR lpWindowName,
291
HGDIOBJ SelectObject(HDC hdc, HGDIOBJ hgdiobj) {
295
LPTSTR lstrcat(LPTSTR lpString1, LPTSTR lpString2) {
296
return strcat(lpString1, lpString2);
299
int lstrlen(LPCTSTR lpString) {
300
return strlen(lpString);
303
int lstrcmp(LPCTSTR lpString1, LPCTSTR lpString2) {
304
return strcmp(lpString1, lpString2);
307
LPTSTR lstrcpy(LPTSTR lpString1, LPCTSTR lpString2) {
308
return strcpy(lpString1, lpString2);
311
int wsprintf(LPTSTR lpOut, LPCTSTR lpFmt, ...) {
315
va_start (args, lpFmt);
316
ret = vsprintf(lpOut,lpFmt, args);
323
int lstrcmpi(LPCTSTR lpString1, LPCTSTR lpString2) {
324
return strcasecmp(lpString1, lpString2);
327
BOOL DeleteObject(HGDIOBJ hObject) {
335
int MessageBox(HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType) {
336
fprintf(stderr, "MessageBox %s: %s\n", lpCaption, lpText);
340
int WINAPI GlobalSize(HGLOBAL hMem) {
344
LPVOID GlobalLock(HGLOBAL hMem) {
348
BOOL GlobalUnlock(HGLOBAL hMem) {
352
BOOL IsBadWritePtr(LPVOID lp, int ucb) {
356
void OutputDebugString(LPCTSTR lpOutputString) {
360
BOOL SetRect(LPRECT lprc, int xLeft, int yTop,
361
int xRight, int yBottom) {
363
lprc->right = xRight;
365
lprc->bottom = yBottom;
369
BOOL PtInRect(const RECT *lprc, POINT pt) {
370
if(pt.x >= lprc->left && pt.x < lprc->right
371
&& pt.y >= lprc->top && pt.y < lprc->bottom)
376
/* This is only called from creatertf.cpp. It does not use lprcDst at all so
377
* we do not need to calculate it.
380
BOOL IntersectRect(LPRECT lprcDst, const RECT *lprcSrc1, const RECT *lprcSrc2) {
381
if(lprcSrc1->left > lprcSrc2->right
382
|| lprcSrc1->right < lprcSrc2->left
383
|| lprcSrc1->top > lprcSrc2->bottom
384
|| lprcSrc1->bottom < lprcSrc2->top)
389
BOOL UnionRect(LPRECT lprcDst, const RECT *lprcSrc1, const RECT *lprcSrc2) {
390
if(lprcSrc1->left - lprcSrc1->right == 0 || lprcSrc1->top - lprcSrc1->bottom == 0) {
391
lprcDst->left = lprcSrc2->left;
392
lprcDst->right = lprcSrc2->right;
393
lprcDst->top = lprcSrc2->top;
394
lprcDst->bottom = lprcSrc2->bottom;
397
if(lprcSrc2->left - lprcSrc2->right == 0 || lprcSrc2->top - lprcSrc2->bottom == 0) {
398
lprcDst->left = lprcSrc1->left;
399
lprcDst->right = lprcSrc1->right;
400
lprcDst->top = lprcSrc1->top;
401
lprcDst->bottom = lprcSrc1->bottom;
405
lprcDst->left = lprcSrc1->left < lprcSrc2->left ? lprcSrc1->left : lprcSrc2->left;
406
lprcDst->right = lprcSrc1->right > lprcSrc2->right ? lprcSrc1->right : lprcSrc2->right;
407
lprcDst->top = lprcSrc1->top < lprcSrc2->top ? lprcSrc1->top : lprcSrc2->top;
408
lprcDst->bottom = lprcSrc1->bottom > lprcSrc2->bottom ? lprcSrc1->bottom : lprcSrc2->bottom;
413
HWND GetActiveWindow() {
417
HFONT CreateFont(int nHeight, int nWidth, int nEscapement,
418
int nOrientation, int fnWeight, DWORD fdwItalic, DWORD fdwUnderline,
419
DWORD fdwStrikeOut, DWORD fdwCharSet, DWORD fdwOutputPrecision,
420
DWORD fdwClipPrecision, DWORD fdwQuality, DWORD fdwPitchAndFamily,
425
BOOL GetTextExtentPoint32(HDC hdc, LPCTSTR lpString, int c, LPSIZE lpSize) {
429
BOOL EnumWindows(WNDENUMPROC lpEnumFunc, LPARAM lParam) {
433
int GetWindowText(HWND hWnd, LPTSTR lpString, int nMaxCount) {
437
HMODULE LoadLibrary(LPCTSTR lpFileName) {
438
return dlopen(lpFileName, RTLD_LAZY);
441
BOOL FreeLibrary(HMODULE hModule) {
442
return dlclose(hModule);
445
void* GetProcAddress(HMODULE hModule, LPCSTR lpProcName) {
446
return dlsym(hModule, lpProcName);
449
HGDIOBJ GetStockObject(int fnObject) {
453
BOOL IsWindowVisible(HWND hWnd) {
457
LRESULT DefWindowProc(HWND hWnd, UINT Msg, WPARAM wParam,
462
LONG GetWindowLong(HWND hWnd, int nIndex) {
466
BOOL RegisterClass(const WNDCLASS *lpWndClass) {
470
HMODULE GetModuleHandle(LPCTSTR lpModuleName) {
474
HICON LoadIcon(HINSTANCE hInstance, LPCTSTR lpIconName) {
478
int LoadCursor(HINSTANCE hInstance, LPCTSTR lpCursorName) {
482
BOOL Rectangle(HDC hdc,
483
int nLeftRect, int nTopRect, int nRightRect, int nBottomRect) {
487
/* String to uppercase. */
489
char* _strupr(char*s) {
502
static HMODULE thismod;
505
WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) {
506
thismod = (HMODULE) hinstDLL;
511
mkdtemp(char *tmpl) {
512
static const char charset[] =
513
"=#abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
514
static const unsigned int charset_len = sizeof(charset) - 1;
516
const int len = strlen (tmpl);
517
char* x_tail = tmpl + len - 6;
518
LARGE_INTEGER rand_seed;
519
uint64_t value = rand_seed.QuadPart ^ GetCurrentThreadId();
520
unsigned int cnt = 0;
524
if(memcmp(x_tail, "XXXXXX", 6))
527
QueryPerformanceCounter(&rand_seed);
530
uint64_t val = value;
531
char* x_char = x_tail;
533
*x_char++ = charset[val % charset_len];
536
if (CreateDirectory (tmpl, NULL))
538
if (ERROR_ALREADY_EXISTS != GetLastError())
542
} while (cnt < TMP_MAX);
549
/* General helper functions. */
551
static const char *separator = "/"; /* Yes, on Windows too. */
555
static void get_install_path(char *path) {
556
const int psize = 128;
557
char modulepath[128]; /* MSVC fails when psize is put in these brackets. */
561
GetModuleFileName(thismod, modulepath, psize);
562
winpath_to_internal(modulepath);
563
split_path(modulepath, path, fname, suffix);
568
static void get_install_path(char *path) {
569
strcat(path, INSTALL_DATADIR);
574
/* We try to locate data files in two locations:
576
* 1. At the directory pointed to by environment variable CF_DATADIR
577
* 2. At a platform-dependent install location
579
* Caller's responsibility is to ensure *e1 and *e2 are large enough.
583
static void build_name_estimates(const char *base_name, char *env_name, char *prefix_name) {
584
const char *env_prefix;
585
const char *varname = "CF_DATADIR";
589
prefix_name[0] = '\0';
591
env_prefix = getenv(varname);
593
len = strlen(env_prefix);
595
strcat(env_name, env_prefix);
596
if(strcmp(env_prefix + len-1, separator) != 0) {
597
strcat(env_name, separator);
599
strcat(env_name, base_name);
602
get_install_path(prefix_name);
603
if(strlen(prefix_name) > 0) {
604
strcat(prefix_name, separator);
605
strcat(prefix_name, base_name);
611
open_data_file(const char *basename, int mode) {
616
build_name_estimates(basename, ename, pname);
617
i = open(ename, mode);
620
return open(pname, mode);
625
data_file_exists(const char *basename) {
629
build_name_estimates(basename, ename, pname);
630
if(_access(ename, 0) == 0)
632
return _access(pname, 0);
635
/* Split a file name in three: path, base file name, and extension.
636
* All internal file names use / as path separator, even on Windows.
639
split_path(const char *fname, char *file_path, char *basename, char *ext) {
642
size_t l = strlen(fname);
643
int path_end, base_start, base_end, ext_start;
649
for (i = 0; i < l; i++) {
658
if (last_path == 0) { // File in root.
663
path_end = last_path;
664
base_start = last_path + 1;
667
if (suff > last_path) {
668
ext_start = suff + 1;
671
base_end = ext_start = l;
674
memcpy(file_path, fname, path_end);
675
file_path[path_end] = '\0';
676
memcpy(basename, fname + base_start, base_end - base_start);
677
basename[base_end - base_start] = '\0';
678
memcpy(ext, fname + ext_start, l - ext_start);
679
ext[l - ext_start] = '\0';
684
make_path(char *opath, const char *dir, const char *basename, const char *ext) {
685
const char dirsep = '/';
686
const char *dirseps = "/";
691
if(opath[strlen(opath) - 1] != dirsep) {
692
strcat(opath, dirseps);
697
strcat(opath, basename);
707
* Convert backslashes to slashes. No-op on UNIX.
710
winpath_to_internal(char *p) {
713
for(i=0; p[i] != '\0'; i++) {
720
/* Get current working directory. */
722
WINDUMMY_FUNC(unsigned int) curr_dir(unsigned int bsize, char* buf) {
728
winpath_to_internal(buf);
736
WINDUMMY_FUNC (FILE*)
737
create_temp_file(void) {
738
char temppath[BUFSIZE];
739
char tempfname[BUFSIZE];
742
retval = GetTempPath(BUFSIZE, temppath);
743
if(retval >= BUFSIZE || retval == 0)
746
if(GetTempFileName(temppath, "CF", 0, tempfname) == 0)
749
return fopen(tempfname, "w+bD");
754
WINDUMMY_FUNC (FILE*)
755
create_temp_file(void) {
758
char* pattrn = malloc(100);
759
strcpy(pattrn, "/tmp/CF.XXXXXX");
761
tmp_fd = mkstemp(pattrn);
763
/* unlink file immediatly, it gets unlinked when file descriptor is closed */
770
if (!(tmp_file = fdopen(tmp_fd, "w+b"))) {