Move to tabs

Author Mitja Felicijan <mitja.felicijan@gmail.com> 2023-11-13 04:44:12 +0100
Committer Mitja Felicijan <mitja.felicijan@gmail.com> 2023-11-13 04:44:12 +0100
Commit ab52e851c95ebe2fa1ee4c2a5dcbc826bbb41769 (patch)
-rw-r--r-- file.c 60
-rw-r--r-- file.h 4
-rw-r--r-- list.c 76
-rw-r--r-- list.h 4
-rw-r--r-- main.c 294
5 files changed, 219 insertions, 219 deletions
diff --git a/file.c b/file.c
...
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;
8
	file_data.content = NULL;
9
  file_data.count = 0;
9
	file_data.count = 0;
10
  
10
  
11
  FILE *file = fopen(file_path, "rb");
11
	FILE *file = fopen(file_path, "rb");
12
  if (file == NULL) {
12
	if (file == NULL) {
13
    perror("Error opening file");
13
		perror("Error opening file");
14
    return file_data;
14
		return file_data;
15
  }
15
	}
16
  
16
  
17
  fseek(file, 0, SEEK_END);
17
	fseek(file, 0, SEEK_END);
18
  long file_size = ftell(file);
18
	long file_size = ftell(file);
19
  fseek(file, 0, SEEK_SET);
19
	fseek(file, 0, SEEK_SET);
20
  
20
  
21
  if (file_size == -1) {
21
	if (file_size == -1) {
22
    perror("Error getting file size");
22
		perror("Error getting file size");
23
    return file_data;
23
		return file_data;
24
  }
24
	}
25
  
25
  
26
  file_data.content = (const char *)malloc(file_size);
26
	file_data.content = (const char *)malloc(file_size);
27
  if (file_data.content == NULL) {
27
	if (file_data.content == NULL) {
28
    perror("Error allocating memory");
28
		perror("Error allocating memory");
29
    return file_data;
29
		return file_data;
30
  }
30
	}
31
  
31
  
32
  size_t bytes_read = fread((void *)file_data.content, 1, file_size, file);
32
	size_t bytes_read = fread((void *)file_data.content, 1, file_size, file);
33
  if (bytes_read != (size_t)file_size) {
33
	if (bytes_read != (size_t)file_size) {
34
    perror("Error reading file");
34
		perror("Error reading file");
35
    free((void *)file_data.content);
35
		free((void *)file_data.content);
36
    file_data.content = NULL;
36
		file_data.content = NULL;
37
    return file_data;
37
		return file_data;
38
  }
38
	}
39
  
39
  
40
  file_data.count = bytes_read;
40
	file_data.count = bytes_read;
41
  
41
  
42
  fclose(file);
42
	fclose(file);
43
  return file_data;
43
	return file_data;
44
}
44
}
diff --git a/file.h b/file.h
...
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);
...
diff --git a/list.c b/list.c
...
7
#include "list.h"
7
#include "list.h"
8
  
8
  
9
void add_file_path(Node **head, char *file_path) {
9
void add_file_path(Node **head, char *file_path) {
10
  Node *new = (Node *)malloc(sizeof(Node));
10
	Node *new = (Node *)malloc(sizeof(Node));
11
  new->file_path = strdup(file_path);
11
	new->file_path = strdup(file_path);
12
  new->next = *head;
12
	new->next = *head;
13
  *head = new;
13
	*head = new;
14
}
14
}
15
  
15
  
16
void list_files_recursively(char *base_path, Node **head) {
16
void list_files_recursively(char *base_path, Node **head) {
17
  char path[1000];
17
	char path[1000];
18
  struct dirent *dp;
18
	struct dirent *dp;
19
  DIR *dir = opendir(base_path);
19
	DIR *dir = opendir(base_path);
20
  
20
  
21
  if (!dir) return;
21
	if (!dir) return;
22
  
22
  
23
  while ((dp = readdir(dir)) != NULL) {
23
	while ((dp = readdir(dir)) != NULL) {
24
    if (strcmp(dp->d_name, ".") != 0 && strcmp(dp->d_name, "..") != 0) {
24
		if (strcmp(dp->d_name, ".") != 0 && strcmp(dp->d_name, "..") != 0) {
25
      strcpy(path, base_path);
25
			strcpy(path, base_path);
26
      strcat(path, "/");
26
			strcat(path, "/");
27
      strcat(path, dp->d_name);
27
			strcat(path, dp->d_name);
28
  
28
  
29
      struct stat statbuf;
29
			struct stat statbuf;
30
      if (stat(path, &statbuf) != -1) {
30
			if (stat(path, &statbuf) != -1) {
31
        if (S_ISDIR(statbuf.st_mode)) {
31
				if (S_ISDIR(statbuf.st_mode)) {
32
          list_files_recursively(path, head);
32
					list_files_recursively(path, head);
33
        } else {
33
				} else {
34
          add_file_path(head, path);
34
					add_file_path(head, path);
35
        }
35
				}
36
      }
36
			}
37
    }
37
		}
38
  }
38
	}
39
  
39
  
40
  closedir(dir);
40
	closedir(dir);
41
}
41
}
42
  
42
  
43
void free_file_list(Node *head) {
43
void free_file_list(Node *head) {
44
  Node *tmp;
44
	Node *tmp;
45
  
45
  
46
  while (head != NULL) {
46
	while (head != NULL) {
47
    tmp = head;
47
		tmp = head;
48
    head = head->next;
48
		head = head->next;
49
    free(tmp->file_path);
49
		free(tmp->file_path);
50
    free(tmp);
50
		free(tmp);
51
  }
51
	}
52
}
52
}
53
  
53
  
54
int size_of_file_list(Node *head) {
54
int size_of_file_list(Node *head) {
55
  int count = 0;
55
	int count = 0;
56
  
56
  
57
  Node *current = head;
57
	Node *current = head;
58
  while (current != NULL) {
58
	while (current != NULL) {
59
    count++;
59
		count++;
60
    current = current->next;
60
		current = current->next;
61
  }
61
	}
62
  
62
  
63
  return count;
63
	return count;
64
}
64
}
diff --git a/list.h b/list.h
...
2
#define LIST_H
2
#define LIST_H
3
  
3
  
4
typedef struct node {
4
typedef struct node {
5
  char *file_path;
5
	char *file_path;
6
  struct node *next;
6
	struct node *next;
7
} Node;
7
} Node;
8
  
8
  
9
void add_file_path(Node **head, char *file_path);
9
void add_file_path(Node **head, char *file_path);
...
diff --git a/main.c b/main.c
...
23
#define DEBUG 1
23
#define DEBUG 1
24
  
24
  
25
typedef struct {
25
typedef struct {
26
  const char *fname;
26
	const char *fname;
27
  const char *ftype;
27
	const char *ftype;
28
  const char *fparams;
28
	const char *fparams;
29
  size_t lineno;
29
	size_t lineno;
30
} Function;
30
} Function;
31
  
31
  
32
const char *extract_value(TSNode captured_node, const char *source_code) {
32
const char *extract_value(TSNode captured_node, const char *source_code) {
33
  size_t start = ts_node_start_byte(captured_node);
33
	size_t start = ts_node_start_byte(captured_node);
34
  size_t end = ts_node_end_byte(captured_node);
34
	size_t end = ts_node_end_byte(captured_node);
35
  size_t length = end - start;
35
	size_t length = end - start;
36
  char *buffer = malloc(length + 1);  // +1 for the null terminator
36
	char *buffer = malloc(length + 1);  // +1 for the null terminator
37
  
37
  
38
  if (buffer != NULL) {
38
	if (buffer != NULL) {
39
    snprintf(buffer, length + 1, "%.*s", (int)length, &source_code[start]);
39
		snprintf(buffer, length + 1, "%.*s", (int)length, &source_code[start]);
40
    return buffer;
40
		return buffer;
41
  }
41
	}
42
  
42
  
43
  return NULL;
43
	return NULL;
44
}
44
}
45
  
45
  
46
char* remove_newlines(const char* str) {
46
char* remove_newlines(const char* str) {
47
  size_t length = strlen(str);
47
	size_t length = strlen(str);
48
  char* result = (char*)malloc(length + 1);  // +1 for the null terminator
48
	char* result = (char*)malloc(length + 1);  // +1 for the null terminator
49
  if (result == NULL) {
49
	if (result == NULL) {
50
    fprintf(stderr, "Memory allocation failed\n");
50
		fprintf(stderr, "Memory allocation failed\n");
51
    exit(1);
51
		exit(1);
52
  }
52
	}
53
  
53
  
54
  size_t j = 0;
54
	size_t j = 0;
55
  for (size_t i = 0; i < length; i++) {
55
	for (size_t i = 0; i < length; i++) {
56
    if (str[i] != '\n') {
56
		if (str[i] != '\n') {
57
      result[j++] = str[i];
57
			result[j++] = str[i];
58
    }
58
		}
59
  }
59
	}
60
  
60
  
61
  result[j] = '\0';
61
	result[j] = '\0';
62
  return result;
62
	return result;
63
}
63
}
64
  
64
  
65
struct ThreadArgs {
65
struct ThreadArgs {
66
  const char* file_path;
66
	const char* file_path;
67
  const char* source_code;
67
	const char* source_code;
68
  TSLanguage* language;
68
	TSLanguage* language;
69
  const char* cfname;
69
	const char* cfname;
70
};
70
};
71
  
71
  
72
// void parse_source_file(const char *file_path, const char *source_code, TSLanguage *language, const char *cfname) {
72
// void parse_source_file(const char *file_path, const char *source_code, TSLanguage *language, const char *cfname) {
73
void *parse_source_file(void *arg) {
73
void *parse_source_file(void *arg) {
74
  struct ThreadArgs* args = (struct ThreadArgs*)arg;
74
	struct ThreadArgs* args = (struct ThreadArgs*)arg;
75
  
75
  
76
  const char *file_path = args->file_path;
76
	const char *file_path = args->file_path;
77
  const char *source_code = args->source_code;
77
	const char *source_code = args->source_code;
78
  TSLanguage *language = args->language;
78
	TSLanguage *language = args->language;
79
  const char *cfname = args->cfname;
79
	const char *cfname = args->cfname;
80
  
80
  
81
  TSParser *parser = ts_parser_new();
81
	TSParser *parser = ts_parser_new();
82
  ts_parser_set_language(parser, language);
82
	ts_parser_set_language(parser, language);
83
  
83
  
84
  TSTree *tree = ts_parser_parse_string(parser, NULL, source_code, strlen(source_code));
84
	TSTree *tree = ts_parser_parse_string(parser, NULL, source_code, strlen(source_code));
85
  TSNode root_node = ts_tree_root_node(tree);
85
	TSNode root_node = ts_tree_root_node(tree);
86
  
86
  
87
  const char *query_string = "(function_definition type: (primitive_type) @ftype declarator: (function_declarator declarator: (identifier) @fname parameters: (parameter_list) @fparams))";
87
	const char *query_string = "(function_definition type: (primitive_type) @ftype declarator: (function_declarator declarator: (identifier) @fname parameters: (parameter_list) @fparams))";
88
  
88
  
89
  uint32_t error_offset;
89
	uint32_t error_offset;
90
  TSQueryError error_type;
90
	TSQueryError error_type;
91
  TSQuery *query = ts_query_new(language, query_string, strlen(query_string), &error_offset, &error_type);
91
	TSQuery *query = ts_query_new(language, query_string, strlen(query_string), &error_offset, &error_type);
92
  
92
  
93
  TSQueryCursor *query_cursor = ts_query_cursor_new();
93
	TSQueryCursor *query_cursor = ts_query_cursor_new();
94
  ts_query_cursor_exec(query_cursor, query, root_node);
94
	ts_query_cursor_exec(query_cursor, query, root_node);
95
  
95
  
96
  if (query != NULL) {
96
	if (query != NULL) {
97
    TSQueryMatch match;
97
		TSQueryMatch match;
98
    while (ts_query_cursor_next_match(query_cursor, &match)) {
98
		while (ts_query_cursor_next_match(query_cursor, &match)) {
99
      Function fn = {0};
99
			Function fn = {0};
100
  
100
  
101
      for (unsigned i = 0; i < match.capture_count; i++) {
101
			for (unsigned i = 0; i < match.capture_count; i++) {
102
        TSQueryCapture capture = match.captures[i];
102
				TSQueryCapture capture = match.captures[i];
103
        TSNode captured_node = capture.node;
103
				TSNode captured_node = capture.node;
104
  
104
  
105
        uint32_t capture_name_length;
105
				uint32_t capture_name_length;
106
        const char *capture_name = ts_query_capture_name_for_id(query, capture.index, &capture_name_length);
106
				const char *capture_name = ts_query_capture_name_for_id(query, capture.index, &capture_name_length);
107
  
107
  
108
        if (strcmp(capture_name, "fname") == 0) {
108
				if (strcmp(capture_name, "fname") == 0) {
109
          fn.fname = extract_value(captured_node, source_code);
109
					fn.fname = extract_value(captured_node, source_code);
110
  
110
  
111
          TSPoint start_point = ts_node_start_point(captured_node);
111
					TSPoint start_point = ts_node_start_point(captured_node);
112
          fn.lineno = start_point.row;
112
					fn.lineno = start_point.row;
113
        }
113
				}
114
  
114
  
115
        if (strcmp(capture_name, "ftype") == 0) {
115
				if (strcmp(capture_name, "ftype") == 0) {
116
          fn.ftype = extract_value(captured_node, source_code);
116
					fn.ftype = extract_value(captured_node, source_code);
117
        }
117
				}
118
  
118
  
119
        if (strcmp(capture_name, "fparams") == 0) {
119
				if (strcmp(capture_name, "fparams") == 0) {
120
          fn.fparams = extract_value(captured_node, source_code);
120
					fn.fparams = extract_value(captured_node, source_code);
121
        }
121
				}
122
      }
122
			}
123
  
123
  
124
      // Substring matching.
124
			// Substring matching.
125
      // FIXME: Add Levenshtein distance.
125
			// FIXME: Add Levenshtein distance.
126
      char *result = strstr(fn.fname, cfname);
126
			char *result = strstr(fn.fname, cfname);
127
      if (result != NULL) {
127
			if (result != NULL) {
128
        char *fparams_formatted = remove_newlines(fn.fparams);
128
				char *fparams_formatted = remove_newlines(fn.fparams);
129
        printf("%s:%zu:\t%s %s %s\n", file_path, fn.lineno, fn.ftype, fn.fname, fparams_formatted);
129
				printf("%s:%zu:\t%s %s %s\n", file_path, fn.lineno, fn.ftype, fn.fname, fparams_formatted);
130
      }
130
			}
131
    }
131
		}
132
  } else {
132
	} else {
133
    if (DEBUG) {
133
		if (DEBUG) {
134
      printf("Query creation failed at offset %u with error type %d\n", error_offset, error_type);
134
			printf("Query creation failed at offset %u with error type %d\n", error_offset, error_type);
135
    }
135
		}
136
  }
136
	}
137
  
137
  
138
  ts_query_cursor_delete(query_cursor);
138
	ts_query_cursor_delete(query_cursor);
139
  ts_query_delete(query);
139
	ts_query_delete(query);
140
  ts_tree_delete(tree);
140
	ts_tree_delete(tree);
141
  ts_parser_delete(parser);
141
	ts_parser_delete(parser);
142
  
142
  
143
  return NULL;
143
	return NULL;
144
}
144
}
145
  
145
  
146
const char *get_file_extension(const char *file_path) {
146
const char *get_file_extension(const char *file_path) {
147
  const char *extension = strrchr(file_path, '.');
147
	const char *extension = strrchr(file_path, '.');
148
  if (extension != NULL) {
148
	if (extension != NULL) {
149
    return extension + 1;
149
		return extension + 1;
150
  }
150
	}
151
  return NULL;
151
	return NULL;
152
}
152
}
153
  
153
  
154
int main(int argc, char *argv[]) {
154
int main(int argc, char *argv[]) {
155
  if (argc < 3) {
155
	if (argc < 3) {
156
    printf("Usage: %s <search term> <directory>\n", argv[0]);
156
		printf("Usage: %s <search term> <directory>\n", argv[0]);
157
    return 1;
157
		return 1;
158
  }
158
	}
159
  
159
  
160
  char *cfname = argv[1];
160
	char *cfname = argv[1];
161
  char *directory = argv[2];
161
	char *directory = argv[2];
162
  
162
  
163
  TSLanguage *tree_sitter_c(void);
163
	TSLanguage *tree_sitter_c(void);
164
  TSLanguage *tree_sitter_python(void);
164
	TSLanguage *tree_sitter_python(void);
165
  
165
  
166
  Node *head = NULL;
166
	Node *head = NULL;
167
  list_files_recursively(directory, &head);
167
	list_files_recursively(directory, &head);
168
  int list_size = size_of_file_list(head);
168
	int list_size = size_of_file_list(head);
169
  /* pthread_t threads[list_size]; */
169
	/* pthread_t threads[list_size]; */
170
  
170
  
171
  if (DEBUG) {
171
	if (DEBUG) {
172
    printf("Scanning %d files\n", list_size);
172
		printf("Scanning %d files\n", list_size);
173
  }
173
	}
174
  
174
  
175
  Node *current = head;
175
	Node *current = head;
176
  int thread_index = 0;
176
	//   int thread_index = 0;
177
  while (current != NULL) {
177
	while (current != NULL) {
178
    const char *file_path = current->file_path;
178
		const char *file_path = current->file_path;
179
    const char *extension = get_file_extension(file_path);
179
		const char *extension = get_file_extension(file_path);
180
    struct FileContent source_file = read_entire_file(file_path);
180
		struct FileContent source_file = read_entire_file(file_path);
181
  
181
  
182
    if (source_file.content != NULL) {
182
		if (source_file.content != NULL) {
183
      if (extension != NULL) {
183
			if (extension != NULL) {
184
        if (strcmp(extension, "c") == 0 || strcmp(extension, "h") == 0) {
184
				if (strcmp(extension, "c") == 0 || strcmp(extension, "h") == 0) {
185
          /* parse_source_file(file_path, source_file.content, tree_sitter_c(), cfname); */
185
					/* parse_source_file(file_path, source_file.content, tree_sitter_c(), cfname); */
186
  
186
  
187
          struct ThreadArgs thread_args;
187
					struct ThreadArgs thread_args;
188
          thread_args.file_path = file_path;
188
					thread_args.file_path = file_path;
189
          thread_args.source_code = source_file.content;
189
					thread_args.source_code = source_file.content;
190
          thread_args.language = tree_sitter_c();
190
					thread_args.language = tree_sitter_c();
191
          thread_args.cfname = cfname;
191
					thread_args.cfname = cfname;
192
  
192
  
193
          parse_source_file(&thread_args);
193
					parse_source_file(&thread_args);
194
  
194
  
195
          /* printf("> creating thread #%d\n", thread_index); */
195
					/* printf("> creating thread #%d\n", thread_index); */
196
          /* if (pthread_create(&threads[thread_index], NULL, parse_source_file, &thread_args) != 0) { */
196
					/* if (pthread_create(&threads[thread_index], NULL, parse_source_file, &thread_args) != 0) { */
197
          /*   fprintf(stderr, "Error creating thread %d\n", thread_index); */
197
					/*   fprintf(stderr, "Error creating thread %d\n", thread_index); */
198
          /*   return 1; */
198
					/*   return 1; */
199
          /* } */
199
					/* } */
200
        }
200
				}
201
      }
201
			}
202
      free((void *)source_file.content);
202
			free((void *)source_file.content);
203
    } else {
203
		} else {
204
      if (DEBUG) {
204
			if (DEBUG) {
205
        fprintf(stderr, "Failed to read file.\n");
205
				fprintf(stderr, "Failed to read file.\n");
206
      }
206
			}
207
    }
207
		}
208
    current = current->next;
208
		current = current->next;
209
    thread_index++;
209
		//     thread_index++;
210
  }
210
	}
211
  
211
  
212
  // Collecting threads.
212
	// Collecting threads.
213
  /* for (int i = 0; i < list_size; i++) { */
213
	/* for (int i = 0; i < list_size; i++) { */
214
  /*   printf("> collecting thread #%d\n", thread_index); */
214
	/*   printf("> collecting thread #%d\n", thread_index); */
215
  /*   if (pthread_join(threads[i], NULL) != 0) { */
215
	/*   if (pthread_join(threads[i], NULL) != 0) { */
216
  /*     fprintf(stderr, "Error joining thread %d\n", i); */
216
	/*     fprintf(stderr, "Error joining thread %d\n", i); */
217
  /*     return 1; */
217
	/*     return 1; */
218
  /*   } */
218
	/*   } */
219
  /* } */
219
	/* } */
220
  
220
  
221
  free_file_list(head);
221
	free_file_list(head);
222
  return 0;
222
	return 0;
223
}
223
}