home *** CD-ROM | disk | FTP | other *** search
- /**
- *
- * Name EDBUFFER -- Perform one set of edit actions on an edit
- * buffer.
- *
- * Synopsis result = edbuffer(pedit_buffer, pedit_key)
- *
- * ED_ACTION result The action code of the last
- * action performed on the
- * buffer.
- * ED_BUFFER *pedit_buffer The edit buffer. This record
- * structure contains the text
- * buffer which is altered, as
- * well as the current buffer
- * position, text attributes and
- * edit mode (insert or replace).
- * const ED_KEY *pedit_key This structure specifies which
- * actions to take, their order,
- * and in the case of ED_ASCII,
- * which character to place in the
- * buffer.
- *
- * Description EDBUFFER edits a buffer based upon the action specified
- * in the action field of the EDIT_KEY structure. No
- * input or output is performed; all editing is confined to
- * the buffer itself. It is up to the calling routine to
- * output and use the altered buffer. The function
- * EDBASE uses EDBUFFER to edit a screen input buffer.
- *
- * The return value represents the last edit action
- * performed on the buffer. Usually, this is the last
- * action in the edit key's action list; however if
- * ED_ABORT, ED_TRANSMIT, ED_ATTR, or ED_UNDO is
- * encountered, the remaining edit actions (if any) are
- * ignored and EDBUFFER returns the appropriate action code
- * immediately. If the edit key has no edit actions
- * associated with it, the return value is ED_NULL.
- *
- * The edit action codes and the effects are as follows:
- *
- * Action Code Description
- * ------------- ------------------------------------------
- * ED_NULL No action taken.
- * ED_ABORT No action taken.
- * ED_BEEP Sound the system speaker.
- * ED_ATTR Set the current buffer text attribute.
- * ED_ASCII Place the character code in the edit
- * buffer at the current buffer position.
- * If in replace mode, the current character
- * is overwritten; in insert mode, characters
- * beginning at the current position are
- * moved to the right before the character is
- * placed in the buffer. In insert mode,
- * the character at the right end of the buf-
- * fer is lost. The current buffer position
- * is incremented if not already at the end
- * of the buffer. Finally, if the new cursor
- * position extends the length of the of the
- * active edit area, the length is incre-
- * mented.
- * ED_LEFT The buffer position is decremented if not
- * already at the leftmost position.
- * ED_RIGHT The buffer position is incremented if not
- * already at the rightmost position.
- * ED_UP The buffer position is decremented by the
- * width of the displayed field (one line) if
- * it is greater than the width of the field.
- * Effectively, it is moved "up" one line if
- * it is not already on the first line.
- * ED_DOWN The buffer position is incremented by the
- * width of the displayed field (one line) if
- * it is less than the buffer length minus
- * the width of the field. Effectively, it is
- * moved "down" one line if it is not already
- * on the first line, and if the column of
- * the buffer end is not less than the
- * current column.
- * ED_FRONT The buffer position is set to 0 (the
- * leftmost position).
- * ED_END The buffer position is set to the end of
- * the active edit area (data_end). Note
- * that this need not be the end of the buf-
- * fer (buffer_len - 1).
- * ED_TEXT_END The buffer position is set to the last
- * non-whitespace character in the buffer.
- * If the buffer contains only whitespace,
- * the buffer position is not altered.
- * ED_WRAP Perform word wrap on the buffer. A word
- * is considered to be one or more non white-
- * space characters surrounded by whitespace.
- * words are moved so that they do not break
- * across line boundaries.
- * ED_REDUCE Reduce whitespace. All runs of one or
- * more consecutive whitespace characters
- * will be reduced to a single blank.
- * ED_NEXT_WORD Move to next word.
- * ED_PREV_WORD Move to previous word.
- * ED_BEGIN_WORD Move to start of word.
- * ED_END_WORD Move to end of word.
- * ED_NEXT_WHITE Move to next whitespace character.
- * ED_PREV_WHITE Move to previous whitespace character.
- * ED_NEXT_NONWHITE
- * Move to next nonwhitespace character.
- * ED_PREV_NONWHITE
- * Move to previous nonwhitespace character.
- * ED_DELETE The character at the current position is
- * removed from the buffer, and all charac-
- * ters to the right are moved to the left.
- * The right most character of the buffer is
- * set to ' '. If the end of the active edit
- * area is to the right of the buffer
- * position, it is decremented.
- * ED_RUBOUT This is just like ED_DELETE, except that
- * the buffer position is first moved to the
- * left if possible (cursor_pos > 0).
- * ED_DELLEFT This is just like ED_RUBOUT, except that
- * no action is taken if the curent edit
- * position is 0.
- * ED_CLEAR The edit buffer is set to blanks, and both
- * the buffer position and end of active area
- * are set to 0.
- * ED_CLEAREOL The buffer from the current position and
- * to the end of the current line is set to
- * blanks. The current position is not
- * altered. If the end of the active edit
- * area is to the right of the current
- * position on the same line, the end of the
- * active area is set to the current
- * position.
- * ED_CLEAREOB The buffer from the current position to
- * the end of the buffer is set to blanks.
- * The current position is not altered, but
- * if the current position is to the left of
- * the end of the active area, the active
- * area end is set equal to the buffer
- * position.
- * ED_INS Insert mode is set (insert is 1).
- * ED_REPLACE Insert mode is set to 0.
- * ED_INS_TOGGLE Insert mode is toggled.
- * ED_UNDO No action taken.
- * ED_TRANSMIT No action taken.
- *
- * Returns int result The action code of the last edit action
- * performed on the buffer. Actions
- * ED_ABORT, ED_TRANSMIT, ED_ATTR, and
- * ED_UNDO cause immediate return, with any
- * remaining actions ignored. If the edit
- * key has no actions, ED_NULL is returned.
- *
- * Version 6.00 (C)Copyright Blaise Computing Inc. 1989
- *
- **/
- #include <bedit.h>
-
-
- typedef struct
- {
- ED_ACTION action;
- unsigned reduce : 1;
- unsigned wrap : 1;
- unsigned reserved : 14;
- } WRAP_ACTION;
- /* The array wrap_actions specifies which edit */
- /* actions, when word wrap is specified, require */
- /* the buffer to have whitespace reduced prior to */
- /* execution, and/or that the buffer be word */
- /* wrapped after execution. */
- static WRAP_ACTION wrap_actions[] =
- {
- {ED_ASCII, 1, 1},
- {ED_LEFT, 1, 1},
- {ED_RIGHT, 1, 1},
- {ED_NEXT_WHITE, 1, 1},
- {ED_PREV_WHITE, 1, 1},
- {ED_DELETE, 1, 1},
- {ED_RUBOUT, 1, 1},
- {ED_DELLEFT, 1, 1},
- {ED_DEL_WORD, 1, 1},
- {ED_CLEAREOL, 1, 1},
- };
-
-
- ED_ACTION edbuffer(pedit_buffer, pedit_key)
- ED_BUFFER *pedit_buffer;
- const ED_KEY *pedit_key;
- {
- int buffer_length;
- int current_action;
- int new_cursor_pos;
- int num_chars_deleted;
- int found, index;
- int line_end;
-
- if (pedit_key->edit_actions.num_actions <= 0)
- return(ED_NULL);
-
- buffer_length = pedit_buffer->buffer_size;
-
- for (current_action = 0;
- current_action < pedit_key->edit_actions.num_actions;
- current_action++)
- {
-
- if (pedit_buffer->control_flags & ED_WORD_WRAP)
- {
- found = 0;
- for (index = 0;
- index < sizeof(wrap_actions) / sizeof(wrap_actions[0]);
- index++)
- {
- if (pedit_key->edit_actions.pactions[current_action] ==
- wrap_actions[index].action)
- {
- found = 1;
- break;
- }
- }
- if (found && wrap_actions[index].reduce)
- edreduce(pedit_buffer);
-
- }
-
- switch(pedit_key->edit_actions.pactions[current_action])
- {
- case ED_NULL:
- break;
-
- case ED_ABORT:
- return(ED_ABORT);
-
- case ED_BEEP:
- scttywrt('\a', 0);
- break;
-
- case ED_ATTR:
- pedit_buffer->attribute = pedit_key->attribute;
- return(ED_ATTR);
-
- case ED_ASCII:
- if (pedit_buffer->control_flags & ED_INSERT_MODE)
- memmove(&pedit_buffer->pbuffer[pedit_buffer->cursor_pos + 1],
- &pedit_buffer->pbuffer[pedit_buffer->cursor_pos],
- buffer_length - pedit_buffer->cursor_pos - 1);
-
- pedit_buffer->pbuffer[pedit_buffer->cursor_pos] =
- pedit_key->key_sequence.character_code;
-
- if (pedit_buffer->cursor_pos == (buffer_length - 1))
- pedit_buffer->data_end = buffer_length;
-
- if (pedit_buffer->cursor_pos < (buffer_length - 1))
- pedit_buffer->cursor_pos++;
-
- if (pedit_buffer->cursor_pos > pedit_buffer->data_end)
- pedit_buffer->data_end = pedit_buffer->cursor_pos;
- else
- if ((pedit_buffer->control_flags & ED_INSERT_MODE) &&
- (pedit_buffer->data_end < buffer_length))
- {
- pedit_buffer->data_end++;
- }
-
- /* Since the character could have been past the end */
- /* of the existing data, we may need to reduce the */
- /* buffer again. */
- if (pedit_buffer->control_flags & ED_WORD_WRAP)
- edreduce(pedit_buffer);
- break;
-
- case ED_LEFT:
- if (pedit_buffer->cursor_pos > 0)
- pedit_buffer->cursor_pos--;
- break;
-
- case ED_RIGHT:
- if (pedit_buffer->cursor_pos < (buffer_length - 1))
- pedit_buffer->cursor_pos++;
- break;
-
- case ED_UP:
- if (pedit_buffer->cursor_pos -
- (pedit_buffer->dimensions.w - 1) > 0)
- {
- pedit_buffer->cursor_pos -=
- pedit_buffer->dimensions.w;
- }
- if (pedit_buffer->control_flags & ED_WORD_WRAP)
- {
- edreduce(pedit_buffer);
- edwrap(pedit_buffer);
- }
- break;
-
- case ED_DOWN:
- if ((pedit_buffer->cursor_pos +
- (pedit_buffer->dimensions.w - 1)) < (buffer_length - 1))
- {
- pedit_buffer->cursor_pos +=
- pedit_buffer->dimensions.w;
- }
- if (pedit_buffer->control_flags & ED_WORD_WRAP)
- {
- edreduce(pedit_buffer);
- edwrap(pedit_buffer);
- }
- break;
-
- case ED_FRONT:
- pedit_buffer->cursor_pos = 0;
- break;
-
- case ED_END:
- if (pedit_buffer->data_end < buffer_length)
- pedit_buffer->cursor_pos = pedit_buffer->data_end;
- else
- pedit_buffer->cursor_pos = pedit_buffer->data_end - 1;
- break;
-
- case ED_TEXT_END:
- for (new_cursor_pos = buffer_length - 1;
- (new_cursor_pos > 0) &&
- (isspace(pedit_buffer->pbuffer[new_cursor_pos]));
- new_cursor_pos--)
- ;
- if (!isspace(pedit_buffer->pbuffer[new_cursor_pos]))
- pedit_buffer->cursor_pos = new_cursor_pos;
- break;
-
- case ED_WRAP:
- edwrap(pedit_buffer);
- break;
-
- case ED_REDUCE:
- edreduce(pedit_buffer);
- break;
-
- case ED_NEXT_WORD:
- if (!isspace(pedit_buffer->pbuffer[pedit_buffer->cursor_pos]))
- {
- for (new_cursor_pos = pedit_buffer->cursor_pos;
- (new_cursor_pos < pedit_buffer->data_end) &&
- (new_cursor_pos < (buffer_length - 1)) &&
- (!isspace(pedit_buffer->pbuffer[new_cursor_pos]));
- new_cursor_pos++)
- ;
- pedit_buffer->cursor_pos = new_cursor_pos;
- }
-
- for (new_cursor_pos = pedit_buffer->cursor_pos;
- (new_cursor_pos < pedit_buffer->data_end) &&
- (new_cursor_pos < (buffer_length - 1)) &&
- (isspace(pedit_buffer->pbuffer[new_cursor_pos]));
- new_cursor_pos++)
- ;
- pedit_buffer->cursor_pos = new_cursor_pos;
-
- break;
-
- case ED_PREV_WORD:
- if (!isspace(pedit_buffer->pbuffer[pedit_buffer->cursor_pos]))
- {
- for (new_cursor_pos = pedit_buffer->cursor_pos;
- (new_cursor_pos > 0) &&
- (!isspace(pedit_buffer->pbuffer[new_cursor_pos]));
- new_cursor_pos--)
- ;
- pedit_buffer->cursor_pos = new_cursor_pos;
- }
-
- for (new_cursor_pos = pedit_buffer->cursor_pos;
- (new_cursor_pos > 0) &&
- (isspace(pedit_buffer->pbuffer[new_cursor_pos]));
- new_cursor_pos--)
- ;
- pedit_buffer->cursor_pos = new_cursor_pos;
-
- for (new_cursor_pos = pedit_buffer->cursor_pos;
- (new_cursor_pos > 0) &&
- (!isspace(pedit_buffer->pbuffer[new_cursor_pos]));
- new_cursor_pos--)
- ;
-
- if (new_cursor_pos != 0)
- new_cursor_pos++;
- pedit_buffer->cursor_pos = new_cursor_pos;
-
- break;
-
- case ED_BEGIN_WORD:
- if (!isspace(pedit_buffer->pbuffer[pedit_buffer->cursor_pos]))
- {
- for (new_cursor_pos = pedit_buffer->cursor_pos;
- (new_cursor_pos > 0) &&
- (!isspace(pedit_buffer->pbuffer[new_cursor_pos - 1]));
- new_cursor_pos--)
- ;
- pedit_buffer->cursor_pos = new_cursor_pos;
- }
-
- break;
-
- case ED_END_WORD:
- if (!isspace(pedit_buffer->pbuffer[pedit_buffer->cursor_pos]))
- {
- for (new_cursor_pos = pedit_buffer->cursor_pos;
- (new_cursor_pos < pedit_buffer->data_end) &&
- (new_cursor_pos < (buffer_length - 1)) &&
- (!isspace(pedit_buffer->pbuffer[new_cursor_pos + 1]));
- new_cursor_pos++)
- ;
- pedit_buffer->cursor_pos = new_cursor_pos;
- }
- break;
-
- case ED_NEXT_WHITE:
- new_cursor_pos = pedit_buffer->cursor_pos + 1;
- if ((new_cursor_pos < pedit_buffer->data_end) &&
- (new_cursor_pos < buffer_length))
- {
- for (;
- (new_cursor_pos < pedit_buffer->data_end) &&
- (new_cursor_pos < buffer_length) &&
- (!isspace(pedit_buffer->pbuffer[new_cursor_pos]));
- new_cursor_pos++)
- ;
- if ((new_cursor_pos < pedit_buffer->data_end) &&
- (new_cursor_pos < buffer_length) &&
- (isspace(pedit_buffer->pbuffer[new_cursor_pos])))
- {
- pedit_buffer->cursor_pos = new_cursor_pos;
- }
- }
- break;
-
- case ED_PREV_WHITE:
- if (pedit_buffer->cursor_pos > 0)
- {
- for (new_cursor_pos = pedit_buffer->cursor_pos - 1;
- (new_cursor_pos > 0) &&
- (!isspace(pedit_buffer->pbuffer[new_cursor_pos]));
- new_cursor_pos--)
- ;
- if (isspace(pedit_buffer->pbuffer[new_cursor_pos]))
- pedit_buffer->cursor_pos = new_cursor_pos;
- }
- break;
-
- case ED_NEXT_NONWHITE:
- new_cursor_pos = pedit_buffer->cursor_pos + 1;
- if ((new_cursor_pos < pedit_buffer->data_end) &&
- (new_cursor_pos < buffer_length))
- {
- for (;
- (new_cursor_pos < pedit_buffer->data_end) &&
- (new_cursor_pos < buffer_length) &&
- (isspace(pedit_buffer->pbuffer[new_cursor_pos]));
- new_cursor_pos++)
- ;
- if ((new_cursor_pos < pedit_buffer->data_end) &&
- (new_cursor_pos < buffer_length) &&
- (!isspace(pedit_buffer->pbuffer[new_cursor_pos])))
- {
- pedit_buffer->cursor_pos = new_cursor_pos;
- }
- }
- break;
-
- case ED_PREV_NONWHITE:
- if (pedit_buffer->cursor_pos > 0)
- {
- for (new_cursor_pos = pedit_buffer->cursor_pos - 1;
- (new_cursor_pos > 0) &&
- (isspace(pedit_buffer->pbuffer[new_cursor_pos]));
- new_cursor_pos--)
- ;
- if (!isspace(pedit_buffer->pbuffer[new_cursor_pos]))
- pedit_buffer->cursor_pos = new_cursor_pos;
- }
- break;
-
- case ED_DELLEFT: /* Delete left if not at start of line. */
- if (pedit_buffer->cursor_pos == 0)
- break;
- case ED_RUBOUT: /* Move left if possible & delete char. */
- if (pedit_buffer->cursor_pos > 0)
- pedit_buffer->cursor_pos--;
- case ED_DELETE: /* Delete char under cursor. */
- if (pedit_buffer->cursor_pos < (buffer_length - 1))
- {
- memmove(&pedit_buffer->pbuffer[pedit_buffer->cursor_pos],
- &pedit_buffer->pbuffer[pedit_buffer->cursor_pos + 1],
- buffer_length - pedit_buffer->cursor_pos - 1);
- if (pedit_buffer->cursor_pos < pedit_buffer->data_end)
- pedit_buffer->data_end--;
- }
- pedit_buffer->pbuffer[buffer_length - 1] = ' ';
- break;
-
- case ED_DEL_WORD:
- /* Find the start of the next word. */
- if (!isspace(pedit_buffer->pbuffer[pedit_buffer->cursor_pos]))
- {
- for (new_cursor_pos = pedit_buffer->cursor_pos;
- (new_cursor_pos < pedit_buffer->data_end) &&
- (new_cursor_pos < buffer_length) &&
- (!isspace(pedit_buffer->pbuffer[new_cursor_pos]));
- new_cursor_pos++)
- ;
- }
- else
- new_cursor_pos = pedit_buffer->cursor_pos;
-
- for (;
- (new_cursor_pos < pedit_buffer->data_end) &&
- (new_cursor_pos < buffer_length) &&
- (isspace(pedit_buffer->pbuffer[new_cursor_pos]));
- new_cursor_pos++)
- ;
-
- /* Now move the buffer left by the required amount. */
- memmove(&pedit_buffer->pbuffer[pedit_buffer->cursor_pos],
- &pedit_buffer->pbuffer[new_cursor_pos],
- buffer_length - new_cursor_pos);
-
- /* Now clear the excess at the end of the buffer and set the new */
- /* buffer end position. */
- num_chars_deleted = new_cursor_pos -
- pedit_buffer->cursor_pos;
- memset(&pedit_buffer->pbuffer[pedit_buffer->data_end -
- num_chars_deleted], ' ', num_chars_deleted);
- pedit_buffer->data_end -= num_chars_deleted;
-
- break;
-
- case ED_CLEAR:
- pedit_buffer->cursor_pos = 0;
- pedit_buffer->data_end = 0;
- memset(pedit_buffer->pbuffer, ' ', buffer_length);
- break;
-
- case ED_CLEAREOL:
- line_end = ((pedit_buffer->cursor_pos /
- pedit_buffer->dimensions.w) + 1) *
- pedit_buffer->dimensions.w - 1;
- memset(&pedit_buffer->pbuffer[pedit_buffer->cursor_pos],
- ' ', line_end - pedit_buffer->cursor_pos + 1);
- if (!utrange(pedit_buffer->data_end,
- pedit_buffer->cursor_pos, line_end))
- pedit_buffer->data_end = pedit_buffer->cursor_pos;
- break;
-
- case ED_CLEAREOB:
- memset(&pedit_buffer->pbuffer[pedit_buffer->cursor_pos],
- ' ', buffer_length - pedit_buffer->cursor_pos + 1);
- if (pedit_buffer->cursor_pos < pedit_buffer->data_end)
- pedit_buffer->data_end = pedit_buffer->cursor_pos;
- break;
-
- case ED_INSERT:
- pedit_buffer->control_flags |= ED_INSERT_MODE;
- break;
-
- case ED_REPLACE:
- pedit_buffer->control_flags &= ~ED_INSERT_MODE;
- break;
-
- case ED_INSTOGGLE:
- if (pedit_buffer->control_flags & ED_INSERT_MODE)
- pedit_buffer->control_flags &= ~ED_INSERT_MODE;
- else
- pedit_buffer->control_flags |= ED_INSERT_MODE;
- break;
-
- case ED_UNDO:
- return(ED_UNDO);
-
- case ED_TRANSMIT:
- return(ED_TRANSMIT);
-
- }
-
- if ((pedit_buffer->control_flags & ED_WORD_WRAP) &&
- found && wrap_actions[index].wrap)
- {
- edwrap(pedit_buffer);
- }
- }
- return(pedit_key->edit_actions.pactions[current_action - 1]);
- }