update
This commit is contained in:
parent
b3258002d1
commit
ee3965aa10
|
@ -0,0 +1,3 @@
|
|||
|
||||
*.obj
|
||||
*.exe
|
486
crt.c
486
crt.c
|
@ -1,11 +1,6 @@
|
|||
#include "crt.h"
|
||||
|
||||
#pragma optimize("", off)
|
||||
#define _FILE_TEXT 0x0001
|
||||
#define _FILE_EOF 0x0002
|
||||
#define _FILE_ERROR 0x0004
|
||||
|
||||
#define EOF (-1)
|
||||
|
||||
#define _MAX_CMD_LINE_ARGS 32
|
||||
char* _argv[_MAX_CMD_LINE_ARGS + 1];
|
||||
|
@ -101,7 +96,7 @@ void _term_args()
|
|||
}
|
||||
|
||||
void* xmalloc(size_t size) {
|
||||
return HeapAlloc(GetProcessHeap(), 0, size);
|
||||
return HeapAlloc(GetProcessHeap(), 0, size);
|
||||
}
|
||||
|
||||
void* xrealloc(void* ptr, size_t size) {
|
||||
|
@ -109,7 +104,7 @@ void* xrealloc(void* ptr, size_t size) {
|
|||
}
|
||||
|
||||
void xfree(void* ptr) {
|
||||
HeapFree(GetProcessHeap(), 0, ptr);
|
||||
HeapFree(GetProcessHeap(),0, ptr);
|
||||
}
|
||||
|
||||
unsigned int rand_seed;
|
||||
|
@ -273,7 +268,31 @@ char* xstrcat(char* dst, const char* src)
|
|||
return lstrcatA(dst, src);
|
||||
}
|
||||
|
||||
const char* xxstrstr(const char* str, const char* substr)
|
||||
int xstrncat_s(char * dest, size_t num, const char * source, size_t count)
|
||||
{
|
||||
size_t i, j;
|
||||
if (!dest || !source)
|
||||
return 22;
|
||||
|
||||
for(i = 0; i < num; i++)
|
||||
{
|
||||
if(dest[i] == '\0')
|
||||
{
|
||||
for(j = 0; (j + i) < num; j++)
|
||||
{
|
||||
if(j == count || (dest[j + i] = source[j]) == '\0')
|
||||
{
|
||||
dest[j + i] = '\0';
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 34;
|
||||
}
|
||||
|
||||
char* xstrstr(char* str, const char* substr)
|
||||
{
|
||||
int i;
|
||||
int str_len = xstrlen(str);
|
||||
|
@ -285,11 +304,19 @@ const char* xxstrstr(const char* str, const char* substr)
|
|||
for (i = 0; i < (int)(str_len - substr_len + 1); i++)
|
||||
{
|
||||
if (!xstrcmp(&str[i], substr))
|
||||
return (const char*)(&str[i]);
|
||||
return (char*)(&str[i]);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
char* xstrtok(char* s, const char* delm)
|
||||
{
|
||||
HMODULE msvcrt = LoadLibraryA("msvcrt.dll");
|
||||
char* (__cdecl *func)(char* s, const char* delm) = NULL;
|
||||
func = (char* (__cdecl *)(char* s, const char* delm))GetProcAddress(msvcrt, "strtok");
|
||||
return (*func)(s, delm);
|
||||
}
|
||||
|
||||
size_t xwcslen(const wchar_t* str)
|
||||
{
|
||||
return lstrlenW(str);
|
||||
|
@ -557,393 +584,6 @@ int xwtoi(const wchar_t* str)
|
|||
return (int)xwtol(str);
|
||||
}
|
||||
|
||||
FILE* __cdecl xfopen(const char* path, const char* attrs)
|
||||
{
|
||||
FILE* file;
|
||||
HANDLE hFile;
|
||||
DWORD access, disp;
|
||||
if (xstrchr(attrs, 'w'))
|
||||
{
|
||||
access = GENERIC_WRITE;
|
||||
disp = CREATE_ALWAYS;
|
||||
}
|
||||
else
|
||||
{
|
||||
access = GENERIC_READ;
|
||||
disp = OPEN_EXISTING;
|
||||
}
|
||||
|
||||
hFile = CreateFileA(path, access, 0, 0, disp, 0, 0);
|
||||
if (hFile == INVALID_HANDLE_VALUE)
|
||||
return 0;
|
||||
|
||||
file = (FILE*)xmalloc(sizeof(FILE));
|
||||
__stosb((PBYTE)file, 0, sizeof(FILE));
|
||||
file->_base = (char*)hFile;
|
||||
|
||||
if (xstrchr(attrs, 't')) {
|
||||
file->_flag |= _FILE_TEXT;
|
||||
}
|
||||
|
||||
return file;
|
||||
}
|
||||
|
||||
FILE* __cdecl _xwfopen(const wchar_t* path, const wchar_t* attrs)
|
||||
{
|
||||
HANDLE hFile;
|
||||
DWORD access, disp;
|
||||
FILE* file;
|
||||
|
||||
if (xwcschr(attrs, L'w')) {
|
||||
access = GENERIC_WRITE;
|
||||
disp = CREATE_ALWAYS;
|
||||
}
|
||||
else
|
||||
{
|
||||
access = GENERIC_READ;
|
||||
disp = OPEN_EXISTING;
|
||||
}
|
||||
|
||||
hFile = CreateFileW(path, access, 0, 0, disp, 0, 0);
|
||||
if (hFile == INVALID_HANDLE_VALUE) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
file = (FILE*)xmalloc(sizeof(FILE));
|
||||
__stosb((PBYTE)file, 0, sizeof(FILE));
|
||||
file->_base = (char*)hFile;
|
||||
|
||||
if (xwcschr(attrs, L't')) {
|
||||
file->_flag |= _FILE_TEXT;
|
||||
}
|
||||
|
||||
return file;
|
||||
}
|
||||
|
||||
size_t __cdecl xfwrite(const void* buffer, size_t size, size_t count, FILE* str)
|
||||
{
|
||||
DWORD bw = 0, bw2 = 0;
|
||||
HANDLE hFile;
|
||||
int textMode;
|
||||
|
||||
if (size * count == 0)
|
||||
return 0;
|
||||
|
||||
hFile = str->_base;
|
||||
textMode = str->_flag & _FILE_TEXT;
|
||||
|
||||
// Text-mode translation is always ANSI!
|
||||
if (textMode) // text mode -> translate LF -> CRLF
|
||||
{
|
||||
const char* src = (const char*)buffer;
|
||||
size_t startpos = 0, i = 0;
|
||||
for (i = 0; i < size * count; i++) {
|
||||
const char* crlf;
|
||||
|
||||
if (src[i] != '\n')
|
||||
continue;
|
||||
if (i > 0 && src[i - 1] == '\r') // don't translate CRLF
|
||||
continue;
|
||||
|
||||
if (i > startpos)
|
||||
{
|
||||
WriteFile(hFile, &src[startpos], i - startpos, &bw2, 0);
|
||||
bw += bw2;
|
||||
}
|
||||
|
||||
crlf = "\r\n";
|
||||
WriteFile(hFile, crlf, 2, &bw2, 0);
|
||||
bw++; // one '\n' written
|
||||
|
||||
startpos = i + 1;
|
||||
}
|
||||
|
||||
if (i > startpos)
|
||||
{
|
||||
WriteFile(hFile, &src[startpos], i - startpos, &bw2, 0);
|
||||
bw += bw2;
|
||||
}
|
||||
}
|
||||
else
|
||||
WriteFile(hFile, buffer, (DWORD)(size * count), &bw, 0);
|
||||
return bw / size;
|
||||
}
|
||||
|
||||
int __cdecl xfprintf(FILE* fp, const char* s, ...)
|
||||
{
|
||||
va_list args;
|
||||
char bfr[1024];
|
||||
int len;
|
||||
|
||||
va_start(args, s);
|
||||
|
||||
len = wvsprintfA(bfr, s, args);
|
||||
va_end(args);
|
||||
|
||||
xfwrite(bfr, len + 1, sizeof(char), fp);
|
||||
return len;
|
||||
}
|
||||
|
||||
int __cdecl vfprintf(FILE* fp, const char* s, va_list args)
|
||||
{
|
||||
char bfr[1024];
|
||||
int len;
|
||||
|
||||
len = wvsprintfA(bfr, s, args);
|
||||
|
||||
xfwrite(bfr, len + 1, sizeof(char), fp);
|
||||
return len;
|
||||
}
|
||||
|
||||
int __cdecl fwprintf(FILE* fp, const wchar_t* s, ...)
|
||||
{
|
||||
va_list args;
|
||||
wchar_t bfr[1024];
|
||||
int len;
|
||||
char ansibfr[1024];
|
||||
|
||||
va_start(args, s);
|
||||
|
||||
len = wvsprintfW(bfr, s, args);
|
||||
|
||||
va_end(args);
|
||||
|
||||
WideCharToMultiByte(CP_ACP, 0, bfr, -1, ansibfr, sizeof(ansibfr), 0, 0);
|
||||
|
||||
xfwrite(ansibfr, len + 1, sizeof(char), fp);
|
||||
return len;
|
||||
}
|
||||
|
||||
int __cdecl xfclose(FILE* fp)
|
||||
{
|
||||
CloseHandle(fp->_base);
|
||||
xfree(fp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int __cdecl xfeof(FILE* fp)
|
||||
{
|
||||
return (fp->_flag & _FILE_EOF) ? 1 : 0;
|
||||
}
|
||||
|
||||
int __cdecl xfseek(FILE* str, long offset, int origin)
|
||||
{
|
||||
DWORD meth = FILE_BEGIN;
|
||||
if (origin == SEEK_CUR)
|
||||
meth = FILE_CURRENT;
|
||||
else if (origin == SEEK_END)
|
||||
meth = FILE_END;
|
||||
SetFilePointer(str->_base, offset, 0, meth);
|
||||
str->_flag &= ~_FILE_EOF;
|
||||
return 0;
|
||||
}
|
||||
|
||||
long __cdecl xftell(FILE* fp)
|
||||
{
|
||||
return SetFilePointer(fp->_base, 0, 0, FILE_CURRENT);
|
||||
}
|
||||
|
||||
size_t __cdecl xfread(void* buffer, size_t size, size_t count, FILE* str)
|
||||
{
|
||||
HANDLE hFile;
|
||||
int textMode;
|
||||
char* src;
|
||||
DWORD br;
|
||||
|
||||
if (size * count == 0)
|
||||
return 0;
|
||||
if (xfeof(str))
|
||||
return 0;
|
||||
|
||||
hFile = str->_base;
|
||||
textMode = str->_flag & _FILE_TEXT;
|
||||
|
||||
if (textMode)
|
||||
src = (char*)xmalloc(size * count);
|
||||
else
|
||||
src = (char*)buffer;
|
||||
|
||||
if (!ReadFile(hFile, src, (DWORD)(size * count), &br, 0))
|
||||
str->_flag |= _FILE_ERROR;
|
||||
else if (!br) // nonzero return value and no bytes read = EOF
|
||||
str->_flag |= _FILE_EOF;
|
||||
|
||||
if (!br)
|
||||
return 0;
|
||||
|
||||
// Text-mode translation is always ANSI
|
||||
if (textMode) { // text mode: must translate CR -> LF
|
||||
char* dst = (char*)buffer;
|
||||
DWORD i;
|
||||
|
||||
for (i = 0; i < br; i++) {
|
||||
if (src[i] != '\r')
|
||||
{
|
||||
*dst++ = src[i];
|
||||
continue;
|
||||
}
|
||||
|
||||
// If next char is LF -> convert CR to LF
|
||||
if (i + 1 < br)
|
||||
{
|
||||
if (src[i + 1] == '\n')
|
||||
{
|
||||
*dst++ = '\n';
|
||||
i++;
|
||||
}
|
||||
else
|
||||
*dst++ = src[i];
|
||||
}
|
||||
else if (br > 1)
|
||||
{
|
||||
// This is the hard part: must peek ahead one byte
|
||||
DWORD br2 = 0;
|
||||
char peekChar = 0;
|
||||
ReadFile(hFile, &peekChar, 1, &br2, 0);
|
||||
if (!br2)
|
||||
*dst++ = src[i];
|
||||
else if (peekChar == '\n')
|
||||
*dst++ = '\n';
|
||||
else
|
||||
{
|
||||
xfseek(str, -1, SEEK_CUR);
|
||||
*dst++ = src[i];
|
||||
}
|
||||
}
|
||||
else
|
||||
*dst++ = src[i];
|
||||
}
|
||||
|
||||
xfree(src);
|
||||
}
|
||||
|
||||
return br / size;
|
||||
}
|
||||
|
||||
char* __cdecl xfgets(char* str, int n, FILE* s)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (xfeof(s))
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < n - 1; i++)
|
||||
{
|
||||
if (!xfread(&str[i], 1, sizeof(char), s))
|
||||
break;
|
||||
if (str[i] == '\r')
|
||||
{
|
||||
i--;
|
||||
continue;
|
||||
}
|
||||
if (str[i] == '\n')
|
||||
{
|
||||
i++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
str[i] = 0;
|
||||
return str;
|
||||
}
|
||||
|
||||
wchar_t* __cdecl xfgetws(wchar_t* str, int n, FILE* s)
|
||||
{
|
||||
int i;
|
||||
// Text-mode fgetws converts MBCS->Unicode
|
||||
if (s->_flag & _FILE_TEXT)
|
||||
{
|
||||
char* bfr = (char*)xmalloc(n);
|
||||
xfgets(bfr, n, s);
|
||||
MultiByteToWideChar(CP_ACP, 0, bfr, -1, str, n);
|
||||
xfree(bfr);
|
||||
return str;
|
||||
}
|
||||
|
||||
// Binary fgetws reads as Unicode
|
||||
|
||||
if (xfeof(s))
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < n - 1; i++)
|
||||
{
|
||||
if (!xfread(&str[i], 1, sizeof(wchar_t), s))
|
||||
break;
|
||||
if (str[i] == L'\r')
|
||||
{
|
||||
i--;
|
||||
continue; // does i++
|
||||
}
|
||||
if (str[i] == L'\n')
|
||||
{
|
||||
i++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
str[i] = 0;
|
||||
return str;
|
||||
}
|
||||
|
||||
int __cdecl xfgetc(FILE* s)
|
||||
{
|
||||
char c;
|
||||
|
||||
if (s == 0 || xfeof(s))
|
||||
return EOF;
|
||||
|
||||
xfread(&c, 1, sizeof(char), s);
|
||||
|
||||
return (int)c;
|
||||
}
|
||||
|
||||
int __cdecl xfputc(int ch, FILE* s)
|
||||
{
|
||||
char c;
|
||||
|
||||
if (s == 0 || xfeof(s))
|
||||
return EOF;
|
||||
|
||||
xfwrite(&c, 1, sizeof(char), s);
|
||||
|
||||
return (int)c;
|
||||
}
|
||||
|
||||
wint_t __cdecl xfgetwc(FILE* s)
|
||||
{
|
||||
wint_t c;
|
||||
|
||||
if (s == 0 || xfeof(s))
|
||||
return (wint_t)EOF;
|
||||
|
||||
// text-mode fgetwc reads and converts MBCS
|
||||
if (s->_flag & _FILE_TEXT)
|
||||
{
|
||||
char ch = (char)xfgetc(s);
|
||||
wint_t wch;
|
||||
|
||||
MultiByteToWideChar(CP_ACP, 0, &ch, 1, (LPWSTR)&wch, 1);
|
||||
return wch;
|
||||
}
|
||||
|
||||
// binary fgetwc reads unicode
|
||||
|
||||
xfread(&c, 1, sizeof(wint_t), s);
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
int __cdecl xfflush(FILE* stream)
|
||||
{
|
||||
return (FlushFileBuffers(stream->_base) ? 0 : 1);
|
||||
}
|
||||
|
||||
int __cdecl xfileno(FILE* stream)
|
||||
{
|
||||
//_VALIDATE_RETURN((stream != NULL), EINVAL, -1);
|
||||
return stream->_file;
|
||||
}
|
||||
|
||||
int x_vscprintf(const char *format, va_list argptr)
|
||||
{
|
||||
HMODULE msvcrt = LoadLibraryA("msvcrt.dll");
|
||||
|
@ -960,6 +600,14 @@ int x_vsnprintf(char *buffer, size_t count, const char *format, va_list argptr)
|
|||
return (*func)(buffer, count, format, argptr);
|
||||
}
|
||||
|
||||
int xvsprintf_s(char *buffer, size_t numberOfElements, const char *format, va_list argptr)
|
||||
{
|
||||
HMODULE msvcrt = LoadLibraryA("msvcrt.dll");
|
||||
int (__cdecl *func)(char *buffer, size_t numberOfElements, const char *format, va_list argptr) = NULL;
|
||||
func = (int (__cdecl *)(char *buffer, size_t numberOfElements, const char *format, va_list argptr))GetProcAddress(msvcrt, "vsprintf_s");
|
||||
return (*func)(buffer, numberOfElements, format, argptr);
|
||||
}
|
||||
|
||||
int xsnprintf(char *s, size_t n, const char *format, ...)
|
||||
{
|
||||
size_t r;
|
||||
|
@ -971,7 +619,7 @@ int xsnprintf(char *s, size_t n, const char *format, ...)
|
|||
va_end(vl);
|
||||
|
||||
va_start(vl, format);
|
||||
r = _vsnprintf(s, n, format, vl);
|
||||
r = x_vsnprintf(s, n, format, vl);
|
||||
va_end(vl);
|
||||
|
||||
if (r >= n)
|
||||
|
@ -983,4 +631,48 @@ int xsnprintf(char *s, size_t n, const char *format, ...)
|
|||
|
||||
return calculated_size;
|
||||
}
|
||||
|
||||
int xputenv(const char *str)
|
||||
{
|
||||
char *name, *value;
|
||||
char *dst;
|
||||
int ret;
|
||||
|
||||
if (!str)
|
||||
return -1;
|
||||
|
||||
name = xmalloc(strlen(str) + 1);
|
||||
if (!name)
|
||||
return -1;
|
||||
dst = name;
|
||||
while (*str && *str != '=')
|
||||
*dst++ = *str++;
|
||||
if (!*str++)
|
||||
{
|
||||
ret = -1;
|
||||
goto finish;
|
||||
}
|
||||
*dst++ = '\0';
|
||||
value = dst;
|
||||
while (*str)
|
||||
*dst++ = *str++;
|
||||
*dst = '\0';
|
||||
|
||||
ret = SetEnvironmentVariableA(name, value[0] ? value : NULL) ? 0 : -1;
|
||||
|
||||
/* _putenv returns success on deletion of nonexistent variable, unlike [Rtl]SetEnvironmentVariable */
|
||||
if ((ret == -1) && (GetLastError() == ERROR_ENVVAR_NOT_FOUND)) ret = 0;
|
||||
|
||||
finish:
|
||||
HeapFree(GetProcessHeap(), 0, name);
|
||||
return ret;
|
||||
}
|
||||
|
||||
time_t xtime( time_t *destTime )
|
||||
{
|
||||
HMODULE msvcrt = LoadLibraryA("msvcrt.dll");
|
||||
time_t (__cdecl *func)(time_t *destTime) = NULL;
|
||||
func = (time_t (__cdecl *)(time_t *destTime))GetProcAddress(msvcrt, "time");
|
||||
return (*func)(destTime);
|
||||
}
|
||||
#pragma optimize("", on)
|
40
crt.h
40
crt.h
|
@ -1,20 +1,5 @@
|
|||
#include <windows.h>
|
||||
|
||||
#ifndef _FILE_DEFINED
|
||||
struct _iobuf {
|
||||
char *_ptr;
|
||||
int _cnt;
|
||||
char *_base;
|
||||
int _flag;
|
||||
int _file;
|
||||
int _charbuf;
|
||||
int _bufsiz;
|
||||
char *_tmpfname;
|
||||
};
|
||||
typedef struct _iobuf FILE;
|
||||
#define _FILE_DEFINED
|
||||
#endif
|
||||
|
||||
int _init_args();
|
||||
void _term_args();
|
||||
void* xmalloc(size_t size);
|
||||
|
@ -39,7 +24,9 @@ char* xstrncpy(char* dest, const char* src, size_t n);
|
|||
const char* xstrchr(const char* str, int ch);
|
||||
const char* xstrrchr(const char* str, int ch);
|
||||
char* xstrcat(char* dst, const char* src);
|
||||
const char* xxstrstr(const char* str, const char* substr);
|
||||
int xstrncat_s(char * dest, size_t num, const char * source, size_t count);
|
||||
char* xstrstr(char* str, const char* substr);
|
||||
char* xstrtok(char* s, const char* delm);
|
||||
size_t xwcslen(const wchar_t* str);
|
||||
wchar_t* xwcscpy(wchar_t* dest, const wchar_t* src);
|
||||
int xwcsicmp(const wchar_t* s1, const wchar_t* s2);
|
||||
|
@ -82,24 +69,9 @@ long xatol(const char* str);
|
|||
int xatoi(const char* str);
|
||||
long xwtol(const wchar_t* str);
|
||||
int xwtoi(const wchar_t* str);
|
||||
FILE* __cdecl xfopen(const char* path, const char* attrs);
|
||||
FILE* __cdecl _xwfopen(const wchar_t* path, const wchar_t* attrs);
|
||||
size_t __cdecl xfwrite(const void* buffer, size_t size, size_t count, FILE* str);
|
||||
int __cdecl xfprintf(FILE* fp, const char* s, ...);
|
||||
int __cdecl vfprintf(FILE* fp, const char* s, va_list args);
|
||||
int __cdecl fwprintf(FILE* fp, const wchar_t* s, ...);
|
||||
int __cdecl xfclose(FILE* fp);
|
||||
int __cdecl xfeof(FILE* fp);
|
||||
int __cdecl xfseek(FILE* str, long offset, int origin);
|
||||
long __cdecl xftell(FILE* fp);
|
||||
size_t __cdecl xfread(void* buffer, size_t size, size_t count, FILE* str);
|
||||
char* __cdecl xfgets(char* str, int n, FILE* s);
|
||||
wchar_t* __cdecl xfgetws(wchar_t* str, int n, FILE* s);
|
||||
int __cdecl xfgetc(FILE* s);
|
||||
int __cdecl xfputc(int ch, FILE* s);
|
||||
wint_t __cdecl xfgetwc(FILE* s);
|
||||
int __cdecl xfflush(FILE* stream);
|
||||
int __cdecl xfileno(FILE* stream);
|
||||
int x_vscprintf(const char *format, va_list argptr);
|
||||
int x_vsnprintf(char *buffer, size_t count, const char *format, va_list argptr);
|
||||
int xsnprintf(char *s, size_t n, const char *format, ...);
|
||||
int xvsprintf_s(char *buffer, size_t numberOfElements, const char *format, va_list argptr);
|
||||
int xputenv(const char *str);
|
||||
time_t xtime( time_t *destTime );
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#include "../crt.h"
|
||||
#include "../crt.c"
|
||||
|
||||
int main()
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue