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 | 30 | #include <v3270.h> |
31 | 31 | #include "private.h" |
32 | 32 | #include <lib3270/charset.h> |
33 | - | |
33 | + #include <lib3270/log.h> | |
34 | 34 | |
35 | 35 | #define ERROR_DOMAIN g_quark_from_static_string(PACKAGE_NAME) |
36 | 36 | |
... | ... | @@ -41,17 +41,207 @@ |
41 | 41 | char * host; |
42 | 42 | char * display; |
43 | 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 | 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 | 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 | 245 | g_free(cfg.host); |
56 | 246 | g_free(cfg.display); |
57 | 247 | ... | ... |