Hi Jason, On Mon, Jan 20, 2025 at 08:42:17AM -0500, Jason Yundt wrote: > +.SS Program source > +.\" SRC BEGIN (pathname_encoding_example.c) > +.EX > +#include <err.h> > +#include <iconv.h> > +#include <langinfo.h> > +#include <locale.h> > +#include <stdio.h> > +#include <stdlib.h> > +#include <uchar.h> > +\& > +#define NELEMS(a) (sizeof(a) / sizeof(a[0])) > +\& > +int > +main(void) > +{ > + if (setlocale(LC_ALL, "") == NULL) { > + err(EXIT_FAILURE, "setlocale"); > + } > + char32_t utf32_pathname[] = U"example"; Please separate declarations from code. int main(void) { size_t size; char32_t utf32_pathname[] = U"example"; ... if (setlocale(... ... } > + size_t len = NELEMS(utf32_pathname) \- 1; > + size_t locale_pathname_size = len * MB_CUR_MAX + 1; Since there's no other use of len, I'd just inline it. Since there's no other *_size variable, let's just call this size. size_t size = NELEMS(utf32_pathname) * MB_CUR_MAX; > + char *locale_pathname = malloc(locale_pathname_size); > + if (locale_pathname == NULL) { > + err(EXIT_FAILURE, "malloc"); > + } > +\& > + iconv_t cd = iconv_open(nl_langinfo(CODESET), "UTF\-32"); > + if (cd == (iconv_t) \- 1) { > + err(EXIT_FAILURE, "iconv_open"); > + } > + char *inbuf = (char *) utf32_pathname; > + size_t inbytesleft = sizeof utf32_pathname; > + char *outbuf = locale_pathname; > + size_t outbytesleft = locale_pathname_size; > + size_t iconv_result = > + iconv(cd, &inbuf, &inbytesleft, &outbuf, &outbytesleft); > + if (iconv_result == \-1) { > + err(EXIT_FAILURE, "iconv"); > + } > + // This ensures that the conversion is 100% complete. > + // See iconv(3) for details. > + iconv_result = > + iconv(cd, NULL, &inbytesleft, &outbuf, &outbytesleft); > + if (iconv_result == \-1) { > + err(EXIT_FAILURE, "iconv"); > + } Do we really need two calls? Why? > + if (iconv_close(cd) == \-1) { > + err(EXIT_FAILURE, "iconv_close"); > + } > +\& > + FILE *fp = fopen(locale_pathname, "w"); > + if (fp == NULL) { > + err(EXIT_FAILURE, "fopen"); > + } > + if (fputs("Hello, world!\\n", fp) == EOF) { > + err(EXIT_FAILURE, "fputs"); > + } We don't check for fputs(3) errors in examples. stdio buffers stuff, so anyway this call most likely won't fail. > + if (fclose(fp) == EOF) { > + err(EXIT_FAILURE, "fclose"); > + } This would be the only error handling we need, I think. Cheers, Alex > +\& > + free(locale_pathname); > + exit(EXIT_SUCCESS); > +} > +.EE > +.\" SRC END > +.SH SEE ALSO > +.BR limits.h (0p), > +.BR open (2), > +.BR fpathconf (3), > +.BR iconv (3), > +.BR nl_langinfo (3), > +.BR path_resolution (7), > +.BR mount (8) > -- > 2.47.1 > -- <https://www.alejandro-colomar.es/>
Attachment:
signature.asc
Description: PGP signature