From 07c61498bd7fa6166029c1ab093a35f82d926667 Mon Sep 17 00:00:00 2001 From: Benjamin Barenblat Date: Tue, 25 Jan 2022 18:23:21 -0500 Subject: skiphead, a program to preserve headers in a pipeline This is a faster, more robust rewrite of a shell script I wrote a few years ago to preserve headers when grepping through program output. I can never remember what the headers are when I run things like 'ps', so being able to say something like 'ps -ef | skiphead grep systemd' is useful. As a bonus, the program detects your locale and automatically displays help and error messages using the correct encoding. --- goldfishlocale.h | 94 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 94 insertions(+) create mode 100644 goldfishlocale.h (limited to 'goldfishlocale.h') diff --git a/goldfishlocale.h b/goldfishlocale.h new file mode 100644 index 0000000..c9448c1 --- /dev/null +++ b/goldfishlocale.h @@ -0,0 +1,94 @@ +// Copyright 2022 Benjamin Barenblat +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not +// use this file except in compliance with the License. You may obtain a copy of +// the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations under +// the License. + +// This is goldfishlocale, a library to help you get your terminal output +// encoded correctly. Use it like this: +// +// int main(int argc, char* argv[]) { +// goldfishlocale::SetLocaleFromEnvironment(); // call this once +// std::cout << goldfishlocale::ToSystem(u8"These are “curly quotes”.\n"); +// } +// +// Running this on most terminals will produce +// +// These are “curly quotes”. +// +// On terminals that lack curly quote characters, this will gracefully degrade +// to +// +// These are "curly quotes". +// +// rather than +// +// These are 窶彡urly quotes窶� +// +// or something similarly unexpected. +// +// LIBRARY ASSUMPTION: Goldfishlocale assumes your system's locale is set once +// (by goldfishlocale) and does not change during program execution. In +// practice, this means you should not call std::locale::global or setlocale(3). +// By default, goldfishlocale detects and throws on locale changes; however, +// this detection does carry a runtime cost, so it's disabled if you define +// NDEBUG. + +#include + +#include +#include + +namespace goldfishlocale_internal { + +std::string ToSystem(char*, size_t); + +} // namespace goldfishlocale_internal + +namespace goldfishlocale { + +// Initializes goldfishlocale based on your environment. After this call +// returns, the C and C++ libraries are aware of the system locale; this may +// affect some behavior, including the way numbers and dates are formatted. +// +// This function must be called exactly once during the execution of your +// program, ideally near the start of main. +// +// Your program must be single-threaded at the time this function is called. +// Having multiple threads executing triggers undefined behavior. +void SetLocaleFromEnvironment(); + +// Converts the specified string to the system locale. Assumes a UTF-8 encoding. +inline std::string ToSystem(std::string s) { + return goldfishlocale_internal::ToSystem(s.data(), s.size()); +} +inline std::string ToSystem(std::string_view s) { + return ToSystem(std::string(s)); +} +inline std::string ToSystem(const char s[]) { return ToSystem(std::string(s)); } + +#if defined(__cpp_char8_t) && defined(__cpp_lib_char8_t) + +// Converts the specified string to the system locale. +inline std::string ToSystem(std::u8string s) { + return goldfishlocale_internal::ToSystem(reinterpret_cast(s.data()), + s.size()); +} +inline std::string ToSystem(std::u8string_view s) { + return ToSystem(std::u8string(s)); +} +inline std::string ToSystem(const char8_t s[]) { + return ToSystem(std::u8string(s)); +} + +#endif // defined(__cpp_char8_t) && defined(__cpp_lib_char8_t) + +} // namespace goldfishlocale -- cgit v1.2.3