本文整理汇总了C++中F_CLR函数的典型用法代码示例。如果您正苦于以下问题:C++ F_CLR函数的具体用法?C++ F_CLR怎么用?C++ F_CLR使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了F_CLR函数的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: __rec_open
//.........这里部分代码省略.........
* and check the errno values.
*/
errno = 0;
if (lseek(rfd, (off_t)0, SEEK_CUR) == -1 && errno == ESPIPE) {
switch (flags & O_ACCMODE) {
case O_RDONLY:
F_SET(t, R_RDONLY);
break;
default:
goto einval;
}
slow: if ((t->bt_rfp = fdopen(rfd, "r")) == NULL)
goto err;
F_SET(t, R_CLOSEFP);
t->bt_irec =
F_ISSET(t, R_FIXLEN) ? __rec_fpipe : __rec_vpipe;
} else {
switch (flags & O_ACCMODE) {
case O_RDONLY:
F_SET(t, R_RDONLY);
break;
case O_RDWR:
break;
default:
goto einval;
}
if (fstat(rfd, &sb))
goto err;
/*
* Kluge -- we'd like to test to see if the file is too
* big to mmap. Since, we don't know what size or type
* off_t's or size_t's are, what the largest unsigned
* integral type is, or what random insanity the local
* C compiler will perpetrate, doing the comparison in
* a portable way is flatly impossible. Hope that mmap
* fails if the file is too large.
*/
if (sb.st_size == 0)
F_SET(t, R_EOF);
else {
#ifdef MMAP_NOT_AVAILABLE
/*
* XXX
* Mmap doesn't work correctly on many current
* systems. In particular, it can fail subtly,
* with cache coherency problems. Don't use it
* for now.
*/
t->bt_msize = sb.st_size;
if ((t->bt_smap = mmap(NULL, t->bt_msize,
PROT_READ, MAP_FILE | MAP_PRIVATE, rfd,
(off_t)0)) == (caddr_t)-1)
goto slow;
t->bt_cmap = t->bt_smap;
t->bt_emap = t->bt_smap + sb.st_size;
t->bt_irec = F_ISSET(t, R_FIXLEN) ?
__rec_fmap : __rec_vmap;
F_SET(t, R_MEMMAPPED);
#else
goto slow;
#endif
}
}
}
/* Use the recno routines. */
dbp->close = __rec_close;
dbp->del = __rec_delete;
dbp->fd = __rec_fd;
dbp->get = __rec_get;
dbp->put = __rec_put;
dbp->seq = __rec_seq;
dbp->sync = __rec_sync;
/* If the root page was created, reset the flags. */
if ((h = mpool_get(t->bt_mp, P_ROOT, 0)) == NULL)
goto err;
if ((h->flags & P_TYPE) == P_BLEAF) {
F_CLR(h, P_TYPE);
F_SET(h, P_RLEAF);
mpool_put(t->bt_mp, h, MPOOL_DIRTY);
} else
mpool_put(t->bt_mp, h, 0);
if (openinfo && openinfo->flags & R_SNAPSHOT &&
!F_ISSET(t, R_EOF | R_INMEM) &&
t->bt_irec(t, MAX_REC_NUMBER) == RET_ERROR)
goto err;
return (dbp);
einval: errno = EINVAL;
err: sverrno = errno;
if (dbp != NULL)
(void)__bt_close(dbp);
if (fname != NULL)
(void)close(rfd);
errno = sverrno;
return (NULL);
}
示例2: exwr
//.........这里部分代码省略.........
*/
F_SET(sp, SC_EX_WAIT_YES);
/*
* !!!
* Ignore the return cursor position, the cursor doesn't
* move.
*/
if (ex_filter(sp, cmdp, &cmdp->addr1,
&cmdp->addr2, &rm, cmdp->argv[1]->bp, FILTER_WRITE))
return (1);
/* Ex terminates with a bang, even if the command fails. */
if (!F_ISSET(sp, SC_VI) && !F_ISSET(sp, SC_EX_SILENT))
(void)ex_puts(sp, "!\n");
return (0);
}
/* Set the FS_ALL flag if we're writing the entire file. */
if (cmdp->addr1.lno <= 1 && !db_exist(sp, cmdp->addr2.lno + 1))
LF_SET(FS_ALL);
/* If "write >>" it's an append to a file. */
if (cmdp->argc != 0 && cmd != XIT && p[0] == '>' && p[1] == '>') {
LF_SET(FS_APPEND);
/* Skip ">>" and whitespace. */
for (p += 2; *p && cmdskip(*p); ++p);
}
/* If no other arguments, just write the file back. */
if (cmdp->argc == 0 || *p == '\0')
return (file_write(sp,
&cmdp->addr1, &cmdp->addr2, NULL, flags));
/* Build an argv so we get an argument count and file expansion. */
if (argv_exp2(sp, cmdp, p, STRLEN(p)))
return (1);
/*
* 0 args: impossible.
* 1 args: impossible (I hope).
* 2 args: read it.
* >2 args: object, too many args.
*
* The 1 args case depends on the argv_sexp() function refusing
* to return success without at least one non-blank character.
*/
switch (cmdp->argc) {
case 0:
case 1:
abort();
/* NOTREACHED */
case 2:
INT2CHAR(sp, cmdp->argv[1]->bp, cmdp->argv[1]->len+1,
n, nlen);
name = v_strdup(sp, n, nlen - 1);
/*
* !!!
* Historically, the read and write commands renamed
* "unnamed" files, or, if the file had a name, set
* the alternate file name.
*/
if (F_ISSET(sp->frp, FR_TMPFILE) &&
!F_ISSET(sp->frp, FR_EXNAMED)) {
if ((n = v_strdup(sp, name, nlen - 1)) != NULL) {
free(sp->frp->name);
sp->frp->name = n;
}
/*
* The file has a real name, it's no longer a
* temporary, clear the temporary file flags.
*
* !!!
* If we're writing the whole file, FR_NAMECHANGE
* will be cleared by the write routine -- this is
* historic practice.
*/
F_CLR(sp->frp, FR_TMPEXIT | FR_TMPFILE);
F_SET(sp->frp, FR_NAMECHANGE | FR_EXNAMED);
/* Notify the screen. */
(void)sp->gp->scr_rename(sp, sp->frp->name, 1);
} else
set_alt_name(sp, name);
break;
default:
INT2CHAR(sp, p, STRLEN(p) + 1, n, nlen);
ex_emsg(sp, n, EXM_FILECOUNT);
return (1);
}
rc = file_write(sp, &cmdp->addr1, &cmdp->addr2, name, flags);
free(name);
return rc;
}
示例3: __bt_open
//.........这里部分代码省略.........
}
if ((t->bt_fd = _open(fname, flags, mode)) < 0)
goto err;
} else {
if ((flags & O_ACCMODE) != O_RDWR)
goto einval;
if ((t->bt_fd = tmp()) == -1)
goto err;
F_SET(t, B_INMEM);
}
if (_fcntl(t->bt_fd, F_SETFD, 1) == -1)
goto err;
if (_fstat(t->bt_fd, &sb))
goto err;
if (sb.st_size) {
if ((nr = _read(t->bt_fd, &m, sizeof(BTMETA))) < 0)
goto err;
if (nr != sizeof(BTMETA))
goto eftype;
/*
* Read in the meta-data. This can change the notion of what
* the lorder, page size and flags are, and, when the page size
* changes, the cachesize value can change too. If the user
* specified the wrong byte order for an existing database, we
* don't bother to return an error, we just clear the NEEDSWAP
* bit.
*/
if (m.magic == BTREEMAGIC)
F_CLR(t, B_NEEDSWAP);
else {
F_SET(t, B_NEEDSWAP);
M_32_SWAP(m.magic);
M_32_SWAP(m.version);
M_32_SWAP(m.psize);
M_32_SWAP(m.free);
M_32_SWAP(m.nrecs);
M_32_SWAP(m.flags);
}
if (m.magic != BTREEMAGIC || m.version != BTREEVERSION)
goto eftype;
if (m.psize < MINPSIZE || m.psize > MAX_PAGE_OFFSET + 1 ||
m.psize & (sizeof(indx_t) - 1) )
goto eftype;
if (m.flags & ~SAVEMETA)
goto eftype;
b.psize = m.psize;
F_SET(t, m.flags);
t->bt_free = m.free;
t->bt_nrecs = m.nrecs;
} else {
/*
* Set the page size to the best value for I/O to this file.
* Don't overflow the page offset type.
*/
if (b.psize == 0) {
b.psize = sb.st_blksize;
if (b.psize < MINPSIZE)
b.psize = MINPSIZE;
if (b.psize > MAX_PAGE_OFFSET + 1)
b.psize = MAX_PAGE_OFFSET + 1;
}
示例4: vs_output
/*
* vs_output --
* Output the text to the screen.
*/
static void
vs_output(SCR *sp, mtype_t mtype, const char *line, int llen)
{
unsigned char *kp;
GS *gp;
VI_PRIVATE *vip;
size_t chlen, notused;
int ch, len, rlen, tlen;
const char *p, *t;
char *cbp, *ecbp, cbuf[128];
gp = sp->gp;
vip = VIP(sp);
for (p = line, rlen = llen; llen > 0;) {
/* Get the next physical line. */
if ((p = memchr(line, '\n', llen)) == NULL)
len = llen;
else
len = p - line;
/*
* The max is sp->cols characters, and we may have already
* written part of the line.
*/
if (len + vip->lcontinue > sp->cols)
len = sp->cols - vip->lcontinue;
/*
* If the first line output, do nothing. If the second line
* output, draw the divider line. If drew a full screen, we
* remove the divider line. If it's a continuation line, move
* to the continuation point, else, move the screen up.
*/
if (vip->lcontinue == 0) {
if (!IS_ONELINE(sp)) {
if (vip->totalcount == 1) {
(void)gp->scr_move(sp,
LASTLINE(sp) - 1, 0);
(void)gp->scr_clrtoeol(sp);
(void)vs_divider(sp);
F_SET(vip, VIP_DIVIDER);
++vip->totalcount;
++vip->linecount;
}
if (vip->totalcount == sp->t_maxrows &&
F_ISSET(vip, VIP_DIVIDER)) {
--vip->totalcount;
--vip->linecount;
F_CLR(vip, VIP_DIVIDER);
}
}
if (vip->totalcount != 0)
vs_scroll(sp, NULL, SCROLL_W_QUIT);
(void)gp->scr_move(sp, LASTLINE(sp), 0);
++vip->totalcount;
++vip->linecount;
if (INTERRUPTED(sp))
break;
} else
(void)gp->scr_move(sp, LASTLINE(sp), vip->lcontinue);
/* Error messages are in inverse video. */
if (mtype == M_ERR)
(void)gp->scr_attr(sp, SA_INVERSE, 1);
/* Display the line, doing character translation. */
#define FLUSH { \
*cbp = '\0'; \
(void)gp->scr_addstr(sp, cbuf, cbp - cbuf); \
cbp = cbuf; \
}
ecbp = (cbp = cbuf) + sizeof(cbuf) - 1;
for (t = line, tlen = len; tlen--; ++t) {
ch = *t;
/*
* Replace tabs with spaces, there are places in
* ex that do column calculations without looking
* at <tabs> -- and all routines that care about
* <tabs> do their own expansions. This catches
* <tabs> in things like tag search strings.
*/
if (ch == '\t')
ch = ' ';
chlen = KEY_LEN(sp, ch);
if (cbp + chlen >= ecbp)
FLUSH;
for (kp = KEY_NAME(sp, ch); chlen--;)
*cbp++ = *kp++;
}
if (cbp > cbuf)
FLUSH;
if (mtype == M_ERR)
(void)gp->scr_attr(sp, SA_INVERSE, 0);
//.........这里部分代码省略.........
示例5: vs_resolve
/*
* vs_resolve --
* Deal with message output.
*
* PUBLIC: int vs_resolve __P((SCR *, SCR *, int));
*/
int
vs_resolve(SCR *sp, SCR *csp, int forcewait)
{
EVENT ev;
GS *gp;
WIN *wp;
MSGS *mp;
VI_PRIVATE *vip;
size_t oldy, oldx;
int redraw;
/*
* Vs_resolve is called from the main vi loop and the refresh function
* to periodically ensure that the user has seen any messages that have
* been displayed and that any status lines are correct. The sp screen
* is the screen we're checking, usually the current screen. When it's
* not, csp is the current screen, used for final cursor positioning.
*/
gp = sp->gp;
wp = sp->wp;
vip = VIP(sp);
if (csp == NULL)
csp = sp;
/* Save the cursor position. */
(void)gp->scr_cursor(csp, &oldy, &oldx);
/* Ring the bell if it's scheduled. */
if (F_ISSET(gp, G_BELLSCHED)) {
F_CLR(gp, G_BELLSCHED);
(void)gp->scr_bell(sp);
}
/* Display new file status line. */
if (F_ISSET(sp, SC_STATUS)) {
F_CLR(sp, SC_STATUS);
msgq_status(sp, sp->lno, MSTAT_TRUNCATE);
}
/* Report on line modifications. */
mod_rpt(sp);
/*
* Flush any saved messages. If the screen isn't ready, refresh
* it. (A side-effect of screen refresh is that we can display
* messages.) Once this is done, don't trust the cursor. That
* extra refresh screwed the pooch.
*/
if (gp->msgq.lh_first != NULL) {
if (!F_ISSET(sp, SC_SCR_VI) && vs_refresh(sp, 1))
return (1);
while ((mp = gp->msgq.lh_first) != NULL) {
wp->scr_msg(sp, mp->mtype, mp->buf, mp->len);
LIST_REMOVE(mp, q);
free(mp->buf);
free(mp);
}
F_SET(vip, VIP_CUR_INVALID);
}
switch (vip->totalcount) {
case 0:
redraw = 0;
break;
case 1:
/*
* If we're switching screens, we have to wait for messages,
* regardless. If we don't wait, skip updating the modeline.
*/
if (forcewait)
vs_scroll(sp, NULL, SCROLL_W);
else
F_SET(vip, VIP_S_MODELINE);
redraw = 0;
break;
default:
/*
* If >1 message line in use, prompt the user to continue and
* repaint overwritten lines.
*/
vs_scroll(sp, NULL, SCROLL_W);
ev.e_event = E_REPAINT;
ev.e_flno = vip->totalcount >=
sp->rows ? 1 : sp->rows - vip->totalcount;
ev.e_tlno = sp->rows;
redraw = 1;
break;
}
/* Reset the count of overwriting lines. */
vip->linecount = vip->lcontinue = vip->totalcount = 0;
//.........这里部分代码省略.........
示例6: cl_vi_init
/*
* cl_vi_init --
* Initialize the curses vi screen.
*/
static int
cl_vi_init(SCR *sp)
{
CL_PRIVATE *clp;
char *o_cols, *o_lines, *o_term;
const char *ttype;
clp = CLP(sp);
/* If already initialized, just set the terminal modes. */
if (F_ISSET(clp, CL_SCR_VI_INIT))
goto fast;
/* Curses vi always reads from (and writes to) a terminal. */
if (!F_ISSET(clp, CL_STDIN_TTY) || !isatty(STDOUT_FILENO)) {
msgq(sp, M_ERR,
"016|Vi's standard input and output must be a terminal");
return (1);
}
/* We'll need a terminal type. */
if (opts_empty(sp, O_TERM, 0))
return (1);
ttype = O_STR(sp, O_TERM);
/*
* XXX
* Changing the row/column and terminal values is done by putting them
* into the environment, which is then read by curses. What this loses
* in ugliness, it makes up for in stupidity. We can't simply put the
* values into the environment ourselves, because in the presence of a
* kernel mechanism for returning the window size, entering values into
* the environment will screw up future screen resizing events, e.g. if
* the user enters a :shell command and then resizes their window. So,
* if they weren't already in the environment, we make sure to delete
* them immediately after setting them.
*
* XXX
* Putting the TERM variable into the environment is necessary, even
* though we're using newterm() here. We may be using initscr() as
* the underlying function.
*/
o_term = getenv("TERM");
cl_putenv(sp, "TERM", ttype, 0);
o_lines = getenv("LINES");
cl_putenv(sp, "LINES", NULL, (u_long)O_VAL(sp, O_LINES));
o_cols = getenv("COLUMNS");
cl_putenv(sp, "COLUMNS", NULL, (u_long)O_VAL(sp, O_COLUMNS));
/* Delete cur_term if exists. */
if (F_ISSET(clp, CL_SETUPTERM)) {
if (del_curterm(cur_term))
return (1);
F_CLR(clp, CL_SETUPTERM);
}
/*
* XXX
* The SunOS initscr() can't be called twice. Don't even think about
* using it. It fails in subtle ways (e.g. select(2) on fileno(stdin)
* stops working). (The SVID notes that applications should only call
* initscr() once.)
*
* XXX
* The HP/UX newterm doesn't support the NULL first argument, so we
* have to specify the terminal type.
*/
errno = 0;
if ((clp->screen = newterm(__UNCONST(ttype), stdout, stdin)) == NULL) {
if (errno)
msgq(sp, M_SYSERR, "%s", ttype);
else
msgq(sp, M_ERR, "%s: unknown terminal type", ttype);
return (1);
}
if (o_term == NULL)
cl_unsetenv(sp, "TERM");
if (o_lines == NULL)
cl_unsetenv(sp, "LINES");
if (o_cols == NULL)
cl_unsetenv(sp, "COLUMNS");
/*
* XXX
* Someone got let out alone without adult supervision -- the SunOS
* newterm resets the signal handlers. There's a race, but it's not
* worth closing.
*/
(void)sig_init(sp->gp, sp);
/*
* We use raw mode. What we want is 8-bit clean, however, signals
* and flow control should continue to work. Admittedly, it sounds
* like cbreak, but it isn't. Using cbreak() can get you additional
* things like IEXTEN, which turns on flags like DISCARD and LNEXT.
//.........这里部分代码省略.........
示例7: cl_screen
/*
* cl_screen --
* Switch screen types.
*
* PUBLIC: int cl_screen __P((SCR *, u_int32_t));
*/
int
cl_screen(SCR *sp, u_int32_t flags)
{
CL_PRIVATE *clp;
WINDOW *win;
GS *gp;
int ret, error;
sigset_t oset;
gp = sp->gp;
clp = CLP(sp);
win = CLSP(sp) ? CLSP(sp) : stdscr;
ret = 0;
/*
* During initialization of the screen, block signals to make sure that
* curses/terminfo routines are not interrupted.
*/
error = sigprocmask(SIG_BLOCK, &__sigblockset, &oset);
/* See if the current information is incorrect. */
if (F_ISSET(gp, G_SRESTART)) {
if (CLSP(sp)) {
delwin(CLSP(sp));
sp->cl_private = NULL;
}
if (cl_quit(gp)) {
ret = 1;
goto end;
}
F_CLR(gp, G_SRESTART);
}
/* See if we're already in the right mode. */
if ((LF_ISSET(SC_EX) && F_ISSET(sp, SC_SCR_EX)) ||
(LF_ISSET(SC_VI) && F_ISSET(sp, SC_SCR_VI)))
goto end;
/*
* Fake leaving ex mode.
*
* We don't actually exit ex or vi mode unless forced (e.g. by a window
* size change). This is because many curses implementations can't be
* called twice in a single program. Plus, it's faster. If the editor
* "leaves" vi to enter ex, when it exits ex we'll just fall back into
* vi.
*/
if (F_ISSET(sp, SC_SCR_EX))
F_CLR(sp, SC_SCR_EX);
/*
* Fake leaving vi mode.
*
* Clear out the rest of the screen if we're in the middle of a split
* screen. Move to the last line in the current screen -- this makes
* terminal scrolling happen naturally. Note: *don't* move past the
* end of the screen, as there are ex commands (e.g., :read ! cat file)
* that don't want to. Don't clear the info line, its contents may be
* valid, e.g. :file|append.
*/
if (F_ISSET(sp, SC_SCR_VI)) {
F_CLR(sp, SC_SCR_VI);
if (TAILQ_NEXT(sp, q) != NULL) {
(void)wmove(win, RLNO(sp, sp->rows), 0);
wclrtobot(win);
}
(void)wmove(win, RLNO(sp, sp->rows) - 1, 0);
wrefresh(win);
}
/* Enter the requested mode. */
if (LF_ISSET(SC_EX)) {
if (cl_ex_init(sp)) {
ret = 1;
goto end;
}
F_SET(clp, CL_IN_EX | CL_SCR_EX_INIT);
/*
* If doing an ex screen for ex mode, move to the last line
* on the screen.
*/
if (F_ISSET(sp, SC_EX) && clp->cup != NULL)
tputs(tgoto(clp->cup,
0, O_VAL(sp, O_LINES) - 1), 1, cl_putchar);
} else {
if (cl_vi_init(sp)) {
ret = 1;
goto end;
}
F_CLR(clp, CL_IN_EX);
F_SET(clp, CL_SCR_VI_INIT);
//.........这里部分代码省略.........
示例8: v_cmd
//.........这里部分代码省略.........
/* Pick up optional buffer. */
if (key == '"') {
cpart = ISPARTIAL;
if (F_ISSET(vp, VC_BUFFER)) {
msgq(sp, M_ERR, "234|Only one buffer may be specified");
return (GC_ERR);
}
if (ismotion != NULL) {
v_emsg(sp, NULL, VIM_COMBUF);
return (GC_ERR);
}
KEY(vp->buffer, 0);
F_SET(vp, VC_BUFFER);
KEY(key, EC_MAPCOMMAND);
}
/* Check for an OOB command key. */
cpart = ISPARTIAL;
if (key > MAXVIKEY) {
v_emsg(sp, KEY_NAME(sp, key), VIM_NOCOM);
return (GC_ERR);
}
kp = &vikeys[vp->key = key];
/*
* !!!
* Historically, D accepted and then ignored a count. Match it.
*/
if (vp->key == 'D' && F_ISSET(vp, VC_C1SET)) {
*comcountp = 0;
vp->count = 0;
F_CLR(vp, VC_C1SET);
}
/* Check for command aliases. */
if (kp->func == NULL && (kp = v_alias(sp, vp, kp)) == NULL)
return (GC_ERR);
/* The tildeop option makes the ~ command take a motion. */
if (key == '~' && O_ISSET(sp, O_TILDEOP))
kp = &tmotion;
vp->kp = kp;
/*
* Find the command. The only legal command with no underlying
* function is dot. It's historic practice that <escape> doesn't
* just erase the preceding number, it beeps the terminal as well.
* It's a common problem, so just beep the terminal unless verbose
* was set.
*/
if (kp->func == NULL) {
if (key != '.') {
v_emsg(sp, KEY_NAME(sp, key),
ev.e_value == K_ESCAPE ? VIM_NOCOM_B : VIM_NOCOM);
return (GC_ERR);
}
/* If called for a motion command, stop now. */
if (dp == NULL)
goto usage;
/*
* !!!
示例9: vi
/*
* vi --
* Main vi command loop.
*
* PUBLIC: int vi __P((SCR **));
*/
int
vi(SCR **spp)
{
GS *gp;
MARK abs;
SCR *next, *sp;
VICMD cmd = { 0 }, *vp;
VI_PRIVATE *vip;
int comcount, mapped, rval;
/* Get the first screen. */
sp = *spp;
gp = sp->gp;
/* Point to the command structure. */
vp = &cmd;
/* Reset strange attraction. */
F_SET(vp, VM_RCM_SET);
/* Initialize the vi screen. */
if (v_init(sp))
return (1);
/* Set the focus. */
(void)sp->gp->scr_rename(sp, sp->frp->name, 1);
for (vip = VIP(sp), rval = 0;;) {
/* Resolve messages. */
if (!MAPPED_KEYS_WAITING(sp) && vs_resolve(sp, NULL, 0))
goto ret;
/*
* If not skipping a refresh, return to command mode and
* refresh the screen.
*/
if (F_ISSET(vip, VIP_S_REFRESH))
F_CLR(vip, VIP_S_REFRESH);
else {
sp->showmode = SM_COMMAND;
if (vs_refresh(sp, 0))
goto ret;
}
/* Set the new favorite position. */
if (F_ISSET(vp, VM_RCM_SET | VM_RCM_SETFNB | VM_RCM_SETNNB)) {
F_CLR(vip, VIP_RCM_LAST);
(void)vs_column(sp, &sp->rcm);
}
/*
* If not currently in a map, log the cursor position,
* and set a flag so that this command can become the
* DOT command.
*/
if (MAPPED_KEYS_WAITING(sp))
mapped = 1;
else {
if (log_cursor(sp))
goto err;
mapped = 0;
}
/*
* There may be an ex command waiting, and we returned here
* only because we exited a screen or file. In this case,
* we simply go back into the ex parser.
*/
if (EXCMD_RUNNING(gp)) {
vp->kp = &vikeys[':'];
goto ex_continue;
}
/* Refresh the command structure. */
memset(vp, 0, sizeof(VICMD));
/*
* We get a command, which may or may not have an associated
* motion. If it does, we get it too, calling its underlying
* function to get the resulting mark. We then call the
* command setting the cursor to the resulting mark.
*
* !!!
* Vi historically flushed mapped characters on error, but
* entering extra <escape> characters at the beginning of
* a map wasn't considered an error -- in fact, users would
* put leading <escape> characters in maps to clean up vi
* state before the map was interpreted. Beauty!
*/
switch (v_cmd(sp, DOT, vp, NULL, &comcount, &mapped)) {
case GC_ERR:
goto err;
case GC_ERR_NOFLUSH:
goto gc_err_noflush;
//.........这里部分代码省略.........
示例10: rcv_sync
/*
* rcv_sync --
* Sync the file, optionally:
* flagging the backup file to be preserved
* snapshotting the backup file and send email to the user
* sending email to the user if the file was modified
* ending the file session
*
* PUBLIC: int rcv_sync __P((SCR *, u_int));
*/
int
rcv_sync(SCR *sp, u_int flags)
{
EXF *ep;
int fd, rval;
char buf[1024];
const char *dp;
/* Make sure that there's something to recover/sync. */
ep = sp->ep;
if (ep == NULL || !F_ISSET(ep, F_RCV_ON))
return (0);
/* Sync the file if it's been modified. */
if (F_ISSET(ep, F_MODIFIED)) {
/*
* If we are using a db1 version of the database,
* we want to sync the underlying btree not the
* recno tree which is transient anyway.
*/
#ifndef R_RECNOSYNC
#define R_RECNOSYNC 0
#endif
if (ep->db->sync(ep->db, R_RECNOSYNC)) {
F_CLR(ep, F_RCV_ON | F_RCV_NORM);
msgq_str(sp, M_SYSERR,
ep->rcv_path, "060|File backup failed: %s");
return (1);
}
/* REQUEST: don't remove backing file on exit. */
if (LF_ISSET(RCV_PRESERVE))
F_SET(ep, F_RCV_NORM);
/* REQUEST: send email. */
if (LF_ISSET(RCV_EMAIL))
rcv_email(sp, ep->rcv_mpath);
}
/*
* !!!
* Each time the user exec's :preserve, we have to snapshot all of
* the recovery information, i.e. it's like the user re-edited the
* file. We copy the DB(3) backing file, and then create a new mail
* recovery file, it's simpler than exiting and reopening all of the
* underlying files.
*
* REQUEST: snapshot the file.
*/
rval = 0;
if (LF_ISSET(RCV_SNAPSHOT)) {
if (opts_empty(sp, O_RECDIR, 0))
goto err;
dp = O_STR(sp, O_RECDIR);
(void)snprintf(buf, sizeof(buf), "%s/vi.XXXXXX", dp);
if ((fd = rcv_mktemp(sp, buf, dp, S_IRUSR | S_IWUSR)) == -1)
goto err;
sp->gp->scr_busy(sp,
"061|Copying file for recovery...", BUSY_ON);
if (rcv_copy(sp, fd, ep->rcv_path) ||
close(fd) || rcv_mailfile(sp, 1, buf)) {
(void)unlink(buf);
(void)close(fd);
rval = 1;
}
sp->gp->scr_busy(sp, NULL, BUSY_OFF);
}
if (0) {
err: rval = 1;
}
/* REQUEST: end the file session. */
if (LF_ISSET(RCV_ENDSESSION) && file_end(sp, NULL, 1))
rval = 1;
return (rval);
}
示例11: __rec_page_dirty_update
/*
* __rec_page_dirty_update --
* Update a dirty page's reference on eviction.
*/
static int
__rec_page_dirty_update(
WT_SESSION_IMPL *session, WT_REF *parent_ref, WT_PAGE *page)
{
WT_ADDR *addr;
WT_PAGE_MODIFY *mod;
mod = page->modify;
switch (F_ISSET(mod, WT_PM_REC_MASK)) {
case WT_PM_REC_EMPTY: /* Page is empty */
if (parent_ref->addr != NULL &&
__wt_off_page(page->parent, parent_ref->addr)) {
__wt_free(session, ((WT_ADDR *)parent_ref->addr)->addr);
__wt_free(session, parent_ref->addr);
}
/*
* Update the parent to reference an empty page.
*
* Set the transaction ID to WT_TXN_NONE because the fact that
* reconciliation left the page "empty" means there's no older
* transaction in the system that might need to see an earlier
* version of the page. It isn't necessary (WT_TXN_NONE is 0),
* but it's the right thing to do.
*
* Publish: a barrier to ensure the structure fields are set
* before the state change makes the page available to readers.
*/
parent_ref->page = NULL;
parent_ref->addr = NULL;
parent_ref->txnid = WT_TXN_NONE;
WT_PUBLISH(parent_ref->state, WT_REF_DELETED);
break;
case WT_PM_REC_REPLACE: /* 1-for-1 page swap */
if (parent_ref->addr != NULL &&
__wt_off_page(page->parent, parent_ref->addr)) {
__wt_free(session, ((WT_ADDR *)parent_ref->addr)->addr);
__wt_free(session, parent_ref->addr);
}
/*
* Update the parent to reference the replacement page.
*
* Publish: a barrier to ensure the structure fields are set
* before the state change makes the page available to readers.
*/
WT_RET(__wt_calloc(session, 1, sizeof(WT_ADDR), &addr));
*addr = mod->u.replace;
mod->u.replace.addr = NULL;
mod->u.replace.size = 0;
parent_ref->page = NULL;
parent_ref->addr = addr;
WT_PUBLISH(parent_ref->state, WT_REF_DISK);
break;
case WT_PM_REC_SPLIT: /* Page split */
/*
* Update the parent to reference new internal page(s).
*
* Publish: a barrier to ensure the structure fields are set
* before the state change makes the page available to readers.
*/
parent_ref->page = mod->u.split;
WT_PUBLISH(parent_ref->state, WT_REF_MEM);
/* Clear the page else discarding the page will free it. */
mod->u.split = NULL;
F_CLR(mod, WT_PM_REC_SPLIT);
break;
WT_ILLEGAL_VALUE(session);
}
return (0);
}
示例12: __wt_meta_track_off
/*
* __wt_meta_track_off --
* Turn off metadata operation tracking, unrolling on error.
*/
int
__wt_meta_track_off(WT_SESSION_IMPL *session, bool need_sync, bool unroll)
{
WT_DECL_RET;
WT_META_TRACK *trk, *trk_orig;
WT_SESSION_IMPL *ckpt_session;
int saved_ret;
bool did_drop;
saved_ret = 0;
WT_ASSERT(session,
WT_META_TRACKING(session) && session->meta_track_nest > 0);
trk_orig = session->meta_track;
trk = session->meta_track_next;
/* If it was a nested transaction, there is nothing to do. */
if (--session->meta_track_nest != 0)
return (0);
/* Turn off tracking for unroll. */
session->meta_track_next = session->meta_track_sub = NULL;
/*
* If there were no operations logged, skip unnecessary metadata
* checkpoints. For example, this happens if attempting to create a
* data source that already exists (or drop one that doesn't).
*/
if (trk == trk_orig)
goto err;
/* Unrolling doesn't require syncing the metadata. */
if (unroll)
goto err;
if (F_ISSET(session, WT_SESSION_SCHEMA_TXN)) {
F_CLR(session, WT_SESSION_SCHEMA_TXN);
#ifdef WT_ENABLE_SCHEMA_TXN
WT_ERR(__wt_txn_commit(session, NULL));
__wt_errx(session, "TRACK: Commit internal schema txn");
#endif
}
/*
* If we don't have the metadata cursor (e.g, we're in the process of
* creating the metadata), we can't sync it.
*/
if (!need_sync || session->meta_cursor == NULL ||
F_ISSET(S2C(session), WT_CONN_IN_MEMORY))
goto err;
/* If we're logging, make sure the metadata update was flushed. */
if (FLD_ISSET(S2C(session)->log_flags, WT_CONN_LOG_ENABLED))
WT_WITH_DHANDLE(session,
WT_SESSION_META_DHANDLE(session),
ret = __wt_txn_checkpoint_log(
session, false, WT_TXN_LOG_CKPT_SYNC, NULL));
else {
WT_ASSERT(session, F_ISSET(session, WT_SESSION_LOCKED_SCHEMA));
ckpt_session = S2C(session)->meta_ckpt_session;
/*
* If this operation is part of a running transaction, that
* should be included in the checkpoint.
*/
ckpt_session->txn.id = session->txn.id;
WT_ASSERT(session,
!F_ISSET(session, WT_SESSION_LOCKED_METADATA));
WT_WITH_DHANDLE(ckpt_session, WT_SESSION_META_DHANDLE(session),
WT_WITH_METADATA_LOCK(ckpt_session,
ret = __wt_checkpoint(ckpt_session, NULL)));
ckpt_session->txn.id = WT_TXN_NONE;
if (ret == 0)
WT_WITH_DHANDLE(session,
WT_SESSION_META_DHANDLE(session),
ret = __wt_checkpoint_sync(session, NULL));
}
err: /*
* Undo any tracked operations on failure.
* Apply any tracked operations post-commit.
*/
did_drop = false;
if (unroll || ret != 0) {
saved_ret = ret;
ret = 0;
while (--trk >= trk_orig) {
did_drop = did_drop || trk->op == WT_ST_DROP_COMMIT;
WT_TRET(__meta_track_unroll(session, trk));
}
} else
for (; trk_orig < trk; trk_orig++) {
did_drop = did_drop ||
trk_orig->op == WT_ST_DROP_COMMIT;
WT_TRET(__meta_track_apply(session, trk_orig));
}
//.........这里部分代码省略.........
示例13: __bt_seqadv
/*
* __bt_seqadvance --
* Advance the sequential scan.
*
* Parameters:
* t: tree
* flags: R_NEXT, R_PREV
*
* Side effects:
* Pins the page the new key/data record is on.
*
* Returns:
* RET_ERROR, RET_SUCCESS or RET_SPECIAL if there's no next key.
*/
static int
__bt_seqadv(BTREE *t, EPG *ep, int flags)
{
CURSOR *c;
PAGE *h;
indx_t idx;
pgno_t pg;
int exact;
/*
* There are a couple of states that we can be in. The cursor has
* been initialized by the time we get here, but that's all we know.
*/
c = &t->bt_cursor;
/*
* The cursor was deleted where there weren't any duplicate records,
* so the key was saved. Find out where that key would go in the
* current tree. It doesn't matter if the returned key is an exact
* match or not -- if it's an exact match, the record was added after
* the delete so we can just return it. If not, as long as there's
* a record there, return it.
*/
if (F_ISSET(c, CURS_ACQUIRE))
return (__bt_first(t, &c->key, ep, &exact));
/* Get the page referenced by the cursor. */
if ((h = mpool_get(t->bt_mp, c->pg.pgno, 0)) == NULL)
return (RET_ERROR);
/*
* Find the next/previous record in the tree and point the cursor at
* it. The cursor may not be moved until a new key has been found.
*/
switch (flags) {
case R_NEXT: /* Next record. */
/*
* The cursor was deleted in duplicate records, and moved
* forward to a record that has yet to be returned. Clear
* that flag, and return the record.
*/
if (F_ISSET(c, CURS_AFTER))
goto usecurrent;
idx = c->pg.index;
if (++idx == NEXTINDEX(h)) {
pg = h->nextpg;
mpool_put(t->bt_mp, h, 0);
if (pg == P_INVALID)
return (RET_SPECIAL);
if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL)
return (RET_ERROR);
idx = 0;
}
break;
case R_PREV: /* Previous record. */
/*
* The cursor was deleted in duplicate records, and moved
* backward to a record that has yet to be returned. Clear
* that flag, and return the record.
*/
if (F_ISSET(c, CURS_BEFORE)) {
usecurrent: F_CLR(c, CURS_AFTER | CURS_BEFORE);
ep->page = h;
ep->index = c->pg.index;
return (RET_SUCCESS);
}
idx = c->pg.index;
if (idx == 0) {
pg = h->prevpg;
mpool_put(t->bt_mp, h, 0);
if (pg == P_INVALID)
return (RET_SPECIAL);
if ((h = mpool_get(t->bt_mp, pg, 0)) == NULL)
return (RET_ERROR);
idx = NEXTINDEX(h) - 1;
} else
--idx;
break;
}
ep->page = h;
ep->index = idx;
return (RET_SUCCESS);
}
示例14: v_exaddr
//.........这里部分代码省略.........
return (1);
/*
* Remember where any remaining command information is, and clean
* up the fake ex command.
*/
cmd = cmdp->cp;
len = cmdp->clen;
gp->excmd.clen = 0;
if (err)
goto err2;
/* Copy out the new cursor position and make sure it's okay. */
switch (cmdp->addrcnt) {
case 1:
vp->m_stop = cmdp->addr1;
break;
case 2:
vp->m_stop = cmdp->addr2;
break;
}
if (!db_exist(sp, vp->m_stop.lno)) {
ex_badaddr(sp, &fake,
vp->m_stop.lno == 0 ? A_ZERO : A_EOF, NUM_OK);
goto err2;
}
/*
* !!!
* Historic practice is that a trailing 'z' was ignored if it was a
* motion command. Should probably be an error, but not worth the
* effort.
*/
if (ISMOTION(vp))
return (v_correct(sp, vp, F_ISSET(cmdp, E_DELTA)));
/*
* !!!
* Historically, if it wasn't a motion command, a delta in the search
* pattern turns it into a first nonblank movement.
*/
nb = F_ISSET(cmdp, E_DELTA);
/* Check for the 'z' command. */
if (len != 0) {
if (*cmd != 'z')
goto err1;
/* No blanks, just like the z command. */
for (t = cmd + 1, tlen = len - 1; tlen > 0; ++t, --tlen)
if (!isdigit(*t))
break;
if (tlen &&
(*t == '-' || *t == '.' || *t == '+' || *t == '^')) {
++t;
--tlen;
type = 1;
} else
type = 0;
if (tlen)
goto err1;
/* The z command will do the nonblank for us. */
nb = 0;
/* Default to z+. */
if (!type &&
v_event_push(sp, NULL, L("+"), 1, CH_NOMAP | CH_QUOTED))
return (1);
/* Push the user's command. */
if (v_event_push(sp, NULL, cmd, len, CH_NOMAP | CH_QUOTED))
return (1);
/* Push line number so get correct z display. */
tlen = snprintf(buf,
sizeof(buf), "%lu", (u_long)vp->m_stop.lno);
CHAR2INT(sp, buf, tlen, w, wlen);
if (v_event_push(sp, NULL, w, wlen, CH_NOMAP | CH_QUOTED))
return (1);
/* Don't refresh until after 'z' happens. */
F_SET(VIP(sp), VIP_S_REFRESH);
}
/* Non-motion commands move to the end of the range. */
vp->m_final = vp->m_stop;
if (nb) {
F_CLR(vp, VM_RCM_MASK);
F_SET(vp, VM_RCM_SETFNB);
}
return (0);
err1: msgq(sp, M_ERR,
"188|Characters after search string, line offset and/or z command");
err2: vp->m_final.lno = s_lno;
vp->m_final.cno = s_cno;
return (1);
}
示例15: __wt_btcur_prev
/*
* __wt_btcur_prev --
* Move to the previous record in the tree.
*/
int
__wt_btcur_prev(WT_CURSOR_BTREE *cbt)
{
WT_DECL_RET;
WT_SESSION_IMPL *session;
int newpage;
session = (WT_SESSION_IMPL *)cbt->iface.session;
WT_BSTAT_INCR(session, cursor_read_prev);
__cursor_func_init(cbt, 0);
/*
* If we aren't already iterating in the right direction, there's
* some setup to do.
*/
if (!F_ISSET(cbt, WT_CBT_ITERATE_PREV))
__wt_btcur_iterate_setup(cbt, 0);
/*
* Walk any page we're holding until the underlying call returns not-
* found. Then, move to the previous page, until we reach the start
* of the file.
*/
for (newpage = 0;; newpage = 1) {
if (F_ISSET(cbt, WT_CBT_ITERATE_APPEND)) {
switch (cbt->page->type) {
case WT_PAGE_COL_FIX:
ret = __cursor_fix_append_prev(cbt, newpage);
break;
case WT_PAGE_COL_VAR:
ret = __cursor_var_append_prev(cbt, newpage);
break;
WT_ILLEGAL_VALUE_ERR(session);
}
if (ret == 0)
break;
F_CLR(cbt, WT_CBT_ITERATE_APPEND);
if (ret != WT_NOTFOUND)
break;
newpage = 1;
}
if (cbt->page != NULL) {
switch (cbt->page->type) {
case WT_PAGE_COL_FIX:
ret = __cursor_fix_prev(cbt, newpage);
break;
case WT_PAGE_COL_VAR:
ret = __cursor_var_prev(cbt, newpage);
break;
case WT_PAGE_ROW_LEAF:
ret = __cursor_row_prev(cbt, newpage);
break;
WT_ILLEGAL_VALUE_ERR(session);
}
if (ret != WT_NOTFOUND)
break;
}
do {
WT_ERR(__wt_tree_np(session, &cbt->page, 0, 0));
WT_ERR_TEST(cbt->page == NULL, WT_NOTFOUND);
} while (
cbt->page->type == WT_PAGE_COL_INT ||
cbt->page->type == WT_PAGE_ROW_INT);
/*
* The last page in a column-store has appended entries.
* We handle it separately from the usual cursor code:
* it's only that one page and it's in a simple format.
*/
if (cbt->page->type != WT_PAGE_ROW_LEAF &&
(cbt->ins_head = WT_COL_APPEND(cbt->page)) != NULL)
F_SET(cbt, WT_CBT_ITERATE_APPEND);
}
err: __cursor_func_resolve(cbt, ret);
return (ret);
}