diff options
author | James Booth <boothj5@gmail.com> | 2013-02-02 21:43:59 +0000 |
---|---|---|
committer | James Booth <boothj5@gmail.com> | 2013-02-02 21:43:59 +0000 |
commit | 740e5b422832f8d043d96f33a0d33bf1725dbbc0 (patch) | |
tree | e28525525de760b696bfd4f7dbb326334db8ee29 /src/tools | |
parent | fc5bfb7d33dc6e1a6a53c46d414df4f9324f6ad5 (diff) | |
download | profani-tty-740e5b422832f8d043d96f33a0d33bf1725dbbc0.tar.gz |
Added command and tools subdirs to source
Diffstat (limited to 'src/tools')
-rw-r--r-- | src/tools/autocomplete.c | 224 | ||||
-rw-r--r-- | src/tools/autocomplete.h | 45 | ||||
-rw-r--r-- | src/tools/history.c | 267 | ||||
-rw-r--r-- | src/tools/history.h | 33 | ||||
-rw-r--r-- | src/tools/tinyurl.c | 88 | ||||
-rw-r--r-- | src/tools/tinyurl.h | 31 |
6 files changed, 688 insertions, 0 deletions
diff --git a/src/tools/autocomplete.c b/src/tools/autocomplete.c new file mode 100644 index 00000000..baeeecb2 --- /dev/null +++ b/src/tools/autocomplete.c @@ -0,0 +1,224 @@ +/* + * autocomplete.c + * + * Copyright (C) 2012, 2013 James Booth <boothj5@gmail.com> + * + * This file is part of Profanity. + * + * Profanity 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. + * + * Profanity 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 Profanity. If not, see <http://www.gnu.org/licenses/>. + * + */ + +#include <stdlib.h> +#include <string.h> + +#include "autocomplete.h" + +struct autocomplete_t { + GSList *items; + GSList *last_found; + gchar *search_str; +}; + +static gchar * _search_from(Autocomplete ac, GSList *curr); + +Autocomplete +autocomplete_new(void) +{ + Autocomplete new = malloc(sizeof(struct autocomplete_t)); + new->items = NULL; + new->last_found = NULL; + new->search_str = NULL; + + return new; +} + +void +autocomplete_clear(Autocomplete ac) +{ + g_slist_free_full(ac->items, free); + ac->items = NULL; + + autocomplete_reset(ac); +} + +void +autocomplete_reset(Autocomplete ac) +{ + ac->last_found = NULL; + if (ac->search_str != NULL) { + free(ac->search_str); + ac->search_str = NULL; + } +} + +void +autocomplete_free(Autocomplete ac) +{ + autocomplete_clear(ac); + g_free(ac); + ac = NULL; +} + +gboolean +autocomplete_add(Autocomplete ac, void *item) +{ + if (ac->items == NULL) { + ac->items = g_slist_append(ac->items, item); + return TRUE; + } else { + GSList *curr = ac->items; + + while(curr) { + + // insert + if (g_strcmp0(curr->data, item) > 0) { + ac->items = g_slist_insert_before(ac->items, + curr, item); + return TRUE; + + // update + } else if (g_strcmp0(curr->data, item) == 0) { + // only update if data different + if (strcmp(curr->data, item) != 0) { + free(curr->data); + curr->data = item; + return TRUE; + } else { + return FALSE; + } + } + + curr = g_slist_next(curr); + } + + // hit end, append + ac->items = g_slist_append(ac->items, item); + + return TRUE; + } +} + +gboolean +autocomplete_remove(Autocomplete ac, const char * const item) +{ + // reset last found if it points to the item to be removed + if (ac->last_found != NULL) + if (g_strcmp0(ac->last_found->data, item) == 0) + ac->last_found = NULL; + + if (!ac->items) { + return FALSE; + } else { + GSList *curr = ac->items; + + while(curr) { + if (g_strcmp0(curr->data, item) == 0) { + void *current_item = curr->data; + ac->items = g_slist_remove(ac->items, curr->data); + free(current_item); + + return TRUE; + } + + curr = g_slist_next(curr); + } + + return FALSE; + } +} + +GSList * +autocomplete_get_list(Autocomplete ac) +{ + GSList *copy = NULL; + GSList *curr = ac->items; + + while(curr) { + copy = g_slist_append(copy, strdup(curr->data)); + curr = g_slist_next(curr); + } + + return copy; +} + +gchar * +autocomplete_complete(Autocomplete ac, gchar *search_str) +{ + gchar *found = NULL; + + // no items to search + if (!ac->items) + return NULL; + + // first search attempt + if (ac->last_found == NULL) { + ac->search_str = + (gchar *) malloc((strlen(search_str) + 1) * sizeof(gchar)); + strcpy(ac->search_str, search_str); + + found = _search_from(ac, ac->items); + return found; + + // subsequent search attempt + } else { + // search from here+1 tp end + found = _search_from(ac, g_slist_next(ac->last_found)); + if (found != NULL) + return found; + + // search from beginning + found = _search_from(ac, ac->items); + if (found != NULL) + return found; + + // we found nothing, reset search + autocomplete_reset(ac); + return NULL; + } +} + +static gchar * +_search_from(Autocomplete ac, GSList *curr) +{ + while(curr) { + + // match found + if (strncmp(curr->data, ac->search_str, strlen(ac->search_str)) == 0) { + + // set pointer to last found + ac->last_found = curr; + + // if contains space, quote before returning + if (g_strrstr(curr->data, " ")) { + GString *quoted = g_string_new("\""); + g_string_append(quoted, curr->data); + g_string_append(quoted, "\""); + + gchar *result = quoted->str; + g_string_free(quoted, FALSE); + + return result; + + // otherwise just return the string + } else { + return strdup(curr->data); + } + } + + curr = g_slist_next(curr); + } + + return NULL; +} diff --git a/src/tools/autocomplete.h b/src/tools/autocomplete.h new file mode 100644 index 00000000..03f4a013 --- /dev/null +++ b/src/tools/autocomplete.h @@ -0,0 +1,45 @@ +/* + * autocomplete.h + * + * Copyright (C) 2012, 2013 James Booth <boothj5@gmail.com> + * + * This file is part of Profanity. + * + * Profanity 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. + * + * Profanity 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 Profanity. If not, see <http://www.gnu.org/licenses/>. + * + */ + +#ifndef AUTOCOMPLETE_H +#define AUTOCOMPLETE_H + +#include <glib.h> + +typedef struct autocomplete_t *Autocomplete; +typedef const char * (*PStrFunc)(const void *obj); +typedef void * (*PCopyFunc)(const void *obj); +typedef int (*PEqualFunc)(const void *o1, const void *o2); +typedef int (*PEqualDeepFunc)(const void *o1, const void *o2); + +Autocomplete autocomplete_new(void); +Autocomplete obj_autocomplete_new(PStrFunc str_func, PCopyFunc copy_func, + PEqualDeepFunc equal_deep_func, GDestroyNotify free_func); +void autocomplete_clear(Autocomplete ac); +void autocomplete_reset(Autocomplete ac); +void autocomplete_free(Autocomplete ac); +gboolean autocomplete_add(Autocomplete ac, void *item); +gboolean autocomplete_remove(Autocomplete ac, const char * const item); +GSList * autocomplete_get_list(Autocomplete ac); +gchar * autocomplete_complete(Autocomplete ac, gchar *search_str); + +#endif diff --git a/src/tools/history.c b/src/tools/history.c new file mode 100644 index 00000000..5ac41969 --- /dev/null +++ b/src/tools/history.c @@ -0,0 +1,267 @@ +/* + * history.c + * + * Copyright (C) 2012, 2013 James Booth <boothj5@gmail.com> + * + * This file is part of Profanity. + * + * Profanity 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. + * + * Profanity 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 Profanity. If not, see <http://www.gnu.org/licenses/>. + * + */ + +#include <stdlib.h> +#include <string.h> + +#include <glib.h> + +#include "history.h" + +struct history_session_t { + GList *items; + GList *sess_curr; + GList *sess_new; + GList *orig_curr; +}; + +struct history_t { + GList *items; + guint max_size; + struct history_session_t session; +}; + +static void _replace_history_with_session(History history); +static gboolean _adding_new(History history); +static void _reset_session(History history); +static gboolean _has_session(History history); +static void _remove_first(History history); +static void _update_current_session_item(History history, char *item); +static void _add_to_history(History history, char *item); +static void _remove_last_session_item(History history); +static void _replace_current_with_original(History history); +static void _create_session(History history); +static void _session_previous(History history); +static void _session_next(History history); + +History +history_new(unsigned int size) +{ + History new_history = malloc(sizeof(struct history_t)); + new_history->items = NULL; + new_history->max_size = size; + + _reset_session(new_history); + + return new_history; +} + +void +history_append(History history, char *item) +{ + char *copied = ""; + if (item != NULL) { + copied = strdup(item); + } + + if (history->items == NULL) { + _add_to_history(history, copied); + return; + } + + if (!_has_session(history)) { + if (g_list_length(history->items) == history->max_size) { + _remove_first(history); + } + + _add_to_history(history, copied); + + } else { + _update_current_session_item(history, copied); + + if (_adding_new(history)) { + if (strcmp(history->session.sess_curr->data, "") == 0) { + _remove_last_session_item(history); + } + + _replace_history_with_session(history); + + } else { + _remove_last_session_item(history); + + char *new = strdup(history->session.sess_curr->data); + history->session.items = g_list_append(history->session.items, new); + + _replace_current_with_original(history); + _replace_history_with_session(history); + } + } +} + +char * +history_previous(History history, char *item) +{ + // no history + if (history->items == NULL) { + return NULL; + } + + char *copied = ""; + if (item != NULL) { + copied = strdup(item); + } + + if (!_has_session(history)) { + _create_session(history); + + // add the new item + history->session.items = g_list_append(history->session.items, copied); + history->session.sess_new = g_list_last(history->session.items); + + char *result = strdup(history->session.sess_curr->data); + return result; + } else { + _update_current_session_item(history, copied); + _session_previous(history); + } + + char *result = strdup(history->session.sess_curr->data); + return result; +} + +char * +history_next(History history, char *item) +{ + // no history, or no session, return NULL + if ((history->items == NULL) || (history->session.items == NULL)) { + return NULL; + } + + char *copied = ""; + if (item != NULL) { + copied = strdup(item); + } + + _update_current_session_item(history, copied); + _session_next(history); + + char *result = strdup(history->session.sess_curr->data); + return result; +} + +static void +_replace_history_with_session(History history) +{ + g_list_free(history->items); + history->items = g_list_copy(history->session.items); + + if (g_list_length(history->items) > history->max_size) { + _remove_first(history); + } + + _reset_session(history); +} + +static gboolean +_adding_new(History history) +{ + return (history->session.sess_curr == + g_list_last(history->session.items)); +} + +static void +_reset_session(History history) +{ + history->session.items = NULL; + history->session.sess_curr = NULL; + history->session.sess_new = NULL; + history->session.orig_curr = NULL; +} + +static gboolean +_has_session(History history) +{ + return (history->session.items != NULL); +} + +static void +_remove_first(History history) +{ + GList *first = g_list_first(history->items); + char *first_item = first->data; + history->items = g_list_remove(history->items, first_item); +} + +static void +_update_current_session_item(History history, char *item) +{ + history->session.sess_curr->data = item; +} + +static void +_add_to_history(History history, char *item) +{ + history->items = g_list_append(history->items, item); +} + +static void +_remove_last_session_item(History history) +{ + history->session.items = g_list_reverse(history->session.items); + GList *first = g_list_first(history->session.items); + history->session.items = + g_list_remove(history->session.items, first->data); + history->session.items = g_list_reverse(history->session.items); +} + +static void +_replace_current_with_original(History history) +{ + history->session.sess_curr->data = strdup(history->session.orig_curr->data); +} + +static void +_create_session(History history) +{ + history->session.items = g_list_copy(history->items); + history->session.sess_curr = g_list_last(history->session.items); + history->session.orig_curr = g_list_last(history->items); +} + +static void +_session_previous(History history) +{ + history->session.sess_curr = + g_list_previous(history->session.sess_curr); + if (history->session.orig_curr == NULL) + history->session.orig_curr = g_list_last(history->items); + else + history->session.orig_curr = + g_list_previous(history->session.orig_curr); + + if (history->session.sess_curr == NULL) { + history->session.sess_curr = g_list_first(history->session.items); + history->session.orig_curr = g_list_first(history->items); + } +} + +static void +_session_next(History history) +{ + history->session.sess_curr = g_list_next(history->session.sess_curr); + history->session.orig_curr = g_list_next(history->session.orig_curr); + + if (history->session.sess_curr == NULL) { + history->session.sess_curr = g_list_last(history->session.items); + history->session.orig_curr = NULL; + } +} diff --git a/src/tools/history.h b/src/tools/history.h new file mode 100644 index 00000000..4258f7a7 --- /dev/null +++ b/src/tools/history.h @@ -0,0 +1,33 @@ +/* + * history.h + * + * Copyright (C) 2012, 2013 James Booth <boothj5@gmail.com> + * + * This file is part of Profanity. + * + * Profanity 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. + * + * Profanity 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 Profanity. If not, see <http://www.gnu.org/licenses/>. + * + */ + +#ifndef HISTORY_H +#define HISTORY_H + +typedef struct history_t *History; + +History history_new(unsigned int size); +char * history_previous(History history, char *item); +char * history_next(History history, char *item); +void history_append(History history, char *item); + +#endif diff --git a/src/tools/tinyurl.c b/src/tools/tinyurl.c new file mode 100644 index 00000000..87fafc47 --- /dev/null +++ b/src/tools/tinyurl.c @@ -0,0 +1,88 @@ +/* + * tinyurl.c + * + * Copyright (C) 2012, 2013 James Booth <boothj5@gmail.com> + * + * This file is part of Profanity. + * + * Profanity 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. + * + * Profanity 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 Profanity. If not, see <http://www.gnu.org/licenses/>. + * + */ + +#include <stdlib.h> +#include <string.h> + +#include <curl/curl.h> +#include <curl/easy.h> +#include <glib.h> + +struct curl_data_t +{ + char *buffer; + size_t size; +}; + +static size_t _data_callback(void *ptr, size_t size, size_t nmemb, void *data); + +gboolean +tinyurl_valid(char *url) +{ + return (g_str_has_prefix(url, "http://") || + g_str_has_prefix(url, "https://")); +} + +char * +tinyurl_get(char *url) +{ + GString *full_url = g_string_new("http://tinyurl.com/api-create.php?url="); + g_string_append(full_url, url); + + CURL *handle = curl_easy_init(); + struct curl_data_t output; + output.buffer = NULL; + output.size = 0; + + curl_easy_setopt(handle, CURLOPT_URL, full_url->str); + curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, _data_callback); + curl_easy_setopt(handle, CURLOPT_WRITEDATA, (void *)&output); + + curl_easy_perform(handle); + curl_easy_cleanup(handle); + + g_string_free(full_url, TRUE); + + if (output.buffer != NULL) { + output.buffer[output.size++] = '\0'; + return output.buffer; + } else { + return NULL; + } +} + +static size_t +_data_callback(void *ptr, size_t size, size_t nmemb, void *data) +{ + size_t realsize = size * nmemb; + struct curl_data_t *mem = (struct curl_data_t *) data; + mem->buffer = realloc(mem->buffer, mem->size + realsize + 1); + + if ( mem->buffer ) + { + memcpy( &( mem->buffer[ mem->size ] ), ptr, realsize ); + mem->size += realsize; + mem->buffer[ mem->size ] = 0; + } + + return realsize; +} diff --git a/src/tools/tinyurl.h b/src/tools/tinyurl.h new file mode 100644 index 00000000..58070839 --- /dev/null +++ b/src/tools/tinyurl.h @@ -0,0 +1,31 @@ +/* + * tinyurl.h + * + * Copyright (C) 2012, 2013 James Booth <boothj5@gmail.com> + * + * This file is part of Profanity. + * + * Profanity 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. + * + * Profanity 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 Profanity. If not, see <http://www.gnu.org/licenses/>. + * + */ + +#ifndef TINYURL_H +#define TINYURL_H + +#include <glib.h> + +gboolean tinyurl_valid(char *url); +char * tinyurl_get(char *url); + +#endif |