Version 7.0
Copyright © 2021 Lowell D. Thomas
APG
… an ABNF Parser Generator
msglog.c
Go to the documentation of this file.
1 /* *************************************************************************************
2  Copyright (c) 2021, Lowell D. Thomas
3  All rights reserved.
4 
5  This file is part of APG Version 7.0.
6  APG Version 7.0 may be used under the terms of the BSD 2-Clause License.
7 
8  Redistribution and use in source and binary forms, with or without
9  modification, are permitted provided that the following conditions are met:
10 
11  1. Redistributions of source code must retain the above copyright notice, this
12  list of conditions and the following disclaimer.
13 
14  2. Redistributions in binary form must reproduce the above copyright notice,
15  this list of conditions and the following disclaimer in the documentation
16  and/or other materials provided with the distribution.
17 
18  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
22  FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24  SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 
29 * *************************************************************************************/
40 #include "../library/lib.h"
41 
42 static const void* s_vpMagicNumber = (void*)"msglog";
43 
49 typedef struct {
50  const void *vpValidate;
52  void *vpMem;
55  void *vpVecMsgs;
56  void *vpVecIndexes;
58 } msgs;
59 
68 void* vpMsgsCtor(exception* spEx) {
69  if(bExValidate(spEx)){
70  void* vpMem = vpMemCtor(spEx);
71  msgs *spCtx = (msgs*) vpMemAlloc(vpMem, sizeof(msgs));
72  memset((void*) spCtx, 0, sizeof(msgs));
73  spCtx->vpMem = vpMem;
74  spCtx->spException = spEx;
75  spCtx->vpVecMsgs = vpVecCtor(vpMem, sizeof(char), 1024); // 16 messages of average 64 characters
76  spCtx->vpVecIndexes = vpVecCtor(vpMem, sizeof(aint), 16); // 16 messages
77  spCtx->vpValidate = s_vpMagicNumber;
78  return (void*) spCtx;
79  }else{
80  vExContext();
81  }
82  return NULL;
83 }
84 
92 void vMsgsDtor(void *vpCtx) {
93  msgs *spCtx = (msgs*) vpCtx;
94  if(vpCtx){
95  if(spCtx->vpValidate == s_vpMagicNumber){
96  void* vpMem = spCtx->vpMem;
97  memset(vpCtx, 0, sizeof(msgs));
98  vMemDtor(vpMem);
99  }else{
100  vExContext();
101  }
102  }
103 }
104 
110 abool bMsgsValidate(void *vpCtx){
111  msgs *spCtx = (msgs*) vpCtx;
112  if (spCtx && (spCtx->vpValidate == s_vpMagicNumber)) {
113  return APG_TRUE;
114  }
115  return APG_FALSE;
116 }
117 
124 void vMsgsClear(void *vpCtx) {
125  msgs *spCtx = (msgs*) vpCtx;
126  if (spCtx && (spCtx->vpValidate == s_vpMagicNumber)) {
127  vVecClear(spCtx->vpVecMsgs);
128  vVecClear(spCtx->vpVecIndexes);
129  spCtx->uiNext = 0;
130  spCtx->uiMsgCount = 0;
131  }else{
132  vExContext();
133  }
134 }
135 
141 void vMsgsLog(void *vpCtx, const char *cpMsg) {
142  msgs *spCtx = (msgs*) vpCtx;
143  if (spCtx && (spCtx->vpValidate == s_vpMagicNumber)) {
144  if(!cpMsg || !cpMsg[0]){
145  XTHROW(spCtx->spException, "NULL or empty messages not allowed");
146  }
147  // push the message & its index
148  aint uiIndex = uiVecLen(spCtx->vpVecMsgs);
149  vpVecPushn(spCtx->vpVecMsgs, (void*) cpMsg, (aint) (strlen(cpMsg) + 1));
150  vpVecPush(spCtx->vpVecIndexes, (void*) &uiIndex);
151  spCtx->uiMsgCount++;
152  }else{
153  vExContext();
154  }
155 }
156 
164 const char* cpMsgsFirst(void *vpCtx) {
165  char *cpReturn = NULL;
166  msgs *spCtx = (msgs*) vpCtx;
167  if (spCtx && (spCtx->vpValidate == s_vpMagicNumber)) {
168  if (spCtx->uiMsgCount) {
169  cpReturn = (char*) vpVecFirst(spCtx->vpVecMsgs);
170  spCtx->uiNext = 1;
171  }
172  }else{
173  vExContext();
174  }
175  return cpReturn;
176 }
177 
185 const char* cpMsgsNext(void *vpCtx) {
186  char *cpReturn = NULL;
187  msgs *spCtx = (msgs*) vpCtx;
188  if (spCtx && (spCtx->vpValidate == s_vpMagicNumber)) {
189  if (spCtx->uiMsgCount && spCtx->uiNext && (spCtx->uiNext < spCtx->uiMsgCount)) {
190  aint *uipIndex = (aint*) vpVecAt(spCtx->vpVecIndexes, spCtx->uiNext);
191  if (uipIndex) {
192  char *cpMsg = (char*) vpVecAt(spCtx->vpVecMsgs, *uipIndex);
193  if (cpMsg) {
194  cpReturn = cpMsg;
195  spCtx->uiNext++;
196  } else {
197  // this should never happen
198  XTHROW(spCtx->spException, "unable to retrieve a saved message");
199  }
200  } // else {end of messages}
201  }
202  }else{
203  vExContext();
204  }
205  return cpReturn;
206 }
207 
213 aint uiMsgsCount(void *vpCtx) {
214  aint uiReturn = 0;
215  msgs *spCtx = (msgs*) vpCtx;
216  if (spCtx && (spCtx->vpValidate == s_vpMagicNumber)) {
217  uiReturn = spCtx->uiMsgCount;
218  }else{
219  vExContext();
220  }
221  return uiReturn;
222 }
vMsgsLog
void vMsgsLog(void *vpCtx, const char *cpMsg)
Logs a message.
Definition: msglog.c:141
vMemDtor
void vMemDtor(void *vpCtx)
Destroys a Memory component. Frees all memory allocated.
Definition: memory.c:141
msgs::uiMsgCount
aint uiMsgCount
The number of logged messages.
Definition: msglog.c:54
msgs::vpMem
void * vpMem
Pointer to a memory object context for all memory allocations.
Definition: msglog.c:53
uiMsgsCount
aint uiMsgsCount(void *vpCtx)
Get the number of logged messages.
Definition: msglog.c:213
vExContext
void vExContext()
Handles bad context pointers.
Definition: exception.c:126
vpVecAt
void * vpVecAt(void *vpCtx, aint uiIndex)
Get a the indexed vector element. The vector is not altered.
Definition: vector.c:362
XTHROW
#define XTHROW(ctx, msg)
Exception throw macro.
Definition: exception.h:67
aint
uint_fast32_t aint
The APG parser's unsigned integer type.
Definition: apg.h:79
msgs::uiNext
aint uiNext
The next message in the message iterator.
Definition: msglog.c:57
vpMsgsCtor
void * vpMsgsCtor(exception *spEx)
The Message Log constructor.
Definition: msglog.c:68
vMsgsClear
void vMsgsClear(void *vpCtx)
Clears the object of all messages.
Definition: msglog.c:124
vpMemAlloc
void * vpMemAlloc(void *vpCtx, aint uiBytes)
Allocates memory.
Definition: memory.c:196
uiVecLen
aint uiVecLen(void *vpCtx)
Get the vector length. That is, the number of elements on the vector.
Definition: vector.c:385
vpVecCtor
void * vpVecCtor(void *vpMem, aint uiElementSize, aint uiInitialAlloc)
The vector object constructor.
Definition: vector.c:118
exception
A structure to describe the type and location of a caught exception.
Definition: exception.h:47
vMsgsDtor
void vMsgsDtor(void *vpCtx)
The object destructor.
Definition: msglog.c:92
cpMsgsFirst
const char * cpMsgsFirst(void *vpCtx)
Get a pointer to the first logged message, if any.
Definition: msglog.c:164
cpMsgsNext
const char * cpMsgsNext(void *vpCtx)
Get a pointer to the next logged message, if any.
Definition: msglog.c:185
bExValidate
abool bExValidate(exception *spException)
Test an exception structure for validity.
Definition: exception.c:70
msgs::vpVecMsgs
void * vpVecMsgs
A vector to hold the logged messages.
Definition: msglog.c:55
vpVecFirst
void * vpVecFirst(void *vpCtx)
Get the first element one the vector. The vector is not altered.
Definition: vector.c:326
vpVecPushn
void * vpVecPushn(void *vpCtx, void *vpElement, aint uiCount)
Adds one or more elements to the end of the array.
Definition: vector.c:221
vpMemCtor
void * vpMemCtor(exception *spException)
Construct a memory component.
Definition: memory.c:121
msgs::vpVecIndexes
void * vpVecIndexes
A vector to hold the indexes of the logged messages in vpVecMsgs.
Definition: msglog.c:56
APG_TRUE
#define APG_TRUE
Definition: apg.h:291
msgs::spException
exception * spException
Pointer to an exception structure to report fatal errors back to the application's catch block.
Definition: msglog.c:51
abool
uint8_t abool
abool is the APG bool type.
Definition: apg.h:140
msgs::vpValidate
const void * vpValidate
A "magic" number to validate the context.
Definition: msglog.c:50
vpVecPush
void * vpVecPush(void *vpCtx, void *vpElement)
Adds one element to the end of the array.
Definition: vector.c:193
msgs
The message log context.
Definition: msglog.c:49
vVecClear
void vVecClear(void *vpCtx)
Clears all used elements in a vector component.
Definition: vector.c:420
bMsgsValidate
abool bMsgsValidate(void *vpCtx)
Validate a msglog context pointer.
Definition: msglog.c:110
APG_FALSE
#define APG_FALSE
Definition: apg.h:292
APG Version 7.0 is licensed under the 2-Clause BSD License,
an Open Source Initiative Approved License.