[AC21.5R21.4] Patch: fix cut & past problem on 64 bit platforms

Martin Buchholz martin at xemacs.org
Sat Feb 17 16:26:01 EST 2007


>>>>> "SJT" == Stephen J Turnbull <stephen at xemacs.org> writes:
SJT> +     generally make long be a 64-bit quantity while while it's 32 bits on

You have a double-trouble typo above.

SJT> +     32-bit platforms.
SJT> +
SJT> +     This means that on all platforms the wire item is the same size as our
SJT> +     buffer unit when format == 8 or format == 16 or format == wordsize == 32,
SJT> +     and the buffer size can be taken as bytes_remaining plus padding.
SJT> +     However, when format == 32 and wordsize == 64, the buffer unit is twice
SJT> +     the size of the wire item.  Obviously this code below is not 128-bit
SJT> +     safe.  (We could replace the factor 2 with (sizeof(long)*8/32.)

Instead of "we could" why not actually use the more meaningful
symbolic expression?

SJT> +     We can hope it doesn't much matter on versions of X11 earlier than R7.
SJT> +  */
SJT> +  if (sizeof(long) == 8 && *actual_format_ret == 32)
SJT> +    total_size = 2 * bytes_remaining + 1;
SJT> +  else
SJT> +    total_size = bytes_remaining + 1;
SJT>    *data_ret = xnew_rawbytes (total_size);
 

I hate this kind of code.

Make sure there's enough configury infrastructure to define the
stdint.h types

uint16_t
uint32_t
uint64_t

(i.e. config.h should either include stdint.h or go and define these
types in the obvious way)

and then in x-select.c one should have code more like

(code sketch only)

Lisp_Object uint32_t_to_lisp (uint32_t x)
{
  return ((EMACS_UINT) x <= (EMACS_UINT) EMACS_INT_MAX)
    ? make_int (x)
    : Fcons (make_int (item >> 16), make_int (item & 0xffff));
}


static Lisp_Object
selection_data_to_lisp_data (struct device *d,
			     Extbyte *data,
			     size_t size,
			     Atom type,
			     int format)
{
  int nitems = size / format;
  if (nitems == 1)
    {
      ...
      else if (format == 32)
	return uint32_t_to_lisp (* ((uint32_t *) data));
      else if (format == 16)
	return make_int ((int) (* ((uint16_t *) data)));
    }
  else
    {
      ...
    }
}

Yes, it's a fair amount of work to do this right.

Martin



More information about the XEmacs-Beta mailing list