librfn
An ad-hoc utility library
mlog.c
Go to the documentation of this file.
1 /*
2  * mlog.c
3  *
4  * Part of librfn (a general utility library from redfelineninja.org.uk)
5  *
6  * Copyright (C) 2015 Daniel Thompson <daniel@redfelineninja.org.uk>
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU Lesser General Public License as published
10  * by the Free Software Foundation; either version 3 of the License, or
11  * (at your option) any later version.
12  */
13 
14 #include "librfn/mlog.h"
15 
16 #include <stdint.h>
17 
18 #include "librfn/string.h"
19 #include "librfn/util.h"
20 
21 struct mlog_line {
22  const char *fmt;
23  uintptr_t arg[3];
24 };
25 
26 struct mlog {
27  struct mlog_line line[256];
28  unsigned int head;
29 };
30 
31 static struct mlog log;
32 
33 void vmlog(const char *fmt, va_list ap)
34 {
35  unsigned int head = log.head % lengthof(log.line);
36 
37  log.line[head].fmt = fmt;
38  log.line[head].arg[0] = va_arg(ap, uintptr_t);
39  log.line[head].arg[1] = va_arg(ap, uintptr_t);
40  log.line[head].arg[2] = va_arg(ap, uintptr_t);
41 
42  log.head++;
43  if (log.head >= 0x7fffffff)
44  log.head -= lengthof(log.line);
45 }
46 
47 void mlog(const char *fmt, ...)
48 {
49  va_list ap;
50 
51  va_start(ap, fmt);
52  vmlog(fmt, ap);
53  va_end(ap);
54 }
55 
56 void vmlog_nice(const char *fmt, va_list ap)
57 {
58  if (log.head < lengthof(log.line))
59  vmlog(fmt, ap);
60 }
61 
62 void mlog_nice(const char *fmt, ...)
63 {
64  va_list ap;
65 
66  va_start(ap, fmt);
67  vmlog_nice(fmt, ap);
68  va_end(ap);
69 }
70 
71 void mlog_clear(void)
72 {
73  log.head = 0;
74 }
75 
76 static struct mlog_line *get_line(unsigned int n)
77 {
78  if (n >= log.head || n >= lengthof(log.line))
79  return NULL;
80 
81  /* if the buffer has wrapped adjust n by the wrap point */
82  if (log.head >= lengthof(log.line))
83  n += log.head;
84 
85  return &log.line[n % lengthof(log.line)];
86 }
87 
88 void mlog_dump(FILE *f)
89 {
90  struct mlog_line *line;
91 
92  for (int i=0; (line = get_line(i)); i++)
93  fprintf(f, line->fmt, line->arg[0], line->arg[1], line->arg[2]);
94 }
95 
96 char *mlog_get_line(int n)
97 {
98  struct mlog_line *line = get_line(n);
99 
100  if (line)
101  return strdup_printf(line->fmt, line->arg[0], line->arg[1],
102  line->arg[2]);
103 
104  return NULL;
105 }
const char * fmt
Definition: mlog.c:22
unsigned int head
Definition: mlog.c:28
#define lengthof(x)
Definition: util.h:44
uintptr_t arg[3]
Definition: mlog.c:23
void mlog_nice(const char *fmt,...)
Log a message, if there is space to do so.
Definition: mlog.c:62
struct mlog_line line[256]
Definition: mlog.c:27
void mlog_dump(FILE *f)
Format the log and write it to the supplied file pointer.
Definition: mlog.c:88
void vmlog(const char *fmt, va_list ap)
Log a message using a variable argument list.
Definition: mlog.c:33
char * mlog_get_line(int n)
Format the Nth line of the log.
Definition: mlog.c:96
void mlog_clear(void)
Clear all data from the log.
Definition: mlog.c:71
Definition: mlog.c:26
Definition: mlog.c:21
void mlog(const char *fmt,...)
Log a message.
Definition: mlog.c:47
void vmlog_nice(const char *fmt, va_list ap)
Log a message using a variable argument list, if there is space to do so.
Definition: mlog.c:56
char * strdup_printf(const char *format,...)
Definition: string.c:88
const uint8_t fmt[]
Definition: wavheader.c:24