| From bacedeb21cd30101b787838d003d686ae3036838 Mon Sep 17 00:00:00 2001 |
| From: Ray Donnelly <mingw.android@gmail.com> |
| Date: Mon, 23 Feb 2015 21:46:45 +0000 |
| Subject: [PATCH 1/9] lang: Allow both extensions and full filenames |
| |
| Because many filetypes (e.g. make) are not indicated by the |
| file extension but instead by the full filename (Makefile). |
| |
| Renames extension to pattern, but retains the existing format |
| where each pattern is treated as an extension. Full filenames |
| are indicated by prefixing the pattern with a '^'. |
| --- |
| src/lang.c | 57 ++++++++++++++++++++++++++++++++++----------------------- |
| src/lang.h | 24 +++++++++++++----------- |
| src/options.c | 26 +++++++++++++------------- |
| 3 files changed, 60 insertions(+), 47 deletions(-) |
| |
| diff --git a/src/lang.c b/src/lang.c |
| index 5ccd860..17783ae 100644 |
| --- a/src/lang.c |
| +++ b/src/lang.c |
| @@ -115,20 +115,27 @@ size_t get_lang_count() { |
| return sizeof(langs) / sizeof(lang_spec_t); |
| } |
| |
| -char *make_lang_regex(char *ext_array, size_t num_exts) { |
| +char *make_lang_regex(char *pat_array, size_t num_pats) { |
| int regex_capacity = 100; |
| char *regex = ag_malloc(regex_capacity); |
| - int regex_length = 3; |
| + int regex_length = 1; |
| int subsequent = 0; |
| - char *extension; |
| + char *pattern; |
| + const char *dot = "\\."; |
| + size_t strlen_dot = strlen(dot); |
| size_t i; |
| |
| - strcpy(regex, "\\.("); |
| + strcpy(regex, "("); |
| |
| - for (i = 0; i < num_exts; ++i) { |
| - extension = ext_array + i * SINGLE_EXT_LEN; |
| - int extension_length = strlen(extension); |
| - while (regex_length + extension_length + 3 + subsequent > regex_capacity) { |
| + for (i = 0; i < num_pats; ++i) { |
| + pattern = pat_array + i * SINGLE_PAT_LEN; |
| + int is_extension = (*pattern == '^') ? 0 : 1; |
| + int length = strlen(pattern); |
| + if (is_extension == 0) { |
| + pattern += 1; |
| + length -= 1; |
| + } |
| + while (regex_length + length + 3 + subsequent > regex_capacity) { |
| regex_capacity *= 2; |
| regex = ag_realloc(regex, regex_capacity); |
| } |
| @@ -137,8 +144,12 @@ char *make_lang_regex(char *ext_array, size_t num_exts) { |
| } else { |
| subsequent = 1; |
| } |
| - strcpy(regex + regex_length, extension); |
| - regex_length += extension_length; |
| + if (is_extension == 1) { |
| + strcpy(regex + regex_length, dot); |
| + regex_length += strlen_dot; |
| + } |
| + strcpy(regex + regex_length, pattern); |
| + regex_length += length; |
| } |
| |
| regex[regex_length++] = ')'; |
| @@ -147,29 +158,29 @@ char *make_lang_regex(char *ext_array, size_t num_exts) { |
| return regex; |
| } |
| |
| -size_t combine_file_extensions(size_t *extension_index, size_t len, char **exts) { |
| +size_t combine_file_patterns(size_t *pattern_index, size_t len, char **pats) { |
| /* Keep it fixed as 100 for the reason that if you have more than 100 |
| * file types to search, you'd better search all the files. |
| * */ |
| - size_t ext_capacity = 100; |
| - (*exts) = (char *)ag_malloc(ext_capacity * SINGLE_EXT_LEN); |
| - memset((*exts), 0, ext_capacity * SINGLE_EXT_LEN); |
| - size_t num_of_extensions = 0; |
| + size_t pat_capacity = 100; |
| + (*pats) = (char *)ag_malloc(pat_capacity * SINGLE_PAT_LEN); |
| + memset((*pats), 0, pat_capacity * SINGLE_PAT_LEN); |
| + size_t num_of_patterns = 0; |
| |
| size_t i; |
| for (i = 0; i < len; ++i) { |
| size_t j = 0; |
| - const char *ext = langs[extension_index[i]].extensions[j]; |
| + const char *pat = langs[pattern_index[i]].patterns[j]; |
| do { |
| - if (num_of_extensions == ext_capacity) { |
| + if (num_of_patterns == pat_capacity) { |
| break; |
| } |
| - char *pos = (*exts) + num_of_extensions * SINGLE_EXT_LEN; |
| - strncpy(pos, ext, strlen(ext)); |
| - ++num_of_extensions; |
| - ext = langs[extension_index[i]].extensions[++j]; |
| - } while (ext); |
| + char *pos = (*pats) + num_of_patterns * SINGLE_PAT_LEN; |
| + strncpy(pos, pat, strlen(pat)); |
| + ++num_of_patterns; |
| + pat = langs[pattern_index[i]].patterns[++j]; |
| + } while (pat); |
| } |
| |
| - return num_of_extensions; |
| + return num_of_patterns; |
| } |
| diff --git a/src/lang.h b/src/lang.h |
| index d0007f9..202da4b 100644 |
| --- a/src/lang.h |
| +++ b/src/lang.h |
| @@ -1,12 +1,12 @@ |
| #ifndef LANG_H |
| #define LANG_H |
| |
| -#define MAX_EXTENSIONS 12 |
| -#define SINGLE_EXT_LEN 20 |
| +#define MAX_PATTERNS 12 |
| +#define SINGLE_PAT_LEN 20 |
| |
| typedef struct { |
| const char *name; |
| - const char *extensions[MAX_EXTENSIONS]; |
| + const char *patterns[MAX_PATTERNS]; |
| } lang_spec_t; |
| |
| extern lang_spec_t langs[]; |
| @@ -17,20 +17,22 @@ extern lang_spec_t langs[]; |
| size_t get_lang_count(void); |
| |
| /** |
| -Convert a NULL-terminated array of language extensions |
| -into a regular expression of the form \.(extension1|extension2...)$ |
| +Convert a NULL-terminated array of language patterns |
| +into a regular expression of the form (\.?pattern1|\.?pattern2...)$ |
| +Patterns that begin with ^ are interpreted as full names, those |
| +without are interpreted as file extensions. |
| |
| Caller is responsible for freeing the returned string. |
| */ |
| -char *make_lang_regex(char *ext_array, size_t num_exts); |
| +char *make_lang_regex(char *pat_array, size_t num_pats); |
| |
| |
| /** |
| -Combine multiple file type extensions into one array. |
| +Combine multiple file type patterns into one array. |
| |
| -The combined result is returned through *exts*; |
| -*exts* is one-dimension array, which can contain up to 100 extensions; |
| -The number of extensions that *exts* actually contain is returned. |
| +The combined result is returned through *pats*; |
| +*pats* is one-dimension array, which can contain up to 100 patterns; |
| +The number of patterns that *pats* actually contain is returned. |
| */ |
| -size_t combine_file_extensions(size_t *extension_index, size_t len, char **exts); |
| +size_t combine_file_patterns(size_t *pattern_index, size_t len, char **pats); |
| #endif |
| diff --git a/src/options.c b/src/options.c |
| index dbe3e24..b8da938 100644 |
| --- a/src/options.c |
| +++ b/src/options.c |
| @@ -224,9 +224,9 @@ void parse_options(int argc, char **argv, char **base_paths[], char **paths[]) { |
| size_t longopts_len, full_len; |
| option_t *longopts; |
| char *lang_regex = NULL; |
| - size_t *ext_index = NULL; |
| - char *extensions = NULL; |
| - size_t num_exts = 0; |
| + size_t *pat_index = NULL; |
| + char *patterns = NULL; |
| + size_t num_pats = 0; |
| |
| init_options(); |
| |
| @@ -332,8 +332,8 @@ void parse_options(int argc, char **argv, char **base_paths[], char **paths[]) { |
| full_len = (longopts_len + lang_count + 1); |
| longopts = ag_malloc(full_len * sizeof(option_t)); |
| memcpy(longopts, base_longopts, sizeof(base_longopts)); |
| - ext_index = (size_t *)ag_malloc(sizeof(size_t) * lang_count); |
| - memset(ext_index, 0, sizeof(size_t) * lang_count); |
| + pat_index = (size_t *)ag_malloc(sizeof(size_t) * lang_count); |
| + memset(pat_index, 0, sizeof(size_t) * lang_count); |
| |
| for (i = 0; i < lang_count; i++) { |
| option_t opt = { langs[i].name, no_argument, NULL, 0 }; |
| @@ -580,7 +580,7 @@ void parse_options(int argc, char **argv, char **base_paths[], char **paths[]) { |
| for (i = 0; i < lang_count; i++) { |
| if (strcmp(longopts[opt_index].name, langs[i].name) == 0) { |
| has_filetype = 1; |
| - ext_index[lang_num++] = i; |
| + pat_index[lang_num++] = i; |
| break; |
| } |
| } |
| @@ -614,15 +614,15 @@ void parse_options(int argc, char **argv, char **base_paths[], char **paths[]) { |
| } |
| |
| if (has_filetype) { |
| - num_exts = combine_file_extensions(ext_index, lang_num, &extensions); |
| - lang_regex = make_lang_regex(extensions, num_exts); |
| + num_pats = combine_file_patterns(pat_index, lang_num, &patterns); |
| + lang_regex = make_lang_regex(patterns, num_pats); |
| compile_study(&opts.file_search_regex, &opts.file_search_regex_extra, lang_regex, 0, 0); |
| } |
| |
| - if (extensions) { |
| - free(extensions); |
| + if (patterns) { |
| + free(patterns); |
| } |
| - free(ext_index); |
| + free(pat_index); |
| if (lang_regex) { |
| free(lang_regex); |
| } |
| @@ -663,8 +663,8 @@ void parse_options(int argc, char **argv, char **base_paths[], char **paths[]) { |
| for (lang_index = 0; lang_index < lang_count; lang_index++) { |
| printf(" --%s\n ", langs[lang_index].name); |
| int j; |
| - for (j = 0; j < MAX_EXTENSIONS && langs[lang_index].extensions[j]; j++) { |
| - printf(" .%s", langs[lang_index].extensions[j]); |
| + for (j = 0; j < MAX_PATTERNS && langs[lang_index].patterns[j]; j++) { |
| + printf(" .%s", langs[lang_index].patterns[j]); |
| } |
| printf("\n\n"); |
| } |
| -- |
| 2.12.1 |
| |