libacfutils
A general purpose library of utility functions designed to make it easier to develop addons for the X-Plane flight simulator.
Loading...
Searching...
No Matches
parser_funcs.h
Go to the documentation of this file.
1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
7 * with the License.
8 *
9 * You can obtain a copy of the license in the file COPYING
10 * or http://www.opensource.org/licenses/CDDL-1.0.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file COPYING.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22/*
23 * Copyright 2023 Saso Kiselkov. All rights reserved.
24 */
27#ifndef _ACF_UTILS_PARSER_FUNCS_H_
28#define _ACF_UTILS_PARSER_FUNCS_H_
29
30#include <ctype.h>
31#include <string.h>
32
33#include "core.h"
34#include "safe_alloc.h"
35
36#ifndef _LACF_PARSER_FUNCS_INCLUDED
37#error "Don't include parser_funcs.h directly. Include acfutils/helpers.h"
38#endif
39
40#ifdef __cplusplus
41extern "C" {
42#endif
43
48UNUSED_ATTR static void
49strip_space(char *line)
50{
51 char *p;
52 size_t len = strlen(line);
53
54 /* strip leading whitespace */
55 for (p = line; *p != 0 && isspace(*p); p++)
56 ;
57 if (p != line) {
58 memmove(line, p, (len + 1) - (p - line));
59 len -= (p - line);
60 }
61
62 for (p = line + len - 1; p >= line && isspace(*p); p--)
63 ;
64 p[1] = 0;
65}
66
71#if defined(ACFUTILS_BUILD) || defined(ACFUTILS_GZIP_PARSER)
72UNUSED_ATTR static ssize_t
73parser_get_next_line_impl(void *fp, char **linep, size_t *linecap,
74 unsigned *linenum, bool_t compressed)
75#else /* !defined(ACFUTILS_BUILD) && defined(ACFUTILS_GZIP_PARSER) */
76UNUSED_ATTR static ssize_t
77parser_get_next_line_impl(void *fp, char **linep, size_t *linecap,
78 unsigned *linenum)
79#endif /* !defined(ACFUTILS_BUILD) && defined(ACFUTILS_GZIP_PARSER) */
80{
81 ASSERT(fp != NULL);
82 ASSERT(linenum != NULL);
83
84 for (;;) {
85#if defined(ACFUTILS_BUILD) || defined(ACFUTILS_GZIP_PARSER)
86 ssize_t len = lacf_getline_impl(linep, linecap, fp, compressed);
87#else
88 ssize_t len = lacf_getline_impl(linep, linecap, fp);
89#endif
90 char *hash;
91 if (len == -1)
92 return (-1);
93 (*linenum)++;
94 hash = strchr(*linep, '#');
95 if (hash != NULL)
96 *hash = '\0';
97 strip_space(*linep);
98 if (**linep == 0)
99 continue;
100 len = strlen(*linep);
101 /* substitute spaces for tabs */
102 for (ssize_t i = 0; i < len; i++) {
103 if ((*linep)[i] == '\t')
104 (*linep)[i] = ' ';
105 }
106 return (len);
107 }
108}
109
142UNUSED_ATTR static char *
143parser_get_next_quoted_str2(FILE *fp, int *linep)
144{
145 char c;
146 char *str = (char *)safe_calloc(1, 1);
147 size_t len = 0, cap = 0;
148
149 for (;;) {
150 do {
151 c = fgetc(fp);
152 if (c == '\n' && linep != NULL)
153 (*linep)++;
154 } while (isspace(c));
155 if (c == EOF)
156 break;
157 if (c != '"') {
158 ungetc(c, fp);
159 break;
160 }
161 while ((c = fgetc(fp)) != EOF) {
162 if (c == '"')
163 break;
164 if (c == '\\') {
165 c = fgetc(fp);
166 if (c == '"') {
167 c = '"';
168 } else if (c == 'n') {
169 c = '\n';
170 } else if (c == 'r') {
171 c = '\r';
172 } else if (c == 't') {
173 c = '\t';
174 } else if (c == '\r') {
175 /* skip the next LF char as well */
176 c = fgetc(fp);
177 if (c != '\n' && c != EOF)
178 ungetc(c, fp);
179 if (linep != NULL)
180 (*linep)++;
181 continue;
182 } else if (c == '\n') {
183 /* skip LF char */
184 if (linep != NULL)
185 (*linep)++;
186 continue;
187 } else if (c >= '0' && c <= '7') {
188 /* 1-3 letter octal codes */
189 char num[4];
190 unsigned val = 0;
191
192 memset(num, 0, sizeof (num));
193 num[0] = c;
194 for (int i = 1; i < 3; i++) {
195 c = fgetc(fp);
196 if (c < '0' || c > '7') {
197 ungetc(c, fp);
198 break;
199 }
200 num[i] = c;
201 }
202 VERIFY(sscanf(num, "%o", &val) == 1);
203 c = val;
204 }
205 }
206 if (len == cap) {
207 str = (char *)safe_realloc(str, cap + 1 + 128);
208 cap += 128;
209 }
210 str[len++] = c;
211 }
212 if (c == EOF)
213 break;
214 }
215
216 str[len] = 0;
217
218 return (str);
219}
220
221#ifdef __cplusplus
222}
223#endif
224
225#endif /* _ACF_UTILS_PARSER_FUNCS_H_ */
#define VERIFY(x)
Definition assert.h:78
#define ASSERT(x)
Definition assert.h:208
#define UNUSED_ATTR
Definition core.h:95
static ssize_t lacf_getline_impl(char **line_p, size_t *cap_p, void *fp)
static void strip_space(char *line)
static char * parser_get_next_quoted_str2(FILE *fp, int *linep)
static ssize_t parser_get_next_line_impl(void *fp, char **linep, size_t *linecap, unsigned *linenum)
static void * safe_realloc(void *oldptr, size_t size)
Definition safe_alloc.h:86
static void * safe_calloc(size_t nmemb, size_t size)
Definition safe_alloc.h:71