1 /* buffer.c - Text buffering and word wrapping
2 * Copyright (c) 1995-1997 Stefan Jokisch
3 *
4 * This file is part of Frotz.
5 *
6 * Frotz is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * Frotz is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 #include <string.h>
22 #include "frotz.h"
23
24 extern void stream_char (zchar);
25 extern void stream_word (const zchar *);
26 extern void stream_new_line (void);
27
28 static zchar buffer[TEXT_BUFFER_SIZE];
29 static int bufpos = 0;
30
31 static zchar prev_c = 0;
32
33
34 /*
35 * init_buffer
36 *
37 * Initialize buffer variables.
38 *
39 */
40
init_buffer(void)41 void init_buffer(void)
42 {
43 memset(buffer, 0, sizeof (zchar) * TEXT_BUFFER_SIZE);
44 bufpos = 0;
45 prev_c = 0;
46 }
47
48
49 /*
50 * flush_buffer
51 *
52 * Copy the contents of the text buffer to the output streams.
53 *
54 */
flush_buffer(void)55 void flush_buffer(void)
56 {
57 static bool locked = FALSE;
58
59 /* Make sure we stop when flush_buffer is called from flush_buffer.
60 * Note that this is difficult to avoid as we might print a newline
61 * during flush_buffer, which might cause a newline interrupt, that
62 * might execute any arbitrary opcode, which might flush the buffer.
63 */
64 if (locked || bufpos == 0)
65 return;
66
67 /* Send the buffer to the output streams */
68
69 buffer[bufpos] = 0;
70
71 locked = TRUE; stream_word (buffer); locked = FALSE;
72
73 /* Reset the buffer */
74
75 bufpos = 0;
76 prev_c = 0;
77 } /* flush_buffer */
78
79
80 /*
81 * print_char
82 *
83 * High level output function.
84 *
85 */
print_char(zchar c)86 void print_char(zchar c)
87 {
88 static bool flag = FALSE;
89 need_newline_at_exit = TRUE;
90
91 if (message || ostream_memory || enable_buffering) {
92 if (!flag) {
93 /* Characters 0 and ZC_RETURN are special cases */
94 if (c == ZC_RETURN) {
95 new_line();
96 return;
97 }
98 if (c == 0)
99 return;
100
101 /* Flush the buffer before a whitespace or
102 * after a hyphen
103 */
104 if (c == ' ' || c == ZC_INDENT || c == ZC_GAP ||
105 (prev_c == '-' && c != '-'))
106 flush_buffer ();
107 /* Set the flag if this is part one of a
108 * style or font change
109 */
110 if (c == ZC_NEW_FONT || c == ZC_NEW_STYLE)
111 flag = TRUE;
112 /* Remember the current character code */
113 prev_c = c;
114
115 } else flag = FALSE;
116
117 /* Insert the character into the buffer */
118 buffer[bufpos++] = c;
119 if (bufpos == TEXT_BUFFER_SIZE)
120 runtime_error (ERR_TEXT_BUF_OVF);
121 } else stream_char (c);
122 } /* print_char */
123
124
125 /*
126 * new_line
127 *
128 * High level newline function.
129 *
130 */
new_line(void)131 void new_line(void)
132 {
133 flush_buffer (); stream_new_line (); need_newline_at_exit = FALSE;
134
135 } /* new_line */
136
137
138