Nilorea Library
C utilities for networking, threading, graphics
Loading...
Searching...
No Matches
n_gui.c
Go to the documentation of this file.
1
8#include "nilorea/n_common.h"
9#include "nilorea/n_log.h"
10#include "nilorea/n_str.h"
11#include "nilorea/n_gui.h"
12
17
18
24void n_gui_init_tokenizer(N_GUI_TOKENIZER *tokenizer, const char *input) {
25 tokenizer->input = input;
26 tokenizer->position = 0;
27}
28
35 return tokenizer->input[tokenizer->position++];
36}
37
44 return tokenizer->input[tokenizer->position];
45}
46
53 return tokenizer->input[tokenizer->position] == '\0';
54}
55
62N_GUI_TOKEN n_gui_next_token(N_GUI_TOKENIZER *tokenizer, bool *inside_open_tag) {
63 N_GUI_TOKEN token = { .type = N_GUI_TOKEN_EOF, .value = {0} };
64 char ch;
65
66 // Skip whitespace
67 while (isspace(n_gui_peek_char(tokenizer))) {
68 n_gui_next_char(tokenizer);
69 }
70
71 ch = n_gui_peek_char(tokenizer);
72
73 // Handle end of file
74 if (ch == '\0') {
75 token.type = N_GUI_TOKEN_EOF;
76 return token;
77 }
78
79 // Handle opening tag '<'
80 if (ch == '<') {
81 n_gui_next_char(tokenizer);
82 ch = n_gui_peek_char(tokenizer);
83 if (ch == '/') {
84 n_gui_next_char(tokenizer);
85 *inside_open_tag = false;
86 token.type = N_GUI_TOKEN_TAG_CLOSE;
87 strncpy(token.value, "/", N_GUI_MAX_TOKEN_SIZE - 1);
88 } else {
89 *inside_open_tag = true;
90 token.type = N_GUI_TOKEN_TAG_OPEN;
91 strncpy(token.value, "<", N_GUI_MAX_TOKEN_SIZE - 1);
92 }
93 return token;
94 }
95
96 // Handle closing tag '>'
97 if (ch == '>') {
98 n_gui_next_char(tokenizer);
99 *inside_open_tag = false;
100 token.type = N_GUI_TOKEN_TAG_CLOSE;
101 strncpy(token.value, ">", N_GUI_MAX_TOKEN_SIZE - 1);
102 return token;
103 }
104
105 // Handle attribute values
106 if (ch == '=') {
107 n_gui_next_char(tokenizer); // consume '='
108 token.type = N_GUI_TOKEN_ATTR_VALUE;
109 ch = n_gui_peek_char(tokenizer);
110 if (ch == '"' || ch == '\'') {
111 char quote = n_gui_next_char(tokenizer);
112 int pos = 0;
113 while (n_gui_peek_char(tokenizer) != quote && !n_gui_is_eof(tokenizer)) {
114 if (pos < N_GUI_MAX_TOKEN_SIZE - 1) {
115 token.value[pos++] = n_gui_next_char(tokenizer);
116 }
117 }
118 n_gui_next_char(tokenizer); // consume closing quote
119 token.value[pos] = '\0';
120 }
121 return token;
122 }
123
124 // Handle tag names and attribute names
125 if (*inside_open_tag && (isalpha(ch) || ch == '-') ) {
126 int pos = 0;
127 while (isalnum(n_gui_peek_char(tokenizer)) || n_gui_peek_char(tokenizer) == '-' || n_gui_peek_char(tokenizer) == '_') {
128 if (pos < N_GUI_MAX_TOKEN_SIZE - 1) {
129 token.value[pos++] = n_gui_next_char(tokenizer);
130 }
131 }
132 token.value[pos] = '\0';
133
134 // Check if the next character is '=' to identify as attribute name
135 if (n_gui_peek_char(tokenizer) == '=') {
136 token.type = N_GUI_TOKEN_ATTR_NAME;
137 } else {
138 token.type = N_GUI_TOKEN_TAG_NAME;
139 }
140 return token;
141 }
142
143 // Handle text content
144 if (ch != '<' && ch != '>') {
145 if (!*inside_open_tag) { // Only capture text when not inside a tag
146 int pos = 0;
147 while (ch != '<' && ch != '>' && !n_gui_is_eof(tokenizer)) {
148 if (pos < N_GUI_MAX_TOKEN_SIZE - 1) {
149 token.value[pos++] = n_gui_next_char(tokenizer);
150 }
151 ch = n_gui_peek_char(tokenizer);
152 }
153 token.value[pos] = '\0';
154 token.type = N_GUI_TOKEN_TEXT;
155
156 // Handle text content if there is a valid length
157 if (pos > 0) {
158 return token;
159 }
160 }
161 }
162 // Default case for unknown or unsupported characters
163 n_gui_next_char(tokenizer); // consume character
164 return n_gui_next_token(tokenizer, inside_open_tag);
165}
166
172 switch (token.type) {
173 case N_GUI_TOKEN_TAG_OPEN: printf("N_GUI_TOKEN_TAG_OPEN: %s\n", token.value); break;
174 case N_GUI_TOKEN_TAG_CLOSE: printf("N_GUI_TOKEN_TAG_CLOSE: %s\n", token.value); break;
175 case N_GUI_TOKEN_TAG_NAME: printf("N_GUI_TOKEN_TAG_NAME: %s\n", token.value); break;
176 case N_GUI_TOKEN_ATTR_NAME: printf("N_GUI_TOKEN_ATTR_NAME: %s\n", token.value); break;
177 case N_GUI_TOKEN_ATTR_VALUE: printf("N_GUI_TOKEN_ATTR_VALUE: %s\n", token.value); break;
178 case N_GUI_TOKEN_TEXT: printf("N_GUI_TOKEN_TEXT: %s\n", token.value); break;
179 case N_GUI_TOKEN_EOF: printf("N_GUI_TOKEN_EOF\n"); break;
180 }
181}
182
189N_GUI_DIALOG *n_gui_load_dialog( char *html, char *css )
190{
191 __n_assert( html , return NULL );
192 N_STR *nstr_html = file_to_nstr( html );
193 __n_assert( nstr_html , return NULL );
194
195 // no assert for css, html can have no style X-D
196 // __n_assert( html , return NULL );
197 N_STR *nstr_css = NULL ;
198 if( css )
199 {
200 nstr_css = file_to_nstr( css );
201 }
202
203 N_GUI_DIALOG *gui = NULL ;
204 Malloc( gui , N_GUI_DIALOG , 1 );
205 __n_assert( gui , free_nstr( &nstr_html ) ; free_nstr( &nstr_css ) ; return NULL );
206
207 N_GUI_TOKENIZER tokenizer;
208 n_gui_init_tokenizer(&tokenizer, _nstr( nstr_html ) );
209 N_GUI_TOKEN token;
210 bool inside_open_tag = false;
211 while ((token = n_gui_next_token(&tokenizer, &inside_open_tag)).type != N_GUI_TOKEN_EOF) {
212 switch (token.type) {
213 case N_GUI_TOKEN_TAG_OPEN:
214 {
215
216 }
217 break;
218 case N_GUI_TOKEN_TAG_CLOSE:
219 {
220
221 }
222 case N_GUI_TOKEN_TAG_NAME:
223 {
224
225 }
226 case N_GUI_TOKEN_ATTR_NAME:
227 {
228
229 }
230 case N_GUI_TOKEN_ATTR_VALUE:
231 {
232
233 }
234 case N_GUI_TOKEN_TEXT:
235 {
236
237 }
238 case N_GUI_TOKEN_EOF:
239 {
240
241 }
242 }
243 }
244
245 free_nstr( &nstr_html );
246 free_nstr( &nstr_css );
247
248 return NULL ;
249}
250
251
#define Malloc(__ptr, __struct, __size)
Malloc Handler to get errors and set to 0.
Definition n_common.h:191
#define __n_assert(__ptr, __ret)
macro to assert things
Definition n_common.h:284
#define _nstr(__PTR)
N_STR or "NULL" string for logging purposes.
Definition n_common.h:186
#define N_ENUM_DEFINE(MACRO_DEFINITION, enum_name)
Macro to define an N_ENUM.
Definition n_enum.h:146
size_t type
type of token
Definition n_gui.h:122
char value[N_GUI_MAX_TOKEN_SIZE]
token content
Definition n_gui.h:124
size_t position
position in the input text
Definition n_gui.h:133
const char * input
pointer to the input text
Definition n_gui.h:131
char n_gui_next_char(N_GUI_TOKENIZER *tokenizer)
Get next character from input.
Definition n_gui.c:34
void n_gui_print_token(N_GUI_TOKEN token)
Function to print a token (for debugging purposes)
Definition n_gui.c:171
int n_gui_is_eof(N_GUI_TOKENIZER *tokenizer)
 
Definition n_gui.c:52
char n_gui_peek_char(N_GUI_TOKENIZER *tokenizer)
Peek at next character without advancing the position.
Definition n_gui.c:43
N_GUI_DIALOG * n_gui_load_dialog(char *html, char *css)
Load a html + css file into a N_GUI_DIALOG.
Definition n_gui.c:189
#define N_GUI_MAX_TOKEN_SIZE
maximum size of a single token content
Definition n_gui.h:27
void n_gui_init_tokenizer(N_GUI_TOKENIZER *tokenizer, const char *input)
Initialize tokenizer.
Definition n_gui.c:24
N_GUI_TOKEN n_gui_next_token(N_GUI_TOKENIZER *tokenizer, bool *inside_open_tag)
Read next N_GUI_TOKEN from input.
Definition n_gui.c:62
structure of a N_GUI_DIALOG
Definition n_gui.h:111
structure of a N_GUI_TOKENIZER token
Definition n_gui.h:120
structure of a N_GUI_DIALOG tokenizer
Definition n_gui.h:129
#define free_nstr(__ptr)
free a N_STR structure and set the pointer to NULL
Definition n_str.h:222
N_STR * file_to_nstr(char *filename)
Load a whole file into a N_STR.
Definition n_str.c:332
A box including a string and his lenght.
Definition n_str.h:173
Common headers and low-level hugly functions & define.
N_ENUM_N_GUI_TOKEN
N_GUI context codes.
Definition n_gui.c:14
__N_GUI_TOKEN
type for a token
Definition n_gui.c:16
GUI headers.
Generic log system.
N_STR and string function declaration.