2
2
* STFL - The Structured Terminal Forms Language/Library
3
* Copyright (C) 2006 Clifford Wolf <clifford@clifford.at>
5
* This program is free software; you can redistribute it and/or modify
6
* it under the terms of the GNU General Public License as published by
7
* the Free Software Foundation; either version 2 of the License, or
8
* (at your option) any later version.
10
* This program is distributed in the hope that it will be useful,
3
* Copyright (C) 2006, 2007 Clifford Wolf <clifford@clifford.at>
5
* This library is free software; you can redistribute it and/or
6
* modify it under the terms of the GNU Lesser General Public
7
* License as published by the Free Software Foundation; either
8
* version 3 of the License, or (at your option) any later version.
10
* This library is distributed in the hope that it will be useful,
11
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU General Public License for more details.
15
* You should have received a copy of the GNU General Public License
16
* along with this program; if not, write to the Free Software
17
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
* Lesser General Public License for more details.
15
* You should have received a copy of the GNU Lesser General Public
16
* License along with this library; if not, write to the Free Software
17
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19
20
* parser.c: STFL Form description file parser
22
23
#include "stfl_internals.h"
24
#include "stfl_compat.h"
25
27
#include <string.h>
26
28
#include <stdlib.h>
28
static void extract_name(char **key, char **name)
30
int len = strcspn(*key, "[");
31
#define MYWCSCSPN_SKIP_QUOTED 0x01
32
#define MYWCSCSPN_SKIP_NAMES 0x02
34
static size_t mywcscspn(const wchar_t *wcs, const wchar_t *reject, int flags)
56
if ((flags & MYWCSCSPN_SKIP_NAMES) && (wcs[len] == L'[')) {
60
if ((flags & MYWCSCSPN_SKIP_QUOTED) && (wcs[len] == L'\'')) {
64
if ((flags & MYWCSCSPN_SKIP_QUOTED) && (wcs[len] == L'\"')) {
68
for (i=0; reject[i]; i++)
69
if (wcs[len] == reject[i])
73
if ((flags & MYWCSCSPN_SKIP_QUOTED) && (wcs[len] == L'\'')) {
74
state = SINGLE_QUOTE_NAME;
77
if ((flags & MYWCSCSPN_SKIP_QUOTED) && (wcs[len] == L'\"')) {
78
state = DOUBLE_QUOTE_NAME;
85
case SINGLE_QUOTE_NAME:
86
if (wcs[len] == L'\'')
87
state = state == SINGLE_QUOTE ? PLAIN : NAME_BLOCK;
90
case DOUBLE_QUOTE_NAME:
91
if (wcs[len] == L'\"')
92
state = state == DOUBLE_QUOTE ? PLAIN : NAME_BLOCK;
100
static wchar_t *unquote(const wchar_t *text, int tlen)
108
for (i=0; text[i] && (i<tlen || tlen<0); i++)
110
if (text[i] == L'\'')
112
if (++i == tlen && tlen >= 0)
113
goto finish_len_v_loop;
114
if (!text[i] || text[i] == L'\'') break;
118
if (text[i] == L'\"')
120
if (++i == tlen && tlen >= 0)
121
goto finish_len_v_loop;
122
if (!text[i] || text[i] == L'\"') break;
130
value = malloc(sizeof(wchar_t)*(len_v+1));
132
for (i=j=0; text[i] && (i<tlen || tlen<0); i++)
134
if (text[i] == L'\'')
136
if (++i == tlen && tlen >= 0)
137
goto finish_copy_loop;
138
if (!text[i] || text[i] == L'\'') break;
139
value[j++] = text[i];
142
if (text[i] == L'\"')
144
if (++i == tlen && tlen >= 0)
145
goto finish_copy_loop;
146
if (!text[i] || text[i] == L'\"') break;
147
value[j++] = text[i];
150
value[j++] = text[i];
160
static void extract_name(wchar_t **key, wchar_t **name)
162
int len = wcscspn(*key, L"[");
32
164
if ((*key)[len] == 0) {
37
*name = strdup(*key+len+1);
38
*key = realloc(*key, len+1);
169
*name = compat_wcsdup(*key+len+1);
170
*key = realloc(*key, sizeof(wchar_t)*(len+1));
41
len = strcspn(*name, "]");
173
len = mywcscspn(*name, L"]", MYWCSCSPN_SKIP_QUOTED);
45
static void extract_class(char **key, char **cls)
177
static void extract_class(wchar_t **key, wchar_t **cls)
47
int len = strcspn(*key, "#");
179
int len = wcscspn(*key, L"#");
49
181
if ((*key)[len] == 0) {
54
*cls = strdup(*key+len+1);
55
*key = realloc(*key, len+1);
186
*cls = compat_wcsdup(*key+len+1);
187
*key = realloc(*key, sizeof(wchar_t)*(len+1));
59
static int read_type(const char **text, char **type, char **name, char **cls)
191
static int read_type(const wchar_t **text, wchar_t **type, wchar_t **name, wchar_t **cls)
61
int len = strcspn(*text, " \t\r\n:{}");
193
int len = mywcscspn(*text, L" \t\r\n:{}", MYWCSCSPN_SKIP_QUOTED|MYWCSCSPN_SKIP_NAMES);
63
if ((*text)[len] == ':' || len == 0)
195
if ((*text)[len] == L':' || len == 0)
66
*type = malloc(len+1);
67
memcpy(*type, *text, len);
198
*type = malloc((len+1)*sizeof(wchar_t));
199
wmemcpy(*type, *text, len);
77
static int read_kv(const char **text, char **key, char **name, char **value)
209
static int read_kv(const wchar_t **text, wchar_t **key, wchar_t **name, wchar_t **value)
79
int len_k = strcspn(*text, " \t\r\n:{}");
211
int len_k = mywcscspn(*text, L" \t\r\n:{}", MYWCSCSPN_SKIP_QUOTED|MYWCSCSPN_SKIP_NAMES);
81
if ((*text)[len_k] != ':' || len_k == 0)
213
if ((*text)[len_k] != L':' || len_k == 0)
84
*key = malloc(len_k+1);
85
memcpy(*key, *text, len_k);
216
*key = malloc((len_k+1)*sizeof(wchar_t));
217
wmemcpy(*key, *text, len_k);
86
218
(*key)[len_k] = 0;
89
221
extract_name(key, name);
91
int len_v = 0, i = 0, j = 0;
92
while ((*text)[i] && (*text)[i] != ' ' && (*text)[i] != '{' && (*text)[i] != '}' &&
93
(*text)[i] != '\t' && (*text)[i] != '\r' && (*text)[i] != '\n')
95
if ((*text)[i] == '\'')
96
while ((*text)[++i] != '\'') len_v++;
98
if ((*text)[i] == '\"')
99
while ((*text)[++i] != '\"') len_v++;
104
*value = malloc(len_v+1);
107
while ((*text)[i] && (*text)[i] != ' ' && (*text)[i] != '{' && (*text)[i] != '}' &&
108
(*text)[i] != '\t' && (*text)[i] != '\r' && (*text)[i] != '\n')
110
if ((*text)[i] == '\'')
111
while ((*text)[++i] != '\'')
112
(*value)[j++] = (*text)[i];
114
if ((*text)[i] == '\"')
115
while ((*text)[++i] != '\"')
116
(*value)[j++] = (*text)[i];
118
(*value)[j++] = (*text)[i];
223
int qval_len = mywcscspn(*text, L" \t\r\n{}", MYWCSCSPN_SKIP_QUOTED);
224
*value = unquote(*text, qval_len);
128
struct stfl_widget *stfl_parser(const char *text)
230
struct stfl_widget *stfl_parser(const wchar_t *text)
130
232
struct stfl_widget *root = 0;
131
233
struct stfl_widget *current = 0;
202
char *key, *name, *cls, *value;
304
wchar_t *key, *name, *cls, *value;
203
305
if (indenting < 0)
204
306
goto parser_error;
208
int filename_len = strcspn(++text, ">");
209
char filename[filename_len+1];
211
memcpy(filename, text, filename_len);
212
filename[filename_len] = 0;
310
int filename_len = wcscspn(++text, L">");
311
wchar_t wfn[filename_len+1];
313
wmemcpy(wfn, text, filename_len+1);
314
wfn[filename_len] = 0;
316
size_t len = wcstombs(NULL,wfn,0)+1;
318
size_t rc = wcstombs(filename, wfn, len);
319
assert(rc != (size_t)-1);
214
321
text += filename_len;
215
322
if (*text) text++;
374
struct stfl_widget *w = stfl_parser(text);
485
const char * text1 = text;
486
size_t wtextsize = mbsrtowcs(NULL,&text1,strlen(text1)+1,NULL)+1;
487
wchar_t * wtext = malloc(sizeof(wchar_t)*wtextsize);
489
size_t rc = mbstowcs(wtext, text, wtextsize);
490
assert(rc != (size_t)-1);
493
fprintf(stderr,"strlen(text) = %u wcslen(wtext) = %u rc = %u wtextsize = %u\n", strlen(text), wcslen(wtext), rc, wtextsize);
494
fprintf(stderr,"this is where is fucked up: `%lc' `%lc' `%lc' `%lc' `%lc'\n",text1[0],text1[1],text1[2],text1[3],text1[4]);
495
fprintf(stderr,"original: `%s'\n", text);
496
fprintf(stderr,"converted: `%ls'\n", wtext);
499
struct stfl_widget *w = stfl_parser(wtext);