Sync usage with man page.
[netbsd-mini2440.git] / gnu / dist / groff / src / preproc / html / pushback.cpp
blob5316ad470d78feac0e91b80e90d205d5438d704c
1 /* $NetBSD$ */
3 // -*- C++ -*-
4 /* Copyright (C) 2000, 2001, 2003, 2004, 2005 Free Software Foundation, Inc.
5 Written by Gaius Mulley (gaius@glam.ac.uk).
7 This file is part of groff.
9 groff is free software; you can redistribute it and/or modify it under
10 the terms of the GNU General Public License as published by the Free
11 Software Foundation; either version 2, or (at your option) any later
12 version.
14 groff is distributed in the hope that it will be useful, but WITHOUT ANY
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 for more details.
19 You should have received a copy of the GNU General Public License along
20 with groff; see the file COPYING. If not, write to the Free Software
21 Foundation, 51 Franklin St - Fifth Floor, Boston, MA 02110-1301, USA. */
23 #include "lib.h"
25 #include <signal.h>
26 #include <ctype.h>
27 #include <assert.h>
28 #include <stdlib.h>
29 #include <errno.h>
30 #include "errarg.h"
31 #include "error.h"
32 #include "stringclass.h"
33 #include "posix.h"
34 #include "nonposix.h"
36 #include <errno.h>
37 #include <sys/types.h>
38 #ifdef HAVE_UNISTD_H
39 #include <unistd.h>
40 #endif
42 #include "pushback.h"
43 #include "pre-html.h"
45 #if !defined(TRUE)
46 # define TRUE (1==1)
47 #endif
49 #if !defined(FALSE)
50 # define FALSE (1==0)
51 #endif
53 # define ERROR(X) (void)(fprintf(stderr, "%s:%d error %s\n", __FILE__, __LINE__, X) && \
54 (fflush(stderr)) && localexit(1))
57 #define MAXPUSHBACKSTACK 4096 /* maximum number of character that can be pushed back */
61 * constructor for pushBackBuffer
64 pushBackBuffer::pushBackBuffer (char *filename)
66 charStack = (char *)malloc(MAXPUSHBACKSTACK);
67 if (charStack == 0) {
68 sys_fatal("malloc");
70 stackPtr = 0; /* index to push back stack */
71 debug = 0;
72 verbose = 0;
73 eofFound = FALSE;
74 lineNo = 1;
75 if (strcmp(filename, "") != 0) {
76 stdIn = dup(0);
77 close(0);
78 if (open(filename, O_RDONLY) != 0) {
79 sys_fatal("when trying to open file");
80 } else {
81 fileName = filename;
86 pushBackBuffer::~pushBackBuffer ()
88 if (charStack != 0) {
89 free(charStack);
91 close(0);
92 /* restore stdin in file descriptor 0 */
93 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 while ((putPB(getPB()) != '\n') && (! eofFound)) {
166 getPB();
171 * skipUntilToken - skips until a token is seen
174 void pushBackBuffer::skipUntilToken (void)
176 char ch;
178 while ((isWhite(putPB(getPB())) || (putPB(getPB()) == '#')) && (! eofFound)) {
179 ch = getPB();
180 if (ch == '#') {
181 skipToNewline();
187 * isString - returns TRUE if the string, s, matches the pushed back string.
188 * if TRUE is returned then this string is consumed, otherwise it is
189 * left alone.
192 int pushBackBuffer::isString (const char *s)
194 int length=strlen(s);
195 int i=0;
197 while ((i<length) && (putPB(getPB())==s[i])) {
198 if (getPB() != s[i]) {
199 ERROR("assert failed");
201 i++;
203 if (i==length) {
204 return( TRUE );
205 } else {
206 i--;
207 while (i>=0) {
208 if (putPB(s[i]) != s[i]) {
209 ERROR("assert failed");
211 i--;
214 return( FALSE );
218 * isDigit - returns TRUE if the character, ch, is a digit.
221 static int isDigit (char ch)
223 return( ((ch>='0') && (ch<='9')) );
227 * isHexDigit - returns TRUE if the character, ch, is a hex digit.
230 #if 0
231 static int isHexDigit (char ch)
233 return( (isDigit(ch)) || ((ch>='a') && (ch<='f')) );
235 #endif
238 * readInt - returns an integer from the input stream.
241 int pushBackBuffer::readInt (void)
243 int c =0;
244 int i =0;
245 int s =1;
246 char ch=getPB();
248 while (isWhite(ch)) {
249 ch=getPB();
251 // now read integer
253 if (ch == '-') {
254 s = -1;
255 ch = getPB();
257 while (isDigit(ch)) {
258 i *= 10;
259 if ((ch>='0') && (ch<='9')) {
260 i += (int)(ch-'0');
262 ch = getPB();
263 c++;
265 if (ch != putPB(ch)) {
266 ERROR("assert failed");
268 return( i*s );
272 * convertToFloat - converts integers, a and b into a.b
275 static double convertToFloat (int a, int b)
277 int c=10;
278 double f;
280 while (b>c) {
281 c *= 10;
283 f = ((double)a) + (((double)b)/((double)c));
284 return( f );
288 * readNumber - returns a float representing the word just read.
291 double pushBackBuffer::readNumber (void)
293 int i;
294 char ch;
296 i = readInt();
297 if ((ch = getPB()) == '.') {
298 return convertToFloat(i, readInt());
300 putPB(ch);
301 return (double)i;
305 * readString - reads a string terminated by white space
306 * and returns a malloced area of memory containing
307 * a copy of the characters.
310 char *pushBackBuffer::readString (void)
312 char buffer[MAXPUSHBACKSTACK];
313 char *str = 0;
314 int i=0;
315 char ch=getPB();
317 while (isWhite(ch)) {
318 ch=getPB();
320 while ((i < MAXPUSHBACKSTACK) && (! isWhite(ch)) && (! eofFound)) {
321 buffer[i] = ch;
322 i++;
323 ch = getPB();
325 if (i < MAXPUSHBACKSTACK) {
326 buffer[i] = (char)0;
327 str = (char *)malloc(strlen(buffer)+1);
328 strcpy(str, buffer);
330 return( str );