diff options
-rw-r--r-- | README.md | 3 | ||||
-rw-r--r-- | src/common.c | 118 | ||||
-rw-r--r-- | src/common.h | 6 | ||||
-rw-r--r-- | src/main.c | 7 | ||||
-rw-r--r-- | src/note.c | 87 | ||||
-rw-r--r-- | src/note.h | 6 | ||||
-rw-r--r-- | src/note_list.c | 34 | ||||
-rw-r--r-- | src/note_list.h | 3 |
8 files changed, 172 insertions, 92 deletions
@@ -28,6 +28,9 @@ there), add ~/bin to your path, and you should be good to go. * **cat**: Outputs the specified note's contents verbatim. * **new**: Creates the specified note and opens for editing. * **edit**: Opens the specified note for editing. +* **find**: Performs a case insensitive search of all notes, displaying only + the lines that match along with their line numbers and files from which + they came. * **ls**: Lists all notes * **help**: Displays the help text. * **rm**: Deletes the specified note diff --git a/src/common.c b/src/common.c index 55149a7..5ec2af5 100644 --- a/src/common.c +++ b/src/common.c @@ -174,3 +174,121 @@ int basename(char* path, char* out) { } return -1; } + + +/** + * Just a wrapper function to call the specified line search function for case + * insensitive or case sensitive matching. + * + * @param line Line to check for the search term + * @param term Search term to find in line + * + * @return int Search term found (1) or not (0) + */ +int str_contains(char* line, char* term, int case_insensitive) { + if(case_insensitive == 1) { + return str_contains_case_insensitive(line, term); + } else { + return str_contains_case_sensitive(line, term); + } +} + + +/** + * Performs a case insensitive search in the given line for the specified term. + * + * Note that for the sake of efficiency, this function is fairly confusing + * (sorry). Learning how chars and ints relate in c will help tremendously + * to understand this function. + * + * @param str String to check for the search term + * @param term Search term to find in line + * + * @return int Search term found (1) or not (0) + */ +int str_contains_case_insensitive(char* str, char* term) { + // String char index + int si = 0; + // Term char index + int ti = 0; + int term_len = strlen(term); + + // Compare one char at a time + while(str[si] != '\0') { + // Current str char + char lc; + // Current term char + char tc; + + // Welcome to the confusing part (see function description) + + // Convert current term char to lowercase + if(term[ti] >= 97 && term[ti] <= 122) { + // Already lower case + tc = term[ti]; + } else if(term[ti] >= 65 && term[ti] <= 90) { + // Uppercase. Add 32 to get lowercase equivelant. + tc = term[ti] + 32; + } else { + // Term char isn't a letter. Must be a symbol or something ELSE... + // Take it as it is. + tc = term[ti]; + } + + // Convert current str char to lowercase + if(str[si] >= 97 && str[si] <= 122) { + // Already lower case + lc = str[si]; + } else if(str[si] >= 65 && str[si] <= 90) { + // Uppercase. Add 32 to get lowercase equivelant. + lc = str[si] + 32; + } else { + // Term char isn't a letter. Must be a symbol or something ELSE... + // Take it as it is. + lc = str[si]; + } + + // Compare the temp lowercase version of the current str and term chars + if(lc == tc) { + ti++; + } else { + ti = 0; + } + + // Return if we've matched the entire search term + if(ti == term_len) { return 1; } + + si++; + } + return 0; +} + + +/** + * Performs a case sensitive search in the given string for the specified term. + * + * @param str String to check for the search term + * @param term Search term to find in str + * + * @return int Search term found (1) or not (0) + */ +int str_contains_case_sensitive(char* str, char* term) { + int s = 0; + int t = 0; + int term_len = strlen(term); + + // Compare one char at a time + while(str[s] != '\0') { + if(t == term_len) { + return 1; + } else if(term[t] == str[s]) { + // Found a single char match. Increment to the next term char + t++; + } else { + // Reset the match counter if a partial or no match was made + t = 0; + } + s++; + } + return 0; +} diff --git a/src/common.h b/src/common.h index 6fb5ed1..c462a80 100644 --- a/src/common.h +++ b/src/common.h @@ -32,4 +32,10 @@ int get_extension(char*, char*); int basename(char*, char*); +int str_contains(char*, char*, int); + +int str_contains_case_sensitive(char*, char*); + +int str_contains_case_insensitive(char*, char*); + #endif @@ -37,7 +37,7 @@ void get_help() { " cat <note> Outputs the specified note's contents verbatim.\n" " new <note> Creates the specified note and opens for editing.\n" " edit <note> Opens the specified note for editing.\n" - //" find <term> Performs a case-insensitive search of all notes for the\n" + " find <term> Performs a case-insensitive search of all notes for the\n" " rm <note> Deletes the specified note.\n" " given search term.\n" " help Displays this help text\n" @@ -179,9 +179,8 @@ int main(int argc, char* argv[]) { printf("Error: Failed deleting note matching \"%s\".\n", argv[2]); } return rm_status; - // } else if( arg == "find" ) { - // string term = argv[i + 1]; - // return search_notes( list, term ); + } else if(strcmp(argv[1], "find") == 0) { + return note_list_search(&list, argv[2], 1); } else if(strcmp(argv[1], "cat") == 0) { return note_list_cat_note(&list, argv[2]); } else if(strcmp(argv[1], "help") == 0) { @@ -107,77 +107,18 @@ int note_rm(note_t* note) { /** * TODO */ -// vector<string> note::find( bool case_sensitive, string term ) { -// vector<string> lines; -// -// // Memory for storing matched lines -// vector<string> matches; -// -// // Read the notes contents into memory -// read(); -// -// for( int i = 0; i < body.size(); i++ ) { -// if( line_matches( body[i], term ) == true ) { -// // Format the output -// string out = friendly_name() + ": " + itos( i ); -// out += ": " + body[i]; -// // Add to the match list -// matches.push_back( out ); -// } -// } -// return matches; -// } +int note_search(note_t* note, char* term, int case_insensitive) { + FILE* f = fopen(note->path, "r"); + + char buf[file_width]; + int line_num = 0; + while((fgets(buf, file_width, f)) != NULL) { + if(str_contains(buf, term, case_insensitive) == 1) { + printf("%s: %02d: %s\n", note->name, line_num, buf); + } + line_num++; + } + fclose(f); + return 0; +} -/** - * Performs a char by char comparison of a line and a search term. If the - * search term is found anywhere within the line even once, returns true; - * Otherwise, returns false. - * - * @param string line The line of text to search - * @param string term The search term - * - * @return bool Whether or not the search term was found in the line - */ -// bool note::line_matches( string line, string term ) { -// // Define the two long arrays -// long line_l[line.size()]; -// long term_l[term.size()]; -// -// // Convert the line to a long array -// for( int i = 0; i < line.size(); i++ ) { line_l[i] = line[i]; } -// -// // Convert the search term to a long array -// for( int i = 0; i < term.size(); i++ ) { term_l[i] = term[i]; } -// -// -// // Iterrate through each letter in the line -// for( int l = 0; l < line.size(); l++ ) { -// // Iterrate through the search term -// for( int t = 0; t < term.size(); t++ ) { -// if( term_l[t] >= 97 && term_l[t] <= 122 ) { -// // Term char is lower. Compare down then up -// if( line_l[l] != term_l[t] -// && line_l[l] != term_l[t] - 32 ) { -// break; -// } -// } else if( term_l[t] >= 65 && term_l[t] <= 90 ) { -// // Term char is upper. Compare up then down -// if( line_l[l] != term_l[t] -// && line_l[l] != term_l[t] + 32 ) { -// break; -// } -// } else { -// // Term char isn't a letter. Must be a symbol or something ELSE... -// // Teehee -// if( line_l[l] != term_l[t] ) { break; } -// } -// -// // Increment the line letter to check the next one on the next search -// // term letter loop -// l++; -// // If we reach the end of the search term, match! -// if( t == term.size() - 1 ) { return true; } -// } -// } -// return false; -// e @@ -23,6 +23,8 @@ #ifndef noteless_note_h #define noteless_note_h +#define file_width 256 + typedef struct note { char extension[32]; char path[256]; @@ -39,7 +41,8 @@ int note_cat(note_t*); int note_rm(note_t*); -int line_matches(char*, char*); +int note_search(note_t*, char*, int); + /** @@ -48,6 +51,5 @@ int line_matches(char*, char*); //vector<string> body; //string friendly_name(); //string get_fqp(); -//vector<string> find( bool, string ); #endif diff --git a/src/note_list.c b/src/note_list.c index 6ddb47a..ed277ad 100644 --- a/src/note_list.c +++ b/src/note_list.c @@ -279,17 +279,27 @@ int note_list_rm_note(note_list_t* list, char* note_name) { return 0; } + /** - * TODO + * Searches each note in the list for the given search term. + * + * @return int Number of instances found in all notes + * TODO: This needs to be written still */ -// int note_list_find(note_list_t* list, int case_sensitive, char* term ) { -// for(int i = 0; i < notes.size(); i++) { -// vector<string> note_matches = notes[i].find( case_sensitive, term ); -// if( note_matches.size() > 0 ) { -// for( int m = 0; m < note_matches.size(); m++ ) { -// matches.push_back( note_matches[m] ); -// } -// } -// } -// return matches; -// } +int note_list_search(note_list_t* list, char* term, int case_insensitive) { + for(int i = 0; i < list->count; i++) { + // TODO: My gosh this section of code needs to be turned into a function. + // I've written this far too many times. + // Construct note path + char path[256] = ""; + strcpy(path, list->path); + strcat(path, "/"); + strcat(path, list->names[i]); + + note_t note; + note_new(¬e, path); + + note_search(¬e, term, case_insensitive); + } + return 0; +} diff --git a/src/note_list.h b/src/note_list.h index a6822db..76e7829 100644 --- a/src/note_list.h +++ b/src/note_list.h @@ -45,11 +45,12 @@ int note_list_create_note(note_list_t*, char*, char*); int note_list_rm_note(note_list_t*, char*); +int note_list_search(note_list_t*, char*, int); + // void get_notes(note_list_t*); // note_list( string, string ); // int add( string, string ); // vector<string> enum_names(); -// vector<string> find( bool, string ); #endif |