1 // Copyright 2020 Michael Reilly (mreilly@resiliware.com).
2 //
3 // Redistribution and use in source and binary forms, with or without
4 // modification, are permitted provided that the following conditions
5 // are met:
6 // 1. Redistributions of source code must retain the above copyright
7 //    notice, this list of conditions and the following disclaimer.
8 // 2. Redistributions in binary form must reproduce the above copyright
9 //    notice, this list of conditions and the following disclaimer in the
10 //    documentation and/or other materials provided with the distribution.
11 // 3. Neither the names of the copyright holders nor the names of the
12 //    contributors may be used to endorse or promote products derived from
13 //    this software without specific prior written permission.
14 //
15 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 // ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
18 // PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS
19 // OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22 // OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23 // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24 // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25 // ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 
27 #ifndef _RESILIWARE_UTIL_H_
28 #define _RESILIWARE_UTIL_H_
29 
30 #include <stddef.h>
31 #include <stdbool.h>
32 #include <stdint.h>
33 #include <stdio.h>
34 
35 // Some constants
36 #if (INTMAX_MAX <= INT64_MAX)
37     #define MAX_DEC 20 // 18446744073709551615
38 #else
39     #error
40 #endif
41 
42 // Strip text from definition (macro to string)
43 #define MSR(m) #m
44 #define MS(m) MSR(m)
45 
46 // Basic math macros
47 #define min(a, b)            ( (a) < (b) ? (a) : (b) )
48 #define max(a, b)            ( (a) > (b) ? (a) : (b) )
49 #define mod(a, b)            ( (b) ? (a) % (b) : (a) )
50 
51 // Distance to the next bound, exclusive of o
52 #define distbound(o, b)      ( ((o) % (b)) ? ((b) - (o) % (b)) : (b) )
53 
54 // Distance to the next bound, inclusive of o
55 #define distbound_incl(o, b) ( ((o) % (b)) ? ((b) - (o) % (b)) :  0  )
56 
57 // Round o up to the next multiple of b (unless it already is a multiple of b)
58 #define ceilbound(o, b)      ( (o) + distbound_incl(o, b) )
59 
60 // Largest multiple of b not greater than l
61 #define _bestfit(b, l)       ( (b) >= (l) ? (l) : ((l) / (b)) * (b) )
62 #define bestfit(b, l)        ( (b) <= 0   ?  0  : _bestfit(b, l) )
63 
64 // Pluralize the string
65 #define plrztn(t)            (t), ((t) == 1 ? "" : "s")
66 
67 // Space removal
68 #define iswhspace(c)          ((c) == ' ')
69 #define stripLeadingSpaces(l) for( ; iswhspace(*l); l++);
70 void stripTrailingSpaces(char *line);
71 
72 // String equality
73 #define streq(a, b) (strcmp((a), (b)) == 0)
74 
75 // Substring equality, advancing a if equal
76 int strnconsume(char const **a, char const *b, size_t len);
77 
78 // Membership of character in the given list
79 bool memberof(char ch, char const *list);
80 bool memberofexnul(char ch, char const *list);
81 
82 // Search for character within substring
83 char const *strnchr(char const *str, int ch, size_t slen);
84 
85 // Bit information
86 int highbit(uint8_t octet);
87 int lowbit(uint8_t octet);
88 int countbit(uint8_t octet);
89 
90 // Tracing capabilities
91 void trace_fmt(FILE *trace_fp, char const *fmt, ...);
92 void trace_close(FILE *trace_fp);
93 #ifndef SRCNAME
94     #define SRCNAME __FILE__
95 #endif
96 #define TRC(p, f, ...) \
97   trace_fmt(p, "[%s:%d]  %s%s" f "%s", __VA_ARGS__)
98 #define tracef(p, f, ...) \
99   TRC(p, f, SRCNAME, __LINE__,           "",  "", ##__VA_ARGS__, "") // -newline
100 #define tracefEntry(p, f, ...) \
101   TRC(p, f, SRCNAME, __LINE__, __FUNCTION__, "(", ##__VA_ARGS__, ")\n")
102 #define tracefExit(p, f, ...) \
103   TRC(p, f, SRCNAME, __LINE__, __FUNCTION__, "() returns ", ##__VA_ARGS__, "\n")
104 
105 // The following macros make tracing easy
106 //#define trace(...)      tracef(TRACE_FILE_POINTER, "" __VA_ARGS__)
107 //#define traceEntry(...) tracefEntry(TRACE_FILE_POINTER, "" __VA_ARGS__)
108 //#define traceExit(...)  tracefExit(TRACE_FILE_POINTER, "" __VA_ARGS__)
109 //#define closeTrace()    trace_close(TRACE_FILE_POINTER)
110 
111 #endif
112