Version 7.0
Copyright © 2021 Lowell D. Thomas
APG
… an ABNF Parser Generator
tools.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 * *************************************************************************************/
34 #include "lib.h"
35 
36 static char s_cPeriod = 46;
37 
53 int iStriCmp(const char* cpLeft, const char* cpRight){
54  if(cpLeft == NULL && cpRight == NULL){
55  return 0;
56  }
57  if(cpLeft == NULL){
58  return -1;
59  }
60  if(cpRight == NULL){
61  return 1;
62  }
63  size_t uiLeftLen = strlen(cpLeft);
64  size_t uiRightLen = strlen(cpRight);
65  size_t uiLen = uiLeftLen < uiRightLen ? uiLeftLen : uiRightLen;
66  size_t ui = 0;
67  unsigned char ucL, ucR;
68  for(; ui < uiLen; ui++){
69  ucL = cpLeft[ui];
70  ucR = cpRight[ui];
71  if(ucL >= 65 && ucL <= 90){
72  ucL += 32;
73  }
74  if(ucR >= 65 && ucR <= 90){
75  ucR += 32;
76  }
77  if(ucL < ucR){
78  return -1;
79  }
80  if(ucL > ucR){
81  return 1;
82  }
83  }
84  if(uiLeftLen < uiRightLen){
85  return -1;
86  }
87  if(uiLeftLen > uiRightLen){
88  return 1;
89  }
90  return 0;
91 }
92 
97  static union {
98  uint32_t ui32;
99  char caChar[4];
100  } sIsBig = {0x01020304};
101  return (abool)(sIsBig.caChar[0] == 1);
102 }
103 
110 abool bMultiplyLong(luint luiL, luint luiR, luint* luipA){
111  if(luiL == 0 || luiR == 0){
112  *luipA = 0;
113  return APG_SUCCESS;
114  }
115  luint luiTest = luiL * luiR;
116  luint luiCheck = luiTest / luiR;
117  if(luiCheck != luiL){
118  *luipA = (luint)-1;
119  return APG_FAILURE;
120  }
121  *luipA = luiTest;
122  return APG_SUCCESS;
123 }
124 
131 abool bSumLong(luint uiL, luint uiR, luint* uipA){
132  luint uiTest = uiL + uiR;
133  if(uiTest < uiR){
134  return APG_FAILURE;
135  }
136  luint uiCheck = uiTest - uiR;
137  if(uiCheck != uiL){
138  return APG_FAILURE;
139  }
140  *uipA = uiTest;
141  return APG_SUCCESS;
142 }
143 
150 abool bMultiply32(uint32_t uiL, uint32_t uiR, uint32_t* uipA){
151  if(uiL == 0 || uiR == 0){
152  *uipA = 0;
153  return APG_SUCCESS;
154  }
155  uint32_t uiTest = uiL * uiR;
156  uint32_t uiCheck = uiTest / uiR;
157  if(uiCheck != uiL){
158  return APG_FAILURE;
159  }
160  *uipA = uiTest;
161  return APG_SUCCESS;
162 }
163 
170 abool bSum32(uint32_t uiL, uint32_t uiR, uint32_t* uipA){
171  uint32_t uiTest = uiL + uiR;
172  if(uiTest < uiR){
173  return APG_FAILURE;
174  }
175  uint32_t uiCheck = uiTest - uiR;
176  if(uiCheck != uiL){
177  return APG_FAILURE;
178  }
179  *uipA = uiTest;
180  return APG_SUCCESS;
181 }
182 
189 abool bMultiply(aint uiL, aint uiR, aint* uipA){
190  if(uiL == 0 || uiR == 0){
191  *uipA = 0;
192  return APG_SUCCESS;
193  }
194  aint uiTest = uiL * uiR;
195  aint uiCheck = uiTest / uiR;
196  if(uiCheck != uiL){
197  return APG_FAILURE;
198  }
199  *uipA = uiTest;
200  return APG_SUCCESS;
201 }
202 
209 abool bSum(aint uiL, aint uiR, aint* uipA){
210  aint uiTest = uiL + uiR;
211  if(uiTest < uiR){
212  return APG_FAILURE;
213  }
214  aint uiCheck = uiTest - uiR;
215  if(uiCheck != uiL){
216  return APG_FAILURE;
217  }
218  *uipA = uiTest;
219  return APG_SUCCESS;
220 }
221 
237 apg_phrase* spStrToPhrase(const char* cpStr, apg_phrase* spPhrase){
238  if(!spPhrase || !cpStr){
239  return NULL;
240  }
241  aint uiStrLen = strlen(cpStr);
242  aint uiBufLen = spPhrase->uiLength;
243  aint uiLen = uiStrLen < uiBufLen ? uiStrLen : uiBufLen;
244  aint ui = 0;
245  achar* acpTmp = (achar*)spPhrase->acpPhrase;
246  for(; ui < uiLen; ui++){
247 // spPhrase->acpPhrase[ui] = (achar)((uint8_t)cpStr[ui]);
248  acpTmp[ui] = (achar)((uint8_t)cpStr[ui]);
249  }
250  spPhrase->uiLength = uiStrLen;
251  return spPhrase;
252 }
253 
264 char* cpPhraseToStr(apg_phrase* spPhrase, char* cpStr){
265  aint ui = 0;
266  achar acChar;
267  for(; ui < spPhrase->uiLength; ui++){
268  acChar = spPhrase->acpPhrase[ui];
269  if(acChar == 9 || acChar == 10 || acChar == 13 || (acChar >= 32 && acChar <= 126)){
270  cpStr[ui] = (char)acChar;
271  }else{
272  cpStr[ui] = s_cPeriod;
273  }
274  }
275  cpStr[ui] = (char)0;
276  return cpStr;
277 }
278 
288  aint ui = 0;
289  achar acChar;
290  if(!spPhrase || !spPhrase->acpPhrase || !spPhrase->uiLength){
291  return APG_FALSE;
292  }
293  for(; ui < spPhrase->uiLength; ui++){
294  acChar = spPhrase->acpPhrase[ui];
295  if(!(acChar == 9 || acChar == 10 || acChar == 13 || (acChar >= 32 && acChar <= 126))){
296  return APG_FALSE;
297  }
298  }
299  return APG_TRUE;
300 }
301 
313 uint32_t* uipStrToUint32(const char* cpStr, uint32_t* uipBuf, aint* uipLen){
314  aint uiStrLen = strlen(cpStr);
315  aint ui = 0;
316  for(; ui < uiStrLen; ui++){
317  uipBuf[ui] = (uint32_t)((uint8_t)cpStr[ui]);
318  }
319  if(uipLen){
320  *uipLen = uiStrLen;
321  }
322  return uipBuf;
323 }
324 
336 char* cpUint32ToStr(uint32_t* uipBuf, aint uiLen, char* cpStr){
337  aint ui = 0;
338  uint32_t uiChar;
339  for(; ui < uiLen; ui++){
340  uiChar = uipBuf[ui];
341  if(uiChar == 9 || uiChar == 10 || uiChar == 13 || (uiChar >= 32 && uiChar <= 126)){
342  cpStr[ui] = (char)uiChar;
343  }else{
344  cpStr[ui] = s_cPeriod;
345  }
346  }
347  cpStr[ui] = (char)0;
348  return cpStr;
349 }
350 
360 u32_phrase sStrToPhrase32(const char* cpStr, uint32_t* uipBuf){
361  u32_phrase sPhrase = {};
362  aint uiStrLen = strlen(cpStr);
363  aint ui = 0;
364  for(; ui < uiStrLen; ui++){
365  uipBuf[ui] = (uint32_t)((uint8_t)cpStr[ui]);
366  }
367  sPhrase.uipPhrase = uipBuf;
368  sPhrase.uiLength = uiStrLen;
369  return sPhrase;
370 }
371 
382 char* cpPhrase32ToStr(u32_phrase* spPhrase, char* cpStr){
383  aint ui = 0;
384  uint32_t uiChar;
385  for(; ui < spPhrase->uiLength; ui++){
386  uiChar = spPhrase->uipPhrase[ui];
387  if(uiChar == 9 || uiChar == 10 || uiChar == 13 || (uiChar >= 32 && uiChar <= 126)){
388  cpStr[ui] = (char)uiChar;
389  }else{
390  cpStr[ui] = s_cPeriod;
391  }
392  }
393  cpStr[ui] = (char)0;
394  return cpStr;
395 }
396 
406  aint ui = 0;
407  uint32_t uiChar;
408  for(; ui < spPhrase->uiLength; ui++){
409  uiChar = spPhrase->uipPhrase[ui];
410  if(!(uiChar == 9 || uiChar == 10 || uiChar == 13 || (uiChar >= 32 && uiChar <= 126))){
411  return APG_FALSE;
412  }
413  }
414  return APG_TRUE;
415 }
lib.h
This header "#include"s all publid lib headers and other standard headers needed by most objects.
APG_FAILURE
#define APG_FAILURE
Definition: apg.h:308
sStrToPhrase32
u32_phrase sStrToPhrase32(const char *cpStr, uint32_t *uipBuf)
Convert an ASCII, null-terminated string to a 32-bit phrase.
Definition: tools.c:360
uipStrToUint32
uint32_t * uipStrToUint32(const char *cpStr, uint32_t *uipBuf, aint *uipLen)
Convert an ASCII, null-terminated string to an 32-bit unsigned integer array.
Definition: tools.c:313
u32_phrase::uiLength
uint32_t uiLength
The number of integers in the array.
Definition: lib.h:75
cpPhrase32ToStr
char * cpPhrase32ToStr(u32_phrase *spPhrase, char *cpStr)
Convert a 32-bit phrase to a null-terminated ASCII string.
Definition: tools.c:382
bIsPhrase32Ascii
abool bIsPhrase32Ascii(u32_phrase *spPhrase)
Determine if a 32-bit phrase consists entirely of printable ASCII characters.
Definition: tools.c:405
achar
uint_fast8_t achar
achar is the type for the parser's alphabet characters.
Definition: apg.h:91
bIsPhraseAscii
abool bIsPhraseAscii(apg_phrase *spPhrase)
Determine if a phrase consists entirely of printable ASCII characters.
Definition: tools.c:287
iStriCmp
int iStriCmp(const char *cpLeft, const char *cpRight)
Compare two strings. A case-insensitive version of strcmp().
Definition: tools.c:53
cpUint32ToStr
char * cpUint32ToStr(uint32_t *uipBuf, aint uiLen, char *cpStr)
Convert an array of 32-bit unsigned integers to a null-terminated ASCII string.
Definition: tools.c:336
bSumLong
abool bSumLong(luint uiL, luint uiR, luint *uipA)
Add two long unsigned integers with overflow notification.
Definition: tools.c:131
cpPhraseToStr
char * cpPhraseToStr(apg_phrase *spPhrase, char *cpStr)
Convert a phrase of achar characters to a null-terminated ASCII string.
Definition: tools.c:264
u32_phrase::uipPhrase
const uint32_t * uipPhrase
Pointer to an array of 32-bit unsigned integers.
Definition: lib.h:74
aint
uint_fast32_t aint
The APG parser's unsigned integer type.
Definition: apg.h:79
bMultiply32
abool bMultiply32(uint32_t uiL, uint32_t uiR, uint32_t *uipA)
Multiply two 32-bit unsigned integers with overflow notification.
Definition: tools.c:150
APG_SUCCESS
#define APG_SUCCESS
Definition: apg.h:307
apg_phrase
Defines a pointer to an achar array plus its length. That is, a phrase as is often used by APG.
Definition: lib.h:60
luint
uintmax_t luint
luint is used to cast integers suitable for the %"PRIuMAX" printf format.
Definition: apg.h:133
bIsBigEndian
abool bIsBigEndian(void)
Determine if the current machine uses big endian word storage.
Definition: tools.c:96
APG_TRUE
#define APG_TRUE
Definition: apg.h:291
apg_phrase::uiLength
aint uiLength
The number of characters in the array.
Definition: lib.h:62
bMultiplyLong
abool bMultiplyLong(luint luiL, luint luiR, luint *luipA)
Multiply two long unsigned integers with overflow notification.
Definition: tools.c:110
abool
uint8_t abool
abool is the APG bool type.
Definition: apg.h:140
spStrToPhrase
apg_phrase * spStrToPhrase(const char *cpStr, apg_phrase *spPhrase)
Convert an ASCII, null-terminated string to an achar phrase.
Definition: tools.c:237
bSum
abool bSum(aint uiL, aint uiR, aint *uipA)
Sum two unsigned integers with overflow notification.
Definition: tools.c:209
bSum32
abool bSum32(uint32_t uiL, uint32_t uiR, uint32_t *uipA)
Sum two 32-bit unsigned integers with overflow notification.
Definition: tools.c:170
u32_phrase
Defines a pointer to an array of 32-bit unsigned integers plus its length. Typically needed by Unicod...
Definition: lib.h:73
bMultiply
abool bMultiply(aint uiL, aint uiR, aint *uipA)
Multiply two APG unsigned integers with overflow notification.
Definition: tools.c:189
apg_phrase::acpPhrase
const achar * acpPhrase
Pointer to an array of type achar APG alphabet characters.
Definition: lib.h:61
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.