home *** CD-ROM | disk | FTP | other *** search
- /**
- *
- * Name wnwrap -- Write a string of characters to the current
- * window, TTY-style, with word wrap.
- *
- * Synopsis wnwrap(num_spaces,buffer,fore,back,option);
- *
- * int num_spaces Number of characters to write.
- * If CHARS_ONLY is specified (see "option"
- * below), num_spaces == 0 indicates that
- * the buffer is terminated by a NUL ('\0')
- * character.
- * char *buffer Data to write
- * int fore -1 if window's native foreground
- * attribute is to be used; if CHARS_ONLY
- * is specified, a value between 0 and 15
- * specifies a new foreground attribute.
- * int back -1 if window's native background
- * attribute is to be used; if CHARS_ONLY
- * is specified, a value between 0 and 15
- * specifies a new background attribute.
- * int option One bit in the option value tells WNWRAP
- * how the buffer is constructed. The two
- * possible values are:
- *
- * Value Meaning
- * ----------- ------------------------------------
- * CHARS_ONLY Buffer contains characters only.
- * If num_spaces is zero, the string
- * is terminated by a NUL ('\0')
- * character.
- * The values of fore and back are used
- * as attributes.
- * CHAR_ATTR Buffer contains (char,attr) pairs.
- * The values of fore and back are
- * ignored.
- *
- * Description This function writes characters to the current window
- * without splitting words between rows of the window.
- *
- * The window's cursor is left after the end of the
- * displayed string. The visible cursor is not moved
- * unless this window is currently selected (via WNCURSOR)
- * to have this page's active cursor.
- *
- * The num_spaces argument specifies the number of actual
- * characters to use from the buffer. (If CHAR_ATTR is
- * specified, twice this number of bytes will be used from
- * the buffer.) If num_spaces is 0 and CHARS_ONLY is used,
- * then characters will be used from the buffer up to (but
- * not including) the first NUL ('\0') encountered. No
- * more than 32767 bytes should be used from the buffer.
- *
- * A "word" is defined to be a sequence of non-whitespace
- * characters that is bounded by whitespace characters or
- * by the beginning or end of the buffer. "Whitespace"
- * characters are blank (' '), tab ('\t'), bell ('\7'),
- * backspace ('\b'), line feed ('\012'), and carriage
- * return ('\15'). Words are split between rows of the
- * window only if they are longer than the width of the
- * window. If a word is too long to fit on the current row
- * without splitting, then it is written on the next row of
- * the window, scrolling the window if necessary.
- *
- * Multiple blanks are written literally up to the end of
- * the current row. They are given the attributes
- * specified by fore and back as usual. No blanks are
- * written at the beginning of a row. When blanks are
- * added to avoid splitting a word, they are given the
- * window's native attributes.
- *
- * The window is scrolled if a line feed occurs on the last
- * row or if the last row is overflowed. The window's
- * native attributes are used for the new blank row.
- *
- * If the screen is in a text mode, specifying -1 for fore
- * or back uses the window's default foreground or background
- * attributes, respectively. This will occur regardless of
- * the value of option.
- *
- * Special Tab characters ('\t') are regarded as single blank
- * characters characters.
- *
- * DEL characters ('\177') are written to the screen as
- * blanks. However, they are treated as nonblanks in that
- * nonblank characters joined by DEL characters will not be
- * split when whole words are wrapped. The character value
- * written to the screen is 0x20.
- *
- * NUL ('\0') is a printable nonblank character (displayed
- * as a blank space), not necessarily the end of the
- * string. It is only regarded as the end of the string if
- * num_spaces is 0 and CHARS_ONLY is specified. Otherwise
- * it is treated the same as DEL, except that the character
- * value written to the screen is 0.
- *
- * Line feed ('\12') causes the cursor to move down one
- * row, unless it is already on the bottom row of the
- * window, in which case the window is scrolled.
- *
- * Carriage return ('\r') causes the cursor to move to the
- * leftmost column of the window.
- *
- * Backspace ('\b') causes the cursor to move one column to
- * the left (non-destructively), unless it is already at
- * the leftmost column of the window, in which case nothing
- * happens.
- *
- * The BEL character ('\7') causes the computer's bell to
- * sound if the current page is active.
- *
- * Returns (Function return type is void.)
- * _wnerr Possible values:
- * (No change) Success.
- * WN_BAD_WIN No window designated
- * as current.
- * WN_ILL_DIM Internal error.
- *
- * Version 3.0 (C)Copyright Blaise Computing Inc. 1986
- *
- **/
-
- #include <string.h>
-
- #include <bwindow.h>
-
- /* Macro inc_ptr steps a pointer through the character buffer, */
- /* returning the new pointer value. */
-
- #define inc_ptr(ptr) (want_attr ? (ptr += 2) : ++ptr)
-
- /* Macro str_len measures the distance between two locations in */
- /* the character buffer. */
-
- #define str_len(from,to) ((to - from) >> (want_attr ? 1 : 0))
-
- #define BEL '\7'
- #define BS '\b'
- #define TAB '\t'
- #define CR '\r'
- #define LF '\12'
- #define DEL '\177'
-
- void wnwrap(num_spaces,buffer,fore,back,option)
- int num_spaces;
- char *buffer;
- int fore,back,option;
- {
- char ch;
- char *pendstr;
- int nbytes,nonblank_len;
- int w,row,col,i;
- int want_attr;
-
- if (wnvalwin(b_pcurwin) == NIL)
- {
- wnerror(WN_BAD_WIN);
- return;
- }
-
- w = b_pcurwin->img.dim.w;
-
- want_attr = ((option & CHAR_ATTR) != 0);
- if ((!want_attr) && num_spaces == 0)
- num_spaces = (int) strlen(buffer);
-
- while (num_spaces > 0)
- {
- wncurpos(&row,&col);
- switch (ch = *buffer)
- {
- case TAB:
- ch = ' '; /* Treat TAB as a blank. */
- case ' ':
- case CR: /* WNWRTTY handles both */
- case LF: /* ordinary and special */
- case BEL: /* characters. */
- case BS:
- if (ch != ' ' || col > 0) /* Write a blank only if */
- /* this isn't the beginning*/
- /* of the row. */
- wnwrtty(ch,
- want_attr ? (int) utlonyb(*(buffer+1)) : fore,
- want_attr ? (int) uthinyb(*(buffer+1)) : back);
- num_spaces--;
- inc_ptr(buffer);
- break;
-
- default: /* This is the beginning of a string of */
- /* one or more nonblanks. */
-
- /* First measure the length of the */
- /* string of nonblanks. */
- nbytes = (want_attr ? (num_spaces << 2) : num_spaces);
- pendstr = buffer;
- while (pendstr < buffer + nbytes)
- if ((ch = *inc_ptr(pendstr)) == ' '
- || ch == CR
- || ch == LF
- || ch == TAB
- || ch == BEL
- || ch == BS)
- break;
- nonblank_len = str_len(buffer,pendstr);
-
- /* If this string won't fit on this row,*/
- if (col + nonblank_len > w
-
- /* and the string is small enough to */
- /* fit on a new row, */
- && nonblank_len <= w
-
- /* and this isn't already a fresh row, */
- && col > 0)
-
- /* Then fill the rest of the row with */
- /* blanks and let WNWRTTY advance us to */
- /* the next row. */
- while (col++ < w)
- wnwrtty((char) ' ',-1,-1);
-
- /* Write the string itself. If the */
- /* the string is longer than the window */
- /* is wide, then it will be split, but */
- /* at least we tried. */
- for (i = nonblank_len; i; i--)
- {
- if ((ch = *buffer++) == DEL)
- ch = ' '; /* Print DEL as a blank */
- wnwrtty(ch,
- want_attr ? (int) utlonyb(*buffer) : fore,
- want_attr ? (int) uthinyb(*buffer) : back);
- if (want_attr)
- buffer++;
- }
- num_spaces -= nonblank_len;
-
- break;
- }
- }
- }