From 575aedc3bf08711f30db5ba545007517abdaf02a Mon Sep 17 00:00:00 2001 From: Isaac Andrade Date: Fri, 30 Aug 2024 19:45:56 -0600 Subject: [PATCH] Implement POSIX support for Linux for the following facilities: - fnmatch - grp - langinfo - locale --- core/sys/posix/fnmatch.odin | 8 ++ core/sys/posix/glob.odin | 36 ++++++- core/sys/posix/grp.odin | 2 +- core/sys/posix/langinfo.odin | 181 ++++++++++++++++++++++++++++++++++- core/sys/posix/locale.odin | 38 ++++++++ 5 files changed, 260 insertions(+), 5 deletions(-) diff --git a/core/sys/posix/fnmatch.odin b/core/sys/posix/fnmatch.odin index 9e54972e7..1326ce9e4 100644 --- a/core/sys/posix/fnmatch.odin +++ b/core/sys/posix/fnmatch.odin @@ -53,6 +53,14 @@ when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS FNM_PERIOD :: 0x04 FNM_NOESCAPE :: 0x01 +} else when ODIN_OS == .Linux { + + FNM_NOMATCH :: 1 + + FNM_PATHNAME :: 0x01 + FNM_NOESCAPE :: 0x02 + FNM_PERIOD :: 0x04 + } else { #panic("posix is unimplemented for the current target") } diff --git a/core/sys/posix/glob.odin b/core/sys/posix/glob.odin index 4f41d83db..b09104900 100644 --- a/core/sys/posix/glob.odin +++ b/core/sys/posix/glob.odin @@ -112,7 +112,7 @@ when ODIN_OS == .Darwin { glob_t :: struct { gl_pathc: c.size_t, /* [PSX] count of paths matched by pattern */ - gl_matchc: c.size_t, /* count of paths matching pattern */ + gl_matchc: c.size_t, /* count of paths matching pattern */ gl_offs: c.size_t, /* [PSX] slots to reserve at the beginning of gl_pathv */ gl_flags: Glob_Flags, /* copy of flags parameter to glob */ gl_pathv: [^]cstring `fmt:"v,gl_pathc"`, /* [PSX] pointer to list of matched pathnames */ @@ -144,7 +144,7 @@ when ODIN_OS == .Darwin { glob_t :: struct { gl_pathc: c.size_t, /* [PSX] count of paths matched by pattern */ - gl_matchc: c.size_t, /* count of paths matching pattern */ + gl_matchc: c.size_t, /* count of paths matching pattern */ gl_offs: c.size_t, /* [PSX] slots to reserve at the beginning of gl_pathv */ gl_flags: Glob_Flags, /* copy of flags parameter to glob */ gl_pathv: [^]cstring `fmt:"v,gl_pathc"`, /* [PSX] pointer to list of matched pathnames */ @@ -174,6 +174,38 @@ when ODIN_OS == .Darwin { GLOB_NOMATCH :: -3 GLOB_NOSPACE :: -1 +} else when ODIN_OS == .Linux { + + glob_t :: struct { + gl_pathc: c.size_t, /* [PSX] count of paths matched by pattern */ + gl_matchc: c.size_t, /* count of paths matching pattern */ + gl_offs: c.size_t, /* [PSX] slots to reserve at the beginning of gl_pathv */ + gl_flags: Glob_Flags, /* copy of flags parameter to glob */ + gl_pathv: [^]cstring `fmt:"v,gl_pathc"`, /* [PSX] pointer to list of matched pathnames */ + + // Non-standard alternate file system access functions: + + gl_errfunc: proc "c" (cstring, c.int) -> c.int, + + gl_closedir: proc "c" (dirp: DIR), + gl_readdir: proc "c" (dirp: DIR) -> ^dirent, + gl_opendir: proc "c" (path: cstring) -> DIR, + gl_lstat: proc "c" (path: cstring, buf: ^stat_t) -> result, + gl_stat: proc "c" (path: cstring, buf: ^stat_t) -> result, + } + + GLOB_ERR :: 1 << 0 + GLOB_MARK :: 1 << 1 + GLOB_NOSORT :: 1 << 2 + GLOB_DOOFFS :: 1 << 3 + GLOB_NOCHECK :: 1 << 4 + GLOB_APPEND :: 1 << 5 + GLOB_NOESCAPE :: 1 << 6 + + GLOB_NOSPACE :: 1 + GLOB_ABORTED :: 2 + GLOB_NOMATCH :: 3 + } else { #panic("posix is unimplemented for the current target") } diff --git a/core/sys/posix/grp.odin b/core/sys/posix/grp.odin index c8a39de6a..3a78e2c4c 100644 --- a/core/sys/posix/grp.odin +++ b/core/sys/posix/grp.odin @@ -114,7 +114,7 @@ foreign lib { getgrnam_r :: proc(name: cstring, grp: ^group, buffer: [^]byte, bufsize: c.size_t, result: ^^group) -> Errno --- } -when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS == .OpenBSD { +when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS == .OpenBSD || ODIN_OS == .Linux { gid_t :: distinct c.uint32_t diff --git a/core/sys/posix/langinfo.odin b/core/sys/posix/langinfo.odin index 24ecc917a..ffb83730c 100644 --- a/core/sys/posix/langinfo.odin +++ b/core/sys/posix/langinfo.odin @@ -238,7 +238,7 @@ when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD { ABDAY_4 :: 16 ABDAY_5 :: 17 ABDAY_6 :: 18 - ABDAY_7 :: 19 + ABDAY_7 :: 19 MON_1 :: 20 MON_2 :: 21 @@ -278,7 +278,184 @@ when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD { YESEXPR :: 47 NOEXPR :: 49 - CRNCYSTR :: 50 + CRNCYSTR :: 50 + +} else when ODIN_OS == .Linux { + + @(private="file") + nl_item :: proc(flag: int) -> int { + return flag << 16 + } + + @(private="file") + _langinfo_values :: enum { + ABDAY_1 = nl_item(LC_TIME), + ABDAY_2, + ABDAY_3, + ABDAY_4, + ABDAY_5, + ABDAY_6, + ABDAY_7, + + DAY_1, + DAY_2, + DAY_3, + DAY_4, + DAY_5, + DAY_6, + DAY_7, + + ABMON_1, + ABMON_2, + ABMON_3, + ABMON_4, + ABMON_5, + ABMON_6, + ABMON_7, + ABMON_8, + ABMON_9, + ABMON_10, + ABMON_11, + ABMON_12, + + MON_1, + MON_2, + MON_3, + MON_4, + MON_5, + MON_6, + MON_7, + MON_8, + MON_9, + MON_10, + MON_11, + MON_12, + + AM_STR, + PM_STR, + + D_T_FMT, + D_FMT, + T_FMT, + T_FMT_AMPM, + + ERA, + _, + ERA_D_FMT, + ALT_DIGITS, + ERA_D_T_FMT, + ERA_T_FMT, + + // These values are defined only to make sure CODESET below gets the correct value. + _NL_CTYPE_CLASS = nl_item(LC_CTYPE), + _NL_CTYPE_TOUPPER, + _NL_CTYPE_GAP1, + _NL_CTYPE_TOLOWER, + _NL_CTYPE_GAP2, + _NL_CTYPE_CLASS32, + _NL_CTYPE_GAP3, + _NL_CTYPE_GAP4, + _NL_CTYPE_GAP5, + _NL_CTYPE_GAP6, + _NL_CTYPE_CLASS_NAMES, + _NL_CTYPE_MAP_NAMES, + _NL_CTYPE_WIDTH, + _NL_CTYPE_MB_CUR_MAX, + CODESET, + + // These values are defined only to make sure CRNCYSTR below gets the correct value. + __INT_CURR_SYMBOL = nl_item(LC_MONETARY), + __CURRENCY_SYMBOL, + __MON_DECIMAL_POINT, + __MON_THOUSANDS_SEP, + __MON_GROUPING, + __POSITIVE_SIGN, + __NEGATIVE_SIGN, + __INT_FRAC_DIGITS, + __FRAC_DIGITS, + __P_CS_PRECEDES, + __P_SEP_BY_SPACE, + __N_CS_PRECEDES, + __N_SEP_BY_SPACE, + __P_SIGN_POSN, + __N_SIGN_POSN, + CRNCYSTR, + + RADIXCHAR = nl_item(LC_NUMERIC), + THOUSEP, + + YESEXPR = nl_item(LC_MESSAGES), + NOEXPR, + } + +// NOTE: declared with `_t` so we can enumerate the real `nl_info`. + nl_item_t :: distinct c.int + + ABDAY_1 :: _langinfo_values.ABDAY_1 + ABDAY_2 :: _langinfo_values.ABDAY_2 + ABDAY_3 :: _langinfo_values.ABDAY_3 + ABDAY_4 :: _langinfo_values.ABDAY_4 + ABDAY_5 :: _langinfo_values.ABDAY_5 + ABDAY_6 :: _langinfo_values.ABDAY_6 + ABDAY_7 :: _langinfo_values.ABDAY_7 + + DAY_1 :: _langinfo_values.DAY_1 + DAY_2 :: _langinfo_values.DAY_2 + DAY_3 :: _langinfo_values.DAY_3 + DAY_4 :: _langinfo_values.DAY_4 + DAY_5 :: _langinfo_values.DAY_5 + DAY_6 :: _langinfo_values.DAY_6 + DAY_7 :: _langinfo_values.DAY_7 + + ABMON_1 :: _langinfo_values.ABMON_1 + ABMON_2 :: _langinfo_values.ABMON_2 + ABMON_3 :: _langinfo_values.ABMON_3 + ABMON_4 :: _langinfo_values.ABMON_4 + ABMON_5 :: _langinfo_values.ABMON_5 + ABMON_6 :: _langinfo_values.ABMON_6 + ABMON_7 :: _langinfo_values.ABMON_7 + ABMON_8 :: _langinfo_values.ABMON_8 + ABMON_9 :: _langinfo_values.ABMON_9 + ABMON_10 :: _langinfo_values.ABMON_10 + ABMON_11 :: _langinfo_values.ABMON_11 + ABMON_12 :: _langinfo_values.ABMON_12 + + MON_1 :: _langinfo_values.MON_1 + MON_2 :: _langinfo_values.MON_2 + MON_3 :: _langinfo_values.MON_3 + MON_4 :: _langinfo_values.MON_4 + MON_5 :: _langinfo_values.MON_5 + MON_6 :: _langinfo_values.MON_6 + MON_7 :: _langinfo_values.MON_7 + MON_8 :: _langinfo_values.MON_8 + MON_9 :: _langinfo_values.MON_9 + MON_10 :: _langinfo_values.MON_10 + MON_11 :: _langinfo_values.MON_11 + MON_12 :: _langinfo_values.MON_12 + + AM_STR :: _langinfo_values.AM_STR + PM_STR :: _langinfo_values.PM_STR + + D_T_FMT :: _langinfo_values.D_T_FMT + D_FMT :: _langinfo_values.D_FMT + T_FMT :: _langinfo_values.T_FMT + T_FMT_AMPM :: _langinfo_values.T_FMT_AMPM + + ERA :: _langinfo_values.ERA + ERA_D_FMT :: _langinfo_values.ERA_D_FMT + ALT_DIGITS :: _langinfo_values.ALT_DIGITS + ERA_D_T_FMT :: _langinfo_values.ERA_D_T_FMT + ERA_T_FMT :: _langinfo_values.ERA_T_FMT + + CODESET :: _langinfo_values.CODESET + + CRNCYSTR :: _langinfo_values.CRNCYSTR + + RADIXCHAR :: _langinfo_values.RADIXCHAR + THOUSEP :: _langinfo_values.THOUSEP + + YESEXP :: _langinfo_values.YESEXP + NOEXPR :: _langinfo_values.NOEXPR } else { #panic("posix is unimplemented for the current target") diff --git a/core/sys/posix/locale.odin b/core/sys/posix/locale.odin index 1f2a336b5..fae692bcb 100644 --- a/core/sys/posix/locale.odin +++ b/core/sys/posix/locale.odin @@ -88,6 +88,44 @@ when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS LC_NUMERIC :: 4 LC_TIME :: 5 +} else when ODIN_OS == .Linux { + + // NOTE: All of these fields are standard ([PSX]). + lconv :: struct { + decimal_point: cstring, + thousand_sep: cstring, + grouping: cstring, + int_curr_symbol: cstring, + currency_symbol: cstring, + mon_decimal_points: cstring, + mon_thousands_sep: cstring, + mon_grouping: cstring, + positive_sign: cstring, + negative_sign: cstring, + int_frac_digits: c.char, + frac_digits: c.char, + p_cs_precedes: c.char, + p_sep_by_space: c.char, + n_cs_precedes: c.char, + n_sep_by_space: c.char, + p_sign_posn: c.char, + n_sign_posn: c.char, + int_p_cs_precedes: c.char, + int_n_cs_precedes: c.char, + int_p_sep_by_space: c.char, + int_n_sep_by_space: c.char, + int_p_sign_posn: c.char, + int_n_sign_posn: c.char, + } + + LC_CTYPE :: 0 + LC_NUMERIC :: 1 + LC_TIME :: 2 + LC_COLLATE :: 3 + LC_MONETARY :: 4 + LC_MESSAGES :: 5 + LC_ALL :: 6 + } else { #panic("posix is unimplemented for the current target") }