| 61 |
\note If the strings you are working on resident in program space (flash), |
\note If the strings you are working on resident in program space (flash), |
| 62 |
you will need to use the string functions described in \ref avr_pgmspace. */ |
you will need to use the string functions described in \ref avr_pgmspace. */ |
| 63 |
|
|
| 64 |
|
/** \ingroup avr_string |
| 65 |
|
|
| 66 |
|
This function find the first (least significant) bit set in the input value. |
| 67 |
|
|
| 68 |
|
\returns The ffs() function returns the position of the first |
| 69 |
|
(least significant) bit set in the word val, or 0 if no bits are set. |
| 70 |
|
The least significant bit is position 1. |
| 71 |
|
|
| 72 |
|
\note The ffs() (and only ffs()) is implemented as macro, that evaluates |
| 73 |
|
a constant argument at compile time. */ |
| 74 |
|
extern int ffs (int val) __attribute__((const)); |
| 75 |
|
|
| 76 |
|
/* FIXME: expression, like 'ffs(ffs(ffs(...(CONSTANT)))', take very |
| 77 |
|
large amount of memory at compile time. */ |
| 78 |
|
#define ffs(x) ( \ |
| 79 |
|
__builtin_constant_p (x) ? \ |
| 80 |
|
( (x) & 1 ? 1 \ |
| 81 |
|
: (x) & 2 ? 2 \ |
| 82 |
|
: (x) & 4 ? 3 \ |
| 83 |
|
: (x) & 010 ? 4 \ |
| 84 |
|
: (x) & 020 ? 5 \ |
| 85 |
|
: (x) & 040 ? 6 \ |
| 86 |
|
: (x) & 0100 ? 7 \ |
| 87 |
|
: (x) & 0200 ? 8 \ |
| 88 |
|
: (x) & 0400 ? 9 \ |
| 89 |
|
: (x) & 01000 ? 10 \ |
| 90 |
|
: (x) & 02000 ? 11 \ |
| 91 |
|
: (x) & 04000 ? 12 \ |
| 92 |
|
: (x) & 010000 ? 13 \ |
| 93 |
|
: (x) & 020000 ? 14 \ |
| 94 |
|
: (x) & 040000 ? 15 \ |
| 95 |
|
: (x) & 0100000 ? 16 \ |
| 96 |
|
: 0 ) \ |
| 97 |
|
: ffs(x) ) |
| 98 |
|
|
| 99 |
|
/** \ingroup avr_string |
| 100 |
|
Same as ffs(), for an argument of type long. */ |
| 101 |
|
extern int ffsl (long val) __attribute__((const)); |
| 102 |
|
|
| 103 |
|
/** \ingroup avr_string |
| 104 |
|
Same as ffs(), for an argument of type long long. */ |
| 105 |
|
extern int ffsll (long long val) __attribute__((const)); |
| 106 |
|
|
| 107 |
extern void *memccpy(void *, const void *, int, size_t); |
extern void *memccpy(void *, const void *, int, size_t); |
| 108 |
extern void *memchr(const void *, int, size_t) __ATTR_PURE__; |
extern void *memchr(const void *, int, size_t) __ATTR_PURE__; |
| 109 |
extern int memcmp(const void *, const void *, size_t) __ATTR_PURE__; |
extern int memcmp(const void *, const void *, size_t) __ATTR_PURE__; |