Commit 6e6a7d1f17b6afcaf96da6720b78d27db85629e1
1 parent
b3e369a7
Exists in
master
and in
5 other branches
Implementando parse do arquivo de remap.
Showing
1 changed file
with
193 additions
and
3 deletions
Show diff stats
src/pw3270/v3270/charset.c
@@ -30,7 +30,7 @@ | @@ -30,7 +30,7 @@ | ||
30 | #include <v3270.h> | 30 | #include <v3270.h> |
31 | #include "private.h" | 31 | #include "private.h" |
32 | #include <lib3270/charset.h> | 32 | #include <lib3270/charset.h> |
33 | - | 33 | + #include <lib3270/log.h> |
34 | 34 | ||
35 | #define ERROR_DOMAIN g_quark_from_static_string(PACKAGE_NAME) | 35 | #define ERROR_DOMAIN g_quark_from_static_string(PACKAGE_NAME) |
36 | 36 | ||
@@ -41,17 +41,207 @@ | @@ -41,17 +41,207 @@ | ||
41 | char * host; | 41 | char * host; |
42 | char * display; | 42 | char * display; |
43 | unsigned long cgcsgid; | 43 | unsigned long cgcsgid; |
44 | + size_t len; | ||
45 | + | ||
46 | + struct { | ||
47 | + unsigned short ebc; | ||
48 | + unsigned short iso; | ||
49 | + unsigned char scope; | ||
50 | + unsigned char oneway; | ||
51 | + } map[256]; | ||
52 | + | ||
44 | }; | 53 | }; |
45 | 54 | ||
55 | + static unsigned short getChar(const gchar *id, GError **error) { | ||
56 | + | ||
57 | + if(*error) { | ||
58 | + return 0; | ||
59 | + } | ||
60 | + | ||
61 | + if(g_str_has_prefix(id,"0x")) { | ||
62 | + | ||
63 | + unsigned int rc = 0; | ||
64 | + | ||
65 | + if(sscanf(id + 2, "%x", &rc) != 1) { | ||
66 | + *error = g_error_new(ERROR_DOMAIN,EINVAL,"%s",_( "Can't parse character value" )); | ||
67 | + return; | ||
68 | + } | ||
69 | + | ||
70 | + return (unsigned short) rc; | ||
71 | + | ||
72 | + } | ||
73 | + | ||
74 | + | ||
75 | + return (unsigned short) *id; | ||
76 | + } | ||
77 | + | ||
78 | + static void element_start(GMarkupParseContext *context, const gchar *element_name, const gchar **names,const gchar **values, struct parse *info, GError **error) | ||
79 | + { | ||
80 | + trace("%s(%s)",__FUNCTION__,element_name); | ||
81 | + | ||
82 | + if(!g_ascii_strcasecmp(element_name,"pw3270-remap")) | ||
83 | + { | ||
84 | + const gchar *host = NULL; | ||
85 | + const gchar *cgcsgid = NULL; | ||
86 | + const gchar *display = NULL; | ||
87 | + | ||
88 | + g_markup_collect_attributes(element_name,names,values,error, | ||
89 | + G_MARKUP_COLLECT_STRING, "host", &host, | ||
90 | + G_MARKUP_COLLECT_STRING, "cgcsgid", &cgcsgid, | ||
91 | + G_MARKUP_COLLECT_STRING, "display", &display, | ||
92 | + G_MARKUP_COLLECT_INVALID); | ||
93 | + if(*error) | ||
94 | + { | ||
95 | + return; | ||
96 | + } | ||
97 | + | ||
98 | + if(host) | ||
99 | + { | ||
100 | + g_free(info->host); | ||
101 | + info->host = g_strdup(host); | ||
102 | + } | ||
103 | + | ||
104 | + if(display) | ||
105 | + { | ||
106 | + g_free(info->display); | ||
107 | + info->display = g_strdup(display); | ||
108 | + } | ||
109 | + | ||
110 | + if(cgcsgid) { | ||
111 | + | ||
112 | + if(!g_str_has_prefix(cgcsgid,"0x")) | ||
113 | + { | ||
114 | + *error = g_error_new(ERROR_DOMAIN,EINVAL,"%s",_( "Invalid cgcsgid value" )); | ||
115 | + return; | ||
116 | + } | ||
117 | + | ||
118 | + if(sscanf(cgcsgid + 2, "%lx", &info->cgcsgid) != 1) { | ||
119 | + *error = g_error_new(ERROR_DOMAIN,EINVAL,"%s",_( "Can't parse cgcsgid value" )); | ||
120 | + return; | ||
121 | + } | ||
122 | + | ||
123 | + } | ||
124 | + | ||
125 | + } | ||
126 | + else if(!g_ascii_strcasecmp(element_name,"char")) | ||
127 | + { | ||
128 | + if(info->len >= G_N_ELEMENTS(info->map)) { | ||
129 | + *error = g_error_new(ERROR_DOMAIN,EINVAL,"%s",_( "Too many remaps" )); | ||
130 | + return; | ||
131 | + } | ||
132 | + | ||
133 | + const gchar *ebc = NULL; | ||
134 | + const gchar *iso = NULL; | ||
135 | + const gchar *scope = NULL; | ||
136 | + const gchar *oneway = NULL; | ||
137 | + | ||
138 | + g_markup_collect_attributes(element_name,names,values,error, | ||
139 | + G_MARKUP_COLLECT_STRING, "ebc", &ebc, | ||
140 | + G_MARKUP_COLLECT_STRING, "iso", &iso, | ||
141 | + G_MARKUP_COLLECT_STRING|G_MARKUP_COLLECT_OPTIONAL, "scope", &scope, | ||
142 | + G_MARKUP_COLLECT_STRING|G_MARKUP_COLLECT_OPTIONAL, "one-way", &oneway, | ||
143 | + G_MARKUP_COLLECT_INVALID); | ||
144 | + | ||
145 | + if(*error) | ||
146 | + { | ||
147 | + return; | ||
148 | + } | ||
149 | + | ||
150 | + if(!scope) | ||
151 | + { | ||
152 | + scope = "both"; | ||
153 | + } | ||
154 | + | ||
155 | + if(!oneway) | ||
156 | + { | ||
157 | + oneway = "no"; | ||
158 | + } | ||
159 | + | ||
160 | + info->map[info->len].ebc = getChar(ebc,error); | ||
161 | + info->map[info->len].iso = getChar(iso,error); | ||
162 | + | ||
163 | + trace("%u: ebc=%04x iso=%04x %c",(unsigned int) info->len,info->map[info->len].ebc,info->map[info->len].iso,info->map[info->len].iso); | ||
164 | + | ||
165 | + info->len++; | ||
166 | + | ||
167 | + } | ||
168 | + } | ||
169 | + | ||
170 | + | ||
171 | + static void element_end(GMarkupParseContext *context, const gchar *element_name, struct parse *info, GError **error) | ||
172 | + { | ||
173 | + // trace("%s(%s)",__FUNCTION__,element_name); | ||
174 | + } | ||
175 | + | ||
176 | + | ||
46 | LIB3270_EXPORT void v3270_remap_from_xml(GtkWidget *widget, const gchar *path) | 177 | LIB3270_EXPORT void v3270_remap_from_xml(GtkWidget *widget, const gchar *path) |
47 | { | 178 | { |
48 | - struct parse cfg; | ||
49 | - v3270 * terminal = GTK_V3270(widget); | 179 | + static const GMarkupParser parser = |
180 | + { | ||
181 | + (void (*)(GMarkupParseContext *, const gchar *, const gchar **, const gchar **, gpointer, GError **)) | ||
182 | + element_start, | ||
183 | + (void (*)(GMarkupParseContext *, const gchar *, gpointer, GError **)) | ||
184 | + element_end, | ||
185 | +// (void (*)(GMarkupParseContext *, const gchar *, gsize, gpointer, GError **)) | ||
186 | + NULL, | ||
187 | + | ||
188 | +// (void (*)(GMarkupParseContext *context, const gchar *passthrough_text, gsize text_len, gpointer user_data,GError **error)) | ||
189 | + NULL, | ||
190 | + | ||
191 | +// (void (*)(GMarkupParseContext *, GError *, gpointer)) | ||
192 | + NULL | ||
193 | + | ||
194 | + }; | ||
195 | + | ||
196 | + GError * error = NULL; | ||
197 | + gchar * text = NULL; | ||
198 | + struct parse cfg; | ||
199 | + v3270 * terminal = GTK_V3270(widget); | ||
50 | 200 | ||
51 | memset(&cfg,0,sizeof(cfg)); | 201 | memset(&cfg,0,sizeof(cfg)); |
52 | 202 | ||
203 | + if(g_file_get_contents(path,&text,NULL,&error)) | ||
204 | + { | ||
205 | + | ||
206 | + GMarkupParseContext * context = g_markup_parse_context_new(&parser,G_MARKUP_TREAT_CDATA_AS_TEXT|G_MARKUP_PREFIX_ERROR_POSITION,&cfg,NULL); | ||
207 | + g_markup_parse_context_parse(context,text,strlen(text),&error); | ||
208 | + g_markup_parse_context_free(context); | ||
209 | + | ||
210 | + } | ||
211 | + | ||
212 | + debug("error=%p",error); | ||
213 | + | ||
214 | + if(error) | ||
215 | + { | ||
216 | + GtkWidget * dialog; | ||
217 | + gchar * name = g_path_get_basename(path); | ||
218 | + | ||
219 | + dialog = gtk_message_dialog_new( NULL, | ||
220 | + GTK_DIALOG_DESTROY_WITH_PARENT, | ||
221 | + GTK_MESSAGE_WARNING, | ||
222 | + GTK_BUTTONS_OK, | ||
223 | + _( "Can't parse %s" ), name); | ||
224 | + | ||
225 | + g_free(name); | ||
226 | + | ||
227 | + gtk_window_set_title(GTK_WINDOW(dialog), _( "Remap Failed" ) ); | ||
228 | + | ||
229 | + if(error->message) | ||
230 | + gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(dialog), "%s", error->message); | ||
231 | + | ||
232 | + g_error_free(error); | ||
233 | + | ||
234 | + gtk_dialog_run(GTK_DIALOG (dialog)); | ||
235 | + gtk_widget_destroy(dialog); | ||
236 | + | ||
237 | + } | ||
53 | 238 | ||
239 | + trace("cgcsgid = %lx",cfg.cgcsgid); | ||
240 | + trace("display = %s",cfg.display); | ||
241 | + trace("host = %s",cfg.host); | ||
242 | + trace("length = %u",(unsigned int) cfg.len); | ||
54 | 243 | ||
244 | + g_free(text); | ||
55 | g_free(cfg.host); | 245 | g_free(cfg.host); |
56 | g_free(cfg.display); | 246 | g_free(cfg.display); |
57 | 247 |