/
string.h
151 lines (125 loc) · 8.55 KB
/
string.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
/***********************************************************************************************************************************
String Handler
Strings are lightweight objects in that they do not have their own memory context, instead they exist in the current context in
which they are instantiated. If a string is needed outside the current memory context, the memory context must be switched to the
old context and then back. Below is a simplified example:
String *result = NULL; <--- is created in the current memory context (referred to as "old context" below)
MEM_CONTEXT_TEMP_BEGIN() <--- begins a new temporary context
{
String *resultStr = strNewN("myNewStr"); <--- creates a string in the temporary memory context
memContextSwitch(MEM_CONTEXT_OLD()); <--- switch to the old context so the duplication of the string is in that context
result = strDup(resultStr); <--- recreates a copy of the string in the old context where "result" was created.
memContextSwitch(MEM_CONTEXT_TEMP()); <--- switch back to the temporary context
}
MEM_CONTEXT_TEMP_END(); <-- frees everything created inside this temporary memory context - i.e resultStr
***********************************************************************************************************************************/
#ifndef COMMON_TYPE_STRING_H
#define COMMON_TYPE_STRING_H
#include <stdint.h>
/***********************************************************************************************************************************
String object
***********************************************************************************************************************************/
typedef struct String String;
#include "common/type/buffer.h"
/***********************************************************************************************************************************
Functions
***********************************************************************************************************************************/
String *strNew(const char *string);
String *strNewBuf(const Buffer *buffer);
String *strNewFmt(const char *format, ...) __attribute__((format(printf, 1, 2)));
String *strNewN(const char *string, size_t size);
String *strBase(const String *this);
bool strBeginsWith(const String *this, const String *beginsWith);
bool strBeginsWithZ(const String *this, const char *beginsWith);
String *strCat(String *this, const char *cat);
String *strCatChr(String *this, char cat);
String *strCatFmt(String *this, const char *format, ...) __attribute__((format(printf, 2, 3)));
int strCmp(const String *this, const String *compare);
int strCmpZ(const String *this, const char *compare);
String *strDup(const String *this);
bool strEmpty(const String *this);
bool strEndsWith(const String *this, const String *endsWith);
bool strEndsWithZ(const String *this, const char *endsWith);
bool strEq(const String *this, const String *compare);
bool strEqZ(const String *this, const char *compare);
String *strFirstUpper(String *this);
String *strFirstLower(String *this);
String *strUpper(String *this);
String *strLower(String *this);
String *strPath(const String *this);
const char *strPtr(const String *this);
String *strQuote(const String *this, const String *quote);
String *strQuoteZ(const String *this, const char *quote);
String *strReplaceChr(String *this, char find, char replace);
size_t strSize(const String *this);
String *strSub(const String *this, size_t start);
String *strSubN(const String *this, size_t start, size_t size);
String *strTrim(String *this);
int strChr(const String *this, char chr);
String *strTrunc(String *this, int idx);
String *strSizeFormat(const uint64_t fileSize);
void strFree(String *this);
/***********************************************************************************************************************************
Fields that are common between dynamically allocated and constant strings
There is nothing user-accessible here but this construct allows constant strings to be created and then handled by the same
functions that process dynamically allocated strings.
***********************************************************************************************************************************/
struct StringCommon
{
size_t size;
char *buffer;
};
/***********************************************************************************************************************************
Macros for constant strings
Frequently used constant strings can be declared with these macros at compile time rather than dynamically at run time.
Note that strings created in this way are declared as const so can't be modified or freed by the str*() methods. Casting to
String * will result in a segfault due to modifying read-only memory.
By convention all string constant identifiers are appended with _STR.
***********************************************************************************************************************************/
// Create a string constant inline. Useful when the constant will only be use once.
#define STRING_CONST(value) \
((const String *)&(const struct StringCommon){.size = sizeof(value) - 1, .buffer = (char *)value})
// Used to declare string constants that will be externed using STRING_DECLARE(). Must be used in a .c file.
#define STRING_EXTERN(name, value) \
const String *name = STRING_CONST(value)
// Used to declare string constants that will be local to the .c file. Must be used in a .c file.
#define STRING_STATIC(name, value) \
static const String *name = STRING_CONST(value)
// Used to extern string constants declared with STRING_EXTERN(. Must be used in a .h file.
#define STRING_DECLARE(name) \
extern const String *name
/***********************************************************************************************************************************
Constant strings that are generally useful
***********************************************************************************************************************************/
STRING_DECLARE(CR_STR);
STRING_DECLARE(EMPTY_STR);
STRING_DECLARE(FSLASH_STR);
STRING_DECLARE(LF_STR);
STRING_DECLARE(N_STR);
STRING_DECLARE(NULL_STR);
STRING_DECLARE(Y_STR);
STRING_DECLARE(ZERO_STR);
/***********************************************************************************************************************************
Helper function/macro for object logging
***********************************************************************************************************************************/
typedef String *(*StrObjToLogFormat)(const void *object);
size_t strObjToLog(const void *object, StrObjToLogFormat formatFunc, char *buffer, size_t bufferSize);
#define FUNCTION_DEBUG_STRING_OBJECT_FORMAT(object, formatFunc, buffer, bufferSize) \
strObjToLog(object, (StrObjToLogFormat)formatFunc, buffer, bufferSize)
/***********************************************************************************************************************************
Macros for function logging
***********************************************************************************************************************************/
String *strToLog(const String *this);
#define FUNCTION_DEBUG_CONST_STRING_TYPE \
const String *
#define FUNCTION_DEBUG_CONST_STRING_FORMAT(value, buffer, bufferSize) \
FUNCTION_DEBUG_STRING_FORMAT(value, buffer, bufferSize)
#define FUNCTION_DEBUG_STRING_TYPE \
String *
#define FUNCTION_DEBUG_STRING_FORMAT(value, buffer, bufferSize) \
FUNCTION_DEBUG_STRING_OBJECT_FORMAT(value, strToLog, buffer, bufferSize)
#define FUNCTION_DEBUG_STRINGP_TYPE \
const String **
#define FUNCTION_DEBUG_STRINGP_FORMAT(value, buffer, bufferSize) \
ptrToLog(value, "String **", buffer, bufferSize)
#endif