@ -11,371 +11,31 @@
*
* @ file
*/
# include <stdio.h>
# include <string.h>
# include <inttypes.h>
# include "od.h"
# define _OCTAL_BYTE_LENGTH (3)
# define _INT_BYTE_LENGTH (3)
# define _HEX_BYTE_LENGTH (2)
static inline void _address_format ( char * format , uint16_t flags )
{
switch ( flags & OD_FLAGS_ADDRESS_MASK ) {
case OD_FLAGS_ADDRESS_OCTAL :
strncpy ( format , " %09o " , sizeof ( " %09o " ) ) ;
break ;
case OD_FLAGS_ADDRESS_HEX :
strncpy ( format , " %06x " , sizeof ( " %06x " ) ) ;
break ;
case OD_FLAGS_ADDRESS_DECIMAL :
strncpy ( format , " %07d " , sizeof ( " %07d " ) ) ;
break ;
default :
break ;
}
}
static inline uint8_t _length ( uint16_t flags )
{
if ( flags & OD_FLAGS_BYTES_CHAR ) {
return 1 ;
}
switch ( flags & OD_FLAGS_LENGTH_MASK ) {
case OD_FLAGS_LENGTH_1 :
return 1 ;
case OD_FLAGS_LENGTH_SHORT :
return sizeof ( short ) ;
case OD_FLAGS_LENGTH_2 :
return 2 ;
case OD_FLAGS_LENGTH_LONG :
return sizeof ( long ) ;
case OD_FLAGS_LENGTH_8 :
return 8 ;
case OD_FLAGS_LENGTH_4 :
default :
return 4 ;
}
}
static inline void _bytes_format ( char * format , uint16_t flags )
{
if ( flags & OD_FLAGS_BYTES_CHAR ) {
strncpy ( format , " %c " , sizeof ( " %c " ) ) ;
return ;
}
switch ( flags & ( OD_FLAGS_BYTES_MASK | OD_FLAGS_LENGTH_MASK ) ) {
case OD_FLAGS_BYTES_OCTAL | OD_FLAGS_LENGTH_1 :
strncpy ( format , " %03o " , sizeof ( " %03o " ) ) ;
break ;
case OD_FLAGS_BYTES_OCTAL | OD_FLAGS_LENGTH_2 :
strncpy ( format , " %06 " PRIo16 , sizeof ( " %06 " PRIo16 ) ) ;
break ;
case OD_FLAGS_BYTES_OCTAL | OD_FLAGS_LENGTH_4 :
strncpy ( format , " %012 " PRIo32 , sizeof ( " %012 " PRIo32 ) ) ;
break ;
case OD_FLAGS_BYTES_OCTAL | OD_FLAGS_LENGTH_8 :
strncpy ( format , " %024 " PRIo64 , sizeof ( " %024 " PRIo64 ) ) ;
break ;
# if !defined(__MACH__) && !defined(__mips__)
case OD_FLAGS_BYTES_OCTAL | OD_FLAGS_LENGTH_SHORT :
sprintf ( format , " %%0%do " , sizeof ( short ) * _OCTAL_BYTE_LENGTH ) ;
break ;
case OD_FLAGS_BYTES_OCTAL | OD_FLAGS_LENGTH_LONG :
sprintf ( format , " %%0%dlo " , sizeof ( long ) * _OCTAL_BYTE_LENGTH ) ;
break ;
# else /* !defined(__MACH__) && !defined(__mips__) */
case OD_FLAGS_BYTES_OCTAL | OD_FLAGS_LENGTH_SHORT :
sprintf ( format , " %lu " , sizeof ( short ) * _OCTAL_BYTE_LENGTH ) ;
break ;
case OD_FLAGS_BYTES_OCTAL | OD_FLAGS_LENGTH_LONG :
sprintf ( format , " %lu " , sizeof ( long ) * _OCTAL_BYTE_LENGTH ) ;
break ;
# endif /* !defined(__MACH__) && !defined(__mips__) */
case OD_FLAGS_BYTES_INT | OD_FLAGS_LENGTH_1 :
strncpy ( format , " %4d " , sizeof ( " %4d " ) ) ;
break ;
case OD_FLAGS_BYTES_INT | OD_FLAGS_LENGTH_2 :
strncpy ( format , " %6 " PRId16 , sizeof ( " %6 " PRId16 ) ) ;
break ;
case OD_FLAGS_BYTES_INT | OD_FLAGS_LENGTH_4 :
strncpy ( format , " %12 " PRId32 , sizeof ( " %12 " PRId32 ) ) ;
break ;
case OD_FLAGS_BYTES_INT | OD_FLAGS_LENGTH_8 :
strncpy ( format , " %24 " PRId64 , sizeof ( " %24 " PRId64 ) ) ;
break ;
# if !defined(__MACH__) && !defined(__mips__)
case OD_FLAGS_BYTES_INT | OD_FLAGS_LENGTH_SHORT :
sprintf ( format , " %%%dd " , sizeof ( short ) * _INT_BYTE_LENGTH ) ;
break ;
case OD_FLAGS_BYTES_INT | OD_FLAGS_LENGTH_LONG :
sprintf ( format , " %%%dld " , sizeof ( long ) * _INT_BYTE_LENGTH ) ;
break ;
# else /* !defined(__MACH__) && !defined(__mips__) */
case OD_FLAGS_BYTES_INT | OD_FLAGS_LENGTH_SHORT :
sprintf ( format , " %%%ld " , sizeof ( short ) * _INT_BYTE_LENGTH ) ;
break ;
case OD_FLAGS_BYTES_INT | OD_FLAGS_LENGTH_LONG :
sprintf ( format , " %%%ld " , sizeof ( long ) * _INT_BYTE_LENGTH ) ;
break ;
# endif /* !defined(__MACH__) && !defined(__mips__) */
case OD_FLAGS_BYTES_UINT | OD_FLAGS_LENGTH_1 :
strncpy ( format , " %3u " , sizeof ( " %3u " ) ) ;
break ;
case OD_FLAGS_BYTES_UINT | OD_FLAGS_LENGTH_2 :
strncpy ( format , " %6 " PRIu16 , sizeof ( " %6 " PRIu16 ) ) ;
break ;
case OD_FLAGS_BYTES_UINT | OD_FLAGS_LENGTH_4 :
strncpy ( format , " %12 " PRIu32 , sizeof ( " %12 " PRIu32 ) ) ;
break ;
case OD_FLAGS_BYTES_UINT | OD_FLAGS_LENGTH_8 :
strncpy ( format , " %24 " PRIu64 , sizeof ( " %24 " PRIu64 ) ) ;
break ;
# if !defined(__MACH__) && !defined(__mips__)
case OD_FLAGS_BYTES_UINT | OD_FLAGS_LENGTH_SHORT :
sprintf ( format , " %%%uu " , ( unsigned ) sizeof ( short ) * _INT_BYTE_LENGTH ) ;
break ;
case OD_FLAGS_BYTES_UINT | OD_FLAGS_LENGTH_LONG :
sprintf ( format , " %%%ulu " , sizeof ( long ) * _INT_BYTE_LENGTH ) ;
break ;
# else /* !defined(__MACH__) && !defined(__mips__) */
case OD_FLAGS_BYTES_UINT | OD_FLAGS_LENGTH_SHORT :
sprintf ( format , " %%%lu " , sizeof ( short ) * _INT_BYTE_LENGTH ) ;
break ;
case OD_FLAGS_BYTES_UINT | OD_FLAGS_LENGTH_LONG :
sprintf ( format , " %%%lu " , sizeof ( long ) * _INT_BYTE_LENGTH ) ;
break ;
# endif /* !defined(__MACH__) && !defined(__mips__) */
case OD_FLAGS_BYTES_HEX | OD_FLAGS_LENGTH_1 :
strncpy ( format , " %02x " , sizeof ( " %02x " ) ) ;
break ;
case OD_FLAGS_BYTES_HEX | OD_FLAGS_LENGTH_2 :
strncpy ( format , " %04 " PRIx16 , sizeof ( " %04 " PRIx16 ) ) ;
break ;
case OD_FLAGS_BYTES_HEX | OD_FLAGS_LENGTH_4 :
strncpy ( format , " %08 " PRIx32 , sizeof ( " %08 " PRIx32 ) ) ;
break ;
case OD_FLAGS_BYTES_HEX | OD_FLAGS_LENGTH_8 :
strncpy ( format , " %016 " PRIx64 , sizeof ( " %016 " PRIx64 ) ) ;
break ;
# if !defined(__MACH__) && !defined(__mips__)
case OD_FLAGS_BYTES_HEX | OD_FLAGS_LENGTH_SHORT :
sprintf ( format , " %%0%ux " , ( unsigned ) sizeof ( short ) * _HEX_BYTE_LENGTH ) ;
break ;
case OD_FLAGS_BYTES_HEX | OD_FLAGS_LENGTH_LONG :
sprintf ( format , " %%0%ulx " , ( unsigned ) sizeof ( long ) * _HEX_BYTE_LENGTH ) ;
break ;
# else /* !defined(__MACH__) && !defined(__mips__) */
case OD_FLAGS_BYTES_HEX | OD_FLAGS_LENGTH_SHORT :
sprintf ( format , " %%0%lx " , sizeof ( short ) * _HEX_BYTE_LENGTH ) ;
break ;
case OD_FLAGS_BYTES_HEX | OD_FLAGS_LENGTH_LONG :
sprintf ( format , " %%0%lx " , sizeof ( long ) * _HEX_BYTE_LENGTH ) ;
break ;
# endif /* !defined(__MACH__) && !defined(__mips__) */
default :
break ;
}
}
static void _print_date ( const void * data , size_t offset , char * format , uint8_t length ,
uint16_t flags )
{
switch ( length ) {
case 1 :
if ( flags & OD_FLAGS_BYTES_CHAR ) {
switch ( ( ( signed char * ) data ) [ offset ] ) {
case ' \0 ' :
printf ( " \\ 0 " ) ;
return ;
case ' \a ' :
printf ( " \\ a " ) ;
return ;
case ' \b ' :
printf ( " \\ b " ) ;
return ;
case ' \f ' :
printf ( " \\ f " ) ;
return ;
case ' \n ' :
printf ( " \\ n " ) ;
return ;
case ' \r ' :
printf ( " \\ r " ) ;
return ;
case ' \t ' :
printf ( " \\ t " ) ;
return ;
case ' \v ' :
printf ( " \\ v " ) ;
return ;
default :
if ( ( ( signed char * ) data ) [ offset ] < 0 ) {
printf ( " %03o " , ( ( unsigned char * ) data ) [ offset ] ) ;
return ;
}
else if ( ( ( signed char * ) data ) [ offset ] < 32 ) {
printf ( " %03o " , ( ( char * ) data ) [ offset ] ) ;
return ;
}
break ;
}
}
if ( flags & OD_FLAGS_BYTES_INT ) {
printf ( format , ( ( int8_t * ) data ) [ offset ] ) ;
}
else {
printf ( format , ( ( uint8_t * ) data ) [ offset ] ) ;
}
break ;
case 2 :
if ( flags & OD_FLAGS_BYTES_INT ) {
printf ( format , ( ( int16_t * ) data ) [ offset ] ) ;
}
else {
printf ( format , ( ( uint16_t * ) data ) [ offset ] ) ;
}
break ;
case 4 :
default :
if ( flags & OD_FLAGS_BYTES_INT ) {
printf ( format , ( ( int32_t * ) data ) [ offset ] ) ;
}
else {
printf ( format , ( ( uint32_t * ) data ) [ offset ] ) ;
}
break ;
case 8 :
# ifndef MODULE_NEWLIB
if ( flags & OD_FLAGS_BYTES_INT ) {
printf ( format , ( ( int64_t * ) data ) [ offset ] ) ;
}
else {
printf ( format , ( ( uint64_t * ) data ) [ offset ] ) ;
}
# else
printf ( " %s " , format ) ;
# endif
break ;
}
}
static int _log10 ( uint8_t a )
{
int res = 0 ;
# include <stdio.h>
# include <stdint.h>
while ( a > 0 ) {
a / = 10 ;
+ + res ;
}
# include "fmt.h"
return + + res ;
}
# include "od.h"
void od ( const void * data , size_t data_len , uint8_t width , uint16_t flags )
void od_hex_dump ( const void * data , size_t data_len , uint8_t width )
{
char address_format [ 5 ] ;
uint8_t date_length = _length ( flags ) ;
char bytes_format [ _log10 ( date_length ) + 7 ] ;
if ( data_len = = 0 ) {
return ;
}
_address_format ( address_format , flags ) ;
_bytes_format ( bytes_format , flags ) ;
print_str ( " 00000000 " ) ;
if ( width = = 0 ) {
width = OD_WIDTH_DEFAULT ;
}
if ( width < date_length ) {
width = 1 ;
}
else {
width = ( width / date_length ) ;
}
if ( data_len % date_length ) {
data_len = ( data_len / date_length ) + 1 ;
}
else {
data_len = data_len / date_length ;
}
if ( ( flags & OD_FLAGS_ADDRESS_MASK ) ! = OD_FLAGS_ADDRESS_NONE ) {
printf ( address_format , 0 ) ;
}
for ( size_t i = 0 ; i < data_len ; i + + ) {
_print_date ( data , i , bytes_format , date_length , flags ) ;
for ( unsigned int i = 0 ; i < data_len ; i + + ) {
print_str ( " " ) ;
print_byte_hex ( ( ( uint8_t * ) data ) [ i ] ) ;
if ( ( ( ( i + 1 ) % width ) = = 0 ) | | i = = ( data_len - 1 ) ) {
printf ( " \n " ) ;
puts ( " " ) ;
if ( i ! = ( data_len - 1 ) ) {
if ( ( flags & OD_FLAGS_ADDRESS_MASK ) ! = OD_FLAGS_ADDRESS_NONE ) {
printf ( address_format , date_length * ( i + 1 ) ) ;
}
print_u32_hex ( ( uint32_t ) ( i + 1 ) ) ;
}
}
}