Adapt src/pre-html (src/preproc/html)
[s-roff.git] / src / pre-html / pushback.cpp
blob0e78239847fc00a7049d7e03881c40b79326b482
1 /*@
2 * Copyright (c) 2014 Steffen (Daode) Nurpmeso <sdaoden@users.sf.net>.
4 * Copyright (C) 2000, 2001, 2003 - 2005 Free Software Foundation, Inc.
5 * Written by Gaius Mulley (gaius@glam.ac.uk).
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.
22 #include "config.h"
23 #include "html-config.h"
25 #include <sys/types.h>
27 #include <assert.h>
28 #include <ctype.h>
29 #include <errno.h>
30 #include <signal.h>
31 #include <stdlib.h>
33 #include "errarg.h"
34 #include "error.h"
35 #include "lib.h"
36 #include "nonposix.h"
37 #include "posix.h"
38 #include "stringclass.h"
40 #include "pushback.h"
41 #include "pre-html.h"
43 #define ERROR(X) \
44 (void)(fprintf(stderr, "%s:%d error %s\n", __FILE__, __LINE__, X) &&\
45 (fflush(stderr)) && localexit(1))
47 pushBackBuffer::pushBackBuffer (char *filename)
49 charStack = (char *)malloc(MAXPUSHBACKSTACK);
50 if (charStack == 0) {
51 sys_fatal("malloc");
53 stackPtr = 0; /* index to push back stack */
54 debug = 0;
55 verbose = 0;
56 eofFound = false;
57 lineNo = 1;
58 if (strcmp(filename, "") != 0) {
59 stdIn = dup(0);
60 close(0);
61 if (open(filename, O_RDONLY) != 0) {
62 sys_fatal("when trying to open file");
63 } else {
64 fileName = filename;
69 pushBackBuffer::~pushBackBuffer ()
71 if (charStack != 0) {
72 free(charStack);
74 close(0);
75 /* restore stdin in file descriptor 0 */
76 dup(stdIn);
77 close(stdIn);
81 * localexit - wraps exit with a return code to aid the ERROR macro.
84 int localexit (int i)
86 exit(i);
87 return( 1 );
91 * getPB - returns a character, possibly a pushed back character.
94 char pushBackBuffer::getPB (void)
96 if (stackPtr>0) {
97 stackPtr--;
98 return( charStack[stackPtr] );
99 } else {
100 char ch;
102 if (read(0, &ch, 1) == 1) {
103 if (verbose) {
104 printf("%c", ch);
106 if (ch == '\n') {
107 lineNo++;
109 return( ch );
110 } else {
111 eofFound = true;
112 return( eof );
118 * putPB - pushes a character onto the push back stack.
119 * The same character is returned.
122 char pushBackBuffer::putPB (char ch)
124 if (stackPtr<MAXPUSHBACKSTACK) {
125 charStack[stackPtr] = ch ;
126 stackPtr++;
127 } else {
128 ERROR("max push back stack exceeded, increase MAXPUSHBACKSTACK constant");
130 return( ch );
134 * isWhite - returns true if a white character is found. This character is NOT consumed.
137 static int isWhite (char ch)
139 return( (ch==' ') || (ch == '\t') || (ch == '\n') );
143 * skipToNewline - skips characters until a newline is seen.
146 void pushBackBuffer::skipToNewline (void)
148 while ((putPB(getPB()) != '\n') && (! eofFound)) {
149 getPB();
154 * skipUntilToken - skips until a token is seen
157 void pushBackBuffer::skipUntilToken (void)
159 char ch;
161 while ((isWhite(putPB(getPB())) || (putPB(getPB()) == '#')) && (! eofFound)) {
162 ch = getPB();
163 if (ch == '#') {
164 skipToNewline();
170 * isString - returns true if the string, s, matches the pushed back string.
171 * if true is returned then this string is consumed, otherwise it is
172 * left alone.
175 int pushBackBuffer::isString (const char *s)
177 int length=strlen(s);
178 int i=0;
180 while ((i<length) && (putPB(getPB())==s[i])) {
181 if (getPB() != s[i]) {
182 ERROR("assert failed");
184 i++;
186 if (i==length) {
187 return true;
188 } else {
189 i--;
190 while (i>=0) {
191 if (putPB(s[i]) != s[i]) {
192 ERROR("assert failed");
194 i--;
197 return false;
201 * isDigit - returns true if the character, ch, is a digit.
204 static int isDigit (char ch)
206 return( ((ch>='0') && (ch<='9')) );
210 * isHexDigit - returns true if the character, ch, is a hex digit.
213 #if 0
214 static int isHexDigit (char ch)
216 return( (isDigit(ch)) || ((ch>='a') && (ch<='f')) );
218 #endif
221 * readInt - returns an integer from the input stream.
224 int pushBackBuffer::readInt (void)
226 int c =0;
227 int i =0;
228 int s =1;
229 char ch=getPB();
231 while (isWhite(ch)) {
232 ch=getPB();
234 // now read integer
236 if (ch == '-') {
237 s = -1;
238 ch = getPB();
240 while (isDigit(ch)) {
241 i *= 10;
242 if ((ch>='0') && (ch<='9')) {
243 i += (int)(ch-'0');
245 ch = getPB();
246 c++;
248 if (ch != putPB(ch)) {
249 ERROR("assert failed");
251 return( i*s );
255 * convertToFloat - converts integers, a and b into a.b
258 static double convertToFloat (int a, int b)
260 int c=10;
261 double f;
263 while (b>c) {
264 c *= 10;
266 f = ((double)a) + (((double)b)/((double)c));
267 return( f );
271 * readNumber - returns a float representing the word just read.
274 double pushBackBuffer::readNumber (void)
276 int i;
277 char ch;
279 i = readInt();
280 if ((ch = getPB()) == '.') {
281 return convertToFloat(i, readInt());
283 putPB(ch);
284 return (double)i;
288 * readString - reads a string terminated by white space
289 * and returns a malloced area of memory containing
290 * a copy of the characters.
293 char *pushBackBuffer::readString (void)
295 char buffer[MAXPUSHBACKSTACK];
296 char *str = 0;
297 int i=0;
298 char ch=getPB();
300 while (isWhite(ch)) {
301 ch=getPB();
303 while ((i < MAXPUSHBACKSTACK) && (! isWhite(ch)) && (! eofFound)) {
304 buffer[i] = ch;
305 i++;
306 ch = getPB();
308 if (i < MAXPUSHBACKSTACK) {
309 buffer[i] = (char)0;
310 str = (char *)malloc(strlen(buffer)+1);
311 strcpy(str, buffer);
313 return( str );
316 // s-it2-mode