summaryrefslogtreecommitdiff
path: root/src/common/strlib.h
blob: ae4f688c23a0f82b5f3313bc4d7ec77ac516fb7e (plain) (blame)
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
152
// Copyright (c) Athena Dev Teams - Licensed under GNU GPL
// For more information, see LICENCE in the main folder

#ifndef _STRLIB_H_
#define _STRLIB_H_

#include "../common/cbasetypes.h"
#include <stdarg.h>

#define __USE_GNU  // required to enable strnlen on some platforms
#include <string.h>
#undef __USE_GNU

char *jstrescape(char *pt);
char *jstrescapecpy(char *pt, const char *spt);
int jmemescapecpy(char *pt, const char *spt, int size);

int remove_control_chars(char *str);
char *trim(char *str);
char *normalize_name(char *str,const char *delims);
const char *stristr(const char *haystack, const char *needle);

#ifdef WIN32
#define HAVE_STRTOK_R
#define strtok_r(s,delim,save_ptr) _strtok_r((s),(delim),(save_ptr))
char *_strtok_r(char *s1, const char *s2, char **lasts);
#endif

#if !(defined(WIN32) && defined(_MSC_VER) && _MSC_VER >= 1400) && !defined(HAVE_STRNLEN)
size_t strnlen(const char *string, size_t maxlen);
#endif

#if defined(WIN32) && defined(_MSC_VER) && _MSC_VER <= 1200
uint64 strtoull(const char *str, char **endptr, int base);
#endif

int e_mail_check(char *email);
int config_switch(const char *str);

/// strncpy that always nul-terminates the string
char *safestrncpy(char *dst, const char *src, size_t n);

/// doesn't crash on null pointer
size_t safestrnlen(const char *string, size_t maxlen);

/// Works like snprintf, but always nul-terminates the buffer.
/// Returns the size of the string (without nul-terminator)
/// or -1 if the buffer is too small.
int safesnprintf(char *buf, size_t sz, const char *fmt, ...);

/// Returns the line of the target position in the string.
/// Lines start at 1.
int strline(const char *str, size_t pos);

/// Produces the hexadecimal representation of the given input.
/// The output buffer must be at least count*2+1 in size.
/// Returns true on success, false on failure.
bool bin2hex(char *output, unsigned char *input, size_t count);


/// Bitfield determining the behaviour of sv_parse and sv_split.
typedef enum e_svopt {
    // default: no escapes and no line terminator
    SV_NOESCAPE_NOTERMINATE = 0,
    // Escapes according to the C compiler.
    SV_ESCAPE_C = 1,
    // Line terminators
    SV_TERMINATE_LF = 2,
    SV_TERMINATE_CRLF = 4,
    SV_TERMINATE_CR = 8,
    // If sv_split keeps the end of line terminator, instead of replacing with '\0'
    SV_KEEP_TERMINATOR = 16
} e_svopt;

/// Other escape sequences supported by the C compiler.
#define SV_ESCAPE_C_SUPPORTED "abtnvfr\?\"'\\"

/// Parse state.
/// The field is [start,end[
struct s_svstate {
    const char *str; //< string to parse
    int len; //< string length
    int off; //< current offset in the string
    int start; //< where the field starts
    int end; //< where the field ends
    enum e_svopt opt; //< parse options
    char delim; //< field delimiter
    bool done; //< if all the text has been parsed
};

/// Parses a single field in a delim-separated string.
/// The delimiter after the field is skipped.
///
/// @param sv Parse state
/// @return 1 if a field was parsed, 0 if done, -1 on error.
int sv_parse_next(struct s_svstate *sv);

/// Parses a delim-separated string.
/// Starts parsing at startoff and fills the pos array with position pairs.
/// out_pos[0] and out_pos[1] are the start and end of line.
/// Other position pairs are the start and end of fields.
/// Returns the number of fields found or -1 if an error occurs.
int sv_parse(const char *str, int len, int startoff, char delim, int *out_pos, int npos, enum e_svopt opt);

/// Splits a delim-separated string.
/// WARNING: this function modifies the input string
/// Starts splitting at startoff and fills the out_fields array.
/// out_fields[0] is the start of the next line.
/// Other entries are the start of fields (nul-teminated).
/// Returns the number of fields found or -1 if an error occurs.
int sv_split(char *str, int len, int startoff, char delim, char **out_fields, int nfields, enum e_svopt opt);

/// Escapes src to out_dest according to the format of the C compiler.
/// Returns the length of the escaped string.
/// out_dest should be len*4+1 in size.
size_t sv_escape_c(char *out_dest, const char *src, size_t len, const char *escapes);

/// Unescapes src to out_dest according to the format of the C compiler.
/// Returns the length of the unescaped string.
/// out_dest should be len+1 in size and can be the same buffer as src.
size_t sv_unescape_c(char *out_dest, const char *src, size_t len);

/// Skips a C escape sequence (starting with '\\').
const char *skip_escaped_c(const char *p);

/// Opens and parses a file containing delim-separated columns, feeding them to the specified callback function row by row.
/// Tracks the progress of the operation (current line number, number of successfully processed rows).
/// Returns 'true' if it was able to process the specified file, or 'false' if it could not be read.
bool sv_readdb(const char *directory, const char *filename, char delim, int mincols, int maxcols, int maxrows, bool (*parseproc)(char *fields[], int columns, int current));


/// StringBuf - dynamic string
struct StringBuf {
    char *buf_;
    char *ptr_;
    unsigned int max_;
};
typedef struct StringBuf StringBuf;

StringBuf *StringBuf_Malloc(void);
void StringBuf_Init(StringBuf *self);
int StringBuf_Printf(StringBuf *self, const char *fmt, ...);
int StringBuf_Vprintf(StringBuf *self, const char *fmt, va_list args);
int StringBuf_Append(StringBuf *self, const StringBuf *sbuf);
int StringBuf_AppendStr(StringBuf *self, const char *str);
int StringBuf_Length(StringBuf *self);
char *StringBuf_Value(StringBuf *self);
void StringBuf_Clear(StringBuf *self);
void StringBuf_Destroy(StringBuf *self);
void StringBuf_Free(StringBuf *self);

#endif /* _STRLIB_H_ */