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
|
#ifndef SLANG_CORE_STRING_ESCAPE_UTIL_H
#define SLANG_CORE_STRING_ESCAPE_UTIL_H
#include "slang-list.h"
#include "slang-string.h"
namespace Slang
{
class StringEscapeHandler
{
public:
/// True if quoting is needed
virtual bool isQuotingNeeded(const UnownedStringSlice& slice) = 0;
/// True if any escaping is needed. If not slice can be used (assuming appropriate quoting) as
/// is
virtual bool isEscapingNeeded(const UnownedStringSlice& slice) = 0;
/// True if we need to unescape
virtual bool isUnescapingNeeeded(const UnownedStringSlice& slice) = 0;
/// Takes slice and adds any appropriate escaping (for example C++/C type escaping for special
/// characters like '\', '"' and if not ascii will write out as hex sequence) Does not append
/// quotes
virtual SlangResult appendEscaped(const UnownedStringSlice& slice, StringBuilder& out) = 0;
/// Given a slice append it unescaped
/// Does not consume surrounding quotes
virtual SlangResult appendUnescaped(const UnownedStringSlice& slice, StringBuilder& out) = 0;
/// Lex quoted text.
/// The first character of cursor should be the quoteCharacter.
/// cursor points to the string to be lexed - must typically be 0 terminated.
/// outCursor on successful lex will be at the next character after was processed.
virtual SlangResult lexQuoted(const char* cursor, const char** outCursor) = 0;
SLANG_FORCE_INLINE char getQuoteChar() const { return m_quoteChar; }
StringEscapeHandler(char quoteChar)
: m_quoteChar(quoteChar)
{
}
protected:
const char m_quoteChar;
};
/* A set of function that can be used for escaping/unescaping quoting/unquoting strings.
The distinction between 'escaping' and 'quoting' here, is just that escaping is the 'payload' of
quotes. In *principal* the Style can determine different styles of escaping that can be used.
*/
struct StringEscapeUtil
{
typedef StringEscapeHandler Handler;
enum class Style
{
Cpp, ///< Cpp style quoting and escape handling
Space, ///< Applies quotes if there are spaces. Does not escape.
JSON, ///< Json encoding
Slang, ///< Slang style string encoding (For now same as Cpp but that may change in the
///< future)
CountOf,
};
/// Given a style returns a handler
static Handler* getHandler(Style style);
/// Get without quotes. Will assert if not correctly quoted
static UnownedStringSlice unquote(char quoteChar, const UnownedStringSlice& slice);
static UnownedStringSlice unquote(Handler* handler, const UnownedStringSlice& slice)
{
return unquote(handler->getQuoteChar(), slice);
}
/// True is slice is quoted
static bool isQuoted(char quoteChar, UnownedStringSlice& slice);
static bool isQuoted(Handler* handler, UnownedStringSlice& slice)
{
return isQuoted(handler->getQuoteChar(), slice);
}
/// If quoting is needed appends to out quoted
static SlangResult appendMaybeQuoted(
Handler* handler,
const UnownedStringSlice& slice,
StringBuilder& out);
/// If the slice appears to be quoted for the style, unquote it, else just append to out
static SlangResult appendMaybeUnquoted(
Handler* handler,
const UnownedStringSlice& slice,
StringBuilder& out);
/// Appends to out slice without quotes
static SlangResult appendUnquoted(
Handler* handler,
const UnownedStringSlice& slice,
StringBuilder& out);
/// Append with quotes (even if not needed)
static SlangResult appendQuoted(
Handler* handler,
const UnownedStringSlice& slice,
StringBuilder& out);
/// True if requires 'shell-like' unescape. With shell-like, quoting does *not* have to start at
/// the start of the slice. and there may be multiple quoted section
static SlangResult isUnescapeShellLikeNeeded(Handler* handler, const UnownedStringSlice& slice);
/// Shells can have multiple quoted sections. This function makes a string with out quoting
static SlangResult unescapeShellLike(
Handler* handler,
const UnownedStringSlice& slice,
StringBuilder& out);
};
} // namespace Slang
#endif // SLANG_CORE_STRING_ESCAPE_UTIL_H
|