char * trim2(const char *s, int how) { char *d; d = strdup(s); if (!d) xalloc_die(); if (MB_CUR_MAX > 1) { mbi_iterator_t i; /* Trim leading whitespaces. */ if (how != TRIM_TRAILING) { mbi_init (i, d, strlen (d)); for (; mbi_avail (i) && mb_isspace (mbi_cur (i)); mbi_advance (i)) ; memmove (d, mbi_cur_ptr (i), strlen (mbi_cur_ptr (i)) + 1); } /* Trim trailing whitespaces. */ if (how != TRIM_LEADING) { int state = 0; char *r IF_LINT (= NULL); /* used only while state = 2 */ mbi_init (i, d, strlen (d)); for (; mbi_avail (i); mbi_advance (i)) { if (state == 0 && mb_isspace (mbi_cur (i))) { state = 0; continue; } if (state == 0 && !mb_isspace (mbi_cur (i))) { state = 1; continue; } if (state == 1 && !mb_isspace (mbi_cur (i))) { state = 1; continue; } if (state == 1 && mb_isspace (mbi_cur (i))) { state = 2; r = (char *) mbi_cur_ptr (i); } else if (state == 2 && mb_isspace (mbi_cur (i))) { state = 2; } else { state = 1; } } if (state == 2) *r = '\0'; }
static int tag_image (char *text, struct text_buffer *outbuf) { mbi_iterator_t iter; enum { state_kw, state_val, state_qstr, state_delim } state = state_kw; struct text_buffer tmpbuf; char *kw; struct info_tag *tag_head = NULL, *tag; int escaped = 0; text_buffer_init (&tmpbuf); for (mbi_init (iter, text, strlen (text)); mbi_avail (iter); mbi_advance (iter)) { const char *cur_ptr; size_t cur_len; if (mb_isspace (mbi_cur (iter))) { if (state == state_val) { struct info_tag *new_kw = tag_found_keyword (&tmpbuf, &kw); new_kw->next = tag_head; tag_head = new_kw; state = state_delim; continue; } if (state == state_delim) continue; } cur_len = mb_len (mbi_cur (iter)); cur_ptr = mbi_cur_ptr (iter); if (state == state_qstr && escaped) { escaped = 0; } else if (cur_len == 1) { switch (*cur_ptr) { case '=': text_buffer_add_char (&tmpbuf, 0); kw = tmpbuf.base; if (!mbi_avail (iter)) break; mbi_advance (iter); state = state_val; cur_len = mb_len (mbi_cur (iter)); cur_ptr = mbi_cur_ptr (iter); if (!(cur_len == 1 && *cur_ptr == '"')) break; /* fall through */ case '"': if (state == state_val) { state = state_qstr; continue; } if (state == state_qstr) { struct info_tag *new_kw = tag_found_keyword (&tmpbuf, &kw); new_kw->next = tag_head; tag_head = new_kw; state = state_delim; continue; } break; case '\\': if (state == state_qstr) { escaped = 1; continue; } } } text_buffer_add_string (&tmpbuf, cur_ptr, cur_len); } tag = info_tag_find (tag_head, "text"); if (!tag) tag = info_tag_find (tag_head, "alt"); if (tag) { text_buffer_add_string (outbuf, tag->val, strlen (tag->val)); } text_buffer_free (&tmpbuf); info_tag_free (tag_head); return 0; }