/* * Kill backwards by "n" words. Move backwards by the desired number of words, * counting the characters. When dot is finally moved to its resting place, * fire off the kill command. Bound to "M-Rubout" and to "M-Backspace" */ int delbword(int f, int n) { int size; if (n < 0) return (FALSE); if (backchar(FALSE, 1) == FALSE) return (FALSE); size = 0; while (n--) { while (inword() == FALSE) { if (backchar(FALSE, 1) == FALSE) return (FALSE); ++size; } while (inword() != FALSE) { if (backchar(FALSE, 1) == FALSE) return (FALSE); ++size; } } if (forwchar(FALSE, 1) == FALSE) return (FALSE); return (ldelete(size, TRUE)); }
/* * Kill backwards by "n" words. Move backwards by the desired number of words, * counting the characters. When dot is finally moved to its resting place, * fire off the kill command. Bound to "M-Rubout" and to "M-Backspace". */ int delbword(int f, int n) { register long size; if (curbp->b_mode&MDVIEW) /* don't allow this command if */ return(rdonly()); /* we are in read only mode */ if (n < 0) return (FALSE); if (backchar(FALSE, 1) == FALSE) return (FALSE); size = 0L; while (n--) { while (inword() == FALSE) { if (backchar(FALSE, 1) == FALSE) return (FALSE); ++size; } while (inword() != FALSE) { if (backchar(FALSE, 1) == FALSE) return (FALSE); ++size; } } if (forwchar(FALSE, 1) == FALSE) return (FALSE); return (ldelete(size, kinsert)); }
/* go back to the begining of the current paragraph here we look for a * <NL><NL> or <NL><TAB> or <NL><SPACE> combination to delimit the begining of * a paragraph */ int gotobop (int f, int n) { int suc; /* success of last backchar */ if (n < 0) /* the other way.. */ return (gotoeop (f, -n)); while (n-- > 0) { /* for each one asked for */ /* first scan back until we are in a word */ suc = backchar (FALSE, 1); while (!inword () && suc) suc = backchar (FALSE, 1); curwp->w_doto = 0; /* and go to the B-O-Line */ /* and scan back until we hit a <NL><NL> or <NL><TAB> or a <NL><SPACE> */ while (lback (curwp->w_dotp) != curbp->b_linep) if (llength (curwp->w_dotp) != 0 && lgetc (curwp->w_dotp, curwp->w_doto) != TAB && lgetc (curwp->w_dotp, curwp->w_doto) != ' ') curwp->w_dotp = lback (curwp->w_dotp); else break; /* and then forward until we are in a word */ suc = forwchar (FALSE, 1); while (suc && !inword ()) suc = forwchar (FALSE, 1); } curwp->w_flag |= WFMOVE; /* force screen update */ return (TRUE); }
/* Close fences are matched against their partners, and if on screen the cursor briefly lights there */ void fmatch(int rch) { MARK oldpos; /* original position */ register LINE *toplp; /* top line in current window */ register int count; /* current fence level count */ register char c; /* current character in scan */ int dir, lch; int backcharfailed = FALSE; /* get the matching left-fence char, if it exists */ lch = is_user_fence(rch, &dir); if (lch == 0 || dir != REVERSE) return; /* first get the display update out there */ (void)update(FALSE); /* save the original cursor position */ oldpos = DOT; /* find the top line and set up for scan */ toplp = lback(curwp->w_line.l); count = 1; backchar(TRUE, 2); /* scan back until we find it, or reach past the top of the window */ while (count > 0 && DOT.l != toplp) { c = CurrentChar(); if (c == rch) ++count; if (c == lch) --count; if (backchar(FALSE, 1) != TRUE) { backcharfailed = TRUE; break; } } /* if count is zero, we have a match, display the sucker */ if (count == 0) { if (!backcharfailed) forwchar(FALSE, 1); if (update(FALSE) == TRUE) /* the idea is to leave the cursor there for about a quarter of a second */ catnap(300, FALSE); } /* restore the current position */ DOT = oldpos; }
/* ARGSUSED */ int delbword(int f, int n) { RSIZE size; int s; if ((s = checkdirty(curbp)) != TRUE) return (s); if (curbp->b_flag & BFREADONLY) { dobeep(); ewprintf("Buffer is read-only"); return (FALSE); } if (n < 0) return (FALSE); /* purge kill buffer */ if ((lastflag & CFKILL) == 0) kdelete(); thisflag |= CFKILL; if (backchar(FFRAND, 1) == FALSE) /* hit buffer start */ return (TRUE); /* one deleted */ size = 1; while (n--) { while (inword() == FALSE) { if (backchar(FFRAND, 1) == FALSE) /* hit buffer start */ goto out; ++size; } while (inword() != FALSE) { if (backchar(FFRAND, 1) == FALSE) /* hit buffer start */ goto out; ++size; } } if (forwchar(FFRAND, 1) == FALSE) return (FALSE); /* undo assumed delete */ --size; out: return (ldelete(size, KBACK)); }
/* * Subroutine to do incremental reverse search. It actually uses the same * code as the normal incremental search, as both can go both ways. */ int risearch(int f, int n) { MARK curpos; /* Current point on entry */ /* remember the initial . on entry: */ curpos = DOT; /* Save the current point */ /* Save direction */ last_srch_direc = REVERSE; /* Make sure the search doesn't match where we already are: */ backchar(TRUE, 1); /* Back up a character */ if (!(isearch(f, -n))) { /* Call ISearch backwards */ /* If error in search: */ DOT = curpos; /* Reset the pointer */ curwp->w_flag |= WFMOVE; /* Say we've moved */ (void) update(FALSE); /* And force an update */ mlwarn("[I-Search failed]"); /* Say we died */ return FALSE; } else mlerase(); /* If happy, just erase the cmd line */ return TRUE; }
/* simple finder -- give it a compiled regex, a direction, and it takes you there if it can. no wrapping allowed */ int findpat(int f, int n, regexp * exp, int direc) { int s; MARK savepos; if (!exp) return FALSE; n = need_a_count(f, n, 1); s = TRUE; scanboundpos = curbp->b_line; /* was scanboundry(FALSE,savepos,0); */ scanbound_is_header = TRUE; savepos = DOT; while (s == TRUE && n--) { savepos = DOT; s = ((direc == FORWARD) ? forwchar(TRUE, 1) : backchar(TRUE, 1)); if (s == TRUE) s = scanner(exp, direc, FALSE, (int *) 0); } if (s != TRUE) DOT = savepos; return s; }
/* * Move the cursor forwards by "n" characters. If "n" is less than zero call * "backchar" to actually do the move. Otherwise compute the new cursor * location, and move ".". Error if you try and move off the end of the * buffer. Set the flag if the line pointer for dot changes. */ int forwchar(int f, int n) { int rc = TRUE; n = need_a_count(f, n, 1); if (n < 0) { rc = backchar(f, -n); } else { while (n--) { /* if an explicit arg was given, allow us to land on the newline, else skip it */ if (is_at_end_of_line(DOT) || (f == FALSE && !insertmode && llength(DOT.l) && DOT.o == llength(DOT.l) - 1)) { if (is_header_line(DOT, curbp) || is_last_line(DOT, curbp)) { rc = FALSE; break; } DOT.l = lforw(DOT.l); DOT.o = w_left_margin(curwp); curwp->w_flag |= WFMOVE; } else { DOT.o += BytesAt(DOT.l, DOT.o); } } } return (rc); }
int PASCAL NEAR stopback() { /* don't stop on the second byte of a 2 byte character */ if (curwp->w_doto > 0 && is2byte(curwp->w_dotp->l_text, curwp->w_dotp->l_text + curwp->w_doto - 1)) return(backchar(TRUE, 1)); return(TRUE); }
/* ARGSUSED */ int backword(int f, int n) { if (n < 0) return (forwword(f | FFRAND, -n)); if (backchar(FFRAND, 1) == FALSE) return (FALSE); while (n--) { while (inword() == FALSE) { if (backchar(FFRAND, 1) == FALSE) return (TRUE); } while (inword() != FALSE) { if (backchar(FFRAND, 1) == FALSE) return (TRUE); } } return (forwchar(FFRAND, 1)); }
/* * Go to the beginning of the current sentence. If we skip into an empty line * (from a non-empty line), return at that point -- that's what vi does. */ int gotobosent(int f, int n) { MARK savepos; int looped = 0; int extra; int empty = is_empty_line(DOT); regexp *exp; int s = TRUE; savepos = DOT; exp = b_val_rexp(curbp, VAL_SENTENCES)->reg; while (s && (is_at_end_of_line(DOT) || isSpace(CharAtDot()))) { s = backchar(TRUE, 1); if (is_empty_line(DOT) && !empty) return TRUE; } top: extra = 0; if (findpat(f, n, exp, REVERSE) != TRUE) { return gotobob(f, n); } s = forwchar(TRUE, RegexpLen(exp)); while (s && (is_at_end_of_line(DOT) || isSpace(CharAtDot()))) { s = forwchar(TRUE, 1); extra++; } if (n == 1 && samepoint(savepos, DOT)) { /* try again */ if (looped > 10) return FALSE; s = backchar(TRUE, RegexpLen(exp) + extra + looped); while (s && is_at_end_of_line(DOT)) { if (!empty && is_empty_line(DOT)) return TRUE; s = backchar(TRUE, 1); } looped++; goto top; } return TRUE; }
/* * Add a character, checking for word wrapping. * Check to see if we're past fillcol, and if so, * justify this line. As a last step, justify the line. */ int fillword (int f, int n, int k) { register char c; register int col, i, nce; for (i = col = 0; col <= fillcol; ++i, ++col) { if (i == curwp->w_dot.o) return selfinsert (f, n, k); c = lgetc (curwp->w_dot.p, i); if (c == '\t') col += (tabsize - col % tabsize) - 1; else if (ISCTRL (c) != FALSE) ++col; } if (curwp->w_dot.o != llength (curwp->w_dot.p)) { selfinsert (f, n, k); nce = llength (curwp->w_dot.p) - curwp->w_dot.o; } else nce = 0; curwp->w_dot.o = i; if ((c = lgetc (curwp->w_dot.p, curwp->w_dot.o)) != ' ' && c != '\t') do { backchar (FALSE, 1, KRANDOM); } while ((c = lgetc (curwp->w_dot.p, curwp->w_dot.o)) != ' ' && c != '\t' && curwp->w_dot.o > 0); if (curwp->w_dot.o == 0) do { forwchar (FALSE, 1, KRANDOM); } while ((c = lgetc (curwp->w_dot.p, curwp->w_dot.o)) != ' ' && c != '\t' && curwp->w_dot.o < llength (curwp->w_dot.p)); delwhite (FALSE, 1, KRANDOM); backdel (FALSE, 1, KRANDOM); lnewline (); curwp->w_dot.o = llength (curwp->w_dot.p) - nce; curwp->w_flag |= WFMOVE; if (nce == 0 && curwp->w_dot.o != 0) return (fillword (f, n, k)); return (TRUE); }
/* * Go to the end of the current paragraph. */ int gotoeop(int f, int n) { MARK odot; int was_at_bol; int was_on_empty; int fc; n = need_a_count(f, n, 1); fc = firstchar(DOT.l); was_on_empty = is_empty_line(DOT); was_at_bol = ((fc >= 0 && DOT.o <= fc) || fc < 0); odot = DOT; while (n) { if (findpat(TRUE, 1, b_val_rexp(curbp, VAL_PARAGRAPHS)->reg, FORWARD) != TRUE) { DOT = curbp->b_line; } else if (is_empty_line(DOT)) { /* special case -- if we found an empty line. */ /* either as the very next line, or at the end of our search */ if ((was_on_empty && lback(DOT.l) == odot.l) || (n > 0 && llength(lback(DOT.l)) == 0)) { /* then we haven't really found what we wanted. keep going */ skipblanksf(); continue; } } n--; } if (doingopcmd) { /* if we're now at the beginning of a line and we can back up, do so to avoid eating the newline and leading whitespace */ fc = firstchar(DOT.l); if (((fc >= 0 && DOT.o <= fc) || fc < 0) && !is_first_line(DOT, curbp) && !sameline(DOT, odot)) { backchar(TRUE, DOT.o + 1); } /* if we started at the start of line, eat the whole line */ if (!sameline(DOT, odot) && was_at_bol) regionshape = rgn_FULLLINE; } return TRUE; }
/* * Delete backwards. This is quite easy too, because it's all done with other * functions. Just move the cursor back, and delete forwards. Like delete * forward, this actually does a kill if presented with an argument. Bound to * both "RUBOUT" and "C-H" */ int backdel(int f, int n) { int s; if (n < 0) return (forwdel(f, -n)); if (f != FALSE) { /* Really a kill */ if ((lastflag & CFKILL) == 0) kdelete(); thisflag |= CFKILL; } if ((s = backchar(f, n)) == TRUE) s = ldelete(n, f); return (s); }
/* ARGSUSED */ int fillword(int f, int n) { char c; int col, i, nce; for (i = col = 0; col <= fillcol; ++i, ++col) { if (i == curwp->w_doto) return selfinsert(f, n); c = lgetc(curwp->w_dotp, i); if (c == '\t' #ifdef NOTAB && !(curbp->b_flag & BFNOTAB) #endif ) col |= 0x07; else if (ISCTRL(c) != FALSE) ++col; } if (curwp->w_doto != llength(curwp->w_dotp)) { (void)selfinsert(f, n); nce = llength(curwp->w_dotp) - curwp->w_doto; } else nce = 0; curwp->w_doto = i; if ((c = lgetc(curwp->w_dotp, curwp->w_doto)) != ' ' && c != '\t') do { (void)backchar(FFRAND, 1); } while ((c = lgetc(curwp->w_dotp, curwp->w_doto)) != ' ' && c != '\t' && curwp->w_doto > 0); if (curwp->w_doto == 0) do { (void)forwchar(FFRAND, 1); } while ((c = lgetc(curwp->w_dotp, curwp->w_doto)) != ' ' && c != '\t' && curwp->w_doto < llength(curwp->w_dotp)); (void)delwhite(FFRAND, 1); (void)lnewline(); i = llength(curwp->w_dotp) - nce; curwp->w_doto = i > 0 ? i : 0; curwp->w_rflag |= WFMOVE; if (nce == 0 && curwp->w_doto != 0) return (fillword(f, n)); return (TRUE); }
/* * Go to the beginning of the current paragraph. */ int gotobop(int f, int n) { MARK odot; int was_on_empty; int fc; n = need_a_count(f, n, 1); was_on_empty = is_empty_line(DOT); odot = DOT; fc = firstchar(DOT.l); if (doingopcmd && ((fc >= 0 && DOT.o <= fc) || fc < 0) && !is_first_line(DOT, curbp)) { backchar(TRUE, DOT.o + 1); pre_op_dot = DOT; } while (n) { if (findpat(TRUE, 1, b_val_rexp(curbp, VAL_PARAGRAPHS)->reg, REVERSE) != TRUE) { (void) gotobob(f, n); } else if (is_empty_line(DOT)) { /* special case -- if we found an empty line, and it's adjacent to where we started, skip all adjacent empty lines, and try again */ if ((was_on_empty && lforw(DOT.l) == odot.l) || (n > 0 && llength(lforw(DOT.l)) == 0)) { /* then we haven't really found what we wanted. keep going */ skipblanksb(); continue; } } n--; } if (doingopcmd) { fc = firstchar(DOT.l); if (!sameline(DOT, odot) && (pre_op_dot.o > lastchar(pre_op_dot.l)) && ((fc >= 0 && DOT.o <= fc) || fc < 0)) { regionshape = rgn_FULLLINE; } } return TRUE; }
/* ARGSUSED */ int gotobop(int f, int n) { /* the other way... */ if (n < 0) return (gotoeop(f, -n)); while (n-- > 0) { /* first scan back until we are in a word */ while (backchar(FFRAND, 1) && inword() == 0); /* and go to the B-O-Line */ curwp->w_doto = 0; /* * and scan back until we hit a <NL><SP> <NL><TAB> or * <NL><NL> */ while (lback(curwp->w_dotp) != curbp->b_headp) if (llength(lback(curwp->w_dotp)) && lgetc(curwp->w_dotp, 0) != ' ' && lgetc(curwp->w_dotp, 0) != '.' && lgetc(curwp->w_dotp, 0) != '\t') curwp->w_dotp = lback(curwp->w_dotp); else { if (llength(lback(curwp->w_dotp)) && lgetc(curwp->w_dotp, 0) == '.') { curwp->w_dotp = lforw(curwp->w_dotp); if (curwp->w_dotp == curbp->b_headp) { /* * beyond end of buffer, * cleanup time */ curwp->w_dotp = lback(curwp->w_dotp); curwp->w_doto = llength(curwp->w_dotp); } } break; } } /* force screen update */ curwp->w_rflag |= WFMOVE; return (TRUE); }
/* * Open up some blank space. The basic plan is to insert a bunch of newlines, * and then back up over them. Everything is done by the subcommand * processors. They even handle the looping. Normally this is bound to "C-O" */ int openline(int f, int n) { int i, s; if (n < 0) return (FALSE); if (n == 0) return (TRUE); i = n; /* Insert newlines */ do { s = lnewline(); } while (s == TRUE && --i); if (s == TRUE) /* Then back up overtop */ s = backchar(f, n); /* of them all */ return (s); }
/* * Move the cursor forwards by "n" characters. If "n" is less than zero call * "backchar" to actually do the move. Otherwise compute the new cursor * location, and move ".". Error if you try and move off the end of the * buffer. Set the flag if the line pointer for dot changes. */ int forwchar (int f, int n) { if (n < 0) return (backchar (f, -n)); while (n--) { if (curwp->w_doto == llength (curwp->w_dotp)) { if (curwp->w_dotp == curbp->b_linep) return (FALSE); curwp->w_dotp = lforw (curwp->w_dotp); curwp->w_doto = 0; curwp->w_flag |= WFMOVE; } else curwp->w_doto++; } return (TRUE); }
/* ARGSUSED */ int forwchar(int f, int n) { if (n < 0) return (backchar(f, -n)); while (n--) { if (curwp->w_doto == llength(curwp->w_dotp)) { curwp->w_dotp = lforw(curwp->w_dotp); if (curwp->w_dotp == curbp->b_headp) { curwp->w_dotp = lback(curwp->w_dotp); if (!(f & FFRAND)) ewprintf("End of buffer"); return (FALSE); } curwp->w_doto = 0; curwp->w_dotline++; curwp->w_rflag |= WFMOVE; } else curwp->w_doto++; } return (TRUE); }
/* * Go back to the begining of the current paragraph. * We look for a <NL><NL> or <NL><TAB> or <NL><SPACE> * or <NL>@ or <NL>. (scribe and nroff commands) * combination to delimit the begining of a paragraph. */ int gotobop (int f, int n, int k) { register int c; /* first character in current line */ register LINE *prev; /* previous line */ if (n < 0) /* the other way... */ return (gotoeop (f, -n, KRANDOM)); while (n-- > 0) { /* for each one asked for */ /* first scan back until we are in a word */ while (backchar (FALSE, 1, KRANDOM)) if (inword ()) break; curwp->w_dot.o = 0; /* and go to the B-O-Line */ /* and scan back until we hit a paragraph delimiter as * described above. */ while ((prev = lback (curwp->w_dot.p)) != curbp->b_linep) { if (llength (prev) == 0) break; c = lgetc (curwp->w_dot.p, 0); if (c == ' ' || c == '\t') break; c = lgetc (prev, 0); if (c == '@' || c == '.') break; else curwp->w_dot.p = prev; } } curwp->w_flag |= WFMOVE; /* force screen update */ return TRUE; }
/* * Go forward to the end of the current paragraph. * We look for a <NL><NL> or <NL><TAB> or <NL><SPACE> * or <NL>@ or <NL>. (scribe and nroff commands) * combination to delimit the begining of a paragraph. */ int gotoeop (f, n, k) { register int c; /* first character in current line */ if (n < 0) /* the other way... */ return (gotobop (f, -n, KRANDOM)); while (n-- > 0) { /* for each one asked for */ /* Find the first word on/after the current line */ curwp->w_dot.o = 0; while (forwchar (FALSE, 1, KRANDOM)) if (inword ()) break; curwp->w_dot.o = 0; curwp->w_dot.p = lforw (curwp->w_dot.p); /* Scan forward until we hit a paragraph delimiter as * described above. */ while (curwp->w_dot.p != curbp->b_linep) { if (llength (curwp->w_dot.p) == 0) break; c = lgetc (curwp->w_dot.p, 0); if (c == ' ' || c == '\t' || c == '@' || c == '.') break; else curwp->w_dot.p = lforw (curwp->w_dot.p); } } if (curwp->w_dot.p == curbp->b_linep) /* at end of buffer? */ backchar (FALSE, 1, KRANDOM); /* back up to prev line */ curwp->w_flag |= WFMOVE; /* force screen update */ return (TRUE); }
int risearch(f, n) { LINE *curline; /* Current line on entry */ int curoff; /* Current offset on entry */ /* remember the initial . on entry: */ curline = curwp->w_dotp; /* Save the current line pointer */ curoff = curwp->w_doto; /* Save the current offset */ /* Make sure the search doesn't match where we already are: */ backchar(TRUE, 1); /* Back up a character */ if (!(isearch(f, -n))) /* Call ISearch backwards */ { /* If error in search: */ curwp->w_dotp = curline; /* Reset the line pointer */ curwp->w_doto = curoff; /* and the offset to original value */ curwp->w_flag |= WFMOVE; /* Say we've moved */ update(FALSE); /* And force an update */ mlwrite ("[search failed]"); /* Say we died */ } else mlerase (); /* If happy, just erase the cmd line */ }
/* * Move the cursor forwards by "n" characters. If "n" is less than zero call * "backchar" to actually do the move. Otherwise compute the new cursor * location, and move ".". Error if you try and move off the end of the * buffer. Set the flag if the line pointer for dot changes. */ PASCAL NEAR forwchar( int f, int n )/* prefix flag and argument */ { if (n < 0) return(backchar(f, -n)); while (n--) { if (curwp->w_doto == llength(curwp->w_dotp)) { if (curwp->w_dotp == curbp->b_linep) return(FALSE); curwp->w_dotp = lforw(curwp->w_dotp); curwp->w_doto = 0; curwp->w_flag |= WFMOVE; } else curwp->w_doto++; } #if DBCS return(stopforw()); #else return(TRUE); #endif }
static int is_find(int dir) { int plen, odoto, odotline; struct line *odotp; odoto = curwp->w_doto; odotp = curwp->w_dotp; odotline = curwp->w_dotline; plen = strlen(pat); if (plen != 0) { if (dir == SRCH_FORW) { (void)backchar(FFARG | FFRAND, plen); if (forwsrch() == FALSE) { curwp->w_doto = odoto; curwp->w_dotp = odotp; curwp->w_dotline = odotline; return (FALSE); } return (TRUE); } if (dir == SRCH_BACK) { (void)forwchar(FFARG | FFRAND, plen); if (backsrch() == FALSE) { curwp->w_doto = odoto; curwp->w_dotp = odotp; curwp->w_dotline = odotline; return (FALSE); } return (TRUE); } dobeep(); ewprintf("bad call to is_find"); return (FALSE); } return (FALSE); }
/* * Delete backwards. This is quite easy too, because it's all done with other * functions. Just move the cursor back, and delete forwards. Like delete * forward, this actually does a kill if presented with an argument. Bound to * both "RUBOUT" and "C-H". */ int backdel(int f, int n) { register int s; if (curbp->b_mode&MDVIEW) /* don't allow this command if */ return(rdonly()); /* we are in read only mode */ if (n < 0) return (forwdel(f, -n)); if(TERM_OPTIMIZE && curwp->w_dotp != curwp->w_bufp->b_linep){ int l; if(worthit(&l) && curwp->w_doto == 0 && lback(curwp->w_dotp) != curwp->w_bufp->b_linep){ if(l == curwp->w_toprow) scrollup(curwp, l+1, 1); else if(llength(lback(curwp->w_dotp)) == 0) scrollup(curwp, l-1, 1); else scrollup(curwp, l, 1); } } if (f != FALSE) { /* Really a kill. */ if ((lastflag&CFKILL) == 0) kdelete(); thisflag |= CFKILL; } if ((s=backchar(f, n)) == TRUE) s = ldelete((long) n, f ? kinsert : NULL); return (s); }
int var_CHAR(TBUFF **rp, const char *vp) { int status = FALSE; if (rp) { if (valid_buffer(curbp) && !is_empty_buf(curbp)) { render_int(rp, CharAtDot()); } else { tb_scopy(rp, error_val); } status = TRUE; } else if (vp) { if ((status = check_editable(curbp)) == TRUE) { int c; mayneedundo(); (void) ldel_chars(1L, FALSE); /* delete 1 char */ c = scan_int(vp); if ((status = bputc(c)) == TRUE) (void) backchar(FALSE, 1); } } return status; }
token get_token() { char c = nextchar(); while (c == ' ' || c == '\n') c = nextchar(); switch(c) { case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'g': case 'h': case 'i': case 'j': case 'k': case 'l': case 'm': case 'n': case 'o': case 'p': case 'q': case 'r': case 's': case 't': case 'u': case 'v': case 'w': case 'x': case 'y': case 'z': case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': case 'G': case 'H': case 'I': case 'J': case 'K': case 'L': case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R': case 'S': case 'T': case 'U': case 'V': case 'W': case 'X': case 'Y': case 'Z': case '_': { char temp_string[32]; int i = 0; while (is_string_character(c)) { temp_string[i] = c; i += 1; c = nextchar(); } backchar(); temp_string[i] = 0; char * s = strdup(temp_string); return create_string_token(s, 0); } case '\"': { char temp_string[32]; c = nextchar(); int pos = 0; while (pos < 31 && c != '\"') { temp_string[pos] = c; pos += 1; c = nextchar(); } temp_string[pos] = 0; if (pos == 31) { error_message("max string length is 31 characters\n"); exit(1); } char * s = strdup(temp_string); return create_string_token(s, 1); } case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': { int value = c - '0'; c = nextchar(); while (c >= '0' && c <= '9') { value = value * 10 + c - '0'; c = nextchar(); } backchar(); return create_token(integer_constant, value); } case '+': case '-': case '*': return create_binary_operator_token(c); case '/': { c = nextchar(); if (c == ' ') return create_binary_operator_token(c); if (c == '/') { current_line->character_number = current_line->length; return get_token(); } else { error_message("unrecognized use of '/' character\n"); exit(1); } } case '=': { c = nextchar(); if (c == ' ') { error_message("for initialization and assignment use :="); exit(1); } else if (c == '=') return create_token(comparison_operator, equal); } case '!': { c = nextchar(); if (c == '=') return create_token(comparison_operator, not_equal); else { error_message("undefined use of '!' character"); exit(1); } } case '<': { c = nextchar(); if (c == '=') return create_token(comparison_operator, less_or_equal); backchar(); return create_token(comparison_operator, less_than); } case '>': { c = nextchar(); if (c == '=') return create_token(comparison_operator, greater_or_equal); backchar(); return create_token(comparison_operator, greater_than); } case ':': { c = nextchar(); if (c != '=') { error_message("did you mean :=?"); exit(1); } else return create_token(assignment, 0); } case '(': return create_token(open_parenthesis, 0); case ')': return create_token(close_parenthesis, 0); case '{': return create_token(open_curly_bracket, 0); case '}': return create_token(close_curly_bracket, 0); case ';': return create_token(semi_colon, 0); case(0): return create_token(end_of_file, 0); //todo: return error token default: { error_message(""); printf("character %c unrecognized\n", c); exit(1); } } }
/* * insert spaces forward into text * * int f, n; default flag and numeric argument */ int insspace(int f, int n) { linsert(n, ' '); backchar(f, n); return TRUE; }
/* * The region we're filling is the region from dot to mark. * We cut out that region and then put it back in filled. * The cut out part is saved in the ldelete call and the * reinstalled region is noted in addedregion, so that yank() * can delete it and restore the saved part. */ int fillregion(UCS *qstr, REGION *addedregion) { long c, sz, last_char = 0; int i, j, qlen, same_word, spaces, word_len, word_ind, line_len, ww; int starts_midline = 0; int ends_midline = 0; int offset_into_start; LINE *line_before_start, *lp; UCS line_last, word[NSTRING]; REGION region; /* if region starts midline insert a newline */ if(curwp->w_doto > 0 && curwp->w_doto < llength(curwp->w_dotp)) starts_midline++; /* if region ends midline insert a newline at end */ if(curwp->w_marko > 0 && curwp->w_marko < llength(curwp->w_markp)) ends_midline++; /* cut the paragraph into our fill buffer */ fdelete(); if(!getregion(®ion, curwp->w_markp, curwp->w_marko)) return(FALSE); if(!ldelete(region.r_size, finsert)) return(FALSE); line_before_start = lback(curwp->w_dotp); offset_into_start = curwp->w_doto; if(starts_midline) lnewline(); /* Now insert it back wrapped */ spaces = word_len = word_ind = line_len = same_word = 0; qlen = qstr ? ucs4_strlen(qstr) : 0; /* Beginning with leading quoting... */ if(qstr){ i = 0; while(qstr[i]){ ww = wcellwidth(qstr[i]); line_len += (ww >= 0 ? ww : 1); linsert(1, qstr[i++]); } line_last = ' '; /* no word-flush space! */ } /* remove first leading quotes if any */ if(starts_midline) i = 0; else for(i = qlen; (c = fremove(i)) == ' ' || c == TAB; i++){ linsert(1, line_last = (UCS) c); line_len += ((c == TAB) ? (~line_len & 0x07) + 1 : 1); } /* then digest the rest... */ while((c = fremove(i++)) >= 0){ last_char = c; switch(c){ case '\n' : /* skip next quote string */ j = 0; while(j < qlen && ((c = fremove(i+j)) == qstr[j] || c == ' ')) j++; i += j; if(!spaces) spaces++; same_word = 0; break; case TAB : case ' ' : spaces++; same_word = 0; break; default : if(spaces){ /* flush word? */ if((line_len - qlen > 0) && line_len + word_len + 1 > fillcol && ((ucs4_isspace(line_last)) || (linsert(1, ' '))) && (line_len = fpnewline(qstr))) line_last = ' '; /* no word-flush space! */ if(word_len){ /* word to write? */ if(line_len && !ucs4_isspace(line_last)){ linsert(1, ' '); /* need padding? */ line_len++; } line_len += word_len; for(j = 0; j < word_ind; j++) linsert(1, line_last = word[j]); if(spaces > 1 && strchr(".?!:;\")", line_last)){ linsert(2, line_last = ' '); line_len += 2; } word_len = word_ind = 0; } spaces = 0; } if(word_ind + 1 >= NSTRING){ /* Magic! Fake that we output a wrapped word */ if((line_len - qlen > 0) && !same_word++){ if(!ucs4_isspace(line_last)) linsert(1, ' '); line_len = fpnewline(qstr); } line_len += word_len; for(j = 0; j < word_ind; j++) linsert(1, word[j]); word_len = word_ind = 0; line_last = ' '; } word[word_ind++] = (UCS) c; ww = wcellwidth((UCS) c); word_len += (ww >= 0 ? ww : 1); break; } } if(word_len){ if((line_len - qlen > 0) && (line_len + word_len + 1 > fillcol)){ if(!ucs4_isspace(line_last)) linsert(1, ' '); (void) fpnewline(qstr); } else if(line_len && !ucs4_isspace(line_last)) linsert(1, ' '); for(j = 0; j < word_ind; j++) linsert(1, word[j]); } if(last_char == '\n') lnewline(); if(ends_midline) (void) fpnewline(qstr); /* * Calculate the size of the region that was added. */ swapmark(0,1); /* mark current location after adds */ addedregion->r_linep = lforw(line_before_start); addedregion->r_offset = offset_into_start; lp = addedregion->r_linep; sz = llength(lp) - addedregion->r_offset; if(lforw(lp) != curwp->w_markp->l_fp){ lp = lforw(lp); while(lp != curwp->w_markp->l_fp){ sz += llength(lp) + 1; lp = lforw(lp); } } sz -= llength(curwp->w_markp) - curwp->w_marko; addedregion->r_size = sz; swapmark(0,1); if(ends_midline){ /* * We want to back up to the end of the original * region instead of being here after the added newline. */ curwp->w_doto = 0; backchar(0, 1); unmarkbuffer(); markregion(1); } return(TRUE); }