* by JH <jheinonen@users.sourceforge.net>
*
* Copyright (C) Jaakko Heinonen
+ * getaline() Copyright (C) Lars Wirzenius
+ * sprintf and snprintf copyright is owned by various people
*/
#include <stdio.h>
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
-#ifdef HANDLE_MULTIBYTE
-# include <mbswidth.h>
-#endif
+#include <mbswidth.h>
+#include "abook.h"
#include "misc.h"
#include "xmalloc.h"
return s;
}
+int
+is_number(char *p)
+{
+ if(!p || !*p || (*p == '-' && !*++p))
+ return 0;
+
+ for(; *p; p++)
+ if(!isdigit(*p))
+ return 0;
+
+ return 1;
+}
+
+#ifndef HAVE_STRCASESTR
+char *
+strcasestr(const char *haystack, const char *needle)
+{
+ int i;
+ int k;
+
+ assert(haystack != NULL);
+ assert(needle != NULL);
+
+ for(i=0; i<strlen(haystack)-strlen(needle)+1; i++) {
+ for(k=0; k<strlen(needle); k++, i++) {
+ if (tolower(haystack[i]) != tolower(needle[k]))
+ break;
+ else if ((k+1) == strlen(needle))
+ return &haystack[i];
+ }
+ }
+
+ return NULL;
+}
+#endif
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
char *
-mkstr (const char *format, ... )
+strdup_printf (const char *format, ... )
{
MY_VA_LOCAL_DECL;
size_t size = 100;
}
MY_VA_END;
- concat = (char *)
- xmalloc(l);
- if(concat == NULL)
- return NULL;
+ concat = xmalloc(l);
strcpy (concat, str);
MY_VA_START(str);
return dir;
}
-#define INITIAL_SIZE 128
+/*
+ * getaline()
+ *
+ * Copyright (c) 1994 Lars Wirzenius
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer
+ * in this position and unchanged.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
char *
getaline(FILE *f)
strwidth(const char *s)
{
assert(s);
-#ifdef HANDLE_MULTIBYTE
- return (int)mbswidth(s, 0);
-#else
- return strlen(s);
-#endif
+ return mbswidth(s, 0);
}
int
#endif /* SNPRINTF_TEST */
#endif /* !HAVE_SNPRINTF */
+
+
+
+
+/*
+ * List handling functions
+ */
+
+void
+abook_list_append(abook_list **list, char *str)
+{
+ abook_list *tmp;
+
+ if(!str)
+ return;
+
+ for(tmp = *list; tmp && tmp->next; tmp = tmp->next)
+ ;
+
+ if(tmp) {
+ tmp->next = xmalloc(sizeof(abook_list));
+ tmp = tmp->next;
+ } else
+ tmp = *list = xmalloc(sizeof(abook_list));
+
+ tmp->data = xstrdup(str);
+ tmp->next = NULL;
+}
+
+void
+abook_list_free(abook_list **list)
+{
+ abook_list *prev = NULL, *tmp = *list;
+
+ if(!list)
+ return;
+
+ while(tmp) {
+ xfree(tmp->data);
+ prev = tmp;
+ tmp = tmp->next;
+ xfree(prev);
+ }
+
+ *list = NULL;
+}
+
+abook_list *
+csv_to_abook_list(char *str)
+{
+ char *start, *p = str, *end;
+ abook_list *list = NULL;
+
+ if(!str)
+ return NULL;
+
+ SKIPWS(p);
+ start = end = p;
+
+ while(*p) {
+ if(!strchr(", ", *p)) {
+ end = ++p;
+ continue;
+ }
+
+ if((*p == ',') && (end - start)) {
+ abook_list_append(&list, xstrndup(start, end - start));
+ p++;
+ SKIPWS(p);
+ start = end = p;
+ continue;
+ }
+
+ p++;
+ }
+ if(end - start)
+ abook_list_append(&list, xstrndup(start, end - start));
+
+ return list;
+}
+
+char *
+abook_list_to_csv(abook_list *list)
+{
+ abook_list *tmp;
+ char *res = NULL;
+
+ for(tmp = list; tmp; tmp = tmp->next) {
+ if(tmp == list)
+ res = xstrdup(tmp->data);
+ else {
+ res = xrealloc(res, strlen(res)+strlen(tmp->data)+2);
+ strcat(res, ",");
+ strcat(res, tmp->data);
+ }
+ }
+
+ return res;
+}
+
+void
+abook_list_rotate(abook_list **list, enum rotate_dir dir)
+{
+ abook_list *tmp = *list;
+
+ if(!tmp || !tmp->next)
+ return;
+
+ switch(dir) {
+ case ROTATE_LEFT:
+ for(; tmp && tmp->next; tmp = tmp->next)
+ ;
+
+ tmp->next = *list;
+ tmp = *list;
+ *list = (*list)->next;
+ tmp->next = NULL;
+ break;
+ case ROTATE_RIGHT:
+ for(; tmp && tmp->next && tmp->next->next;
+ tmp = tmp->next)
+ ;
+
+ tmp->next->next = *list;
+ *list = tmp->next;
+ tmp->next = NULL;
+ break;
+ default:
+ assert(0);
+ }
+}
+
+/* if str == NULL, deleting the list element */
+void
+abook_list_replace(abook_list **list, int index, char *str)
+{
+ abook_list *cur, *prev;
+ int i = 0;
+
+ cur = prev = *list;
+
+ if((index == 0) && !str) {
+ *list = cur->next;
+ free(cur->data);
+ free(cur);
+ return;
+ }
+
+ while(1) {
+ if(!cur)
+ return;
+
+ if(i == index)
+ break;
+
+ prev = cur;
+ cur = cur->next;
+ i++;
+ }
+
+ if(str) {
+ free(cur->data);
+ cur->data = xstrdup(str);
+ } else {
+ prev->next = cur->next;
+ free(cur->data);
+ free(cur);
+ }
+}
+
+abook_list *
+abook_list_get(abook_list *list, int index)
+{
+ int i = 0;
+
+ while(1) {
+ if(!list)
+ return NULL;
+
+ if(i == index)
+ return list;
+
+ i++;
+ list = list->next;
+ }
+}