diff options
author | Qball Cow <qball@gmpclient.org> | 2014-05-13 10:45:59 +0200 |
---|---|---|
committer | Qball Cow <qball@gmpclient.org> | 2014-05-13 10:45:59 +0200 |
commit | 87b51f5430bf0f4a4abeea5235618d4b0fba8e80 (patch) | |
tree | f8a95e1a7a7d626c8693d965a3b7d223a87af4e7 /source/history.c | |
parent | db9bb13111e1fbb191e8bf073d28315d8798c92d (diff) |
Extract out the history code and create functions for it.
(Easier to fix issues later on)
Diffstat (limited to 'source/history.c')
-rw-r--r-- | source/history.c | 256 |
1 files changed, 256 insertions, 0 deletions
diff --git a/source/history.c b/source/history.c new file mode 100644 index 00000000..5eda4773 --- /dev/null +++ b/source/history.c @@ -0,0 +1,256 @@ +/** + * rofi + * + * MIT/X11 License + * Copyright 2013-2014 Qball Cow <qball@gmpclient.org> + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <unistd.h> +#include <sys/types.h> +#include <errno.h> +#include "rofi.h" +#include "history.h" + +#define HISTORY_NAME_LENGTH 256 +#define HISTORY_MAX_ENTRIES 25 + +typedef struct __element +{ + long int index; + char name[HISTORY_NAME_LENGTH]; +}_element; + +static int __element_sort_func ( const void *ea, const void *eb ) +{ + _element *a = *(_element * *) ea; + _element *b = *(_element * *) eb; + return b->index - a->index; +} + +static void __history_write_element_list( FILE *fd, _element **list, unsigned int length) +{ + if(list == NULL) { + return; + } + // Sort the list before writing out. + qsort ( list, length, sizeof ( _element* ), __element_sort_func ); + + // Set the max length of the list. + length = (length > HISTORY_MAX_ENTRIES)? HISTORY_MAX_ENTRIES:length; + + // Write out entries. + for(unsigned int iter = 0; iter < length ;iter++) + { + fprintf(fd , "%ld %s\n", list[iter]->index, list[iter]->name); + } +} + +static _element ** __history_get_element_list ( FILE *fd, unsigned int *length ) +{ + _element **retv = NULL; + + if (length == NULL) + { + return NULL; + } + *length = 0; + + if( fd == NULL) + { + return NULL; + } + char buffer[HISTORY_NAME_LENGTH+16]; + while ( fgets (buffer, HISTORY_NAME_LENGTH+16, fd ) != NULL) + { + // Skip empty lines. + if ( strlen ( buffer ) == 0 ) + { + continue; + } + retv = reallocate ( retv, ( *length + 2 ) * sizeof ( _element* ) ); + retv[(*length)] = allocate ( sizeof ( _element ) ); + // remove trailing \n + buffer[strlen ( buffer ) - 1] = '\0'; + // Parse the number of times. + char * start = NULL; + retv[(*length)]->index = strtol ( buffer, &start, 10 ); + strncpy(retv[(*length)]->name, (start+1),HISTORY_NAME_LENGTH); + // Force trailing '\0' + retv[(*length)]->name[HISTORY_NAME_LENGTH-1] = '\0'; + retv[(*length) + 1] = NULL; + + (*length)++; + } + return retv; +} + + +void history_set ( const char *filename, const char *entry ) +{ + int found = 0; + unsigned int curr = 0; + unsigned int length = 0; + // Open file for reading and writing. + FILE *fd = fopen(filename, "a+"); + if(fd == NULL) + { + fprintf(stderr, "Failed to open file: %s\n", strerror(errno)); + return ; + } + // Get list. + _element ** list = __history_get_element_list(fd, &length); + + // Look if the entry exists. + for(unsigned int iter = 0;!found && iter < length; iter++) + { + if(strcmp(list[iter]->name, entry) == 0) + { + curr = iter; + found = 1; + } + } + + if(found) { + // If exists, increment list index number + list[curr]->index++; + }else{ + // If not exists, add it. + // Increase list by one + list = reallocate(list,(length+2)*sizeof(_element *)); + list[length] = allocate(sizeof(_element)); + // Copy name + strncpy(list[length]->name, entry, HISTORY_NAME_LENGTH); + list[length]->name[HISTORY_NAME_LENGTH-1] = '\0'; + // set # hits + list[length]->index = 1; + + length++; + list[length] = NULL; + } + + // Rewind. + fseek(fd, 0L, SEEK_SET); + // Clear file. + ftruncate(fileno(fd), 0); + + // Write list. + __history_write_element_list(fd, list, length); + + + // Free the list. + for(unsigned int iter = 0; iter < length; iter++) + { + if(list[iter] != NULL) { free(list[iter]); } + } + if(list != NULL) free(list); + // Close file. + fclose(fd); +} + +void history_remove ( const char *filename, const char *entry ) +{ + int found = 0; + unsigned int curr = 0; + unsigned int length = 0; + // Open file for reading and writing. + FILE *fd = fopen(filename, "a+"); + if(fd == NULL) + { + fprintf(stderr, "Failed to open file: %s\n", strerror(errno)); + return ; + } + // Get list. + _element ** list = __history_get_element_list(fd, &length); + + // Find entry. + for(unsigned int iter = 0;!found && iter < length; iter++) + { + if(strcmp(list[iter]->name, entry) == 0) + { + curr = iter; + found = 1; + } + } + + // If found, remove it and write out new file. + if(found) { + // Remove the entry. + free(list[curr]); + // Swap last to here (if list is size 1, we just swap empty sets). + list[curr] = list[length-1]; + // Empty last. + list[length-1] = NULL; + length--; + + // Rewind. + fseek(fd, 0L, SEEK_SET); + // Clear list. + ftruncate(fileno(fd), 0); + + // Write list. + __history_write_element_list(fd, list, length); + } + + // Free the list. + for(unsigned int iter = 0; iter < length; iter++) + { + if(list[iter] != NULL) { free(list[iter]); } + } + if(list != NULL) free(list); + // Close file. + fclose(fd); +} + +char ** history_get_list ( const char *filename, unsigned int *length ) +{ + char **retv = NULL; + // Open file. + FILE *fd = fopen(filename, "r"); + if(fd == NULL) + { + if(errno != ENOENT) { + fprintf(stderr, "Failed to open file: %s\n", strerror(errno)); + } + return NULL; + } + // Get list. + _element ** list = __history_get_element_list(fd, length); + + // Copy list in right format. + if((*length) > 0 ) + { + retv = allocate(((*length)+1)*sizeof(char *)); + for ( int iter = 0; iter < (*length); iter++) + { + retv[iter] = strdup(list[iter]->name); + free(list[iter]); + } + retv[(*length)] = NULL; + free(list); + } + + fclose(fd); + return retv; +} |