From 83b7e5e78c5db58549b556b1911e763836121bac Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Tue, 29 Dec 2009 16:59:08 +0100 Subject: [PATCH] optionally use bundled db In fact, use it by default. Rename db.[ch] to avoid confusion with the similarly named files in db.1.85. Put db1 specific code in log1.c and vi_db1.c. Some of this code is very similar to the db[34] code. We may want to clean that up later. --- common/common.h | 4 +- common/log1.c | 777 +++++++++++++++++++++++++++++++++++++++++++++ common/{db.c => vi_db.c} | 0 common/{db.h => vi_db.h} | 23 ++ common/{db1.c => vi_db1.c} | 343 ++++++++------------ dist/Makefile.am | 52 ++- dist/acconfig.h | 4 +- dist/configure.in | 180 ++++++----- 8 files changed, 1086 insertions(+), 297 deletions(-) create mode 100644 common/log1.c rename common/{db.c => vi_db.c} (100%) rename common/{db.h => vi_db.h} (73%) rename common/{db1.c => vi_db1.c} (69%) diff --git a/common/common.h b/common/common.h index 5d59dbd8..624a53f9 100644 --- a/common/common.h +++ b/common/common.h @@ -26,7 +26,7 @@ * on most machines to which we're porting vi, and we want to include * them in a very specific order, regardless. */ -#include "db.h" +#include "vi_db.h" #include /* @@ -102,6 +102,8 @@ typedef enum { SEQ_ABBREV, SEQ_COMMAND, SEQ_INPUT } seq_t; #include "screen.h" /* Required by exf.h. */ #include "exf.h" #include "mem.h" +#ifndef USE_BUNDLED_DB #include "vi_auto.h" +#endif #include "extern.h" diff --git a/common/log1.c b/common/log1.c new file mode 100644 index 00000000..34198630 --- /dev/null +++ b/common/log1.c @@ -0,0 +1,777 @@ +/*- + * Copyright (c) 1992, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * Copyright (c) 1992, 1993, 1994, 1995, 1996 + * Keith Bostic. All rights reserved. + * + * See the LICENSE file for redistribution information. + */ + +#include "config.h" + +#ifndef lint +static const char sccsid[] = "$Id: log.c,v 10.26 2002/03/02 23:12:13 skimo Exp $ (Berkeley) $Date: 2002/03/02 23:12:13 $"; +#endif /* not lint */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "common.h" + +/* + * The log consists of records, each containing a type byte and a variable + * length byte string, as follows: + * + * LOG_CURSOR_INIT MARK + * LOG_CURSOR_END MARK + * LOG_LINE_APPEND_F db_recno_t char * + * LOG_LINE_APPEND_B db_recno_t char * + * LOG_LINE_DELETE_F db_recno_t char * + * LOG_LINE_DELETE_B db_recno_t char * + * LOG_LINE_RESET_F db_recno_t char * + * LOG_LINE_RESET_B db_recno_t char * + * LOG_MARK LMARK + * + * We do before image physical logging. This means that the editor layer + * MAY NOT modify records in place, even if simply deleting or overwriting + * characters. Since the smallest unit of logging is a line, we're using + * up lots of space. This may eventually have to be reduced, probably by + * doing logical logging, which is a much cooler database phrase. + * + * The implementation of the historic vi 'u' command, using roll-forward and + * roll-back, is simple. Each set of changes has a LOG_CURSOR_INIT record, + * followed by a number of other records, followed by a LOG_CURSOR_END record. + * LOG_LINE_RESET records come in pairs. The first is a LOG_LINE_RESET_B + * record, and is the line before the change. The second is LOG_LINE_RESET_F, + * and is the line after the change. Roll-back is done by backing up to the + * first LOG_CURSOR_INIT record before a change. Roll-forward is done in a + * similar fashion. + * + * The 'U' command is implemented by rolling backward to a LOG_CURSOR_END + * record for a line different from the current one. It should be noted that + * this means that a subsequent 'u' command will make a change based on the + * new position of the log's cursor. This is okay, and, in fact, historic vi + * behaved that way. + */ + +static int log_cursor1 __P((SCR *, int)); +static void log_err __P((SCR *, char *, int)); +#if defined(DEBUG) && 0 +static void log_trace __P((SCR *, char *, db_recno_t, u_char *)); +#endif + +/* Try and restart the log on failure, i.e. if we run out of memory. */ +#define LOG_ERR { \ + log_err(sp, __FILE__, __LINE__); \ + return (1); \ +} + +/* offset of CHAR_T string in log needs to be aligned on some systems + * because it is passed to db_set as a string + */ +typedef struct { + char data[sizeof(u_char) /* type */ + sizeof(db_recno_t)]; + CHAR_T str[1]; +} log_t; +#define CHAR_T_OFFSET ((char *)(((log_t*)0)->str) - (char *)0) + +/* + * log_init -- + * Initialize the logging subsystem. + * + * PUBLIC: int log_init __P((SCR *, EXF *)); + */ +int +log_init(SCR *sp, EXF *ep) +{ + /* + * !!! + * ep MAY NOT BE THE SAME AS sp->ep, DON'T USE THE LATTER. + * + * Initialize the buffer. The logging subsystem has its own + * buffers because the global ones are almost by definition + * going to be in use when the log runs. + */ + sp->wp->l_lp = NULL; + sp->wp->l_len = 0; + ep->l_cursor.lno = 1; /* XXX Any valid recno. */ + ep->l_cursor.cno = 0; + ep->l_high = ep->l_cur = 1; + + ep->log = dbopen(NULL, O_CREAT | O_NONBLOCK | O_RDWR, + S_IRUSR | S_IWUSR, DB_RECNO, NULL); + if (ep->log == NULL) { + msgq(sp, M_SYSERR, "009|Log file"); + F_SET(ep, F_NOLOG); + return (1); + } + + ep->l_win = NULL; + /*LOCK_INIT(sp->wp, ep);*/ + + return (0); +} + +/* + * log_end -- + * Close the logging subsystem. + * + * PUBLIC: int log_end __P((SCR *, EXF *)); + */ +int +log_end(SCR *sp, EXF *ep) +{ + /* + * !!! + * ep MAY NOT BE THE SAME AS sp->ep, DON'T USE THE LATTER. + */ + /*LOCK_END(sp->wp, ep);*/ + if (ep->log != NULL) { + (void)(ep->log->close)(ep->log); + ep->log = NULL; + } + if (sp->wp->l_lp != NULL) { + free(sp->wp->l_lp); + sp->wp->l_lp = NULL; + } + sp->wp->l_len = 0; + ep->l_cursor.lno = 1; /* XXX Any valid recno. */ + ep->l_cursor.cno = 0; + ep->l_high = ep->l_cur = 1; + return (0); +} + +/* + * log_cursor -- + * Log the current cursor position, starting an event. + * + * PUBLIC: int log_cursor __P((SCR *)); + */ +int +log_cursor(SCR *sp) +{ + EXF *ep; + + ep = sp->ep; + if (F_ISSET(ep, F_NOLOG)) + return (0); + + /* + * If any changes were made since the last cursor init, + * put out the ending cursor record. + */ + if (ep->l_cursor.lno == OOBLNO) { + if (ep->l_win && ep->l_win != sp->wp) + return 0; + ep->l_cursor.lno = sp->lno; + ep->l_cursor.cno = sp->cno; + ep->l_win = NULL; + return (log_cursor1(sp, LOG_CURSOR_END)); + } + ep->l_cursor.lno = sp->lno; + ep->l_cursor.cno = sp->cno; + return (0); +} + +/* + * log_cursor1 -- + * Actually push a cursor record out. + */ +static int +log_cursor1(SCR *sp, int type) +{ + DBT data, key; + EXF *ep; + + ep = sp->ep; + + /* + if (type == LOG_CURSOR_INIT && + LOCK_TRY(sp->wp, ep)) + return 1; + */ + + BINC_RETC(sp, sp->wp->l_lp, sp->wp->l_len, sizeof(u_char) + sizeof(MARK)); + sp->wp->l_lp[0] = type; + memmove(sp->wp->l_lp + sizeof(u_char), &ep->l_cursor, sizeof(MARK)); + + memset(&key, 0, sizeof(key)); + key.data = &ep->l_cur; + key.size = sizeof(db_recno_t); + memset(&data, 0, sizeof(data)); + data.data = sp->wp->l_lp; + data.size = sizeof(u_char) + sizeof(MARK); + if (ep->log->put(ep->log, &key, &data, 0) == -1) + LOG_ERR; + +#if defined(DEBUG) && 0 + vtrace(sp, "%lu: %s: %u/%u\n", ep->l_cur, + type == LOG_CURSOR_INIT ? "log_cursor_init" : "log_cursor_end", + sp->lno, sp->cno); +#endif + /* Reset high water mark. */ + ep->l_high = ++ep->l_cur; + + /* + if (type == LOG_CURSOR_END) + LOCK_UNLOCK(sp->wp, ep); + */ + return (0); +} + +/* + * log_line -- + * Log a line change. + * + * PUBLIC: int log_line __P((SCR *, db_recno_t, u_int)); + */ +int +log_line(SCR *sp, db_recno_t lno, u_int action) +{ + DBT data, key; + EXF *ep; + size_t len; + CHAR_T *lp; + db_recno_t lcur; + + ep = sp->ep; + if (F_ISSET(ep, F_NOLOG)) + return (0); + + /* + * XXX + * + * Kluge for vi. Clear the EXF undo flag so that the + * next 'u' command does a roll-back, regardless. + */ + F_CLR(ep, F_UNDO); + + /* Put out one initial cursor record per set of changes. */ + if (ep->l_cursor.lno != OOBLNO) { + if (log_cursor1(sp, LOG_CURSOR_INIT)) + return (1); + ep->l_cursor.lno = OOBLNO; + ep->l_win = sp->wp; + } /*else if (ep->l_win != sp->wp) { + printf("log_line own: %p, this: %p\n", ep->l_win, sp->wp); + return 1; + }*/ + + switch (action) { + /* newly added for DB4 logging */ + case LOG_LINE_APPEND_B: + case LOG_LINE_DELETE_F: + return 0; + } + + /* + * Put out the changes. If it's a LOG_LINE_RESET_B call, it's a + * special case, avoid the caches. Also, if it fails and it's + * line 1, it just means that the user started with an empty file, + * so fake an empty length line. + */ + if (action == LOG_LINE_RESET_B) { + if (db_get(sp, lno, DBG_NOCACHE, &lp, &len)) { + static CHAR_T nul = 0; + if (lno != 1) { + db_err(sp, lno); + return (1); + } + len = 0; + lp = &nul; + } + } else + if (db_get(sp, lno, DBG_FATAL, &lp, &len)) + return (1); + BINC_RETC(sp, + sp->wp->l_lp, sp->wp->l_len, + len * sizeof(CHAR_T) + CHAR_T_OFFSET); + sp->wp->l_lp[0] = action; + memmove(sp->wp->l_lp + sizeof(u_char), &lno, sizeof(db_recno_t)); + MEMMOVEW(sp->wp->l_lp + CHAR_T_OFFSET, lp, len); + + lcur = ep->l_cur; + memset(&key, 0, sizeof(key)); + key.data = &lcur; + key.size = sizeof(db_recno_t); + memset(&data, 0, sizeof(data)); + data.data = sp->wp->l_lp; + data.size = len * sizeof(CHAR_T) + CHAR_T_OFFSET; + if (ep->log->put(ep->log, &key, &data, 0) == -1) + LOG_ERR; + +#if defined(DEBUG) && 0 + switch (action) { + case LOG_LINE_APPEND_F: + vtrace(sp, "%u: log_line: append_f: %lu {%u}\n", + ep->l_cur, lno, len); + break; + case LOG_LINE_APPEND_B: + vtrace(sp, "%u: log_line: append_b: %lu {%u}\n", + ep->l_cur, lno, len); + break; + case LOG_LINE_DELETE_F: + vtrace(sp, "%lu: log_line: delete_f: %lu {%u}\n", + ep->l_cur, lno, len); + break; + case LOG_LINE_DELETE_B: + vtrace(sp, "%lu: log_line: delete_b: %lu {%u}\n", + ep->l_cur, lno, len); + break; + case LOG_LINE_RESET_F: + vtrace(sp, "%lu: log_line: reset_f: %lu {%u}\n", + ep->l_cur, lno, len); + break; + case LOG_LINE_RESET_B: + vtrace(sp, "%lu: log_line: reset_b: %lu {%u}\n", + ep->l_cur, lno, len); + break; + } +#endif + /* Reset high water mark. */ + ep->l_high = ++ep->l_cur; + + return (0); +} + +/* + * log_mark -- + * Log a mark position. For the log to work, we assume that there + * aren't any operations that just put out a log record -- this + * would mean that undo operations would only reset marks, and not + * cause any other change. + * + * PUBLIC: int log_mark __P((SCR *, LMARK *)); + */ +int +log_mark(SCR *sp, LMARK *lmp) +{ + DBT data, key; + EXF *ep; + + ep = sp->ep; + if (F_ISSET(ep, F_NOLOG)) + return (0); + + /* Put out one initial cursor record per set of changes. */ + if (ep->l_cursor.lno != OOBLNO) { + if (log_cursor1(sp, LOG_CURSOR_INIT)) + return (1); + ep->l_cursor.lno = OOBLNO; + ep->l_win = sp->wp; + } + + BINC_RETC(sp, sp->wp->l_lp, + sp->wp->l_len, sizeof(u_char) + sizeof(LMARK)); + sp->wp->l_lp[0] = LOG_MARK; + memmove(sp->wp->l_lp + sizeof(u_char), lmp, sizeof(LMARK)); + + memset(&key, 0, sizeof(key)); + key.data = &ep->l_cur; + key.size = sizeof(db_recno_t); + memset(&data, 0, sizeof(data)); + data.data = sp->wp->l_lp; + data.size = sizeof(u_char) + sizeof(LMARK); + if (ep->log->put(ep->log, &key, &data, 0) == -1) + LOG_ERR; + +#if defined(DEBUG) && 0 + vtrace(sp, "%lu: mark %c: %lu/%u\n", + ep->l_cur, lmp->name, lmp->lno, lmp->cno); +#endif + /* Reset high water mark. */ + ep->l_high = ++ep->l_cur; + return (0); +} + +/* + * Log_backward -- + * Roll the log backward one operation. + * + * PUBLIC: int log_backward __P((SCR *, MARK *)); + */ +int +log_backward(SCR *sp, MARK *rp) +{ + DBT key, data; + EXF *ep; + LMARK lm; + MARK m; + db_recno_t lno; + int didop; + u_char *p; + + ep = sp->ep; + if (F_ISSET(ep, F_NOLOG)) { + msgq(sp, M_ERR, + "010|Logging not being performed, undo not possible"); + return (1); + } + + if (ep->l_cur == 1) { + msgq(sp, M_BERR, "011|No changes to undo"); + return (1); + } + + if (ep->l_win && ep->l_win != sp->wp) { + ex_emsg(sp, NULL, EXM_LOCKED); + return 1; + } + ep->l_win = sp->wp; + + + F_SET(ep, F_NOLOG); /* Turn off logging. */ + + key.data = &ep->l_cur; /* Initialize db request. */ + key.size = sizeof(recno_t); + for (didop = 0;;) { + --ep->l_cur; + if (ep->log->get(ep->log, &key, &data, 0)) + LOG_ERR; +#if defined(DEBUG) && 0 + log_trace(sp, "log_backward", ep->l_cur, data.data); +#endif + switch (*(p = (u_char *)data.data)) { + case LOG_CURSOR_INIT: + if (didop) { + memmove(rp, p + sizeof(u_char), sizeof(MARK)); + F_CLR(ep, F_NOLOG); + ep->l_win = NULL; + return (0); + } + break; + case LOG_CURSOR_END: + break; + case LOG_LINE_APPEND_F: + didop = 1; + memmove(&lno, p + sizeof(u_char), sizeof(db_recno_t)); + if (db_delete(sp, lno)) + goto err; + ++sp->rptlines[L_DELETED]; + break; + case LOG_LINE_DELETE_B: + didop = 1; + memmove(&lno, p + sizeof(u_char), sizeof(db_recno_t)); + if (db_insert(sp, lno, + (CHAR_T *)(p + CHAR_T_OFFSET), + (data.size - CHAR_T_OFFSET) / sizeof(CHAR_T))) + goto err; + ++sp->rptlines[L_ADDED]; + break; + case LOG_LINE_RESET_F: + break; + case LOG_LINE_RESET_B: + didop = 1; + memmove(&lno, p + sizeof(u_char), sizeof(db_recno_t)); + if (db_set(sp, lno, + (CHAR_T *)(p + CHAR_T_OFFSET), + (data.size - CHAR_T_OFFSET) / sizeof(CHAR_T))) + goto err; + if (sp->rptlchange != lno) { + sp->rptlchange = lno; + ++sp->rptlines[L_CHANGED]; + } + break; + case LOG_MARK: + didop = 1; + memmove(&lm, p + sizeof(u_char), sizeof(LMARK)); + m.lno = lm.lno; + m.cno = lm.cno; + if (mark_set(sp, lm.name, &m, 0)) + goto err; + break; + default: + abort(); + } + } + +err: F_CLR(ep, F_NOLOG); + ep->l_win = NULL; + return (1); +} + +/* + * Log_setline -- + * Reset the line to its original appearance. + * + * XXX + * There's a bug in this code due to our not logging cursor movements + * unless a change was made. If you do a change, move off the line, + * then move back on and do a 'U', the line will be restored to the way + * it was before the original change. + * + * PUBLIC: int log_setline __P((SCR *)); + */ +int +log_setline(SCR *sp) +{ + DBT key, data; + EXF *ep; + LMARK lm; + MARK m; + db_recno_t lno; + u_char *p; + + ep = sp->ep; + if (F_ISSET(ep, F_NOLOG)) { + msgq(sp, M_ERR, + "012|Logging not being performed, undo not possible"); + return (1); + } + + if (ep->l_cur == 1) + return (1); + + if (ep->l_win && ep->l_win != sp->wp) { + ex_emsg(sp, NULL, EXM_LOCKED); + return 1; + } + ep->l_win = sp->wp; + + F_SET(ep, F_NOLOG); /* Turn off logging. */ + + key.data = &ep->l_cur; /* Initialize db request. */ + key.size = sizeof(recno_t); + + for (;;) { + --ep->l_cur; + if (ep->log->get(ep->log, &key, &data, 0)) + LOG_ERR; +#if defined(DEBUG) && 0 + log_trace(sp, "log_setline", ep->l_cur, data.data); +#endif + switch (*(p = (u_char *)data.data)) { + case LOG_CURSOR_INIT: + memmove(&m, p + sizeof(u_char), sizeof(MARK)); + if (m.lno != sp->lno || ep->l_cur == 1) { + F_CLR(ep, F_NOLOG); + ep->l_win = NULL; + return (0); + } + break; + case LOG_CURSOR_END: + memmove(&m, p + sizeof(u_char), sizeof(MARK)); + if (m.lno != sp->lno) { + ++ep->l_cur; + F_CLR(ep, F_NOLOG); + ep->l_win = NULL; + return (0); + } + break; + case LOG_LINE_APPEND_F: + case LOG_LINE_DELETE_B: + case LOG_LINE_RESET_F: + break; + case LOG_LINE_RESET_B: + memmove(&lno, p + sizeof(u_char), sizeof(db_recno_t)); + if (lno == sp->lno && + db_set(sp, lno, (CHAR_T *)(p + CHAR_T_OFFSET), + (data.size - CHAR_T_OFFSET) / sizeof(CHAR_T))) + goto err; + if (sp->rptlchange != lno) { + sp->rptlchange = lno; + ++sp->rptlines[L_CHANGED]; + } + case LOG_MARK: + memmove(&lm, p + sizeof(u_char), sizeof(LMARK)); + m.lno = lm.lno; + m.cno = lm.cno; + if (mark_set(sp, lm.name, &m, 0)) + goto err; + break; + default: + abort(); + } + } + +err: F_CLR(ep, F_NOLOG); + ep->l_win = NULL; + return (1); +} + +/* + * Log_forward -- + * Roll the log forward one operation. + * + * PUBLIC: int log_forward __P((SCR *, MARK *)); + */ +int +log_forward(SCR *sp, MARK *rp) +{ + DBT key, data; + EXF *ep; + LMARK lm; + MARK m; + db_recno_t lno; + int didop; + u_char *p; + + ep = sp->ep; + if (F_ISSET(ep, F_NOLOG)) { + msgq(sp, M_ERR, + "013|Logging not being performed, roll-forward not possible"); + return (1); + } + + if (ep->l_cur == ep->l_high) { + msgq(sp, M_BERR, "014|No changes to re-do"); + return (1); + } + + if (ep->l_win && ep->l_win != sp->wp) { + ex_emsg(sp, NULL, EXM_LOCKED); + return 1; + } + ep->l_win = sp->wp; + + F_SET(ep, F_NOLOG); /* Turn off logging. */ + + key.data = &ep->l_cur; /* Initialize db request. */ + key.size = sizeof(recno_t); + for (didop = 0;;) { + ++ep->l_cur; + if (ep->log->get(ep->log, &key, &data, 0)) + LOG_ERR; +#if defined(DEBUG) && 0 + log_trace(sp, "log_forward", ep->l_cur, data.data); +#endif + switch (*(p = (u_char *)data.data)) { + case LOG_CURSOR_END: + if (didop) { + ++ep->l_cur; + memmove(rp, p + sizeof(u_char), sizeof(MARK)); + F_CLR(ep, F_NOLOG); + ep->l_win = NULL; + return (0); + } + break; + case LOG_CURSOR_INIT: + break; + case LOG_LINE_APPEND_F: + didop = 1; + memmove(&lno, p + sizeof(u_char), sizeof(db_recno_t)); + if (db_insert(sp, lno, + (CHAR_T *)(p + CHAR_T_OFFSET), + (data.size - CHAR_T_OFFSET) / sizeof(CHAR_T))) + goto err; + ++sp->rptlines[L_ADDED]; + break; + case LOG_LINE_DELETE_B: + didop = 1; + memmove(&lno, p + sizeof(u_char), sizeof(db_recno_t)); + if (db_delete(sp, lno)) + goto err; + ++sp->rptlines[L_DELETED]; + break; + case LOG_LINE_RESET_B: + break; + case LOG_LINE_RESET_F: + didop = 1; + memmove(&lno, p + sizeof(u_char), sizeof(db_recno_t)); + if (db_set(sp, lno, + (CHAR_T *)(p + CHAR_T_OFFSET), + (data.size - CHAR_T_OFFSET) / sizeof(CHAR_T))) + goto err; + if (sp->rptlchange != lno) { + sp->rptlchange = lno; + ++sp->rptlines[L_CHANGED]; + } + break; + case LOG_MARK: + didop = 1; + memmove(&lm, p + sizeof(u_char), sizeof(LMARK)); + m.lno = lm.lno; + m.cno = lm.cno; + if (mark_set(sp, lm.name, &m, 0)) + goto err; + break; + default: + abort(); + } + } + +err: F_CLR(ep, F_NOLOG); + ep->l_win = NULL; + return (1); +} + +/* + * log_err -- + * Try and restart the log on failure, i.e. if we run out of memory. + */ +static void +log_err(SCR *sp, char *file, int line) +{ + EXF *ep; + + msgq(sp, M_SYSERR, "015|%s/%d: log put error", tail(file), line); + ep = sp->ep; + (void)ep->log->close(ep->log); + if (!log_init(sp, ep)) + msgq(sp, M_ERR, "267|Log restarted"); +} + +#if defined(DEBUG) && 0 +static void +log_trace(sp, msg, rno, p) + SCR *sp; + char *msg; + db_recno_t rno; + u_char *p; +{ + LMARK lm; + MARK m; + db_recno_t lno; + + switch (*p) { + case LOG_CURSOR_INIT: + memmove(&m, p + sizeof(u_char), sizeof(MARK)); + vtrace(sp, "%lu: %s: C_INIT: %u/%u\n", rno, msg, m.lno, m.cno); + break; + case LOG_CURSOR_END: + memmove(&m, p + sizeof(u_char), sizeof(MARK)); + vtrace(sp, "%lu: %s: C_END: %u/%u\n", rno, msg, m.lno, m.cno); + break; + case LOG_LINE_APPEND_F: + memmove(&lno, p + sizeof(u_char), sizeof(db_recno_t)); + vtrace(sp, "%lu: %s: APPEND_F: %lu\n", rno, msg, lno); + break; + case LOG_LINE_APPEND_B: + memmove(&lno, p + sizeof(u_char), sizeof(db_recno_t)); + vtrace(sp, "%lu: %s: APPEND_B: %lu\n", rno, msg, lno); + break; + case LOG_LINE_DELETE_F: + memmove(&lno, p + sizeof(u_char), sizeof(db_recno_t)); + vtrace(sp, "%lu: %s: DELETE_F: %lu\n", rno, msg, lno); + break; + case LOG_LINE_DELETE_B: + memmove(&lno, p + sizeof(u_char), sizeof(db_recno_t)); + vtrace(sp, "%lu: %s: DELETE_B: %lu\n", rno, msg, lno); + break; + case LOG_LINE_RESET_F: + memmove(&lno, p + sizeof(u_char), sizeof(db_recno_t)); + vtrace(sp, "%lu: %s: RESET_F: %lu\n", rno, msg, lno); + break; + case LOG_LINE_RESET_B: + memmove(&lno, p + sizeof(u_char), sizeof(db_recno_t)); + vtrace(sp, "%lu: %s: RESET_B: %lu\n", rno, msg, lno); + break; + case LOG_MARK: + memmove(&lm, p + sizeof(u_char), sizeof(LMARK)); + vtrace(sp, + "%lu: %s: MARK: %u/%u\n", rno, msg, lm.lno, lm.cno); + break; + default: + abort(); + } +} +#endif diff --git a/common/db.c b/common/vi_db.c similarity index 100% rename from common/db.c rename to common/vi_db.c diff --git a/common/db.h b/common/vi_db.h similarity index 73% rename from common/db.h rename to common/vi_db.h index 87dcf2d1..081dc3e5 100644 --- a/common/db.h +++ b/common/vi_db.h @@ -4,6 +4,27 @@ #define DB_BUFFER_SMALL ENOMEM #endif +#ifdef USE_BUNDLED_DB + +typedef void DB_ENV; + +typedef recno_t db_recno_t; +#define DB_MAX_RECORDS MAX_REC_NUMBER + +#define db_env_close(env,flags) +#define db_env_create(env,flags) \ + 1 +#define db_env_remove(env,path,flags) \ + 1 +#define db_open(db,file,type,flags,mode) \ + (db)->open(db, file, NULL, type, flags, mode) +#define db_get_low(db,key,data,flags) \ + (db)->get(db, key, data, flags) +#define db_close(db) \ + (db)->close(db) + +#else + #if DB_VERSION_MAJOR >= 3 && DB_VERSION_MINOR >= 1 #define db_env_open(env,path,flags,mode) \ (env)->open(env, path, flags, mode) @@ -31,6 +52,8 @@ #define db_close(db) \ (db)->close(db, DB_NOSYNC) +#endif + #ifdef USE_DYNAMIC_LOADING #define db_create nvi_db_create #define db_env_create nvi_db_env_create diff --git a/common/db1.c b/common/vi_db1.c similarity index 69% rename from common/db1.c rename to common/vi_db1.c index 86430daa..6d63c94a 100644 --- a/common/db1.c +++ b/common/vi_db1.c @@ -16,9 +16,11 @@ static const char sccsid[] = "$Id: db1.c,v 10.1 2002/03/09 12:53:57 skimo Exp $ #include #include #include +#include #include #include +#include #include #include #include @@ -26,8 +28,6 @@ static const char sccsid[] = "$Id: db1.c,v 10.1 2002/03/09 12:53:57 skimo Exp $ #include "common.h" #include "../vi/vi.h" -static int scr_update __P((SCR *, db_recno_t, lnop_t, int)); - /* * db_eget -- * Front-end to db_get, special case handling for empty files. @@ -140,35 +140,28 @@ db_get(SCR *sp, db_recno_t lno, u_int32_t flags, CHAR_T **pp, size_t *lenp) } /* Look-aside into the cache, and see if the line we want is there. */ - /* - * Line cache will not work if different screens view the same - * file with different encodings. - * Multiple threads accessing the same cache can be a problem as - * well. - * So, line cache is (temporarily) disabled. - */ - if (0 && lno == ep->c_lno) { + if (lno == sp->c_lno) { #if defined(DEBUG) && 0 vtrace(sp, "retrieve cached line %lu\n", (u_long)lno); #endif if (lenp != NULL) - *lenp = ep->c_len; + *lenp = sp->c_len; if (pp != NULL) - *pp = ep->c_lp; + *pp = sp->c_lp; return (0); } - ep->c_lno = OOBLNO; + sp->c_lno = OOBLNO; nocache: nlen = 1024; retry: /* data.size contains length in bytes */ - BINC_GOTO(sp, CHAR_T, ep->c_lp, ep->c_blen, nlen); + BINC_GOTO(sp, CHAR_T, sp->c_lp, sp->c_blen, nlen); /* Get the line from the underlying database. */ key.data = &lno; key.size = sizeof(lno); - switch (ep->db->actual_db->get(ep->db->actual_db, &key, &data, 0)) { + switch (ep->db->get(ep->db, &key, &data, 0)) { case -1: goto err2; case 1: @@ -185,7 +178,7 @@ err3: if (lenp != NULL) nlen = data.size; goto retry; } else - memcpy(ep->c_lp, data.data, nlen); + memcpy(sp->c_lp, data.data, nlen); } if (FILE2INT(sp, data.data, data.size, wp, wlen)) { @@ -198,11 +191,11 @@ err3: if (lenp != NULL) /* Reset the cache. */ if (wp != data.data) { - BINC_GOTOW(sp, ep->c_lp, ep->c_blen, wlen); - MEMCPYW(ep->c_lp, wp, wlen); + BINC_GOTOW(sp, sp->c_lp, sp->c_blen, wlen); + MEMCPYW(sp->c_lp, wp, wlen); } - ep->c_lno = lno; - ep->c_len = wlen; + sp->c_lno = lno; + sp->c_len = wlen; #if defined(DEBUG) && 0 vtrace(sp, "retrieve DB line %lu\n", (u_long)lno); @@ -210,7 +203,7 @@ err3: if (lenp != NULL) if (lenp != NULL) *lenp = wlen; if (pp != NULL) - *pp = ep->c_lp; + *pp = sp->c_lp; return (0); } @@ -246,12 +239,12 @@ db_delete(SCR *sp, db_recno_t lno) return (1); /* Log change. */ - log_line(sp, lno, LOG_LINE_DELETE); + log_line(sp, lno, LOG_LINE_DELETE_B); /* Update file. */ key.data = &lno; key.size = sizeof(lno); - sp->db_error = ep->db->actual_db->del(ep->db->actual_db, &key, 0); + sp->db_error = ep->db->del(ep->db, &key, 0); if (sp->db_error != 0) { if (sp->db_error == -1) sp->db_error = errno; @@ -262,16 +255,16 @@ db_delete(SCR *sp, db_recno_t lno) } /* Flush the cache, update line count, before screen update. */ - if (lno <= ep->c_lno) - ep->c_lno = OOBLNO; - if (ep->c_nlines != OOBLNO) - --ep->c_nlines; + update_cache(sp, LINE_DELETE, lno); /* File now modified. */ if (F_ISSET(ep, F_FIRSTMODIFY)) (void)rcv_init(sp); F_SET(ep, F_MODIFIED); + /* Log after change. */ + log_line(sp, lno, LOG_LINE_DELETE_F); + /* Update screen. */ return (scr_update(sp, lno, LINE_DELETE, 1)); } @@ -287,6 +280,8 @@ db_append(SCR *sp, int update, db_recno_t lno, CHAR_T *p, size_t len) { DBT data, key; EXF *ep; + char *fp; + size_t flen; int rval; #if defined(DEBUG) && 0 @@ -301,31 +296,33 @@ db_append(SCR *sp, int update, db_recno_t lno, CHAR_T *p, size_t len) ex_emsg(sp, NULL, EXM_LOCKED); return 1; } + + /* Log before change. */ + log_line(sp, lno + 1, LOG_LINE_APPEND_B); + + INT2FILE(sp, p, len, fp, flen); /* Update file. */ key.data = &lno; key.size = sizeof(lno); - data.data = p; - data.size = len; - if (ep->db->actual_db->put(ep->db->actual_db, &key, &data, R_IAFTER)) { + data.data = fp; + data.size = flen; + if (ep->db->put(ep->db, &key, &data, R_IAFTER)) { msgq(sp, M_DBERR, "004|unable to append to line %lu", (u_long)lno); return (1); } /* Flush the cache, update line count, before screen update. */ - if (lno < ep->c_lno) - ep->c_lno = OOBLNO; - if (ep->c_nlines != OOBLNO) - ++ep->c_nlines; + update_cache(sp, LINE_INSERT, lno); /* File now dirty. */ if (F_ISSET(ep, F_FIRSTMODIFY)) (void)rcv_init(sp); F_SET(ep, F_MODIFIED); - /* Log change. */ - log_line(sp, lno + 1, LOG_LINE_APPEND); + /* Log after change. */ + log_line(sp, lno + 1, LOG_LINE_APPEND_F); /* Update marks, @ and global commands. */ rval = 0; @@ -358,6 +355,8 @@ db_insert(SCR *sp, db_recno_t lno, CHAR_T *p, size_t len) { DBT data, key; EXF *ep; + char *fp; + size_t flen; int rval; #if defined(DEBUG) && 0 @@ -373,31 +372,33 @@ db_insert(SCR *sp, db_recno_t lno, CHAR_T *p, size_t len) ex_emsg(sp, NULL, EXM_LOCKED); return 1; } + + /* Log before change. */ + log_line(sp, lno, LOG_LINE_APPEND_B); + + INT2FILE(sp, p, len, fp, flen); /* Update file. */ key.data = &lno; key.size = sizeof(lno); - data.data = p; - data.size = len; - if (ep->db->actual_db->put(ep->db->actual_db, &key, &data, R_IBEFORE)) { + data.data = fp; + data.size = flen; + if (ep->db->put(ep->db, &key, &data, R_IBEFORE)) { msgq(sp, M_SYSERR, "005|unable to insert at line %lu", (u_long)lno); return (1); } /* Flush the cache, update line count, before screen update. */ - if (lno >= ep->c_lno) - ep->c_lno = OOBLNO; - if (ep->c_nlines != OOBLNO) - ++ep->c_nlines; + update_cache(sp, LINE_INSERT, lno); /* File now dirty. */ if (F_ISSET(ep, F_FIRSTMODIFY)) (void)rcv_init(sp); F_SET(ep, F_MODIFIED); - /* Log change. */ - log_line(sp, lno, LOG_LINE_INSERT); + /* Log after change. */ + log_line(sp, lno, LOG_LINE_APPEND_F); /* Update marks, @ and global commands. */ rval = 0; @@ -449,7 +450,7 @@ db_set(SCR *sp, db_recno_t lno, CHAR_T *p, size_t len) data.data = fp; data.size = flen; sp->db_error = - ep->db->actual_db->put(ep->db->actual_db, &key, &data, 0); + ep->db->put(ep->db, &key, &data, 0); if (sp->db_error != 0) { if (sp->db_error == -1) sp->db_error = errno; @@ -459,8 +460,7 @@ db_set(SCR *sp, db_recno_t lno, CHAR_T *p, size_t len) } /* Flush the cache, before logging or screen update. */ - if (lno == ep->c_lno) - ep->c_lno = OOBLNO; + update_cache(sp, LINE_RESET, lno); /* File now dirty. */ if (F_ISSET(ep, F_FIRSTMODIFY)) @@ -543,8 +543,7 @@ db_last(SCR *sp, db_recno_t *lnop) key.data = &lno; key.size = sizeof(lno); - sp->db_error = ep->db->actual_db->seq(ep->db->actual_db, &key, &data, - R_LAST); + sp->db_error = ep->db->seq(ep->db, &key, &data, R_LAST); switch (sp->db_error) { case 1: *lnop = 0; @@ -561,16 +560,14 @@ alloc_err: memcpy(&lno, key.data, sizeof(lno)); - if (lno != ep->c_lno) { + if (lno != sp->c_lno) { FILE2INT(sp, data.data, data.size, wp, wlen); /* Fill the cache. */ - if (wp != data.data) { - BINC_GOTOW(sp, ep->c_lp, ep->c_blen, wlen); - MEMCPYW(ep->c_lp, wp, wlen); - } - ep->c_lno = lno; - ep->c_len = wlen; + BINC_GOTOW(sp, sp->c_lp, sp->c_blen, wlen); + MEMCPYW(sp->c_lp, wp, wlen); + sp->c_lno = lno; + sp->c_len = wlen; } ep->c_nlines = lno; @@ -599,7 +596,7 @@ db_err(SCR *sp, db_recno_t lno) * Update all of the screens that are backed by the file that * just changed. */ -static int +int scr_update(SCR *sp, db_recno_t lno, lnop_t op, int current) { EXF *ep; @@ -623,169 +620,97 @@ scr_update(SCR *sp, db_recno_t lno, lnop_t op, int current) } /* - * DB1->3 compatibility layer + * PUBLIC: void update_cache __P((SCR *sp, lnop_t op, db_recno_t lno)); */ +void +update_cache(SCR *sp, lnop_t op, db_recno_t lno) +{ + SCR* scrp; + EXF *ep; -#include -#include - -#undef O_SHLOCK -#undef O_EXLOCK -#include - -static int db1_close(DB *, u_int32_t); -static int db1_open(DB *, const char *, const char *, DBTYPE, u_int32_t, int); -static int db1_sync(DB *, u_int32_t); -static int db1_get(DB *, DB_TXN *, DBT *, DBT *, u_int32_t); -static int db1_put(DB *, DB_TXN *, DBT *, DBT *, u_int32_t); -static int db1_set_flags(DB *, u_int32_t); -static int db1_set_pagesize(DB *, u_int32_t); -static int db1_set_re_delim(DB *, int); -static int db1_set_re_source(DB *, const char *); - -int -db_create(DB **dbp, DB_ENV *dbenv, u_int32_t flags) { - assert(dbenv == NULL && flags == 0); - - *dbp = malloc(sizeof **dbp); - if (*dbp == NULL) - return -1; - - (*dbp)->type = DB_UNKNOWN; - (*dbp)->actual_db = NULL; - (*dbp)->_pagesize = 0; - (*dbp)->_flags = 0; - memset(&(*dbp)->_recno_info, 0, sizeof (RECNOINFO)); - - (*dbp)->close = db1_close; - (*dbp)->open = db1_open; - (*dbp)->sync = db1_sync; - (*dbp)->get = db1_get; - (*dbp)->put = db1_put; - (*dbp)->set_flags = db1_set_flags; - (*dbp)->set_pagesize = db1_set_pagesize; - (*dbp)->set_re_delim = db1_set_re_delim; - (*dbp)->set_re_source = db1_set_re_source; + ep = sp->ep; - return 0; -} + /* Flush the cache, update line count, before screen update. */ + /* The flushing is probably not needed, since it was incorrect + * for db_insert. It might be better to adjust it, like + * marks, @ and global + */ + for (scrp = ep->scrq.cqh_first; scrp != (void *)&ep->scrq; + scrp = scrp->eq.cqe_next) + switch (op) { + case LINE_INSERT: + case LINE_DELETE: + if (lno <= scrp->c_lno) + scrp->c_lno = OOBLNO; + break; + case LINE_RESET: + if (lno == scrp->c_lno) + scrp->c_lno = OOBLNO; + break; + } -char * -db_strerror(int error) { - return error > 0? strerror(error) : "record not found"; + if (ep->c_nlines != OOBLNO) + switch (op) { + case LINE_INSERT: + ++ep->c_nlines; + break; + case LINE_DELETE: + --ep->c_nlines; + break; + } } -static int -db1_close(DB *db, u_int32_t flags) { - if (flags & DB_NOSYNC) { - /* XXX warn user? */ - } - db->actual_db->close(db->actual_db); - - db->type = DB_UNKNOWN; - db->actual_db = NULL; - db->_pagesize = 0; - db->_flags = 0; - memset(&db->_recno_info, 0, sizeof (RECNOINFO)); +/* + * PUBLIC: int db_msg_open __P((SCR *, char *, DB **)); + */ +int db_msg_open(SCR *sp, char *file, DB **dbp) +{ + *dbp = dbopen(file, O_NONBLOCK | O_RDONLY, 0, DB_RECNO, NULL); - return 0; + return *dbp == NULL; } -static int -db1_open(DB *db, const char *file, const char *database, DBTYPE type, - u_int32_t flags, int mode) { - int oldflags = 0; - - assert(database == NULL && !(flags & ~(DB_CREATE | DB_TRUNCATE))); - - db->type = type; - - if (flags & DB_CREATE) - oldflags |= O_CREAT; - if (flags & DB_TRUNCATE) - oldflags |= O_TRUNC; - - if (type == DB_RECNO) { - char *tmp = (char *) file; - - /* The interface is reversed in DB3 */ - file = db->_recno_info.bfname; - db->_recno_info.bfname = tmp; - - /* ... and so, we should avoid to truncate the main file! */ - oldflags &= ~O_TRUNC; - - db->_recno_info.flags = - db->_flags & DB_SNAPSHOT? R_SNAPSHOT : 0; - db->_recno_info.psize = db->_pagesize; +/* + * PUBLIC: int db_init __P((SCR *, EXF *, char *, char *, size_t, int *)); + */ +int +db_init(SCR *sp, EXF *ep, char *rcv_name, char *oname, size_t psize, int *open_err) +{ + RECNOINFO oinfo; + + memset(&oinfo, 0, sizeof(RECNOINFO)); + oinfo.bval = '\n'; /* Always set. */ + oinfo.psize = psize; + oinfo.flags = R_SNAPSHOT; + if (rcv_name) + oinfo.bfname = ep->rcv_path; + +#define _DB_OPEN_MODE S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH + + ep->db = dbopen(rcv_name == NULL ? oname : NULL, + O_NONBLOCK | O_RDONLY, _DB_OPEN_MODE, DB_RECNO, &oinfo); + + if (!ep->db) { + msgq_str(sp, + M_DBERR, rcv_name == NULL ? oname : rcv_name, "%s"); + /* + * !!! + * Historically, vi permitted users to edit files that couldn't + * be read. This isn't useful for single files from a command + * line, but it's quite useful for "vi *.c", since you can skip + * past files that you can't read. + */ + ep->db = NULL; /* Don't close it; it wasn't opened */ + + *open_err = 1; + return 1; } - db->actual_db = dbopen(file, oldflags, mode, type, - type == DB_RECNO? &db->_recno_info : NULL); - - return db->actual_db == NULL? errno : 0; -} - -static int -db1_sync(DB *db, u_int32_t flags) { - assert(flags == 0); - - return db->actual_db->sync(db->actual_db, db->type == DB_UNKNOWN? - R_RECNOSYNC : 0) == 0? 0 : errno; -} - -static int -db1_get(DB *db, DB_TXN *txnid, DBT *key, DBT *data, u_int32_t flags) { - int err; - - assert(flags == 0 && txnid == NULL); - - err = db->actual_db->get(db->actual_db, key, data, flags); - - return err == -1? errno : err; -} - -static int -db1_put(DB *db, DB_TXN *txnid, DBT *key, DBT *data, u_int32_t flags) { - int err; - - assert(flags == 0 && txnid == NULL); - - err = db->actual_db->put(db->actual_db, key, data, flags); - - return err == -1? errno : err; -} - -static int -db1_set_flags(DB *db, u_int32_t flags) { - assert((flags & ~(DB_RENUMBER | DB_SNAPSHOT)) == 0); - - /* Can't prevent renumbering from happening with DB1 */ - assert((flags | db->_flags) & DB_RENUMBER); - - - db->_flags |= flags; - return 0; } -static int -db1_set_pagesize(DB *db, u_int32_t pagesize) { - db->_pagesize = pagesize; - - return 0; -} - -static int -db1_set_re_delim(DB *db, int re_delim) { - db->_recno_info.bval = re_delim; - - return 0; -} - -static int -db1_set_re_source(DB *db, const char *re_source) { - db->_recno_info.bfname = (char *) re_source; - - return 0; +char * +db_strerror(int error) +{ + return error > 0 ? strerror(error) : "record not found"; } diff --git a/dist/Makefile.am b/dist/Makefile.am index c1d6871a..db85a266 100644 --- a/dist/Makefile.am +++ b/dist/Makefile.am @@ -2,8 +2,46 @@ visrcdir= @srcdir@/.. ACLOCAL_AMFLAGS = -I m4 +if BUNDLED_DB + DB_C = $(visrcdir)/common/vi_db1.c + DB_SRCS = \ + $(visrcdir)/db.1.85/recno/rec_delete.c \ + $(visrcdir)/db.1.85/recno/rec_get.c \ + $(visrcdir)/db.1.85/recno/rec_put.c \ + $(visrcdir)/db.1.85/recno/rec_utils.c \ + $(visrcdir)/db.1.85/recno/rec_open.c \ + $(visrcdir)/db.1.85/recno/rec_seq.c \ + $(visrcdir)/db.1.85/recno/rec_close.c \ + $(visrcdir)/db.1.85/recno/rec_search.c \ + $(visrcdir)/db.1.85/db/db.c \ + $(visrcdir)/db.1.85/btree/bt_debug.c \ + $(visrcdir)/db.1.85/btree/bt_get.c \ + $(visrcdir)/db.1.85/btree/bt_open.c \ + $(visrcdir)/db.1.85/btree/bt_delete.c \ + $(visrcdir)/db.1.85/btree/bt_put.c \ + $(visrcdir)/db.1.85/btree/bt_overflow.c \ + $(visrcdir)/db.1.85/btree/bt_close.c \ + $(visrcdir)/db.1.85/btree/bt_page.c \ + $(visrcdir)/db.1.85/btree/bt_split.c \ + $(visrcdir)/db.1.85/btree/bt_search.c \ + $(visrcdir)/db.1.85/btree/bt_utils.c \ + $(visrcdir)/db.1.85/btree/bt_seq.c \ + $(visrcdir)/db.1.85/btree/bt_conv.c \ + $(visrcdir)/db.1.85/mpool/mpool.c \ + $(visrcdir)/db.1.85/hash/hash_bigkey.c \ + $(visrcdir)/db.1.85/hash/hash_log2.c \ + $(visrcdir)/db.1.85/hash/hash.c \ + $(visrcdir)/db.1.85/hash/hash_func.c \ + $(visrcdir)/db.1.85/hash/hash_page.c \ + $(visrcdir)/db.1.85/hash/hash_buf.c \ + $(visrcdir)/db.1.85/hash/hsearch.c +else + DB_C = $(visrcdir)/common/vi_db.c +endif + lib_LTLIBRARIES = libvi.la libvi_la_SOURCES = \ + $(DB_SRCS) \ $(visrcdir)/common/api.c \ $(visrcdir)/common/conv.c \ $(visrcdir)/common/conv.h \ @@ -12,7 +50,7 @@ libvi_la_SOURCES = \ $(visrcdir)/common/args.h \ $(visrcdir)/common/common.h \ $(visrcdir)/common/cut.h \ - $(visrcdir)/common/db.h \ + $(visrcdir)/common/vi_db.h \ $(visrcdir)/common/exf.h \ $(visrcdir)/common/gs.h \ $(visrcdir)/common/key.h \ @@ -85,7 +123,7 @@ libvi_la_SOURCES = \ $(visrcdir)/vi/vi.h \ $(visrcdir)/common/gs.c \ $(visrcdir)/common/key.c \ - $(visrcdir)/common/db.c \ + $(DB_C) \ $(visrcdir)/common/main.c \ $(visrcdir)/common/mark.c \ $(visrcdir)/common/msg.c \ @@ -148,8 +186,11 @@ EXTRA_libvi_la_SOURCES = \ $(visrcdir)/regex/regex.h \ $(visrcdir)/regex/regex2.h \ $(visrcdir)/regex/utils.h \ + $(visrcdir)/common/vi_db.c \ + $(visrcdir)/common/vi_db1.c \ $(visrcdir)/common/dldb.c \ $(visrcdir)/common/log.c \ + $(visrcdir)/common/log1.c \ $(visrcdir)/common/log4.c \ $(visrcdir)/clib/bsearch.c \ $(visrcdir)/clib/env.c \ @@ -189,7 +230,7 @@ vi_SOURCES = \ $(visrcdir)/cl/cl_term.c \ $(visrcdir)/common/nothread.c vi_LDADD = libvi.la @perllibs@ @CURSLIBS@ -vi_CPPFLAGS = @CURSCPPFLAGS@ @perlldflags@ $(AM_CPPFLAGS) +vi_CPPFLAGS = $(AM_CPPFLAGS) @CURSCPPFLAGS@ @perlldflags@ vi_LDFLAGS = @CURSLDFLAGS@ @perlldflags@ vi_ipc_SOURCES = \ @@ -243,7 +284,12 @@ vi_motif_CFLAGS = @XINCS@ VI=-DVI=\"$(bindir)/`echo vi-ipc | sed '$(transform)'`\" CFLAGS= $(OPTFLAG) +if BUNDLED_DB +AM_CPPFLAGS= -D__DBINTERFACE_PRIVATE -I$(visrcdir)/db.1.85/include \ + -D__REGEX_PRIVATE -I. -I$(visrcdir)/include $(VI) +else AM_CPPFLAGS= -D__REGEX_PRIVATE -I. -I$(visrcdir)/include $(VI) +endif PERL= @vi_cv_path_perl@ PERLLIB=@vi_cv_perllib@ SHRPENV=@shrpenv@ diff --git a/dist/acconfig.h b/dist/acconfig.h index bd720c9c..1e622756 100644 --- a/dist/acconfig.h +++ b/dist/acconfig.h @@ -96,8 +96,8 @@ /* Define if your sprintf returns a pointer, not a length. */ #undef SPRINTF_RET_CHARPNT -/* Define when using db1 */ -#undef USE_DB1 +/* Define when using bundled db */ +#undef USE_BUNDLED_DB /* Define when using db4 logging */ #undef USE_DB4_LOGGING diff --git a/dist/configure.in b/dist/configure.in index f91c8fce..f0f9e607 100644 --- a/dist/configure.in +++ b/dist/configure.in @@ -948,30 +948,45 @@ fi AC_ARG_WITH(db_type, [ --with-db=bundled|system Which db to use. ]) + +dnl Check for DB 3 +AC_ARG_WITH(db_prefix, + [ --with-db-prefix=PFX Path to db installation. ]) + +AC_SUBST(DB_LDFLAGS) +AC_SUBST(DB_CPPFLAGS) +if test "x$with_db_prefix" != "x"; then + DB_LDFLAGS="-L$with_db_prefix/lib $LDFLAGS" + DB_CPPFLAGS="-I$with_db_prefix/include $CPPFLAGS" + with_db_type="system" +fi + +AC_MSG_CHECKING(which db to use) case "$with_db_type" in -"db1") - AC_MSG_WARN([Use of db1 is not officially supported.]) - AC_DEFINE(USE_DB1) - ;; "system") ;; *) with_db_type="bundled" ;; esac +AC_MSG_RESULT($with_db_type) +AM_CONDITIONAL(BUNDLED_DB, test $with_db_type = bundled) -dnl Check for DB 3 -AC_ARG_WITH(db_prefix, - [ --with-db-prefix=PFX Path to db installation. ]) - -SAVELDFLAGS="$LDFLAGS" -if test "x$with_db_prefix" != "x"; then - LDFLAGS="-L$with_db_prefix/lib $LDFLAGS" - CPPFLAGS="-I$with_db_prefix/include $CPPFLAGS" -fi -if test "$with_db_type" != db1; then +case "$with_db_type" in +bundled) + AC_DEFINE(USE_BUNDLED_DB) + LIBOBJS="log1.o $LIBOBJS" + ;; +system) + SAVELDFLAGS="$LDFLAGS" SAVELIBS="$LIBS" + if test "x$with_db_prefix" != "x"; then + LDFLAGS="-L$with_db_prefix/lib $LDFLAGS" + CPPFLAGS="-I$with_db_prefix/include $CPPFLAGS" + with_db_type="system" + fi + LIBS="$LIBS -ldb" AC_TRY_LINK([#include ], [db_create(NULL,NULL,0)], @@ -981,78 +996,79 @@ if test "$with_db_type" != db1; then fi LIBS="$SAVELIBS" -fi -LDFLAGS="$SAVELDFLAGS" - -AC_SUBST(dl_src) -AC_MSG_CHECKING(if --enable-dynamic-loading option specified) -AC_ARG_ENABLE(dynamic-loading, - [ --enable-dynamic-loading Load DB 3 dynamically.], - [vi_cv_dl=$enableval], [vi_cv_dl="no"]) -AC_MSG_RESULT($vi_cv_dl) -if test "$vi_cv_dl" = yes; then - AC_CHECK_LIB(dl, dlopen, - [vi_cv_dlfatal="no"], [vi_cv_dlfatal="yes"]) - if test "$vi_cv_dlfatal" = "yes"; then - AC_MSG_ERROR([Need dl to support dynamic loading.]) - fi - OLDPATH="$PATH" + LDFLAGS="$SAVELDFLAGS" - PATH="$with_db_prefix/lib:/usr/lib:/lib" - AC_PATH_PROG(vi_cv_path_db3, libdb-3.so, no) - if test "$vi_cv_path_db3" = no; then - AC_MSG_ERROR([Path of libdb-3.so not found.]) - fi - PATH="$OLDPATH" + AC_SUBST(dl_src) + AC_MSG_CHECKING(if --enable-dynamic-loading option specified) + AC_ARG_ENABLE(dynamic-loading, + [ --enable-dynamic-loading Load DB 3 dynamically.], + [vi_cv_dl=$enableval], [vi_cv_dl="no"]) + AC_MSG_RESULT($vi_cv_dl) + if test "$vi_cv_dl" = yes; then + AC_CHECK_LIB(dl, dlopen, + [vi_cv_dlfatal="no"], [vi_cv_dlfatal="yes"]) + if test "$vi_cv_dlfatal" = "yes"; then + AC_MSG_ERROR([Need dl to support dynamic loading.]) + fi + OLDPATH="$PATH" - AC_DEFINE(USE_DYNAMIC_LOADING) - LIBOBJS="dldb.o $LIBOBJS" - dl_src=../common/dldb.c - LIBS="-ldl $LIBS" -else - LIBS="-ldb $LIBS" - if test "X$with_db_prefix" != "X"; then - LDFLAGS="`echo $with_db_prefix/lib | sed "$LRscript"` $LDFLAGS" + PATH="$with_db_prefix/lib:/usr/lib:/lib" + AC_PATH_PROG(vi_cv_path_db3, libdb-3.so, no) + if test "$vi_cv_path_db3" = no; then + AC_MSG_ERROR([Path of libdb-3.so not found.]) + fi + PATH="$OLDPATH" + + AC_DEFINE(USE_DYNAMIC_LOADING) + LIBOBJS="dldb.o $LIBOBJS" + dl_src=../common/dldb.c + LIBS="-ldl $LIBS" + else + LIBS="-ldb $LIBS" + if test "X$with_db_prefix" != "X"; then + LDFLAGS="`echo $with_db_prefix/lib | sed "$LRscript"` $LDFLAGS" + fi fi -fi -AC_ARG_WITH(db_build, - [ --with-db-build=prefix Path to db build. ]) -if test "x$with_db_build" != "x"; then - vi_cv_dbsrc=`$AWK '/^srcdir/ {gsub("srcdir[[ \t]]*=","");print $1}' \ - $with_db_build/Makefile` - case $with_db_build in - *[[\\/]]);; - *) - with_db_build="$with_db_build/";; - esac - case $vi_cv_dbsrc in - [[\\/]]*);; - *) - vi_cv_dbsrc="$with_db_build$vi_cv_dbsrc";; - esac -fi; - -vi_cv_db4="no" -AC_ARG_ENABLE(log4, - [ --enable-db4-logging Enable experimental/broken db4 logging.], - [ - AC_MSG_CHECKING(for DB 4) - AC_EGREP_CPP([^4], - [#include - DB_VERSION_MAJOR], - [vi_cv_db4="yes"], [vi_cv_db4="no"]) - AC_MSG_RESULT($vi_cv_db4) - ]) -if test "$vi_cv_db4" = "yes"; then - CPPFLAGS="-I$vi_cv_dbsrc/include $CPPFLAGS" - CPPFLAGS="-I$vi_cv_dbsrc/include_auto $CPPFLAGS" - CPPFLAGS="-I$with_db_build $CPPFLAGS" - AC_DEFINE(USE_DB4_LOGGING) - LIBOBJS="log4.o vi_auto.o vi_rec.o $LIBOBJS" -else - LIBOBJS="log.o $LIBOBJS" -fi + AC_ARG_WITH(db_build, + [ --with-db-build=prefix Path to db build. ]) + if test "x$with_db_build" != "x"; then + vi_cv_dbsrc=`$AWK '/^srcdir/ {gsub("srcdir[[ \t]]*=","");print $1}' \ + $with_db_build/Makefile` + case $with_db_build in + *[[\\/]]);; + *) + with_db_build="$with_db_build/";; + esac + case $vi_cv_dbsrc in + [[\\/]]*);; + *) + vi_cv_dbsrc="$with_db_build$vi_cv_dbsrc";; + esac + fi; + + vi_cv_db4="no" + AC_ARG_ENABLE(log4, + [ --enable-db4-logging Enable experimental/broken db4 logging.], + [ + AC_MSG_CHECKING(for DB 4) + AC_EGREP_CPP([^4], + [#include + DB_VERSION_MAJOR], + [vi_cv_db4="yes"], [vi_cv_db4="no"]) + AC_MSG_RESULT($vi_cv_db4) + ]) + if test "$vi_cv_db4" = "yes"; then + DB_CPPFLAGS="-I$vi_cv_dbsrc/include $DB_CPPFLAGS" + DB_CPPFLAGS="-I$vi_cv_dbsrc/include_auto $DB_CPPFLAGS" + DB_CPPFLAGS="-I$with_db_build $DB_CPPFLAGS" + AC_DEFINE(USE_DB4_LOGGING) + LIBOBJS="log4.o vi_auto.o vi_rec.o $LIBOBJS" + else + LIBOBJS="log.o $LIBOBJS" + fi + ;; +esac dnl We compile in nvi's RE routines unless the user specifies otherwise. AC_MSG_CHECKING(if --disable-re option specified) -- 2.11.4.GIT