MD_Node->at fix.

node->at now points to the first relevant character in the source .md file.
For namespaces and tags that is the first character of the identifier
(not the '#'/'@' symbols).
For labels it's the first character in node->whole_string if non-empty.
For unlabeled sets it's the opening '(', '[' or '{' character.
This commit is contained in:
Miguel Lechon
2021-03-16 09:19:02 +01:00
parent 52fdfdbc38
commit eb0cf0c9bf
2 changed files with 82 additions and 7 deletions
+71
View File
@@ -468,6 +468,65 @@ static int StringCompare(MD_String8 a, MD_String8 b)
return result;
}
static MD_Node *
FirstBadNodeAtPointer(MD_Node *node)
{
MD_Node *result = 0;
switch(node->kind){
case MD_NodeKind_File:
{
} break;
case MD_NodeKind_Label:
{
if(node->at != node->whole_string.str)
{
if(node->whole_string.size)
{
result = node;
}
else
{
if(!node->at || (node->at[0] != '(' && node->at[0] != '[' && node->at[0] != '{'))
{
result = node;
}
}
if(result)
{
goto end;
}
}
} break;
case MD_NodeKind_Namespace:
case MD_NodeKind_Tag:
{
if(node->at != node->whole_string.str)
{
result = node;
goto end;
}
} break;
default:
break;
}
for(MD_EachNode(child, node->first_child))
{
result = FirstBadNodeAtPointer(child);
if(result) goto end;
}
for(MD_EachNode(child, node->first_tag))
{
result = FirstBadNodeAtPointer(child);
if(result) goto end;
}
end:
return result;
}
int main(int argument_count, char **arguments)
{
MD_Node *grammar = MD_ParseWholeFile(MD_S8Lit("tests/grammar.md")).node;
@@ -701,6 +760,18 @@ int main(int argument_count, char **arguments)
MD_OutputTree(stdout, test->expected_output); printf("\n");
return -1;
}
MD_Node *bad_at_node = FirstBadNodeAtPointer(file_node);
if(bad_at_node)
{
printf("\nBad node->at on test %d\n", i_test);
printf("> %.*s <\n", MD_StringExpand(test->input));
printf("MD:\n");
MD_OutputTree(stdout, file_node);
printf("offending_node");
MD_OutputTree(stdout, bad_at_node);
return -1;
}
++i_test;
}