Open Broadcaster Software
Free, open source software for live streaming and recording
lexer.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2013 Hugh Bailey <obs.jim@gmail.com>
3  *
4  * Permission to use, copy, modify, and distribute this software for any
5  * purpose with or without fee is hereby granted, provided that the above
6  * copyright notice and this permission notice appear in all copies.
7  *
8  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15  */
16 
17 #pragma once
18 
19 #include "c99defs.h"
20 #include "dstr.h"
21 #include "darray.h"
22 
23 #ifdef __cplusplus
24 extern "C" {
25 #endif
26 
27 /* ------------------------------------------------------------------------- */
28 /* string reference (string segment within an already existing array) */
29 
30 struct strref {
31  const char *array;
32  size_t len;
33 };
34 
35 static inline void strref_clear(struct strref *dst)
36 {
37  dst->array = NULL;
38  dst->len = 0;
39 }
40 
41 static inline void strref_set(struct strref *dst, const char *array, size_t len)
42 {
43  dst->array = array;
44  dst->len = len;
45 }
46 
47 static inline void strref_copy(struct strref *dst, const struct strref *src)
48 {
49  dst->array = src->array;
50  dst->len = src->len;
51 }
52 
53 static inline void strref_add(struct strref *dst, const struct strref *t)
54 {
55  if (!dst->array)
56  strref_copy(dst, t);
57  else
58  dst->len += t->len;
59 }
60 
61 static inline bool strref_is_empty(const struct strref *str)
62 {
63  return !str || !str->array || !str->len || !*str->array;
64 }
65 
66 EXPORT int strref_cmp(const struct strref *str1, const char *str2);
67 EXPORT int strref_cmpi(const struct strref *str1, const char *str2);
68 EXPORT int strref_cmp_strref(const struct strref *str1,
69  const struct strref *str2);
70 EXPORT int strref_cmpi_strref(const struct strref *str1,
71  const struct strref *str2);
72 
73 /* ------------------------------------------------------------------------- */
74 
75 EXPORT bool valid_int_str(const char *str, size_t n);
76 EXPORT bool valid_float_str(const char *str, size_t n);
77 
78 static inline bool valid_int_strref(const struct strref *str)
79 {
80  return valid_int_str(str->array, str->len);
81 }
82 
83 static inline bool valid_float_strref(const struct strref *str)
84 {
85  return valid_float_str(str->array, str->len);
86 }
87 
88 static inline bool is_whitespace(char ch)
89 {
90  return ch == ' ' || ch == '\r' || ch == '\t' || ch == '\n';
91 }
92 
93 static inline bool is_newline(char ch)
94 {
95  return ch == '\r' || ch == '\n';
96 }
97 
98 static inline bool is_space_or_tab(const char ch)
99 {
100  return ch == ' ' || ch == '\t';
101 }
102 
103 static inline bool is_newline_pair(char ch1, char ch2)
104 {
105  return (ch1 == '\r' && ch2 == '\n') ||
106  (ch1 == '\n' && ch2 == '\r');
107 }
108 
109 static inline int newline_size(const char *array)
110 {
111  if (strncmp(array, "\r\n", 2) == 0 || strncmp(array, "\n\r", 2) == 0)
112  return 2;
113  else if (*array == '\r' || *array == '\n')
114  return 1;
115 
116  return 0;
117 }
118 
119 /* ------------------------------------------------------------------------- */
120 
121 /*
122  * A "base" token is one of four things:
123  * 1.) A sequence of alpha characters
124  * 2.) A sequence of numeric characters
125  * 3.) A single whitespace character if whitespace is not ignored
126  * 4.) A single character that does not fall into the above 3 categories
127  */
128 
135 };
136 
137 struct base_token {
138  struct strref text;
139  enum base_token_type type;
141 };
142 
143 static inline void base_token_clear(struct base_token *t)
144 {
145  memset(t, 0, sizeof(struct base_token));
146 }
147 
148 static inline void base_token_copy(struct base_token *dst,
149  struct base_token *src)
150 {
151  memcpy(dst, src, sizeof(struct base_token));
152 }
153 
154 /* ------------------------------------------------------------------------- */
155 
156 #define LEX_ERROR 0
157 #define LEX_WARNING 1
158 
159 struct error_item {
160  char *error;
161  const char *file;
162  uint32_t row, column;
163  int level;
164 };
165 
166 static inline void error_item_init(struct error_item *ei)
167 {
168  memset(ei, 0, sizeof(struct error_item));
169 }
170 
171 static inline void error_item_free(struct error_item *ei)
172 {
173  bfree(ei->error);
174  error_item_init(ei);
175 }
176 
177 static inline void error_item_array_free(struct error_item *array, size_t num)
178 {
179  size_t i;
180  for (i = 0; i < num; i++)
181  error_item_free(array+i);
182 }
183 
184 /* ------------------------------------------------------------------------- */
185 
186 struct error_data {
187  DARRAY(struct error_item) errors;
188 };
189 
190 static inline void error_data_init(struct error_data *data)
191 {
192  da_init(data->errors);
193 }
194 
195 static inline void error_data_free(struct error_data *data)
196 {
197  error_item_array_free(data->errors.array, data->errors.num);
198  da_free(data->errors);
199 }
200 
201 static inline const struct error_item *error_data_item(struct error_data *ed,
202  size_t idx)
203 {
204  return ed->errors.array+idx;
205 }
206 
207 EXPORT char *error_data_buildstring(struct error_data *ed);
208 
209 EXPORT void error_data_add(struct error_data *ed, const char *file,
210  uint32_t row, uint32_t column, const char *msg, int level);
211 
212 static inline size_t error_data_type_count(struct error_data *ed,
213  int type)
214 {
215  size_t count = 0, i;
216  for (i = 0; i < ed->errors.num; i++) {
217  if (ed->errors.array[i].level == type)
218  count++;
219  }
220 
221  return count;
222 }
223 
224 static inline bool error_data_has_errors(struct error_data *ed)
225 {
226  size_t i;
227  for (i = 0; i < ed->errors.num; i++)
228  if (ed->errors.array[i].level == LEX_ERROR)
229  return true;
230 
231  return false;
232 }
233 
234 /* ------------------------------------------------------------------------- */
235 
236 struct lexer {
237  char *text;
238  const char *offset;
239 };
240 
241 static inline void lexer_init(struct lexer *lex)
242 {
243  memset(lex, 0, sizeof(struct lexer));
244 }
245 
246 static inline void lexer_free(struct lexer *lex)
247 {
248  bfree(lex->text);
249  lexer_init(lex);
250 }
251 
252 static inline void lexer_start(struct lexer *lex, const char *text)
253 {
254  lexer_free(lex);
255  lex->text = bstrdup(text);
256  lex->offset = lex->text;
257 }
258 
259 static inline void lexer_start_move(struct lexer *lex, char *text)
260 {
261  lexer_free(lex);
262  lex->text = text;
263  lex->offset = lex->text;
264 }
265 
266 static inline void lexer_reset(struct lexer *lex)
267 {
268  lex->offset = lex->text;
269 }
270 
274 };
275 
276 EXPORT bool lexer_getbasetoken(struct lexer *lex, struct base_token *t,
277  enum ignore_whitespace iws);
278 
279 EXPORT void lexer_getstroffset(const struct lexer *lex, const char *str,
280  uint32_t *row, uint32_t *col);
281 
282 #ifdef __cplusplus
283 }
284 #endif
Definition: lexer.h:159
EXPORT char * error_data_buildstring(struct error_data *ed)
Definition: lexer.h:236
#define LEX_ERROR
Definition: lexer.h:156
size_t len
Definition: lexer.h:32
uint32_t row
Definition: lexer.h:162
Definition: lexer.h:186
unsigned uint32_t
Definition: vc_stdint.h:31
uint32_t column
Definition: lexer.h:162
char * error
Definition: lexer.h:160
Definition: lexer.h:137
typedef DARRAY(profiler_time_entry_t) profiler_time_entries_t
EXPORT int strref_cmp_strref(const struct strref *str1, const struct strref *str2)
const char * offset
Definition: lexer.h:238
bool passed_whitespace
Definition: lexer.h:140
int level
Definition: lexer.h:163
Definition: lexer.h:132
const char * file
Definition: lexer.h:161
EXPORT int strref_cmpi_strref(const struct strref *str1, const struct strref *str2)
#define EXPORT
Definition: c99defs.h:49
EXPORT void lexer_getstroffset(const struct lexer *lex, const char *str, uint32_t *row, uint32_t *col)
base_token_type
Definition: lexer.h:129
EXPORT int strref_cmpi(const struct strref *str1, const char *str2)
EXPORT bool valid_int_str(const char *str, size_t n)
#define da_free(v)
Definition: darray.h:456
Definition: lexer.h:130
EXPORT void error_data_add(struct error_data *ed, const char *file, uint32_t row, uint32_t column, const char *msg, int level)
Definition: lexer.h:273
Definition: lexer.h:134
ignore_whitespace
Definition: lexer.h:271
EXPORT bool valid_float_str(const char *str, size_t n)
EXPORT int strref_cmp(const struct strref *str1, const char *str2)
const char * array
Definition: lexer.h:31
char * text
Definition: lexer.h:237
#define da_init(v)
Definition: darray.h:454
Definition: lexer.h:131
EXPORT void bfree(void *ptr)
EXPORT bool lexer_getbasetoken(struct lexer *lex, struct base_token *t, enum ignore_whitespace iws)
Definition: lexer.h:133
Definition: lexer.h:30
Definition: lexer.h:272