aboutsummaryrefslogtreecommitdiff
path: root/src/ast.c
blob: 2a9ca8f94df51d94716e07da490ace6664628791 (plain)
  1. #include <stdbool.h>
  2. #include <stdio.h>
  3. #include "buffer.h"
  4. #include "ast.h"
  5. #include "references.h"
  6. // Free a node_block list and any children.
  7. void cmark_free_blocks(node_block *e)
  8. {
  9. node_block * next;
  10. while (e != NULL) {
  11. free_inlines(e->inline_content);
  12. strbuf_free(&e->string_content);
  13. if (e->tag == BLOCK_FENCED_CODE) {
  14. strbuf_free(&e->as.code.info);
  15. } else if (e->tag == BLOCK_DOCUMENT) {
  16. reference_map_free(e->as.document.refmap);
  17. }
  18. if (e->last_child) {
  19. // Splice children into list
  20. e->last_child->next = e->next;
  21. e->next = e->children;
  22. }
  23. next = e->next;
  24. free(e);
  25. e = next;
  26. }
  27. }
  28. // Utility function used by free_inlines
  29. static void splice_into_list(node_inl* e, node_inl* children) {
  30. node_inl * tmp;
  31. if (children) {
  32. tmp = children;
  33. // Find last child
  34. while (tmp->next) {
  35. tmp = tmp->next;
  36. }
  37. // Splice children into list
  38. tmp->next = e->next;
  39. e->next = children;
  40. }
  41. return ;
  42. }
  43. // Free an inline list. Avoid recursion to prevent stack overflows
  44. // on deeply nested structures.
  45. extern void free_inlines(node_inl* e)
  46. {
  47. node_inl * next;
  48. while (e != NULL) {
  49. switch (e->tag){
  50. case INL_STRING:
  51. case INL_RAW_HTML:
  52. case INL_CODE:
  53. chunk_free(&e->content.literal);
  54. break;
  55. case INL_LINEBREAK:
  56. case INL_SOFTBREAK:
  57. break;
  58. case INL_LINK:
  59. case INL_IMAGE:
  60. free(e->content.linkable.url);
  61. free(e->content.linkable.title);
  62. splice_into_list(e, e->content.linkable.label);
  63. break;
  64. case INL_EMPH:
  65. case INL_STRONG:
  66. splice_into_list(e, e->content.inlines);
  67. break;
  68. default:
  69. fprintf(stderr, "[WARN] (%s:%d) Unknown inline tag %d",
  70. __FILE__, __LINE__, e->tag);
  71. break;
  72. }
  73. next = e->next;
  74. free(e);
  75. e = next;
  76. }
  77. }