From d7a0ce2f7c9b77d43d9126f2cd77173447afce69 Mon Sep 17 00:00:00 2001
From: Andre Maroneze <andre.maroneze@cea.fr>
Date: Tue, 31 Aug 2021 17:16:34 +0200
Subject: [PATCH] [Libc] add langinfo.h; add definitions to improve non-POSIX
 compatibility

---
 headers/header_spec.txt           |   2 +
 share/libc/__fc_define_locale_t.h |  36 +++++++
 share/libc/__fc_libc.h            |   1 +
 share/libc/fcntl.h                |   3 +
 share/libc/langinfo.h             | 163 ++++++++++++++++++++++++++++++
 share/libc/locale.h               |   7 +-
 share/libc/regex.h                |  12 ++-
 share/libc/sys/stat.h             |  15 +++
 share/libc/sys/types.h            |  10 +-
 share/libc/sys/wait.h             |   3 +
 tests/libc/fc_libc.c              |   2 +
 11 files changed, 247 insertions(+), 7 deletions(-)
 create mode 100644 share/libc/__fc_define_locale_t.h
 create mode 100644 share/libc/langinfo.h

diff --git a/headers/header_spec.txt b/headers/header_spec.txt
index f2b7746849a..081be10cddc 100644
--- a/headers/header_spec.txt
+++ b/headers/header_spec.txt
@@ -190,6 +190,7 @@ share/libc/__fc_define_ino_t.h: CEA_LGPL
 share/libc/__fc_define_intptr_t.h: CEA_LGPL
 share/libc/__fc_define_iovec.h: CEA_LGPL
 share/libc/__fc_define_key_t.h: CEA_LGPL
+share/libc/__fc_define_locale_t.h: CEA_LGPL
 share/libc/__fc_define_max_open_files.h: CEA_LGPL
 share/libc/__fc_define_mode_t.h: CEA_LGPL
 share/libc/__fc_define_nlink_t.h: CEA_LGPL
@@ -254,6 +255,7 @@ share/libc/ifaddrs.h: CEA_LGPL
 share/libc/inttypes.c: CEA_LGPL
 share/libc/inttypes.h: CEA_LGPL
 share/libc/iso646.h: CEA_LGPL
+share/libc/langinfo.h: CEA_LGPL
 share/libc/libgen.h: CEA_LGPL
 share/libc/limits.h: CEA_LGPL
 share/libc/locale.c: CEA_LGPL
diff --git a/share/libc/__fc_define_locale_t.h b/share/libc/__fc_define_locale_t.h
new file mode 100644
index 00000000000..68e4db7e6d5
--- /dev/null
+++ b/share/libc/__fc_define_locale_t.h
@@ -0,0 +1,36 @@
+/**************************************************************************/
+/*                                                                        */
+/*  This file is part of Frama-C.                                         */
+/*                                                                        */
+/*  Copyright (C) 2007-2021                                               */
+/*    CEA (Commissariat à l'énergie atomique et aux énergies              */
+/*         alternatives)                                                  */
+/*                                                                        */
+/*  you can redistribute it and/or modify it under the terms of the GNU   */
+/*  Lesser General Public License as published by the Free Software       */
+/*  Foundation, version 2.1.                                              */
+/*                                                                        */
+/*  It is distributed in the hope that it will be useful,                 */
+/*  but WITHOUT ANY WARRANTY; without even the implied warranty of        */
+/*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         */
+/*  GNU Lesser General Public License for more details.                   */
+/*                                                                        */
+/*  See the GNU Lesser General Public License version 2.1                 */
+/*  for more details (enclosed in the file licenses/LGPLv2.1).            */
+/*                                                                        */
+/**************************************************************************/
+
+#ifndef __FC_DEFINE_LOCALE_T
+#define __FC_DEFINE_LOCALE_T
+#include "features.h"
+__PUSH_FC_STDLIB
+__BEGIN_DECLS
+struct __fc_locale_struct
+{
+  const char *names[13];
+};
+
+typedef struct __fc_locale_struct *locale_t;
+__END_DECLS
+__POP_FC_STDLIB
+#endif
diff --git a/share/libc/__fc_libc.h b/share/libc/__fc_libc.h
index 310a2148445..3e710e9cec5 100644
--- a/share/libc/__fc_libc.h
+++ b/share/libc/__fc_libc.h
@@ -51,6 +51,7 @@
 #include "ifaddrs.h"
 #include "inttypes.h"
 #include "iso646.h"
+#include "langinfo.h"
 #include "libgen.h"
 #include "limits.h"
 #include "locale.h"
diff --git a/share/libc/fcntl.h b/share/libc/fcntl.h
index 2fb91da8e75..7ef658186f9 100644
--- a/share/libc/fcntl.h
+++ b/share/libc/fcntl.h
@@ -63,6 +63,9 @@ __PUSH_FC_STDLIB
 #define O_TRUNC 0x200
 //#define O_TTY_INIT
 
+// Non-POSIX
+#define O_DIRECT 0x4000
+
 #define O_APPEND 0x400
 #define O_DSYNC 0x1000
 #define O_NONBLOCK 0x800
diff --git a/share/libc/langinfo.h b/share/libc/langinfo.h
new file mode 100644
index 00000000000..02ba80f8dd4
--- /dev/null
+++ b/share/libc/langinfo.h
@@ -0,0 +1,163 @@
+/**************************************************************************/
+/*                                                                        */
+/*  This file is part of Frama-C.                                         */
+/*                                                                        */
+/*  Copyright (C) 2007-2021                                               */
+/*    CEA (Commissariat à l'énergie atomique et aux énergies              */
+/*         alternatives)                                                  */
+/*                                                                        */
+/*  you can redistribute it and/or modify it under the terms of the GNU   */
+/*  Lesser General Public License as published by the Free Software       */
+/*  Foundation, version 2.1.                                              */
+/*                                                                        */
+/*  It is distributed in the hope that it will be useful,                 */
+/*  but WITHOUT ANY WARRANTY; without even the implied warranty of        */
+/*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         */
+/*  GNU Lesser General Public License for more details.                   */
+/*                                                                        */
+/*  See the GNU Lesser General Public License version 2.1                 */
+/*  for more details (enclosed in the file licenses/LGPLv2.1).            */
+/*                                                                        */
+/**************************************************************************/
+
+#ifndef __FC_LANGINFO_H
+#define __FC_LANGINFO_H
+#include "features.h"
+__PUSH_FC_STDLIB
+#include "__fc_define_locale_t.h"
+#include "nl_types.h"
+#include "locale.h" // for LC_CTYPE and other constants
+__BEGIN_DECLS
+
+
+#define _NL_ITEM(category, index)	(((category) << 16) | (index))
+
+/* Extract the category and item index from a constructed `nl_item' value.  */
+#define _NL_ITEM_CATEGORY(item)		((int) (item) >> 16)
+#define _NL_ITEM_INDEX(item)		((int) (item) & 0xffff)
+
+enum
+{
+  CODESET = (LC_CTYPE) << 16,
+#define CODESET CODESET
+  ABDAY_1 = (LC_TIME) << 16,
+#define ABDAY_1 ABDAY_1
+  ABDAY_2,
+#define ABDAY_2 ABDAY_2
+  ABDAY_3,
+#define ABDAY_3 ABDAY_3
+  ABDAY_4,
+#define ABDAY_4 ABDAY_4
+  ABDAY_5,
+#define ABDAY_5 ABDAY_5
+  ABDAY_6,
+#define ABDAY_6 ABDAY_6
+  ABDAY_7,
+#define ABDAY_7 ABDAY_7
+  DAY_1,
+#define DAY_1 DAY_1
+  DAY_2,
+#define DAY_2 DAY_2
+  DAY_3,
+#define DAY_3 DAY_3
+  DAY_4,
+#define DAY_4 DAY_4
+  DAY_5,
+#define DAY_5 DAY_5
+  DAY_6,
+#define DAY_6 DAY_6
+  DAY_7,
+#define DAY_7 DAY_7
+  ABMON_1,
+#define ABMON_1 ABMON_1
+  ABMON_2,
+#define ABMON_2 ABMON_2
+  ABMON_3,
+#define ABMON_3 ABMON_3
+  ABMON_4,
+#define ABMON_4 ABMON_4
+  ABMON_5,
+#define ABMON_5 ABMON_5
+  ABMON_6,
+#define ABMON_6 ABMON_6
+  ABMON_7,
+#define ABMON_7 ABMON_7
+  ABMON_8,
+#define ABMON_8 ABMON_8
+  ABMON_9,
+#define ABMON_9 ABMON_9
+  ABMON_10,
+#define ABMON_10 ABMON_10
+  ABMON_11,
+#define ABMON_11 ABMON_11
+  ABMON_12,
+#define ABMON_12 ABMON_12
+  MON_1,
+#define MON_1 MON_1
+  MON_2,
+#define MON_2 MON_2
+  MON_3,
+#define MON_3 MON_3
+  MON_4,
+#define MON_4 MON_4
+  MON_5,
+#define MON_5 MON_5
+  MON_6,
+#define MON_6 MON_6
+  MON_7,
+#define MON_7 MON_7
+  MON_8,
+#define MON_8 MON_8
+  MON_9,
+#define MON_9 MON_9
+  MON_10,
+#define MON_10 MON_10
+  MON_11,
+#define MON_11 MON_11
+  MON_12,
+#define MON_12 MON_12
+  AM_STR,
+#define AM_STR AM_STR
+  PM_STR,
+#define PM_STR PM_STR
+  D_T_FMT,
+#define D_T_FMT D_T_FMT
+  D_FMT,
+#define D_FMT D_FMT
+  T_FMT,
+#define T_FMT T_FMT
+  T_FMT_AMPM,
+#define T_FMT_AMPM T_FMT_AMPM
+  ERA,
+#define ERA ERA
+  ERA_YEAR, // Non-POSIX; GNU
+#define ERA_YEAR ERA_YEAR
+  ERA_D_FMT,
+#define ERA_D_FMT ERA_D_FMT
+  ALT_DIGITS,
+#define ALT_DIGITS ALT_DIGITS
+  ERA_D_T_FMT,
+#define ERA_D_T_FMT ERA_D_T_FMT
+  ERA_T_FMT,
+#define ERA_T_FMT ERA_T_FMT
+  DECIMAL_POINT = (LC_NUMERIC) << 16, // Non-POSIX; GNU
+#define DECIMAL_POINT DECIMAL_POINT
+  RADIXCHAR,
+#define RADIXCHAR RADIXCHAR
+  THOUSEP,
+#define THOUSEP THOUSEP
+  YESEXPR = (LC_MESSAGES) << 16,
+#define YESEXPR YESEXPR
+  NOEXPR,
+#define NOEXPR NOEXPR
+  CRNCYSTR = (LC_MONETARY) << 16,
+#define CRNCYSTR CRNCYSTR
+};
+
+extern char *nl_langinfo(nl_item item);
+extern char *nl_langinfo_l(nl_item item, locale_t locale);
+
+__END_DECLS
+
+__POP_FC_STDLIB
+#endif
diff --git a/share/libc/locale.h b/share/libc/locale.h
index ca23603228d..04b0e75495c 100644
--- a/share/libc/locale.h
+++ b/share/libc/locale.h
@@ -24,7 +24,7 @@
 #define __FC_LOCALE
 #include "features.h"
 __PUSH_FC_STDLIB
-
+#include "__fc_define_locale_t.h"
 __BEGIN_DECLS
 
 /* Structure giving information about numeric and monetary notation.  */
@@ -149,6 +149,11 @@ extern char *setlocale(int category, const char *locale);
 */
 extern struct lconv *localeconv(void);
 
+extern locale_t duplocale(locale_t);
+extern void freelocale(locale_t);
+extern locale_t newlocale(int, const char *, locale_t);
+extern locale_t uselocale(locale_t);
+
 __END_DECLS
 
 __POP_FC_STDLIB
diff --git a/share/libc/regex.h b/share/libc/regex.h
index c2bdf2b4251..ac0bb089414 100644
--- a/share/libc/regex.h
+++ b/share/libc/regex.h
@@ -25,7 +25,7 @@
 #include "features.h"
 __PUSH_FC_STDLIB
 #include "__fc_define_size_t.h"
-
+#include "__fc_define_ssize_t.h"
 __BEGIN_DECLS
 
 struct re_pattern_buffer { size_t re_nsub;  };
@@ -64,7 +64,15 @@ typedef enum __fc_reg_errcode_t
   REG_ERPAREN	  
 } reg_errcode_t;
 
-typedef int regoff_t;
+typedef ssize_t regoff_t;
+
+// Non-POSIX
+struct re_registers
+{
+  size_t num_regs;
+  regoff_t *start;
+  regoff_t *end;
+};
 
 typedef struct __fc_regmatch_t
 {
diff --git a/share/libc/sys/stat.h b/share/libc/sys/stat.h
index 190c944be82..af9b9e59d2d 100644
--- a/share/libc/sys/stat.h
+++ b/share/libc/sys/stat.h
@@ -104,6 +104,21 @@ extern mode_t umask(mode_t cmask);
 #define S_TYPEISSHM(buf) ((buf)->st_mode - (buf)->st_mode)
 #define S_TYPEISTMO(buf) (0)
 
+// Non-POSIX; Linux-specific
+#define S_IRWXUGO       (S_IRWXU|S_IRWXG|S_IRWXO)
+#define S_IALLUGO       (S_ISUID|S_ISGID|S_ISVTX|S_IRWXUGO)
+#define S_IRUGO         (S_IRUSR|S_IRGRP|S_IROTH)
+#define S_IWUGO         (S_IWUSR|S_IWGRP|S_IWOTH)
+#define S_IXUGO         (S_IXUSR|S_IXGRP|S_IXOTH)
+
+// Non-POSIX
+#define S_IFDOOR 0
+#define S_ISDOOR(m) 0
+
+// Non-POSIX
+#define UTIME_NOW ((1L << 30) - 1L)
+#define UTIME_OMIT ((1L << 30) - 2L)
+
 __END_DECLS
 __POP_FC_STDLIB
 #endif
diff --git a/share/libc/sys/types.h b/share/libc/sys/types.h
index d540a3b9df7..929f09a019c 100644
--- a/share/libc/sys/types.h
+++ b/share/libc/sys/types.h
@@ -50,10 +50,12 @@ typedef unsigned int u_int;
 typedef unsigned short u_short;
 typedef unsigned char u_char;
 
-// Note: makedev (non-POSIX) is usually a macro; in case of problems,
-// consider redefining this.
-/*@ assigns \result \from maj, min; */
-extern dev_t makedev(int maj, int min);
+// The macros below are non-POSIX; the definitions below should allow
+// parsing coreutils.
+# define major(dev)  (((dev) >> 8) & 0xff)
+# define minor(dev)  ((dev) & 0xff)
+# define makedev(maj, min)  (((maj) << 8) | (min))
+
 #define __u_char_defined
 #endif
 
diff --git a/share/libc/sys/wait.h b/share/libc/sys/wait.h
index df14c934bc7..37ea46dc9ec 100644
--- a/share/libc/sys/wait.h
+++ b/share/libc/sys/wait.h
@@ -45,6 +45,9 @@ __BEGIN_DECLS
 #define WNOWAIT 0x01000000
 #define WSTOPPED 2
 
+// Non-POSIX
+#define WCOREDUMP(status) ((status) & 0x80)
+
 #include "../__fc_define_id_t.h"
 #include "../__fc_define_pid_t.h"
 #include "../__fc_define_uid_and_gid.h"
diff --git a/tests/libc/fc_libc.c b/tests/libc/fc_libc.c
index 23ce1d6fe4b..89e599df66e 100644
--- a/tests/libc/fc_libc.c
+++ b/tests/libc/fc_libc.c
@@ -53,6 +53,7 @@
 #include "__fc_define_intptr_t.h"
 #include "__fc_define_iovec.h"
 #include "__fc_define_key_t.h"
+#include "__fc_define_locale_t.h"
 #include "__fc_define_max_open_files.h"
 #include "__fc_define_mode_t.h"
 #include "__fc_define_nlink_t.h"
@@ -97,6 +98,7 @@
 #include "ifaddrs.h"
 #include "inttypes.h"
 #include "iso646.h"
+#include "langinfo.h"
 #include "libgen.h"
 #include "limits.h"
 #include "locale.h"
-- 
GitLab