static SgObject glob_make_pattern(SgString *path, int flags) { const int escape = !(flags & SG_NOESCAPE); SgObject h = SG_NIL, t = SG_NIL, h1 = SG_NIL, t1 = SG_NIL; int i, start; #define emit() \ do { \ if (start != i) { \ SgObject tmp = Sg_Substring(path, start, i); \ if (escape) tmp = remove_backslashes(tmp); \ SG_APPEND1(h1, t1, tmp); \ } \ start = i+1; \ } while (0) for (i = 0, start = 0; i < SG_STRING_SIZE(path);) { SgChar c = SG_STRING_VALUE_AT(path, i); switch (c) { case '[': { int s = i, e; e = find_close_bracket(path, start, flags); if (s != e) { emit(); SG_APPEND1(h1, t1, Sg_ParseCharSetString(path, FALSE, s, i=++e)); start = i; } i++; } break; case '/': /* next */ emit(); /* if the path starts with '/', then this can be null */ if (!SG_NULLP(h1)) { SG_APPEND1(h, t, convert_star(h1)); } h1 = t1 = SG_NIL; /* reset it */ /* this need to be updated */ start = ++i; break; case '*': { int has = (start != i); emit(); /* merge it if it's there */ if (!has && SG_STRING_SIZE(path) - i >= 3 && SG_STRING_VALUE_AT(path, i+1) == '*' && SG_STRING_VALUE_AT(path, i+2) == '/') { do { i += 3; /* skip '/' */ while (SG_STRING_VALUE_AT(path, i) == '/') i++; } while (SG_STRING_VALUE_AT(path, i) == '*' && SG_STRING_VALUE_AT(path, i+1) == '*' && SG_STRING_VALUE_AT(path, i+2) == '/'); SG_APPEND1(h1, t1, STAR_SLASH); SG_APPEND1(h, t, h1); h1 = t1 = SG_NIL; /* reset it */ start = i; } else { SG_APPEND1(h1, t1, STAR); while (SG_STRING_VALUE_AT(path, i) == '*') i++; } break; } case '?': emit(); SG_APPEND1(h1, t1, FULL_CHARSET); i++; break; default: i++; break; } } emit(); if (!SG_NULLP(h1)) { SG_APPEND1(h, t, convert_star(h1)); SG_APPEND1(h, t, SG_LIST1(ANY)); } else { SG_APPEND1(h, t, SG_LIST1(DIR)); } #undef emit return h; }
void litehtml::css::parse_stylesheet( const tchar_t* str, const tchar_t* baseurl, document* doc, media_query_list::ptr& media ) { tstring text = str; // remove comments tstring::size_type c_start = text.find(_t("/*")); while(c_start != tstring::npos) { tstring::size_type c_end = text.find(_t("*/"), c_start + 2); text.erase(c_start, c_end - c_start + 2); c_start = text.find(_t("/*")); } tstring::size_type pos = text.find_first_not_of(_t(" \n\r\t")); while(pos != tstring::npos) { while(pos != tstring::npos && text[pos] == _t('@')) { tstring::size_type sPos = pos; pos = text.find_first_of(_t("{"), pos); if(pos != tstring::npos && text[pos] == _t('{')) { pos = find_close_bracket(text, pos, _t('{'), _t('}')); } if(pos != tstring::npos) { parse_atrule(text.substr(sPos, pos - sPos + 1), baseurl, doc, media); } else { parse_atrule(text.substr(sPos), baseurl, doc, media); } if(pos != tstring::npos) { pos = text.find_first_not_of(_t(" \n\r\t"), pos + 1); } } if(pos == tstring::npos) { break; } tstring::size_type style_start = text.find(_t("{"), pos); tstring::size_type style_end = text.find(_t("}"), pos); if(style_start != tstring::npos && style_end != tstring::npos) { style::ptr st = new style; st->add(text.substr(style_start + 1, style_end - style_start - 1).c_str(), baseurl); parse_selectors(text.substr(pos, style_start - pos), st, media); if(media && doc) { doc->add_media_list(media); } pos = style_end + 1; } else { pos = tstring::npos; } if(pos != tstring::npos) { pos = text.find_first_not_of(_t(" \n\r\t"), pos); } } }