Expand PMF_FN_* macros.
[netbsd-mini2440.git] / dist / nvi / common / log.c
bloba89b3972017840ebb5ed4d3bb88d0b442fa0aae9
1 /* $NetBSD: log.c,v 1.1.1.2 2008/05/18 14:29:46 aymeric Exp $ */
3 /*-
4 * Copyright (c) 1992, 1993, 1994
5 * The Regents of the University of California. All rights reserved.
6 * Copyright (c) 1992, 1993, 1994, 1995, 1996
7 * Keith Bostic. All rights reserved.
9 * See the LICENSE file for redistribution information.
12 #include "config.h"
14 #ifndef lint
15 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";
16 #endif /* not lint */
18 #include <sys/types.h>
19 #include <sys/queue.h>
20 #include <sys/stat.h>
22 #include <bitstring.h>
23 #include <errno.h>
24 #include <fcntl.h>
25 #include <limits.h>
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
30 #include "common.h"
31 #include "dbinternal.h"
34 * The log consists of records, each containing a type byte and a variable
35 * length byte string, as follows:
37 * LOG_CURSOR_INIT MARK
38 * LOG_CURSOR_END MARK
39 * LOG_LINE_APPEND_F db_recno_t char *
40 * LOG_LINE_APPEND_B db_recno_t char *
41 * LOG_LINE_DELETE_F db_recno_t char *
42 * LOG_LINE_DELETE_B db_recno_t char *
43 * LOG_LINE_RESET_F db_recno_t char *
44 * LOG_LINE_RESET_B db_recno_t char *
45 * LOG_MARK LMARK
47 * We do before image physical logging. This means that the editor layer
48 * MAY NOT modify records in place, even if simply deleting or overwriting
49 * characters. Since the smallest unit of logging is a line, we're using
50 * up lots of space. This may eventually have to be reduced, probably by
51 * doing logical logging, which is a much cooler database phrase.
53 * The implementation of the historic vi 'u' command, using roll-forward and
54 * roll-back, is simple. Each set of changes has a LOG_CURSOR_INIT record,
55 * followed by a number of other records, followed by a LOG_CURSOR_END record.
56 * LOG_LINE_RESET records come in pairs. The first is a LOG_LINE_RESET_B
57 * record, and is the line before the change. The second is LOG_LINE_RESET_F,
58 * and is the line after the change. Roll-back is done by backing up to the
59 * first LOG_CURSOR_INIT record before a change. Roll-forward is done in a
60 * similar fashion.
62 * The 'U' command is implemented by rolling backward to a LOG_CURSOR_END
63 * record for a line different from the current one. It should be noted that
64 * this means that a subsequent 'u' command will make a change based on the
65 * new position of the log's cursor. This is okay, and, in fact, historic vi
66 * behaved that way.
69 static int vi_log_get __P((SCR *sp, db_recno_t *lnop, size_t *size));
70 static int log_cursor1 __P((SCR *, int));
71 static void log_err __P((SCR *, const char *, int));
72 #if defined(DEBUG) && 0
73 static void log_trace __P((SCR *, const char *, db_recno_t, u_char *));
74 #endif
76 /* Try and restart the log on failure, i.e. if we run out of memory. */
77 #define LOG_ERR { \
78 log_err(sp, __FILE__, __LINE__); \
79 return (1); \
82 /* offset of CHAR_T string in log needs to be aligned on some systems
83 * because it is passed to db_set as a string
85 typedef struct {
86 char data[sizeof(u_char) /* type */ + sizeof(db_recno_t)];
87 CHAR_T str[1];
88 } log_t;
89 #define CHAR_T_OFFSET ((char *)(((log_t*)0)->str) - (char *)0)
92 * log_init --
93 * Initialize the logging subsystem.
95 * PUBLIC: int log_init __P((SCR *, EXF *));
97 int
98 log_init(SCR *sp, EXF *ep)
101 * !!!
102 * ep MAY NOT BE THE SAME AS sp->ep, DON'T USE THE LATTER.
104 * Initialize the buffer. The logging subsystem has its own
105 * buffers because the global ones are almost by definition
106 * going to be in use when the log runs.
108 sp->wp->l_lp = NULL;
109 sp->wp->l_len = 0;
110 ep->l_cursor.lno = 1; /* XXX Any valid recno. */
111 ep->l_cursor.cno = 0;
112 ep->l_high = ep->l_cur = 1;
114 if (db_create(&ep->log, 0, 0) != 0 ||
115 db_open(ep->log, NULL, DB_RECNO,
116 DB_CREATE | VI_DB_THREAD, S_IRUSR | S_IWUSR) != 0) {
117 msgq(sp, M_SYSERR, "009|Log file");
118 F_SET(ep, F_NOLOG);
119 return (1);
122 ep->l_win = NULL;
123 /*LOCK_INIT(sp->wp, ep);*/
125 return (0);
129 * log_end --
130 * Close the logging subsystem.
132 * PUBLIC: int log_end __P((SCR *, EXF *));
135 log_end(SCR *sp, EXF *ep)
138 * !!!
139 * ep MAY NOT BE THE SAME AS sp->ep, DON'T USE THE LATTER.
141 /*LOCK_END(sp->wp, ep);*/
142 if (ep->log != NULL) {
143 (void)(ep->log->close)(ep->log,DB_NOSYNC);
144 ep->log = NULL;
146 if (sp->wp->l_lp != NULL) {
147 free(sp->wp->l_lp);
148 sp->wp->l_lp = NULL;
150 sp->wp->l_len = 0;
151 ep->l_cursor.lno = 1; /* XXX Any valid recno. */
152 ep->l_cursor.cno = 0;
153 ep->l_high = ep->l_cur = 1;
154 return (0);
158 * log_cursor --
159 * Log the current cursor position, starting an event.
161 * PUBLIC: int log_cursor __P((SCR *));
164 log_cursor(SCR *sp)
166 EXF *ep;
168 ep = sp->ep;
169 if (F_ISSET(ep, F_NOLOG))
170 return (0);
173 * If any changes were made since the last cursor init,
174 * put out the ending cursor record.
176 if (ep->l_cursor.lno == OOBLNO) {
177 if (ep->l_win && ep->l_win != sp->wp)
178 return 0;
179 ep->l_cursor.lno = sp->lno;
180 ep->l_cursor.cno = sp->cno;
181 ep->l_win = NULL;
182 return (log_cursor1(sp, LOG_CURSOR_END));
184 ep->l_cursor.lno = sp->lno;
185 ep->l_cursor.cno = sp->cno;
186 return (0);
190 * log_cursor1 --
191 * Actually push a cursor record out.
193 static int
194 log_cursor1(SCR *sp, int type)
196 DBT data, key;
197 EXF *ep;
199 ep = sp->ep;
202 if (type == LOG_CURSOR_INIT &&
203 LOCK_TRY(sp->wp, ep))
204 return 1;
207 BINC_RETC(sp, sp->wp->l_lp, sp->wp->l_len, sizeof(u_char) + sizeof(MARK));
208 sp->wp->l_lp[0] = type;
209 memmove(sp->wp->l_lp + sizeof(u_char), &ep->l_cursor, sizeof(MARK));
211 memset(&key, 0, sizeof(key));
212 key.data = &ep->l_cur;
213 key.size = sizeof(db_recno_t);
214 memset(&data, 0, sizeof(data));
215 data.data = sp->wp->l_lp;
216 data.size = sizeof(u_char) + sizeof(MARK);
217 if (ep->log->put(ep->log, NULL, &key, &data, 0) == -1)
218 LOG_ERR;
220 #if defined(DEBUG) && 0
221 vtrace(sp, "%lu: %s: %u/%u\n", ep->l_cur,
222 type == LOG_CURSOR_INIT ? "log_cursor_init" : "log_cursor_end",
223 sp->lno, sp->cno);
224 #endif
225 /* Reset high water mark. */
226 ep->l_high = ++ep->l_cur;
229 if (type == LOG_CURSOR_END)
230 LOCK_UNLOCK(sp->wp, ep);
232 return (0);
236 * log_line --
237 * Log a line change.
239 * PUBLIC: int log_line __P((SCR *, db_recno_t, u_int));
242 log_line(SCR *sp, db_recno_t lno, u_int action)
244 DBT data, key;
245 EXF *ep;
246 size_t len;
247 CHAR_T *lp;
248 db_recno_t lcur;
250 ep = sp->ep;
251 if (F_ISSET(ep, F_NOLOG))
252 return (0);
255 * XXX
257 * Kluge for vi. Clear the EXF undo flag so that the
258 * next 'u' command does a roll-back, regardless.
260 F_CLR(ep, F_UNDO);
262 /* Put out one initial cursor record per set of changes. */
263 if (ep->l_cursor.lno != OOBLNO) {
264 if (log_cursor1(sp, LOG_CURSOR_INIT))
265 return (1);
266 ep->l_cursor.lno = OOBLNO;
267 ep->l_win = sp->wp;
268 } /*else if (ep->l_win != sp->wp) {
269 printf("log_line own: %p, this: %p\n", ep->l_win, sp->wp);
270 return 1;
273 switch (action) {
274 /* newly added for DB4 logging */
275 case LOG_LINE_APPEND_B:
276 case LOG_LINE_DELETE_F:
277 return 0;
281 * Put out the changes. If it's a LOG_LINE_RESET_B call, it's a
282 * special case, avoid the caches. Also, if it fails and it's
283 * line 1, it just means that the user started with an empty file,
284 * so fake an empty length line.
286 if (action == LOG_LINE_RESET_B) {
287 if (db_get(sp, lno, DBG_NOCACHE, &lp, &len)) {
288 static CHAR_T nul = 0;
289 if (lno != 1) {
290 db_err(sp, lno);
291 return (1);
293 len = 0;
294 lp = &nul;
296 } else
297 if (db_get(sp, lno, DBG_FATAL, &lp, &len))
298 return (1);
299 BINC_RETC(sp,
300 sp->wp->l_lp, sp->wp->l_len,
301 len * sizeof(CHAR_T) + CHAR_T_OFFSET);
302 sp->wp->l_lp[0] = action;
303 memmove(sp->wp->l_lp + sizeof(u_char), &lno, sizeof(db_recno_t));
304 MEMMOVEW(sp->wp->l_lp + CHAR_T_OFFSET, lp, len);
306 lcur = ep->l_cur;
307 memset(&key, 0, sizeof(key));
308 key.data = &lcur;
309 key.size = sizeof(db_recno_t);
310 memset(&data, 0, sizeof(data));
311 data.data = sp->wp->l_lp;
312 data.size = len * sizeof(CHAR_T) + CHAR_T_OFFSET;
313 if (ep->log->put(ep->log, NULL, &key, &data, 0) == -1)
314 LOG_ERR;
316 #if defined(DEBUG) && 0
317 switch (action) {
318 case LOG_LINE_APPEND_F:
319 vtrace(sp, "%u: log_line: append_f: %lu {%u}\n",
320 ep->l_cur, lno, len);
321 break;
322 case LOG_LINE_APPEND_B:
323 vtrace(sp, "%u: log_line: append_b: %lu {%u}\n",
324 ep->l_cur, lno, len);
325 break;
326 case LOG_LINE_DELETE_F:
327 vtrace(sp, "%lu: log_line: delete_f: %lu {%u}\n",
328 ep->l_cur, lno, len);
329 break;
330 case LOG_LINE_DELETE_B:
331 vtrace(sp, "%lu: log_line: delete_b: %lu {%u}\n",
332 ep->l_cur, lno, len);
333 break;
334 case LOG_LINE_RESET_F:
335 vtrace(sp, "%lu: log_line: reset_f: %lu {%u}\n",
336 ep->l_cur, lno, len);
337 break;
338 case LOG_LINE_RESET_B:
339 vtrace(sp, "%lu: log_line: reset_b: %lu {%u}\n",
340 ep->l_cur, lno, len);
341 break;
343 #endif
344 /* Reset high water mark. */
345 ep->l_high = ++ep->l_cur;
347 return (0);
351 * log_mark --
352 * Log a mark position. For the log to work, we assume that there
353 * aren't any operations that just put out a log record -- this
354 * would mean that undo operations would only reset marks, and not
355 * cause any other change.
357 * PUBLIC: int log_mark __P((SCR *, LMARK *));
360 log_mark(SCR *sp, LMARK *lmp)
362 DBT data, key;
363 EXF *ep;
365 ep = sp->ep;
366 if (F_ISSET(ep, F_NOLOG))
367 return (0);
369 /* Put out one initial cursor record per set of changes. */
370 if (ep->l_cursor.lno != OOBLNO) {
371 if (log_cursor1(sp, LOG_CURSOR_INIT))
372 return (1);
373 ep->l_cursor.lno = OOBLNO;
374 ep->l_win = sp->wp;
377 BINC_RETC(sp, sp->wp->l_lp,
378 sp->wp->l_len, sizeof(u_char) + sizeof(LMARK));
379 sp->wp->l_lp[0] = LOG_MARK;
380 memmove(sp->wp->l_lp + sizeof(u_char), lmp, sizeof(LMARK));
382 memset(&key, 0, sizeof(key));
383 key.data = &ep->l_cur;
384 key.size = sizeof(db_recno_t);
385 memset(&data, 0, sizeof(data));
386 data.data = sp->wp->l_lp;
387 data.size = sizeof(u_char) + sizeof(LMARK);
388 if (ep->log->put(ep->log, NULL, &key, &data, 0) == -1)
389 LOG_ERR;
391 #if defined(DEBUG) && 0
392 vtrace(sp, "%lu: mark %c: %lu/%u\n",
393 ep->l_cur, lmp->name, lmp->lno, lmp->cno);
394 #endif
395 /* Reset high water mark. */
396 ep->l_high = ++ep->l_cur;
397 return (0);
401 * vi_log_get --
402 * Get a line from the log in log buffer.
404 static int
405 vi_log_get(SCR *sp, db_recno_t *lnop, size_t *size)
407 DBT key, data;
408 size_t nlen;
409 EXF *ep;
411 ep = sp->ep;
413 nlen = 1024;
414 retry:
415 BINC_RETC(sp, sp->wp->l_lp, sp->wp->l_len, nlen);
417 memset(&key, 0, sizeof(key));
418 key.data = lnop; /* Initialize db request. */
419 key.size = sizeof(db_recno_t);
420 memset(&data, 0, sizeof(data));
421 data.data = sp->wp->l_lp;
422 data.ulen = sp->wp->l_len;
423 data.flags = DB_DBT_USERMEM;
424 switch (ep->log->get(ep->log, NULL, &key, &data, 0)) {
425 case ENOMEM:
426 nlen = data.size;
427 goto retry;
428 case 0:
429 *size = data.size;
430 return 0;
431 default:
432 return 1;
437 * Log_backward --
438 * Roll the log backward one operation.
440 * PUBLIC: int log_backward __P((SCR *, MARK *));
443 log_backward(SCR *sp, MARK *rp)
445 EXF *ep;
446 LMARK lm;
447 MARK m;
448 db_recno_t lno;
449 int didop;
450 u_char *p;
451 size_t size;
453 ep = sp->ep;
454 if (F_ISSET(ep, F_NOLOG)) {
455 msgq(sp, M_ERR,
456 "010|Logging not being performed, undo not possible");
457 return (1);
460 if (ep->l_cur == 1) {
461 msgq(sp, M_BERR, "011|No changes to undo");
462 return (1);
465 if (ep->l_win && ep->l_win != sp->wp) {
466 ex_emsg(sp, NULL, EXM_LOCKED);
467 return 1;
469 ep->l_win = sp->wp;
472 F_SET(ep, F_NOLOG); /* Turn off logging. */
474 for (didop = 0;;) {
475 --ep->l_cur;
476 if (vi_log_get(sp, &ep->l_cur, &size))
477 LOG_ERR;
478 #if defined(DEBUG) && 0
479 log_trace(sp, "log_backward", ep->l_cur, data.data);
480 #endif
481 switch (*(p = (u_char *)sp->wp->l_lp)) {
482 case LOG_CURSOR_INIT:
483 if (didop) {
484 memmove(rp, p + sizeof(u_char), sizeof(MARK));
485 F_CLR(ep, F_NOLOG);
486 ep->l_win = NULL;
487 return (0);
489 break;
490 case LOG_CURSOR_END:
491 break;
492 case LOG_LINE_APPEND_F:
493 didop = 1;
494 memmove(&lno, p + sizeof(u_char), sizeof(db_recno_t));
495 if (db_delete(sp, lno))
496 goto err;
497 ++sp->rptlines[L_DELETED];
498 break;
499 case LOG_LINE_DELETE_B:
500 didop = 1;
501 memmove(&lno, p + sizeof(u_char), sizeof(db_recno_t));
502 if (db_insert(sp, lno,
503 (CHAR_T *)(p + CHAR_T_OFFSET),
504 (size - CHAR_T_OFFSET) / sizeof(CHAR_T)))
505 goto err;
506 ++sp->rptlines[L_ADDED];
507 break;
508 case LOG_LINE_RESET_F:
509 break;
510 case LOG_LINE_RESET_B:
511 didop = 1;
512 memmove(&lno, p + sizeof(u_char), sizeof(db_recno_t));
513 if (db_set(sp, lno,
514 (CHAR_T *)(p + CHAR_T_OFFSET),
515 (size - CHAR_T_OFFSET) / sizeof(CHAR_T)))
516 goto err;
517 if (sp->rptlchange != lno) {
518 sp->rptlchange = lno;
519 ++sp->rptlines[L_CHANGED];
521 break;
522 case LOG_MARK:
523 didop = 1;
524 memmove(&lm, p + sizeof(u_char), sizeof(LMARK));
525 m.lno = lm.lno;
526 m.cno = lm.cno;
527 if (mark_set(sp, lm.name, &m, 0))
528 goto err;
529 break;
530 default:
531 abort();
535 err: F_CLR(ep, F_NOLOG);
536 ep->l_win = NULL;
537 return (1);
541 * Log_setline --
542 * Reset the line to its original appearance.
544 * XXX
545 * There's a bug in this code due to our not logging cursor movements
546 * unless a change was made. If you do a change, move off the line,
547 * then move back on and do a 'U', the line will be restored to the way
548 * it was before the original change.
550 * PUBLIC: int log_setline __P((SCR *));
553 log_setline(SCR *sp)
555 EXF *ep;
556 LMARK lm;
557 MARK m;
558 db_recno_t lno;
559 u_char *p;
560 size_t size;
562 ep = sp->ep;
563 if (F_ISSET(ep, F_NOLOG)) {
564 msgq(sp, M_ERR,
565 "012|Logging not being performed, undo not possible");
566 return (1);
569 if (ep->l_cur == 1)
570 return (1);
572 if (ep->l_win && ep->l_win != sp->wp) {
573 ex_emsg(sp, NULL, EXM_LOCKED);
574 return 1;
576 ep->l_win = sp->wp;
578 F_SET(ep, F_NOLOG); /* Turn off logging. */
580 for (;;) {
581 --ep->l_cur;
582 if (vi_log_get(sp, &ep->l_cur, &size))
583 LOG_ERR;
584 #if defined(DEBUG) && 0
585 log_trace(sp, "log_setline", ep->l_cur, data.data);
586 #endif
587 switch (*(p = (u_char *)sp->wp->l_lp)) {
588 case LOG_CURSOR_INIT:
589 memmove(&m, p + sizeof(u_char), sizeof(MARK));
590 if (m.lno != sp->lno || ep->l_cur == 1) {
591 F_CLR(ep, F_NOLOG);
592 ep->l_win = NULL;
593 return (0);
595 break;
596 case LOG_CURSOR_END:
597 memmove(&m, p + sizeof(u_char), sizeof(MARK));
598 if (m.lno != sp->lno) {
599 ++ep->l_cur;
600 F_CLR(ep, F_NOLOG);
601 ep->l_win = NULL;
602 return (0);
604 break;
605 case LOG_LINE_APPEND_F:
606 case LOG_LINE_DELETE_B:
607 case LOG_LINE_RESET_F:
608 break;
609 case LOG_LINE_RESET_B:
610 memmove(&lno, p + sizeof(u_char), sizeof(db_recno_t));
611 if (lno == sp->lno &&
612 db_set(sp, lno, (CHAR_T *)(p + CHAR_T_OFFSET),
613 (size - CHAR_T_OFFSET) / sizeof(CHAR_T)))
614 goto err;
615 if (sp->rptlchange != lno) {
616 sp->rptlchange = lno;
617 ++sp->rptlines[L_CHANGED];
619 case LOG_MARK:
620 memmove(&lm, p + sizeof(u_char), sizeof(LMARK));
621 m.lno = lm.lno;
622 m.cno = lm.cno;
623 if (mark_set(sp, lm.name, &m, 0))
624 goto err;
625 break;
626 default:
627 abort();
631 err: F_CLR(ep, F_NOLOG);
632 ep->l_win = NULL;
633 return (1);
637 * Log_forward --
638 * Roll the log forward one operation.
640 * PUBLIC: int log_forward __P((SCR *, MARK *));
643 log_forward(SCR *sp, MARK *rp)
645 EXF *ep;
646 LMARK lm;
647 MARK m;
648 db_recno_t lno;
649 int didop;
650 u_char *p;
651 size_t size;
653 ep = sp->ep;
654 if (F_ISSET(ep, F_NOLOG)) {
655 msgq(sp, M_ERR,
656 "013|Logging not being performed, roll-forward not possible");
657 return (1);
660 if (ep->l_cur == ep->l_high) {
661 msgq(sp, M_BERR, "014|No changes to re-do");
662 return (1);
665 if (ep->l_win && ep->l_win != sp->wp) {
666 ex_emsg(sp, NULL, EXM_LOCKED);
667 return 1;
669 ep->l_win = sp->wp;
671 F_SET(ep, F_NOLOG); /* Turn off logging. */
673 for (didop = 0;;) {
674 ++ep->l_cur;
675 if (vi_log_get(sp, &ep->l_cur, &size))
676 LOG_ERR;
677 #if defined(DEBUG) && 0
678 log_trace(sp, "log_forward", ep->l_cur, data.data);
679 #endif
680 switch (*(p = (u_char *)sp->wp->l_lp)) {
681 case LOG_CURSOR_END:
682 if (didop) {
683 ++ep->l_cur;
684 memmove(rp, p + sizeof(u_char), sizeof(MARK));
685 F_CLR(ep, F_NOLOG);
686 ep->l_win = NULL;
687 return (0);
689 break;
690 case LOG_CURSOR_INIT:
691 break;
692 case LOG_LINE_APPEND_F:
693 didop = 1;
694 memmove(&lno, p + sizeof(u_char), sizeof(db_recno_t));
695 if (db_insert(sp, lno,
696 (CHAR_T *)(p + CHAR_T_OFFSET),
697 (size - CHAR_T_OFFSET) / sizeof(CHAR_T)))
698 goto err;
699 ++sp->rptlines[L_ADDED];
700 break;
701 case LOG_LINE_DELETE_B:
702 didop = 1;
703 memmove(&lno, p + sizeof(u_char), sizeof(db_recno_t));
704 if (db_delete(sp, lno))
705 goto err;
706 ++sp->rptlines[L_DELETED];
707 break;
708 case LOG_LINE_RESET_B:
709 break;
710 case LOG_LINE_RESET_F:
711 didop = 1;
712 memmove(&lno, p + sizeof(u_char), sizeof(db_recno_t));
713 if (db_set(sp, lno,
714 (CHAR_T *)(p + CHAR_T_OFFSET),
715 (size - CHAR_T_OFFSET) / sizeof(CHAR_T)))
716 goto err;
717 if (sp->rptlchange != lno) {
718 sp->rptlchange = lno;
719 ++sp->rptlines[L_CHANGED];
721 break;
722 case LOG_MARK:
723 didop = 1;
724 memmove(&lm, p + sizeof(u_char), sizeof(LMARK));
725 m.lno = lm.lno;
726 m.cno = lm.cno;
727 if (mark_set(sp, lm.name, &m, 0))
728 goto err;
729 break;
730 default:
731 abort();
735 err: F_CLR(ep, F_NOLOG);
736 ep->l_win = NULL;
737 return (1);
741 * log_err --
742 * Try and restart the log on failure, i.e. if we run out of memory.
744 static void
745 log_err(SCR *sp, const char *file, int line)
747 EXF *ep;
749 msgq(sp, M_SYSERR, "015|%s/%d: log put error", tail(file), line);
750 ep = sp->ep;
751 (void)ep->log->close(ep->log, DB_NOSYNC);
752 if (!log_init(sp, ep))
753 msgq(sp, M_ERR, "267|Log restarted");
756 #if defined(DEBUG) && 0
757 static void
758 log_trace(SCR *sp, const char *msg, db_recno_t rno, u_char *p)
760 LMARK lm;
761 MARK m;
762 db_recno_t lno;
764 switch (*p) {
765 case LOG_CURSOR_INIT:
766 memmove(&m, p + sizeof(u_char), sizeof(MARK));
767 vtrace(sp, "%lu: %s: C_INIT: %u/%u\n", rno, msg, m.lno, m.cno);
768 break;
769 case LOG_CURSOR_END:
770 memmove(&m, p + sizeof(u_char), sizeof(MARK));
771 vtrace(sp, "%lu: %s: C_END: %u/%u\n", rno, msg, m.lno, m.cno);
772 break;
773 case LOG_LINE_APPEND_F:
774 memmove(&lno, p + sizeof(u_char), sizeof(db_recno_t));
775 vtrace(sp, "%lu: %s: APPEND_F: %lu\n", rno, msg, lno);
776 break;
777 case LOG_LINE_APPEND_B:
778 memmove(&lno, p + sizeof(u_char), sizeof(db_recno_t));
779 vtrace(sp, "%lu: %s: APPEND_B: %lu\n", rno, msg, lno);
780 break;
781 case LOG_LINE_DELETE_F:
782 memmove(&lno, p + sizeof(u_char), sizeof(db_recno_t));
783 vtrace(sp, "%lu: %s: DELETE_F: %lu\n", rno, msg, lno);
784 break;
785 case LOG_LINE_DELETE_B:
786 memmove(&lno, p + sizeof(u_char), sizeof(db_recno_t));
787 vtrace(sp, "%lu: %s: DELETE_B: %lu\n", rno, msg, lno);
788 break;
789 case LOG_LINE_RESET_F:
790 memmove(&lno, p + sizeof(u_char), sizeof(db_recno_t));
791 vtrace(sp, "%lu: %s: RESET_F: %lu\n", rno, msg, lno);
792 break;
793 case LOG_LINE_RESET_B:
794 memmove(&lno, p + sizeof(u_char), sizeof(db_recno_t));
795 vtrace(sp, "%lu: %s: RESET_B: %lu\n", rno, msg, lno);
796 break;
797 case LOG_MARK:
798 memmove(&lm, p + sizeof(u_char), sizeof(LMARK));
799 vtrace(sp,
800 "%lu: %s: MARK: %u/%u\n", rno, msg, lm.lno, lm.cno);
801 break;
802 default:
803 abort();
806 #endif