cake
/
libg1m
Archived
1
0
Fork 0
This repository has been archived on 2024-03-16. You can view files and clone it, but cannot push or open issues or pull requests.
libg1m/src/core/log.c

138 lines
3.7 KiB
C

/* *****************************************************************************
* core/log.c -- logging utilities.
* Copyright (C) 2017 Thomas "Cakeisalie5" Touhey <thomas@touhey.fr>
*
* This file is part of libg1m.
* libg1m is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 3.0 of the License,
* or (at your option) any later version.
*
* libg1m is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with libg1m; if not, see <http://www.gnu.org/licenses/>.
* ************************************************************************** */
#include <libg1m/internals.h>
#include <libg1m/format.h>
#include <stdint.h>
#include <string.h>
#include <ctype.h>
#ifndef min
# define min(A, B) ((A) < (B) ? (A) : (B))
#endif
/* ************************************************************************** */
/* Memory logging */
/* ************************************************************************** */
/**
* putascii:
* Put a number in ASCII-hex, in a n-dimensionned field.
*
* @arg p pointer where to put ASCII number
* @arg i ASCII number
* @arg n the size of the field
*/
static void putascii(unsigned char *p, unsigned int i, int n)
{
/* goto end of the field */
p += (n - 1);
/* for each digit */
while (n--) {
/* get end digit from this point */
int j = i % 16;
/* put it in ASCII-hex */
*p-- = j >= 10 ? j - 10 + 'A' : j + '0';
/* then go to digit that's left */
i /= 16;
}
}
/**
* log_mem_hex:
* Prints the octal interpretation of a max of two octets.
*
* @arg s the string where to put it
* @arg m the memory zone to print
* @arg n the size of the memory zone
*/
static void log_mem_hex(char *s, unsigned char *m, size_t n)
{
size_t l = 0;
while (l < 16) {
/* put the hex number */
if (n) putascii((unsigned char*)s, *m++, 2), s += 2;
else *s++ = ' ', *s++ = ' ';
/* decrement size of the memory zone to go */
n -= !!n;
/* go to next character if s is at the ending of a group */
if (l++ % 2) s++;
}
}
/**
* log_mem_asc:
* Prints the ascii interpretation of a max of two octets.
*
* @arg s the string where to put it
* @arg m the memory zone to print
* @arg n the size of the memory zone
*/
static void log_mem_asc(char *s, unsigned char *m, size_t n)
{
size_t l = 0;
/* for each byte */
while (n-- && l++ < 16) {
/* put the character (or a dot if non printable) */
if (isprint(*m++)) *s++ = *((char*)m - 1);
else *s++ = '.';
}
/* put the line ending */
*s++ = '\n', *s = '\0';
}
/**
* g1m_log_mem:
* Print memory zone.
*
* @arg prefx the line prefix
* @arg m the memory zone to print
* @arg n the size of the memory zone
*/
void g1m_log_mem(const char *prefx, void *m, size_t n)
{
/* if nothing, print it directly */
if (!n) fprintf(stderr, "%s(nothing)\n", prefx);
/* prepare line buffer */
unsigned int lineoff = strlen(prefx);
char linebuf[strlen(prefx) + 58];
memcpy(linebuf, prefx, lineoff);
/* - for spaces - */
memcpy(&linebuf[lineoff], "0000 0000 0000 0000 0000 0000 0000 0000 ", 40);
/* then loop-loop-loop-loop-loop */
unsigned char *p = m;
while (n > 0) {
/* fill in ascii-hex part */
log_mem_hex(&linebuf[lineoff], p, n);
/* fill in ascii part */
log_mem_asc(&linebuf[lineoff + 40], p, n);
/* then print line */
fputs(linebuf, stderr);
/* and increment pointer */
p += 16;
n -= min(16, n);
}
}