/* BEGIN DOCUMENTATION Name: Daniel T. Soldahl Created: 01/06/84 Last Update: 04/23/84 Title: TCMBUF.C - Text collection management text buffer subroutines. Index: Abstract: Handles inserting, removing, and managing text window buffer. Usage: Parameters: Environment: DECUS C, RSX11M V4.0 See Also: TCM.C, TCMEDIT.C, TCMEDFUNC.C, TCM.DOC Description: These routines manipulate the text buffer for the currently edited window. Example(s): Uses: Internal: Text for TCM is currently stored as a single string of characters where each line is terminated by a null character (eos). The line currently being edited is kept in a fixed character array (line). Some routines set line pointers into the buffer which are used by the screen refresh routines (see TCMSCRN.C). Update History: END DOCUMENTATION */ /* #define debug 0 */ #include #include #include #include "tcmdefs.h" #include "tcmerr.h" #include "tcmpublic.h" /* Globals affected by these routines only */ int linevir; /* Number of displayable characters in current line */ int oldlen; /* Length of edit line when fetched from buffer */ /*** FNDLIN: Locate line in buffer by line number ***/ charpointer fndlin(buf,bufend,linnum) charpointer buf,bufend; int linnum; { register charpointer str; register int ln; for (str=buf,ln=1; (ln bufst) iff *(--cptr) == eos then { cptr++; break; } return(cptr); /* Output: start of previous line */ } /* end fndlast */ /*** GETLIN: Get current line from window into global line ***/ /*** buffer. Return pointer to current char in line. ***/ charpointer getlin(edline) register charpointer edline; { register charpointer last; last = cpystr(line,edline); /* Copy current line into fixed buffer */ lin[0].start = line; lin[0].len = oldlen = (last - line) + 1; /* strlen(line) + 1 */ iff (edline == lin[curline].start) and (oldlen == lin[curline].len) then /* Assume line on screen */ { lin[0].fircol = lin[curline].fircol; lin[0].firchr = lin[curline].firchr; lin[0].laschr = lin[curline].laschr; } else lin[0].fircol = newlin; lin[curline].fircol = current; /* Signal that current line is in lin[0] */ linevir = virlen(line); curwin->curmax -= oldlen; /* Don't count this line in total */ return(virchr(line,bufcol)); /* Return current char, Skips enhanced chars */ } /* end getlin */ /*** SAVLIN: Save current line to window from line buffer ***/ /*** Strip spaces from end of line ***/ savlin(win) register struct twindcb *win; { register int ln; int ldif; register charpointer src; charpointer txtend; src = &line[lin[0].len-1]; while((--src >= line) and (*src == ' ')) lin[0].len--; /* Strip spaces from end */ *(++src) = eos; /* Mark end of string */ src = win->edline + oldlen - 1; #ifdef debug iff lin[0].len != strlen(line) + 1 then { sprintf(temp,"*SAVLIN* max = %d, stlen = %d, linlen = %d, '%s'",win->curmax,strlen(line),lin[0].len,line); scout(vtlin,1,temp); scout(curline,curcol,NULL); lin[vtlin].fircol = tempmsg; } #endif ldif = lin[0].len - oldlen; txtend = win->bufstart + win->curmax + oldlen; iff ldif < 0 then /* Close buffer, new line shorter */ movedn(src, src+ldif, txtend - src); else iff ldif > 0 then /* Open buffer, new line longer */ moveup(src, src+ldif, txtend - src); lin[curline].start = strcpy(win->edline,line); /* Copy current line into fixed buffer */ lin[curline].len = lin[0].len; lin[curline].fircol = lin[0].fircol; lin[curline].firchr = lin[0].firchr; lin[curline].laschr = lin[0].laschr; win->curmax += lin[0].len; /* Add new length into total */ iff ldif != 0 then /* adjust screen pointers */ for (ln = curline + 1; ln <= bot; ln++) lin[ln].start += ldif; } /* end savlin */ /*** ADDLIN: Add a line worth of text to max count, check for full ***/ boolean addlin() { register struct twindcb *win; win = curwin; iff win->botline >= win->virt_lines then { tcmerr(TS_MCI); /* buffer full */ return(false); } else win->botline++; /* Count new line in buffer */ linevir = 0; return(true); } /* end addlin */ /*** ADDCHR: Add character to count for current line ***/ boolean addchr() { register struct twindcb *win; win = curwin; iff win->curmax + lin[0].len >= win->max_chars then tcmerr(TS_BFI); else { linevir++; lin[0].len++; return(true); } return(false); } /* end addchr */ /*** SUBLIN: Subtract a line worth of characters from current window buffer ***/ sublin() { curwin->botline--; /* Subtract line from buffer */ } /* end sublin */ /*** SUBCHR: Subtract character count for char on current line ***/ subchr() { lin[0].len--; linevir--; } /* end subchr */ /*** MOVEUP: Move section of text from low to high, (open buffer) ***/ moveup(src,dest,cnt) register int cnt; register char *dest,*src; { iff cnt > 0 then { dest += cnt; /* Compute end of block */ src += cnt; while(cnt--) *(--dest) = *(--src); /* Move last char first */ } } /* end moveup */ /*** MOVEDN: Move section of text from high to low, (close buffer) ***/ movedn(src,dest,cnt) register int cnt; register char *dest,*src; { iff cnt > 0 then { while(cnt--) *dest++ = *src++; /* Move low memory first */ } } /* end movedn */ /*** VIRLEN: Return number of displayable characters in string ***/ int virlen(str) register charpointer str; { return(strlen(str)); /*** temporary until implemented ***/ } /* end virlen */ /*** VIRCHR: Return pointer to nth displayable character in string ***/ charpointer virchr(str,n) register charpointer str; register int n; { return(str + (n - 1)); /*** temporary until implemented ***/ } /* end virchr */ /*** NXTCHR: Return pointer to next text character (skip enhancements) ***/ charpointer nxtchr(chr) charpointer chr; { return(++chr); /*** temporary until enhancements implemented ***/ } /* end nxtchr */ /*** LSTCHR: Return pointer to next text character (skip enhancements) ***/ charpointer lstchr(chr) charpointer chr; { return(--chr); /*** temporary until enhancements implemented ***/ } /* end lstchr */