mirror of https://github.com/PrimeDecomp/prime.git
Match and link sscanf, string and mbstring
Former-commit-id: eb14c6e0ad
This commit is contained in:
parent
5cbb51975e
commit
efb5cb0597
|
@ -9,8 +9,9 @@
|
||||||
"cStandard": "c99",
|
"cStandard": "c99",
|
||||||
"cppStandard": "c++98",
|
"cppStandard": "c++98",
|
||||||
"intelliSenseMode": "linux-clang-x86",
|
"intelliSenseMode": "linux-clang-x86",
|
||||||
"compilerPath": ""
|
"compilerPath": "",
|
||||||
|
"configurationProvider": "ms-vscode.makefile-tools"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"version": 4
|
"version": 4
|
||||||
}
|
}
|
|
@ -57,7 +57,8 @@
|
||||||
"gxpriv.h": "c",
|
"gxpriv.h": "c",
|
||||||
"osfastcast.h": "c",
|
"osfastcast.h": "c",
|
||||||
"osfont.h": "c",
|
"osfont.h": "c",
|
||||||
"arq.h": "c"
|
"arq.h": "c",
|
||||||
|
"string.h": "c"
|
||||||
},
|
},
|
||||||
"files.autoSave": "onFocusChange",
|
"files.autoSave": "onFocusChange",
|
||||||
"files.insertFinalNewline": true,
|
"files.insertFinalNewline": true,
|
||||||
|
|
|
@ -872,15 +872,15 @@ LIBS = [
|
||||||
["Runtime/file_io", True],
|
["Runtime/file_io", True],
|
||||||
["Runtime/errno", True],
|
["Runtime/errno", True],
|
||||||
["Runtime/FILE_POS", True],
|
["Runtime/FILE_POS", True],
|
||||||
"Runtime/mbstring",
|
["Runtime/mbstring", True],
|
||||||
["Runtime/mem", True],
|
["Runtime/mem", True],
|
||||||
["Runtime/mem_funcs", True],
|
["Runtime/mem_funcs", True],
|
||||||
["Runtime/misc_io", True],
|
["Runtime/misc_io", True],
|
||||||
"Runtime/printf",
|
"Runtime/printf",
|
||||||
["Runtime/qsort", False],
|
["Runtime/qsort", False],
|
||||||
["Runtime/rand", True],
|
["Runtime/rand", True],
|
||||||
"Runtime/sscanf",
|
["Runtime/sscanf", True],
|
||||||
"Runtime/string",
|
["Runtime/string", True],
|
||||||
["Runtime/float", True],
|
["Runtime/float", True],
|
||||||
"Runtime/strtold",
|
"Runtime/strtold",
|
||||||
["Runtime/uart_console_io", True],
|
["Runtime/uart_console_io", True],
|
||||||
|
|
|
@ -10,8 +10,9 @@ extern int errno;
|
||||||
#define ENOERR 0
|
#define ENOERR 0
|
||||||
#define EDOM 33
|
#define EDOM 33
|
||||||
#define ERANGE 34
|
#define ERANGE 34
|
||||||
#define EFPOS 40
|
|
||||||
#define ESIGPARM 36
|
#define ESIGPARM 36
|
||||||
|
#define EFPOS 40
|
||||||
|
#define EILSEQ 84
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
17
libc/stdio.h
17
libc/stdio.h
|
@ -99,6 +99,21 @@ typedef struct _IO_FILE {
|
||||||
struct _IO_FILE* next_file_struct;
|
struct _IO_FILE* next_file_struct;
|
||||||
} FILE;
|
} 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 _IONBF 0
|
||||||
#define _IOLBF 1
|
#define _IOLBF 1
|
||||||
#define _IOFBF 2
|
#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);
|
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 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*);
|
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*);
|
size_t __fwrite(const void*, size_t, size_t, FILE*);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#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