mirror of https://github.com/PrimeDecomp/prime.git
Match and link sscanf, string and mbstring
This commit is contained in:
parent
a8f8ef18e5
commit
eb14c6e0ad
|
@ -9,7 +9,8 @@
|
|||
"cStandard": "c99",
|
||||
"cppStandard": "c++98",
|
||||
"intelliSenseMode": "linux-clang-x86",
|
||||
"compilerPath": ""
|
||||
"compilerPath": "",
|
||||
"configurationProvider": "ms-vscode.makefile-tools"
|
||||
}
|
||||
],
|
||||
"version": 4
|
||||
|
|
|
@ -57,7 +57,8 @@
|
|||
"gxpriv.h": "c",
|
||||
"osfastcast.h": "c",
|
||||
"osfont.h": "c",
|
||||
"arq.h": "c"
|
||||
"arq.h": "c",
|
||||
"string.h": "c"
|
||||
},
|
||||
"files.autoSave": "onFocusChange",
|
||||
"files.insertFinalNewline": true,
|
||||
|
|
|
@ -872,15 +872,15 @@ LIBS = [
|
|||
["Runtime/file_io", True],
|
||||
["Runtime/errno", True],
|
||||
["Runtime/FILE_POS", True],
|
||||
"Runtime/mbstring",
|
||||
["Runtime/mbstring", True],
|
||||
["Runtime/mem", True],
|
||||
["Runtime/mem_funcs", True],
|
||||
["Runtime/misc_io", True],
|
||||
"Runtime/printf",
|
||||
["Runtime/qsort", False],
|
||||
["Runtime/rand", True],
|
||||
"Runtime/sscanf",
|
||||
"Runtime/string",
|
||||
["Runtime/sscanf", True],
|
||||
["Runtime/string", True],
|
||||
["Runtime/float", True],
|
||||
"Runtime/strtold",
|
||||
["Runtime/uart_console_io", True],
|
||||
|
|
|
@ -10,8 +10,9 @@ extern int errno;
|
|||
#define ENOERR 0
|
||||
#define EDOM 33
|
||||
#define ERANGE 34
|
||||
#define EFPOS 40
|
||||
#define ESIGPARM 36
|
||||
#define EFPOS 40
|
||||
#define EILSEQ 84
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
17
libc/stdio.h
17
libc/stdio.h
|
@ -99,6 +99,21 @@ typedef struct _IO_FILE {
|
|||
struct _IO_FILE* next_file_struct;
|
||||
} FILE;
|
||||
|
||||
typedef struct {
|
||||
char* CharStr;
|
||||
size_t MaxCharCount;
|
||||
size_t CharsWritten;
|
||||
} __OutStrCtrl;
|
||||
|
||||
typedef struct {
|
||||
char* NextChar;
|
||||
int NullCharDetected;
|
||||
} __InStrCtrl;
|
||||
|
||||
#define EOF -1L
|
||||
|
||||
enum __ReadProcActions { __GetChar, __UngetChar, __CheckForError };
|
||||
|
||||
#define _IONBF 0
|
||||
#define _IOLBF 1
|
||||
#define _IOFBF 2
|
||||
|
@ -110,7 +125,7 @@ int vprintf(const char* format, va_list arg);
|
|||
int vsprintf(char* s, const char* format, va_list arg);
|
||||
size_t fread(const void*, size_t memb_size, size_t num_memb, FILE*);
|
||||
size_t fwrite(const void*, size_t memb_size, size_t num_memb, FILE*);
|
||||
int fseek(FILE * file, long offset, int mode);
|
||||
int fseek(FILE* file, long offset, int mode);
|
||||
size_t __fwrite(const void*, size_t, size_t, FILE*);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -0,0 +1,116 @@
|
|||
#include "errno.h"
|
||||
#include "stdio.h"
|
||||
#include "string.h"
|
||||
#include "wstring.h"
|
||||
|
||||
#pragma ANSI_strict off
|
||||
|
||||
#ifndef __WINT_TYPE__
|
||||
#define __WINT_TYPE__ unsigned int
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
int __count;
|
||||
union {
|
||||
__WINT_TYPE__ __wch;
|
||||
char __wchb[4];
|
||||
} __value; /* Value so far. */
|
||||
} mbstate_t;
|
||||
|
||||
static int is_utf8_complete(const char* s, size_t n);
|
||||
static int is_utf8_complete(const char* s, size_t n) {
|
||||
if (n <= 0) /* 0 or fewer characters do not form a valid multibyte character */
|
||||
return (-1);
|
||||
|
||||
if (*s == 0x00)
|
||||
return (0);
|
||||
|
||||
if ((*s & 0x80) == 0x00)
|
||||
return (1);
|
||||
else if ((*s & 0xe0) == 0xc0) /* need 2 bytes */
|
||||
if (n >= 2)
|
||||
if (((*(s + 1) & 0x80) == 0x80))
|
||||
return (2);
|
||||
else
|
||||
return (-1);
|
||||
else
|
||||
return (-2);
|
||||
|
||||
else if ((*s & 0xf0) == 0xe0)
|
||||
if (n >= 3)
|
||||
if (((*(s + 1) & 0x80) == 0x80) && ((*(s + 2) & 0x80) == 0x80))
|
||||
return (3);
|
||||
else
|
||||
return (-1);
|
||||
else if (((n == 2) && ((*(s + 1) & 0x80) == 0x80)) || (n == 1))
|
||||
return (-2);
|
||||
else
|
||||
return (-1);
|
||||
else
|
||||
return (-1);
|
||||
}
|
||||
|
||||
#pragma dont_inline on
|
||||
static int unicode_to_UTF8(char* s, wchar_t wchar) {
|
||||
int number_of_bytes;
|
||||
wchar_t wide_char;
|
||||
char* target_ptr;
|
||||
char first_byte_mark[4] = {0x00, 0x00, 0xc0, 0xe0};
|
||||
|
||||
if (!s) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
wide_char = wchar;
|
||||
if (wide_char < 0x0080)
|
||||
number_of_bytes = 1;
|
||||
else if (wide_char < 0x0800)
|
||||
number_of_bytes = 2;
|
||||
else
|
||||
number_of_bytes = 3;
|
||||
|
||||
target_ptr = s + number_of_bytes;
|
||||
|
||||
switch (number_of_bytes) {
|
||||
case 3:
|
||||
*--target_ptr = (wide_char & 0x003f) | 0x80;
|
||||
wide_char >>= 6;
|
||||
case 2:
|
||||
*--target_ptr = (wide_char & 0x003f) | 0x80;
|
||||
wide_char >>= 6;
|
||||
case 1:
|
||||
*--target_ptr = wide_char | first_byte_mark[number_of_bytes];
|
||||
}
|
||||
|
||||
return (number_of_bytes);
|
||||
}
|
||||
#pragma dont_inline reset
|
||||
|
||||
int wctomb(char* s, wchar_t wchar) { return (unicode_to_UTF8(s, wchar)); }
|
||||
|
||||
size_t wcstombs(char* s, const wchar_t* pwcs, size_t n) {
|
||||
int chars_written = 0;
|
||||
int result;
|
||||
char temp[3];
|
||||
wchar_t* source;
|
||||
|
||||
if (!s || !pwcs)
|
||||
return (0);
|
||||
|
||||
source = (wchar_t*)pwcs;
|
||||
while (chars_written <= n) {
|
||||
if (!*source) {
|
||||
*(s + chars_written) = '\0';
|
||||
break;
|
||||
} else {
|
||||
result = wctomb(temp, *source++);
|
||||
if ((chars_written + result) <= n) {
|
||||
strncpy(s + chars_written, temp, result);
|
||||
chars_written += result;
|
||||
} else
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return (chars_written);
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
#include "stdio.h"
|
||||
|
||||
int __StringRead(void* isc, int ch, int Action) {
|
||||
char ret;
|
||||
__InStrCtrl* iscp = (__InStrCtrl*)isc;
|
||||
switch (Action) {
|
||||
case __GetChar:
|
||||
ret = *(iscp->NextChar);
|
||||
if (ret == '\0') {
|
||||
iscp->NullCharDetected = 1;
|
||||
return (EOF);
|
||||
} else {
|
||||
iscp->NextChar++;
|
||||
return ((unsigned char)ret);
|
||||
}
|
||||
case __UngetChar:
|
||||
if (!iscp->NullCharDetected)
|
||||
iscp->NextChar--;
|
||||
else
|
||||
iscp->NullCharDetected = 0;
|
||||
return (ch);
|
||||
case __CheckForError:
|
||||
return (iscp->NullCharDetected);
|
||||
}
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,201 @@
|
|||
#include "string.h"
|
||||
|
||||
size_t strlen(const char* str) {
|
||||
size_t len = -1;
|
||||
unsigned char* p = (unsigned char*)str - 1;
|
||||
do {
|
||||
len++;
|
||||
} while (*++p);
|
||||
return len;
|
||||
}
|
||||
|
||||
char*(strcpy)(char* dst, const char* src) {
|
||||
unsigned char *destb, *fromb;
|
||||
unsigned int w, t, align;
|
||||
unsigned int k1;
|
||||
unsigned int k2;
|
||||
|
||||
fromb = (unsigned char*)src;
|
||||
destb = (unsigned char*)dst;
|
||||
|
||||
if ((align = ((int)fromb & 3)) != ((int)destb & 3)) {
|
||||
goto bytecopy;
|
||||
}
|
||||
|
||||
if (align) {
|
||||
if ((*destb = *fromb) == 0) {
|
||||
return dst;
|
||||
}
|
||||
|
||||
for (align = 3 - align; align; align--) {
|
||||
if ((*(++destb) = *(++fromb)) == 0) {
|
||||
return dst;
|
||||
}
|
||||
}
|
||||
++destb;
|
||||
++fromb;
|
||||
}
|
||||
|
||||
k1 = 0x80808080;
|
||||
k2 = 0xfefefeff;
|
||||
|
||||
w = *((int*)(fromb));
|
||||
t = w + k2;
|
||||
t &= k1;
|
||||
if (t) {
|
||||
goto bytecopy;
|
||||
}
|
||||
|
||||
--((int*)(destb));
|
||||
|
||||
do {
|
||||
*(++((int*)(destb))) = w;
|
||||
w = *(++((int*)(fromb)));
|
||||
|
||||
t = w + k2;
|
||||
t &= k1;
|
||||
if (t)
|
||||
goto adjust;
|
||||
} while (1);
|
||||
|
||||
adjust:
|
||||
++((int*)(destb));
|
||||
|
||||
bytecopy:
|
||||
if ((*destb = *fromb) == 0)
|
||||
return (dst);
|
||||
do {
|
||||
if ((*(++destb) = *(++fromb)) == 0)
|
||||
return dst;
|
||||
} while (1);
|
||||
|
||||
return dst;
|
||||
}
|
||||
|
||||
char* strncpy(char* dst, const char* src, size_t n) {
|
||||
const unsigned char* p = (const unsigned char*)src - 1;
|
||||
unsigned char* q = (unsigned char*)dst - 1;
|
||||
unsigned char zero = 0;
|
||||
|
||||
n++;
|
||||
|
||||
while (--n)
|
||||
if (!(*++q = *++p)) {
|
||||
while (--n)
|
||||
*++q = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
return dst;
|
||||
}
|
||||
|
||||
int strcmp(const char* str1, const char* str2) {
|
||||
unsigned char* left = (unsigned char*)str1;
|
||||
unsigned char* right = (unsigned char*)str2;
|
||||
unsigned int k1, k2, align, l1, r1, x;
|
||||
|
||||
l1 = *left;
|
||||
r1 = *right;
|
||||
if (l1 - r1) {
|
||||
return l1 - r1;
|
||||
}
|
||||
|
||||
if ((align = ((int)left & 3)) != ((int)right & 3)) {
|
||||
goto bytecopy;
|
||||
}
|
||||
if (align) {
|
||||
if (l1 == 0) {
|
||||
return 0;
|
||||
}
|
||||
for (align = 3 - align; align; align--) {
|
||||
l1 = *(++left);
|
||||
r1 = *(++right);
|
||||
if (l1 - r1) {
|
||||
return l1 - r1;
|
||||
}
|
||||
if (l1 == 0) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
left++;
|
||||
right++;
|
||||
}
|
||||
|
||||
k1 = 0x80808080;
|
||||
k2 = 0xfefefeff;
|
||||
|
||||
l1 = *(int*)left;
|
||||
r1 = *(int*)right;
|
||||
x = l1 + k2;
|
||||
if (x & k1) {
|
||||
goto adjust;
|
||||
}
|
||||
while (l1 == r1) {
|
||||
l1 = *(++((int*)(left)));
|
||||
r1 = *(++((int*)(right)));
|
||||
x = l1 + k2;
|
||||
if (x & k1) {
|
||||
goto adjust;
|
||||
}
|
||||
}
|
||||
|
||||
if (l1 > r1) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return -1;
|
||||
|
||||
adjust:
|
||||
l1 = *left;
|
||||
r1 = *right;
|
||||
if (l1 - r1) {
|
||||
return l1 - r1;
|
||||
}
|
||||
|
||||
bytecopy:
|
||||
if (l1 == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
do {
|
||||
l1 = *(++left);
|
||||
r1 = *(++right);
|
||||
if (l1 - r1) {
|
||||
return l1 - r1;
|
||||
}
|
||||
if (l1 == 0) {
|
||||
return 0;
|
||||
}
|
||||
} while (1);
|
||||
}
|
||||
|
||||
int strncmp(const char* str1, const char* str2, size_t n) {
|
||||
const unsigned char* p1 = (unsigned char*)str1 - 1;
|
||||
const unsigned char* p2 = (unsigned char*)str2 - 1;
|
||||
unsigned long c1, c2;
|
||||
|
||||
n++;
|
||||
|
||||
while (--n) {
|
||||
if ((c1 = *++p1) != (c2 = *++p2)) {
|
||||
return (c1 - c2);
|
||||
} else if (!c1) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
char* strchr(const char* str, int chr) {
|
||||
const unsigned char* p = (unsigned char*)str - 1;
|
||||
unsigned long c = (chr & 0xff);
|
||||
unsigned long ch;
|
||||
|
||||
while (ch = *++p) {
|
||||
if (ch == c)
|
||||
return ((char*)p);
|
||||
}
|
||||
|
||||
return (c ? 0 : (char*)p);
|
||||
}
|
Loading…
Reference in New Issue