* All affected files: Update postal address of FSF.
[s-roff.git] / src / preproc / html / pushback.cpp
blobfa2c0ce5aa64e2fce48d4df8ce937c753e778dce
1 // -*- C++ -*-
2 /* Copyright (C) 2000, 2001, 2003, 2004 Free Software Foundation, Inc.
3 Written by Gaius Mulley (gaius@glam.ac.uk).
5 This file is part of groff.
7 groff is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2, or (at your option) any later
10 version.
12 groff is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
17 You should have received a copy of the GNU General Public License along
18 with groff; see the file COPYING. If not, write to the Free Software
19 Foundation, 51 Franklin St - Fifth Floor, Boston, MA 02110-1301, USA. */
21 #include "lib.h"
23 #include <signal.h>
24 #include <ctype.h>
25 #include <assert.h>
26 #include <stdlib.h>
27 #include <errno.h>
28 #include "errarg.h"
29 #include "error.h"
30 #include "stringclass.h"
31 #include "posix.h"
32 #include "nonposix.h"
34 #include <errno.h>
35 #include <sys/types.h>
36 #ifdef HAVE_UNISTD_H
37 #include <unistd.h>
38 #endif
40 #include "pushback.h"
41 #include "pre-html.h"
43 #if !defined(TRUE)
44 # define TRUE (1==1)
45 #endif
47 #if !defined(FALSE)
48 # define FALSE (1==0)
49 #endif
51 # define ERROR(X) (void)(fprintf(stderr, "%s:%d error %s\n", __FILE__, __LINE__, X) && \
52 (fflush(stderr)) && localexit(1))
55 #define MAXPUSHBACKSTACK 4096 /* maximum number of character that can be pushed back */
59 * constructor for pushBackBuffer
62 pushBackBuffer::pushBackBuffer (char *filename)
64 charStack = (char *)malloc(MAXPUSHBACKSTACK);
65 if (charStack == 0) {
66 sys_fatal("malloc");
68 stackPtr = 0; /* index to push back stack */
69 debug = 0;
70 verbose = 0;
71 eofFound = FALSE;
72 lineNo = 1;
73 if (strcmp(filename, "") != 0) {
74 stdIn = dup(0);
75 close(0);
76 if (open(filename, O_RDONLY) != 0) {
77 sys_fatal("when trying to open file");
78 } else {
79 fileName = filename;
84 pushBackBuffer::~pushBackBuffer ()
86 int old;
88 if (charStack != 0) {
89 free(charStack);
91 close(0);
92 /* restore stdin in file descriptor 0 */
93 old = dup(stdIn);
94 close(stdIn);
98 * localexit - wraps exit with a return code to aid the ERROR macro.
101 int localexit (int i)
103 exit(i);
104 return( 1 );
108 * getPB - returns a character, possibly a pushed back character.
111 char pushBackBuffer::getPB (void)
113 if (stackPtr>0) {
114 stackPtr--;
115 return( charStack[stackPtr] );
116 } else {
117 char ch;
119 if (read(0, &ch, 1) == 1) {
120 if (verbose) {
121 printf("%c", ch);
123 if (ch == '\n') {
124 lineNo++;
126 return( ch );
127 } else {
128 eofFound = TRUE;
129 return( eof );
135 * putPB - pushes a character onto the push back stack.
136 * The same character is returned.
139 char pushBackBuffer::putPB (char ch)
141 if (stackPtr<MAXPUSHBACKSTACK) {
142 charStack[stackPtr] = ch ;
143 stackPtr++;
144 } else {
145 ERROR("max push back stack exceeded, increase MAXPUSHBACKSTACK constant");
147 return( ch );
151 * isWhite - returns TRUE if a white character is found. This character is NOT consumed.
154 static int isWhite (char ch)
156 return( (ch==' ') || (ch == '\t') || (ch == '\n') );
160 * skipToNewline - skips characters until a newline is seen.
163 void pushBackBuffer::skipToNewline (void)
165 char ch;
167 while ((putPB(getPB()) != '\n') && (! eofFound)) {
168 ch = getPB();
173 * skipUntilToken - skips until a token is seen
176 void pushBackBuffer::skipUntilToken (void)
178 char ch;
180 while ((isWhite(putPB(getPB())) || (putPB(getPB()) == '#')) && (! eofFound)) {
181 ch = getPB();
182 if (ch == '#') {
183 skipToNewline();
189 * isString - returns TRUE if the string, s, matches the pushed back string.
190 * if TRUE is returned then this string is consumed, otherwise it is
191 * left alone.
194 int pushBackBuffer::isString (const char *s)
196 int length=strlen(s);
197 int i=0;
199 while ((i<length) && (putPB(getPB())==s[i])) {
200 if (getPB() != s[i]) {
201 ERROR("assert failed");
203 i++;
205 if (i==length) {
206 return( TRUE );
207 } else {
208 i--;
209 while (i>=0) {
210 if (putPB(s[i]) != s[i]) {
211 ERROR("assert failed");
213 i--;
216 return( FALSE );
220 * isDigit - returns TRUE if the character, ch, is a digit.
223 static int isDigit (char ch)
225 return( ((ch>='0') && (ch<='9')) );
229 * isHexDigit - returns TRUE if the character, ch, is a hex digit.
232 #if 0
233 static int isHexDigit (char ch)
235 return( (isDigit(ch)) || ((ch>='a') && (ch<='f')) );
237 #endif
240 * readInt - returns an integer from the input stream.
243 int pushBackBuffer::readInt (void)
245 int c =0;
246 int i =0;
247 int s =1;
248 char ch=getPB();
250 while (isWhite(ch)) {
251 ch=getPB();
253 // now read integer
255 if (ch == '-') {
256 s = -1;
257 ch = getPB();
259 while (isDigit(ch)) {
260 i *= 10;
261 if ((ch>='0') && (ch<='9')) {
262 i += (int)(ch-'0');
264 ch = getPB();
265 c++;
267 if (ch != putPB(ch)) {
268 ERROR("assert failed");
270 return( i*s );
274 * convertToFloat - converts integers, a and b into a.b
277 static double convertToFloat (int a, int b)
279 int c=10;
280 double f;
282 while (b>c) {
283 c *= 10;
285 f = ((double)a) + (((double)b)/((double)c));
286 return( f );
290 * readNumber - returns a float representing the word just read.
293 double pushBackBuffer::readNumber (void)
295 int i;
296 char ch;
298 i = readInt();
299 if ((ch = getPB()) == '.') {
300 return convertToFloat(i, readInt());
302 putPB(ch);
303 return (double)i;
307 * readString - reads a string terminated by white space
308 * and returns a malloced area of memory containing
309 * a copy of the characters.
312 char *pushBackBuffer::readString (void)
314 char buffer[MAXPUSHBACKSTACK];
315 char *str = 0;
316 int i=0;
317 char ch=getPB();
319 while (isWhite(ch)) {
320 ch=getPB();
322 while ((i < MAXPUSHBACKSTACK) && (! isWhite(ch)) && (! eofFound)) {
323 buffer[i] = ch;
324 i++;
325 ch = getPB();
327 if (i < MAXPUSHBACKSTACK) {
328 buffer[i] = (char)0;
329 str = (char *)malloc(strlen(buffer)+1);
330 strcpy(str, buffer);
332 return( str );