struct iovec iov[2 + nelems + 2 * ctype->nr_charclass + ctype->map_collection_nr + 4];
struct iovec *iov = alloca (sizeof *iov * (2 + nelems + 2 * ctype->nr_charclass + ctype->map_collection_nr + 4));
ctype_output (struct localedef_t *locale, const struct charmap_t *charmap,	      const char *output_path){  static const char nulbytes[4] = { 0, 0, 0, 0 };  struct locale_ctype_t *ctype = locale->categories[LC_CTYPE].ctype;  const size_t nelems = (_NL_ITEM_INDEX (_NL_CTYPE_EXTRA_MAP_1)			 + ctype->nr_charclass + ctype->map_collection_nr);  struct iovec iov[2 + nelems + 2 * ctype->nr_charclass		  + ctype->map_collection_nr + 4];  struct locale_file data;  uint32_t idx[nelems + 1];  uint32_t default_missing_len;  size_t elem, cnt, offset, total;  char *cp;  /* Now prepare the output: Find the sizes of the table we can use.  */  allocate_arrays (ctype, charmap, ctype->repertoire);  data.magic = LIMAGIC (LC_CTYPE);  data.n = nelems;  iov[0].iov_base = (void *) &data;  iov[0].iov_len = sizeof (data);  iov[1].iov_base = (void *) idx;  iov[1].iov_len = nelems * sizeof (uint32_t);  idx[0] = iov[0].iov_len + iov[1].iov_len;  offset = 0;  for (elem = 0; elem < nelems; ++elem)    {      if (elem < _NL_ITEM_INDEX (_NL_CTYPE_EXTRA_MAP_1))	switch (elem)	  {#define CTYPE_EMPTY(name) \	  case name:							      \	    iov[2 + elem + offset].iov_base = NULL;			      \	    iov[2 + elem + offset].iov_len = 0;				      \	    idx[elem + 1] = idx[elem];					      \	    break	  CTYPE_EMPTY(_NL_CTYPE_GAP1);	  CTYPE_EMPTY(_NL_CTYPE_GAP2);	  CTYPE_EMPTY(_NL_CTYPE_GAP3);	  CTYPE_EMPTY(_NL_CTYPE_GAP4);	  CTYPE_EMPTY(_NL_CTYPE_GAP5);	  CTYPE_EMPTY(_NL_CTYPE_GAP6);#define CTYPE_DATA(name, base, len)					      \	  case _NL_ITEM_INDEX (name):					      \	    iov[2 + elem + offset].iov_base = (base);			      \	    iov[2 + elem + offset].iov_len = (len);			      \	    idx[elem + 1] = idx[elem] + iov[2 + elem + offset].iov_len;	      \	    break	  CTYPE_DATA (_NL_CTYPE_CLASS,		      ctype->ctype_b,		      (256 + 128) * sizeof (char_class_t));	  CTYPE_DATA (_NL_CTYPE_TOUPPER,		      ctype->map_b[0],		      (256 + 128) * sizeof (uint32_t));	  CTYPE_DATA (_NL_CTYPE_TOLOWER,		      ctype->map_b[1],		      (256 + 128) * sizeof (uint32_t));	  CTYPE_DATA (_NL_CTYPE_TOUPPER32,		      ctype->map32_b[0],		      256 * sizeof (uint32_t));	  CTYPE_DATA (_NL_CTYPE_TOLOWER32,		      ctype->map32_b[1],		      256 * sizeof (uint32_t));	  CTYPE_DATA (_NL_CTYPE_CLASS32,		      ctype->ctype32_b,		      256 * sizeof (char_class32_t));	  CTYPE_DATA (_NL_CTYPE_CLASS_OFFSET,		      &ctype->class_offset, sizeof (uint32_t));	  CTYPE_DATA (_NL_CTYPE_MAP_OFFSET,		      &ctype->map_offset, sizeof (uint32_t));	  CTYPE_DATA (_NL_CTYPE_TRANSLIT_TAB_SIZE,		      &ctype->translit_idx_size, sizeof (uint32_t));	  CTYPE_DATA (_NL_CTYPE_TRANSLIT_FROM_IDX,		      ctype->translit_from_idx,		      ctype->translit_idx_size * sizeof (uint32_t));	  CTYPE_DATA (_NL_CTYPE_TRANSLIT_FROM_TBL,		      ctype->translit_from_tbl,		      ctype->translit_from_tbl_size);	  CTYPE_DATA (_NL_CTYPE_TRANSLIT_TO_IDX,		      ctype->translit_to_idx,		      ctype->translit_idx_size * sizeof (uint32_t));	  CTYPE_DATA (_NL_CTYPE_TRANSLIT_TO_TBL,		      ctype->translit_to_tbl, ctype->translit_to_tbl_size);	  case _NL_ITEM_INDEX (_NL_CTYPE_CLASS_NAMES):	    /* The class name array.  */	    total = 0;	    for (cnt = 0; cnt < ctype->nr_charclass; ++cnt, ++offset)	      {		iov[2 + elem + offset].iov_base		  = (void *) ctype->classnames[cnt];		iov[2 + elem + offset].iov_len		  = strlen (ctype->classnames[cnt]) + 1;		total += iov[2 + elem + offset].iov_len;	      }	    iov[2 + elem + offset].iov_base = (void *) nulbytes;	    iov[2 + elem + offset].iov_len = 1 + (4 - ((total + 1) % 4));	    total += 1 + (4 - ((total + 1) % 4));	    idx[elem + 1] = idx[elem] + total;	    break;	  case _NL_ITEM_INDEX (_NL_CTYPE_MAP_NAMES):	    /* The class name array.  */	    total = 0;	    for (cnt = 0; cnt < ctype->map_collection_nr; ++cnt, ++offset)	      {		iov[2 + elem + offset].iov_base		  = (void *) ctype->mapnames[cnt];		iov[2 + elem + offset].iov_len		  = strlen (ctype->mapnames[cnt]) + 1;		total += iov[2 + elem + offset].iov_len;	      }	    iov[2 + elem + offset].iov_base = (void *) nulbytes;	    iov[2 + elem + offset].iov_len = 1 + (4 - ((total + 1) % 4));	    total += 1 + (4 - ((total + 1) % 4));	    idx[elem + 1] = idx[elem] + total;	    break;	  CTYPE_DATA (_NL_CTYPE_WIDTH,		      ctype->width.iov_base,		      ctype->width.iov_len);	  CTYPE_DATA (_NL_CTYPE_MB_CUR_MAX,		      &ctype->mb_cur_max, sizeof (uint32_t));	  case _NL_ITEM_INDEX (_NL_CTYPE_CODESET_NAME):	    total = strlen (ctype->codeset_name) + 1;	    if (total % 4 == 0)	      iov[2 + elem + offset].iov_base = (char *) ctype->codeset_name;	    else	      {		iov[2 + elem + offset].iov_base = alloca ((total + 3) & ~3);		memset (mempcpy (iov[2 + elem + offset].iov_base,				 ctype->codeset_name, total),			'\0', 4 - (total & 3));		total = (total + 3) & ~3;	      }	    iov[2 + elem + offset].iov_len = total;	    idx[elem + 1] = idx[elem] + iov[2 + elem + offset].iov_len;	    break;	  CTYPE_DATA (_NL_CTYPE_MAP_TO_NONASCII,		      &ctype->to_nonascii, sizeof (uint32_t));	  case _NL_ITEM_INDEX (_NL_CTYPE_INDIGITS_MB_LEN):	    iov[2 + elem + offset].iov_base = alloca (sizeof (uint32_t));	    iov[2 + elem + offset].iov_len = sizeof (uint32_t);	    *(uint32_t *) iov[2 + elem + offset].iov_base =	      ctype->mbdigits_act / 10;	    idx[elem + 1] = idx[elem] + sizeof (uint32_t);	    break;	  case _NL_ITEM_INDEX (_NL_CTYPE_INDIGITS_WC_LEN):	    /* Align entries.  */	    iov[2 + elem + offset].iov_base = (void *) nulbytes;	    iov[2 + elem + offset].iov_len = (4 - idx[elem] % 4) % 4;	    idx[elem] += iov[2 + elem + offset].iov_len;	    ++offset;	    iov[2 + elem + offset].iov_base = alloca (sizeof (uint32_t));	    iov[2 + elem + offset].iov_len = sizeof (uint32_t);	    *(uint32_t *) iov[2 + elem + offset].iov_base =	      ctype->wcdigits_act / 10;	    idx[elem + 1] = idx[elem] + sizeof (uint32_t);	    break;	  case _NL_ITEM_INDEX (_NL_CTYPE_INDIGITS0_MB) ... _NL_ITEM_INDEX (_NL_CTYPE_INDIGITS9_MB):	    /* Compute the length of all possible characters.  For INDIGITS	       there might be more than one.  We simply concatenate all of	       them with a NUL byte following.  The NUL byte wouldn't be	       necessary but it makes it easier for the user.  */	    total = 0;	    for (cnt = elem - _NL_ITEM_INDEX (_NL_CTYPE_INDIGITS0_MB);		 cnt < ctype->mbdigits_act; cnt += 10)	      total += ctype->mbdigits[cnt]->nbytes + 1;	    iov[2 + elem + offset].iov_base = (char *) alloca (total);	    iov[2 + elem + offset].iov_len = total;	    cp = iov[2 + elem + offset].iov_base;	    for (cnt = elem - _NL_ITEM_INDEX (_NL_CTYPE_INDIGITS0_MB);		 cnt < ctype->mbdigits_act; cnt += 10)	      {		cp = mempcpy (cp, ctype->mbdigits[cnt]->bytes,			      ctype->mbdigits[cnt]->nbytes);		*cp++ = '\0';	      }	    idx[elem + 1] = idx[elem] + iov[2 + elem + offset].iov_len;	    break;	  case _NL_ITEM_INDEX (_NL_CTYPE_OUTDIGIT0_MB) ... _NL_ITEM_INDEX (_NL_CTYPE_OUTDIGIT9_MB):	    /* Compute the length of all possible characters.  For INDIGITS	       there might be more than one.  We simply concatenate all of	       them with a NUL byte following.  The NUL byte wouldn't be	       necessary but it makes it easier for the user.  */	    cnt = elem - _NL_ITEM_INDEX (_NL_CTYPE_OUTDIGIT0_MB);	    total = ctype->mboutdigits[cnt]->nbytes + 1;	    iov[2 + elem + offset].iov_base = (char *) alloca (total);	    iov[2 + elem + offset].iov_len = total;	    *(char *) mempcpy (iov[2 + elem + offset].iov_base,			       ctype->mboutdigits[cnt]->bytes,			       ctype->mboutdigits[cnt]->nbytes) = '\0';	    idx[elem + 1] = idx[elem] + iov[2 + elem + offset].iov_len;	    break;	  case _NL_ITEM_INDEX (_NL_CTYPE_INDIGITS0_WC) ... _NL_ITEM_INDEX (_NL_CTYPE_INDIGITS9_WC):	    total = ctype->wcdigits_act / 10;	    iov[2 + elem + offset].iov_base =	      (uint32_t *) alloca (total * sizeof (uint32_t));	    iov[2 + elem + offset].iov_len = total * sizeof (uint32_t);	    for (cnt = elem - _NL_ITEM_INDEX (_NL_CTYPE_INDIGITS0_WC);		 cnt < ctype->wcdigits_act; cnt += 10)	      ((uint32_t *) iov[2 + elem + offset].iov_base)[cnt / 10]		= ctype->wcdigits[cnt];	    idx[elem + 1] = idx[elem] + iov[2 + elem + offset].iov_len;	    break;	  case _NL_ITEM_INDEX (_NL_CTYPE_OUTDIGIT0_WC):	    /* Align entries.  */	    iov[2 + elem + offset].iov_base = (void *) nulbytes;	    iov[2 + elem + offset].iov_len = (4 - idx[elem] % 4) % 4;	    idx[elem] += iov[2 + elem + offset].iov_len;	    ++offset;	    /* FALLTRHOUGH */	  case _NL_ITEM_INDEX (_NL_CTYPE_OUTDIGIT1_WC) ... _NL_ITEM_INDEX (_NL_CTYPE_OUTDIGIT9_WC):	    cnt = elem - _NL_ITEM_INDEX (_NL_CTYPE_OUTDIGIT0_WC);	    iov[2 + elem + offset].iov_base = &ctype->wcoutdigits[cnt];	    iov[2 + elem + offset].iov_len = sizeof (uint32_t);	    idx[elem + 1] = idx[elem] + iov[2 + elem + offset].iov_len;	    break;	  case _NL_ITEM_INDEX(_NL_CTYPE_TRANSLIT_DEFAULT_MISSING_LEN):	    /* Align entries.  */	    iov[2 + elem + offset].iov_base = (void *) nulbytes;	    iov[2 + elem + offset].iov_len = (4 - idx[elem] % 4) % 4;	    idx[elem] += iov[2 + elem + offset].iov_len;	    ++offset;	    default_missing_len = (ctype->default_missing				   ? wcslen ((wchar_t *)ctype->default_missing)				   : 0);	    iov[2 + elem + offset].iov_base = &default_missing_len;	    iov[2 + elem + offset].iov_len = sizeof (uint32_t);	    idx[elem + 1] = idx[elem] + iov[2 + elem + offset].iov_len;	    break;	  case _NL_ITEM_INDEX(_NL_CTYPE_TRANSLIT_DEFAULT_MISSING):	    iov[2 + elem + offset].iov_base =	      ctype->default_missing ?: (uint32_t *) L"";	    iov[2 + elem + offset].iov_len =	      wcslen (iov[2 + elem + offset].iov_base);	    idx[elem + 1] = idx[elem] + iov[2 + elem + offset].iov_len;	    break;	  case _NL_ITEM_INDEX(_NL_CTYPE_TRANSLIT_IGNORE_LEN):	    /* Align entries.  */	    iov[2 + elem + offset].iov_base = (void *) nulbytes;	    iov[2 + elem + offset].iov_len = (4 - idx[elem] % 4) % 4;	    idx[elem] += iov[2 + elem + offset].iov_len;	    ++offset;	    iov[2 + elem + offset].iov_base = &ctype->ntranslit_ignore;	    iov[2 + elem + offset].iov_len = sizeof (uint32_t);	    idx[elem + 1] = idx[elem] + iov[2 + elem + offset].iov_len;	    break;	  case _NL_ITEM_INDEX(_NL_CTYPE_TRANSLIT_IGNORE):	    {	      uint32_t *ranges = (uint32_t *) alloca (ctype->ntranslit_ignore						      * 3 * sizeof (uint32_t));	      struct translit_ignore_t *runp;	      iov[2 + elem + offset].iov_base = ranges;	      iov[2 + elem + offset].iov_len = (ctype->ntranslit_ignore						* 3 * sizeof (uint32_t));	      for (runp = ctype->translit_ignore; runp != NULL;		   runp = runp->next)		{		  *ranges++ = runp->from;		  *ranges++ = runp->to;		  *ranges++ = runp->step;		}	    }	    /* Remove the following line in case a new entry is added	       after _NL_CTYPE_TRANSLIT_DEFAULT_MISSING_LEN.  */	    if (elem < nelems)	      idx[elem + 1] = idx[elem] + iov[2 + elem + offset].iov_len;	    break;	  default:	    assert (! "unknown CTYPE element");	  }      else	{	  /* Handle extra maps.  */	  size_t nr = elem - _NL_ITEM_INDEX (_NL_CTYPE_EXTRA_MAP_1);	  if (nr < ctype->nr_charclass)	    {	      iov[2 + elem + offset].iov_base = ctype->class_b[nr];	      iov[2 + elem + offset].iov_len = 256 / 32 * sizeof (uint32_t);	      idx[elem] += iov[2 + elem + offset].iov_len;	      ++offset;	      iov[2 + elem + offset] = ctype->class_3level[nr];	    }	  else	    {	      nr -= ctype->nr_charclass;	      assert (nr < ctype->map_collection_nr);	      iov[2 + elem + offset] = ctype->map_3level[nr];	    }	  idx[elem + 1] = idx[elem] + iov[2 + elem + offset].iov_len;	}    }  assert (2 + elem + offset == (nelems + 2 * ctype->nr_charclass				+ ctype->map_collection_nr + 4 + 2));  write_locale_data (output_path, LC_CTYPE, "LC_CTYPE", 2 + elem + offset,		     iov);}