HTML parsing stack is now a vector.

This commit is contained in:
2025-08-05 23:07:31 -04:00
parent f20470acaf
commit 96d984777c
3 changed files with 38 additions and 43 deletions

View File

@ -475,20 +475,19 @@ DilloHtml::DilloHtml(BrowserWindow *p_bw, const DilloUrl *url,
styleEngine = std::make_unique< StyleEngine >(HT2LT (this), page_url.get(), base_url.get(), bw->zoom);
stack = new misc::SimpleVector <DilloHtmlState> (16);
stack->increase();
stack->getRef(0)->parse_mode = DILLO_HTML_PARSE_MODE_INIT;
stack->getRef(0)->table_mode = DILLO_HTML_TABLE_MODE_NONE;
stack->getRef(0)->table_border_mode = DILLO_HTML_TABLE_BORDER_SEPARATE;
stack->getRef(0)->cell_text_align_set = false;
stack->getRef(0)->display_none = false;
stack->getRef(0)->list_type = HTML_LIST_NONE;
stack->getRef(0)->list_number = 0;
stack->getRef(0)->tag_idx = -1; /* MUST not be used */
stack->getRef(0)->textblock = NULL;
stack->getRef(0)->table = NULL;
stack->getRef(0)->ref_list_item = NULL;
stack->getRef(0)->hand_over_break = false;
stack.emplace_back();
stack.back().parse_mode = DILLO_HTML_PARSE_MODE_INIT;
stack.back().table_mode = DILLO_HTML_TABLE_MODE_NONE;
stack.back().table_border_mode = DILLO_HTML_TABLE_BORDER_SEPARATE;
stack.back().cell_text_align_set = false;
stack.back().display_none = false;
stack.back().list_type = HTML_LIST_NONE;
stack.back().list_number = 0;
stack.back().tag_idx = -1; /* MUST not be used */
stack.back().textblock = NULL;
stack.back().table = NULL;
stack.back().ref_list_item = NULL;
stack.back().hand_over_break = false;
InFlags = IN_NONE;
@ -531,7 +530,7 @@ void DilloHtml::initDw()
dReturn_if_fail (dw == NULL);
/* Create the main widget */
dw = stack->getRef(0)->textblock = new Textblock (prefs.limit_text_width);
dw = stack.back().textblock = new Textblock (prefs.limit_text_width);
bw->num_page_bugs = 0;
bw->page_bugs.clear();
@ -604,8 +603,6 @@ int DilloHtml::getCurrLineNumber()
*/
void DilloHtml::freeParseData()
{
delete(stack);
dStr_free(Stash, TRUE);
dStr_free(attr_data, TRUE);
}
@ -624,9 +621,9 @@ void DilloHtml::finishParsing(int ClientKey)
InFlags |= IN_EOF;
/* force the close of elements left open (TODO: not for XHTML) */
while ((si = stack->size() - 1)) {
if (stack->getRef(si)->tag_idx != -1) {
Html_tag_cleanup_at_close(this, stack->getRef(si)->tag_idx);
while ((si = stack.size() - 1)) {
if (stack.at(si).tag_idx != -1) {
Html_tag_cleanup_at_close(this, stack.at(si).tag_idx);
}
}
@ -1320,14 +1317,10 @@ static void Html_eventually_pop_dw(DilloHtml *html, bool hand_over_break)
*/
static void Html_push_tag(DilloHtml *html, int tag_idx)
{
int n_items;
n_items = html->stack->size ();
html->stack->increase ();
/* We'll copy the former stack item and just change the tag and its index
* instead of copying all fields except for tag. --Jcid */
*html->stack->getRef(n_items) = *html->stack->getRef(n_items - 1);
html->stack->getRef(n_items)->tag_idx = tag_idx;
html->stack.push_back( html->stack.back() );
html->stack.back().tag_idx = tag_idx;
html->dw = S_TOP(html)->textblock;
}
@ -1350,7 +1343,7 @@ static void Html_real_pop_tag(DilloHtml *html)
html->styleEngine->endElement (S_TOP(html)->tag_idx);
hand_over_break = S_TOP(html)->hand_over_break;
html->stack->setSize (html->stack->size() - 1);
html->stack.pop_back();
Html_eventually_pop_dw(html, hand_over_break);
}
@ -2877,7 +2870,7 @@ static void Html_tag_open_li(DilloHtml *html, const char *tag, int tagsize)
html->InFlags |= IN_LI;
/* Get our parent tag's variables (used as state storage) */
list_number = &html->stack->getRef(html->stack->size()-2)->list_number;
list_number = &html->stack.at(html->stack.size()-2).list_number;
if (style->listStyleType >= LIST_STYLE_TYPE_DECIMAL) {
// ordered
@ -3641,7 +3634,7 @@ static void Html_tag_cleanup_to_idx(DilloHtml *html, int s_idx,
int new_idx, int fi, char op)
{
int s_top, ni = new_idx;
while ((s_top = html->stack->size() - 1) >= s_idx) {
while ((s_top = html->stack.size() - 1) >= s_idx) {
int toptag_idx = S_TOP(html)->tag_idx;
TagInfo toptag = Tags[toptag_idx];
@ -3694,10 +3687,10 @@ static void Html_stack_cleanup_at_open(DilloHtml *html, int ni)
if (!html->TagSoup)
return;
int s_top = html->stack->size() - 1, s_idx;
int s_top = html->stack.size() - 1, s_idx;
int fi = Html_forbids_cross_nesting(html->InFlags, ni);
for (s_idx = s_top; s_idx > 0; --s_idx) {
int ti = html->stack->getRef(s_idx)->tag_idx;
int ti = html->stack.at(s_idx).tag_idx;
if (fi >= 0) {
// forbidden cross nesting found
@ -3745,9 +3738,9 @@ static void Html_tag_cleanup_at_close(DilloHtml *html, int new_idx)
TagInfo new_tag = Tags[new_idx];
/* Look for the candidate tag to close */
stack_idx = html->stack->size();
stack_idx = html->stack.size();
while (--stack_idx) {
tag_idx = html->stack->getRef(stack_idx)->tag_idx;
tag_idx = html->stack.at(stack_idx).tag_idx;
if (tag_idx == new_idx) {
/* matching tag found */
matched = 1;
@ -3938,8 +3931,8 @@ static void Html_display_listitem(DilloHtml *html)
char buf[16];
/* Get our parent tag's variables (used as state storage) */
list_number = &html->stack->getRef(html->stack->size()-2)->list_number;
ref_list_item = &html->stack->getRef(html->stack->size()-2)->ref_list_item;
list_number = &html->stack.at(html->stack.size()-2).list_number;
ref_list_item = &html->stack.at(html->stack.size()-2).ref_list_item;
HT2TB(html)->addParbreak (0, wordStyle);

View File

@ -47,7 +47,7 @@
/** "Image" to "Dw Widget" */
#define IM2DW(Image) ((Widget*)Image->dw)
/** Top of the parsing stack */
#define S_TOP(html) (html->stack->getRef(html->stack->size()-1))
#define S_TOP(html) (&html->stack.back())
/** Add a bug-meter message. */
#define BUG_MSG(...) \
@ -189,7 +189,9 @@ public: //BUG: for now everything is public
/* vector of remote CSS resources, as given by the LINK element */
std::vector< std::unique_ptr< DilloUrl > > cssUrls;
lout::misc::SimpleVector<DilloHtmlState> *stack;
// Apparently, there's peeks down a level or two, so we'll use a vector.
// The stack will grow "up" in addresses -- back is the "top".
std::vector< DilloHtmlState > stack;
std::unique_ptr< StyleEngine > styleEngine;
int InFlags; /**< tracks which elements we are in */

View File

@ -302,10 +302,10 @@ static int Html_table_get_border_model(DilloHtml *html)
if (i_TABLE == -1)
i_TABLE = a_Html_tag_index("table");
int s_idx = html->stack->size();
while (--s_idx > 0 && html->stack->getRef(s_idx)->tag_idx != i_TABLE)
int s_idx = html->stack.size();
while (--s_idx > 0 && html->stack.at(s_idx).tag_idx != i_TABLE)
;
return html->stack->getRef(s_idx)->table_border_mode;
return html->stack.at(s_idx).table_border_mode;
}
/**
@ -314,11 +314,11 @@ static int Html_table_get_border_model(DilloHtml *html)
static void Html_table_set_border_model(DilloHtml *html,
DilloHtmlTableBorderMode mode)
{
int s_idx = html->stack->size(), i_TABLE = a_Html_tag_index("table");
int s_idx = html->stack.size(), i_TABLE = a_Html_tag_index("table");
while (--s_idx > 0 && html->stack->getRef(s_idx)->tag_idx != i_TABLE) ;
while (--s_idx > 0 && html->stack.at(s_idx).tag_idx != i_TABLE) ;
if (s_idx > 0)
html->stack->getRef(s_idx)->table_border_mode = mode;
html->stack.at(s_idx).table_border_mode = mode;
}
/* WORKAROUND: collapsing border model requires moving rendering code from