📄 xrolo.db.c
字号:
/**** xrolo.db.c ****//*********************************************************************** Copyright (c) 1991, 1992 Iris Computing Laboratories.** This software is provided for demonstration purposes only. As* freely-distributed, modifiable source code, this software carries* absolutely no warranty. Iris Computing Laboratories disclaims* all warranties for this software, including any implied warranties* of merchantability and fitness, and shall not be liable for* damages of any type resulting from its use.* Permission to use, copy, modify, and distribute this source code* for any purpose and without fee is hereby granted, provided that* the above copyright and this permission notice appear in all copies* and supporting documentation, and provided that Iris Computing* Laboratories not be named in advertising or publicity pertaining* to the redistribution of this software without specific, written* prior permission.**********************************************************************//*******************************************************************This module imposes arbitrary rolodex policies on the generic,stream-oriented database object, `StreamDB', that's implemented in`steamdb.c'. `xrolo.db.c' is not useful with applications otherthan `xrolo'.Overall, the idea is that `xrolo' manages only one active rolodexdatabase/file at a time. Thus, the state of the rolodex file canbe managed with a small number of variables that are private tothis file; these variables include `xrolo', `entry', and`deleted_entry'.Although `streamdb.c' provides facilities for maintaining thecurrent database entry, `xrolo.db.c' maintains its own pointerto the "current" database entry in `entry', and formally sets thecurrent entry pointer in `streamdb.c' only when necessary as anintermediate step in performing a database operation, e.g.,deleting the current database entry.*******************************************************************/#include "xrolo.db.h"/*Private globals (these maintain the current database state):*/static StreamDB xrolo = NULL;static EntryDB entry, deleted_entry, temp_entry;static char **index_array = NULL;/*xrolo_db_create() uses streamdb_create() to create a stream-oriented rolodex database. The `StreamDB' object `xrolo'maintains the state of the database per se, including thefilename associated with the database.*/EntryDB xrolo_db_create(filename, delimiter)char *filename, *delimiter;{ if (xrolo) { /* policy: support one DB only */ xrolo_db_destroy(); deleted_entry = NULL; } xrolo = streamdb_create(filename, delimiter); entry = streamdb_load(xrolo); /* NULL for a new file */ return streamdb_set_current(xrolo, entry);} /* xrolo_db_create *//*xrolo_db_destroy() frees the stream-oriented database,as well as the entries maintained by this module.*/void xrolo_db_destroy(){ if (deleted_entry) streamdb_free_solitaire(xrolo, deleted_entry); if (xrolo) streamdb_destroy(xrolo); xrolo_db_free_index_array();} /* xrolo_db_destroy *//*xrolo_db_is_active() provides information about whetheror not the database has been activated.*/int xrolo_db_is_active(){ return (xrolo) ? TRUE : FALSE;} /* xrolo_db_is_active *//*xrolo_db_is_modified() provides information about whetheror not the database has been modified.*/int xrolo_db_is_modified(){ if (!xrolo) return FALSE; else return streamdb_modified(xrolo);} /* xrolo_db_is_modified *//*xrolo_db_save() updates the database to disk usinginformation stored in the `StreamDB' object, `xrolo'.*/int xrolo_db_save(){ int status; if (!xrolo) return FALSE; else if ((status = streamdb_save(xrolo)) < 0) return FALSE; else return status;} /* xrolo_db_save *//*xrolo_db_save_as() updates the database to disk usinginformation stored in the `StreamDB' object, `xrolo'and the filename given as an argument.*/int xrolo_db_save_as(filename)char *filename;{ int status; if (!xrolo) return FALSE; else if ((status = streamdb_save_as(xrolo, filename)) < 0) return FALSE; else return status;} /* xrolo_db_save_as *//*xrolo_db_save_backup() makes a copy of the rolodex file underan alternate filename.*/int xrolo_db_save_backup(){ if (!xrolo || !file_exists(xrolo->filename)) return FALSE; else { char command[streamdb_MAX_FILENAME_SPEC + 10]; sprintf(command, "cp -p %s %s%s", xrolo->filename, xrolo->filename, ".bak"); system(command); /* don't check result at present */ return TRUE; }} /* xrolo_db_save_backup *//*xrolo_db_current_entry_is_first_entry() allows the applicationto determine if it's already processing the first entry.*/int xrolo_db_current_entry_is_first_entry(){ if (!xrolo || !entry) return FALSE; else return (entry == streamdb_get_first(xrolo));} /* xrolo_db_current_entry_is_first_entry *//*xrolo_db_current_entry_is_last_entry() allows the applicationto determine if it's already processing the last entry.*/int xrolo_db_current_entry_is_last_entry(){ if (!xrolo || !entry) return FALSE; else return (entry == streamdb_get_last(xrolo));} /* xrolo_db_current_entry_is_last_entry *//*xrolo_db_get_text() retrieves the text for the specified entry.*/char *xrolo_db_get_text(entry)EntryDB entry;{ if (!xrolo) return NULL; return streamdb_get_entry_text(xrolo, entry);} /* xrolo_db_get_text *//*xrolo_db_nth_entry() locates the nth entry, if possible.*/EntryDB xrolo_db_nth_entry(position)int position;{ if (!xrolo) return NULL; if ((temp_entry = streamdb_get_entry_by_position(xrolo, position)) == NULL) return NULL; return entry = temp_entry;} /* xrolo_db_nth_entry *//*xrolo_db_next_entry() moves forward one entry in therolodex database, if possible.*/EntryDB xrolo_db_next_entry(){ if (!xrolo) return NULL; if (!entry) { /* if pointer past last entry, return last entry: */ if ((temp_entry = streamdb_get_last(xrolo)) == NULL) return NULL; } else if ((temp_entry = streamdb_get_next(xrolo, entry)) == NULL) return NULL; return entry = temp_entry;} /* xrolo_db_next_entry *//*xrolo_db_current_entry() gets the current entry fromthe stream database, as maintained by this module in `entry'.*/EntryDB xrolo_db_current_entry(){ if (!xrolo) return NULL; return entry;} /* xrolo_db_current_entry *//*xrolo_db_previous_entry() moves backward one entry in therolodex database, if possible.*/EntryDB xrolo_db_previous_entry(){ if (!xrolo) return NULL; if (!entry) { /* if pointer past last entry, return last entry: */ if ((temp_entry = streamdb_get_last(xrolo)) == NULL) return NULL; } else if ((temp_entry = streamdb_get_previous(xrolo, entry)) == NULL) return NULL; return entry = temp_entry;} /* xrolo_db_previous_entry *//*xrolo_db_first_entry() moves to the beginning of therolodex database, if possible.*/EntryDB xrolo_db_first_entry(){ if (!xrolo) return NULL; if ((temp_entry = streamdb_get_first(xrolo)) == NULL) return NULL; return entry = temp_entry;} /* xrolo_db_first_entry *//*xrolo_db_last_entry() moves to the end of therolodex database, if possible.*/EntryDB xrolo_db_last_entry(){ if (!xrolo) return NULL; if ((temp_entry = streamdb_get_last(xrolo)) == NULL) return NULL; return entry = temp_entry;} /* xrolo_db_last_entry *//*xrolo_db_past_last_entry() simply sets the current entry toNULL, implying that insertions will be appended to the endof the database. See xrolo_db_insert_new_entry();*/EntryDB xrolo_db_past_last_entry(){ if (!xrolo) return NULL; if ((temp_entry = streamdb_get_last(xrolo)) == NULL) return NULL; return entry = NULL;} /* xrolo_db_past_last_entry *//*xrolo_db_insert_new_entry() inserts a new entry in therolodex database at the current database offset (beforethe current entry) -- a "paste" operation.*/EntryDB xrolo_db_insert_new_entry(text)char *text;{ char *temp = NULL; if (!xrolo) return NULL; if (!text) /* but, OK if it's an empty string */ return NULL; if (!*text || text[strlen(text) - 1] != '\n') { if ((temp = (char *) malloc((unsigned) (strlen(text) + 2))) != NULL) { strcpy(temp, text); strcat(temp, "\n"); text = temp; } else return NULL; } if (!entry) /* occur when empty after last deletion or if past last entry */ temp_entry = streamdb_insert(xrolo, text, streamdb_APPEND); else { streamdb_set_current(xrolo, entry); temp_entry = streamdb_insert(xrolo, text, streamdb_CURRENT); } if (temp) free(temp); if (temp_entry) return entry = temp_entry; /* update the current entry (`entry') */ else return NULL;} /* xrolo_db_insert_new_entry *//*xrolo_db_delete_current_entry() removes the current entryfrom the rolodex database. The deleted entry is saved forsubsequent recovery.*/EntryDB xrolo_db_delete_current_entry(){ int delete_last_entry; if (!xrolo) return NULL; if (deleted_entry) streamdb_free_solitaire(xrolo, deleted_entry); deleted_entry = streamdb_create_solitaire(xrolo, entry); delete_last_entry = (streamdb_get_next(xrolo, entry) == NULL); streamdb_set_current(xrolo, entry); temp_entry = streamdb_delete(xrolo, streamdb_CURRENT); if (delete_last_entry) return entry = streamdb_get_last(xrolo); else return entry = temp_entry;} /* xrolo_db_delete_current_entry *//*xrolo_db_delete_current_entry_no_undo() removes the current entryfrom the rolodex database. The deleted entry is not saved forsubsequent recovery.*/EntryDB xrolo_db_delete_current_entry_no_undo(){ int delete_last_entry; if (!xrolo) return NULL; delete_last_entry = (streamdb_get_next(xrolo, entry) == NULL); streamdb_set_current(xrolo, entry); temp_entry = streamdb_delete(xrolo, streamdb_CURRENT); if (delete_last_entry) return entry = streamdb_get_last(xrolo); else return entry = temp_entry;} /* xrolo_db_delete_current_entry_no_undo *//*xrolo_db_recover_deleted_entry() "pastes" the most recently deletedentry into the rolodex database before the current entry.*/EntryDB xrolo_db_recover_deleted_entry(){ if (!xrolo || !deleted_entry) return NULL; streamdb_set_current(xrolo, entry); if ((temp_entry = streamdb_insert(xrolo, deleted_entry->text, streamdb_CURRENT)) == NULL) return NULL; streamdb_free_solitaire(xrolo, deleted_entry); deleted_entry = NULL; return entry = temp_entry;} /* xrolo_db_recover_deleted_entry *//*xrolo_db_find_entry_forward() finds the next rolodex entry withtext that matches the search text.*/EntryDB xrolo_db_find_entry_forward(search_text, case_sensitive_search)char *search_text;int case_sensitive_search;{ if (!xrolo || !entry) return NULL; if ((temp_entry = streamdb_get_next(xrolo, entry)) == NULL) return NULL; streamdb_set_current(xrolo, temp_entry); if ((temp_entry = streamdb_search_forward(xrolo, search_text, case_sensitive_search ? string_SENSITIVE : string_INSENSITIVE)) == NULL) return NULL; return entry = temp_entry;} /* xrolo_db_find_entry_forward *//*xrolo_db_find_entry_reverse() finds the previous rolodex entry withtext that matches the search text.*/EntryDB xrolo_db_find_entry_reverse(search_text, case_sensitive_search)char *search_text;int case_sensitive_search;{ if (!xrolo) return NULL; if (!entry) { /* if pointer past last entry, get last entry: */ if ((temp_entry = streamdb_get_last(xrolo)) == NULL) return NULL; } else if ((temp_entry = streamdb_get_previous(xrolo, entry)) == NULL) return NULL; streamdb_set_current(xrolo, temp_entry); if ((temp_entry = streamdb_search_backward(xrolo, search_text, case_sensitive_search ? string_SENSITIVE : string_INSENSITIVE)) == NULL) return NULL; return entry = temp_entry;} /* xrolo_db_find_entry_reverse *//*xrolo_db_build_index_array() extracts the first line of textfrom each entry and builds a dynamic array of strings. Itis a null-terminated array.*/char **xrolo_db_build_index_array(){ int i, j, len, num_entries; char *first_line; EntryDB next_entry; if (!xrolo) return NULL; if ((num_entries = streamdb_get_num_entries(xrolo)) == 0) return NULL; index_array = (char **) malloc((unsigned) (sizeof(char *) * (num_entries + 1))); if (!index_array) return NULL; next_entry = streamdb_get_first(xrolo); for (i = 0; i < num_entries; i++) { first_line = streamdb_get_entry_text(xrolo, next_entry); len = strlen(first_line); for (j = 0; j < len && first_line[j] != '\n'; j++) /* count the characters on the first line */; len = j; index_array[i] = (char *) malloc((unsigned) (len + 1)); if (!index_array[i]) { for (i--; i >= 0; ) free(index_array[i--]); free(index_array); index_array = NULL; return NULL; } for (j = 0; j < len; j++) index_array[i][j] = first_line[j]; index_array[i][j] = EOS; next_entry = streamdb_get_next(xrolo, next_entry); } index_array[num_entries] = NULL; return index_array;} /* xrolo_db_build_index_array *//*xrolo_db_free_index_array() releases storage for thedynamic array of strings used in the index.*/void xrolo_db_free_index_array(){ if (index_array) { int i; for (i = 0; index_array[i]; i++) free(index_array[i]); free(index_array); index_array = NULL; }} /* xrolo_db_free_index_array *//*xrolo_db_sort_ascending() sorts the entries in ascending order.*/EntryDB xrolo_db_sort_ascending(){ if (!xrolo || !entry) return NULL; entry = streamdb_sort(xrolo, streamdb_ASCEND); streamdb_set_current(xrolo, entry); return entry;} /* xrolo_db_sort_ascending *//*xrolo_db_sort_descending() sorts the entries in descending order.*/EntryDB xrolo_db_sort_descending(){ if (!xrolo || !entry) return NULL; entry = streamdb_sort(xrolo, streamdb_DESCEND); streamdb_set_current(xrolo, entry); return entry;} /* xrolo_db_sort_descending */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -