/*
* $Id$
*
- * by JH <jheinonen@bigfoot.com>
+ * by JH <jheinonen@users.sourceforge.net>
*
* Copyright (C) Jaakko Heinonen
*/
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
-#include "abook_curses.h"
#include "abook.h"
+#include <assert.h>
#include "database.h"
#include "list.h"
#include "misc.h"
{"Name", "name", TAB_CONTACT},/* NAME */
{"E-mails", "email", TAB_CONTACT},/* EMAIL */
{"Address", "address", TAB_ADDRESS},/* ADDRESS */
+ {"Address2", "address2", TAB_ADDRESS},/* ADDRESS2 */
{"City", "city", TAB_ADDRESS},/* CITY */
{"State/Province","state", TAB_ADDRESS},/* STATE */
{"ZIP/Postal Code","zip", TAB_ADDRESS},/* ZIP */
} else if((tmp = strchr(line, '=') ) && sec ) {
*tmp++ = '\0';
for(i=0; i<ITEM_FIELDS; i++)
- if( !strcmp(abook_fields[i].key, line) )
+ if( !strcmp(abook_fields[i].key, line) ) {
item[i] = strdup(tmp);
+ goto next;
+ }
}
+next:
free(line);
}
parse_database(in);
- if ( items == 0 )
- return 2;
-
- return 0;
+ return (items == 0) ? 2 : 0;
}
int
-write_database(FILE *out)
+write_database(FILE *out, struct db_enumerator e)
{
- int i,j;
-
- fprintf(out, "# abook addressbook file\n\n");
- fprintf(out, "[format]\n");
- fprintf(out, "program=" PACKAGE "\n");
- fprintf(out, "version=" VERSION "\n");
- fprintf(out, "\n\n");
-
- for( i = 0; i < items; i++ ) {
+ int j;
+ int i = 0;
+
+ fprintf(out,
+ "# abook addressbook file\n\n"
+ "[format]\n"
+ "program=" PACKAGE "\n"
+ "version=" VERSION "\n"
+ "\n\n"
+ );
+
+ db_enumerate_items(e) {
fprintf(out, "[%d]\n", i);
- for(j=0; j<ITEM_FIELDS; j++) {
- if( database[i][j] != NULL && *database[i][j] )
+ for(j = 0; j < ITEM_FIELDS; j++) {
+ if( database[e.item][j] != NULL &&
+ *database[e.item][j] )
fprintf(out, "%s=%s\n",
- abook_fields[j].key, database[i][j]);
+ abook_fields[j].key,
+ database[e.item][j]
+ );
}
fputc('\n', out);
+ i++;
}
return 0;
save_database()
{
FILE *out;
+ struct db_enumerator e = init_db_enumerator(ENUM_ALL);
if( (out = abook_fopen(datafile, "w")) == NULL )
return -1;
- if( items < 1 ) {
+ if( list_is_empty() ) {
fclose(out);
unlink(datafile);
return 1;
}
- write_database(out);
+ write_database(out, e);
fclose(out);
#define _MAX_FIELD_LEN(X) (X == EMAIL ? MAX_EMAILSTR_LEN:MAX_FIELD_LEN)
-inline static void
+static void
validate_item(list_item item)
{
int i;
item[EMAIL] = strdup("");
for(i=0; i<ITEM_FIELDS; i++)
- if( item[i] && (strlen(item[i]) > _MAX_FIELD_LEN(i) ) ) {
+ if( item[i] && ((int)strlen(item[i]) > _MAX_FIELD_LEN(i) ) ) {
tmp = item[i];
item[i][_MAX_FIELD_LEN(i)-1] = 0;
item[i] = strdup(item[i]);
else
return;
- database = abook_realloc(database,
+ database = (list_item *)abook_realloc(database,
sizeof(list_item) * list_capacity);
- selected = abook_realloc(selected, list_capacity);
+ selected = (char *)abook_realloc(selected, list_capacity);
}
int
}
void
-remove_items()
+remove_selected_items()
{
int i, j;
- if( items < 1 || curitem < 0 )
+ if( list_is_empty() )
return;
- statusline_addstr("Remove selected item(s) (Y/n)");
- switch( getch() ) {
- case '\r':
- case 'y':
- case 'Y': break;
- default:
- clear_statusline();
- return;
- }
-
if( ! selected_items() )
selected[ curitem ] = 1;
adjust_list_capacity();
select_none();
- clear_statusline();
- refresh_list();
}
char *
get_surname(char *s)
{
- int i, a;
- int len = strlen(s);
- char *name = strdup(s);
+ char *p = s + strlen(s);
- for( a = 0, i = len - 1; i >= 0; i--, a++ ) {
- name[a] = s[i];
- if(name[a] == ' ')
- break;
- }
+ assert(s != NULL);
- name[ a ] = 0;
+ while(p > s && *(p - 1) != ' ')
+ p--;
- revstr(name);
-
- return name;
+ return strdup(p);
}
static int
s1 = get_surname(a[NAME]);
s2 = get_surname(b[NAME]);
- if( !(ret = safe_strcmp(s1, s2)) )
- ret = safe_strcmp(a[NAME], b[NAME]);
+ if( !(ret = safe_strcoll(s1, s2)) )
+ ret = safe_strcoll(a[NAME], b[NAME]);
free(s1);
free(s2);
itemcpy(a, i1);
itemcpy(b, i2);
- return safe_strcmp( a[NAME], b[NAME] );
+ return safe_strcoll( a[NAME], b[NAME] );
}
void
refresh_screen();
}
-void
-clear_database()
-{
-
- statusline_addstr("Clear WHOLE database (y/N)");
- switch( getch() ) {
- case 'y':
- case 'Y': break;
- default:
- clear_statusline();
- return;
- }
-
- close_database();
-
- refresh_screen();
-}
-
-void
-find(int next)
+int
+find_item(char *str, int start, int search_fields[])
{
int i;
- static char findstr[81];
- char tmp[81];
-
-#ifdef DEBUG
- fprintf(stderr, "find(): findstr = |%s|\n", findstr);
-#endif
-
- if(next) {
- if( !*findstr )
- return;
- } else {
- clear_statusline();
- statusline_addstr("/");
- statusline_getnstr(findstr, 67, 0);
- strupper(findstr);
- clear_statusline();
- }
-
- if(items < 1)
- return;
-
- for( i = (curitem < LAST_ITEM) && next ? curitem+1 : curitem;
- i < items; i++ ) {
- strcpy(tmp, database[i][NAME]);
- if( strstr(strupper(tmp), findstr) != NULL ) {
- curitem = i;
- refresh_list();
- break;
+ char *findstr = NULL;
+ char *tmp = NULL;
+ int ret = -1; /* not found */
+ struct db_enumerator e = init_db_enumerator(ENUM_ALL);
+
+ if(list_is_empty() || !is_valid_item(start))
+ return -2; /* error */
+
+ findstr = strdup(str);
+ findstr = strlower(findstr);
+
+ e.item = start - 1; /* must be "real start" - 1 */
+ db_enumerate_items(e) {
+ for( i = 0; search_fields[i] >= 0; i++ ) {
+ tmp = safe_strdup(database[e.item][search_fields[i]]);
+ if( tmp && strstr(strlower(tmp), findstr) ) {
+ ret = e.item;
+ goto out;
+ }
+ my_free(tmp);
}
}
+
+out:
+ free(findstr);
+ free(tmp);
+ return ret;
}
-void
-print_number_of_items()
+int
+is_selected(int item)
{
- char *str = mkstr(" " "|%3d/%3d", selected_items(), items);
-
- mvaddstr(0, COLS-strlen(str), str);
-
- free(str);
+ return selected[item];
}
-void
-read_database()
+int
+is_valid_item(int item)
{
- if(items > 0) {
- statusline_addstr("Your current data will be lost - Press 'y' to continue");
- switch( getch() ) {
- case 'y':
- case 'Y': break;
- default: clear_statusline();
- return;
- }
- clear_statusline();
- }
-
- load_database(datafile);
- refresh_list();
+ return item <= LAST_ITEM && item >= 0;
}
-
-void
-print_database()
+int
+real_db_enumerate_items(struct db_enumerator e)
{
- FILE *handle;
- char *command = options_get_str("print_command");
-
- statusline_addstr("Print addressbook? (y/N)");
- switch( getch() ) {
- case 'y':
- case 'Y':
+ int item = max(0, e.item + 1);
+ int i;
+
+ switch(e.mode) {
+#ifdef DEBUG
+ case ENUM_ALL:
+ break;
+#endif
+ case ENUM_SELECTED:
+ for(i = item; i < items; i++) {
+ if(is_selected(i)) {
+ item = i;
+ goto out;
+ }
+ }
+ return -1;
+#ifdef DEBUG
+ default:
+ fprintf(stderr, "real_db_enumerate_items() "
+ "BUG: unknown db_enumerator mode: %d\n",
+ e.mode);
break;
- default: clear_statusline(); return;
+#endif
}
- clear_statusline();
+out:
+ return (item > LAST_ITEM || item < 0) ? -1 : item;
+}
- if( ! *command || (handle = popen(command, "w")) == NULL)
- return;
+struct db_enumerator
+init_db_enumerator(int mode)
+{
+ struct db_enumerator e;
- fexport("text", handle);
-
- pclose(handle);
-}
+ e.item = -1; /* important - means "start from beginning" */
+ e.mode = mode;
+ return e;
+}