wchar_t *
mbstouwcs (const char *s)
@{
  /* @r{Include the null terminator in the conversion.} */
  size_t len = strlen (s) + 1;
  wchar_t *result = reallocarray (NULL, len, sizeof (wchar_t));
  if (result == NULL)
    return NULL;

  wchar_t *wcp = result;
  mbstate_t state;
  memset (&state, '\0', sizeof (state));

  while (true)
    @{
      wchar_t wc;
      size_t nbytes = mbrtowc (&wc, s, len, &state);
      if (nbytes == 0)
        @{
          /* @r{Terminate the result string.} */
          *wcp = L'\0';
          break;
        @}
      else if (nbytes == (size_t) -2)
        @{
          /* @r{Truncated input string.} */
          errno = EILSEQ;
          free (result);
          return NULL;
        @}
      else if (nbytes == (size_t) -1)
        @{
          /* @r{Some other error (including EILSEQ).} */
          free (result);
          return NULL;
        @}
      else
        @{
          /* @r{A character was converted.} */
          *wcp++ = towupper (wc);
          len -= nbytes;
          s += nbytes;
        @}
    @}
  return result;
@}
