diff options
Diffstat (limited to 'contrib/llvm-project/llvm/lib/Support/AutoConvert.cpp')
| -rw-r--r-- | contrib/llvm-project/llvm/lib/Support/AutoConvert.cpp | 73 |
1 files changed, 62 insertions, 11 deletions
diff --git a/contrib/llvm-project/llvm/lib/Support/AutoConvert.cpp b/contrib/llvm-project/llvm/lib/Support/AutoConvert.cpp index 4fb7e242c348..8170e553ac6e 100644 --- a/contrib/llvm-project/llvm/lib/Support/AutoConvert.cpp +++ b/contrib/llvm-project/llvm/lib/Support/AutoConvert.cpp @@ -14,21 +14,36 @@ #ifdef __MVS__ #include "llvm/Support/AutoConvert.h" +#include <cassert> #include <fcntl.h> #include <sys/stat.h> +#include <unistd.h> -std::error_code llvm::disableAutoConversion(int FD) { +static int savedStdHandleAutoConversionMode[3] = {-1, -1, -1}; + +int disableAutoConversion(int FD) { static const struct f_cnvrt Convert = { - SETCVTOFF, // cvtcmd - 0, // pccsid - (short)FT_BINARY, // fccsid + SETCVTOFF, // cvtcmd + 0, // pccsid + 0, // fccsid }; - if (fcntl(FD, F_CONTROL_CVT, &Convert) == -1) - return std::error_code(errno, std::generic_category()); - return std::error_code(); + + return fcntl(FD, F_CONTROL_CVT, &Convert); } -std::error_code llvm::enableAutoConversion(int FD) { +int restoreStdHandleAutoConversion(int FD) { + assert(FD == STDIN_FILENO || FD == STDOUT_FILENO || FD == STDERR_FILENO); + if (savedStdHandleAutoConversionMode[FD] == -1) + return 0; + struct f_cnvrt Cvt = { + savedStdHandleAutoConversionMode[FD], // cvtcmd + 0, // pccsid + 0, // fccsid + }; + return (fcntl(FD, F_CONTROL_CVT, &Cvt)); +} + +int enableAutoConversion(int FD) { struct f_cnvrt Query = { QUERYCVT, // cvtcmd 0, // pccsid @@ -36,17 +51,53 @@ std::error_code llvm::enableAutoConversion(int FD) { }; if (fcntl(FD, F_CONTROL_CVT, &Query) == -1) - return std::error_code(errno, std::generic_category()); + return -1; + + // We don't need conversion for UTF-8 tagged files. + // TODO: Remove the assumption of ISO8859-1 = UTF-8 here when we fully resolve + // problems related to UTF-8 tagged source files. + // When the pccsid is not ISO8859-1, autoconversion is still needed. + if (Query.pccsid == CCSID_ISO8859_1 && + (Query.fccsid == CCSID_UTF_8 || Query.fccsid == CCSID_ISO8859_1)) + return 0; + + // Save the state of std handles before we make changes to it. + if ((FD == STDIN_FILENO || FD == STDOUT_FILENO || FD == STDERR_FILENO) && + savedStdHandleAutoConversionMode[FD] == -1) + savedStdHandleAutoConversionMode[FD] = Query.cvtcmd; + + if (FD == STDOUT_FILENO || FD == STDERR_FILENO) + Query.cvtcmd = SETCVTON; + else + Query.cvtcmd = SETCVTALL; - Query.cvtcmd = SETCVTALL; Query.pccsid = (FD == STDIN_FILENO || FD == STDOUT_FILENO || FD == STDERR_FILENO) ? 0 : CCSID_UTF_8; // Assume untagged files to be IBM-1047 encoded. Query.fccsid = (Query.fccsid == FT_UNTAGGED) ? CCSID_IBM_1047 : Query.fccsid; - if (fcntl(FD, F_CONTROL_CVT, &Query) == -1) + return fcntl(FD, F_CONTROL_CVT, &Query); +} + +std::error_code llvm::disableAutoConversion(int FD) { + if (::disableAutoConversion(FD) == -1) + return std::error_code(errno, std::generic_category()); + + return std::error_code(); +} + +std::error_code llvm::enableAutoConversion(int FD) { + if (::enableAutoConversion(FD) == -1) return std::error_code(errno, std::generic_category()); + + return std::error_code(); +} + +std::error_code llvm::restoreStdHandleAutoConversion(int FD) { + if (::restoreStdHandleAutoConversion(FD) == -1) + return std::error_code(errno, std::generic_category()); + return std::error_code(); } |
