Function: aset

aset is a function defined in data.c.

Signature

(aset ARRAY IDX NEWELT)

Documentation

Store into the element of ARRAY at index IDX the value NEWELT.

Return NEWELT. ARRAY may be a vector, a string, a char-table or a bool-vector. IDX starts at 0.

View in manual

Probably introduced at or before Emacs version 1.12.

Source Code

// Defined in /usr/src/emacs/src/data.c
{
  register EMACS_INT idxval;

  CHECK_FIXNUM (idx);
  idxval = XFIXNUM (idx);
  if (! RECORDP (array))
    CHECK_ARRAY (array, Qarrayp);

  if (VECTORP (array))
    {
      CHECK_IMPURE (array, XVECTOR (array));
      if (idxval < 0 || idxval >= ASIZE (array))
	args_out_of_range (array, idx);
      ASET (array, idxval, newelt);
    }
  else if (BOOL_VECTOR_P (array))
    {
      if (idxval < 0 || idxval >= bool_vector_size (array))
	args_out_of_range (array, idx);
      bool_vector_set (array, idxval, !NILP (newelt));
    }
  else if (CHAR_TABLE_P (array))
    {
      CHECK_CHARACTER (idx);
      CHAR_TABLE_SET (array, idxval, newelt);
    }
  else if (RECORDP (array))
    {
      CHECK_IMPURE (array, XVECTOR (array));
      if (idxval < 0 || idxval >= PVSIZE (array))
	args_out_of_range (array, idx);
      ASET (array, idxval, newelt);
    }
  else /* STRINGP */
    {
      CHECK_IMPURE (array, XSTRING (array));
      if (idxval < 0 || idxval >= SCHARS (array))
	args_out_of_range (array, idx);
      CHECK_CHARACTER (newelt);
      int c = XFIXNAT (newelt);
      ptrdiff_t idxval_byte;
      int prev_bytes;
      unsigned char workbuf[MAX_MULTIBYTE_LENGTH], *p0 = workbuf, *p1;

      if (STRING_MULTIBYTE (array))
	{
	  idxval_byte = string_char_to_byte (array, idxval);
	  p1 = SDATA (array) + idxval_byte;
	  prev_bytes = BYTES_BY_CHAR_HEAD (*p1);
	}
      else if (SINGLE_BYTE_CHAR_P (c))
	{
	  SSET (array, idxval, c);
	  return newelt;
	}
      else
	{
	  for (ptrdiff_t i = SBYTES (array) - 1; i >= 0; i--)
	    if (!ASCII_CHAR_P (SREF (array, i)))
	      args_out_of_range (array, newelt);
	  /* ARRAY is an ASCII string.  Convert it to a multibyte string.  */
	  STRING_SET_MULTIBYTE (array);
	  idxval_byte = idxval;
	  p1 = SDATA (array) + idxval_byte;
	  prev_bytes = 1;
	}

      int new_bytes = CHAR_STRING (c, p0);
      if (prev_bytes != new_bytes)
	p1 = resize_string_data (array, idxval_byte, prev_bytes, new_bytes);

      do
	*p1++ = *p0++;
      while (--new_bytes != 0);
    }

  return newelt;
}