aboutsummaryrefslogtreecommitdiff
path: root/libc
diff options
context:
space:
mode:
authorJoseph Huber <jhuber6@vols.utk.edu>2023-07-19 19:10:30 -0500
committerJoseph Huber <jhuber6@vols.utk.edu>2023-07-20 08:11:19 -0500
commited7ade9cfa56acae3c67bdf837dec05555769e3c (patch)
tree7c92992767bbdbf6df009a804875b2cd807861f8 /libc
parentcc92212d75dff07644e478c55a6f145c020f6f8e (diff)
downloadllvm-ed7ade9cfa56acae3c67bdf837dec05555769e3c.zip
llvm-ed7ade9cfa56acae3c67bdf837dec05555769e3c.tar.gz
llvm-ed7ade9cfa56acae3c67bdf837dec05555769e3c.tar.bz2
[libc] Remove global constructor in `getopt` implementation
This file required a global constructor due to copying the file stream and have a non-constexpr constructor for the wrapper type. Also, I changes the `opterr` to be a pointer, because it seemed like it wasn't being set correctly as an externally visibile variable if we just captured it by value. Reviewed By: abrachet Differential Revision: https://reviews.llvm.org/D155766
Diffstat (limited to 'libc')
-rw-r--r--libc/src/unistd/getopt.cpp17
-rw-r--r--libc/src/unistd/getopt.h2
-rw-r--r--libc/test/src/unistd/getopt_test.cpp2
3 files changed, 9 insertions, 12 deletions
diff --git a/libc/src/unistd/getopt.cpp b/libc/src/unistd/getopt.cpp
index 4c6aaf6..70ca454 100644
--- a/libc/src/unistd/getopt.cpp
+++ b/libc/src/unistd/getopt.cpp
@@ -22,7 +22,6 @@
namespace __llvm_libc {
template <typename T> struct RefWrapper {
- RefWrapper(T *ptr) : ptr(ptr) {}
RefWrapper &operator=(const RefWrapper &) = default;
operator T &() { return *ptr; }
T &get() { return *ptr; }
@@ -35,7 +34,7 @@ struct GetoptContext {
RefWrapper<int> optopt;
RefWrapper<unsigned> optpos;
- int opterr;
+ RefWrapper<int> opterr;
FILE *errstream;
@@ -43,7 +42,9 @@ struct GetoptContext {
template <typename... Ts> void report_error(const char *fmt, Ts... ts) {
if (opterr)
- __llvm_libc::fprintf(errstream, fmt, ts...);
+ __llvm_libc::fprintf(
+ errstream ? errstream : reinterpret_cast<FILE *>(__llvm_libc::stderr),
+ fmt, ts...);
}
};
@@ -171,25 +172,21 @@ int getopt_r(int argc, char *const argv[], const char *optstring,
namespace impl {
extern "C" {
-
char *optarg = nullptr;
int optind = 1;
int optopt = 0;
int opterr = 0;
-
}
static unsigned optpos;
-static GetoptContext ctx{
- &impl::optarg, &impl::optind,
- &impl::optopt, &optpos,
- impl::opterr, reinterpret_cast<FILE *>(__llvm_libc::stderr)};
+static GetoptContext ctx{&impl::optarg, &impl::optind, &impl::optopt,
+ &optpos, &impl::opterr, /*errstream=*/nullptr};
#ifndef LIBC_COPT_PUBLIC_PACKAGING
// This is used exclusively in tests.
void set_getopt_state(char **optarg, int *optind, int *optopt, unsigned *optpos,
- int opterr, FILE *errstream) {
+ int *opterr, FILE *errstream) {
ctx = {optarg, optind, optopt, optpos, opterr, errstream};
}
#endif
diff --git a/libc/src/unistd/getopt.h b/libc/src/unistd/getopt.h
index bf5f8d0..0bc7ed6 100644
--- a/libc/src/unistd/getopt.h
+++ b/libc/src/unistd/getopt.h
@@ -15,7 +15,7 @@
namespace __llvm_libc {
namespace impl {
-void set_getopt_state(char **, int *, int *, unsigned *, int, FILE *);
+void set_getopt_state(char **, int *, int *, unsigned *, int *, FILE *);
}
int getopt(int argc, char *const argv[], const char *optstring);
diff --git a/libc/test/src/unistd/getopt_test.cpp b/libc/test/src/unistd/getopt_test.cpp
index b90ea64..546138a 100644
--- a/libc/test/src/unistd/getopt_test.cpp
+++ b/libc/test/src/unistd/getopt_test.cpp
@@ -31,7 +31,7 @@ unsigned optpos;
void set_state(FILE *errstream) {
__llvm_libc::impl::set_getopt_state(
&test_globals::optarg, &test_globals::optind, &test_globals::optopt,
- &test_globals::optpos, test_globals::opterr, errstream);
+ &test_globals::optpos, &test_globals::opterr, errstream);
}
// TODO: <stdio> could be either llvm-libc's or the system libc's. The former