Start working on measurement unit utils

This commit is contained in:
Alex Kotov 2021-12-14 00:36:36 +05:00
parent 9362a422a8
commit 675827558f
Signed by: kotovalexarian
GPG Key ID: 553C0EBBEB5D5F08
8 changed files with 212 additions and 1 deletions

1
.gitignore vendored
View File

@ -37,6 +37,7 @@
/examples/cmdline
/examples/printf
/examples/printf_va
/examples/units_human
/tests/multiboot2_print1
/tests/multiboot2_print2
/tests/test_cmdline

View File

@ -60,6 +60,11 @@ libkernaux_a_SOURCES += src/pfa.c
TESTS += tests/test_pfa
endif
if ENABLE_UNITS
libkernaux_a_SOURCES += src/units.c
TESTS += examples/units_human
endif
examples_cmdline_SOURCES = \
$(libkernaux_a_SOURCES) \
examples/cmdline.c
@ -72,6 +77,10 @@ examples_printf_va_SOURCES = \
$(libkernaux_a_SOURCES) \
examples/printf_va.c
examples_units_human_SOURCES = \
$(libkernaux_a_SOURCES) \
examples/units_human.c
tests_multiboot2_print1_SOURCES = \
$(libkernaux_a_SOURCES) \
tests/multiboot2_print1.c

View File

@ -22,6 +22,7 @@ Table of contents
API
---
* [Measurement units utils](/include/kernaux/units.h) *(work in progress)*
* [Simple command line parser](/include/kernaux/cmdline.h)
* [Multiboot 2 (GRUB 2) information parser](/include/kernaux/multiboot2.h)
* [Serial console](/include/kernaux/console.h)

View File

@ -14,6 +14,7 @@ AC_ARG_ENABLE([cmdline], AS_HELP_STRING([--disable-cmdline], [disable comm
AC_ARG_ENABLE([console], AS_HELP_STRING([--disable-console], [disable serial console]))
AC_ARG_ENABLE([multiboot2], AS_HELP_STRING([--disable-multiboot2], [disable Multiboot 2 information parser]))
AC_ARG_ENABLE([pfa], AS_HELP_STRING([--disable-pfa], [disable Page Frame Allocator]))
AC_ARG_ENABLE([units], AS_HELP_STRING([--disable-units], [disable measurement units utils]))
AM_CONDITIONAL([ARCH_I386], [test "$host_cpu" = i386])
AM_CONDITIONAL([ARCH_X86_64], [test "$host_cpu" = x86_64])
@ -21,6 +22,7 @@ AM_CONDITIONAL([ENABLE_CMDLINE], [test "$enable_cmdline" != no])
AM_CONDITIONAL([ENABLE_CONSOLE], [test "$enable_console" != no])
AM_CONDITIONAL([ENABLE_MULTIBOOT2], [test "$enable_multiboot2" != no])
AM_CONDITIONAL([ENABLE_PFA], [test "$enable_pfa" != no])
AM_CONDITIONAL([ENABLE_UNITS], [test "$enable_units" != no])
AS_IF([test "$host_cpu" = i386], [AC_DEFINE([ARCH_I386], [1], [architecture is i386])])
AS_IF([test "$host_cpu" = x86_64], [AC_DEFINE([ARCH_X86_64], [1], [architecture is x86_64])])
@ -28,6 +30,7 @@ AS_IF([test "$enable_cmdline" != no], [AC_DEFINE([ENABLE_CMDLINE], [1], [e
AS_IF([test "$enable_console" != no], [AC_DEFINE([ENABLE_CONSOLE], [1], [enabled serial console])])
AS_IF([test "$enable_multiboot2" != no], [AC_DEFINE([ENABLE_MULTIBOOT2], [1], [enabled Multiboot 2 information parser])])
AS_IF([test "$enable_pfa" != no], [AC_DEFINE([ENABLE_PFA], [1], [enabled Page Frame Allocator])])
AS_IF([test "$enable_units", != no], [AC_DEFINE([ENABLE_UNITS], [1], [enable measurement units utils])])
AM_INIT_AUTOMAKE([1.9 subdir-objects -Wall -Werror])

47
examples/units_human.c Normal file
View File

@ -0,0 +1,47 @@
#include <kernaux/units.h>
#include <assert.h>
#include <string.h>
int main()
{
char buffer[256];
kernaux_units_human_raw(123, KERNAUX_UNIT_BIT, buffer, sizeof(buffer));
assert(strcmp(buffer, "123 bit") == 0);
kernaux_units_human_dec(123, KERNAUX_UNIT_BIT, KERNAUX_UNITPFX_KILO, buffer, sizeof(buffer));
assert(strcmp(buffer, "123 kbit") == 0);
kernaux_units_human_bin(123, KERNAUX_UNIT_BIT, KERNAUX_UNITPFX_KIBI, buffer, sizeof(buffer));
assert(strcmp(buffer, "123 Kibit") == 0);
kernaux_units_human_dec(123, KERNAUX_UNIT_BIT, KERNAUX_UNITPFX_MEGA, buffer, sizeof(buffer));
assert(strcmp(buffer, "123 Mbit") == 0);
kernaux_units_human_bin(123, KERNAUX_UNIT_BIT, KERNAUX_UNITPFX_MEBI, buffer, sizeof(buffer));
assert(strcmp(buffer, "123 Mibit") == 0);
kernaux_units_human_dec(123, KERNAUX_UNIT_BIT, KERNAUX_UNITPFX_GIGA, buffer, sizeof(buffer));
assert(strcmp(buffer, "123 Gbit") == 0);
kernaux_units_human_bin(123, KERNAUX_UNIT_BIT, KERNAUX_UNITPFX_GIBI, buffer, sizeof(buffer));
assert(strcmp(buffer, "123 Gibit") == 0);
kernaux_units_human_raw(123, KERNAUX_UNIT_BYTE, buffer, sizeof(buffer));
assert(strcmp(buffer, "123 Byte") == 0);
kernaux_units_human_dec(123, KERNAUX_UNIT_BYTE, KERNAUX_UNITPFX_KILO, buffer, sizeof(buffer));
assert(strcmp(buffer, "123 kB") == 0);
kernaux_units_human_bin(123, KERNAUX_UNIT_BYTE, KERNAUX_UNITPFX_KIBI, buffer, sizeof(buffer));
assert(strcmp(buffer, "123 KiB") == 0);
kernaux_units_human_dec(123, KERNAUX_UNIT_BYTE, KERNAUX_UNITPFX_MEGA, buffer, sizeof(buffer));
assert(strcmp(buffer, "123 MB") == 0);
kernaux_units_human_bin(123, KERNAUX_UNIT_BYTE, KERNAUX_UNITPFX_MEBI, buffer, sizeof(buffer));
assert(strcmp(buffer, "123 MiB") == 0);
kernaux_units_human_dec(123, KERNAUX_UNIT_BYTE, KERNAUX_UNITPFX_GIGA, buffer, sizeof(buffer));
assert(strcmp(buffer, "123 GB") == 0);
kernaux_units_human_bin(123, KERNAUX_UNIT_BYTE, KERNAUX_UNITPFX_GIBI, buffer, sizeof(buffer));
assert(strcmp(buffer, "123 GiB") == 0);
return 0;
}

View File

@ -6,4 +6,5 @@ nobase_include_HEADERS = \
kernaux/multiboot2.h \
kernaux/pfa.h \
kernaux/printf.h \
kernaux/stdlib.h
kernaux/stdlib.h \
kernaux/units.h

41
include/kernaux/units.h Normal file
View File

@ -0,0 +1,41 @@
#ifndef KERNAUX_INCLUDED_UNITS
#define KERNAUX_INCLUDED_UNITS
#include <stdbool.h>
#include <stddef.h>
#ifdef __cplusplus
extern "C" {
#endif
enum KernAux_Unit {
KERNAUX_UNIT_BIT,
KERNAUX_UNIT_BYTE,
};
enum KernAux_UnitPrefixDec {
KERNAUX_UNITPFX_KILO,
KERNAUX_UNITPFX_MEGA,
KERNAUX_UNITPFX_GIGA,
};
enum KernAux_UnitPrefixBin {
KERNAUX_UNITPFX_KIBI,
KERNAUX_UNITPFX_MEBI,
KERNAUX_UNITPFX_GIBI,
};
bool kernaux_units_human_raw(size_t value, enum KernAux_Unit unit,
char *buffer, size_t buffer_size);
bool kernaux_units_human_dec(size_t value, enum KernAux_Unit unit,
enum KernAux_UnitPrefixDec prefix,
char *buffer, size_t buffer_size);
bool kernaux_units_human_bin(size_t value, enum KernAux_Unit unit,
enum KernAux_UnitPrefixBin prefix,
char *buffer, size_t buffer_size);
#ifdef __cplusplus
}
#endif
#endif

108
src/units.c Normal file
View File

@ -0,0 +1,108 @@
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <kernaux/units.h>
#include <kernaux/stdlib.h>
bool kernaux_units_human_raw(
const size_t value,
const enum KernAux_Unit unit,
char *buffer,
const size_t buffer_size
) {
kernaux_itoa(value, buffer, 10);
while (*buffer != '\0') ++buffer;
*(buffer++) = ' ';
switch (unit) {
case KERNAUX_UNIT_BIT:
*(buffer++) = 'b';
*(buffer++) = 'i';
*(buffer++) = 't';
break;
case KERNAUX_UNIT_BYTE:
*(buffer++) = 'B';
*(buffer++) = 'y';
*(buffer++) = 't';
*(buffer++) = 'e';
break;
}
*(buffer++) = '\0';
}
bool kernaux_units_human_dec(
const size_t value,
const enum KernAux_Unit unit,
const enum KernAux_UnitPrefixDec prefix,
char *buffer,
const size_t buffer_size
) {
kernaux_itoa(value, buffer, 10);
while (*buffer != '\0') ++buffer;
*(buffer++) = ' ';
switch (prefix) {
case KERNAUX_UNITPFX_KILO:
*(buffer++) = 'k';
break;
case KERNAUX_UNITPFX_MEGA:
*(buffer++) = 'M';
break;
case KERNAUX_UNITPFX_GIGA:
*(buffer++) = 'G';
break;
}
switch (unit) {
case KERNAUX_UNIT_BIT:
*(buffer++) = 'b';
*(buffer++) = 'i';
*(buffer++) = 't';
break;
case KERNAUX_UNIT_BYTE:
*(buffer++) = 'B';
break;
}
*(buffer++) = '\0';
}
bool kernaux_units_human_bin(
const size_t value,
const enum KernAux_Unit unit,
const enum KernAux_UnitPrefixBin prefix,
char *buffer,
const size_t buffer_size
) {
kernaux_itoa(value, buffer, 10);
while (*buffer != '\0') ++buffer;
*(buffer++) = ' ';
switch (prefix) {
case KERNAUX_UNITPFX_KIBI:
*(buffer++) = 'K';
*(buffer++) = 'i';
break;
case KERNAUX_UNITPFX_MEBI:
*(buffer++) = 'M';
*(buffer++) = 'i';
break;
case KERNAUX_UNITPFX_GIBI:
*(buffer++) = 'G';
*(buffer++) = 'i';
break;
}
switch (unit) {
case KERNAUX_UNIT_BIT:
*(buffer++) = 'b';
*(buffer++) = 'i';
*(buffer++) = 't';
break;
case KERNAUX_UNIT_BYTE:
*(buffer++) = 'B';
break;
}
*(buffer++) = '\0';
}