Commit 589167f0bc045667621ac6224defa6122c0975e9
1 parent
0c5fcd8e
Exists in
master
and in
1 other branch
Implementando parse do arquivo de remap.
Showing
1 changed file
with
193 additions
and
3 deletions
Show diff stats
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 |