diff options
author | Joseph Huber <jhuber6@vols.utk.edu> | 2023-07-19 19:10:30 -0500 |
---|---|---|
committer | Joseph Huber <jhuber6@vols.utk.edu> | 2023-07-20 08:11:19 -0500 |
commit | ed7ade9cfa56acae3c67bdf837dec05555769e3c (patch) | |
tree | 7c92992767bbdbf6df009a804875b2cd807861f8 /libc | |
parent | cc92212d75dff07644e478c55a6f145c020f6f8e (diff) | |
download | llvm-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.cpp | 17 | ||||
-rw-r--r-- | libc/src/unistd/getopt.h | 2 | ||||
-rw-r--r-- | libc/test/src/unistd/getopt_test.cpp | 2 |
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 |