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