Index

lognestmonster / 01b67c5

A general-purpose single-header C logging library and parser for event-based logs. (Incomplete)

Latest Commit

{#}TimeHashSubjectAuthor#(+)(-)GPG?
13618 Nov 2019 22:1101b67c5Basic events and event pushing; debug parsingJosh Stockin1787N

Blob @ lognestmonster / src / c / lognestmonster.h

text/plain5159 bytesdownload raw
1// lognestmonster Copyright (c) 2019 Joshua 'joshuas3' Stockin
2// lognestmonster.h
3// C header file for implementation of the lognestmonster logging library
4
5// <https://github.com/JoshuaS3/lognestmonster/>.
6
7
8// This file is part of lognestmonster.
9
10// lognestmonster is free software: you can redistribute it and/or modify
11// it under the terms of the GNU General Public License as published by
12// the Free Software Foundation, either version 3 of the License, or
13// (at your option) any later version.
14
15// lognestmonster is distributed in the hope that it will be useful,
16// but WITHOUT ANY WARRANTY; without even the implied warranty of
17// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18// GNU General Public License for more details.
19
20// You should have received a copy of the GNU General Public License
21// along with lognestmonster. If not, see <https://www.gnu.org/licenses/>.
22
23#ifndef __LOGNESTMONSTER__
24#define __LOGNESTMONSTER__ 1
25
26// SEMANTICS
27// internal definitions: lnm_lower_camel_case
28// public definitions: lnmUpperCamelCase
29
30// stdc inclusions
31
32#include <stdint.h>
33#include <stdlib.h>
34#include <string.h>
35
36
37// Base definitions
38
39enum lnmVerbosityLevel {lnmInfo, lnmDebug, lnmVerbose, lnmVeryVerbose, lnmWarning, lnmError};
40
41
42// Pushable structure
43
44typedef uint8_t * lnmItem;
45
46typedef struct {
47 uint16_t length;
48 lnmItem * pushed;
49} lnm_pushable;
50
51lnm_pushable * lnm_new_pushable() {
52 lnm_pushable * new_pushable = malloc(sizeof(lnm_pushable));
53 new_pushable->length = 0;
54 new_pushable->pushed = malloc(0);
55 return new_pushable;
56}
57void lnm_pushable_push(lnm_pushable * pushable, lnmItem item) {
58 pushable->pushed = realloc(pushable->pushed, sizeof(lnmItem)*(pushable->length+1)); // reallocate with size: length+1
59 pushable->pushed[pushable->length] = item;
60 pushable->length += 1;
61}
62
63
64// Statement and event structure definitions
65
66typedef struct {
67 uint8_t type; // Used internally; 0 = statement, 1 = event
68 lnm_pushable * pushed; // array of memory locations for lnm_event and lnm_log_statement structs
69} lnm_log_event;
70
71typedef struct {
72 // word 1, 4 bytes data 4 bytes padding
73 uint8_t type:1; // Used internally; 0 = statement, 1 = event
74 uint8_t verbosity:3; // lnmVerbosityLevel, 0-5
75 uint8_t tag_size; // character length of the tag
76 uint16_t message_size; // character length of the message
77
78 // word 2, 8 bytes data
79 uint64_t timestamp; // 64-bit millisecond timestamp
80
81 // word 3, 8 bytes data
82 char * log; // tag string + message string
83} lnm_log_statement;
84
85
86// Core library
87
88lnmItem lnmStatement(uint8_t verbosity, char * tag, char * message) {
89 lnm_log_statement * new_statement = malloc(sizeof(lnm_log_statement));
90 new_statement->type = 0;
91 new_statement->verbosity = verbosity;
92 new_statement->timestamp = 0;
93 int tlen = strlen(tag);
94 if (tlen > 255 || tlen < 0) {
95 printf("lognestmonster: tag length %i is longer than the cap 255 characters. exiting...\n", tlen);
96 exit(1);
97 }
98 int mlen = strlen(message);
99 if (mlen > 65535 || mlen < 0) {
100 printf("lognestmonster: message length %i is longer than the cap 65535 characters. exiting...\n", mlen);
101 exit(1);
102 }
103 new_statement->tag_size = tlen;
104 new_statement->message_size = mlen;
105 new_statement->log = malloc(tlen+mlen+1);
106 strcpy(new_statement->log, tag);
107 strcat(new_statement->log, message);
108 return (lnmItem)new_statement;
109}
110
111lnmItem lnmEvent() {
112 lnm_log_event * new_event = malloc(sizeof(lnm_log_event));
113 new_event->type = 1;
114 new_event->pushed = lnm_new_pushable();
115 return (lnmItem)new_event;
116}
117
118void lnmEventPush(lnmItem event, lnmItem item) {
119 if (event == item) {
120 printf("lognestmonster: attempt to push event to self. exiting...\n");
121 exit(1);
122 }
123 lnm_pushable_push(((lnm_log_event*)event)->pushed, item);
124}
125
126void lnmEventPushS(lnmItem event, uint8_t verbosity, char * tag, char * message) {
127 lnmItem statement = lnmStatement(verbosity, tag, message);
128 lnmEventPush(event, statement);
129}
130
131lnmItem lnmEventI(lnmItem item) {
132 lnmItem event = lnmEvent();
133 lnmEventPush(event, item);
134 return event;
135}
136
137lnmItem lnmEventS(uint8_t verbosity, char * tag, char * message) {
138 lnmItem statement = lnmStatement(verbosity, tag, message);
139 return lnmEventI(statement);
140}
141
142void lnm_debug_tabs(int count) {
143 for (int i = 0; i < count; i++) {
144 printf(" ");
145 }
146}
147
148void lnm_debug_parse(lnmItem item, int tabcount) {
149 lnm_log_statement * statement = (lnm_log_statement *) item;
150 if (statement->type == 0) {
151 lnm_debug_tabs(tabcount);
152 printf("Statement {\n");
153 lnm_debug_tabs(tabcount+1);
154 printf("Verbosity %i\n", statement->verbosity);
155 lnm_debug_tabs(tabcount+1);
156 printf("Timestamp %ld\n", statement->timestamp);
157 lnm_debug_tabs(tabcount+1);
158 printf("Log %s\n", statement->log);
159 lnm_debug_tabs(tabcount);
160 printf("}\n");
161 } else if (statement->type == 1) {
162 lnm_debug_tabs(tabcount);
163 printf("Event {\n");
164 lnm_log_event * event = (lnm_log_event *) item;
165 for (int i = 0; i < event->pushed->length; i++) {
166 lnmItem item = event->pushed->pushed[i];
167 lnm_debug_parse(item, tabcount + 1);
168 }
169 lnm_debug_tabs(tabcount);
170 printf("}\n");
171 } else {
172 printf("Bad item type\n");
173 exit(1);
174 }
175}
176
177#endif
178