void display(std::ostream& os) const { switch (this->type) { case RANGE: if (this->data.range.l == 0 && this->data.range.r == ~char_int{}) { os << "."; } else if (this->data.range.l == this->data.range.r) { os << "[" << this->data.range.l << "] '" << utf8_char(this->data.range.l) << "'"; } else { os << "[" << this->data.range.l << "-" << this->data.range.r << "] ['" << utf8_char(this->data.range.l) << "'-'" << utf8_char(this->data.range.r) << "']"; } break; case SEQUENCE: { os << '"'; for (const char_int * p = this->data.sequence.s; *p; ++p) { os << utf8_char(*p); } os << '"'; break; } case CAPTURE_CLOSE: os << ")"; break; case CAPTURE_OPEN: os << "("; break; case EPSILONE: os << "(epsilone)"; break; case FINISH: os << "(finish)"; break; case SPLIT: os << "(split)"; break; case FIRST: os << "^"; break; case LAST: os << "$"; break; default: os << "???"; break; } }
inline bool st_search(StateParser & stparser, const char * s) { if ( stparser.empty()) { return false; } StatesValue stval(stparser.states(), stparser.nb_capture()); // #ifdef DISPLAY_TRACE // display_states(stval, stparser.root()); // #endif st_step_range_list_t lst; st_step_range_list_t l1; add_first(lst, l1, stparser.root()); if (l1.empty() && lst.empty()) { return false; } utf8_consumer consumer(s); st_step_range_list_t l2; bool res = false; unsigned count = 1; while (consumer.valid()) { #ifdef DISPLAY_TRACE std::cout << "\033[01;31mc: '" << utf8_char(consumer.getc()) << "'\033[0m\n"; #endif for (st_step_range_iterator_t first = lst.begin(), last = lst.end(); first != last; ++first) { if (stval.get_num_at(first->first) != count) { l1.push_back(*first); } } if (l1.empty()) { return false; } l2.clear(); if ((res = st_step(l1, l2, stval, consumer.bumpc(), consumer, ++count))) { break ; } l1.swap(l2); } if (res) { return true; } if (consumer.valid()) { return false; } for (st_step_range_iterator_t first = l1.begin(), last = l1.end(); first != last; ++first) { if (first->first->type == LAST) { return true; } } return false; }
inline bool st_exact_search(StateParser & stparser, const char * s) { if ( stparser.empty() ) { return false; } StatesValue stval(stparser.states(), stparser.nb_capture()); // #ifdef DISPLAY_TRACE // display_states(stval, stparser.root()); // #endif st_step_range_list_t l1; add_first(l1, l1, stparser.root()); if (l1.empty()) { return false; } utf8_consumer consumer(s); st_step_range_list_t l2; bool res = false; unsigned count = 1; while (consumer.valid() && !(res = st_exact_step(l1, l2, stval, consumer.bumpc(), consumer, ++count))) { #ifdef DISPLAY_TRACE std::cout << "\033[01;31mc: '" << utf8_char(consumer.getc()) << "'\033[0m\n"; #endif if (l2.empty()) { return false; } l1.swap(l2); l2.clear(); } if (consumer.valid()) { return false; } if (res) { return true; } return false; }
static size_t sql_utf8_escape_func(char *out, size_t outlen, const char *in) { int len = 0; int utf8 = 0; while (in[0]) { /* * Skip over UTF8 characters */ utf8 = utf8_char((uint8_t *)in); if (utf8) { if (outlen <= utf8) { break; } while (utf8-- > 0) { *out = *in; out++; in++; outlen--; len++; } continue; } /* * Non-printable characters get replaced with their * mime-encoded equivalents. */ if ((in[0] < 32) || strchr(allowed_chars, *in) == NULL) { /* * Only 3 or less bytes available. */ if (outlen <= 3) { break; } snprintf(out, outlen, "=%02X", (unsigned char) in[0]); in++; out += 3; outlen -= 3; len += 3; continue; } /* * Only one byte left. */ if (outlen <= 1) { break; } /* * Allowed character. */ *out = *in; out++; in++; outlen--; len++; } *out = '\0'; return len; }
static void html_output_tag(struct html_output *output, const struct array *tag) #if GTK_CHECK_VERSION(2,0,0) { static struct { gboolean initialized; short_string_t centre_line, nbsp, bullet, soft_hyphen, em_dash; short_string_t list_item_prefix; } special; struct html_context *ctx; const gchar *style, *text, *attr; enum html_tag id; gboolean closing; GtkTextBuffer *buffer; if (!special.initialized) { special.initialized = TRUE; special.bullet = utf8_char(0x2022); special.centre_line = utf8_char(0xFE4E); special.soft_hyphen = utf8_char(0x00AD); special.nbsp = utf8_char(0x00A0); special.em_dash = utf8_char(0x2014); concat_strings(special.list_item_prefix.str, sizeof special.list_item_prefix.str, " ", special.bullet.str, " ", (void *) 0); } style = NULL; text = NULL; attr = NULL; closing = html_tag_is_closing(tag); ctx = html_output_get_udata(output); id = html_parse_tag(tag); buffer = gtk_text_view_get_buffer(ctx->html_view->widget); switch (id) { case HTML_TAG_BODY: style = STYLE_TAG_WORD_WRAP; break; case HTML_TAG_A: if (closing) { if (ctx->start[id] && ctx->href) { GtkTextIter start, end; GtkTextTag *anchor; anchor = gtk_text_buffer_create_tag(buffer, NULL, (void *) 0); g_object_set_data(G_OBJECT(anchor), "href", deconstify_gchar(ctx->href)); gtk_text_buffer_get_iter_at_mark(buffer, &start, ctx->start[id]); gtk_text_buffer_get_end_iter(buffer, &end); gtk_text_buffer_apply_tag(buffer, anchor, &start, &end); style = get_style_for_href(ctx->href); ctx->href = NULL; } } else { struct array value; value = html_get_attribute(tag, HTML_ATTR_HREF); if (value.data && value.size > 0) { GtkTextIter iter; ctx->href = g_strndup(value.data, value.size); ctx->html_view->to_free = g_slist_prepend( ctx->html_view->to_free, deconstify_gchar(ctx->href)); gtk_text_buffer_get_end_iter(buffer, &iter); ctx->start[id] = gtk_text_buffer_create_mark(buffer, NULL, &iter, TRUE); g_object_set_data(G_OBJECT(ctx->start[id]), "href", deconstify_gchar(ctx->href)); } value = html_get_attribute(tag, HTML_ATTR_NAME); if (value.data && value.size > 0) { GtkTextTagTable *table; gchar name[256]; size_t n; n = sizeof name - 2; n = MIN(value.size, n); name[0] = '#'; memcpy(&name[1], value.data, n); name[n + 1] = '\0'; table = gtk_text_buffer_get_tag_table(buffer); if (NULL == gtk_text_tag_table_lookup(table, name)) { GtkTextIter iter; gtk_text_buffer_get_end_iter(buffer, &iter); gtk_text_buffer_create_mark(buffer, name, &iter, TRUE); } } } break; case HTML_TAG_B: case HTML_TAG_STRONG: case HTML_TAG_THEAD: style = STYLE_TAG_BOLD; break; case HTML_TAG_TH: if (closing) text = "\t"; break; case HTML_TAG_EM: style = STYLE_TAG_UNDERLINE; break; case HTML_TAG_I: case HTML_TAG_Q: style = STYLE_TAG_ITALIC; break; case HTML_TAG_IMG: if (!closing) { struct array value; static gchar alt[1024]; value = html_get_attribute(tag, HTML_ATTR_ALT); if (value.data) { gm_snprintf(alt, sizeof alt, "\n[image alt=\"%.*s\"]\n", (int)value.size, value.data); text = alt; } value = html_get_attribute(tag, HTML_ATTR_SRC); if (value.data) { GdkPixbuf *pixbuf; gchar *filename; GtkTextIter iter; filename = h_strndup(value.data, value.size); pixbuf = gdk_pixbuf_new_from_file(filename, NULL); if (pixbuf) { gtk_text_buffer_get_end_iter(buffer, &iter); gtk_text_buffer_insert_pixbuf(buffer, &iter, pixbuf); } else { static gchar msg[1024]; gm_snprintf(msg, sizeof msg, "\n[Image not found (\"%s\")]\n", filename); text = msg; } HFREE_NULL(filename); } if (!text) { text = "\n[image]\n"; } } attr = STYLE_TAG_BOLD; break; case HTML_TAG_TD: if (closing) text = "\t"; break; case HTML_TAG_P: case HTML_TAG_DIV: text = closing ? "\n\n" : special.soft_hyphen.str; break; case HTML_TAG_DL: case HTML_TAG_TABLE: case HTML_TAG_TR: case HTML_TAG_UL: case HTML_TAG_OL: case HTML_TAG_BR: text = "\n"; break; case HTML_TAG_DT: case HTML_TAG_LI: if (closing) { GtkTextIter start, end; GtkTextTag *margin; PangoLayout *pl; gint width; pl = pango_layout_new(gtk_widget_get_pango_context( GTK_WIDGET(ctx->html_view->widget))); pango_layout_set_text(pl, special.list_item_prefix.str, -1); pango_layout_get_pixel_size(pl, &width, NULL); g_object_unref(G_OBJECT(pl)); margin = gtk_text_buffer_create_tag(buffer, NULL, "left-margin", width * 2, "left-margin-set", TRUE, (void *) 0); gtk_text_buffer_get_iter_at_mark(buffer, &start, ctx->start[id]); gtk_text_buffer_get_end_iter(buffer, &end); gtk_text_buffer_apply_tag(buffer, margin, &start, &end); } else { GtkTextIter iter; gtk_text_buffer_get_end_iter(buffer, &iter); gtk_text_buffer_insert(buffer, &iter, "\n", (-1)); gtk_text_buffer_get_end_iter(buffer, &iter); gtk_text_buffer_insert_with_tags_by_name(buffer, &iter, special.list_item_prefix.str, (-1), STYLE_TAG_BOLD, (void *) 0); gtk_text_buffer_get_end_iter(buffer, &iter); ctx->start[id] = gtk_text_buffer_create_mark(buffer, NULL, &iter, TRUE); } break; case HTML_TAG_CODE: case HTML_TAG_KBD: case HTML_TAG_PRE: case HTML_TAG_TT: style = STYLE_TAG_MONOSPACE; break; case HTML_TAG_H1: style = STYLE_TAG_HEADING_1; text = closing ? "\n\n" : "\n"; break; case HTML_TAG_H2: style = STYLE_TAG_HEADING_2; text = closing ? "\n\n" : "\n"; break; case HTML_TAG_H3: style = STYLE_TAG_HEADING_3; text = closing ? "\n\n" : "\n"; break; case HTML_TAG_H4: case HTML_TAG_H5: case HTML_TAG_H6: style = STYLE_TAG_HEADING_4; text = closing ? "\n\n" : "\n"; break; case HTML_TAG_TITLE: if (closing) { if (ctx->title) { GtkWidget *window; window = gtk_widget_get_toplevel( GTK_WIDGET(ctx->html_view->widget)); gtk_window_set_title(GTK_WINDOW(window), str_2c(ctx->title)); str_destroy_null(&ctx->title); } } else { ctx->title = str_new(0); } break; case HTML_TAG_HR: { GtkTextIter iter; gtk_text_buffer_get_end_iter(buffer, &iter); gtk_text_buffer_insert_with_tags_by_name(buffer, &iter, "\n \n", (-1), STYLE_TAG_CENTER, STYLE_TAG_UNDERLINE, (void *) 0); } text = "\n"; break; case HTML_TAG_COMMENT: #if 0 { GtkTextIter iter; /* Comments can be made visible this way */ ctx->start[id] = gtk_text_buffer_create_mark(buffer, NULL, &iter, TRUE); gtk_text_buffer_get_end_iter(buffer, &iter); gtk_text_buffer_insert_with_tags_by_name(buffer, &iter, tag->data, tag->size, STYLE_TAG_ITALIC, (void *) 0); } closing = TRUE; text = "\n"; #endif break; case HTML_TAG_HTML: if (closing) { if (ctx->lang && ctx->start[id]) { GtkTextIter start, end; GtkTextTag *lang; lang = gtk_text_buffer_create_tag(buffer, NULL, "language", ctx->lang, "language-set", TRUE, (void *) 0); gtk_text_buffer_get_iter_at_mark(buffer, &start, ctx->start[id]); gtk_text_buffer_get_end_iter(buffer, &end); gtk_text_buffer_apply_tag(buffer, lang, &start, &end); ctx->lang = NULL; } } else { struct array value; value = html_get_attribute(tag, HTML_ATTR_LANG); if (value.data && value.size > 0) { GtkTextIter iter; ctx->lang = g_strndup(value.data, value.size); ctx->html_view->to_free = g_slist_prepend( ctx->html_view->to_free, deconstify_gchar(ctx->lang)); gtk_text_buffer_get_end_iter(buffer, &iter); ctx->start[id] = gtk_text_buffer_create_mark(buffer, NULL, &iter, TRUE); } } case HTML_TAG_HEAD: case HTML_TAG_META: case HTML_TAG_SPAN: case HTML_TAG_COL: case HTML_TAG_DD: case HTML_TAG_TBODY: case HTML_TAG_DOCTYPE: case HTML_TAG_UNKNOWN: break; case NUM_HTML_TAG: g_assert_not_reached(); } if (style) { if (closing) { if (ctx->start[id]) { GtkTextIter start, end; gtk_text_buffer_get_iter_at_mark(buffer, &start, ctx->start[id]); gtk_text_buffer_get_end_iter(buffer, &end); gtk_text_buffer_apply_tag_by_name(buffer, style, &start, &end); ctx->start[id] = NULL; } } else { GtkTextIter iter; gtk_text_buffer_get_end_iter(buffer, &iter); ctx->start[id] = gtk_text_buffer_create_mark(buffer, NULL, &iter, TRUE); } } if (text) { GtkTextIter iter; gtk_text_buffer_get_end_iter(buffer, &iter); gtk_text_buffer_insert_with_tags_by_name(buffer, &iter, text, (-1), attr, (void *) 0); } }
/* * Convert a string to something printable. The output string * has to be larger than the input string by at least 5 bytes. * If not, the output is silently truncated... */ void fr_print_string(const char *in, size_t inlen, char *out, size_t outlen) { uint8_t *str = (uint8_t *)in; int sp = 0; int utf8 = 0; if (inlen == 0) inlen = strlen(in); /* * */ while ((inlen > 0) && (outlen > 4)) { /* * Hack: never print trailing zero. * Some clients send strings with an off-by-one * length (confused with strings in C). */ if ((inlen == 1) && (*str == 0)) break; switch (*str) { case '\\': sp = '\\'; break; case '\r': sp = 'r'; break; case '\n': sp = 'n'; break; case '\t': sp = 't'; break; case '"': sp = '"'; break; default: sp = 0; break; } if (sp) { *out++ = '\\'; *out++ = sp; outlen -= 2; str++; inlen--; continue; } utf8 = utf8_char((uint8_t *)str); if (!utf8) { snprintf(out, outlen, "\\%03o", *str); out += 4; outlen -= 4; str++; inlen--; continue; } do { *out++ = *str++; outlen--; inlen--; } while (--utf8 > 0); } *out = 0; }