diff options
author | Aaron Ball <nullspoon@oper.io> | 2016-12-29 00:22:01 -0700 |
---|---|---|
committer | Aaron Ball <nullspoon@oper.io> | 2016-12-29 00:22:08 -0700 |
commit | 5df1855c71a5339f05da2e0709ee53ffee07c287 (patch) | |
tree | 02f3bf71e9b0bad6d026aa5d0612ba5ae79d6c93 | |
parent | 98715aba77ece62765634aa47675386f1966171f (diff) | |
parent | 1e8584e8cbe0181ea5a1a55f48d92be93929b0e7 (diff) | |
download | noteless-5df1855c71a5339f05da2e0709ee53ffee07c287.tar.gz noteless-5df1855c71a5339f05da2e0709ee53ffee07c287.tar.xz |
Merge branch 'list_refactor'
Signed-off-by: Aaron Ball <nullspoon@oper.io>
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | src/common.c | 18 | ||||
-rw-r--r-- | src/common.h | 2 | ||||
-rw-r--r-- | src/config.h | 2 | ||||
-rw-r--r-- | src/main.c | 131 | ||||
-rw-r--r-- | src/note.c | 53 | ||||
-rw-r--r-- | src/note.h | 27 | ||||
-rw-r--r-- | src/note_list.c | 323 | ||||
-rw-r--r-- | src/note_list.h | 38 |
9 files changed, 218 insertions, 378 deletions
@@ -5,7 +5,7 @@ warnings = -Wall -Wpedantic cc = cc all: - if [[ ! -d obj ]]; then mkdir obj; fi + if [ ! -d obj ]; then mkdir obj; fi $(cc) $(dbg) $(warnings) -std=$(std) -c src/common.c -o $(obj)common.o # $(cc) $(dbg) $(warnings) -std=$(std) -c src/path.c -o $(obj)path.o $(cc) $(dbg) $(warnings) -std=$(std) -c src/config.c -o $(obj)config.o diff --git a/src/common.c b/src/common.c index 65eb1ad..5f1ba3e 100644 --- a/src/common.c +++ b/src/common.c @@ -16,6 +16,7 @@ */ #include "common.h" + /** * Determins the text editor that should be used. Checks the environmental * variable EDITOR for this. @@ -146,7 +147,7 @@ int get_extension(char* path, char* extension) { for(int i = path_len; i > 0; i--) { // Copy if an extension delimiter (a period) is found if(path[i] == '.') { - int ext_len = path_len - i - 1; + int ext_len = path_len - i; strncpy(extension, &path[i+1], ext_len); return ext_len; } @@ -156,6 +157,20 @@ int get_extension(char* path, char* extension) { /** + * Opens a note using the specified editor + * + * @param string editor Path to the editor binary to use for editing. + * + * @return int Success or failure of the command + */ +int file_edit(char* path, char* editor) { + char cmd[strlen(editor) + 3 + strlen(path)]; + sprintf(cmd, "%s %s", editor, path); + return system(cmd); +} + + +/** * Yup, wrote my own. * TODO: Make this work with escaped path delimiters * TODO: Write this function description @@ -293,6 +308,7 @@ int str_contains_case_sensitive(char* str, char* term) { return 0; } + /** * Removes the extension from the given string filename * diff --git a/src/common.h b/src/common.h index 5a3deea..262db6b 100644 --- a/src/common.h +++ b/src/common.h @@ -30,6 +30,8 @@ void get_current_date_time(char*); int get_extension(char*, char*); +int file_edit(char*, char*); + int basename(char*, char*); int str_contains(char*, char*, int); diff --git a/src/config.h b/src/config.h index d0cc9cb..e71ccec 100644 --- a/src/config.h +++ b/src/config.h @@ -19,7 +19,7 @@ #ifndef NOTELESS_CONFIG_H #define NOTELESS_CONFIG_H #define config_line_len 120 -#define config_max 128 +#define config_max 256 #include <stdlib.h> #include <stdio.h> @@ -1,25 +1,11 @@ -/** - * Copyright (C) 2014 Aaron Ball <nullspoon@iohq.net> - * - * Noteless is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Noteless is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with noteless. If not, see <http://www.gnu.org/licenses/>. - */ -#include <stdlib.h> #include <stdio.h> +#include <stdlib.h> +#include <dirent.h> #include <string.h> -#include "common.h" -#include "config.h" + #include "note_list.h" +#include "note.h" +#include "config.h" /** * Prints the standard help text @@ -49,90 +35,69 @@ void get_help() { * * @param list Note list whos names to enumerate */ -void list_notes(note_list_t* list) { - // List notes - for(int i = 0; i < list->count; i++) { - char name[128]; - strcpy(name, list->names[i]); - strip_extension(name); - printf("* %s\n", name); +void list_notes(note_list* list) { + note* n; + + while((n = note_list_read(list)) != NULL) { + printf("* %s\n", n->name); } } /** - * Ye olde main function + * Sets up environment variables. + * Handles loading in configuration defaults before loading the config file + * values if one is present. */ -int main(int argc, char* argv[]) { - // Print helptext if no commands specified - if(argc == 1) { - printf("\nNo command specified. Printing help text.\n"); - get_help(); - return 1; - } - +void config_setup(config_t* c) { // Get the home dir char home_path[strlen(getenv("HOME"))]; strcpy(home_path, getenv("HOME")); - /** - * Config file overrides - */ - config_t c; - // Set default note path char tmp_note_path[strlen(home_path) + 17]; strcpy(tmp_note_path, home_path); strcat(tmp_note_path, "/Documents/Notes"); - config_set(&c, "note_path", tmp_note_path); + config_set(c, "note_path", tmp_note_path); // Set the default note extension - config_set(&c, "extension", "mdown"); + config_set(c, "extension", "mdown"); // Set editor default char tmp_editor[128]; get_user_editor(tmp_editor); - config_set(&c, "editor", tmp_editor); + config_set(c, "editor", tmp_editor); // Assemble the path to the conf file char conf_path[strlen(home_path) + 23]; strcpy(conf_path, home_path); strcat(conf_path, "/.config/noteless.conf"); // Load the actual config file to override any defaults - config_load(&c, conf_path); - - // Just some literal code comments - // int config_status = config_load(&c, conf_path); - // if(config_status == -1) { - // printf("Config file could not be opened or does not exist.\n"); - // printf("Assuming defaults.\n"); - // } - - - // // If the init command was passed, we want to init before checking if the - // // note path exists, otherwise the error will display and the store will - // // never be initialized. - // if( string( argv[1] ) == "init" ) { - // path p( note_path ); - // return p.create(); - // } - - // // Check to make sure the note path exists - // path p( note_path ); - // if( ! p.exists() ) { - // string out = - // "\nThe note store path '" + p.out() + "' does not exist.\n\n" - // "If this is your first time running noteless, please run " - // "'[1mnoteless init[0m' to\n" - // "create the note store here.\n\n" - // "Otherwise, please verify the path variable in your configuration."; - // cout << out << endl; - // return 1; - // } - - note_list_t list; - - note_list_new(&list, config_get(&c, "note_path"), config_get(&c, "extension")); + config_load(c, conf_path); +} + + +int main(int argc, char* argv []) { + // Print helptext if no commands specified + if(argc == 1) { + printf("\nNo command specified. Printing help text.\n"); + get_help(); + return 1; + } + + config_t c; + note_list list; + + // + // Config setup + // + config_setup(&c); + + note_list_new( + &list, + config_get(&c, "note_path"), + config_get(&c, "extension") + ); if(strcmp(argv[1], "ls") == 0 || strcmp(argv[1], "list") == 0) { list_notes(&list); @@ -161,16 +126,14 @@ int main(int argc, char* argv[]) { return note_list_cat_note(&list, argv[2]); } else if(strcmp(argv[1], "help") == 0) { get_help(); - } else if(note_list_get_note_id(&list, argv[1]) != -1 ) { - // Try to open the note if it exists - return note_list_edit(&list, config_get(&c, "editor"), argv[1]); } else { - printf("Error: Unknown command or note name '%s'.\n", argv[1]); - return 1; + int err = note_list_edit(&list, config_get(&c, "editor"), argv[1]); + if(err == 1) { + printf("%s is also not a valid command.\n", argv[1]); + return 1; + } } - // DANGER WILL ROBINSON!!! - // Clean up note_list_free(&list); config_free(&c); @@ -19,9 +19,9 @@ /** * Creates a new empty note object since no filename was specified. */ -void note_new(note_t* note, char* path) { - strcpy(note->path, path); - basename(path, note->name); +void note_new(note* n, char* path) { + strcpy(n->path, path); + basename(path, n->name); } @@ -32,24 +32,8 @@ void note_new(note_t* note, char* path) { * * @return int Success or failure of the command */ -int note_create(note_t* note, char* editor) { - return note_edit(note, editor); -} - - -/** - * Opens a note using the specified editor - * - * @param string editor Path to the editor binary to use for editing. - * - * @return int Success or failure of the command - */ -int note_edit(note_t* note, char* editor) { - char cmd[strlen(editor) + 3 + strlen(note->path)]; - strcpy(cmd, editor); - strcat(cmd, " "); - strcat(cmd, note->path); - return system(cmd); +int note_create(note* n, char* editor) { + return file_edit(n->path, editor); } @@ -60,8 +44,8 @@ int note_edit(note_t* note, char* editor) { * 0 Success * -1 File could not be opened */ -int note_cat(note_t* note) { - FILE* f = fopen(note->path, "r"); +int note_cat(note* n) { + FILE* f = fopen(n->path, "r"); // Return early if the file could not be opened if(!f) { return -1; } @@ -85,41 +69,32 @@ int note_cat(note_t* note) { * * @return int Success or failure */ -int note_rm(note_t* note) { +int note_rm(note* n) { // Verify file exists. - FILE* f = fopen(note->path, "r"); + FILE* f = fopen(n->path, "r"); if(f) { - return remove(note->path); + return remove(n->path); fclose(f); } else { return 1; } } -/** - * Gets the filename of the current note instance without its extension. - * - * @return string Note filename without extension - */ -// string note::friendly_name() { -// return name.substr( 0, name.length() - extension.length() - 1 ); -// } /** * TODO */ -int note_search(note_t* note, char* term, int case_insensitive) { - FILE* f = fopen(note->path, "r"); +int note_search(note* n, char* term, int case_insensitive) { + FILE* f = fopen(n->path, "r"); char buf[file_width]; - int line_num = 0; + int line_num = 1; while((fgets(buf, file_width, f)) != NULL) { if(str_contains(buf, term, case_insensitive) == 1) { - printf("%s: %02d: %s", note->name, line_num, buf); + printf("%s: % 4d: %s", n->name, line_num, buf); } line_num++; } fclose(f); return 0; } - @@ -17,39 +17,30 @@ #include <stdlib.h> #include <stdio.h> #include <string.h> + #include "common.h" -//#include "path.h" #ifndef noteless_note_h #define noteless_note_h #define file_width 256 -typedef struct note { +typedef struct { char extension[32]; char path[256]; char name[256]; -} note_t; - -void note_new(note_t*, char*); - -int note_create(note_t*, char*); +} note; -int note_edit(note_t*, char*); +void note_new(note*, char*); -int note_cat(note_t*); +int note_create(note*, char*); -int note_rm(note_t*); +int note_edit(note*, char*); -int note_search(note_t*, char*, int); +int note_cat(note*); +int note_rm(note*); - -/** - * C++ code - */ -//vector<string> body; -//string friendly_name(); -//string get_fqp(); +int note_search(note*, char*, int); #endif diff --git a/src/note_list.c b/src/note_list.c index ed277ad..19727bb 100644 --- a/src/note_list.c +++ b/src/note_list.c @@ -19,241 +19,155 @@ /** * Constructor * - * @param list List to be instantiated + * @param list List stream to be instantiated * @param path Path to the treasure... er... notes * @param ext Extension of the notes to pay attention to */ -void note_list_new(note_list_t* list, char* path, char* ext) { - list->count = 0; - strcpy(list->extension, ext); +int note_list_new(note_list* list, char* path, char* ext) { + list->cursor = 0; + // Open the dir fd + list->dirp = opendir(path); + list->noteent = malloc(sizeof(note)); strcpy(list->path, path); + strcpy(list->ext, ext); - DIR* d = opendir(path); - struct dirent* ent; + // Skip the first two, as they are always . and .. + readdir(list->dirp); + readdir(list->dirp); - int ext_len = strlen(ext); - - // First iterration to get a matching file count - while((ent = readdir(d))) { - // The start index of the extension in the current filename - int ext_start = strlen(ent->d_name) - ext_len; - - if(strncmp(&ent->d_name[ext_start], ext, ext_len) == 0) { - list->count++; - } - } + return 0; +} - // Create name list of previously discovered size - list->names = malloc(sizeof(char*) * list->count); - rewinddir(d); - int i = 0; - // Second iterration for populating the file list - while((ent = readdir(d))) { - // The start index of the extension in the current filename - int ext_start = strlen(ent->d_name) - ext_len; +void note_list_free(note_list* list) { + closedir(list->dirp); +} - // If the current file's extension matches the list extension... - if(strncmp(&ent->d_name[ext_start], ext, ext_len) == 0) { - // Allocate space for the entire filename (we'll strip the extension off - // as needed later). This will make calculating path lengths much - // simpler. - list->names[i] = malloc(sizeof(char) * (strlen(ent->d_name) + 1)); - // Copy the filename into the struct - strcpy(list->names[i], ent->d_name); +note* note_list_read(note_list* list) { + struct dirent* de; + char fext[64]; - i++; - } - } + // Iterrate over dir entities + while(1) { + // Return null if readdir also returns null + if((de = readdir(list->dirp)) == NULL) { return NULL; } + // Skip any non-regular files (DT_REG == 8) + if(de->d_type != 8) { continue; } + // Skip hidden files + if(de->d_name[0] == '.') { continue; } - closedir(d); -} + // Skip files that don't match the specified extension + get_extension(de->d_name, fext); + if(strcmp(fext, list->ext) != 0) { continue; } - -void note_list_free(note_list_t* list) { - for(int i = 0; i < list->count; i++) { - free(list->names[i]); + break; } - free(list->names); -} - -// void note_list::get_notes( string base, string ext, string sub ) { -// // Dir pointer -// DIR* dp; -// -// string search_dir = base; -// // Append the subdir if necessary -// if( sub != "" ) { -// // Open the subdir if it's specified -// search_dir = base + "/" + sub; -// } -// dp = opendir( search_dir.c_str() ); -// -// if( dp ) { -// // Prepare to iterrate through dir items -// struct dirent* item; -// while( item = readdir( dp ) ) { -// string name = item->d_name; -// -// path p( base + "/" + sub + "/" + name ); -// -// if( name[0] != '.' ) { -// if( p.is_dir() == 1 ) { -// // TODO -// // I really hate the way I'm doing this repeatedly. Going to need a -// // better way. -// if( sub != "" ) { -// get_notes( base, ext, sub + "/" + name ); -// } else { -// get_notes( base, ext, name ); -// } -// } else { -// // This will be replaced later with path.join() when it's implemented -// if( sub != "" ) { -// add( base, sub + "/" + name ); -// } else { -// add( base, name ); -// } -// } -// } -// } -// closedir( dp ); -// } -// } + // Copy in the path + sprintf(list->noteent->path, "%s/%s", list->path, de->d_name); + // Copy in the extension + strcpy(list->noteent->extension, fext); + // Copy in the filename + strcpy(list->noteent->name, de->d_name); + // Overwrite . with null byte + list->noteent->name[strlen(de->d_name) - strlen(fext) - 1] = '\0'; + + // Increment the file counter + ++list->cursor; + return list->noteent; +} /** - * Adds a new note item to the list by path. - * - * @param string path Path to the note to be added to the list + * Opens the specified note for editing * - * @return 0 + * @param list Note list the note-to-be-edited belongs to + * @param editor Path to the editor to use for editing + * @param term Search term */ -// int note_list::add( string base, string name ) { -// note n( base, name ); -// notes.push_back( n ); -// return 0; -// } - +int note_list_edit(note_list* list, char* editor, char* term) { + note* n; -/** - * Opens a new note for editing - * - * @param string editor Path to the editor to use for editing - * @param string note_name Name of the note to be created and edited - * - * @return int Success or failure (always success for now) - */ -int note_list_create_note(note_list_t* list, char* editor, char* note_name) { - char tmp_note_name[64]; - strcpy(tmp_note_name, note_name); - strcat(tmp_note_name, "."); - strcat(tmp_note_name, list->extension); + while(1) { + n = note_list_read(list); + if(n == NULL) { break; } - // Check if note already exists - for(int i = 0; i < list->count; i++) { - if(strcmp(list->names[i], tmp_note_name) == 0) { - return 1; + if(strncmp(n->name, term, strlen(term)) == 0) { + file_edit(n->path, editor); + return 0; } } - // Construct full note path - char note_path[256]; - strcpy(note_path, list->path); - strcat(note_path, "/"); - strcat(note_path, tmp_note_name); - - note_t note; - note_new(¬e, note_path); - note_edit(¬e, editor); - - return 0; + printf("No notes exist that match the search term '%s'.\n", term); + return 1; } /** - * Opens the specified note for editing + * Opens a new note for editing * - * @param list Note list the note-to-be-edited belongs to - * @param editor Path to the editor to use for editing - * @param note_name Name of the note to be edited + * @param string editor Path to the editor to use for editing + * @param string note_name Name of the note to be created and edited + * + * @return int Success or failure (always success for now) */ -int note_list_edit(note_list_t* list, char* editor, char* note_name) { - int id = note_list_get_note_id(list, note_name); - if(id != -1) { - // Construct the note path - // It's safe to assume 256 here since various other path variables also - // limit to 256. - char path[256]; - strcpy(path, list->path); - strcat(path, "/"); - strcat(path, list->names[id]); +int note_list_create_note(note_list* list, char* editor, char* name) { + char fullname[128]; + char fullpath[256]; + note* n; - note_t note; - note_new(¬e, path); - note_edit(¬e, editor); - } else { - printf("Note '%s' does not exist.\n", note_name); - return 1; + // Create full file name + sprintf(fullname, "%s.%s", name, list->ext); + + // Check if note already exists + while((n = note_list_read(list)) != NULL) { + if(strcmp(n->name, fullname) == 0) { return 1; } } + + // Construct full note path for the new note + sprintf(fullpath, "%s/%s", list->path, fullname); + file_edit(fullpath, editor); return 0; } /** - * Searches all note *names* (friendly and unfriendly) for the given name and - * returns the note id (not necissarily persistent). If note does not exist, - * returns -1. Can be used for a sort of "note_exists" method as such. - * - * Note that this does a partial comparison, so only the number of characters - * passed for note_name is the number compared, thus allowing for fuzzy-ish - * name matching. This will return the id of the first matched note name. + * Returns the contents of the requested note * - * @param list Note list to search for the given note [partial] name - * @param note_name Name of the note to search for + * @param string note_name Name of the note to get the contents for * - * @return int The integer of the note. -1 if note does not exist + * @return vector<string> Contents of the note, broken per line into a vector. */ -int note_list_get_note_id(note_list_t* list, char* note_name) { - for(int i = 0; i < list->count; i++) { - if(strncmp(list->names[i], note_name, strlen(note_name)) == 0) { - return i; +int note_list_cat_note(note_list* list, char* term) { + note* n; + // Check for the requested note + while((n = note_list_read(list)) != NULL) { + if(strncmp(n->name, term, strlen(term)) == 0) { + note_cat(n); + return 0; } } - return -1; + return 1; } /** - * Returns the contents of the requested note - * - * @param string note_name Name of the note to get the contents for - * - * @return vector<string> Contents of the note, broken per line into a vector. + * 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_cat_note(note_list_t* list, char* note_name) { - // Check for the requested note - int id = note_list_get_note_id(list, note_name); - if(id != -1) { - // Construct the full note path - char path[strlen(list->path) + strlen(list->names[id]) + 3]; - strcpy(path, list->path); - strcat(path, "/"); - strcat(path, list->names[id]); - - note_t note; - note_new(¬e, path); +int note_list_search(note_list* list, char* term, int case_insensitive) { + note* n; - // Read in the note's contents - note_cat(¬e); - } else { - return 1; + while((n = note_list_read(list)) != NULL) { + note_search(n, term, case_insensitive); } return 0; } + /** * Deletes the specified note * @@ -261,45 +175,14 @@ int note_list_cat_note(note_list_t* list, char* note_name) { * * @return int Exit code (1 = error, 0 = success) */ -int note_list_rm_note(note_list_t* list, char* note_name) { - int id = note_list_get_note_id(list, note_name); - if(id == -1) { - printf("Error: There is no note matching \"%s\".\n", note_name); - return 1; - } else { - char note_path[256] = ""; - strcpy(note_path, list->path); - strcat(note_path, "/"); - strcat(note_path, list->names[id]); +int note_list_rm_note(note_list* list, char* name) { + note* n; - note_t note; - note_new(¬e, note_path); - return note_rm(¬e); + while((n = note_list_read(list)) != NULL) { + if(strncmp(n->name, name, strlen(name)) == 0) { + return note_rm(n); + } } - return 0; + return 1; } - -/** - * 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_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 d393a80..524e689 100644 --- a/src/note_list.h +++ b/src/note_list.h @@ -18,32 +18,42 @@ #include <dirent.h> #include <stdio.h> #include <string.h> + +#include "common.h" #include "note.h" #ifndef noteless_note_list_h #define noteless_note_list_h -typedef struct note_list { - char path[256]; - char extension[32]; - char** names; - int count; -} note_list_t; +typedef struct { + DIR* dirp; + note* noteent; + char path[256]; + char ext[64]; + int cursor; +} note_list; + +//typedef struct note_list{ +// DIR* dirp; +// char path[256]; +// char ext[64]; +// int cursor; +//} note_list; -void note_list_new(note_list_t*, char*, char*); +int note_list_new(note_list*, char*, char*); -void note_list_free(note_list_t*); +void note_list_free(note_list*); -int note_list_edit(note_list_t*, char*, char*); +note* note_list_read(note_list*); -int note_list_get_note_id(note_list_t*, char*); +int note_list_edit(note_list*, char*, char*); -int note_list_cat_note(note_list_t*, char*); +int note_list_create_note(note_list*, char*, char*); -int note_list_create_note(note_list_t*, char*, char*); +int note_list_cat_note(note_list*, char*); -int note_list_rm_note(note_list_t*, char*); +int note_list_search(note_list*, char*, int); -int note_list_search(note_list_t*, char*, int); +int note_list_rm_note(note_list*, char*); #endif |