This patch also produces readable error messages on z/OS by defining two new svn_cmdline functions which take native string arguments, then calling svn_cmdline_fprintf_asis() from print_error(), only in the path where I can see that native strings are being used.
Greg Index: subversion/libsvn_subr/cmdline.c =================================================================== --- subversion/libsvn_subr/cmdline.c (revision 943729) +++ subversion/libsvn_subr/cmdline.c (working copy) @@ -316,6 +316,19 @@ } svn_error_t * +svn_cmdline_fprintf_asis(FILE *stream, apr_pool_t *pool, const char *fmt, ...) +{ + const char *message; + va_list ap; + + va_start(ap, fmt); + message = apr_pvsprintf(pool, fmt, ap); + va_end(ap); + + return svn_cmdline_fputs_asis(message, stream, pool); +} + +svn_error_t * svn_cmdline_fputs(const char *string, FILE* stream, apr_pool_t *pool) { svn_error_t *err; @@ -348,6 +361,28 @@ } svn_error_t * +svn_cmdline_fputs_asis(const char *string, FILE* stream, apr_pool_t *pool) +{ + + /* On POSIX systems, errno will be set on an error in fputs, but this might + not be the case on other platforms. We reset errno and only + use it if it was set by the below fputs call. Else, we just return + a generic error. */ + errno = 0; + + if (fputs(string, stream) == EOF) + { + if (errno) + return svn_error_wrap_apr(errno, _("Write error")); + else + return svn_error_create + (SVN_ERR_IO_WRITE_ERROR, NULL, NULL); + } + + return SVN_NO_ERROR; +} + +svn_error_t * svn_cmdline_fflush(FILE *stream) { /* See comment in svn_cmdline_fputs about use of errno and stdio. */ Index: subversion/libsvn_subr/error.c =================================================================== --- subversion/libsvn_subr/error.c (revision 943729) +++ subversion/libsvn_subr/error.c (working copy) @@ -415,8 +415,8 @@ /* Only print the same APR error string once. */ else if (err->message) { - svn_error_clear(svn_cmdline_fprintf(stream, err->pool, "%s%s\n", - prefix, err->message)); + svn_error_clear(svn_cmdline_fprintf_asis(stream, err->pool, "%s%s\n", + prefix, err->message)); } else { Index: subversion/include/svn_cmdline.h =================================================================== --- subversion/include/svn_cmdline.h (revision 943729) +++ subversion/include/svn_cmdline.h (working copy) @@ -128,6 +128,28 @@ FILE *stream, apr_pool_t *pool); +/** Write to the stdio @a stream, using a printf-like format string @a fmt, + * passed through apr_pvsprintf(). All string arguments are in the native + * encoding; no codepage conversion is done. Use @a pool for + * temporary allocation. + * + * @since New in ?? + */ +svn_error_t *svn_cmdline_fprintf_asis(FILE *stream, + apr_pool_t *pool, + const char *fmt, + ...) + __attribute__((format(printf, 3, 4))); + +/** Output the @a string to the stdio @a stream without changing the encoding. + * Use @a pool for temporary allocation. + * + * @since New in ?? + */ +svn_error_t *svn_cmdline_fputs_asis(const char *string, + FILE *stream, + apr_pool_t *pool); + /** Flush output buffers of the stdio @a stream, returning an error if that * fails. This is just a wrapper for the standard fflush() function for * consistent error handling.