summaryrefslogtreecommitdiffstats
path: root/contrib/nvi/common/log.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/nvi/common/log.c')
-rw-r--r--contrib/nvi/common/log.c174
1 files changed, 112 insertions, 62 deletions
diff --git a/contrib/nvi/common/log.c b/contrib/nvi/common/log.c
index 9a9fe79..eb8d85b 100644
--- a/contrib/nvi/common/log.c
+++ b/contrib/nvi/common/log.c
@@ -10,7 +10,7 @@
#include "config.h"
#ifndef lint
-static const char sccsid[] = "@(#)log.c 10.8 (Berkeley) 3/6/96";
+static const char sccsid[] = "$Id: log.c,v 10.27 2011/07/13 06:25:50 zy Exp $";
#endif /* not lint */
#include <sys/types.h>
@@ -21,6 +21,7 @@ static const char sccsid[] = "@(#)log.c 10.8 (Berkeley) 3/6/96";
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
+#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -67,6 +68,8 @@ static void log_err __P((SCR *, char *, int));
#if defined(DEBUG) && 0
static void log_trace __P((SCR *, char *, recno_t, u_char *));
#endif
+static int apply_with __P((int (*)(SCR *, recno_t, CHAR_T *, size_t),
+ SCR *, recno_t, u_char *, size_t));
/* Try and restart the log on failure, i.e. if we run out of memory. */
#define LOG_ERR { \
@@ -74,6 +77,15 @@ static void log_trace __P((SCR *, char *, recno_t, u_char *));
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(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.
@@ -81,9 +93,9 @@ static void log_trace __P((SCR *, char *, recno_t, u_char *));
* PUBLIC: int log_init __P((SCR *, EXF *));
*/
int
-log_init(sp, ep)
- SCR *sp;
- EXF *ep;
+log_init(
+ SCR *sp,
+ EXF *ep)
{
/*
* !!!
@@ -117,9 +129,9 @@ log_init(sp, ep)
* PUBLIC: int log_end __P((SCR *, EXF *));
*/
int
-log_end(sp, ep)
- SCR *sp;
- EXF *ep;
+log_end(
+ SCR *sp,
+ EXF *ep)
{
/*
* !!!
@@ -147,8 +159,7 @@ log_end(sp, ep)
* PUBLIC: int log_cursor __P((SCR *));
*/
int
-log_cursor(sp)
- SCR *sp;
+log_cursor(SCR *sp)
{
EXF *ep;
@@ -175,15 +186,16 @@ log_cursor(sp)
* Actually push a cursor record out.
*/
static int
-log_cursor1(sp, type)
- SCR *sp;
- int type;
+log_cursor1(
+ SCR *sp,
+ int type)
{
DBT data, key;
EXF *ep;
ep = sp->ep;
- BINC_RET(sp, ep->l_lp, ep->l_len, sizeof(u_char) + sizeof(MARK));
+
+ BINC_RETC(sp, ep->l_lp, ep->l_len, sizeof(u_char) + sizeof(MARK));
ep->l_lp[0] = type;
memmove(ep->l_lp + sizeof(u_char), &ep->l_cursor, sizeof(MARK));
@@ -212,15 +224,16 @@ log_cursor1(sp, type)
* PUBLIC: int log_line __P((SCR *, recno_t, u_int));
*/
int
-log_line(sp, lno, action)
- SCR *sp;
- recno_t lno;
- u_int action;
+log_line(
+ SCR *sp,
+ recno_t lno,
+ u_int action)
{
DBT data, key;
EXF *ep;
size_t len;
- char *lp;
+ CHAR_T *lp;
+ recno_t lcur;
ep = sp->ep;
if (F_ISSET(ep, F_NOLOG))
@@ -254,28 +267,30 @@ log_line(sp, lno, action)
return (1);
}
len = 0;
- lp = "";
+ lp = L("");
}
} else
if (db_get(sp, lno, DBG_FATAL, &lp, &len))
return (1);
- BINC_RET(sp,
- ep->l_lp, ep->l_len, len + sizeof(u_char) + sizeof(recno_t));
+ BINC_RETC(sp,
+ ep->l_lp, ep->l_len,
+ len * sizeof(CHAR_T) + CHAR_T_OFFSET);
ep->l_lp[0] = action;
memmove(ep->l_lp + sizeof(u_char), &lno, sizeof(recno_t));
- memmove(ep->l_lp + sizeof(u_char) + sizeof(recno_t), lp, len);
+ memmove(ep->l_lp + CHAR_T_OFFSET, lp, len * sizeof(CHAR_T));
- key.data = &ep->l_cur;
+ lcur = ep->l_cur;
+ key.data = &lcur;
key.size = sizeof(recno_t);
data.data = ep->l_lp;
- data.size = len + sizeof(u_char) + sizeof(recno_t);
+ 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:
- TRACE(sp, "%u: log_line: append: %lu {%u}\n",
+ TRACE(sp, "%lu: log_line: append: %lu {%u}\n",
ep->l_cur, lno, len);
break;
case LOG_LINE_DELETE:
@@ -312,9 +327,9 @@ log_line(sp, lno, action)
* PUBLIC: int log_mark __P((SCR *, LMARK *));
*/
int
-log_mark(sp, lmp)
- SCR *sp;
- LMARK *lmp;
+log_mark(
+ SCR *sp,
+ LMARK *lmp)
{
DBT data, key;
EXF *ep;
@@ -330,7 +345,7 @@ log_mark(sp, lmp)
ep->l_cursor.lno = OOBLNO;
}
- BINC_RET(sp, ep->l_lp,
+ BINC_RETC(sp, ep->l_lp,
ep->l_len, sizeof(u_char) + sizeof(LMARK));
ep->l_lp[0] = LOG_MARK;
memmove(ep->l_lp + sizeof(u_char), lmp, sizeof(LMARK));
@@ -358,9 +373,9 @@ log_mark(sp, lmp)
* PUBLIC: int log_backward __P((SCR *, MARK *));
*/
int
-log_backward(sp, rp)
- SCR *sp;
- MARK *rp;
+log_backward(
+ SCR *sp,
+ MARK *rp)
{
DBT key, data;
EXF *ep;
@@ -414,9 +429,8 @@ log_backward(sp, rp)
case LOG_LINE_DELETE:
didop = 1;
memmove(&lno, p + sizeof(u_char), sizeof(recno_t));
- if (db_insert(sp, lno, p + sizeof(u_char) +
- sizeof(recno_t), data.size - sizeof(u_char) -
- sizeof(recno_t)))
+ if (apply_with(db_insert, sp, lno,
+ p + CHAR_T_OFFSET, data.size - CHAR_T_OFFSET))
goto err;
++sp->rptlines[L_ADDED];
break;
@@ -425,9 +439,8 @@ log_backward(sp, rp)
case LOG_LINE_RESET_B:
didop = 1;
memmove(&lno, p + sizeof(u_char), sizeof(recno_t));
- if (db_set(sp, lno, p + sizeof(u_char) +
- sizeof(recno_t), data.size - sizeof(u_char) -
- sizeof(recno_t)))
+ if (apply_with(db_set, sp, lno,
+ p + CHAR_T_OFFSET, data.size - CHAR_T_OFFSET))
goto err;
if (sp->rptlchange != lno) {
sp->rptlchange = lno;
@@ -464,8 +477,7 @@ err: F_CLR(ep, F_NOLOG);
* PUBLIC: int log_setline __P((SCR *));
*/
int
-log_setline(sp)
- SCR *sp;
+log_setline(SCR *sp)
{
DBT key, data;
EXF *ep;
@@ -488,7 +500,6 @@ log_setline(sp)
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))
@@ -520,9 +531,8 @@ log_setline(sp)
case LOG_LINE_RESET_B:
memmove(&lno, p + sizeof(u_char), sizeof(recno_t));
if (lno == sp->lno &&
- db_set(sp, lno, p + sizeof(u_char) +
- sizeof(recno_t), data.size - sizeof(u_char) -
- sizeof(recno_t)))
+ apply_with(db_set, sp, lno,
+ p + CHAR_T_OFFSET, data.size - CHAR_T_OFFSET))
goto err;
if (sp->rptlchange != lno) {
sp->rptlchange = lno;
@@ -551,9 +561,9 @@ err: F_CLR(ep, F_NOLOG);
* PUBLIC: int log_forward __P((SCR *, MARK *));
*/
int
-log_forward(sp, rp)
- SCR *sp;
- MARK *rp;
+log_forward(
+ SCR *sp,
+ MARK *rp)
{
DBT key, data;
EXF *ep;
@@ -601,9 +611,8 @@ log_forward(sp, rp)
case LOG_LINE_INSERT:
didop = 1;
memmove(&lno, p + sizeof(u_char), sizeof(recno_t));
- if (db_insert(sp, lno, p + sizeof(u_char) +
- sizeof(recno_t), data.size - sizeof(u_char) -
- sizeof(recno_t)))
+ if (apply_with(db_insert, sp, lno,
+ p + CHAR_T_OFFSET, data.size - CHAR_T_OFFSET))
goto err;
++sp->rptlines[L_ADDED];
break;
@@ -619,9 +628,8 @@ log_forward(sp, rp)
case LOG_LINE_RESET_F:
didop = 1;
memmove(&lno, p + sizeof(u_char), sizeof(recno_t));
- if (db_set(sp, lno, p + sizeof(u_char) +
- sizeof(recno_t), data.size - sizeof(u_char) -
- sizeof(recno_t)))
+ if (apply_with(db_set, sp, lno,
+ p + CHAR_T_OFFSET, data.size - CHAR_T_OFFSET))
goto err;
if (sp->rptlchange != lno) {
sp->rptlchange = lno;
@@ -650,10 +658,10 @@ err: F_CLR(ep, F_NOLOG);
* Try and restart the log on failure, i.e. if we run out of memory.
*/
static void
-log_err(sp, file, line)
- SCR *sp;
- char *file;
- int line;
+log_err(
+ SCR *sp,
+ char *file,
+ int line)
{
EXF *ep;
@@ -666,11 +674,11 @@ log_err(sp, file, line)
#if defined(DEBUG) && 0
static void
-log_trace(sp, msg, rno, p)
- SCR *sp;
- char *msg;
- recno_t rno;
- u_char *p;
+log_trace(
+ SCR *sp,
+ char *msg,
+ recno_t rno,
+ u_char *p)
{
LMARK lm;
MARK m;
@@ -715,3 +723,45 @@ log_trace(sp, msg, rno, p)
}
}
#endif
+
+/*
+ * apply_with --
+ * Apply a realigned line from the log db to the file db.
+ */
+static int
+apply_with(
+ int (*db_func)(SCR *, recno_t, CHAR_T *, size_t),
+ SCR *sp,
+ recno_t lno,
+ u_char *p,
+ size_t len)
+{
+#ifdef USE_WIDECHAR
+ typedef unsigned long nword;
+
+ static size_t blen;
+ static nword *bp;
+ nword *lp = (nword *)((uintptr_t)p / sizeof(nword) * sizeof(nword));
+
+ if (lp != (nword *)p) {
+ int offl = ((uintptr_t)p - (uintptr_t)lp) << 3;
+ int offr = (sizeof(nword) << 3) - offl;
+ size_t i, cnt = (len + sizeof(nword) / 2) / sizeof(nword);
+
+ if (len > blen) {
+ blen = p2roundup(MAX(len, 512));
+ REALLOC(sp, bp, nword *, blen);
+ if (bp == NULL)
+ return (1);
+ }
+ for (i = 0; i < cnt; ++i)
+#if BYTE_ORDER == BIG_ENDIAN
+ bp[i] = (lp[i] << offl) ^ (lp[i+1] >> offr);
+#else
+ bp[i] = (lp[i] >> offl) ^ (lp[i+1] << offr);
+#endif
+ p = (u_char *)bp;
+ }
+#endif
+ return db_func(sp, lno, (CHAR_T *)p, len / sizeof(CHAR_T));
+}
OpenPOWER on IntegriCloud