I need a macro to transform an value like 274A into {(char)0x27, (char)
0x4A}. Does anyone know how to do it, or where can I find more
information about this kind of macro?
Thanks,
Andre
It's not absolutely to me clear what you want to do, but I /think/ you
want to load 0x274A into the first two members of an array of char. This
is somewhat muddied by C's allowing chars to be wider than 8 bits, but
if we just assume you want the high 8 bits in the first char, and the
low 8 bits in the second, you can do this:
#define U16_TO_CHAR2(arr, x) \
do { (arr)[0] = ((x) & 0xFF00) >> 8; \
(arr)[1] = (x) & 0xFF; } \
while(0)
I wouldn't trust my weight to that macro, however. In fact, in the light
of recent "discussions" about what constitutes a recommendation, I would
add that I definitely don't recommend it. Too many things can go wrong.
Note that this macro does not null-terminate the array, so it isn't a
string-builder. (Easily fixed if that's what you want.) Note, too, that
it assumes x is an integer type, and it will take only the bottom 16
bits of that value. If you want more, write a bigger macro - or, far
better, write a decent function to do the job instead.
--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
"Usenet is a strange place" - dmr 29 July 1999
Sig line vacant - apply within
> Andre wrote:
>> I need a macro to transform an value like 274A into {(char)0x27, (char)
>> 0x4A}. Does anyone know how to do it, or where can I find more
>> information about this kind of macro?
>
> It's not absolutely to me clear what you want to do, but I /think/ you
> want to load 0x274A into the first two members of an array of
> char. This is somewhat muddied by C's allowing chars to be wider than
> 8 bits, but if we just assume you want the high 8 bits in the first
> char, and the low 8 bits in the second, you can do this:
>
> #define U16_TO_CHAR2(arr, x) \
> do { (arr)[0] = ((x) & 0xFF00) >> 8; \
> (arr)[1] = (x) & 0xFF; } \
> while(0)
To do this, I'd write a function, e.g. following your model:
#include <stdint.h>
void u16_to_char2(unsigned char arr[2], unsigned int x)
{
arr[0] = (x & 0xff00) >> 8;
arr[1] = x & 0xff;
}
--
char a[]="\n .CJacehknorstu";int putchar(int);int main(void){unsigned long b[]
={0x67dffdff,0x9aa9aa6a,0xa77ffda9,0x7da6aa6a,0xa67f6aaa,0xaa9aa9f6,0x11f6},*p
=b,i=24;for(;p+=!*p;*p/=4)switch(0[p]&3)case 0:{return 0;for(p--;i--;i--)case+
2:{i++;if(i)break;else default:continue;if(0)case 1:putchar(a[i&15]);break;}}}
So would I. :-)
The value I have will be in the following format 75B22636-668E-11CF-
A6D900AA0062CE6C, and I would like to transform it into {(char)0x75,
(char)0xB2, (char)0x26, (char)0x36, (char)0x66, ... , (char)0x6C}.
Thanks,
Andre
Do you get this value at runtime or compile time?
--
Ben Pfaff
http://benpfaff.org
> On Feb 3, 9:45 am, Ben Pfaff <b...@cs.stanford.edu> wrote:
>> Andre <sieg1...@yahoo.com> writes:
>> > I wasn't clear enough.
>>
>> > The value I have will be in the following format 75B22636-668E-11CF-
>> > A6D900AA0062CE6C, and I would like to transform it into {(char)0x75,
>> > (char)0xB2, (char)0x26, (char)0x36, (char)0x66, ... , (char)0x6C}.
>>
>> Do you get this value at runtime or compile time?
>
> Compile time
Can you give an example?
75B22636-668E-11CF-A6D900AA0062CE6C is not a valid piece of C code.
Do you have a string literal in your program? How did it get there?
--
Keith Thompson (The_Other_Keith) ks...@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
You are trying to transform a string uuid into an uuid:
Use:
Under windows:
#include <rpc.h>
RPC_STATUS RPC_ENTRY UuidFromString(
unsigned char __RPC_FAR *StringUuid,
UUID __RPC_FAR *Uuid
);
Under linux:
#include <uuid/uuid.h>
int uuid_parse( char *in, uuid_t uu);
DESCRIPTION
The uuid_parse function converts the UUID string given by in into the binary representation. The
input UUID is a string of the form 1b4e28ba-2fa1-11d2-883f-b9a761bde3fb (in printf(3) format
"%08x-%04x-%04x-%04x-%012x", 36 bytes plus the trailing '\0').
jacob
This is still pretty unclear.
Do you want a literal translation at compile time, where you'll have a
compile-time string 75B2..., and you want to transform it into a
compile-time string { (char) ...}?
Or do you have incoming data at runtime, and you want to translate it into
a series of values in an array?
-s
--
Copyright 2010, all wrongs reversed. Peter Seebach / usenet...@seebs.net
http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!
How does it get from the original source into your C source?
Can you supply 75B22636,668E,11CF,A6D900AA0062CE6C instead?
Then you can use a variant of Richard's method (if you have
a compiler that supports unsigned long long.)
#include <stdio.h>
#define UUID(p0, p1, p2, p3) \
{ UUID_X4(p0), UUID_X2(p1), UUID_X2(p2), UUID_X8(p3) }
#define UUID_X8(p1) UUID_8(0x ## p1 ## ull)
#define UUID_X4(p1) UUID_4(0x ## p1 ## ul )
#define UUID_X2(p1) UUID_2(0x ## p1 ## u )
#define UUID_8(x) UUID_4((x) >> 32), UUID_4(x)
#define UUID_4(x) UUID_2((x) >> 16), UUID_2(x)
#define UUID_2(x) UUID_1((x) >> 8), UUID_1(x)
#define UUID_1(x) ((x) & 0xFF)
#define countof(x) ((size_t) (sizeof (x) / sizeof *(x)))
int main(void)
{
size_t i;
unsigned char uuid[] = UUID(75B22636,668E,11CF,A6D900AA0062CE6C);
for (i = 0; i < countof (uuid); i++)
printf(" %02X", 0u + uuid[i]);
putchar('\n');
return 0;
}
--
Peter
I apologize for my confusing questions.
I have something like the following in my code
#define ASF_OBJECT_GUID_HEADER "75B22630668E11CFA6D900AA0062CE6C"
And if variable test is created in the following
char test[] = ASF_OBJECT_GUID_HEADER;
its values would be
test[0] = '7'
test[1] = '5'
test[2] = 'B'
test[2] = '2'
...
test[32] = '6'
test[31] = 'C'
test[32] = 0
And I would like to know if that is a way to create a macro to
redefine ASF_OBJECT_GUID_HEADER
#define ASF_OBJECT_GUID_HEADER SOME_COOL_MACRO_HERE
(75B22630668E11CFA6D900AA0062CE6C)
Now, it test is create in the same way as before
char test[] = ASF_OBJECT_GUID_HEADER;
Its values would be
test[0] = '75'
test[1] = 'B2'
...
test[15] = '6C'
test[16] = 0
Thanks,
Andre
So there are no '-' characters, unlike everything you've told us so
far.
Wait, you have "something like" that? How much like it? Can you tell
us what you actually have rather than what it resembles?
How did that string literal get into your code? How much control do
you have over it? Can you write it as "\x75\xB2...\x6C"?
[...]
> And I would like to know if that is a way to create a macro to
> redefine ASF_OBJECT_GUID_HEADER
>
> #define ASF_OBJECT_GUID_HEADER SOME_COOL_MACRO_HERE
> (75B22630668E11CFA6D900AA0062CE6C)
And now it's no longer a string literal. Again, what *exactly* are
you starting with, and how much control do you have over it?
A macro can apply operations (such as <<, &, et al) to an operand to
generate a value at run time, or even at compile time if the
> Now, it test is create in the same way as before
>
> char test[] = ASF_OBJECT_GUID_HEADER;
>
> Its values would be
>
> test[0] = '75'
> test[1] = 'B2'
> ...
> test[15] = '6C'
> test[16] = 0
I seriously doubt that. '75' is a multi-character constant; its value
is implementation-defined. I guess you mean '\x75'.
Is there any reason you can't just write
{ '\x75', '\xB2', ... }
in the first place?
You probably don't mean that. I'll guess that you
mean `\x75' instead.
> test[1] = 'B2'
> ...
> test[15] = '6C'
> test[16] = 0
If you absolutely must do this, I guess you might
proceed more or less like this:
#define HEX(c) ('0' <= (c) && (c) <= '9' ? (c)-'0' \
: (c) == 'A' ? 10 : (c) == 'B' ? 11 \
: (c) == 'C' ? 12 : (c) == 'D' ? 13 \
: (c) == 'E' ? 14 : 15 )
#define PAIR(u,v) (HEX(u) << 4 | HEX(v))
#define SOME_COOL_MACRO_HERE(x) { \
PAIR((x)[0],(x)[1]), PAIR((x)[2],(x)[3]), \
PAIR((x)[4],(x)[5]), PAIR((x)[6],(x)[7]), \
...
PAIR((x)[30],(x)[31]), 0 }
This approach has many disadvantages. There's no way to check
that the right number of characters has been supplied, nor that
they are all valid hex digits. Also, it's not suitable for
initializing a static variable because the array subscripts
(that is, the pointer dereferences) -- mean that the expressions
inside the initializer are not "constant expressions").
I find I'm unable to rid myself of the strong feeling that
you are doing something stupi^H^H^H^H^Hyou will regret.
--
Eric Sosman
eso...@ieee-dot-org.invalid
> I need a macro to transform an value like 274A into {(char)0x27, (char)
> 0x4A}. Does anyone know how to do it, or where can I find more
> information about this kind of macro?
I don't think you can do it with the Standard C preprocessor. It's time to
write a little utility to do the transformation.
--
Thad
Like
$ printf '%s\n' '75B22636-668E-11CF-A6D900AA0062CE6C' \
| sed 's/-//g;s/\(..\)/0x\1u, /g'
returns
0x75u, 0xB2u, 0x26u, 0x36u, 0x66u, 0x8Eu, 0x11u, 0xCFu, 0xA6u, 0xD9u,
0x00u, 0xAAu, 0x00u, 0x62u, 0xCEu, 0x6Cu,
(Line break added manually for readibility.) The input string must have
an even number of nibbles.
----v----
static const char unsigned uuid[] = { UUID_INITIALIZER_LIST };
----^----
$ gcc -c -D UUID_INITIALIZER_LIST="$(printf ... | sed ...)" source.c
With bash, one can use the <<< redirection operator ("here string")
instead of the printf command and the pipeline.
$ sed 's/-//g;s/\(..\)/0x\1u, /g' <<< '75B22636-668E-11CF-A6D900AA0062CE6C'
Note that C90 6.5.7 "Initialization" explicitly allows the trailing
comma (also shown in Example 5), and so does C99 6.7.8 "Initialization".
The C99 Rationale v5.10 says in 6.7.8 "Initialization", page 89, lines
5-9:
----v----
K&R allows a trailing comma in an initializer at the end of an
initializer-list. The Standard has retained this syntax, since it
provides flexibility in adding or deleting members from an initializer
list, and simplifies machine generation of such lists.
----^----
Cheers,
lacos
#include "stdio.h"
#define themacro(x) {(char)(x>>8),(char)(x&255)}
int main(void) {
char a[2]=themacro(0x274A);
printf ("A = %X %X\n",a[0],a[1]);
}
Or am I missing something?
(The value is expanded into decimal rather than hex constants; that didn't
seem important as you don't usually see the macro expansions)
--
Bartc
No, the macro expanded into constant expressions such as
``(char)(0x274A>>8)'' and ``(char)(0x274A&255)''. The results of
evaluating those constant expressions are numeric values which are
not inherently either decimal or hexadecimal.
Note that converting a value exceeding 127 to char might cause
problems. It's almost certainly better to use unsigned char.
As far as I can tell, we *still* don't know exactly what the original
poster is asking for.
He went away after somebody (Jacob Navia, I think) suggested he
use his system's UUID en/decoding functions, and the example
values he gave looked an awful lot like UUID's, so I'd say
that was a safe bet that's what he needed.
(Specifically, I think he wanted to copy UUID's from his system
into a #define in some include file and have the code interpret
it properly without needing any special formatting.)
Andrew
Andre wrote:
> I need a macro to transform an value like 274A into {(char)0x27, (char)
> 0x4A}. Does anyone know how to do it, or where can I find more
> information about this kind of macro?
Don't use macros. They are dangerous. Use inline functions instead.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (GNU/Linux)
iEYEARECAAYFAktrzCwACgkQm4klUUKw07ClwwCdHm+RyWuiDPcH+6Xp/Rs+bhNB
dn8AniI/07Z9gcywUG/LKEejzS+lfeEA
=X+DB
-----END PGP SIGNATURE-----
When you've figured out a way to make an inline function
return a brace-enclosed list of values, please tell us how
you did it.
--
Eric Sosman
eso...@ieee-dot-org.invalid