42#define LARGEST_SIGNED long long int
44#define LARGEST_SIGNED long int
48#ifndef LARGEST_UNSIGNED
50#define LARGEST_UNSIGNED unsigned long long int
52#define LARGEST_UNSIGNED unsigned long int
57#define POINTER_INT uintptr_t
60typedef uint32_t FormatFlags;
62#define MAKE_MASK(shift, size) (((1 << size) - 1) << (shift))
64#define JUSTIFY_SHIFT 0
66#define JUSTIFY_RIGHT 0x0000
67#define JUSTIFY_LEFT 0x0001
68#define JUSTIFY_MASK MAKE_MASK(JUSTIFY_SHIFT, JUSTIFY_SIZE)
71#define POSITIVE_SHIFT (JUSTIFY_SHIFT + JUSTIFY_SIZE)
72#define POSITIVE_NONE (0x0000 << POSITIVE_SHIFT)
73#define POSITIVE_SPACE (0x0001 << POSITIVE_SHIFT)
74#define POSITIVE_PLUS (0x0003 << POSITIVE_SHIFT)
75#define POSITIVE_MASK MAKE_MASK(POSITIVE_SHIFT, POSITIVE_SIZE)
77#define POSITIVE_SIZE 2
79#define ALTERNATE_FORM_SHIFT (POSITIVE_SHIFT + POSITIVE_SIZE)
80#define ALTERNATE_FORM_SIZE 1
81#define ALTERNATE_FORM (0x0001 << ALTERNATE_FORM_SHIFT)
83#define PAD_SHIFT (ALTERNATE_FORM_SHIFT + ALTERNATE_FORM_SIZE)
85#define PAD_SPACE (0x0000 << PAD_SHIFT)
86#define PAD_ZERO (0x0001 << PAD_SHIFT)
88#define SIZE_SHIFT (PAD_SHIFT + PAD_SIZE)
90#define SIZE_CHAR (0x0001 << SIZE_SHIFT)
91#define SIZE_SHORT (0x0002 << SIZE_SHIFT)
92#define SIZE_INT (0x0000 << SIZE_SHIFT)
93#define SIZE_LONG (0x0003 << SIZE_SHIFT)
94#define SIZE_LONGLONG (0x0004 << SIZE_SHIFT)
95#define SIZE_MASK MAKE_MASK(SIZE_SHIFT, SIZE_SIZE)
97#define CONV_SHIFT (SIZE_SHIFT + SIZE_SIZE)
99#define CONV_INTEGER (0x0001 << CONV_SHIFT)
100#define CONV_FLOAT (0x0002 << CONV_SHIFT)
101#define CONV_POINTER (0x0003 << CONV_SHIFT)
102#define CONV_STRING (0x0004 << CONV_SHIFT)
103#define CONV_CHAR (0x0005 << CONV_SHIFT)
104#define CONV_PERCENT (0x0006 << CONV_SHIFT)
105#define CONV_WRITTEN (0x0007 << CONV_SHIFT)
106#define CONV_MASK MAKE_MASK(CONV_SHIFT, CONV_SIZE)
108#define RADIX_SHIFT (CONV_SHIFT + CONV_SIZE)
110#define RADIX_DECIMAL (0x0001 << RADIX_SHIFT)
111#define RADIX_OCTAL (0x0002 << RADIX_SHIFT)
112#define RADIX_HEX (0x0003 << RADIX_SHIFT)
113#define RADIX_MASK MAKE_MASK(RADIX_SHIFT, RADIX_SIZE)
115#define SIGNED_SHIFT (RADIX_SHIFT + RADIX_SIZE)
117#define SIGNED_NO (0x0000 << SIGNED_SHIFT)
118#define SIGNED_YES (0x0001 << SIGNED_SHIFT)
119#define SIGNED_MASK MAKE_MASK(SIGNED_SHIFT, SIGNED_SIZE)
121#define CAPS_SHIFT (SIGNED_SHIFT + SIGNED_SIZE)
123#define CAPS_NO (0x0000 << CAPS_SHIFT)
124#define CAPS_YES (0x0001 << CAPS_SHIFT)
125#define CAPS_MASK MAKE_MASK(CAPS_SHIFT, CAPS_SIZE)
127#define FLOAT_SHIFT (CAPS_SHIFT + CAPS_SIZE)
129#define FLOAT_NORMAL (((uint32_t)0x0000) << FLOAT_SHIFT)
130#define FLOAT_EXPONENT (((uint32_t)0x0001) << FLOAT_SHIFT)
131#define FLOAT_DEPENDANT (((uint32_t)0x0002) << FLOAT_SHIFT)
132#define FLOAT_HEX (((uint32_t)0x0003) << FLOAT_SHIFT)
133#define FLOAT_MASK MAKE_MASK(FLOAT_SHIFT, FLOAT_SIZE)
135#define CHECKCB(res) { if((res) != STRFORMAT_OK) { return -1; } }
137#define MAXCHARS_HEX ((sizeof(LARGEST_UNSIGNED) * 8) / 4)
140#define MAXCHARS ((sizeof(LARGEST_UNSIGNED) * 8 + 2) / 3)
143parse_flags(
const char **posp)
145 FormatFlags
flags = 0;
146 const char *pos = *posp;
151 flags |= JUSTIFY_LEFT;
154 flags |= POSITIVE_PLUS;
157 flags |= POSITIVE_SPACE;
160 flags |= ALTERNATE_FORM;
175parse_uint(
const char **posp)
178 const char *pos = *posp;
181 while((ch = *pos) >=
'0' && ch <=
'9') {
182 v = v * 10 + (ch -
'0');
192output_uint_decimal(
char **posp, LARGEST_UNSIGNED v)
198 *--pos = (v % 10) +
'0';
209output_uint_hex(
char **posp, LARGEST_UNSIGNED v,
unsigned int flags)
212 const char *hex = (
flags & CAPS_YES) ?
"0123456789ABCDEF" :
"0123456789abcdef";
216 *--pos = hex[(v % 16)];
227output_uint_octal(
char **posp, LARGEST_UNSIGNED v)
233 *--pos = (v % 8) +
'0';
243static strformat_result
244fill_space(
const strformat_context_t *ctxt,
unsigned int len)
246 strformat_result res;
247 static const char buffer[16] =
" ";
250 res = ctxt->write_str(ctxt->user_data, buffer, 16);
251 if(res != STRFORMAT_OK) {
261 return ctxt->write_str(ctxt->user_data, buffer, len);
264static strformat_result
265fill_zero(
const strformat_context_t *ctxt,
unsigned int len)
267 strformat_result res;
268 static const char buffer[16] =
"0000000000000000";
271 res = ctxt->write_str(ctxt->user_data, buffer, 16);
272 if(res != STRFORMAT_OK) {
281 return ctxt->write_str(ctxt->user_data, buffer, len);
285format_str(
const strformat_context_t *ctxt,
const char *format, ...)
289 va_start(ap, format);
290 ret = format_str_v(ctxt, format, ap);
296format_str_v(
const strformat_context_t *ctxt,
const char *format, va_list ap)
298 unsigned int written = 0;
299 const char *pos = format;
301 while(*pos !=
'\0') {
303 unsigned int minwidth = 0;
306 const char *
start = pos;
308 while((ch = *pos) !=
'\0' && ch !=
'%') {
313 CHECKCB(ctxt->write_str(ctxt->user_data,
start, pos -
start));
314 written += pos -
start;
327 flags = parse_flags(&pos);
330 if(*pos >=
'1' && *pos <=
'9') {
331 minwidth = parse_uint(&pos);
332 }
else if(*pos ==
'*') {
333 int w = va_arg(ap,
int);
336 flags |= JUSTIFY_LEFT;
349 if(*pos >=
'0' && *pos <=
'9') {
350 precision = parse_uint(&pos);
351 }
else if(*pos ==
'*') {
353 precision = va_arg(ap,
int);
364 flags |= SIZE_LONGLONG;
369 }
else if(*pos ==
'h') {
378 }
else if(*pos ==
'z') {
379 if(
sizeof(
size_t) ==
sizeof(
short)) {
381 }
else if(
sizeof(
size_t) ==
sizeof(
long)) {
384 }
else if(
sizeof(
size_t) ==
sizeof(
long long)) {
385 flags |= SIZE_LONGLONG;
395 flags |= CONV_INTEGER | RADIX_DECIMAL | SIGNED_YES;
398 flags |= CONV_INTEGER | RADIX_DECIMAL | SIGNED_NO;
401 flags |= CONV_INTEGER | RADIX_OCTAL | SIGNED_NO;
404 flags |= CONV_INTEGER | RADIX_HEX | SIGNED_NO;
407 flags |= CONV_INTEGER | RADIX_HEX | SIGNED_NO | CAPS_YES;
425 flags |= CONV_STRING;
428 flags |= CONV_POINTER;
431 flags |= CONV_WRITTEN;
434 flags |= CONV_PERCENT;
441 switch(
flags & CONV_MASK) {
443 CHECKCB(ctxt->write_str(ctxt->user_data,
"%", 1));
450 unsigned int prefix_len = 0;
451 char buffer[MAXCHARS];
452 char *conv_pos = buffer + MAXCHARS;
453 unsigned int conv_len = 0;
454 unsigned int width = 0;
455 unsigned int precision_fill;
456 unsigned int field_fill;
457 LARGEST_UNSIGNED uvalue = 0;
466 if(
flags & SIGNED_YES) {
468 LARGEST_SIGNED
value = 0;
469 switch(
flags & SIZE_MASK) {
471 value = (
signed char)va_arg(ap,
int);
474 value = (short)va_arg(ap,
int);
477 value = va_arg(ap,
int);
483 value = va_arg(ap,
long);
487 value = va_arg(ap,
long long);
499 switch(
flags & SIZE_MASK) {
501 uvalue = (
unsigned char)va_arg(ap,
unsigned int);
504 uvalue = (
unsigned short)va_arg(ap,
unsigned int);
507 uvalue = va_arg(ap,
unsigned int);
513 uvalue = va_arg(ap,
unsigned long);
517 uvalue = va_arg(ap,
unsigned long long);
523 switch(
flags & (RADIX_MASK)) {
525 conv_len = output_uint_decimal(&conv_pos, uvalue);
528 conv_len = output_uint_octal(&conv_pos, uvalue);
531 conv_len = output_uint_hex(&conv_pos, uvalue,
flags);
536 precision_fill = (precision > conv_len) ? precision - conv_len : 0;
537 if((
flags & (RADIX_MASK | ALTERNATE_FORM))
538 == (RADIX_OCTAL | ALTERNATE_FORM)) {
539 if(precision_fill < 1) {
544 width += precision_fill;
546 if((
flags & (RADIX_MASK | ALTERNATE_FORM))
547 == (RADIX_HEX | ALTERNATE_FORM) && uvalue != 0) {
549 if(
flags & CAPS_YES) {
556 if(
flags & SIGNED_YES) {
561 switch(
flags & POSITIVE_MASK) {
576 field_fill = (minwidth > width) ? minwidth - width : 0;
578 if((
flags & JUSTIFY_MASK) == JUSTIFY_RIGHT) {
579 if(
flags & PAD_ZERO) {
580 precision_fill += field_fill;
583 CHECKCB(fill_space(ctxt, field_fill));
588 CHECKCB(ctxt->write_str(ctxt->user_data, prefix, prefix_len));
590 written += prefix_len;
592 CHECKCB(fill_zero(ctxt, precision_fill));
593 written += precision_fill;
595 CHECKCB(ctxt->write_str(ctxt->user_data, conv_pos, conv_len));
598 if((
flags & JUSTIFY_MASK) == JUSTIFY_LEFT) {
599 CHECKCB(fill_space(ctxt, field_fill));
601 written += field_fill;
606 unsigned int field_fill;
608 char *str = va_arg(ap,
char *);
612 while(*pos !=
'\0') pos++;
619 if(precision >= 0 && precision < len) {
623 field_fill = (minwidth > len) ? minwidth - len : 0;
625 if((
flags & JUSTIFY_MASK) == JUSTIFY_RIGHT) {
626 CHECKCB(fill_space(ctxt, field_fill));
629 CHECKCB(ctxt->write_str(ctxt->user_data, str, len));
632 if((
flags & JUSTIFY_MASK) == JUSTIFY_LEFT) {
633 CHECKCB(fill_space(ctxt, field_fill));
635 written += field_fill;
640 LARGEST_UNSIGNED uvalue =
641 (LARGEST_UNSIGNED)(POINTER_INT)va_arg(ap,
void *);
642 char buffer[MAXCHARS_HEX + 2];
643 char *conv_pos = buffer + MAXCHARS_HEX + 2;
644 unsigned int conv_len;
645 unsigned int field_fill;
647 conv_len = output_uint_hex(&conv_pos, uvalue,
flags);
658 field_fill = (minwidth > conv_len) ? minwidth - conv_len : 0;
660 if((
flags & JUSTIFY_MASK) == JUSTIFY_RIGHT) {
661 CHECKCB(fill_space(ctxt, field_fill));
664 CHECKCB(ctxt->write_str(ctxt->user_data, conv_pos, conv_len));
667 if((
flags & JUSTIFY_MASK) == JUSTIFY_LEFT) {
668 CHECKCB(fill_space(ctxt, field_fill));
671 written += field_fill;
676 char ch = va_arg(ap,
int);
677 unsigned int field_fill = (minwidth > 1) ? minwidth - 1 : 0;
679 if((
flags & JUSTIFY_MASK) == JUSTIFY_RIGHT) {
680 CHECKCB(fill_space(ctxt, field_fill));
683 CHECKCB(ctxt->write_str(ctxt->user_data, &ch, 1));
686 if((
flags & JUSTIFY_MASK) == JUSTIFY_LEFT) {
687 CHECKCB(fill_space(ctxt, field_fill));
689 written += field_fill;
696 (void)va_arg(ap,
int *);
702 (void)va_arg(ap,
double);
static volatile at86rf215_flags_t flags
The radio driver uses the following flags to keep track of the current state of the radio and IRQ eve...
static int value(int type)
static void start(void)
Start measurement.