diff options
Diffstat (limited to 'main.c')
| -rw-r--r-- | main.c | 192 |
1 files changed, 96 insertions, 96 deletions
| @@ -10,133 +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 | |||
| 37 | TSTree *tree = ts_parser_parse_string(parser, NULL, source_code, strlen(source_code)); | ||
| 38 | TSNode root_node = ts_tree_root_node(tree); | ||
| 39 | 36 | ||
| 40 | const char *query_string = "(function_definition type: (primitive_type) @ftype declarator: (function_declarator declarator: (identifier) @fname parameters: (parameter_list) @fparams))"; | 37 | TSTree *tree = ts_parser_parse_string(parser, NULL, source_code, strlen(source_code)); |
| 38 | TSNode root_node = ts_tree_root_node(tree); | ||
| 41 | 39 | ||
| 42 | uint32_t error_offset; | 40 | const char *query_string = "(function_definition type: (primitive_type) @ftype declarator: (function_declarator declarator: (identifier) @fname parameters: (parameter_list) @fparams))"; |
| 43 | TSQueryError error_type; | ||
| 44 | TSQuery *query = ts_query_new(language, query_string, strlen(query_string), &error_offset, &error_type); | ||
| 45 | 41 | ||
| 46 | TSQueryCursor *query_cursor = ts_query_cursor_new(); | 42 | uint32_t error_offset; |
| 47 | ts_query_cursor_exec(query_cursor, query, root_node); | 43 | TSQueryError error_type; |
| 44 | TSQuery *query = ts_query_new(language, query_string, strlen(query_string), &error_offset, &error_type); | ||
| 48 | 45 | ||
| 49 | if (query != NULL) { | 46 | TSQueryCursor *query_cursor = ts_query_cursor_new(); |
| 50 | TSQueryMatch match; | 47 | ts_query_cursor_exec(query_cursor, query, root_node); |
| 51 | while (ts_query_cursor_next_match(query_cursor, &match)) { | ||
| 52 | Function fn = {0}; | ||
| 53 | 48 | ||
| 54 | for (unsigned i = 0; i < match.capture_count; i++) { | 49 | if (query != NULL) { |
| 55 | TSQueryCapture capture = match.captures[i]; | 50 | TSQueryMatch match; |
| 56 | TSNode captured_node = capture.node; | 51 | while (ts_query_cursor_next_match(query_cursor, &match)) { |
| 52 | Function fn = {0}; | ||
| 57 | 53 | ||
| 58 | /* fprintf(stderr, "Query: %p, Capture index: %u\n", (void *)query, capture.index); */ | 54 | for (unsigned i = 0; i < match.capture_count; i++) { |
| 55 | TSQueryCapture capture = match.captures[i]; | ||
| 56 | TSNode captured_node = capture.node; | ||
| 59 | 57 | ||
| 60 | uint32_t capture_name_length; | 58 | /* fprintf(stderr, "Query: %p, Capture index: %u\n", (void *)query, capture.index); */ |
| 61 | const char *capture_name = ts_query_capture_name_for_id(query, capture.index, &capture_name_length); | ||
| 62 | 59 | ||
| 63 | if (strcmp(capture_name, "fname") == 0) { | 60 | uint32_t capture_name_length; |
| 64 | fn.fname = extract_value(captured_node, source_code); | 61 | const char *capture_name = ts_query_capture_name_for_id(query, capture.index, &capture_name_length); |
| 65 | 62 | ||
| 66 | TSPoint start_point = ts_node_start_point(captured_node); | 63 | if (strcmp(capture_name, "fname") == 0) { |
| 67 | fn.lineno = start_point.row; | 64 | fn.fname = extract_value(captured_node, source_code); |
| 68 | } | ||
| 69 | 65 | ||
| 70 | if (strcmp(capture_name, "ftype") == 0) { | 66 | TSPoint start_point = ts_node_start_point(captured_node); |
| 71 | fn.ftype = extract_value(captured_node, source_code); | 67 | fn.lineno = start_point.row; |
| 72 | } | 68 | } |
| 73 | |||
| 74 | if (strcmp(capture_name, "fparams") == 0) { | ||
| 75 | fn.fparams = extract_value(captured_node, source_code); | ||
| 76 | } | ||
| 77 | } | ||
| 78 | 69 | ||
| 79 | printf("%s:%zu\t%s %s %s\n", file_path, fn.lineno, fn.ftype, fn.fname, fn.fparams); | 70 | if (strcmp(capture_name, "ftype") == 0) { |
| 71 | fn.ftype = extract_value(captured_node, source_code); | ||
| 80 | } | 72 | } |
| 81 | } else { | 73 | |
| 82 | if (DEBUG) { | 74 | if (strcmp(capture_name, "fparams") == 0) { |
| 83 | printf("Query creation failed at offset %u with error type %d\n", error_offset, error_type); | 75 | fn.fparams = extract_value(captured_node, source_code); |
| 84 | } | 76 | } |
| 77 | } | ||
| 78 | |||
| 79 | printf("%s:%zu\t%s %s %s\n", file_path, fn.lineno, fn.ftype, fn.fname, fn.fparams); | ||
| 85 | } | 80 | } |
| 81 | } else { | ||
| 82 | if (DEBUG) { | ||
| 83 | printf("Query creation failed at offset %u with error type %d\n", error_offset, error_type); | ||
| 84 | } | ||
| 85 | } | ||
| 86 | 86 | ||
| 87 | ts_query_cursor_delete(query_cursor); | 87 | ts_query_cursor_delete(query_cursor); |
| 88 | ts_query_delete(query); | 88 | ts_query_delete(query); |
| 89 | ts_tree_delete(tree); | 89 | ts_tree_delete(tree); |
| 90 | ts_parser_delete(parser); | 90 | ts_parser_delete(parser); |
| 91 | } | 91 | } |
| 92 | 92 | ||
| 93 | const char *get_file_extension(const char *file_path) { | 93 | const char *get_file_extension(const char *file_path) { |
| 94 | const char *extension = strrchr(file_path, '.'); | 94 | const char *extension = strrchr(file_path, '.'); |
| 95 | if (extension != NULL) { | 95 | if (extension != NULL) { |
| 96 | return extension + 1; | 96 | return extension + 1; |
| 97 | } | 97 | } |
| 98 | return NULL; | 98 | return NULL; |
| 99 | } | 99 | } |
| 100 | 100 | ||
| 101 | int main(void) { | 101 | int main(void) { |
| 102 | const char *file_path = "examples/cmdline.c"; | 102 | const char *file_path = "examples/cmdline.c"; |
| 103 | /* const char *file_path = "examples/tabs.py"; */ | 103 | /* const char *file_path = "examples/tabs.py"; */ |
| 104 | const char *extension = get_file_extension(file_path); | 104 | const char *extension = get_file_extension(file_path); |
| 105 | 105 | ||
| 106 | TSLanguage *tree_sitter_c(void); | 106 | TSLanguage *tree_sitter_c(void); |
| 107 | TSLanguage *tree_sitter_python(void); | 107 | TSLanguage *tree_sitter_python(void); |
| 108 | 108 | ||
| 109 | struct FileContent source_file = read_entire_file(file_path); | 109 | struct FileContent source_file = read_entire_file(file_path); |
| 110 | if (source_file.content != NULL) { | 110 | if (source_file.content != NULL) { |
| 111 | if (DEBUG) { | 111 | if (DEBUG) { |
| 112 | /* fprintf(stdout, "File contents:\n%s\n", source_file.content); */ | 112 | /* fprintf(stdout, "File contents:\n%s\n", source_file.content); */ |
| 113 | /* fprintf(stdout, "Count of characters: %zu\n", source_file.count); */ | 113 | /* fprintf(stdout, "Count of characters: %zu\n", source_file.count); */ |
| 114 | } | 114 | } |
| 115 | 115 | ||
| 116 | if (extension != NULL) { | 116 | if (extension != NULL) { |
| 117 | if (DEBUG) { | 117 | if (DEBUG) { |
| 118 | fprintf(stdout, "File extension: %s\n", extension); | 118 | fprintf(stdout, "File extension: %s\n", extension); |
| 119 | } | 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 | } | ||
| 133 | 120 | ||
| 134 | free((void *)source_file.content); | 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 | } | ||
| 135 | } else { | 128 | } else { |
| 136 | if (DEBUG) { | 129 | if (DEBUG) { |
| 137 | fprintf(stderr, "Failed to read file.\n"); | 130 | fprintf(stderr,"No file extension found.\n"); |
| 138 | } | 131 | } |
| 132 | } | ||
| 133 | |||
| 134 | free((void *)source_file.content); | ||
| 135 | } else { | ||
| 136 | if (DEBUG) { | ||
| 137 | fprintf(stderr, "Failed to read file.\n"); | ||
| 139 | } | 138 | } |
| 139 | } | ||
| 140 | 140 | ||
| 141 | return 0; | 141 | return 0; |
| 142 | } | 142 | } |
