Skip to content

Commit ed7ade9

Browse files
committed
[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
1 parent cc92212 commit ed7ade9

File tree

3 files changed

+9
-12
lines changed

3 files changed

+9
-12
lines changed

libc/src/unistd/getopt.cpp

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222
namespace __llvm_libc {
2323

2424
template <typename T> struct RefWrapper {
25-
RefWrapper(T *ptr) : ptr(ptr) {}
2625
RefWrapper &operator=(const RefWrapper &) = default;
2726
operator T &() { return *ptr; }
2827
T &get() { return *ptr; }
@@ -35,15 +34,17 @@ struct GetoptContext {
3534
RefWrapper<int> optopt;
3635
RefWrapper<unsigned> optpos;
3736

38-
int opterr;
37+
RefWrapper<int> opterr;
3938

4039
FILE *errstream;
4140

4241
GetoptContext &operator=(const GetoptContext &) = default;
4342

4443
template <typename... Ts> void report_error(const char *fmt, Ts... ts) {
4544
if (opterr)
46-
__llvm_libc::fprintf(errstream, fmt, ts...);
45+
__llvm_libc::fprintf(
46+
errstream ? errstream : reinterpret_cast<FILE *>(__llvm_libc::stderr),
47+
fmt, ts...);
4748
}
4849
};
4950

@@ -171,25 +172,21 @@ int getopt_r(int argc, char *const argv[], const char *optstring,
171172
namespace impl {
172173

173174
extern "C" {
174-
175175
char *optarg = nullptr;
176176
int optind = 1;
177177
int optopt = 0;
178178
int opterr = 0;
179-
180179
}
181180

182181
static unsigned optpos;
183182

184-
static GetoptContext ctx{
185-
&impl::optarg, &impl::optind,
186-
&impl::optopt, &optpos,
187-
impl::opterr, reinterpret_cast<FILE *>(__llvm_libc::stderr)};
183+
static GetoptContext ctx{&impl::optarg, &impl::optind, &impl::optopt,
184+
&optpos, &impl::opterr, /*errstream=*/nullptr};
188185

189186
#ifndef LIBC_COPT_PUBLIC_PACKAGING
190187
// This is used exclusively in tests.
191188
void set_getopt_state(char **optarg, int *optind, int *optopt, unsigned *optpos,
192-
int opterr, FILE *errstream) {
189+
int *opterr, FILE *errstream) {
193190
ctx = {optarg, optind, optopt, optpos, opterr, errstream};
194191
}
195192
#endif

libc/src/unistd/getopt.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
namespace __llvm_libc {
1616

1717
namespace impl {
18-
void set_getopt_state(char **, int *, int *, unsigned *, int, FILE *);
18+
void set_getopt_state(char **, int *, int *, unsigned *, int *, FILE *);
1919
}
2020

2121
int getopt(int argc, char *const argv[], const char *optstring);

libc/test/src/unistd/getopt_test.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ unsigned optpos;
3131
void set_state(FILE *errstream) {
3232
__llvm_libc::impl::set_getopt_state(
3333
&test_globals::optarg, &test_globals::optind, &test_globals::optopt,
34-
&test_globals::optpos, test_globals::opterr, errstream);
34+
&test_globals::optpos, &test_globals::opterr, errstream);
3535
}
3636

3737
// TODO: <stdio> could be either llvm-libc's or the system libc's. The former

0 commit comments

Comments
 (0)