author | Olivier Brunel
<jjk@jjacky.com> 2023-02-20 20:32:45 UTC |
committer | Olivier Brunel
<jjk@jjacky.com> 2023-02-20 20:32:45 UTC |
parent | 43295558b288f95abc5ffdab686c30a711460e4f |
doc/u16_fmt.3.md | +84 | -0 |
doc/u16_le.3.md | +46 | -0 |
doc/u16_scan.3.md | +67 | -0 |
doc/u32_fmt.3.md | +84 | -0 |
doc/u32_le.3.md | +46 | -0 |
doc/u32_scan.3.md | +67 | -0 |
doc/u64_fmt.3.md | +84 | -0 |
doc/u64_fmt_generic.3.md | +38 | -0 |
doc/u64_le.3.md | +46 | -0 |
doc/u64_scan.3.md | +67 | -0 |
include/limb/u16.h | +37 | -0 |
include/limb/u32.h | +37 | -0 |
include/limb/u64.h | +40 | -0 |
meta/libs/limb | +3 | -0 |
src/u640_fmt_generic.c | +19 | -0 |
src/u64_fmt_generic.c | +29 | -0 |
diff --git a/doc/u16_fmt.3.md b/doc/u16_fmt.3.md new file mode 100644 index 0000000..8693bbc --- /dev/null +++ b/doc/u16_fmt.3.md @@ -0,0 +1,84 @@ +% limb manual +% u16_fmt(3) + +# NAME + +u16\_fmt, u16\_fmtg, u160\_fmt - print an u16 as decimal value into a byte array + +u16\_xfmt, u160\_xfmt - print an u16 as hexadecimal value into a byte array + +u16\_ofmt, u160\_ofmt - print an u16 as octal value into a byte array + +u16\_bfmt, u160\_bfmt - print an u16 as binary value into a byte array + + +# SYNOPSIS + + #include <limb/u16.h> + +```pre hl +size_t u16_fmt(char *<em>s</em>, u16 <em>u</em>) +size_t u160_fmt(char *<em>s</em>, u16 <em>u</em>, size_t <em>min</em>) + +size_t u16_fmtg(char *<em>s</em>, u16 <em>u</em>) +size_t u160_fmtg(char *<em>s</em>, u16 <em>u</em>, size_t <em>min</em>) + +size_t u16_xfmt(char *<em>s</em>, u16 <em>u</em>) +size_t u160_xfmt(char *<em>s</em>, u16 <em>u</em>, size_t <em>min</em>) + +size_t u16_ofmt(char *<em>s</em>, u16 <em>u</em>) +size_t u160_ofmt(char *<em>s</em>, u16 <em>u</em>, size_t <em>min</em>) + +size_t u16_bfmt(char *<em>s</em>, u16 <em>u</em>) +size_t u160_bfmt(char *<em>s</em>, u16 <em>u</em>, size_t <em>min</em>) +``` + +# DESCRIPTION + +The `u16_fmt`() function will put into `s` the value of `u` in decimal. +The `u160_fmt`() function will put into `s` the value of `u` in decimal, +prefixing it with leading zeroes if it requires less than `min` characters to do +so. + +The `u16_fmtg`() and `u160_fmtg`() function are similar, only they will use a +coma (`,`) as thousand separator as needed. + +The `u16_xfmt`() and `u160_xfmt`() functions are similar, only putting the value +of `u` in hexadecimal. + +The `u16_ofmt`() and `u160_ofmt`() functions are similar, only putting the value +of `u` in octal. + +The `u16_bfmt`() and `u160_bfmt`() functions are similar, only putting the value +of `u` in binary. + +It is possible to use `NULL` as `s` to only have length computation performed. + +Note that those are macros to [u64_fmt_generic](3). + +## Constants + +Some constants are available if needed, e.g. to allocate a buffer large enough : + +: *U16_FMT* +:: Maximum number of `char` needed to hold a decimal string + +: *U16_FMTG* +:: Maximum number of `char` needed to hold a thousand-separated decimal string + +: *U16_XFMT* +:: Maximum number of `char` needed to hold an hexadecimal string + +: *U16_OFMT* +:: Maximum number of `char` needed to hold an octal string + +: *U16_BFMT* +:: Maximum number of `char` needed to hold a binary string + +Note that all of those include an extra `char` for a proper NUL-terminated +string. + +# RETURN VALUE + +All of these return the length of the string written into `s`, or required to +do so when `s` is `NULL` diff --git a/doc/u16_le.3.md b/doc/u16_le.3.md new file mode 100644 index 0000000..b1539ff --- /dev/null +++ b/doc/u16_le.3.md @@ -0,0 +1,46 @@ +% limb manual +% u16_le(3) + +# NAME + +u16\_le, u16\_be - convert a value to little\/big endian + +u16p\_le, u16p\_be - convert an u16 into little\/big endian + +u16pa\_le, u16pa\_be - convert an array of u16 into little\/big endian + +# SYNOPSIS + + #include <limb/u16.h> + +```pre hl +u16 u16_le(u16 <em>u</em>) +u16 u16_be(u16 <em>u</em>) + +void u16p_le(u16 *<em>val</em>) +void u16p_be(u16 *<em>val</em>) + +void u16pa_le(u16 *<em>val</em>, size_t <em>length</em>) +void u16pa_be(u16 *<em>val</em>, size_t <em>length</em>) +``` + +# DESCRIPTION + +All of these aim to ensure a value or variable is in expected endianness. + +The `u16_le`() and `u16_be`() functions will return the value after having read +the given number `u` as a little endian and big endian value respectively. + +The `u16p_le`() and `u16p_be`() functions are similar, only they take a pointer +to an u16 and will convert it into little endian and big endian, respectively. + +Finally the `u16pa_le`() and `u16pa_be`() are similar to the previous two, only +they take an array of u16 of size `length` and convert every element. + +These are actually macros to the relevant `uint16_*` functions as needed, i.e. +if the requested endianness is that of the host, no operation is performed. + +# RETURN VALUE + +Only `u16_le`() and `u16_be`() have a return value, that of the number `u` read +as a little or big endian number, respectively. diff --git a/doc/u16_scan.3.md b/doc/u16_scan.3.md new file mode 100644 index 0000000..fb79fe7 --- /dev/null +++ b/doc/u16_scan.3.md @@ -0,0 +1,67 @@ +% limb manual +% u16_scan(3) + +# NAME + +u16\_scan, u160\_scan - Read an u16 value from a decimal string + +u16\_xscan, u160\_xscan - Read an u16 value from an hexadecimal string + +u16\_oscan, u160\_oscan - Read an u16 value from an octal string + +u16\_bscan, u160\_bscan - Read an u16 value from a binary string + + +# SYNOPSIS + + #include <limb/u16.h> + +```pre hl +size_t u16_scan(u16 *<em>dst</em>, const char *<em>s</em>) +size_t u160_scan(u16 *<em>dst</em>, const char *<em>s</em>) + +size_t u16_xscan(u16 *<em>dst</em>, const char *<em>s</em>) +size_t u160_xscan(u16 *<em>dst</em>, const char *<em>s</em>) + +size_t u16_oscan(u16 *<em>dst</em>, const char *<em>s</em>) +size_t u160_oscan(u16 *<em>dst</em>, const char *<em>s</em>) + +size_t u16_bscan(u16 *<em>dst</em>, const char *<em>s</em>) +size_t u160_bscan(u16 *<em>dst</em>, const char *<em>s</em>) +``` + +# DESCRIPTION + +The `u16_scan`() function will place into `dst` the number read as a decimal +value from the string `s`, stopping as soon as a character isn't valid. + +The `u160_scan`() function is similar but expects the string to contain a valid +value and nothing else, stopping with a NUL-terminating byte. + +The `u16_xscan`() and `u160_xscan`() functions are similar, but expecting an +hexadecimal value in `s`. + +The `u16_oscan`() and `u160_oscan`() functions are similar, but expecting an +octal value in `s`. + +The `u16_bscan`() and `u160_bscan`() functions are similar, but expecting a +binary value in `s`. + + +# RETURN VALUE + +The `u16_*` family of functions return the number of characters read from `s` +(starting at 0 when the first character is invalid). + +The `u160_*` family of functions return the number of characters read from `s` +or 0 on error. + +# ERRORS + +The `u160_*` family of functions may fail and set `errno` if : + +: *EINVAL* +:: Invalid character in `s` + +: *ERANGE* +:: The value in `s` is too large diff --git a/doc/u32_fmt.3.md b/doc/u32_fmt.3.md new file mode 100644 index 0000000..1cab022 --- /dev/null +++ b/doc/u32_fmt.3.md @@ -0,0 +1,84 @@ +% limb manual +% u32_fmt(3) + +# NAME + +u32\_fmt, u32\_fmtg, u320\_fmt - print an u32 as decimal value into a byte array + +u32\_xfmt, u320\_xfmt - print an u32 as hexadecimal value into a byte array + +u32\_ofmt, u320\_ofmt - print an u32 as octal value into a byte array + +u32\_bfmt, u320\_bfmt - print an u32 as binary value into a byte array + + +# SYNOPSIS + + #include <limb/u32.h> + +```pre hl +size_t u32_fmt(char *<em>s</em>, u32 <em>u</em>) +size_t u320_fmt(char *<em>s</em>, u32 <em>u</em>, size_t <em>min</em>) + +size_t u32_fmtg(char *<em>s</em>, u32 <em>u</em>) +size_t u320_fmtg(char *<em>s</em>, u32 <em>u</em>, size_t <em>min</em>) + +size_t u32_xfmt(char *<em>s</em>, u32 <em>u</em>) +size_t u320_xfmt(char *<em>s</em>, u32 <em>u</em>, size_t <em>min</em>) + +size_t u32_ofmt(char *<em>s</em>, u32 <em>u</em>) +size_t u320_ofmt(char *<em>s</em>, u32 <em>u</em>, size_t <em>min</em>) + +size_t u32_bfmt(char *<em>s</em>, u32 <em>u</em>) +size_t u320_bfmt(char *<em>s</em>, u32 <em>u</em>, size_t <em>min</em>) +``` + +# DESCRIPTION + +The `u32_fmt`() function will put into `s` the value of `u` in decimal. +The `u320_fmt`() function will put into `s` the value of `u` in decimal, +prefixing it with leading zeroes if it requires less than `min` characters to do +so. + +The `u32_fmtg`() and `u320_fmtg`() function are similar, only they will use a +coma (`,`) as thousand separator as needed. + +The `u32_xfmt`() and `u320_xfmt`() functions are similar, only putting the value +of `u` in hexadecimal. + +The `u32_ofmt`() and `u320_ofmt`() functions are similar, only putting the value +of `u` in octal. + +The `u32_bfmt`() and `u320_bfmt`() functions are similar, only putting the value +of `u` in binary. + +It is possible to use `NULL` as `s` to only have length computation performed. + +Note that those are macros to [u64_fmt_generic](3). + +## Constants + +Some constants are available if needed, e.g. to allocate a buffer large enough : + +: *U32_FMT* +:: Maximum number of `char` needed to hold a decimal string + +: *U32_FMTG* +:: Maximum number of `char` needed to hold a thousand-separated decimal string + +: *U32_XFMT* +:: Maximum number of `char` needed to hold an hexadecimal string + +: *U32_OFMT* +:: Maximum number of `char` needed to hold an octal string + +: *U32_BFMT* +:: Maximum number of `char` needed to hold a binary string + +Note that all of those include an extra `char` for a proper NUL-terminated +string. + +# RETURN VALUE + +All of these return the length of the string written into `s`, or required to +do so when `s` is `NULL` diff --git a/doc/u32_le.3.md b/doc/u32_le.3.md new file mode 100644 index 0000000..d2e6aea --- /dev/null +++ b/doc/u32_le.3.md @@ -0,0 +1,46 @@ +% limb manual +% u32_le(3) + +# NAME + +u32\_le, u32\_be - convert a value to little\/big endian + +u32p\_le, u32p\_be - convert an u32 into little\/big endian + +u32pa\_le, u32pa\_be - convert an array of u32 into little\/big endian + +# SYNOPSIS + + #include <limb/u32.h> + +```pre hl +u32 u32_le(u32 <em>u</em>) +u32 u32_be(u32 <em>u</em>) + +void u32p_le(u32 *<em>val</em>) +void u32p_be(u32 *<em>val</em>) + +void u32pa_le(u32 *<em>val</em>, size_t <em>length</em>) +void u32pa_be(u32 *<em>val</em>, size_t <em>length</em>) +``` + +# DESCRIPTION + +All of these aim to ensure a value or variable is in expected endianness. + +The `u32_le`() and `u32_be`() functions will return the value after having read +the given number `u` as a little endian and big endian value respectively. + +The `u32p_le`() and `u32p_be`() functions are similar, only they take a pointer +to an u32 and will convert it into little endian and big endian, respectively. + +Finally the `u32pa_le`() and `u32pa_be`() are similar to the previous two, only +they take an array of u32 of size `length` and convert every element. + +These are actually macros to the relevant `uint32_*` functions as needed, i.e. +if the requested endianness is that of the host, no operation is performed. + +# RETURN VALUE + +Only `u32_le`() and `u32_be`() have a return value, that of the number `u` read +as a little or big endian number, respectively. diff --git a/doc/u32_scan.3.md b/doc/u32_scan.3.md new file mode 100644 index 0000000..4e07202 --- /dev/null +++ b/doc/u32_scan.3.md @@ -0,0 +1,67 @@ +% limb manual +% u32_scan(3) + +# NAME + +u32\_scan, u320\_scan - Read an u32 value from a decimal string + +u32\_xscan, u320\_xscan - Read an u32 value from an hexadecimal string + +u32\_oscan, u320\_oscan - Read an u32 value from an octal string + +u32\_bscan, u320\_bscan - Read an u32 value from a binary string + + +# SYNOPSIS + + #include <limb/u32.h> + +```pre hl +size_t u32_scan(u32 *<em>dst</em>, const char *<em>s</em>) +size_t u320_scan(u32 *<em>dst</em>, const char *<em>s</em>) + +size_t u32_xscan(u32 *<em>dst</em>, const char *<em>s</em>) +size_t u320_xscan(u32 *<em>dst</em>, const char *<em>s</em>) + +size_t u32_oscan(u32 *<em>dst</em>, const char *<em>s</em>) +size_t u320_oscan(u32 *<em>dst</em>, const char *<em>s</em>) + +size_t u32_bscan(u32 *<em>dst</em>, const char *<em>s</em>) +size_t u320_bscan(u32 *<em>dst</em>, const char *<em>s</em>) +``` + +# DESCRIPTION + +The `u32_scan`() function will place into `dst` the number read as a decimal +value from the string `s`, stopping as soon as a character isn't valid. + +The `u320_scan`() function is similar but expects the string to contain a valid +value and nothing else, stopping with a NUL-terminating byte. + +The `u32_xscan`() and `u320_xscan`() functions are similar, but expecting an +hexadecimal value in `s`. + +The `u32_oscan`() and `u320_oscan`() functions are similar, but expecting an +octal value in `s`. + +The `u32_bscan`() and `u320_bscan`() functions are similar, but expecting a +binary value in `s`. + + +# RETURN VALUE + +The `u32_*` family of functions return the number of characters read from `s` +(starting at 0 when the first character is invalid). + +The `u320_*` family of functions return the number of characters read from `s` +or 0 on error. + +# ERRORS + +The `u320_*` family of functions may fail and set `errno` if : + +: *EINVAL* +:: Invalid character in `s` + +: *ERANGE* +:: The value in `s` is too large diff --git a/doc/u64_fmt.3.md b/doc/u64_fmt.3.md new file mode 100644 index 0000000..d6954b6 --- /dev/null +++ b/doc/u64_fmt.3.md @@ -0,0 +1,84 @@ +% limb manual +% u64_fmt(3) + +# NAME + +u64\_fmt, u64\_fmtg, u640\_fmt - print an u64 as decimal value into a byte array + +u64\_xfmt, u640\_xfmt - print an u64 as hexadecimal value into a byte array + +u64\_ofmt, u640\_ofmt - print an u64 as octal value into a byte array + +u64\_bfmt, u640\_bfmt - print an u64 as binary value into a byte array + + +# SYNOPSIS + + #include <limb/u64.h> + +```pre hl +size_t u64_fmt(char *<em>s</em>, u64 <em>u</em>) +size_t u640_fmt(char *<em>s</em>, u64 <em>u</em>, size_t <em>min</em>) + +size_t u64_fmtg(char *<em>s</em>, u64 <em>u</em>) +size_t u640_fmtg(char *<em>s</em>, u64 <em>u</em>, size_t <em>min</em>) + +size_t u64_xfmt(char *<em>s</em>, u64 <em>u</em>) +size_t u640_xfmt(char *<em>s</em>, u64 <em>u</em>, size_t <em>min</em>) + +size_t u64_ofmt(char *<em>s</em>, u64 <em>u</em>) +size_t u640_ofmt(char *<em>s</em>, u64 <em>u</em>, size_t <em>min</em>) + +size_t u64_bfmt(char *<em>s</em>, u64 <em>u</em>) +size_t u640_bfmt(char *<em>s</em>, u64 <em>u</em>, size_t <em>min</em>) +``` + +# DESCRIPTION + +The `u64_fmt`() function will put into `s` the value of `u` in decimal. +The `u640_fmt`() function will put into `s` the value of `u` in decimal, +prefixing it with leading zeroes if it requires less than `min` characters to do +so. + +The `u64_fmtg`() and `u640_fmtg`() function are similar, only they will use a +coma (`,`) as thousand separator as needed. + +The `u64_xfmt`() and `u640_xfmt`() functions are similar, only putting the value +of `u` in hexadecimal. + +The `u64_ofmt`() and `u640_ofmt`() functions are similar, only putting the value +of `u` in octal. + +The `u64_bfmt`() and `u640_bfmt`() functions are similar, only putting the value +of `u` in binary. + +It is possible to use `NULL` as `s` to only have length computation performed. + +Note that those are macros to [u64_fmt_generic](3). + +## Constants + +Some constants are available if needed, e.g. to allocate a buffer large enough : + +: *U64_FMT* +:: Maximum number of `char` needed to hold a decimal string + +: *U64_FMTG* +:: Maximum number of `char` needed to hold a thousand-separated decimal string + +: *U64_XFMT* +:: Maximum number of `char` needed to hold an hexadecimal string + +: *U64_OFMT* +:: Maximum number of `char` needed to hold an octal string + +: *U64_BFMT* +:: Maximum number of `char` needed to hold a binary string + +Note that all of those include an extra `char` for a proper NUL-terminated +string. + +# RETURN VALUE + +All of these return the length of the string written into `s`, or required to +do so when `s` is `NULL` diff --git a/doc/u64_fmt_generic.3.md b/doc/u64_fmt_generic.3.md new file mode 100644 index 0000000..85b85ca --- /dev/null +++ b/doc/u64_fmt_generic.3.md @@ -0,0 +1,38 @@ +% limb manual +% u64_fmt_generic(3) + +# NAME + +u64\_fmt\_generic, u640\_fmt\_generic - print an u64 value into a byte array + +# SYNOPSIS + + #include <limb/u64.h> + +```pre hl +size_t u64_fmt_generic(char *<em>s</em>, u64 <em>u</em>, u8 <em>base</em>, u8 <em>grp</em>, const char <em>sep</em>) +size_t u640_fmt_generic(char *<em>s</em>, u64 <em>u</em>, u8 <em>base</em>, size_t <em>min</em>, const char <em>fill</em>, + u8 <em>grp</em>, const char <em>sep</em>) +``` + +# DESCRIPTION + +The `u64_fmt_generic`() function will put into `s` the value of `u` encoded in +base `base`. If `grp` is not zero, `sep` will be used as separator every `grp` +characters, starting from the end. + +The `u640_fmt_generic`() function is similar, only if the size needed is less +than `min` it will fill it up by prefixing it using as many instances of `fill` +as needed. + +It is possible to use `NULL` as `s` to only have length computation performed. + +## Macros + +Note that many macros are available for ease of use, such as [u64_fmt](3), +[u32_fmt](3) or [u16_fmt](3) and their related macros. + +# RETURN VALUE + +Both functions return the length of the string written into `s`, or required to +do so when `s` is `NULL` diff --git a/doc/u64_le.3.md b/doc/u64_le.3.md new file mode 100644 index 0000000..05c41f8 --- /dev/null +++ b/doc/u64_le.3.md @@ -0,0 +1,46 @@ +% limb manual +% u64_le(3) + +# NAME + +u64\_le, u64\_be - convert a value to little\/big endian + +u64p\_le, u64p\_be - convert an u64 into little\/big endian + +u64pa\_le, u64pa\_be - convert an array of u64 into little\/big endian + +# SYNOPSIS + + #include <limb/u64.h> + +```pre hl +u64 u64_le(u64 <em>u</em>) +u64 u64_be(u64 <em>u</em>) + +void u64p_le(u64 *<em>val</em>) +void u64p_be(u64 *<em>val</em>) + +void u64pa_le(u64 *<em>val</em>, size_t <em>length</em>) +void u64pa_be(u64 *<em>val</em>, size_t <em>length</em>) +``` + +# DESCRIPTION + +All of these aim to ensure a value or variable is in expected endianness. + +The `u64_le`() and `u64_be`() functions will return the value after having read +the given number `u` as a little endian and big endian value respectively. + +The `u64p_le`() and `u64p_be`() functions are similar, only they take a pointer +to an u64 and will convert it into little endian and big endian, respectively. + +Finally the `u64pa_le`() and `u64pa_be`() are similar to the previous two, only +they take an array of u64 of size `length` and convert every element. + +These are actually macros to the relevant `uint64_*` functions as needed, i.e. +if the requested endianness is that of the host, no operation is performed. + +# RETURN VALUE + +Only `u64_le`() and `u64_be`() have a return value, that of the number `u` read +as a little or big endian number, respectively. diff --git a/doc/u64_scan.3.md b/doc/u64_scan.3.md new file mode 100644 index 0000000..5d0b2d5 --- /dev/null +++ b/doc/u64_scan.3.md @@ -0,0 +1,67 @@ +% limb manual +% u64_scan(3) + +# NAME + +u64\_scan, u640\_scan - Read an u64 value from a decimal string + +u64\_xscan, u640\_xscan - Read an u64 value from an hexadecimal string + +u64\_oscan, u640\_oscan - Read an u64 value from an octal string + +u64\_bscan, u640\_bscan - Read an u64 value from a binary string + + +# SYNOPSIS + + #include <limb/u64.h> + +```pre hl +size_t u64_scan(u64 *<em>dst</em>, const char *<em>s</em>) +size_t u640_scan(u64 *<em>dst</em>, const char *<em>s</em>) + +size_t u64_xscan(u64 *<em>dst</em>, const char *<em>s</em>) +size_t u640_xscan(u64 *<em>dst</em>, const char *<em>s</em>) + +size_t u64_oscan(u64 *<em>dst</em>, const char *<em>s</em>) +size_t u640_oscan(u64 *<em>dst</em>, const char *<em>s</em>) + +size_t u64_bscan(u64 *<em>dst</em>, const char *<em>s</em>) +size_t u640_bscan(u64 *<em>dst</em>, const char *<em>s</em>) +``` + +# DESCRIPTION + +The `u64_scan`() function will place into `dst` the number read as a decimal +value from the string `s`, stopping as soon as a character isn't valid. + +The `u640_scan`() function is similar but expects the string to contain a valid +value and nothing else, stopping with a NUL-terminating byte. + +The `u64_xscan`() and `u640_xscan`() functions are similar, but expecting an +hexadecimal value in `s`. + +The `u64_oscan`() and `u640_oscan`() functions are similar, but expecting an +octal value in `s`. + +The `u64_bscan`() and `u640_bscan`() functions are similar, but expecting a +binary value in `s`. + + +# RETURN VALUE + +The `u64_*` family of functions return the number of characters read from `s` +(starting at 0 when the first character is invalid). + +The `u640_*` family of functions return the number of characters read from `s` +or 0 on error. + +# ERRORS + +The `u640_*` family of functions may fail and set `errno` if : + +: *EINVAL* +:: Invalid character in `s` + +: *ERANGE* +:: The value in `s` is too large diff --git a/include/limb/u16.h b/include/limb/u16.h index 9c824c6..8fada79 100644 --- a/include/limb/u16.h +++ b/include/limb/u16.h @@ -3,10 +3,47 @@ #include <skalibs/uint16.h> #include "limb/int.h" +#include "limb/u64.h" + +#define u16_le(u) uint16_little(u) +#define u16_be(u) uint16_big(u) + +#define u16p_le(u) uint16_littlep(u) +#define u16p_be(u) uint16_bigp(u) +#define u16pa_le(a,l) uint16_littlen(a,l) +#define u16pa_be(a,l) uint16_bign(a,l) #define u16_pack(dst,val) uint16_pack((char *) (dst), val) #define u16_unpack(val,sce) uint16_unpack((const char *) (sce), val) #define u16_pack_big(dst,val) uint16_pack_big((char *) (dst), val) #define u16_unpack_big(val,sce) uint16_unpack_big((const char *) (sce), val) +#define U16_FMT 6 +#define U16_FMTG 7 +#define U16_XFMT 5 +#define U16_OFMT 7 +#define U16_BFMT 17 + +#define u16_fmt(s,u) u64_fmt_generic(s, (u), 10, 0, 0) +#define u16_fmtg(s,u) u64_fmt_generic(s, (u), 10, 3, ',') +#define u16_xfmt(s,u) u64_fmt_generic(s, (u), 16, 0, 0) +#define u16_ofmt(s,u) u64_fmt_generic(s, (u), 8, 0, 0) +#define u16_bfmt(s,u) u64_fmt_generic(s, (u), 2, 0, 0) + +#define u160_fmt(s,u,m) u640_fmt_generic(s, (u), 10, (m), '0', 0, 0) +#define u160_fmtg(s,u,m) u640_fmt_generic(s, (u), 10, (m), '0', 3, ',') +#define u160_xfmt(s,u,m) u640_fmt_generic(s, (u), 16, (m), '0', 0, 0) +#define u160_ofmt(s,u,m) u640_fmt_generic(s, (u), 8, (m), '0', 0, 0) +#define u160_bfmt(s,u,m) u640_fmt_generic(s, (u), 2, (m), '0', 0, 0) + +#define u16_scan(dst,s) uint16_scan(s, (dst)) +#define u16_xscan(dst,s) uint16_xscan(s, (dst)) +#define u16_oscan(dst,s) uint16_oscan(s, (dst)) +#define u16_bscan(dst,s) uint16_bscan(s, (dst)) + +#define u160_scan(dst,s) uint160_scan(s, (dst)) +#define u160_xscan(dst,s) uint160_xscan(s, (dst)) +#define u160_oscan(dst,s) uint160_oscan(s, (dst)) +#define u160_bscan(dst,s) uint160_bscan(s, (dst)) + #endif /* LIMB_U16_H */ diff --git a/include/limb/u32.h b/include/limb/u32.h index d7c32de..ade1da1 100644 --- a/include/limb/u32.h +++ b/include/limb/u32.h @@ -3,10 +3,47 @@ #include <skalibs/uint32.h> #include "limb/int.h" +#include "limb/u64.h" + +#define u32_le(u) uint32_little(u) +#define u32_be(u) uint32_big(u) + +#define u32p_le(u) uint32_littlep(u) +#define u32p_be(u) uint32_bigp(u) +#define u32pa_le(a,l) uint32_littlen(a,l) +#define u32pa_be(a,l) uint32_bign(a,l) #define u32_pack(dst,val) uint32_pack((char *) (dst), val) #define u32_unpack(val,sce) uint32_unpack((const char *) (sce), val) #define u32_pack_big(dst,val) uint32_pack_big((char *) (dst), val) #define u32_unpack_big(val,sce) uint32_unpack_big((const char *) (sce), val) +#define U32_FMT 11 +#define U32_FMTG 14 +#define U32_XFMT 9 +#define U32_OFMT 13 +#define U32_BFMT 33 + +#define u32_fmt(s,u) u64_fmt_generic(s, (u), 10, 0, 0) +#define u32_fmtg(s,u) u64_fmt_generic(s, (u), 10, 3, ',') +#define u32_xfmt(s,u) u64_fmt_generic(s, (u), 16, 0, 0) +#define u32_ofmt(s,u) u64_fmt_generic(s, (u), 8, 0, 0) +#define u32_bfmt(s,u) u64_fmt_generic(s, (u), 2, 0, 0) + +#define u320_fmt(s,u,m) u640_fmt_generic(s, (u), 10, (m), '0', 0, 0) +#define u320_fmtg(s,u,m) u640_fmt_generic(s, (u), 10, (m), '0', 3, ',') +#define u320_xfmt(s,u,m) u640_fmt_generic(s, (u), 16, (m), '0', 0, 0) +#define u320_ofmt(s,u,m) u640_fmt_generic(s, (u), 8, (m), '0', 0, 0) +#define u320_bfmt(s,u,m) u640_fmt_generic(s, (u), 2, (m), '0', 0, 0) + +#define u32_scan(dst,s) uint32_scan(s, (dst)) +#define u32_xscan(dst,s) uint32_xscan(s, (dst)) +#define u32_oscan(dst,s) uint32_oscan(s, (dst)) +#define u32_bscan(dst,s) uint32_bscan(s, (dst)) + +#define u320_scan(dst,s) uint320_scan(s, (dst)) +#define u320_xscan(dst,s) uint320_xscan(s, (dst)) +#define u320_oscan(dst,s) uint320_oscan(s, (dst)) +#define u320_bscan(dst,s) uint320_bscan(s, (dst)) + #endif /* LIMB_U32_H */ diff --git a/include/limb/u64.h b/include/limb/u64.h index fe79dc4..f66fd20 100644 --- a/include/limb/u64.h +++ b/include/limb/u64.h @@ -5,6 +5,14 @@ #include "limb/int.h" #include "limb/uint64.h" +#define u64_le(u) uint64_little(u) +#define u64_be(u) uint64_big(u) + +#define u64p_le(u) uint64_littlep(u) +#define u64p_be(u) uint64_bigp(u) +#define u64pa_le(a,l) uint64_littlen(a,l) +#define u64pa_be(a,l) uint64_bign(a,l) + #define u64_pack(dst,val) uint64_pack((char *) (dst), val) #define u64_unpack(val,sce) uint64_unpack((const char *) (sce), val) #define u64_pack_big(dst,val) uint64_pack_big((char *) (dst), val) @@ -12,4 +20,36 @@ #define u64_pack_trim(dst,val) uint64_pack_trim((char *) (dst), val) #define u64_unpack_trim(val,sce) uint64_unpack_trim((const char *) (sce), val) +extern size_t u64_fmt_generic(char *s, u64 u, u8 base, u8 grp, const char sep); +extern size_t u640_fmt_generic(char *s, u64 u, u8 base, size_t min, const char fill, + u8 grp, const char sep); + +#define U64_FMT 21 +#define U64_FMTG 27 +#define U64_XFMT 17 +#define U64_OFMT 25 +#define U64_BFMT 65 + +#define u64_fmt(s,u) u64_fmt_generic(s, (u), 10, 0, 0) +#define u64_fmtg(s,u) u64_fmt_generic(s, (u), 10, 3, ',') +#define u64_xfmt(s,u) u64_fmt_generic(s, (u), 16, 0, 0) +#define u64_ofmt(s,u) u64_fmt_generic(s, (u), 8, 0, 0) +#define u64_bfmt(s,u) u64_fmt_generic(s, (u), 2, 0, 0) + +#define u640_fmt(s,u,m) u640_fmt_generic(s, (u), 10, (m), '0', 0, 0) +#define u640_fmtg(s,u,m) u640_fmt_generic(s, (u), 10, (m), '0', 3, ',') +#define u640_xfmt(s,u,m) u640_fmt_generic(s, (u), 16, (m), '0', 0, 0) +#define u640_ofmt(s,u,m) u640_fmt_generic(s, (u), 8, (m), '0', 0, 0) +#define u640_bfmt(s,u,m) u640_fmt_generic(s, (u), 2, (m), '0', 0, 0) + +#define u64_scan(dst,s) uint64_scan(s, (dst)) +#define u64_xscan(dst,s) uint64_xscan(s, (dst)) +#define u64_oscan(dst,s) uint64_oscan(s, (dst)) +#define u64_bscan(dst,s) uint64_bscan(s, (dst)) + +#define u640_scan(dst,s) uint640_scan(s, (dst)) +#define u640_xscan(dst,s) uint640_xscan(s, (dst)) +#define u640_oscan(dst,s) uint640_oscan(s, (dst)) +#define u640_bscan(dst,s) uint640_bscan(s, (dst)) + #endif /* LIMB_U64_H */ diff --git a/meta/libs/limb b/meta/libs/limb index c07cca7..e90f061 100644 --- a/meta/libs/limb +++ b/meta/libs/limb @@ -12,6 +12,9 @@ obj/msb64.o # {,un}pack u64 obj/uint64_pack_trim.o obj/uint64_unpack_trim.o +# u64 +obj/u64_fmt_generic.o +obj/u640_fmt_generic.o # data-encoding (integers or blobs) obj/saencdata.o # content-based chunking diff --git a/src/u640_fmt_generic.c b/src/u640_fmt_generic.c new file mode 100644 index 0000000..fd1ff8f --- /dev/null +++ b/src/u640_fmt_generic.c @@ -0,0 +1,19 @@ +#include <string.h> +#include "limb/u64.h" + +size_t +u640_fmt_generic(char *s, u64 u, u8 base, size_t min, const char fill, + u8 grp, const char sep) +{ + size_t len = u64_fmt_generic(0, u, base, grp, sep); + + if (s) { + if (len < min) { + memset(s, fill, min - len); + s += min - len; + } + u64_fmt_generic(s, u, base, grp, sep); + } + + return (len > min) ? len : min; +} diff --git a/src/u64_fmt_generic.c b/src/u64_fmt_generic.c new file mode 100644 index 0000000..fb3ff18 --- /dev/null +++ b/src/u64_fmt_generic.c @@ -0,0 +1,29 @@ +#include <skalibs/fmtscan.h> +#include "limb/u64.h" + +size_t +u64_fmt_generic(char *s, u64 u, u8 base, u8 grp, const char sep) +{ + size_t len = 1; + u64 n = u; + + while (n >= base) { + ++len; + n /= base; + } + if (grp) + len += (len - 1) / grp; + + if (s) { + s += len; + n = 0; + do { + *--s = fmtscan_asc(u % base); + if (grp && !(++n % grp)) + *--s = sep; + u /= base; + } while (u); + } + + return len; +}