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
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
44 int getnumtokens() const { return (m_nt
-m_eat
)>=0 ? (m_nt
-m_eat
) : 0; }
45 int parse(const char *line
) { return parse_ex(line
,false); } // <0 on error, old style (;# starting tokens means comment to EOL)
47 #ifdef WDL_LINEPARSE_INTF_ONLY
48 int parse_ex(const char *line
, bool withcomments
= true); // <0 on error, withcomments = true means don't treat #; as comments
50 double gettoken_float(int token
, int *success
=NULL
) const;
51 int gettoken_int(int token
, int *success
=NULL
) const;
52 unsigned int gettoken_uint(int token
, int *success
=NULL
) const;
53 const char *gettoken_str(int token
) const;
54 int gettoken_enum(int token
, const char *strlist
) const; // null seperated list
56 void set_one_token(const char *ptr
);
59 void eattoken() { m_eat
++; }
62 LineParser(bool ignoredLegacyValue
=false)
74 #endif // !WDL_LINEPARSE_IMPL_ONLY
78 #ifndef WDL_LINEPARSE_INTF_ONLY
79 #ifdef WDL_LINEPARSE_IMPL_ONLY
80 #define WDL_LINEPARSE_PREFIX LineParser::
81 #define WDL_LINEPARSE_DEFPARM(x)
83 #define WDL_LINEPARSE_PREFIX
84 #define WDL_LINEPARSE_DEFPARM(x) =(x)
87 int WDL_LINEPARSE_PREFIX
parse_ex(const char *line
, bool withcomments
WDL_LINEPARSE_DEFPARM(true))
90 int n
=doline(line
, withcomments
);
91 if (n
) { m_nt
=0; return n
; }
94 m_tokens
=(char**)tmpbufalloc(sizeof(char*)*m_nt
);
95 if (m_tokens
) memset(m_tokens
,0,m_nt
* sizeof(char*));
96 n
=doline(line
, withcomments
);
107 void WDL_LINEPARSE_PREFIX
set_one_token(const char *ptr
)
112 m_tokens
=(char **)tmpbufalloc(sizeof(char *));
113 m_tokens
[0]=tmpbufalloc(strlen(ptr
)+1);
114 if (m_tokens
[0]) strcpy(m_tokens
[0],ptr
);
117 double WDL_LINEPARSE_PREFIX
gettoken_float(int token
, int *success
WDL_LINEPARSE_DEFPARM(NULL
)) const
120 if (token
< 0 || token
>= m_nt
|| !m_tokens
|| !m_tokens
[token
])
122 if (success
) *success
=0;
125 const char *t
=m_tokens
[token
];
129 // todo: detect d or f prefix for double/float base64 encodings
132 while (*t
&&ot
<(int)sizeof(buf
)-1)
135 if (c
== ',') c
= '.';
136 else if (success
&& (c
< '0' || c
> '9') && c
!= '.') *success
=0;
143 int WDL_LINEPARSE_PREFIX
gettoken_int(int token
, int *success
WDL_LINEPARSE_DEFPARM(NULL
)) const
146 if (token
< 0 || token
>= m_nt
|| !m_tokens
|| !m_tokens
[token
] || !m_tokens
[token
][0])
148 if (success
) *success
=0;
153 if (m_tokens
[token
][0] == '-') l
=strtol(m_tokens
[token
],&tmp
,0);
154 else l
=(int)strtoul(m_tokens
[token
],&tmp
,0);
155 if (success
) *success
=! (int)(*tmp
);
159 unsigned int WDL_LINEPARSE_PREFIX
gettoken_uint(int token
, int *success
WDL_LINEPARSE_DEFPARM(NULL
)) const
162 if (token
< 0 || token
>= m_nt
|| !m_tokens
|| !m_tokens
[token
] || !m_tokens
[token
][0])
164 if (success
) *success
=0;
168 const char* p
=m_tokens
[token
];
169 if (p
[0] == '-') ++p
;
170 unsigned int val
=(int)strtoul(p
, &tmp
, 0);
171 if (success
) *success
=! (int)(*tmp
);
175 const char * WDL_LINEPARSE_PREFIX
gettoken_str(int token
) const
178 if (token
< 0 || token
>= m_nt
|| !m_tokens
|| !m_tokens
[token
]) return "";
179 return m_tokens
[token
];
182 int WDL_LINEPARSE_PREFIX
gettoken_enum(int token
, const char *strlist
) const // null seperated list
185 const char *tt
=gettoken_str(token
);
186 if (tt
&& *tt
) while (*strlist
)
189 if (!stricmp(tt
,strlist
)) return x
;
191 if (!strcasecmp(tt
,strlist
)) return x
;
193 strlist
+=strlen(strlist
)+1;
199 #ifndef WDL_LINEPARSE_IMPL_ONLY
203 void WDL_LINEPARSE_PREFIX
freetokens()
208 for (x
= 0; x
< m_nt
; x
++) tmpbuffree(m_tokens
[x
]);
209 tmpbuffree((char*)m_tokens
);
216 int WDL_LINEPARSE_PREFIX
doline(const char *line
, bool withcomments
)
219 while (*line
== ' ' || *line
== '\t') line
++;
222 int lstate
=0; // 1=", 2=`, 4='
223 if (!withcomments
&& (*line
== ';' || *line
== '#')) break;
224 if (*line
== '\"') lstate
=1;
225 else if (*line
== '\'') lstate
=2;
226 else if (*line
== '`') lstate
=4;
229 const char *p
= line
;
232 if (lstate
==1 && *line
=='\"') break;
233 if (lstate
==2 && *line
=='\'') break;
234 if (lstate
==4 && *line
=='`') break;
235 if (!lstate
&& (*line
== ' ' || *line
== '\t')) break;
241 m_tokens
[m_nt
]=tmpbufalloc(nc
+1);
244 memcpy(m_tokens
[m_nt
], p
, nc
);
245 m_tokens
[m_nt
][nc
]=0;
254 while (*line
== ' ' || *line
== '\t') line
++;
259 char * WDL_LINEPARSE_PREFIX
tmpbufalloc(size_t sz
)
262 if (sz
+m_tmpbuf_used
<= sizeof(m_tmpbuf
))
265 return m_tmpbuf
+ m_tmpbuf_used
- sz
;
267 return (char *)malloc(sz
);
269 void WDL_LINEPARSE_PREFIX
tmpbuffree(char *p
)
271 if (p
< m_tmpbuf
|| p
>= m_tmpbuf
+ sizeof(m_tmpbuf
)) free(p
);
274 #undef WDL_LINEPARSE_PREFIX
275 #undef WDL_LINEPARSE_DEFPARM
276 #endif // ! WDL_LINEPARSE_INTF_ONLY
278 #ifndef WDL_LINEPARSE_IMPL_ONLY
281 #ifdef WDL_LINEPARSE_INTF_ONLY
283 int doline(const char *line
, bool withcomments
);
284 char *tmpbufalloc(size_t sz
);
285 void tmpbuffree(char *p
);
288 size_t m_tmpbuf_used
;
294 #endif//!WDL_LINEPARSE_IMPL_ONLY
295 #endif//WDL_LINEPARSE_H_