#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
const char *source = " \
ABC equ 1h \
GHI equ 2h \
JKL equ 3h \
TUV equ 6h \
MNO equ 4h \
PQR equ 5h \
\
cjne A,#ABC,def \
mov GHI,#1h \
mov JKL,MNO \
def:";
struct symbol_s {
char *name;
size_t count;
struct symbol_s *next;
};
void symbol_append_child(struct symbol_s *head, struct symbol_s *next)
{
struct symbol_s *it;
it = head;
while (it->next != NULL && (it = it->next)) { }
it->next = next;
}
int main()
{
int cursor = 0;
int c;
size_t source_length
= strlen(source
);
struct symbol_s head = { 0 };
while ((c = source[cursor]) != 0) {
int begin_cursor = cursor;
while ((c
= source
[cursor
++]) && isalnum(c
)) {}
// If followed by "equ" it's a symbol declaration
struct symbol_s *symbol;
symbol
= calloc(1, sizeof(*symbol
)); size_t len = cursor - begin_cursor - 1;
strncpy(symbol
->name
, source
+ begin_cursor
, len
); symbol->name[len] = 0;
symbol_append_child(&head, symbol);
} else {
// treat alphanumeric string as a usage
char buffer[512];
size_t len = cursor - begin_cursor - 1;
strncpy(buffer
, source
+ begin_cursor
, len
); buffer[len] = 0;
struct symbol_s *it;
for (it = &head; it != NULL; it = it->next) {
if (it->name == NULL) {
continue;
}
if (strncmp(it
->name
, source
+ begin_cursor
, len
) == 0) { it->count += 1;
}
}
continue;
}
}
cursor++;
}
struct symbol_s *it;
for (it = &head; it != NULL; it = it->next) {
if (it->name == NULL) {
continue;
}
if (it->count == 0) {
printf("Unused symbol: %s\n", it
->name
, it
->count
); }
}
// clean up
struct symbol_s *prev;
for (prev = NULL, it = &head; it != NULL; prev = it, it = it->next) {
if (it->name == NULL) {
continue;
}
if (prev != NULL && prev->name) {
}
}
return 0;
}
I2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxjdHlwZS5oPgojaW5jbHVkZSA8c3RkbGliLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KI2luY2x1ZGUgPGFzc2VydC5oPgoKCmNvbnN0IGNoYXIgKnNvdXJjZSA9ICIgXApBQkMgZXF1IDFoICAgICAgICAgICAgIFwKR0hJIGVxdSAyaCAgICAgICAgICAgICBcCkpLTCBlcXUgM2ggICAgICAgICAgICAgXApUVVYgZXF1IDZoICAgICAgICAgICAgIFwKTU5PIGVxdSA0aCAgICAgICAgICAgICBcClBRUiBlcXUgNWggICAgICAgICAgICAgXAogICAgICAgICAgICAgICAgICAgICAgIFwKY2puZSBBLCNBQkMsZGVmICAgICAgICBcCiAgbW92IEdISSwjMWggICAgICAgICAgXAogIG1vdiBKS0wsTU5PICAgICAgICAgIFwKZGVmOiI7CgpzdHJ1Y3Qgc3ltYm9sX3MgewogICAgY2hhciAqbmFtZTsKICAgIHNpemVfdCBjb3VudDsKCiAgICBzdHJ1Y3Qgc3ltYm9sX3MgKm5leHQ7Cn07Cgp2b2lkIHN5bWJvbF9hcHBlbmRfY2hpbGQoc3RydWN0IHN5bWJvbF9zICpoZWFkLCBzdHJ1Y3Qgc3ltYm9sX3MgKm5leHQpCnsKICAgIHN0cnVjdCBzeW1ib2xfcyAqaXQ7CgogICAgYXNzZXJ0KGhlYWQgIT0gTlVMTCk7CiAgICBhc3NlcnQobmV4dCAhPSBOVUxMKTsKCiAgICBpdCA9IGhlYWQ7CgogICAgd2hpbGUgKGl0LT5uZXh0ICE9IE5VTEwgJiYgKGl0ID0gaXQtPm5leHQpKSB7IH0KCiAgICBpdC0+bmV4dCA9IG5leHQ7Cn0KCgppbnQgbWFpbigpCnsKICAgIGludCBjdXJzb3IgPSAwOwogICAgaW50IGM7CiAgICBzaXplX3Qgc291cmNlX2xlbmd0aCA9IHN0cmxlbihzb3VyY2UpOwoKICAgIHN0cnVjdCBzeW1ib2xfcyBoZWFkID0geyAwIH07CgogICAgd2hpbGUgKChjID0gc291cmNlW2N1cnNvcl0pICE9IDApIHsKICAgICAgICBpZiAoaXNhbHBoYShjKSkgewogICAgICAgICAgICBpbnQgYmVnaW5fY3Vyc29yID0gY3Vyc29yOwoKICAgICAgICAgICAgd2hpbGUgKChjID0gc291cmNlW2N1cnNvcisrXSkgJiYgaXNhbG51bShjKSkge30KCiAgICAgICAgICAgIGlmIChpc3NwYWNlKGMpICYmIHN0cm5jbXAoImVxdSIsIHNvdXJjZSArIGN1cnNvciwgMykgPT0gMCkgewogICAgICAgICAgICAgICAgLy8gSWYgZm9sbG93ZWQgYnkgImVxdSIgaXQncyBhIHN5bWJvbCBkZWNsYXJhdGlvbgoKICAgICAgICAgICAgICAgIHN0cnVjdCBzeW1ib2xfcyAqc3ltYm9sOwoKICAgICAgICAgICAgICAgIHN5bWJvbCA9IGNhbGxvYygxLCBzaXplb2YoKnN5bWJvbCkpOwogICAgICAgICAgICAgICAgc2l6ZV90IGxlbiA9IGN1cnNvciAtIGJlZ2luX2N1cnNvciAtIDE7CgogICAgICAgICAgICAgICAgc3ltYm9sLT5uYW1lID0gbWFsbG9jKGxlbik7CiAgICAgICAgICAgICAgICBzdHJuY3B5KHN5bWJvbC0+bmFtZSwgc291cmNlICsgYmVnaW5fY3Vyc29yLCBsZW4pOwogICAgICAgICAgICAgICAgc3ltYm9sLT5uYW1lW2xlbl0gPSAwOwoKICAgICAgICAgICAgICAgIHN5bWJvbF9hcHBlbmRfY2hpbGQoJmhlYWQsIHN5bWJvbCk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAvLyB0cmVhdCBhbHBoYW51bWVyaWMgc3RyaW5nIGFzIGEgdXNhZ2UKICAgICAgICAgICAgICAgIGNoYXIgYnVmZmVyWzUxMl07CiAgICAgICAgICAgICAgICBzaXplX3QgbGVuID0gY3Vyc29yIC0gYmVnaW5fY3Vyc29yIC0gMTsKCiAgICAgICAgICAgICAgICBzdHJuY3B5KGJ1ZmZlciwgc291cmNlICsgYmVnaW5fY3Vyc29yLCBsZW4pOwogICAgICAgICAgICAgICAgYnVmZmVyW2xlbl0gPSAwOwoKICAgICAgICAgICAgICAgIHN0cnVjdCBzeW1ib2xfcyAqaXQ7CgogICAgICAgICAgICAgICAgZm9yIChpdCA9ICZoZWFkOyBpdCAhPSBOVUxMOyBpdCA9IGl0LT5uZXh0KSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKGl0LT5uYW1lID09IE5VTEwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICBpZiAoc3RybmNtcChpdC0+bmFtZSwgc291cmNlICsgYmVnaW5fY3Vyc29yLCBsZW4pID09IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgaXQtPmNvdW50ICs9IDE7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgY3Vyc29yKys7CiAgICB9CgogICAgc3RydWN0IHN5bWJvbF9zICppdDsKCiAgICBmb3IgKGl0ID0gJmhlYWQ7IGl0ICE9IE5VTEw7IGl0ID0gaXQtPm5leHQpIHsKICAgICAgICBpZiAoaXQtPm5hbWUgPT0gTlVMTCkgewogICAgICAgICAgICBjb250aW51ZTsKICAgICAgICB9CgogICAgICAgIGlmIChpdC0+Y291bnQgPT0gMCkgewogICAgICAgICAgICBwcmludGYoIlVudXNlZCBzeW1ib2w6ICVzXG4iLCBpdC0+bmFtZSwgaXQtPmNvdW50KTsKICAgICAgICB9CiAgICB9CgogICAgLy8gY2xlYW4gdXAKICAgIHN0cnVjdCBzeW1ib2xfcyAqcHJldjsKICAgIGZvciAocHJldiA9IE5VTEwsIGl0ID0gJmhlYWQ7IGl0ICE9IE5VTEw7IHByZXYgPSBpdCwgaXQgPSBpdC0+bmV4dCkgewogICAgICAgIGlmIChpdC0+bmFtZSA9PSBOVUxMKSB7CiAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgIH0KCiAgICAgICAgaWYgKHByZXYgIT0gTlVMTCAmJiBwcmV2LT5uYW1lKSB7CiAgICAgICAgICAgIGZyZWUocHJldi0+bmFtZSk7CiAgICAgICAgICAgIGZyZWUocHJldik7CiAgICAgICAgfQogICAgfQogICAgZnJlZShwcmV2LT5uYW1lKTsKICAgIGZyZWUocHJldik7CgogICAgcmV0dXJuIDA7Cn0K