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 | ... | ... |