| 45 | |
| 46 | char* read_file(const char *filename); |
| 47 | char* read_file(const char *filename) { |
| 48 | FILE *file = NULL; |
| 49 | long length = 0; |
| 50 | char *content = NULL; |
| 51 | size_t read_chars = 0; |
| 52 | |
| 53 | /* open in read binary mode */ |
| 54 | file = fopen(filename, "rb"); |
| 55 | if (file == NULL) |
| 56 | { |
| 57 | goto cleanup; |
| 58 | } |
| 59 | |
| 60 | /* get the length */ |
| 61 | if (fseek(file, 0, SEEK_END) != 0) |
| 62 | { |
| 63 | goto cleanup; |
| 64 | } |
| 65 | length = ftell(file); |
| 66 | if (length < 0) |
| 67 | { |
| 68 | goto cleanup; |
| 69 | } |
| 70 | if (fseek(file, 0, SEEK_SET) != 0) |
| 71 | { |
| 72 | goto cleanup; |
| 73 | } |
| 74 | |
| 75 | /* allocate content buffer */ |
| 76 | content = (char*)malloc((size_t)length + sizeof("")); |
| 77 | if (content == NULL) |
| 78 | { |
| 79 | goto cleanup; |
| 80 | } |
| 81 | |
| 82 | /* read the file into memory */ |
| 83 | read_chars = fread(content, sizeof(char), (size_t)length, file); |
| 84 | if ((long)read_chars != length) |
| 85 | { |
| 86 | free(content); |
| 87 | content = NULL; |
| 88 | goto cleanup; |
| 89 | } |
| 90 | content[read_chars] = '\0'; |
| 91 | |
| 92 | |
| 93 | cleanup: |
| 94 | if (file != NULL) |
| 95 | { |
| 96 | fclose(file); |
| 97 | } |
| 98 | |
| 99 | return content; |
| 100 | } |
| 101 | |
| 102 | /* assertion helper macros */ |
| 103 | #define assert_has_type(item, item_type) TEST_ASSERT_BITS_MESSAGE(0xFF, item_type, item->type, "Item doesn't have expected type.") |
no outgoing calls
searching dependent graphs…