On Mon, Jan 20, 2025 at 03:22:05PM +0100, Alejandro Colomar wrote: > 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; OK. I made that change locally. I’ll submit a new version later. > 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; Done. > > > + 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? iconv(3) says “In each series of calls to iconv(), the last should be one with inbuf or *inbuf equal to NULL, in order to flush out any partially converted input.” To me, that quote makes it sound like you should always call iconv() at least twice and that inbuf (or *inbuf) should be NULL the last time that you call iconv(). I don’t know why the man page says that you should always call iconv() at least twice. > > + 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. Done.