/* * db_insert -- * Insert a line into the file. * * PUBLIC: int db_insert(SCR *, recno_t, CHAR_T *, size_t); */ int db_insert( SCR *sp, 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 TRACE(sp, "insert before %lu: len %lu {%.*s}\n", (u_long)lno, (u_long)len, MIN(len, 20), p); #endif /* Check for no underlying file. */ if ((ep = sp->ep) == NULL) { ex_emsg(sp, NULL, EXM_NOFILEYET); return (1); } INT2FILE(sp, p, len, fp, flen); /* Update file. */ key.data = &lno; key.size = sizeof(lno); data.data = fp; data.size = flen; if (ep->db->put(ep->db, &key, &data, R_IBEFORE) == -1) { 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; /* 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); /* Update marks, @ and global commands. */ rval = 0; if (mark_insdel(sp, LINE_INSERT, lno)) rval = 1; if (ex_g_insdel(sp, LINE_INSERT, lno)) rval = 1; /* Update screen. */ return (scr_update(sp, lno, LINE_INSERT, 1) || rval); }
/* * db_set -- * Store a line in the file. * * PUBLIC: int db_set __P((SCR *, db_recno_t, CHAR_T *, size_t)); */ int db_set(SCR *sp, db_recno_t lno, CHAR_T *p, size_t len) { DBT data, key; EXF *ep; const char *fp; size_t flen; #if defined(DEBUG) && 0 vtrace(sp, "replace line %lu: len %lu {%.*s}\n", (u_long)lno, (u_long)len, MIN(len, 20), p); #endif /* Check for no underlying file. */ if ((ep = sp->ep) == NULL) { ex_emsg(sp, NULL, EXM_NOFILEYET); return (1); } if (ep->l_win && ep->l_win != sp->wp) { ex_emsg(sp, NULL, EXM_LOCKED); return 1; } /* Log before change. */ log_line(sp, lno, LOG_LINE_RESET_B); INT2FILE(sp, p, len, fp, flen); /* Update file. */ memset(&key, 0, sizeof(key)); key.data = &lno; key.size = sizeof(lno); memset(&data, 0, sizeof(data)); data.data = __UNCONST(fp); data.size = flen; if ((sp->db_error = ep->db->put(ep->db, NULL, &key, &data, 0)) != 0) { msgq(sp, M_DBERR, "006|unable to store line %lu", (u_long)lno); return (1); } /* Flush the cache, update line count, before screen update. */ update_cache(sp, LINE_RESET, lno); /* File now dirty. */ if (F_ISSET(ep, F_FIRSTMODIFY)) (void)rcv_init(sp); F_SET(ep, F_MODIFIED); /* Log after change. */ log_line(sp, lno, LOG_LINE_RESET_F); /* Update screen. */ return (scr_update(sp, lno, LINE_RESET, 1)); }
/* * db_set -- * Store a line in the file. * * PUBLIC: int db_set(SCR *, recno_t, CHAR_T *, size_t); */ int db_set( SCR *sp, recno_t lno, CHAR_T *p, size_t len) { DBT data, key; EXF *ep; char *fp; size_t flen; #if defined(DEBUG) && 0 TRACE(sp, "replace line %lu: len %lu {%.*s}\n", (u_long)lno, (u_long)len, MIN(len, 20), p); #endif /* Check for no underlying file. */ if ((ep = sp->ep) == NULL) { ex_emsg(sp, NULL, EXM_NOFILEYET); return (1); } /* Log before change. */ log_line(sp, lno, LOG_LINE_RESET_B); INT2FILE(sp, p, len, fp, flen); /* Update file. */ key.data = &lno; key.size = sizeof(lno); data.data = fp; data.size = flen; if (ep->db->put(ep->db, &key, &data, 0) == -1) { msgq(sp, M_SYSERR, "006|unable to store line %lu", (u_long)lno); return (1); } /* Flush the cache, before logging or screen update. */ if (lno == ep->c_lno) ep->c_lno = OOBLNO; /* File now dirty. */ if (F_ISSET(ep, F_FIRSTMODIFY)) (void)rcv_init(sp); F_SET(ep, F_MODIFIED); /* Log after change. */ log_line(sp, lno, LOG_LINE_RESET_F); /* Update screen. */ return (scr_update(sp, lno, LINE_RESET, 1)); }
/* * db_delete -- * Delete a line from the file. * * PUBLIC: int db_delete __P((SCR *, db_recno_t)); */ int db_delete(SCR *sp, db_recno_t lno) { DBT key; EXF *ep; #if defined(DEBUG) && 0 vtrace(sp, "delete line %lu\n", (u_long)lno); #endif /* Check for no underlying file. */ if ((ep = sp->ep) == NULL) { ex_emsg(sp, NULL, EXM_NOFILEYET); return (1); } if (ep->l_win && ep->l_win != sp->wp) { ex_emsg(sp, NULL, EXM_LOCKED); return 1; } /* Update marks, @ and global commands. */ if (line_insdel(sp, LINE_DELETE, lno)) return 1; /* Log before change. */ log_line(sp, lno, LOG_LINE_DELETE_B); /* Update file. */ memset(&key, 0, sizeof(key)); key.data = &lno; key.size = sizeof(lno); if ((sp->db_error = ep->db->del(ep->db, NULL, &key, 0)) != 0) { msgq(sp, M_DBERR, "003|unable to delete line %lu", (u_long)lno); return (1); } /* Flush the cache, update line count, before screen update. */ 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)); }
/* * db_delete -- * Delete a line from the file. * * PUBLIC: int db_delete(SCR *, recno_t); */ int db_delete( SCR *sp, recno_t lno) { DBT key; EXF *ep; #if defined(DEBUG) && 0 TRACE(sp, "delete line %lu\n", (u_long)lno); #endif /* Check for no underlying file. */ if ((ep = sp->ep) == NULL) { ex_emsg(sp, NULL, EXM_NOFILEYET); return (1); } /* Update marks, @ and global commands. */ if (mark_insdel(sp, LINE_DELETE, lno)) return (1); if (ex_g_insdel(sp, LINE_DELETE, lno)) return (1); /* Log change. */ log_line(sp, lno, LOG_LINE_DELETE); /* Update file. */ key.data = &lno; key.size = sizeof(lno); if (ep->db->del(ep->db, &key, 0) == 1) { msgq(sp, M_SYSERR, "003|unable to delete 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; /* File now modified. */ if (F_ISSET(ep, F_FIRSTMODIFY)) (void)rcv_init(sp); F_SET(ep, F_MODIFIED); /* Update screen. */ return (scr_update(sp, lno, LINE_DELETE, 1)); }
/* maybe this could be simpler * * DB3 behaves differently from DB1 * * if lno != 0 just go to lno and put the new line after it * if lno == 0 then if there are any record, put in front of the first * otherwise just append to the end thus creating the first * line */ static int append(SCR *sp, db_recno_t lno, const CHAR_T *p, size_t len, lnop_t op, int update) { DBT data, key; DBC *dbcp_put; EXF *ep; const char *fp; size_t flen; int rval; /* Check for no underlying file. */ if ((ep = sp->ep) == NULL) { ex_emsg(sp, NULL, EXM_NOFILEYET); return (1); } if (ep->l_win && ep->l_win != sp->wp) { ex_emsg(sp, NULL, EXM_LOCKED); return 1; } /* Log before change. */ log_line(sp, lno + 1, LOG_LINE_APPEND_B); /* Update file. */ memset(&key, 0, sizeof(key)); key.data = &lno; key.size = sizeof(lno); memset(&data, 0, sizeof(data)); if ((sp->db_error = ep->db->cursor(ep->db, NULL, &dbcp_put, 0)) != 0) return 1; INT2FILE(sp, p, len, fp, flen); if (lno != 0) { if ((sp->db_error = dbcp_put->c_get(dbcp_put, &key, &data, DB_SET)) != 0) goto err2; data.data = __UNCONST(fp); data.size = flen; if ((sp->db_error = dbcp_put->c_put(dbcp_put, &key, &data, DB_AFTER)) != 0) { err2: (void)dbcp_put->c_close(dbcp_put); msgq(sp, M_DBERR, (op == LINE_APPEND) ? "004|unable to append to line %lu" : "005|unable to insert at line %lu", (u_long)lno); return (1); } } else { if ((sp->db_error = dbcp_put->c_get(dbcp_put, &key, &data, DB_FIRST)) != 0) { if (sp->db_error != DB_NOTFOUND) goto err2; data.data = __UNCONST(fp); data.size = flen; if ((sp->db_error = ep->db->put(ep->db, NULL, &key, &data, DB_APPEND)) != 0) { goto err2; } } else { key.data = &lno; key.size = sizeof(lno); data.data = __UNCONST(fp); data.size = flen; if ((sp->db_error = dbcp_put->c_put(dbcp_put, &key, &data, DB_BEFORE)) != 0) { goto err2; } } } (void)dbcp_put->c_close(dbcp_put); /* Flush the cache, update line count, before screen update. */ 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 after change. */ log_line(sp, lno + 1, LOG_LINE_APPEND_F); /* Update marks, @ and global commands. */ rval = line_insdel(sp, LINE_INSERT, lno + 1); /* * Update screen. * * comment copied from db_append * XXX * Nasty hack. If multiple lines are input by the user, they aren't * committed until an <ESC> is entered. The problem is the screen was * updated/scrolled as each line was entered. So, when this routine * is called to copy the new lines from the cut buffer into the file, * it has to know not to update the screen again. */ return (scr_update(sp, lno + 1, LINE_INSERT, update) || rval); }
/* * db_append -- * Append a line into the file. * * PUBLIC: int db_append(SCR *, int, recno_t, CHAR_T *, size_t); */ int db_append( SCR *sp, int update, 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 TRACE(sp, "append to %lu: len %u {%.*s}\n", lno, len, MIN(len, 20), p); #endif /* Check for no underlying file. */ if ((ep = sp->ep) == NULL) { ex_emsg(sp, NULL, EXM_NOFILEYET); return (1); } INT2FILE(sp, p, len, fp, flen); /* Update file. */ key.data = &lno; key.size = sizeof(lno); data.data = fp; data.size = flen; if (ep->db->put(ep->db, &key, &data, R_IAFTER) == -1) { msgq(sp, M_SYSERR, "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; /* 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); /* Update marks, @ and global commands. */ rval = 0; if (mark_insdel(sp, LINE_INSERT, lno + 1)) rval = 1; if (ex_g_insdel(sp, LINE_INSERT, lno + 1)) rval = 1; /* * Update screen. * * XXX * Nasty hack. If multiple lines are input by the user, they aren't * committed until an <ESC> is entered. The problem is the screen was * updated/scrolled as each line was entered. So, when this routine * is called to copy the new lines from the cut buffer into the file, * it has to know not to update the screen again. */ return (scr_update(sp, lno, LINE_APPEND, update) || rval); }