diff options
| -rw-r--r-- | file.c | 70 | ||||
| -rw-r--r-- | file.h | 4 | ||||
| -rw-r--r-- | main.c | 193 |
3 files changed, 133 insertions, 134 deletions
| @@ -4,41 +4,41 @@ | |||
| 4 | #include "file.h" | 4 | #include "file.h" |
| 5 | 5 | ||
| 6 | struct FileContent read_entire_file(const char *file_path) { | 6 | struct FileContent read_entire_file(const char *file_path) { |
| 7 | struct FileContent file_data; | 7 | struct FileContent file_data; |
| 8 | file_data.content = NULL; | ||
| 9 | file_data.count = 0; | ||
| 10 | |||
| 11 | FILE *file = fopen(file_path, "rb"); | ||
| 12 | if (file == NULL) { | ||
| 13 | perror("Error opening file"); | ||
| 14 | return file_data; | ||
| 15 | } | ||
| 16 | |||
| 17 | fseek(file, 0, SEEK_END); | ||
| 18 | long file_size = ftell(file); | ||
| 19 | fseek(file, 0, SEEK_SET); | ||
| 20 | |||
| 21 | if (file_size == -1) { | ||
| 22 | perror("Error getting file size"); | ||
| 23 | return file_data; | ||
| 24 | } | ||
| 25 | |||
| 26 | file_data.content = (const char *)malloc(file_size); | ||
| 27 | if (file_data.content == NULL) { | ||
| 28 | perror("Error allocating memory"); | ||
| 29 | return file_data; | ||
| 30 | } | ||
| 31 | |||
| 32 | size_t bytes_read = fread((void *)file_data.content, 1, file_size, file); | ||
| 33 | if (bytes_read != (size_t)file_size) { | ||
| 34 | perror("Error reading file"); | ||
| 35 | free((void *)file_data.content); | ||
| 36 | file_data.content = NULL; | 8 | file_data.content = NULL; |
| 9 | file_data.count = 0; | ||
| 10 | |||
| 11 | FILE *file = fopen(file_path, "rb"); | ||
| 12 | if (file == NULL) { | ||
| 13 | perror("Error opening file"); | ||
| 14 | return file_data; | ||
| 15 | } | ||
| 16 | |||
| 17 | fseek(file, 0, SEEK_END); | ||
| 18 | long file_size = ftell(file); | ||
| 19 | fseek(file, 0, SEEK_SET); | ||
| 20 | |||
| 21 | if (file_size == -1) { | ||
| 22 | perror("Error getting file size"); | ||
| 23 | return file_data; | ||
| 24 | } | ||
| 25 | |||
| 26 | file_data.content = (const char *)malloc(file_size); | ||
| 27 | if (file_data.content == NULL) { | ||
| 28 | perror("Error allocating memory"); | ||
| 29 | return file_data; | ||
| 30 | } | ||
| 31 | |||
| 32 | size_t bytes_read = fread((void *)file_data.content, 1, file_size, file); | ||
| 33 | if (bytes_read != (size_t)file_size) { | ||
| 34 | perror("Error reading file"); | ||
| 35 | free((void *)file_data.content); | ||
| 36 | file_data.content = NULL; | ||
| 37 | return file_data; | ||
| 38 | } | ||
| 39 | |||
| 40 | file_data.count = bytes_read; | ||
| 41 | |||
| 42 | fclose(file); | ||
| 37 | return file_data; | 43 | return file_data; |
| 38 | } | ||
| 39 | |||
| 40 | file_data.count = bytes_read; | ||
| 41 | |||
| 42 | fclose(file); | ||
| 43 | return file_data; | ||
| 44 | } | 44 | } |
| @@ -4,8 +4,8 @@ | |||
| 4 | #include <stdio.h> | 4 | #include <stdio.h> |
| 5 | 5 | ||
| 6 | struct FileContent { | 6 | struct FileContent { |
| 7 | const char *content; | 7 | const char *content; |
| 8 | size_t count; | 8 | size_t count; |
| 9 | }; | 9 | }; |
| 10 | 10 | ||
| 11 | struct FileContent read_entire_file(const char *file_path); | 11 | struct FileContent read_entire_file(const char *file_path); |
| @@ -10,134 +10,133 @@ | |||
| 10 | #define DEBUG 1 | 10 | #define DEBUG 1 |
| 11 | 11 | ||
| 12 | typedef struct { | 12 | typedef struct { |
| 13 | const char *fname; | 13 | const char *fname; |
| 14 | const char *ftype; | 14 | const char *ftype; |
| 15 | const char *fparams; | 15 | const char *fparams; |
| 16 | size_t lineno; | 16 | size_t lineno; |
| 17 | } Function; | 17 | } Function; |
| 18 | 18 | ||
| 19 | const char *extract_value(TSNode captured_node, const char *source_code) { | 19 | const char *extract_value(TSNode captured_node, const char *source_code) { |
| 20 | size_t start = ts_node_start_byte(captured_node); | 20 | size_t start = ts_node_start_byte(captured_node); |
| 21 | size_t end = ts_node_end_byte(captured_node); | 21 | size_t end = ts_node_end_byte(captured_node); |
| 22 | size_t length = end - start; | 22 | size_t length = end - start; |
| 23 | char *buffer = malloc(length + 1); // +1 for the null terminator | 23 | char *buffer = malloc(length + 1); // +1 for the null terminator |
| 24 | 24 | ||
| 25 | if (buffer != NULL) { | 25 | if (buffer != NULL) { |
| 26 | snprintf(buffer, length + 1, "%.*s", (int)length, &source_code[start]); | 26 | snprintf(buffer, length + 1, "%.*s", (int)length, &source_code[start]); |
| 27 | return buffer; | 27 | return buffer; |
| 28 | } | 28 | } |
| 29 | 29 | ||
| 30 | return NULL; | 30 | return NULL; |
| 31 | } | 31 | } |
| 32 | 32 | ||
| 33 | void parse_source_file(const char *file_path, const char *source_code, TSLanguage *language) { | 33 | void parse_source_file(const char *file_path, const char *source_code, TSLanguage *language) { |
| 34 | TSParser *parser = ts_parser_new(); | 34 | TSParser *parser = ts_parser_new(); |
| 35 | ts_parser_set_language(parser, language); | 35 | ts_parser_set_language(parser, language); |
| 36 | 36 | ||
| 37 | TSTree *tree = ts_parser_parse_string(parser, NULL, source_code, strlen(source_code)); | 37 | TSTree *tree = ts_parser_parse_string(parser, NULL, source_code, strlen(source_code)); |
| 38 | TSNode root_node = ts_tree_root_node(tree); | 38 | TSNode root_node = ts_tree_root_node(tree); |
| 39 | 39 | ||
| 40 | const char *query_string = "(function_definition type: (primitive_type) @ftype declarator: (function_declarator declarator: (identifier) @fname parameters: (parameter_list) @fparams))"; | 40 | const char *query_string = "(function_definition type: (primitive_type) @ftype declarator: (function_declarator declarator: (identifier) @fname parameters: (parameter_list) @fparams))"; |
| 41 | 41 | ||
| 42 | uint32_t error_offset; | 42 | uint32_t error_offset; |
| 43 | TSQueryError error_type; | 43 | TSQueryError error_type; |
| 44 | TSQuery *query = ts_query_new(language, query_string, strlen(query_string), &error_offset, &error_type); | 44 | TSQuery *query = ts_query_new(language, query_string, strlen(query_string), &error_offset, &error_type); |
| 45 | 45 | ||
| 46 | TSQueryCursor *query_cursor = ts_query_cursor_new(); | 46 | TSQueryCursor *query_cursor = ts_query_cursor_new(); |
| 47 | ts_query_cursor_exec(query_cursor, query, root_node); | 47 | ts_query_cursor_exec(query_cursor, query, root_node); |
| 48 | 48 | ||
| 49 | if (query != NULL) { | 49 | if (query != NULL) { |
| 50 | TSQueryMatch match; | 50 | TSQueryMatch match; |
| 51 | while (ts_query_cursor_next_match(query_cursor, &match)) { | 51 | while (ts_query_cursor_next_match(query_cursor, &match)) { |
| 52 | Function fn = {0}; | 52 | Function fn = {0}; |
| 53 | 53 | ||
| 54 | for (unsigned i = 0; i < match.capture_count; i++) { | 54 | for (unsigned i = 0; i < match.capture_count; i++) { |
| 55 | TSQueryCapture capture = match.captures[i]; | 55 | TSQueryCapture capture = match.captures[i]; |
| 56 | TSNode captured_node = capture.node; | 56 | TSNode captured_node = capture.node; |
| 57 | 57 | ||
| 58 | /* fprintf(stderr, "Query: %p, Capture index: %u\n", (void *)query, capture.index); */ | 58 | /* fprintf(stderr, "Query: %p, Capture index: %u\n", (void *)query, capture.index); */ |
| 59 | 59 | ||
| 60 | uint32_t capture_name_length; | 60 | uint32_t capture_name_length; |
| 61 | const char *capture_name = ts_query_capture_name_for_id(query, capture.index, &capture_name_length); | 61 | const char *capture_name = ts_query_capture_name_for_id(query, capture.index, &capture_name_length); |
| 62 | 62 | ||
| 63 | if (strcmp(capture_name, "fname") == 0) { | 63 | if (strcmp(capture_name, "fname") == 0) { |
| 64 | fn.fname = extract_value(captured_node, source_code); | 64 | fn.fname = extract_value(captured_node, source_code); |
| 65 | 65 | ||
| 66 | TSPoint start_point = ts_node_start_point(captured_node); | 66 | TSPoint start_point = ts_node_start_point(captured_node); |
| 67 | fn.lineno = start_point.row; | 67 | fn.lineno = start_point.row; |
| 68 | } | 68 | } |
| 69 | |||
| 70 | if (strcmp(capture_name, "ftype") == 0) { | ||
| 71 | fn.ftype = extract_value(captured_node, source_code); | ||
| 72 | } | ||
| 73 | 69 | ||
| 74 | if (strcmp(capture_name, "fparams") == 0) { | 70 | if (strcmp(capture_name, "ftype") == 0) { |
| 75 | fn.fparams = extract_value(captured_node, source_code); | 71 | fn.ftype = extract_value(captured_node, source_code); |
| 76 | } | 72 | } |
| 77 | } | ||
| 78 | 73 | ||
| 79 | printf("%s:%zu\t%s %s %s\n", file_path, fn.lineno, fn.ftype, fn.fname, fn.fparams); | 74 | if (strcmp(capture_name, "fparams") == 0) { |
| 75 | fn.fparams = extract_value(captured_node, source_code); | ||
| 76 | } | ||
| 77 | } | ||
| 80 | 78 | ||
| 79 | printf("%s:%zu\t%s %s %s\n", file_path, fn.lineno, fn.ftype, fn.fname, fn.fparams); | ||
| 80 | } | ||
| 81 | } else { | ||
| 82 | if (DEBUG) { | ||
| 83 | printf("Query creation failed at offset %u with error type %d\n", error_offset, error_type); | ||
| 84 | } | ||
| 81 | } | 85 | } |
| 82 | } else { | ||
| 83 | if (DEBUG) { | ||
| 84 | printf("Query creation failed at offset %u with error type %d\n", error_offset, error_type); | ||
| 85 | } | ||
| 86 | } | ||
| 87 | 86 | ||
| 88 | ts_query_cursor_delete(query_cursor); | 87 | ts_query_cursor_delete(query_cursor); |
| 89 | ts_query_delete(query); | 88 | ts_query_delete(query); |
| 90 | ts_tree_delete(tree); | 89 | ts_tree_delete(tree); |
| 91 | ts_parser_delete(parser); | 90 | ts_parser_delete(parser); |
| 92 | } | 91 | } |
| 93 | 92 | ||
| 94 | const char *get_file_extension(const char *file_path) { | 93 | const char *get_file_extension(const char *file_path) { |
| 95 | const char *extension = strrchr(file_path, '.'); | 94 | const char *extension = strrchr(file_path, '.'); |
| 96 | if (extension != NULL) { | 95 | if (extension != NULL) { |
| 97 | return extension + 1; | 96 | return extension + 1; |
| 98 | } | 97 | } |
| 99 | return NULL; | 98 | return NULL; |
| 100 | } | 99 | } |
| 101 | 100 | ||
| 102 | int main(void) { | 101 | int main(void) { |
| 103 | const char *file_path = "examples/cmdline.c"; | 102 | const char *file_path = "examples/cmdline.c"; |
| 104 | /* const char *file_path = "examples/tabs.py"; */ | 103 | /* const char *file_path = "examples/tabs.py"; */ |
| 105 | const char *extension = get_file_extension(file_path); | 104 | const char *extension = get_file_extension(file_path); |
| 106 | 105 | ||
| 107 | TSLanguage *tree_sitter_c(void); | 106 | TSLanguage *tree_sitter_c(void); |
| 108 | TSLanguage *tree_sitter_python(void); | 107 | TSLanguage *tree_sitter_python(void); |
| 109 | 108 | ||
| 110 | struct FileContent source_file = read_entire_file(file_path); | 109 | struct FileContent source_file = read_entire_file(file_path); |
| 111 | if (source_file.content != NULL) { | 110 | if (source_file.content != NULL) { |
| 112 | if (DEBUG) { | 111 | if (DEBUG) { |
| 113 | /* fprintf(stdout, "File contents:\n%s\n", source_file.content); */ | 112 | /* fprintf(stdout, "File contents:\n%s\n", source_file.content); */ |
| 114 | /* fprintf(stdout, "Count of characters: %zu\n", source_file.count); */ | 113 | /* fprintf(stdout, "Count of characters: %zu\n", source_file.count); */ |
| 115 | } | 114 | } |
| 116 | |||
| 117 | if (extension != NULL) { | ||
| 118 | if (DEBUG) { | ||
| 119 | fprintf(stdout, "File extension: %s\n", extension); | ||
| 120 | } | ||
| 121 | 115 | ||
| 122 | if (strcmp(extension, "c") == 0) { | 116 | if (extension != NULL) { |
| 123 | parse_source_file(file_path, source_file.content, tree_sitter_c()); | 117 | if (DEBUG) { |
| 124 | } | 118 | fprintf(stdout, "File extension: %s\n", extension); |
| 119 | } | ||
| 120 | |||
| 121 | if (strcmp(extension, "c") == 0) { | ||
| 122 | parse_source_file(file_path, source_file.content, tree_sitter_c()); | ||
| 123 | } | ||
| 124 | |||
| 125 | if (strcmp(extension, "py") == 0) { | ||
| 126 | parse_source_file(file_path, source_file.content, tree_sitter_python()); | ||
| 127 | } | ||
| 128 | } else { | ||
| 129 | if (DEBUG) { | ||
| 130 | fprintf(stderr,"No file extension found.\n"); | ||
| 131 | } | ||
| 132 | } | ||
| 125 | 133 | ||
| 126 | if (strcmp(extension, "py") == 0) { | 134 | free((void *)source_file.content); |
| 127 | parse_source_file(file_path, source_file.content, tree_sitter_python()); | ||
| 128 | } | ||
| 129 | } else { | 135 | } else { |
| 130 | if (DEBUG) { | 136 | if (DEBUG) { |
| 131 | fprintf(stderr,"No file extension found.\n"); | 137 | fprintf(stderr, "Failed to read file.\n"); |
| 132 | } | 138 | } |
| 133 | } | ||
| 134 | |||
| 135 | free((void *)source_file.content); | ||
| 136 | } else { | ||
| 137 | if (DEBUG) { | ||
| 138 | fprintf(stderr, "Failed to read file.\n"); | ||
| 139 | } | 139 | } |
| 140 | } | ||
| 141 | 140 | ||
| 142 | return 0; | 141 | return 0; |
| 143 | } | 142 | } |
