[IPLUG/AU] add IParam::mIsMeta and related setter/getter in order to get params that...
[wdl/wdl-ol.git] / WDL / lineparse.h
blob03f7340a7ff2bb57e54f1a16dff9b1118cde05a4
1 /*
2 WDL - lineparse.h
3 Copyright (C) 2005-2014 Cockos Incorporated
4 Copyright (C) 1999-2004 Nullsoft, Inc.
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.
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:
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.
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).
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.
36 #ifndef WDL_LINEPARSE_H_
37 #define WDL_LINEPARSE_H_
40 #ifndef WDL_LINEPARSE_IMPL_ONLY
41 class LineParser
43 public:
44 int getnumtokens() const { return (m_nt-m_eat)>=0 ? (m_nt-m_eat) : 0; }
45 #ifdef WDL_LINEPARSE_INTF_ONLY
46 int parse(const char *line); //-1 on error
48 double gettoken_float(int token, int *success=NULL) const;
49 int gettoken_int(int token, int *success=NULL) const;
50 unsigned int gettoken_uint(int token, int *success=NULL) const;
51 const char *gettoken_str(int token) const;
52 int gettoken_enum(int token, const char *strlist) const; // null seperated list
54 void set_one_token(const char *ptr);
55 #endif
57 void eattoken() { m_eat++; }
60 LineParser(bool ignoredLegacyValue=false)
62 m_nt=m_eat=0;
63 m_tokens=0;
64 m_tmpbuf_used=0;
67 ~LineParser()
69 freetokens();
72 #endif // !WDL_LINEPARSE_IMPL_ONLY
76 #ifndef WDL_LINEPARSE_INTF_ONLY
77 #ifdef WDL_LINEPARSE_IMPL_ONLY
78 #define WDL_LINEPARSE_PREFIX LineParser::
79 #define WDL_LINEPARSE_DEFPARM(x)
80 #else
81 #define WDL_LINEPARSE_PREFIX
82 #define WDL_LINEPARSE_DEFPARM(x) =(x)
83 #endif
85 int WDL_LINEPARSE_PREFIX parse(const char *line)
87 freetokens();
88 int n=doline(line);
89 if (n) { m_nt=0; return n; }
90 if (m_nt)
92 m_tokens=(char**)tmpbufalloc(sizeof(char*)*m_nt);
93 if (m_tokens) memset(m_tokens,0,m_nt * sizeof(char*));
94 n=doline(line);
95 if (n)
97 freetokens();
98 return -1;
101 return 0;
103 void WDL_LINEPARSE_PREFIX set_one_token(const char *ptr)
105 freetokens();
106 m_eat=0;
107 m_nt=1;
108 m_tokens=(char **)tmpbufalloc(sizeof(char *));
109 m_tokens[0]=tmpbufalloc(strlen(ptr)+1);
110 if (m_tokens[0]) strcpy(m_tokens[0],ptr);
113 double WDL_LINEPARSE_PREFIX gettoken_float(int token, int *success WDL_LINEPARSE_DEFPARM(NULL)) const
115 token+=m_eat;
116 if (token < 0 || token >= m_nt || !m_tokens || !m_tokens[token])
118 if (success) *success=0;
119 return 0.0;
121 const char *t=m_tokens[token];
122 if (success)
123 *success=*t?1:0;
125 // todo: detect d or f prefix for double/float base64 encodings
126 char buf[512];
127 int ot = 0;
128 while (*t&&ot<(int)sizeof(buf)-1)
130 char c=*t++;
131 if (c == ',') c = '.';
132 else if (success && (c < '0' || c > '9') && c != '.') *success=0;
133 buf[ot++]=c;
135 buf[ot] = 0;
136 return atof(buf);
139 int WDL_LINEPARSE_PREFIX gettoken_int(int token, int *success WDL_LINEPARSE_DEFPARM(NULL)) const
141 token+=m_eat;
142 if (token < 0 || token >= m_nt || !m_tokens || !m_tokens[token] || !m_tokens[token][0])
144 if (success) *success=0;
145 return 0;
147 char *tmp;
148 int l;
149 if (m_tokens[token][0] == '-') l=strtol(m_tokens[token],&tmp,0);
150 else l=(int)strtoul(m_tokens[token],&tmp,0);
151 if (success) *success=! (int)(*tmp);
152 return l;
155 unsigned int WDL_LINEPARSE_PREFIX gettoken_uint(int token, int *success WDL_LINEPARSE_DEFPARM(NULL)) const
157 token+=m_eat;
158 if (token < 0 || token >= m_nt || !m_tokens || !m_tokens[token] || !m_tokens[token][0])
160 if (success) *success=0;
161 return 0;
163 char *tmp;
164 const char* p=m_tokens[token];
165 if (p[0] == '-') ++p;
166 unsigned int val=(int)strtoul(p, &tmp, 0);
167 if (success) *success=! (int)(*tmp);
168 return val;
171 const char * WDL_LINEPARSE_PREFIX gettoken_str(int token) const
173 token+=m_eat;
174 if (token < 0 || token >= m_nt || !m_tokens || !m_tokens[token]) return "";
175 return m_tokens[token];
178 int WDL_LINEPARSE_PREFIX gettoken_enum(int token, const char *strlist) const // null seperated list
180 int x=0;
181 const char *tt=gettoken_str(token);
182 if (tt && *tt) while (*strlist)
184 #ifdef _WIN32
185 if (!stricmp(tt,strlist)) return x;
186 #else
187 if (!strcasecmp(tt,strlist)) return x;
188 #endif
189 strlist+=strlen(strlist)+1;
190 x++;
192 return -1;
195 #ifndef WDL_LINEPARSE_IMPL_ONLY
196 private:
197 #endif
199 void WDL_LINEPARSE_PREFIX freetokens()
201 if (m_tokens)
203 int x;
204 for (x = 0; x < m_nt; x ++) tmpbuffree(m_tokens[x]);
205 tmpbuffree((char*)m_tokens);
207 m_tmpbuf_used=0;
208 m_tokens=0;
209 m_nt=0;
212 int WDL_LINEPARSE_PREFIX doline(const char *line)
214 m_nt=0;
215 while (*line == ' ' || *line == '\t') line++;
216 while (*line)
218 int lstate=0; // 1=", 2=`, 4='
219 if (*line == ';' || *line == '#') break;
220 if (*line == '\"') lstate=1;
221 else if (*line == '\'') lstate=2;
222 else if (*line == '`') lstate=4;
223 if (lstate) line++;
224 int nc=0;
225 const char *p = line;
226 while (*line)
228 if (lstate==1 && *line =='\"') break;
229 if (lstate==2 && *line =='\'') break;
230 if (lstate==4 && *line =='`') break;
231 if (!lstate && (*line == ' ' || *line == '\t')) break;
232 line++;
233 nc++;
235 if (m_tokens)
237 m_tokens[m_nt]=tmpbufalloc(nc+1);
238 if (m_tokens[m_nt])
240 memcpy(m_tokens[m_nt], p, nc);
241 m_tokens[m_nt][nc]=0;
244 m_nt++;
245 if (lstate)
247 if (*line) line++;
248 else return -2;
250 while (*line == ' ' || *line == '\t') line++;
252 return 0;
255 char * WDL_LINEPARSE_PREFIX tmpbufalloc(size_t sz)
257 if (sz<1)sz=1;
258 if (sz+m_tmpbuf_used <= sizeof(m_tmpbuf))
260 m_tmpbuf_used+=sz;
261 return m_tmpbuf + m_tmpbuf_used - sz;
263 return (char *)malloc(sz);
265 void WDL_LINEPARSE_PREFIX tmpbuffree(char *p)
267 if (p < m_tmpbuf || p >= m_tmpbuf + sizeof(m_tmpbuf)) free(p);
270 #undef WDL_LINEPARSE_PREFIX
271 #undef WDL_LINEPARSE_DEFPARM
272 #endif // ! WDL_LINEPARSE_INTF_ONLY
274 #ifndef WDL_LINEPARSE_IMPL_ONLY
275 private:
277 #ifdef WDL_LINEPARSE_INTF_ONLY
278 void freetokens();
279 int doline(const char *line);
280 char *tmpbufalloc(size_t sz);
281 void tmpbuffree(char *p);
282 #endif
284 size_t m_tmpbuf_used;
285 char **m_tokens;
286 int m_eat;
287 int m_nt;
288 char m_tmpbuf[2048];
290 #endif//!WDL_LINEPARSE_IMPL_ONLY
291 #endif//WDL_LINEPARSE_H_