Skip to content

Commit db847e6

Browse files
authored
Merge pull request #981 from htacg/iterate
Documentation and Recursion
2 parents ab6b76d + e56716f commit db847e6

File tree

9 files changed

+3873
-1684
lines changed

9 files changed

+3873
-1684
lines changed

src/clean.c

+54-29
Original file line numberDiff line numberDiff line change
@@ -1585,11 +1585,16 @@ void TY_(List2BQ)( TidyDocImpl* doc, Node* node )
15851585
*/
15861586
void TY_(BQ2Div)( TidyDocImpl* doc, Node *node )
15871587
{
1588+
Stack *stack = TY_(newStack)(doc, 16);
1589+
Node *next;
1590+
15881591
tmbchar indent_buf[ 32 ];
15891592
uint indent;
15901593

15911594
while (node)
15921595
{
1596+
next = node->next;
1597+
15931598
if ( nodeIsBLOCKQUOTE(node) && node->implicit )
15941599
{
15951600
indent = 1;
@@ -1602,19 +1607,27 @@ void TY_(BQ2Div)( TidyDocImpl* doc, Node *node )
16021607
StripOnlyChild( doc, node );
16031608
}
16041609

1605-
if (node->content)
1606-
TY_(BQ2Div)( doc, node->content );
1607-
16081610
TY_(tmbsnprintf)(indent_buf, sizeof(indent_buf), "margin-left: %dem",
16091611
2*indent);
16101612

16111613
RenameElem( doc, node, TidyTag_DIV );
16121614
TY_(AddStyleProperty)(doc, node, indent_buf );
1615+
1616+
if (node->content)
1617+
{
1618+
TY_(push)(stack, next);
1619+
node = node->content;
1620+
continue;
1621+
}
16131622
}
16141623
else if (node->content)
1615-
TY_(BQ2Div)( doc, node->content );
1624+
{
1625+
TY_(push)(stack, next);
1626+
node = node->content;
1627+
continue;
1628+
}
16161629

1617-
node = node->next;
1630+
node = next ? next : TY_(pop)(stack);
16181631
}
16191632
}
16201633

@@ -2736,30 +2749,42 @@ void TY_(FixAnchors)(TidyDocImpl* doc, Node *node, Bool wantName, Bool wantId)
27362749
*/
27372750
static void StyleToHead(TidyDocImpl* doc, Node *head, Node *node, Bool fix, int indent)
27382751
{
2739-
Node *next;
2740-
while (node)
2741-
{
2742-
next = node->next; /* get 'next' now , in case the node is moved */
2743-
/* dbg_show_node(doc, node, 0, indent); */
2744-
if (nodeIsSTYLE(node))
2745-
{
2746-
if (fix)
2747-
{
2748-
TY_(RemoveNode)(node); /* unhook style node from body */
2749-
TY_(InsertNodeAtEnd)(head, node); /* add to end of head */
2750-
TY_(Report)(doc, node, head, MOVED_STYLE_TO_HEAD); /* report move */
2751-
}
2752-
else
2753-
{
2754-
TY_(Report)(doc, node, head, FOUND_STYLE_IN_BODY);
2755-
}
2756-
}
2757-
else if (node->content)
2758-
{
2759-
StyleToHead(doc, head, node->content, fix, indent + 1);
2760-
}
2761-
node = next; /* process the 'next', if any */
2762-
}
2752+
Stack *stack = TY_(newStack)(doc, 16);
2753+
Node *next;
2754+
2755+
while (node)
2756+
{
2757+
next = node->next;
2758+
2759+
if (nodeIsSTYLE(node))
2760+
{
2761+
if (fix)
2762+
{
2763+
TY_(RemoveNode)(node); /* unhook style node from body */
2764+
TY_(InsertNodeAtEnd)(head, node); /* add to end of head */
2765+
TY_(Report)(doc, node, head, MOVED_STYLE_TO_HEAD); /* report move */
2766+
}
2767+
else
2768+
{
2769+
TY_(Report)(doc, node, head, FOUND_STYLE_IN_BODY);
2770+
}
2771+
}
2772+
else if (node->content)
2773+
{
2774+
TY_(push)(stack, next);
2775+
node = node->content;
2776+
indent++;
2777+
continue;
2778+
}
2779+
2780+
if (next)
2781+
node = next;
2782+
else
2783+
{
2784+
node = TY_(pop)(stack);
2785+
indent--;
2786+
}
2787+
}
27632788
}
27642789

27652790

src/lexer.c

+99-23
Original file line numberDiff line numberDiff line change
@@ -877,15 +877,6 @@ static tmbchar LastChar( tmbstr str )
877877
return 0;
878878
}
879879

880-
/*
881-
node->type is one of these:
882-
883-
#define TextNode 1
884-
#define StartTag 2
885-
#define EndTag 3
886-
#define StartEndTag 4
887-
*/
888-
889880
Lexer* TY_(NewLexer)( TidyDocImpl* doc )
890881
{
891882
Lexer* lexer = (Lexer*) TidyDocAlloc( doc, sizeof(Lexer) );
@@ -1545,13 +1536,7 @@ void TY_(FreeNode)( TidyDocImpl* doc, Node *node )
15451536
}
15461537
}
15471538
#endif
1548-
/* this is no good ;=((
1549-
if (node && doc && doc->lexer) {
1550-
if (node == doc->lexer->token) {
1551-
doc->lexer->token = NULL; // TY_(NewNode)( doc->lexer->allocator, doc->lexer );
1552-
}
1553-
}
1554-
----------------- */
1539+
15551540
while ( node )
15561541
{
15571542
Node* next = node->next;
@@ -4462,11 +4447,102 @@ static Node *ParseDocTypeDecl(TidyDocImpl* doc)
44624447
return NULL;
44634448
}
44644449

4465-
/*
4466-
* local variables:
4467-
* mode: c
4468-
* indent-tabs-mode: nil
4469-
* c-basic-offset: 4
4470-
* eval: (c-set-offset 'substatement-open 0)
4471-
* end:
4450+
4451+
/****************************************************************************//*
4452+
** MARK: - Node Stack
4453+
***************************************************************************/
4454+
4455+
4456+
/**
4457+
* Create a new stack with a given starting capacity. If memory allocation
4458+
* fails, then the allocator will panic the program automatically.
4459+
*/
4460+
Stack* TY_(newStack)(TidyDocImpl *doc, uint capacity)
4461+
{
4462+
Stack *stack = (Stack *)TidyAlloc(doc->allocator, sizeof(Stack));
4463+
stack->top = -1;
4464+
stack->capacity = capacity;
4465+
stack->firstNode = (Node **)TidyAlloc(doc->allocator, stack->capacity * sizeof(Node**));
4466+
stack->allocator = doc->allocator;
4467+
return stack;
4468+
}
4469+
4470+
4471+
/**
4472+
* Increase the stack size. This will be called automatically when the
4473+
* current stack is full. If memory allocation fails, then the allocator
4474+
* will panic the program automatically.
4475+
*/
4476+
void TY_(growStack)(Stack *stack)
4477+
{
4478+
uint new_capacity = stack->capacity * 2;
4479+
4480+
Node **firstNode = (Node **)TidyAlloc(stack->allocator, new_capacity);
4481+
4482+
memcpy( firstNode, stack->firstNode, sizeof(Node**) * (stack->top + 1) );
4483+
TidyFree(stack->allocator, stack->firstNode);
4484+
4485+
stack->firstNode = firstNode;
4486+
stack->capacity = new_capacity;
4487+
}
4488+
4489+
4490+
/**
4491+
* Stack is full when top is equal to the last index.
4492+
*/
4493+
Bool TY_(stackFull)(Stack *stack)
4494+
{
4495+
return stack->top == stack->capacity - 1;
4496+
}
4497+
4498+
4499+
/**
4500+
* Stack is empty when top is equal to -1
4501+
*/
4502+
Bool TY_(stackEmpty)(Stack *stack)
4503+
{
4504+
return stack->top == -1;
4505+
}
4506+
4507+
4508+
/**
4509+
* Push an item to the stack.
4510+
*/
4511+
void TY_(push)(Stack *stack, Node *node)
4512+
{
4513+
if (TY_(stackFull)(stack))
4514+
TY_(growStack)(stack);
4515+
4516+
if (node)
4517+
stack->firstNode[++stack->top] = node;
4518+
}
4519+
4520+
4521+
/**
4522+
* Pop an item from the stack.
4523+
*/
4524+
Node* TY_(pop)(Stack *stack)
4525+
{
4526+
return TY_(stackEmpty)(stack) ? NULL : stack->firstNode[stack->top--];
4527+
}
4528+
4529+
4530+
/**
4531+
* Peek at the stack.
44724532
*/
4533+
FUNC_UNUSED Node* TY_(peek)(Stack *stack)
4534+
{
4535+
return TY_(stackEmpty)(stack) ? NULL : stack->firstNode[stack->top--];
4536+
}
4537+
4538+
/**
4539+
* Frees the stack when done.
4540+
*/
4541+
void TY_(freeStack)(Stack *stack)
4542+
{
4543+
TidyFree( stack->allocator, stack->firstNode );
4544+
stack->top = -1;
4545+
stack->capacity = 0;
4546+
stack->firstNode = NULL;
4547+
stack->allocator = NULL;
4548+
}

0 commit comments

Comments
 (0)