nt

Unnamed repository; edit this file 'description' to name the repository.
git clone git://edryd.org/nt
Log | Files | Refs | LICENSE

commit babb8ed59908b2afbbd16410c7e4f811a5f6951f
parent ef74744e0f03db85563567a114ba506afd074740
Author: Ed van Bruggen <edvb54@gmail.com>
Date:   Sat, 18 Mar 2017 20:17:48 -0700

Used doubly linked list to store notes

Replace the array previously used and now simply modifying the list will
cause the file to be updated. Hugely simplification of code.

Diffstat:
Makefile | 2+-
nt.c | 197++++++++++++++++++++++++++++++++++++++++++++-----------------------------------
2 files changed, 111 insertions(+), 88 deletions(-)

diff --git a/Makefile b/Makefile @@ -1,4 +1,4 @@ -# nt - create notes +# nt - simple note taker # See LICENSE file for copyright and license details. include config.mk diff --git a/nt.c b/nt.c @@ -3,6 +3,7 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <unistd.h> #include "arg.h" #include "util.h" @@ -11,11 +12,16 @@ #define MAX_SUB 2048 /* typedefs */ +typedef struct Note { + char *str; + struct Note *next; + struct Note *prev; +} Note; /* functions */ char *trimwhitespace(char *str); -void nt_new(void); +void nt_add(char *str); void nt_edit(void); void nt_del(void); void nt_search(void); @@ -27,20 +33,19 @@ void setup(void); void cleanup(void); void usage(void); -/* varibles */ +/* variables */ char *argv0; -FILE *fp; char *sub; -char **notes; -int notec; +Note *head = NULL; +Note *tail = NULL; char mode = 0; int lsnum; #include "config.h" -/* remove tailing or leading whitespace from str */ +/* remove tailing or leading white space from str */ char * trimwhitespace(char *str) { @@ -49,12 +54,12 @@ trimwhitespace(char *str) /* trim leading space */ while(isspace((unsigned char)*str)) str++; - if(*str == 0) /* all spaces? */ + if (*str == 0) /* all spaces? */ return str; /* trim trailing space */ end = str + strlen(str) - 1; - while(end > str && isspace((unsigned char)*end)) end--; + while (end > str && isspace((unsigned char)*end)) end--; /* write new null terminator */ *(end+1) = 0; @@ -64,74 +69,86 @@ trimwhitespace(char *str) /* create a new note */ void -nt_new(void) +nt_add(char *str) { - if (sub == NULL) usage(); + if (!str) usage(); + + if (!head->str && !head->next && !head->prev) { + head = ecalloc(1, sizeof(Note)); + head->str = estrdup(str); + head->next = NULL; + head->prev = NULL; + tail = head; + return; + } + + /* go through notes until we reach the last one */ + Note *cur = head; + while (cur->next) + cur = cur->next; + + /* allocate note */ + cur->next = ecalloc(1, sizeof(Note)); + cur->next->prev = cur; + cur = cur->next; + cur->str = estrdup(str); + cur->next = NULL; + tail = cur; - fprintf(fp, "%s\n", sub); } /* delete oldest matching note from notes */ void nt_del(void) { - if (sub == NULL) usage(); - - int i, found = 0; - FILE *tmpfp; - char *tmpfpext = "part"; - char *tmpfpname = ecalloc(strlen(fname)+strlen(tmpfpext)+1, sizeof(char)); - - strcpy(tmpfpname, fname); - strcat(tmpfpname, "."); - strcat(tmpfpname, tmpfpext); - tmpfp = fopen(tmpfpname, "w"); - - for (i = 0; i < notec; i++) - if (strcmp(notes[i], sub) != 0 || found) - fprintf(tmpfp, "%s\n", notes[i]); - else - found = 1; - if (!found) - die("%s: delete: '%s' not found", argv0, sub); + if (!sub) usage(); + Note *cur = head; + + for (; cur; cur = cur->next) { + if (strcmp(cur->str, sub) == 0) { + if (!cur->prev) { /* beginning */ + head = cur->next; + } else if (!cur->next) { /* end */ + cur->prev->next = NULL; + } else { /* middle */ + cur->prev->next = cur->next; + cur->next->prev = cur->prev; + } + free(cur); + return; + } + } - fclose(tmpfp); - remove(fname); - rename(tmpfpname, fname); + die("%s: delete: '%s' not found", argv0, sub); } void nt_edit() { - if (sub == NULL) usage(); - int i, found = 0; - - for (i = 0; i < notec; i++) - if (strcmp(notes[i], sub) == 0 && !found) { - fgets(notes[i], MAX_SUB, stdin); - trimwhitespace(notes[i]); - found = 1; + if (!sub) usage(); + Note *cur = head; + + for (; cur; cur = cur->next) + if (strcmp(cur->str, sub) == 0) { + fgets(cur->str, MAX_SUB, stdin); + trimwhitespace(cur->str); + return; } - if (!found) - die("%s: edit: '%s' not found", argv0, sub); - fclose(fp); - fp = fopen(fname, "w"); - for (i = 0; i < notec; i++) - fprintf(fp, "%s\n", notes[i]); - rewind(fp); + die("%s: edit: '%s' not found", argv0, sub); } /* search notes for given note */ void nt_search() { - if (sub == NULL) usage(); + if (!sub) usage(); + int found = 0; + Note *cur = head; - int i, found = 0; - for (i = 0; i < notec; i++) - if (strstr(notes[i], sub)) { - printf("%s\n", notes[i]); + for (; cur; cur = cur->next) + if (strstr(cur->str, sub)) { + printf("%s\n", cur->str); found = 1; } if (!found) @@ -142,19 +159,21 @@ nt_search() void nt_list_all(void) { - int i; - for (i = 0; i < notec; i++) - printf("%s\n", notes[i]); + Note *cur = head; + for (; cur; cur = cur->next) + if (cur->str) + printf("%s\n", cur->str); } -/* diplay n most recent subjects in file */ +/* display n most recent subjects in file */ void nt_list_n(int n) { - int i = notec; - n = n > i ? -1 : i-n-1; - for (i--; i > n; i--) - printf("%s\n", notes[i]); + int i; + Note *cur = tail; + for (i = 0; i < n && cur; cur = cur->prev, i++) + if (cur->str) + printf("%s\n", cur->str); } /* handle options and create notes */ @@ -170,53 +189,57 @@ run(void) break; case 'l': nt_list_all(); - exit(0); + break; case 'n': nt_list_n(lsnum); - exit(0); + break; case 's': nt_search(); break; default: - nt_new(); + nt_add(sub); } } -/* load fname, set notec, populate notes, allocate sub */ +/* populate notes list, allocate sub */ void setup(void) { - int c, i = 0, last = 0; - - /* open file */ - fp = fopen(fname, "ab+"); - - /* get number of notec */ - while ((c = fgetc(fp)) != EOF) { - if (c == '\n' && last != '\n') - ++notec; - last = c; + char buf[MAX_SUB]; + FILE *fp; + + head = ecalloc(1, sizeof(Note)); + tail = head; + + /* load file if it exists */ + if (access(fname, F_OK) != -1) { + fp = fopen(fname, "r"); + while (fscanf(fp, "%2048[^\n]\n", buf) != EOF) + nt_add(buf); + fclose(fp); } - rewind(fp); - - /* copy file fp to notes */ - notes = ecalloc(notec+1, sizeof(char*)); - do - notes[i] = ecalloc(MAX_SUB, sizeof(char)); - while (fscanf(fp, "%2048[^\n]\n", notes[i++]) != EOF); - rewind(fp); sub = ecalloc(MAX_SUB, sizeof(char)); + } -/* close fname, free memory */ +/* write list to file, free memory */ void cleanup(void) { + FILE *fp; + Note *cur = head; + + /* write note list to file */ + fp = fopen(fname, "w"); + for (; cur; cur = cur->next) + if (cur->str) + fprintf(fp, "%s\n", cur->str); fclose(fp); - for (int j = 0; j < notec+1; j++) - free(notes[j]); - free(notes); + + for (cur = head; cur; cur = cur->next) + free(cur->str); + free(head); free(sub); }