fixed typo
[strongswan.git] / src / libstrongswan / utils / lexparser.c
1 /**
2 * @file lexparser.c
3 *
4 * @brief lexical parser for text-based configuration files
5 *
6 */
7
8 /*
9 * Copyright (C) 2001-2006 Andreas Steffen, Zuercher Hochschule Winterthur
10 *
11 * This program is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU General Public License as published by the
13 * Free Software Foundation; either version 2 of the License, or (at your
14 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
15 *
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
18 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19 * for more details.
20 */
21
22 #include <string.h>
23
24 #include "lexparser.h"
25
26
27 /**
28 * eat whitespace
29 */
30 bool eat_whitespace(chunk_t *src)
31 {
32 while (src->len > 0 && (*src->ptr == ' ' || *src->ptr == '\t'))
33 {
34 src->ptr++; src->len--;
35 }
36 return src->len > 0 && *src->ptr != '#';
37 }
38
39 /**
40 * compare string with chunk
41 */
42 bool match(const char *pattern, const chunk_t *ch)
43 {
44 return ch->len == strlen(pattern) && strncmp(pattern, ch->ptr, ch->len) == 0;
45 }
46
47 /**
48 * extracts a token ending with a given termination symbol
49 */
50 bool extract_token(chunk_t *token, const char termination, chunk_t *src)
51 {
52 u_char *eot = memchr(src->ptr, termination, src->len);
53
54 /* initialize empty token */
55 *token = chunk_empty;
56
57 if (eot == NULL) /* termination symbol not found */
58 {
59 return FALSE;
60 }
61
62 /* extract token */
63 token->ptr = src->ptr;
64 token->len = (u_int)(eot - src->ptr);
65
66 /* advance src pointer after termination symbol */
67 src->ptr = eot + 1;
68 src->len -= (token->len + 1);
69
70 return TRUE;
71 }
72
73 /**
74 * fetches a new line terminated by \n or \r\n
75 */
76 bool fetchline(chunk_t *src, chunk_t *line)
77 {
78 if (src->len == 0) /* end of src reached */
79 return FALSE;
80
81 if (extract_token(line, '\n', src))
82 {
83 if (line->len > 0 && *(line->ptr + line->len -1) == '\r')
84 line->len--; /* remove optional \r */
85 }
86 else /*last line ends without newline */
87 {
88 *line = *src;
89 src->ptr += src->len;
90 src->len = 0;
91 }
92 return TRUE;
93 }
94
95 err_t extract_value(chunk_t *value, chunk_t *line)
96 {
97 char delimiter = ' ';
98
99 if (!eat_whitespace(line))
100 {
101 *value = chunk_empty;
102 return NULL;
103 }
104 if (*line->ptr == '\'' || *line->ptr == '"')
105 {
106 delimiter = *line->ptr;
107 line->ptr++; line->len--;
108 }
109 if (!extract_token(value, delimiter, line))
110 {
111 if (delimiter == ' ')
112 {
113 *value = *line;
114 line->len = 0;
115 }
116 else
117 {
118 return "missing second delimiter";
119 }
120 }
121 return NULL;
122 }
123
124 /**
125 * extracts a parameter: value pair
126 */
127 err_t extract_parameter_value(chunk_t *name, chunk_t *value, chunk_t *line)
128 {
129 /* extract name */
130 if (!extract_token(name,':', line))
131 {
132 return "missing ':'";
133 }
134
135 /* extract value */
136 return extract_value(value, line);
137 }