Open Broadcaster Software
Free, open source software for live streaming and recording
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
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;
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;
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
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
DARRAY(struct error_item) errors
EXPORT int strref_cmpi_strref(const struct strref *str1, const struct strref *str2)
#define EXPORT
Definition: c99defs.h:49
enum base_token_type type
Definition: lexer.h:139
EXPORT void lexer_getstroffset(const struct lexer *lex, const char *str, uint32_t *row, uint32_t *col)
struct strref text
Definition: lexer.h:138
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