From: Jamie Lokier <jamie@shareable.org>
To: Anthony Liguori <anthony@codemonkey.ws>
Cc: Blue Swirl <blauwirbel@gmail.com>,
Anthony Liguori <aliguori@us.ibm.com>,
Gerd Hoffman <kraxel@redhat.com>,
Paul Brook <paul@codesourcery.com>,
qemu-devel@nongnu.org
Subject: Re: [Qemu-devel] [PATCH 2/2] Introduce macro for defining qdev properties
Date: Mon, 20 Jul 2009 03:29:05 +0100 [thread overview]
Message-ID: <20090720022905.GB28197@shareable.org> (raw)
In-Reply-To: <4A61F498.6060208@codemonkey.ws>
Anthony Liguori wrote:
> Jamie Lokier wrote:
> >In (hopefully) ANSI-portable C code which performs a very similar
> >function, I got it down to OPTION_SIGNED("name", var),
> >OPTION_UNSIGNED("name", var), OPTION_BOOL("name", var),
> >OPTION_STRING("name", var), for the major non-compound types.
> >
> How do you detect the size of the integer?
Using sizeof(var) :-)
The macros expand to something like
{ name, (void *)&var, sizeof(var),
SIGNED_MIN_FROM_SIZE(sizeof(var)),
SIGNED_MAX_FROM_SIZE(sizeof(var)),
option_parse_signed },
option_parse_signed is a generic integer parsing function, parsing any
size integer up to intmax_t. The result is checked against the min
and max fields, which are calculated at compile time. The _RANGE
version of the macros lets you set them explicitly instead.
Then all parsing functions use the code attached below to store the
value in the correct variable size.
In my app I also include OPTION_SET_{FALSE,TRUE,CONST}, which are good
for options that don't parse an argument; their presence is enough. I
don't know if that applies to qdev. I also include help text in each
macro, which proves to be quite nice in several contexts including --help:
OPTION_UNSIGNED_RANGE("port", opt_port, 0, 65535,
"the port number to listen on, from 0 to 65535")
Unfortunately although I did find expressions which say if something
is signed or a floating-point value, and evaluate to a constant at
compile time, they aren't "compile-time constant expressions" and so
cannot be used in global initialisers in standard C. They look like:
#define is_signed(var) ((var) * 0 - 1 < 0)
-- Jamie
ps. Code to store parsed value in arbitrarily sized integer variables:
/* Store an option's value in the option's destination variable, for any
standard integer or data pointer variable. The value is expected to
be appropriate and within range for the destination variable's type. */
static void
option_store_value (const struct option * option, uintmax_t value)
{
if (option->option_var_ptr != 0)
{
char * var_ptr = (char *) option->option_var_ptr;
const char * value_ptr = (const char *) &value;
size_t p, size = option->option_var_size;
#ifdef LIBJL_LITTLE_ENDIAN
/* Nothing to do. */
#else
# ifdef LIBJL_BIG_ENDIAN
value_ptr += sizeof (value) - size;
# else
# ifdef LIBJL_PDP_ENDIAN
value_ptr += (sizeof (value) - size) & ~(size_t)1;
# else
/* Should work with any reasonable byte order, even complicated
ones like 3412 (PDP, VAX) and 43218765 (ARM GCC before 2.8),
and even when they aren't 8-bit bytes. */
if (size < sizeof (uintmax_t))
{
uintmax_t order = ((uintmax_t) 1 << (size * BITS_PER_BYTE)) - 1;
const char * order_ptr = (const char *) ℴ
for (p = 0; p < size; p++)
if (order_ptr [p] != 0)
break;
value_ptr += p;
}
# endif
# endif
#endif
for (p = 0; p < size; p++)
var_ptr [p] = value_ptr [p];
}
}
next prev parent reply other threads:[~2009-07-20 2:29 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-07-17 14:41 [Qemu-devel] [PATCH 0/2][RFC] Introduce macros for setting properties Anthony Liguori
2009-07-17 14:41 ` [Qemu-devel] [PATCH 1/2] Introduce CharDriverState qdev property type Anthony Liguori
2009-07-21 14:46 ` [Qemu-devel] " Gerd Hoffmann
2009-07-21 14:53 ` Anthony Liguori
2009-07-21 15:03 ` Gerd Hoffmann
2009-07-21 15:14 ` Gerd Hoffmann
2009-07-21 15:23 ` Anthony Liguori
2009-07-21 15:34 ` Gerd Hoffmann
2009-07-21 15:47 ` Anthony Liguori
2009-07-22 9:48 ` Gerd Hoffmann
2009-07-17 14:41 ` [Qemu-devel] [PATCH 2/2] Introduce macro for defining qdev properties Anthony Liguori
2009-07-17 17:23 ` Blue Swirl
2009-07-17 17:26 ` Anthony Liguori
2009-07-17 17:33 ` Paul Brook
2009-07-17 18:11 ` Anthony Liguori
2009-07-17 18:32 ` Blue Swirl
2009-07-17 20:05 ` Anthony Liguori
2009-07-17 22:58 ` Paul Brook
2009-07-18 12:43 ` Jamie Lokier
2009-07-18 16:13 ` Anthony Liguori
2009-07-20 2:29 ` Jamie Lokier [this message]
2009-07-21 8:30 ` [Qemu-devel] " Gerd Hoffmann
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20090720022905.GB28197@shareable.org \
--to=jamie@shareable.org \
--cc=aliguori@us.ibm.com \
--cc=anthony@codemonkey.ws \
--cc=blauwirbel@gmail.com \
--cc=kraxel@redhat.com \
--cc=paul@codesourcery.com \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).