/* ldump_heap_state * * Traverse the heap segments, writing the FASL code of each cell to * a file of the specified name. */ lref_t ldump_heap_state(lref_t port) { for (size_t heap_no = 0; heap_no < interp.gc_max_heap_segments; heap_no++) { if (interp.gc_heap_segments[heap_no] == NULL) continue; lref_t obj; lref_t org = interp.gc_heap_segments[heap_no]; lref_t end = org + interp.gc_heap_segment_size; fixnum_t ii; for (obj = org, ii = 0; obj < end; obj++, ii++) { if (ii % 256 == 0) { lnewline(port); ii = 0; } scwritef(_T("~cd, "), port, TYPE(obj)); } } return NIL; }
/* * Yank text back from the kill buffer. This is really easy. All of the work * is done by the standard insert routines. All you do is run the loop, and * check for errors. Bound to "C-Y" */ int yank(int f, int n) { int c, i; if (n < 0) return (FALSE); while (n--) { i = 0; while ((c = kremove(i)) >= 0) { if (c == '\n') { if (lnewline(FALSE, 1) == FALSE) return (FALSE); } else { if (linsert(1, c) == FALSE) return (FALSE); } ++i; } } return (TRUE); }
/* Word wrap on n-spaces. Back-over whatever precedes the point on the current * line and stop on the first word-break or the beginning of the line. If we * reach the beginning of the line, jump back to the end of the word and start * a new line. Otherwise, break the line at the word-break, eat it, and jump * back to the end of the word. * Returns TRUE on success, FALSE on errors. */ wrapword() { register int cnt; /* size of word wrapped to next line */ register int bp; /* index to wrap on */ register int first = -1; register int i; if(curwp->w_doto <= 0) /* no line to wrap? */ return(FALSE); for(bp = cnt = i = 0; cnt < llength(curwp->w_dotp) && !bp; cnt++, i++){ if(isspace((unsigned char) lgetc(curwp->w_dotp, cnt).c)){ first = 0; if(lgetc(curwp->w_dotp, cnt).c == TAB) while(i+1 & 0x07) i++; } else if(!first) first = cnt; if(first > 0 && i >= fillcol) bp = first; } if(!bp) return(FALSE); /* bp now points to the first character of the next line */ cnt = curwp->w_doto - bp; curwp->w_doto = bp; if(!lnewline()) /* break the line */ return(FALSE); /* * if there's a line below, it doesn't start with whitespace * and there's room for this line... */ if(!(curbp->b_flag & BFWRAPOPEN) && lforw(curwp->w_dotp) != curbp->b_linep && llength(lforw(curwp->w_dotp)) && !isspace((unsigned char) lgetc(lforw(curwp->w_dotp), 0).c) && (llength(curwp->w_dotp) + llength(lforw(curwp->w_dotp)) < fillcol)){ gotoeol(0, 1); /* then pull text up from below */ if(lgetc(curwp->w_dotp, curwp->w_doto - 1).c != ' ') linsert(1, ' '); forwdel(0, 1); gotobol(0, 1); } curbp->b_flag &= ~BFWRAPOPEN; /* don't open new line next wrap */ /* restore dot (account for NL) */ if(cnt && !forwchar(0, cnt < 0 ? cnt-1 : cnt)) return(FALSE); return(TRUE); }
void region_put_data(const char *buf, int len) { int i; for (i = 0; buf[i] != '\0' && i < len; i++) { if (buf[i] == '\n') lnewline(); else linsert(1, buf[i]); } }
/* * 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); }
/* * Insert a newline. Bound to "C-M". */ int newline(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 (FALSE); if(TERM_OPTIMIZE && (curwp->w_dotp != curwp->w_bufp->b_linep)){ int l; if(worthit(&l)){ if(curwp->w_doto != 0) l++; scrolldown(curwp, l, n); } } /* if we are in C mode and this is a default <NL> */ /* pico's never in C mode */ if(Pmaster && Pmaster->allow_flowed_text && curwp->w_doto && ucs4_isspace(lgetc(curwp->w_dotp, curwp->w_doto - 1).c) && !(curwp->w_doto == 3 && lgetc(curwp->w_dotp, 0).c == '-' && lgetc(curwp->w_dotp, 1).c == '-' && lgetc(curwp->w_dotp, 2).c == ' ')){ /* * flowed mode, make the newline a hard one by * stripping trailing space. */ int i, dellen; for(i = curwp->w_doto - 1; i && ucs4_isspace(lgetc(curwp->w_dotp, i - 1).c); i--); dellen = curwp->w_doto - i; curwp->w_doto = i; ldelete(dellen, NULL); } /* insert some lines */ while (n--) { if ((s=lnewline()) != TRUE) return (s); } return (TRUE); }
/* * Insert a newline. Bound to "C-M". */ int newline(int f, int n) { int s; if (n < 0) return (FALSE); /* insert some lines */ while (n--) { if ((s = lnewline()) != TRUE) return (s); } return (TRUE); }
/* ARGSUSED */ int insert(int f, int n) { char buf[128], *bufp, *cp; int count, c; if (inmacro) { while (--n >= 0) { for (count = 0; count < maclcur->l_used; count++) { if ((((c = maclcur->l_text[count]) == '\n') ? lnewline() : linsert(1, c)) != TRUE) return (FALSE); } } maclcur = maclcur->l_fp; return (TRUE); } if (n == 1) /* CFINS means selfinsert can tack on the end */ thisflag |= CFINS; if ((bufp = eread("Insert: ", buf, sizeof(buf), EFNEW)) == NULL) return (ABORT); else if (bufp[0] == '\0') return (FALSE); while (--n >= 0) { cp = buf; while (*cp) { if (((*cp == '\n') ? lnewline() : linsert(1, *cp)) != TRUE) return (FALSE); cp++; } } return (TRUE); }
/* * putctext: * replace the current line with the passed in text * * char *iline; contents of new line */ int putctext(char *iline) { int status; /* delete the current line */ curwp->w_doto = 0; /* starting at the beginning of the line */ if ((status = killtext(TRUE, 1)) != TRUE) return status; /* insert the new line */ if ((status = linstr(iline)) != TRUE) return status; status = lnewline(); backline(TRUE, 1); return status; }
/* * fpnewline - output a fill paragraph newline mindful of quote string */ int fpnewline(UCS *quote) { int len; lnewline(); for(len = 0; quote && *quote; quote++){ int ww; ww = wcellwidth(*quote); len += (ww >= 0 ? ww : 1); linsert(1, *quote); } return(len); }
/* 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); }
lref_t lfresh_line(lref_t port) { if (NULLP(port)) port = CURRENT_OUTPUT_PORT(); if (!TEXT_PORTP(port)) vmerror_wrong_type_n(1, port); if (PORT_INPUTP(port)) vmerror_unsupported(_T("cannot fresh-line to input ports")); if ((PORT_TEXT_INFO(port)->col != 0) && !PORT_TEXT_INFO(port)->needs_lf) { lnewline(port); return boolcons(true); } return boolcons(false); }
/* * 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); }
int linstr(char *instr) { int status = TRUE; char tmpc; if (instr != NULL) while ((tmpc = *instr) && status == TRUE) { status = (tmpc == '\n' ? lnewline() : linsert(1, tmpc)); /* Insertion error? */ if (status != TRUE) { mlwrite("%%Out of memory while inserting"); break; } instr++; } return status; }
/* * Quote the next character, and insert it into the buffer. All the characters * are taken literally, with the exception of the newline, which always has * its line splitting meaning. The character is always read, even if it is * inserted 0 times, for regularity. Bound to "C-Q" */ int quote(int f, int n) { int s, c; c = (*term.t_getchar) (); if (n < 0) return (FALSE); if (n == 0) return (TRUE); if (c == '\n') { do { s = lnewline(); } while (s == TRUE && --n); return (s); } return (linsert(n, c)); }
/* * Yank text back from the kill buffer. This is really easy. All of the work * is done by the standard insert routines. All you do is run the loop, and * check for errors. Bound to "C-Y". */ int yank(int f, int n) { int c; int i; char *sp; /* pointer into string to insert */ struct kill *kp; /* pointer into kill buffer */ if (curbp->b_mode & MDVIEW) /* don't allow this command if */ return rdonly(); /* we are in read only mode */ if (n < 0) return FALSE; /* make sure there is something to yank */ if (kbufh == NULL) return TRUE; /* not an error, just nothing */ /* for each time.... */ while (n--) { kp = kbufh; while (kp != NULL) { if (kp->d_next == NULL) i = kused; else i = KBLOCK; sp = kp->d_chunk; while (i--) { if ((c = *sp++) == '\n') { if (lnewline() == FALSE) return FALSE; } else { if (linsert(1, c) == FALSE) return FALSE; } } kp = kp->d_next; } } return TRUE; }
PASCAL NEAR makefold(f, n) { register int status; /* return status */ BUFFER *bp; /* buffer being folded*/ WINDOW *wp; /* windows to fix up pointers in as well */ REGION creg; /* region boundry structure */ char foldstr[NSTRING]; /* Fold string to insert into buffer/file */ LINE *topboundary; /* Line before fold */ LINE *botboundary; /* Line after fold */ int i; /* Loop */ char mprefix[NSTRING]; /* mark prefix */ int lm; /* left margin value */ LINE *lp; /* line pointer */ short ltype; /* saved line type */ if (curbp->b_mode&MDVIEW) /* don't allow this command if */ return(rdonly()); /* we are in read only mode */ /* find the proper buffer */ bp = curwp->w_bufp; /* find the boundries of the current region */ /* remember these could be fold lines */ /* call getrawregion first, cos this will check if we cross crease */ if ((status=getrawregion(&creg)) != TRUE) return(status); /* check if we have to indent the fold marker */ i = 0; lm = curwp->w_markp[0]->l_lmargin; if (curwp->w_marko[0] > lm) { while (((curwp->w_markp[0]->l_text[i + lm] == ' ') || (curwp->w_markp[0]->l_text[i + lm] == '\t')) && (i + lm < curwp->w_marko[0])) { mprefix[i] = curwp->w_markp[0]->l_text[i + lm]; i++; } } mprefix[i] = NULL; if ((status=getregion(&creg)) != TRUE) return(status); curwp->w_dotp = creg.r_linep; /* only by full lines */ curwp->w_doto = 0; creg.r_size += (long)creg.r_offset; if (creg.r_size <= (long)curwp->w_dotp->l_used) { mlwrite(TEXT222); /* "%%Must fold at least 1 full line" */ return(FALSE); } /* insert the mapped fold-start line at top */ /* have to insert and backup since it could already be a fold line */ /* Unless line is normal cannot insert nl at left margin */ ltype = curwp->w_dotp->l_type; curwp->w_dotp->l_type = LNORMAL; curwp->w_doto = curwp->w_dotp->l_lmargin; lnewline(); /* Reset line type, backup and insert fold symbol */ curwp->w_dotp->l_type = ltype; curwp->w_dotp = curwp->w_dotp->l_bp; strcpy(foldstr, mprefix); strcat(foldstr, FOLDSYMBOL); linstr(foldstr); topboundary = curwp->w_dotp; curwp->w_dotp = curwp->w_dotp->l_fp; curwp->w_doto = 0; /* move forward to the end of this region (a long number of bytes perhaps) */ while (creg.r_size > (long)32000) { forwchar(TRUE, 32000); creg.r_size -= (long)32000; } forwchar(TRUE, (int)creg.r_size); curwp->w_doto = 0; /* only full lines! */ /* Unless line is normal cannot insert nl at left margin */ ltype = curwp->w_dotp->l_type; /* exception is end of open fold */ if (ltype == LEOEFOLD) curwp->w_doto = loffset(curwp->w_dotp); else { curwp->w_dotp->l_type = LNORMAL; curwp->w_doto = curwp->w_dotp->l_lmargin; } lnewline(); /* Reset line type, backup and insert end fold symbol */ curwp->w_dotp->l_type = ltype; curwp->w_dotp = curwp->w_dotp->l_bp; strcpy(foldstr, mprefix); strcat(foldstr, ENDFOLD); linstr(foldstr); botboundary = curwp->w_dotp; /* set the fold pointers and line types */ topboundary->l_type = LSOFOLD; topboundary->l_foldp = botboundary; botboundary->l_type = LEOFOLD; botboundary->l_foldp = topboundary; /* set left margin? */ if (i) { curwp->w_dotp = topboundary->l_fp; i += curwp->w_dotp->l_lmargin; while (curwp->w_dotp != botboundary) { if (loffset(curwp->w_dotp) < i) { /* insert prefix - else problems! */ curwp->w_doto = curwp->w_dotp->l_lmargin; linstr(mprefix); } if (curwp->w_dotp->l_lmargin < i) /* not inner fold */ curwp->w_dotp->l_lmargin = i; curwp->w_dotp = curwp->w_dotp->l_fp; /* lforw() won't find the line */ } } /* move cursor to fold line */ curwp->w_dotp = topboundary; curwp->w_doto = llength(curwp->w_dotp); /* clear out marks */ for (i = 0; i < NMARKS; i++) bp->b_markp[i] = (LINE *)NULL; /* let all the proper windows be updated */ wp = wheadp; while (wp) { if (wp->w_bufp == bp) wp->w_flag |= (WFHARD|WFMODE); wp = wp->w_wndp; } mlwrite(TEXT224); /* "[Buffer folded]" */ return(TRUE); }
/* * replaces: search for a string and replace it with another string. query * might be enabled (according to kind) */ int replaces (int kind, int f, int n) { LINE *origline; /* original "." position */ char tmpc; /* temporary character */ char c; /* input char for query */ char tpat[NPAT]; /* temporary to hold search pattern */ int i; /* loop index */ int s; /* success flag on pattern inputs */ int slength, rlength; /* length of search and replace strings */ int numsub; /* number of substitutions */ int nummatch; /* number of found matches */ int nlflag; /* last char of search string a <NL>? */ int nlrepl; /* was a replace done on the last line? */ int origoff; /* and offset (for . query option) */ /* check for negative repititions */ if (f && n < 0) return (FALSE); /* ask the user for the text of a pattern */ if ((s = readpattern ((kind == FALSE ? "Replace" : "Query replace"))) != TRUE) return (s); strncpy (&tpat[0], &pat[0], NPAT); /* salt it away */ /* ask for the replacement string */ strncpy (&pat[0], &rpat[0], NPAT); /* set up default string */ if ((s = readpattern ("with")) == ABORT) return (s); /* move everything to the right place and length them */ strncpy (&rpat[0], &pat[0], NPAT); strncpy (&pat[0], &tpat[0], NPAT); slength = strlen (&pat[0]); rlength = strlen (&rpat[0]); /* set up flags so we can make sure not to do a recursive replace on the * last line */ nlflag = (pat[slength - 1] == '\n'); nlrepl = FALSE; /* build query replace question string */ strncpy (tpat, "Replace '", 10); expandp (&pat[0], &tpat[strlen (tpat)], NPAT / 3); strncat (tpat, "' with '", 9); expandp (&rpat[0], &tpat[strlen (tpat)], NPAT / 3); strncat (tpat, "'? ", 4); /* save original . position */ origline = curwp->w_dotp; origoff = curwp->w_doto; /* scan through the file */ numsub = 0; nummatch = 0; while ((f == FALSE || n > nummatch) && (nlflag == FALSE || nlrepl == FALSE)) { /* search for the pattern */ if (forscan (&pat[0], PTBEG) != TRUE) break; /* all done */ ++nummatch; /* increment # of matches */ /* check if we are on the last line */ nlrepl = (lforw (curwp->w_dotp) == curwp->w_bufp->b_linep); /* check for query */ if (kind) { /* get the query */ mlwrite (&tpat[0], &pat[0], &rpat[0]); qprompt: update (); /* show the proposed place to change */ c = (*term.t_getchar) (); /* and input */ mlwrite (""); /* and clear it */ /* and respond appropriately */ switch (c) { case 'y': /* yes, substitute */ case ' ': break; case 'n': /* no, onword */ forwchar (FALSE, 1); continue; case '!': /* yes/stop asking */ kind = FALSE; break; case '.': /* abort! and return */ /* restore old position */ curwp->w_dotp = origline; curwp->w_doto = origoff; curwp->w_flag |= WFMOVE; case BELL: /* abort! and stay */ mlwrite ("Aborted!"); return (FALSE); case 0x0d: /* controlled exit */ case 'q': return (TRUE); default: /* bitch and beep */ (*term.t_beep) (); case '?': /* help me */ mlwrite ("(Y)es, (N)o, (!)Do the rest, (^G,RET,q)Abort, (.)Abort back, (?)Help: "); goto qprompt; } } /* delete the sucker */ if (ldelete (slength, FALSE) != TRUE) { /* error while deleting */ mlwrite ("ERROR while deleteing"); return (FALSE); } /* and insert its replacement */ for (i = 0; i < rlength; i++) { tmpc = rpat[i]; s = (tmpc == '\n' ? lnewline () : linsert (1, tmpc)); if (s != TRUE) { /* error while inserting */ mlwrite ("Out of memory while inserting"); return (FALSE); } } numsub++; /* increment # of substitutions */ } /* and report the results */ mlwrite ("%d substitutions", numsub); 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); }
int setquotelevelinregion(int quotelevel, REGION *addedregion) { int i, standards_based = 0; int quote_chars = 0, backuptoprevline = 0; int starts_midline = 0, ends_midline = 0, offset_into_start; long c, sz; UCS qstr_def1[] = { '>', ' ', 0}, qstr_def2[] = { '>', 0}; LINE *lp, *line_before_start; REGION region; if(curbp->b_mode&MDVIEW) /* don't allow this command if */ return(rdonly()); /* we are in read only mode */ if(!glo_quote_str || !ucs4_strcmp(glo_quote_str, qstr_def1) || !ucs4_strcmp(glo_quote_str, qstr_def2)) standards_based++; if(!standards_based){ emlwrite("Quote level setting only works with standard \"> \" quotes", NULL); return(FALSE); } /* 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++; backuptoprevline++; /* count quote chars for re-insertion */ for(i = 0; i < llength(curwp->w_markp); ++i) if(lgetc(curwp->w_markp, i).c != '>') break; quote_chars = i; } else if(curwp->w_marko == 0) backuptoprevline++; /* find the size of the region */ getregion(®ion, curwp->w_markp, curwp->w_marko); /* cut the paragraph into our fill buffer */ fdelete(); if(!ldelete(region.r_size, finsert)) return(FALSE); line_before_start = lback(curwp->w_dotp); offset_into_start = curwp->w_doto; /* if region starts midline add a newline */ if(starts_midline) lnewline(); i = 0; while(fremove(i) >= 0){ /* remove all quote strs from current line */ if(standards_based){ while((c = fremove(i)) == '>') i++; if(c == ' ') i++; } else{ } /* insert quotelevel quote strs */ if(standards_based){ linsert(quotelevel, '>'); if(quotelevel > 0) linsert(1, ' '); } else{ } /* put back the actual line */ while((c = fremove(i++)) >= 0 && c != '\n') linsert(1, (UCS) c); if(c == '\n') lnewline(); } /* if region ends midline add a newline */ if(ends_midline){ lnewline(); if(quote_chars){ linsert(quote_chars, '>'); if(curwp->w_doto < llength(curwp->w_dotp) && lgetc(curwp->w_dotp, curwp->w_doto).c != ' ') linsert(1, ' '); } } /* * 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); /* * This puts us at the end of the quoted region instead * of on the following line. This makes it convenient * for the user to follow a quotelevel adjustment with * a Justify if desired. */ if(backuptoprevline){ curwp->w_doto = 0; backchar(0, 1); } if(ends_midline){ /* doesn't need fixing otherwise */ unmarkbuffer(); markregion(1); } return (TRUE); }
/* * Yank text back from the kill buffer. This is really easy. All of the work * is done by the standard insert routines. All you do is run the loop, and * check for errors. Bound to "C-Y". */ int yank(int f, int n) { int c, i; REGION region, *added_region; LINE *dotp; 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(TERM_OPTIMIZE && (curwp->w_dotp != curwp->w_bufp->b_linep)){ int l; if(worthit(&l) && !(lastflag&CFFILL)){ register int t = 0; register int i = 0; register int ch; while((ch=fremove(i++)) >= 0) if(ch == '\n') t++; if(t+l < curwp->w_toprow+curwp->w_ntrows) scrolldown(curwp, l, t); } } if(lastflag & CFFILL){ /* if last command was fillpara() */ if(lastflag & CFFLBF){ gotoeob(FALSE, 1); dotp = curwp->w_dotp; gotobob(FALSE, 1); curwp->w_doto = 0; getregion(®ion, dotp, llength(dotp)); } else{ added_region = get_last_region_added(); if(added_region){ curwp->w_dotp = added_region->r_linep; curwp->w_doto = added_region->r_offset; region = (*added_region); } else return(FALSE); } if(!ldelete(region.r_size, NULL)) return(FALSE); } /* then splat out the saved buffer */ while (n--) { i = 0; while ((c = ((lastflag&CFFILL) ? ((lastflag & CFFLBF) ? kremove(i) : fremove(i)) : kremove(i))) >= 0) { if (c == '\n') { if (lnewline() == FALSE) return (FALSE); } else { if (linsert(1, c) == FALSE) return (FALSE); } ++i; } } if(lastflag&CFFLPA){ /* if last command was fill paragraph */ curwp->w_dotp = lforw(curwp->w_dotp); curwp->w_doto = 0; curwp->w_flag |= WFMODE; if(!Pmaster){ sgarbk = TRUE; emlwrite("", NULL); } } return (TRUE); }
int insertfile(char *fname, char *newname, int replacebuf) { struct buffer *bp; struct line *lp1, *lp2; struct line *olp; /* line we started at */ struct mgwin *wp; int nbytes, s, nline = 0, siz, x, x2; int opos; /* offset we started at */ int oline; /* original line number */ char *dp; if (replacebuf == TRUE) x = undo_enable(FFRAND, 0); else x = undo_enabled(); lp1 = NULL; if (line == NULL) { line = malloc(NLINE); if (line == NULL) panic("out of memory"); linesize = NLINE; } /* cheap */ bp = curbp; if (newname != NULL) { (void)strlcpy(bp->b_fname, newname, sizeof(bp->b_fname)); dp = xdirname(newname); (void)strlcpy(bp->b_cwd, dp, sizeof(bp->b_cwd)); (void)strlcat(bp->b_cwd, "/", sizeof(bp->b_cwd)); free(dp); } /* hard file open */ if ((s = ffropen(fname, (replacebuf == TRUE) ? bp : NULL)) == FIOERR) goto out; if (s == FIOFNF) { /* file not found */ if (newname != NULL) ewprintf("(New file)"); else ewprintf("(File not found)"); goto out; } else if (s == FIODIR) { /* file was a directory */ if (replacebuf == FALSE) { ewprintf("Cannot insert: file is a directory, %s", fname); goto cleanup; } killbuffer(bp); if ((bp = dired_(fname)) == NULL) return (FALSE); undo_enable(FFRAND, x); curbp = bp; return (showbuffer(bp, curwp, WFFULL | WFMODE)); } else { dp = xdirname(fname); (void)strlcpy(bp->b_cwd, dp, sizeof(bp->b_cwd)); (void)strlcat(bp->b_cwd, "/", sizeof(bp->b_cwd)); free(dp); } opos = curwp->w_doto; oline = curwp->w_dotline; /* * Open a new line at dot and start inserting after it. * We will delete this newline after insertion. * Disable undo, as we create the undo record manually. */ x2 = undo_enable(FFRAND, 0); (void)lnewline(); olp = lback(curwp->w_dotp); undo_enable(FFRAND, x2); nline = 0; siz = 0; while ((s = ffgetline(line, linesize, &nbytes)) != FIOERR) { retry: siz += nbytes + 1; switch (s) { case FIOSUC: /* FALLTHRU */ case FIOEOF: ++nline; if ((lp1 = lalloc(nbytes)) == NULL) { /* keep message on the display */ s = FIOERR; undo_add_insert(olp, opos, siz - nbytes - 1 - 1); goto endoffile; } bcopy(line, <ext(lp1)[0], nbytes); lp2 = lback(curwp->w_dotp); lp2->l_fp = lp1; lp1->l_fp = curwp->w_dotp; lp1->l_bp = lp2; curwp->w_dotp->l_bp = lp1; if (s == FIOEOF) { undo_add_insert(olp, opos, siz - 1); goto endoffile; } break; case FIOLONG: { /* a line too long to fit in our buffer */ char *cp; int newsize; newsize = linesize * 2; if (newsize < 0 || (cp = malloc(newsize)) == NULL) { ewprintf("Could not allocate %d bytes", newsize); s = FIOERR; goto endoffile; } bcopy(line, cp, linesize); free(line); line = cp; s = ffgetline(line + linesize, linesize, &nbytes); nbytes += linesize; linesize = newsize; if (s == FIOERR) goto endoffile; goto retry; } default: ewprintf("Unknown code %d reading file", s); s = FIOERR; break; } } endoffile: /* ignore errors */ ffclose(NULL); /* don't zap an error */ if (s == FIOEOF) { if (nline == 1) ewprintf("(Read 1 line)"); else ewprintf("(Read %d lines)", nline); } /* set mark at the end of the text */ curwp->w_dotp = curwp->w_markp = lback(curwp->w_dotp); curwp->w_marko = llength(curwp->w_markp); curwp->w_markline = oline + nline + 1; /* * if we are at the end of the file, ldelnewline is a no-op, * but we still need to decrement the line and markline counts * as we've accounted for this fencepost in our arithmetic */ if (lforw(curwp->w_dotp) == curwp->w_bufp->b_headp) { curwp->w_bufp->b_lines--; curwp->w_markline--; } else (void)ldelnewline(); curwp->w_dotp = olp; curwp->w_doto = opos; curwp->w_dotline = oline; if (olp == curbp->b_headp) curwp->w_dotp = lforw(olp); if (newname != NULL) bp->b_flag |= BFCHG | BFBAK; /* Need a backup. */ else bp->b_flag |= BFCHG; /* * If the insert was at the end of buffer, set lp1 to the end of * buffer line, and lp2 to the beginning of the newly inserted text. * (Otherwise lp2 is set to NULL.) This is used below to set * pointers in other windows correctly if they are also at the end of * buffer. */ lp1 = bp->b_headp; if (curwp->w_markp == lp1) { lp2 = curwp->w_dotp; } else { /* delete extraneous newline */ (void)ldelnewline(); out: lp2 = NULL; } for (wp = wheadp; wp != NULL; wp = wp->w_wndp) { if (wp->w_bufp == curbp) { wp->w_flag |= WFMODE | WFEDIT; if (wp != curwp && lp2 != NULL) { if (wp->w_dotp == lp1) wp->w_dotp = lp2; if (wp->w_markp == lp1) wp->w_markp = lp2; if (wp->w_linep == lp1) wp->w_linep = lp2; } } } bp->b_lines += nline; cleanup: undo_enable(FFRAND, x); /* return FALSE if error */ return (s != FIOERR); }
/* ARGSUSED */ int fillpara(int f, int n) { int c; /* current char during scan */ int wordlen; /* length of current word */ int clength; /* position on line during fill */ int i; /* index during word copy */ int eopflag; /* Are we at the End-Of-Paragraph? */ int firstflag; /* first word? (needs no space) */ int newlength; /* tentative new line length */ int eolflag; /* was at end of line */ int retval; /* return value */ struct line *eopline; /* pointer to line just past EOP */ char wbuf[MAXWORD]; /* buffer for current word */ if (n == 0) return (TRUE); undo_boundary_enable(FFRAND, 0); /* record the pointer to the line just past the EOP */ (void)gotoeop(FFRAND, 1); if (curwp->w_doto != 0) { /* paragraph ends at end of buffer */ (void)lnewline(); eopline = lforw(curwp->w_dotp); } else eopline = curwp->w_dotp; /* and back top the beginning of the paragraph */ (void)gotobop(FFRAND, 1); /* initialize various info */ while (inword() == 0 && forwchar(FFRAND, 1)); clength = curwp->w_doto; wordlen = 0; /* scan through lines, filling words */ firstflag = TRUE; eopflag = FALSE; while (!eopflag) { /* get the next character in the paragraph */ if ((eolflag = (curwp->w_doto == llength(curwp->w_dotp)))) { c = ' '; if (lforw(curwp->w_dotp) == eopline) eopflag = TRUE; } else c = lgetc(curwp->w_dotp, curwp->w_doto); /* and then delete it */ if (ldelete((RSIZE) 1, KNONE) == FALSE && !eopflag) { retval = FALSE; goto cleanup; } /* if not a separator, just add it in */ if (c != ' ' && c != '\t') { if (wordlen < MAXWORD - 1) wbuf[wordlen++] = c; else { /* * You lose chars beyond MAXWORD if the word * is too long. I'm too lazy to fix it now; it * just silently truncated the word before, * so I get to feel smug. */ ewprintf("Word too long!"); } } else if (wordlen) { /* calculate tentative new length with word added */ newlength = clength + 1 + wordlen; /* * if at end of line or at doublespace and previous * character was one of '.','?','!' doublespace here. * behave the same way if a ')' is preceded by a * [.?!] and followed by a doublespace. */ if (dblspace && (!eopflag && ((eolflag || curwp->w_doto == llength(curwp->w_dotp) || (c = lgetc(curwp->w_dotp, curwp->w_doto)) == ' ' || c == '\t') && (ISEOSP(wbuf[wordlen - 1]) || (wbuf[wordlen - 1] == ')' && wordlen >= 2 && ISEOSP(wbuf[wordlen - 2])))) && wordlen < MAXWORD - 1)) wbuf[wordlen++] = ' '; /* at a word break with a word waiting */ if (newlength <= fillcol) { /* add word to current line */ if (!firstflag) { (void)linsert(1, ' '); ++clength; } firstflag = FALSE; } else { if (curwp->w_doto > 0 && lgetc(curwp->w_dotp, curwp->w_doto - 1) == ' ') { curwp->w_doto -= 1; (void)ldelete((RSIZE) 1, KNONE); } /* start a new line */ (void)lnewline(); clength = 0; } /* and add the word in in either case */ for (i = 0; i < wordlen; i++) { (void)linsert(1, wbuf[i]); ++clength; } wordlen = 0; } } /* and add a last newline for the end of our new paragraph */ (void)lnewline(); /* * We really should wind up where we started, (which is hard to keep * track of) but I think the end of the last line is better than the * beginning of the blank line. */ (void)backchar(FFRAND, 1); retval = TRUE; cleanup: undo_boundary_enable(FFRAND, 1); return (retval); }
lref_t ldebug_write(lref_t form) { debug_print_object(form, CURRENT_DEBUG_PORT(), true); return lnewline(CURRENT_DEBUG_PORT()); }
/* * Fill the current paragraph according to the current fill column. */ int fillpara (int f, int n, int k) { register int c; /* current char durring scan */ register int wordlen; /* length of current word */ register int clength; /* position on line during fill */ register int eopflag; /* Are we at the End-Of-Paragraph? */ int firstflag; /* first word? (needs no space) */ int newlength; /* tentative new line length */ int eolflag; /* was at end of line */ LINE *eopline; /* pointer to line just past EOP */ char wbuf[MAXWORD]; /* buffer for current word */ /* Record the pointer to the line just past the * end of the paragraph. */ gotoeop (FALSE, 1, KRANDOM); eopline = curwp->w_dot.p; if (lforw (eopline) == curbp->b_linep) eopline = curbp->b_linep; /* Move to the begining of the paragraph. */ gotobop (FALSE, 1, KRANDOM); /* Skip to the start of the first word in the paragraph, * and set our current column position. */ while (!inword ()) if (forwchar (FALSE, 1, KRANDOM) == FALSE) break; clength = getcolpos () - 1; wordlen = 0; /* scan through lines, filling words */ firstflag = TRUE; eopflag = FALSE; while (!eopflag) { /* get the next character in the paragraph */ if ((eolflag = (curwp->w_dot.o == llength (curwp->w_dot.p))) == TRUE) { c = ' '; if (lforw (curwp->w_dot.p) == eopline) eopflag = TRUE; } else c = lgetc (curwp->w_dot.p, curwp->w_dot.o); /* and then delete it */ if (ldelete (1, FALSE) == FALSE) return (FALSE); /* if not a separator, just add it in */ if (c != ' ' && c != '\t') { if (wordlen < MAXWORD - 1) wbuf[wordlen++] = c; else { /* You lose chars beyond MAXWORD if the word * is to long. I'm to lazy to fix it now; it * just silently truncated the word before, so * I get to feel smug. */ eprintf ("Word too long!"); } } else if (wordlen) { /* calculate tenatitive new length with word added */ newlength = clength + 1 + wordlen; /* if at end of line or at doublespace and previous * character was one of '.','?','!' doublespace here. */ if ((eolflag || curwp->w_dot.o == llength (curwp->w_dot.p) || (c = lgetc (curwp->w_dot.p, curwp->w_dot.o)) == ' ' || c == '\t') && ISEOSP (wbuf[wordlen - 1]) && wordlen < MAXWORD - 1) wbuf[wordlen++] = ' '; /* at a word break with a word waiting */ if (newlength <= fillcol) { /* add word to current line */ if (!firstflag) { linsert (1, ' ', NULLPTR); ++clength; } firstflag = FALSE; } else { if (curwp->w_dot.o > 0 && lgetc (curwp->w_dot.p, curwp->w_dot.o - 1) == ' ') { curwp->w_dot.o -= 1; ldelete (1, FALSE); } /* start a new line */ lnewline (); clength = 0; } /* and add the word in in either case */ linsert (wordlen, 0, wbuf); clength += wordlen; wordlen = 0; } } /* and add a last newline for the end of our new paragraph */ lnewline (); /* we realy should wind up where we started, (which is hard to keep * track of) but I think the end of the last line is better than the * begining of the blank line. */ backchar (FALSE, 1, KRANDOM); return (TRUE); }
/* * Insert a character. While defining a macro, create a "LINE" containing * all inserted characters. */ int selfinsert(int f, int n) { struct line *lp; int c; int count; if (n < 0) return (FALSE); if (n == 0) return (TRUE); c = key.k_chars[key.k_count - 1]; if (macrodef && macrocount < MAXMACRO) { if (f & FFARG) macrocount -= 2; /* last command was insert -- tack on the end */ if (lastflag & CFINS) { macrocount--; /* Ensure the line can handle the new characters */ if (maclcur->l_size < maclcur->l_used + n) { if (lrealloc(maclcur, maclcur->l_used + n) == FALSE) return (FALSE); } maclcur->l_used += n; /* Copy in the new data */ for (count = maclcur->l_used - n; count < maclcur->l_used; count++) maclcur->l_text[count] = c; } else { macro[macrocount - 1].m_funct = insert; if ((lp = lalloc(n)) == NULL) return (FALSE); lp->l_bp = maclcur; lp->l_fp = maclcur->l_fp; maclcur->l_fp = lp; maclcur = lp; for (count = 0; count < n; count++) lp->l_text[count] = c; } thisflag |= CFINS; } if (c == '\n') { do { count = lnewline(); } while (--n && count == TRUE); return (count); } /* overwrite mode */ if (curbp->b_flag & BFOVERWRITE) { lchange(WFEDIT); while (curwp->w_doto < llength(curwp->w_dotp) && n--) lputc(curwp->w_dotp, curwp->w_doto++, c); if (n <= 0) return (TRUE); } return (linsert(n, c)); }
/* * Set a variable. * * @var: variable to set. * @value: value to set to. */ int svar(struct variable_description *var, char *value) { int vnum; /* ordinal number of var refrenced */ int vtype; /* type of variable to set */ int status; /* status return */ int c; /* translated character */ char *sp; /* scratch string pointer */ /* simplify the vd structure (we are gonna look at it a lot) */ vnum = var->v_num; vtype = var->v_type; /* and set the appropriate value */ status = TRUE; switch (vtype) { case TKVAR: /* set a user variable */ if (uv[vnum].u_value != NULL) free(uv[vnum].u_value); sp = malloc(strlen(value) + 1); if (sp == NULL) return FALSE; strcpy(sp, value); uv[vnum].u_value = sp; break; case TKENV: /* set an environment variable */ status = TRUE; /* by default */ switch (vnum) { case EVFILLCOL: fillcol = atoi(value); break; case EVPAGELEN: status = newsize(TRUE, atoi(value)); break; case EVCURCOL: status = setccol(atoi(value)); break; case EVCURLINE: status = gotoline(TRUE, atoi(value)); break; case EVRAM: break; case EVFLICKER: flickcode = stol(value); break; case EVCURWIDTH: status = newwidth(TRUE, atoi(value)); break; case EVCBUFNAME: strcpy(curbp->b_bname, value); curwp->w_flag |= WFMODE; break; case EVCFNAME: strcpy(curbp->b_fname, value); curwp->w_flag |= WFMODE; break; case EVSRES: status = TTrez(value); break; case EVDEBUG: macbug = stol(value); break; case EVSTATUS: cmdstatus = stol(value); break; case EVASAVE: gasave = atoi(value); break; case EVACOUNT: gacount = atoi(value); break; case EVLASTKEY: lastkey = atoi(value); break; case EVCURCHAR: ldelchar(1, FALSE); /* delete 1 char */ c = atoi(value); if (c == '\n') lnewline(); else linsert(1, c); backchar(FALSE, 1); break; case EVDISCMD: discmd = stol(value); break; case EVVERSION: break; case EVPROGNAME: break; case EVSEED: seed = atoi(value); break; case EVDISINP: disinp = stol(value); break; case EVWLINE: status = resize(TRUE, atoi(value)); break; case EVCWLINE: status = forwline(TRUE, atoi(value) - getwpos()); break; case EVTARGET: curgoal = atoi(value); thisflag = saveflag; break; case EVSEARCH: strcpy(pat, value); rvstrcpy(tap, pat); #if MAGIC mcclear(); #endif break; case EVREPLACE: strcpy(rpat, value); break; case EVMATCH: break; case EVKILL: break; case EVCMODE: curbp->b_mode = atoi(value); curwp->w_flag |= WFMODE; break; case EVGMODE: gmode = atoi(value); break; case EVTPAUSE: term.t_pause = atoi(value); break; case EVPENDING: break; case EVLWIDTH: break; case EVLINE: putctext(value); case EVGFLAGS: gflags = atoi(value); break; case EVRVAL: break; case EVTAB: tabmask = atoi(value) - 1; if (tabmask != 0x07 && tabmask != 0x03) tabmask = 0x07; curwp->w_flag |= WFHARD; break; case EVOVERLAP: overlap = atoi(value); break; case EVSCROLLCOUNT: scrollcount = atoi(value); break; case EVSCROLL: #if SCROLLCODE if (!stol(value)) term.t_scroll = NULL; #endif break; } break; } return status; }