summaryrefslogtreecommitdiff
path: root/src/nonstd
diff options
context:
space:
mode:
Diffstat (limited to 'src/nonstd')
-rw-r--r--src/nonstd/LIBC_INTERNAL.c3
-rw-r--r--src/nonstd/__libc.c16
-rw-r--r--src/nonstd/__libc_start.c33
-rw-r--r--src/nonstd/__load_locale.c4
-rw-r--r--src/nonstd/_locale.h134
-rw-r--r--src/nonstd/ctype-internal.ref2
-rw-r--r--src/nonstd/ctype_t.c22
-rw-r--r--src/nonstd/io-internal.ref2
-rw-r--r--src/nonstd/lib-internal.ref2
-rw-r--r--src/nonstd/locale-internal.ref2
-rw-r--r--src/nonstd/locale-limits.ref2
-rw-r--r--src/nonstd/locale-locale.ref2
-rw-r--r--src/nonstd/struct_locale_t.c27
-rw-r--r--src/nonstd/syscall-internal.ref (renamed from src/nonstd/nonstd-inernal.ref)0
14 files changed, 220 insertions, 31 deletions
diff --git a/src/nonstd/LIBC_INTERNAL.c b/src/nonstd/LIBC_INTERNAL.c
index af964cd7..03495623 100644
--- a/src/nonstd/LIBC_INTERNAL.c
+++ b/src/nonstd/LIBC_INTERNAL.c
@@ -4,6 +4,7 @@ typedef enum {
ERRNO,
THREAD_LOCALE,
GLOBAL_LOCALE,
+ LOAD_LOCALE,
SYSCALL_LOOKUP,
PRINTF,
SCANF,
@@ -11,7 +12,7 @@ typedef enum {
CTYPE,
TOLOWER,
TOUPPER,
- FILE_TAIL,
+ FILE_STREAMS,
ATEXIT,
RAND
} LIBC_INTERNAL;
diff --git a/src/nonstd/__libc.c b/src/nonstd/__libc.c
index d48d6714..354dee9b 100644
--- a/src/nonstd/__libc.c
+++ b/src/nonstd/__libc.c
@@ -1,19 +1,21 @@
#include "sys/types.h"
#include <nonstd/internal.h>
-#include "locale.h"
#include "nonstd/locale.h"
+#include "nonstd/io.h"
#include "_printf.h"
+#include "_scanf.h"
+#include "_locale.h"
#include "_syscall.h"
void *__libc(LIBC_INTERNAL variable)
{
extern void *__libc_per_thread(LIBC_INTERNAL __variable);
+ static struct __locale_t locale;
+ static struct __FILE file_streams[FOPEN_MAX];
void *r = (void*)0;
- static struct __locale_t locale;
-
switch (variable) {
case ERRNO:
return __libc_per_thread(ERRNO);
@@ -45,6 +47,14 @@ void *__libc(LIBC_INTERNAL variable)
r = (void*)(__printf);
break;
+ case FILE_STREAMS:
+ r = file_streams;
+ break;
+
+ case LOAD_LOCALE:
+ r = (void*)(__load_locale);
+ break;
+
default:
break;
}
diff --git a/src/nonstd/__libc_start.c b/src/nonstd/__libc_start.c
index e10e081e..c1cf7803 100644
--- a/src/nonstd/__libc_start.c
+++ b/src/nonstd/__libc_start.c
@@ -3,18 +3,37 @@
#include "nonstd/io.h"
+#ifdef _POSIX_SOURCE
+#include "unistd.h"
+#else
+#include "nonstd/syscall.h"
+#define isatty(fd) __syscall(__lookup("tty"), fd)
+#endif
+
void __libc_start(int argc, char **argv)
{
- struct __FILE sin, sout, serr;
+ struct __FILE *files = __libc(FILE_STREAMS);
+
+ stdin = files + 0;
+ stdin->fd = 0;
+ freopen(NULL, "r", stdin);
+ setvbuf(stdin, NULL, isatty(0) ? _IOLBF : _IOFBF, BUFSIZ);
+
+ stdout = files + 1;
+ stdout->fd = 1;
+ freopen(NULL, "w", stdout);
+ setvbuf(stdin, NULL, isatty(1) ? _IOLBF : _IOFBF, BUFSIZ);
- sin.fd = 0;
- stdin = &sin;
+ stderr = files + 2;
+ stderr->fd = 2;
+ freopen(NULL, "w", stderr);
+ setvbuf(stderr, NULL, _IONBF, 0);
- sout.fd = 1;
- stdout = &sout;
+ stdin->next = stdout;
+ stdout->next = stderr;
- serr.fd = 2;
- stderr = &serr;
+ stdout->prev = stdin;
+ stderr->prev = stdout;
#if defined _POSIX_SOURCE
setlocale(LC_ALL, "POSIX");
diff --git a/src/nonstd/__load_locale.c b/src/nonstd/__load_locale.c
new file mode 100644
index 00000000..2233e6b8
--- /dev/null
+++ b/src/nonstd/__load_locale.c
@@ -0,0 +1,4 @@
+#include <nonstd/locale.h>
+
+#define __load_locale(_loc, _mask, _name) \
+ ((char * (*)(struct __locale_t *, int, const char *))__libc(LOAD_LOCALE))(_loc, _mask, _name)
diff --git a/src/nonstd/_locale.h b/src/nonstd/_locale.h
new file mode 100644
index 00000000..7bb676ed
--- /dev/null
+++ b/src/nonstd/_locale.h
@@ -0,0 +1,134 @@
+#include <locale.h>
+#include <limits.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "nonstd/locale.h"
+#include "nonstd/ctype.h"
+
+/*
+#define LC_COLLATE_MASK (1<<0)
+#define LC_CTYPE_MASK (1<<1)
+#define LC_MONETARY_MASK (1<<2)
+#define LC_NUMERIC_MASK (1<<3)
+#define LC_TIME_MASK (1<<4)
+#define LC_MESSAGES_MASK (1<<5)
+#define LC_ALL_MASK (0xff)
+*/
+
+static char * (__load_locale)(struct __locale_t *loc, int mask, const char *name)
+{
+ char localepath[FILENAME_MAX] = "/lib/locale/";
+ strcat(localepath, name);
+
+ FILE *localefile = fopen(localepath, "rb");
+ if (localefile == NULL && strcmp(name, "C") && strcmp(name, "POSIX")) {
+ return NULL;
+ }
+
+ if (mask & LC_COLLATE_MASK) {
+ strcpy(loc->collate, name);
+
+ /* read from file */
+ loc->lc_collate = NULL;
+ }
+
+ if (mask & LC_CTYPE_MASK) {
+ strcpy(loc->ctype, name);
+
+ if (localefile == NULL) {
+ int i;
+
+ for (i = 0; i < 32; i++) {
+ loc->lc_ctype.ctattr[i] = CT_CNTRL;
+ }
+ for (i = 'a'; i < 'z'; i++) {
+ loc->lc_ctype.ctattr[i] = CT_LOWER;
+ }
+ for (i = 'A'; i < 'Z'; i++) {
+ loc->lc_ctype.ctattr[i] = CT_UPPER;
+ }
+ for (i = '0'; i < '9'; i++) {
+ loc->lc_ctype.ctattr[i] = CT_DIGIT | CT_XDIGIT;
+ }
+ /* others */
+ for (i = 0; i < CHAR_MAX; i++) {
+ loc->lc_ctype.ctoupper[i] = ('a' <= i && i <= 'z') ? i + 32 : i;
+ }
+
+ for (i = 0; i < CHAR_MAX; i++) {
+ loc->lc_ctype.ctolower[i] = ('A' <= i && i <= 'Z') ? i - 32 : i;
+ }
+ } else {
+ /* read from file */
+ /*
+ loc->lc_ctype.ctattr
+ loc->lc_ctype.ctoupper
+ loc->lc_ctype.ctolower
+ */
+ }
+ }
+
+ if (mask & LC_MONETARY_MASK) {
+ strcpy(loc->monetary, name);
+
+ if (localefile == NULL) {
+ loc->mn.mon_decimal_point = "";
+ loc->mn.mon_thousands_sep = "";
+ loc->mn.mon_grouping = "";
+ loc->mn.positive_sign = "";
+ loc->mn.negative_sign = "";
+ loc->mn.currency_symbol = "";
+ loc->mn.frac_digits = CHAR_MAX;
+ loc->mn.p_cs_precedes = CHAR_MAX;
+ loc->mn.n_cs_precedes = CHAR_MAX;
+ loc->mn.p_sep_by_space = CHAR_MAX;
+ loc->mn.n_sep_by_space = CHAR_MAX;
+ loc->mn.p_sign_posn = CHAR_MAX;
+ loc->mn.n_sign_posn = CHAR_MAX;
+ loc->mn.int_curr_symbol = "";
+ loc->mn.int_frac_digits = CHAR_MAX;
+ loc->mn.int_p_cs_precedes = CHAR_MAX;
+ loc->mn.int_n_cs_precedes = CHAR_MAX;
+ loc->mn.int_p_sep_by_space = CHAR_MAX;
+ loc->mn.int_n_sep_by_space = CHAR_MAX;
+ loc->mn.int_p_sign_posn = CHAR_MAX;
+ loc->mn.int_n_sign_posn = CHAR_MAX;
+ } else {
+ /*
+ loc->mn.monetary fields;
+ */
+ }
+ }
+
+ if (mask & LC_NUMERIC_MASK) {
+ strcpy(loc->numeric, name);
+
+ if (localefile == NULL) {
+ loc->mn.decimal_point = ".";
+ loc->mn.thousands_sep = "";
+ loc->mn.grouping = "";
+ } else {
+ /*
+ loc->mn.numeric fields
+ */
+ }
+ }
+
+ if (mask & LC_TIME_MASK) {
+ strcpy(loc->time, name);
+
+ /* read from file */
+ /* loc->lc_time */
+ }
+
+ if (mask & LC_MESSAGES_MASK) {
+ strcpy(loc->messages, name);
+
+ /* read */
+ loc->lc_messages.yesexpr = NULL;
+ loc->lc_messages.noexpr = NULL;
+ }
+
+ return (char*)name;
+}
diff --git a/src/nonstd/ctype-internal.ref b/src/nonstd/ctype-internal.ref
new file mode 100644
index 00000000..3412e61c
--- /dev/null
+++ b/src/nonstd/ctype-internal.ref
@@ -0,0 +1,2 @@
+#include <nonstd/ctype.h>
+REFERENCE(<nonstd/internal.h>)
diff --git a/src/nonstd/ctype_t.c b/src/nonstd/ctype_t.c
index 468214b1..dad5568f 100644
--- a/src/nonstd/ctype_t.c
+++ b/src/nonstd/ctype_t.c
@@ -1,15 +1,15 @@
#include <nonstd/ctype.h>
typedef enum {
- ALPHA = (1 << 0),
- CNTRL = (1 << 1),
- DIGIT = (1 << 2),
- GRAPH = (1 << 3),
- LOWER = (1 << 4),
- PRINT = (1 << 5),
- PUNCT = (1 << 6),
- SPACE = (1 << 7),
- UPPER = (1 << 8),
- XDIGIT = (1 << 9),
- BLANK = (1 << 10),
+ CT_ALPHA = (1 << 0),
+ CT_CNTRL = (1 << 1),
+ CT_DIGIT = (1 << 2),
+ CT_GRAPH = (1 << 3),
+ CT_LOWER = (1 << 4),
+ CT_PRINT = (1 << 5),
+ CT_PUNCT = (1 << 6),
+ CT_SPACE = (1 << 7),
+ CT_UPPER = (1 << 8),
+ CT_XDIGIT = (1 << 9),
+ CT_BLANK = (1 << 10),
} ctype_t;
diff --git a/src/nonstd/io-internal.ref b/src/nonstd/io-internal.ref
new file mode 100644
index 00000000..4c06d2f9
--- /dev/null
+++ b/src/nonstd/io-internal.ref
@@ -0,0 +1,2 @@
+#include <nonstd/io.h>
+REFERENCE(<nonstd/internal.h>)
diff --git a/src/nonstd/lib-internal.ref b/src/nonstd/lib-internal.ref
new file mode 100644
index 00000000..3361d2f6
--- /dev/null
+++ b/src/nonstd/lib-internal.ref
@@ -0,0 +1,2 @@
+#include <nonstd/lib.h>
+REFERENCE(<nonstd/internal.h>)
diff --git a/src/nonstd/locale-internal.ref b/src/nonstd/locale-internal.ref
new file mode 100644
index 00000000..d795ee8f
--- /dev/null
+++ b/src/nonstd/locale-internal.ref
@@ -0,0 +1,2 @@
+#include <nonstd/locale.h>
+REFERENCE(<nonstd/internal.h>)
diff --git a/src/nonstd/locale-limits.ref b/src/nonstd/locale-limits.ref
new file mode 100644
index 00000000..705296b4
--- /dev/null
+++ b/src/nonstd/locale-limits.ref
@@ -0,0 +1,2 @@
+#include <nonstd/locale.h>
+REFERENCE(<limits.h>)
diff --git a/src/nonstd/locale-locale.ref b/src/nonstd/locale-locale.ref
new file mode 100644
index 00000000..98478b9f
--- /dev/null
+++ b/src/nonstd/locale-locale.ref
@@ -0,0 +1,2 @@
+#include <nonstd/locale.h>
+REFERENCE(<locale.h>)
diff --git a/src/nonstd/struct_locale_t.c b/src/nonstd/struct_locale_t.c
index 1981bd8d..1bc8e932 100644
--- a/src/nonstd/struct_locale_t.c
+++ b/src/nonstd/struct_locale_t.c
@@ -1,22 +1,31 @@
#include <nonstd/locale.h>
struct __locale_t {
- int mask;
- char *all;
- char *collate;
- unsigned char *collation;
- char *ctype;
- unsigned char *ctattr;
- unsigned char *ctoupper;
- unsigned char *ctolower;
- char *message;
+ char all[UCHAR_MAX];
+
+ char ctype[UCHAR_MAX];
+ struct {
+ unsigned int ctattr[UCHAR_MAX + 1];
+ unsigned char ctoupper[UCHAR_MAX + 1];
+ unsigned char ctolower[UCHAR_MAX + 1];
+ } lc_ctype;
+
+ char collate[UCHAR_MAX];
+ struct collation {
+ char * sequence;
+ int weight;
+ } *lc_collate;
+
+ char messages[UCHAR_MAX];
struct {
char *yesexpr;
char *noexpr;
} lc_messages;
+
char *monetary;
char *numeric;
struct lconv mn;
+
char *time;
struct {
char *abday[7];
diff --git a/src/nonstd/nonstd-inernal.ref b/src/nonstd/syscall-internal.ref
index 839537f1..839537f1 100644
--- a/src/nonstd/nonstd-inernal.ref
+++ b/src/nonstd/syscall-internal.ref