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