LMMS
Loading...
Searching...
No Matches
lineparse.h
Go to the documentation of this file.
1/*
2 WDL - lineparse.h
3 Copyright (C) 2005-2014 Cockos Incorporated
4 Copyright (C) 1999-2004 Nullsoft, Inc.
5
6 This software is provided 'as-is', without any express or implied
7 warranty. In no event will the authors be held liable for any damages
8 arising from the use of this software.
9
10 Permission is granted to anyone to use this software for any purpose,
11 including commercial applications, and to alter it and redistribute it
12 freely, subject to the following restrictions:
13
14 1. The origin of this software must not be misrepresented; you must not
15 claim that you wrote the original software. If you use this software
16 in a product, an acknowledgment in the product documentation would be
17 appreciated but is not required.
18 2. Altered source versions must be plainly marked as such, and must not be
19 misrepresented as being the original software.
20 3. This notice may not be removed or altered from any source distribution.
21
22*/
23
24/*
25
26 This file provides a simple line parsing class. This class was derived from that of NSIS,
27 http://nsis.sf.net, but it is no longer compatible (escaped-encodings and multiline C-style comments
28 are ignored).
29
30 In particular, it allows for multiple space delimited tokens
31 on a line, with a choice of three quotes (`bla`, 'bla', or "bla") to contain any
32 items that may have spaces.
33
34*/
35
36#ifndef WDL_LINEPARSE_H_
37#define WDL_LINEPARSE_H_
38
39#include "heapbuf.h"
40
41#ifndef WDL_LINEPARSER_HAS_LINEPARSERINT
42#define WDL_LINEPARSER_HAS_LINEPARSERINT
43#endif
44
45#ifdef WDL_LINEPARSE_ATOF
46 extern "C" double WDL_LINEPARSE_ATOF(const char *);
47#else
48 #define WDL_LINEPARSE_ATOF atof
49#endif
50
51#ifndef WDL_LINEPARSE_IMPL_ONLY
52class LineParserInt // version which does not have any temporary space for buffers (requires use of parseDestroyBuffer)
53{
54 public:
55 int getnumtokens() const { return m_nt-m_eat; }
56
57 #ifdef WDL_LINEPARSE_INTF_ONLY
58 // parse functions return <0 on error (-1=mem, -2=unterminated quotes), ignore_commentchars = true means don't treat #; as comments
59 int parseDestroyBuffer(char *line, bool ignore_commentchars = true, bool backtickquote = true, bool allowunterminatedquotes = false);
60
61 double gettoken_float(int token, int *success=NULL) const;
62 int gettoken_int(int token, int *success=NULL) const;
63 unsigned int gettoken_uint(int token, int *success=NULL) const;
64 const char *gettoken_str(int token) const;
65 char gettoken_quotingchar(int token) const;
66 int gettoken_enum(int token, const char *strlist) const; // null seperated list
67 #endif
68
69 void eattoken() { if (m_eat<m_nt) m_eat++; }
70
71
78
80 {
81 }
82
83#endif // !WDL_LINEPARSE_IMPL_ONLY
84
85
86
87#ifndef WDL_LINEPARSE_INTF_ONLY
88 #ifdef WDL_LINEPARSE_IMPL_ONLY
89 #define WDL_LINEPARSE_PREFIX LineParserInt::
90 #define WDL_LINEPARSE_DEFPARM(x)
91 #else
92 #define WDL_LINEPARSE_PREFIX
93 #define WDL_LINEPARSE_DEFPARM(x) =(x)
94 #endif
95
96 int WDL_LINEPARSE_PREFIX parseDestroyBuffer(char *line, bool ignore_commentchars WDL_LINEPARSE_DEFPARM(true), bool backtickquote WDL_LINEPARSE_DEFPARM(true), bool allowunterminatedquotes WDL_LINEPARSE_DEFPARM(false))
97 {
98 m_nt=0;
99 m_eat=0;
100 if (!line) return -1;
101
103 m_tokenbasebuffer = line;
104 char thischar;
105 while ((thischar=*line) == ' ' || thischar == '\t') line++;
106 if (!thischar) return 0;
107
108 for (;;)
109 {
110 static const char tab[4]={0, '"', '\'', '`'};
111 int lstate=0; // 1=", 2=`, 3='
112
113 switch (*line)
114 {
115 case ';':
116 case '#':
117 if (!ignore_commentchars) return 0; // we're done!
118 break;
119 case '"': line++; lstate=1; break;
120 case '\'': line++; lstate=2; break;
121 case '`': if (backtickquote) { line++; lstate=3; } break;
122 }
123
124 const char *basep = line;
125
126 if (!lstate) while ((thischar=*line) && thischar != ' ' && thischar != '\t') line++;
127 else while ((thischar=*line) && thischar != tab[lstate]) line++;
128
129 const char oldterm = *line;
130 *line=0; // null terminate this token
131
132 if (m_nt >= (int) (sizeof(m_toklist_small)/sizeof(m_toklist_small[0])))
133 {
134 m_tokens = m_toklist_big.ResizeOK(m_nt+1,false);
135 if (!m_tokens)
136 {
137 m_nt=0;
138 return -1;
139 }
140 if (m_nt == (int) (sizeof(m_toklist_small)/sizeof(m_toklist_small[0])))
141 memcpy(m_tokens,m_toklist_small,m_nt*sizeof(const char *));
142 }
143 m_tokens[m_nt++] = basep;
144
145 if (!oldterm)
146 {
147 if (lstate && !allowunterminatedquotes)
148 {
149 m_nt = 0;
150 return -2;
151 }
152 return 0;
153 }
154
155 line++;
156 while ((thischar=*line) == ' ' || thischar == '\t') line++;
157 if (!thischar) return 0;
158 }
159 }
160
161
162 double WDL_LINEPARSE_PREFIX gettoken_float(int token, int *success WDL_LINEPARSE_DEFPARM(NULL)) const
163 {
164 token+=m_eat;
165 if ((unsigned int)token >= m_nt)
166 {
167 if (success) *success=0;
168 return 0.0;
169 }
170 const char *t=m_tokens[token];
171 if (success)
172 *success=*t?1:0;
173
174 // todo: detect d or f prefix for double/float base64 encodings
175 char buf[512];
176 int ot = 0;
177 while (*t&&ot<(int)sizeof(buf)-1)
178 {
179 char c=*t++;
180 if (c == ',') c = '.';
181 else if (success && (c < '0' || c > '9') && c != '.') *success=0;
182 buf[ot++]=c;
183 }
184 buf[ot] = 0;
185 return WDL_LINEPARSE_ATOF(buf);
186 }
187
189 {
190 token+=m_eat;
191 const char *tok;
192 if ((unsigned int)token >= m_nt || !((tok=m_tokens[token])[0]))
193 {
194 if (success) *success=0;
195 return 0;
196 }
197 char *tmp;
198 int l;
199 if (tok[0] == '-') l=(int)strtol(tok,&tmp,0);
200 else l=(int)strtoul(tok,&tmp,0);
201 if (success) *success=! (int)(*tmp);
202 return l;
203 }
204
205 unsigned int WDL_LINEPARSE_PREFIX gettoken_uint(int token, int *success WDL_LINEPARSE_DEFPARM(NULL)) const
206 {
207 token+=m_eat;
208 const char *tok;
209 if ((unsigned int)token >= m_nt || !((tok=m_tokens[token])[0]))
210 {
211 if (success) *success=0;
212 return 0;
213 }
214 char *tmp;
215 const char* p=tok;
216 if (p[0] == '-') ++p;
217 unsigned int val=(int)strtoul(p, &tmp, 0);
218 if (success) *success=! (int)(*tmp);
219 return val;
220 }
221
222 const char * WDL_LINEPARSE_PREFIX gettoken_str(int token) const
223 {
224 token+=m_eat;
225 if ((unsigned int)token >= m_nt) return "";
226 return m_tokens[token];
227 }
228
230 {
231 token+=m_eat;
232 if ((unsigned int)token >= m_nt) return 0;
233
234 const char *tok = m_tokens[token];
235 if (tok != m_tokenbasebuffer) switch (tok[-1])
236 {
237 case '"': return '"';
238 case '`': return '`';
239 case '\'': return '\'';
240 }
241 return 0;
242 }
243
244 int WDL_LINEPARSE_PREFIX gettoken_enum(int token, const char *strlist) const // null seperated list
245 {
246 token+=m_eat;
247 if ((unsigned int)token >= m_nt) return -1;
248
249 int x=0;
250 const char *tt=m_tokens[token];
251 if (*tt) while (*strlist)
252 {
253#ifdef _WIN32
254 if (!stricmp(tt,strlist)) return x;
255#else
256 if (!strcasecmp(tt,strlist)) return x;
257#endif
258 while (*strlist) strlist++;
259 strlist++;
260 x++;
261 }
262 return -1;
263 }
264
265#ifndef WDL_LINEPARSE_IMPL_ONLY
266 private:
267#endif
268
269
270 #undef WDL_LINEPARSE_PREFIX
271 #undef WDL_LINEPARSE_DEFPARM
272#endif // ! WDL_LINEPARSE_INTF_ONLY
273
274#ifndef WDL_LINEPARSE_IMPL_ONLY
275 protected:
276
278
279 unsigned int m_nt, m_eat;
280
281 const char *m_tokenbasebuffer; // points to (mangled) caller's buffer
282 const char **m_tokens; // points to m_toklist_small or m_toklist_big
283
284 const char *m_toklist_small[64];
285};
286#endif
287
288
289
290
291
292
293// derived
294
295#ifndef WDL_LINEPARSE_IMPL_ONLY
297{
298 public:
299 int parse(const char *line) { return parse_ex(line,false); } // <0 on error, old style (;# starting tokens means comment to EOL)
300
301 #ifdef WDL_LINEPARSE_INTF_ONLY
302 // parse functions return <0 on error (-1=mem, -2=unterminated quotes), ignore_commentchars = true means don't treat #; as comments
303 int parse_ex(const char *line, bool ignore_commentchars = true, bool backtickquote = true, bool allowunterminatedquotes = false);
304 void set_one_token(const char *ptr);
305 char *__get_tmpbuf(const char *line);
306 #endif
307
308
309 LineParser(bool ignoredLegacyValue=false) { }
310
311#endif // !WDL_LINEPARSE_IMPL_ONLY
312
313
314
315#ifndef WDL_LINEPARSE_INTF_ONLY
316 #ifdef WDL_LINEPARSE_IMPL_ONLY
317 #define WDL_LINEPARSE_PREFIX LineParser::
318 #define WDL_LINEPARSE_DEFPARM(x)
319 #else
320 #define WDL_LINEPARSE_PREFIX
321 #define WDL_LINEPARSE_DEFPARM(x) =(x)
322 #endif
323
324 int WDL_LINEPARSE_PREFIX parse_ex(const char *line, bool ignore_commentchars WDL_LINEPARSE_DEFPARM(true), bool backtickquote WDL_LINEPARSE_DEFPARM(true), bool allowunterminatedquotes WDL_LINEPARSE_DEFPARM(false))
325 {
326 return parseDestroyBuffer(__get_tmpbuf(line), ignore_commentchars, backtickquote, allowunterminatedquotes);
327 }
328
329 void WDL_LINEPARSE_PREFIX set_one_token(const char *line)
330 {
333 m_eat=0;
335 }
336
337 char * WDL_LINEPARSE_PREFIX __get_tmpbuf(const char *line)
338 {
339 int linelen = (int)strlen(line);
340
341 char *usebuf=m_tmpbuf;
342 if (linelen >= (int)sizeof(m_tmpbuf))
343 {
344 usebuf = (char *)m_tmpbuf_big.ResizeOK(linelen+1,false);
345 if (!usebuf)
346 {
347 m_nt=0;
348 return NULL;
349 }
350 }
351 memcpy(usebuf,line,linelen+1);
352 return usebuf;
353 }
354
355 #undef WDL_LINEPARSE_PREFIX
356 #undef WDL_LINEPARSE_DEFPARM
357#endif // ! WDL_LINEPARSE_INTF_ONLY
358
359#ifndef WDL_LINEPARSE_IMPL_ONLY
360 private:
361
363 char m_tmpbuf[2048];
364};
365#endif
366
367
368
369
370
371
372
373#endif//WDL_LINEPARSE_H_
374
#define NULL
Definition CarlaBridgeFormat.cpp:30
LineParser(bool ignoredLegacyValue=false)
Definition lineparse.h:309
char *WDL_LINEPARSE_PREFIX __get_tmpbuf(const char *line)
Definition lineparse.h:337
int WDL_LINEPARSE_PREFIX parse_ex(const char *line, bool ignore_commentchars WDL_LINEPARSE_DEFPARM(true), bool backtickquote WDL_LINEPARSE_DEFPARM(true), bool allowunterminatedquotes WDL_LINEPARSE_DEFPARM(false))
Definition lineparse.h:324
char m_tmpbuf[2048]
Definition lineparse.h:363
int parse(const char *line)
Definition lineparse.h:299
void WDL_LINEPARSE_PREFIX set_one_token(const char *line)
Definition lineparse.h:329
WDL_HeapBuf m_tmpbuf_big
Definition lineparse.h:362
int WDL_LINEPARSE_PREFIX gettoken_enum(int token, const char *strlist) const
Definition lineparse.h:244
WDL_TypedBuf< const char * > m_toklist_big
Definition lineparse.h:277
double WDL_LINEPARSE_PREFIX gettoken_float(int token, int *success WDL_LINEPARSE_DEFPARM(NULL)) const
Definition lineparse.h:162
const char *WDL_LINEPARSE_PREFIX gettoken_str(int token) const
Definition lineparse.h:222
const char * m_toklist_small[64]
Definition lineparse.h:284
unsigned int WDL_LINEPARSE_PREFIX gettoken_uint(int token, int *success WDL_LINEPARSE_DEFPARM(NULL)) const
Definition lineparse.h:205
LineParserInt()
Definition lineparse.h:72
char WDL_LINEPARSE_PREFIX gettoken_quotingchar(int token) const
Definition lineparse.h:229
int WDL_LINEPARSE_PREFIX parseDestroyBuffer(char *line, bool ignore_commentchars WDL_LINEPARSE_DEFPARM(true), bool backtickquote WDL_LINEPARSE_DEFPARM(true), bool allowunterminatedquotes WDL_LINEPARSE_DEFPARM(false))
Definition lineparse.h:96
unsigned int m_nt
Definition lineparse.h:279
~LineParserInt()
Definition lineparse.h:79
const char ** m_tokens
Definition lineparse.h:282
unsigned int m_eat
Definition lineparse.h:279
const char * m_tokenbasebuffer
Definition lineparse.h:281
void eattoken()
Definition lineparse.h:69
int WDL_LINEPARSE_PREFIX gettoken_int(int token, int *success WDL_LINEPARSE_DEFPARM(NULL)) const
Definition lineparse.h:188
int getnumtokens() const
Definition lineparse.h:55
Definition heapbuf.h:48
Definition heapbuf.h:259
int * l
Definition inflate.c:1579
struct huft * t
Definition inflate.c:943
unsigned x[BMAX+1]
Definition inflate.c:1586
int val
Definition jpeglib.h:956
#define WDL_LINEPARSE_ATOF
Definition lineparse.h:48
#define WDL_LINEPARSE_PREFIX
Definition lineparse.h:92
#define WDL_LINEPARSE_DEFPARM(x)
Definition lineparse.h:93
#define stricmp(x, y)
Definition swell-types.h:68
uch * p
Definition crypt.c:594
return c
Definition crypt.c:175
memcpy(hh, h, RAND_HEAD_LEN)
typedef int(UZ_EXP MsgFn)()