fork(1) download
  1. #include <stdio.h>
  2. #include <ctype.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include <assert.h>
  6.  
  7.  
  8. const char *source = " \
  9. ABC equ 1h \
  10. GHI equ 2h \
  11. JKL equ 3h \
  12. TUV equ 6h \
  13. MNO equ 4h \
  14. PQR equ 5h \
  15. \
  16. cjne A,#ABC,def \
  17. mov GHI,#1h \
  18. mov JKL,MNO \
  19. def:";
  20.  
  21. struct symbol_s {
  22. char *name;
  23. size_t count;
  24.  
  25. struct symbol_s *next;
  26. };
  27.  
  28. void symbol_append_child(struct symbol_s *head, struct symbol_s *next)
  29. {
  30. struct symbol_s *it;
  31.  
  32. assert(head != NULL);
  33. assert(next != NULL);
  34.  
  35. it = head;
  36.  
  37. while (it->next != NULL && (it = it->next)) { }
  38.  
  39. it->next = next;
  40. }
  41.  
  42.  
  43. int main()
  44. {
  45. int cursor = 0;
  46. int c;
  47. size_t source_length = strlen(source);
  48.  
  49. struct symbol_s head = { 0 };
  50.  
  51. while ((c = source[cursor]) != 0) {
  52. if (isalpha(c)) {
  53. int begin_cursor = cursor;
  54.  
  55. while ((c = source[cursor++]) && isalnum(c)) {}
  56.  
  57. if (isspace(c) && strncmp("equ", source + cursor, 3) == 0) {
  58. // If followed by "equ" it's a symbol declaration
  59.  
  60. struct symbol_s *symbol;
  61.  
  62. symbol = calloc(1, sizeof(*symbol));
  63. size_t len = cursor - begin_cursor - 1;
  64.  
  65. symbol->name = malloc(len);
  66. strncpy(symbol->name, source + begin_cursor, len);
  67. symbol->name[len] = 0;
  68.  
  69. symbol_append_child(&head, symbol);
  70. } else {
  71. // treat alphanumeric string as a usage
  72. char buffer[512];
  73. size_t len = cursor - begin_cursor - 1;
  74.  
  75. strncpy(buffer, source + begin_cursor, len);
  76. buffer[len] = 0;
  77.  
  78. struct symbol_s *it;
  79.  
  80. for (it = &head; it != NULL; it = it->next) {
  81. if (it->name == NULL) {
  82. continue;
  83. }
  84.  
  85. if (strncmp(it->name, source + begin_cursor, len) == 0) {
  86. it->count += 1;
  87. }
  88. }
  89. continue;
  90. }
  91. }
  92. cursor++;
  93. }
  94.  
  95. struct symbol_s *it;
  96.  
  97. for (it = &head; it != NULL; it = it->next) {
  98. if (it->name == NULL) {
  99. continue;
  100. }
  101.  
  102. if (it->count == 0) {
  103. printf("Unused symbol: %s\n", it->name, it->count);
  104. }
  105. }
  106.  
  107. // clean up
  108. struct symbol_s *prev;
  109. for (prev = NULL, it = &head; it != NULL; prev = it, it = it->next) {
  110. if (it->name == NULL) {
  111. continue;
  112. }
  113.  
  114. if (prev != NULL && prev->name) {
  115. free(prev->name);
  116. free(prev);
  117. }
  118. }
  119. free(prev->name);
  120. free(prev);
  121.  
  122. return 0;
  123. }
  124.  
Success #stdin #stdout 0s 4376KB
stdin
Standard input is empty
stdout
Unused symbol: TUV
Unused symbol: PQR