/
niceSOFT
/
groff
Обзор
Документация
Войти
/
niceSOFT
/
groff
Код
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
src/preproc/html/pushback.cpp
326 строк
6 KB
G. Branden Robinson
[grohtml]: Migrate to ISO C++98 Boolean literals.
12 июн 2026, 00:59
12 июн 2026, 00:59
91cc498
Код
Авторство
О чём код?
/* Copyright (C) 2000-2025 Free Software Foundation, Inc. Written by Gaius Mulley (gaius@glam.ac.uk). This file is part of groff, the GNU roff typesetting system. groff is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. groff is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ #ifdef HAVE_CONFIG_H #include <config.h> #endif #include <stdio.h> // fflush(), fprintf(), printf(), putchar(), stderr #include <stdlib.h> // exit(), free(), malloc() #include <string.h> // strcpy(), strlen() // needed for close(), dup(), open(), read() #include "posix.h" #include "nonposix.h" #include "lib.h" #include "errarg.h" #include "error.h" #include "stringclass.h" #include "pushback.h" #include "pre-html.h" # define ERROR(X) (void)(fprintf(stderr, "%s:%d error %s\n", __FILE__, __LINE__, X) && \ (fflush(stderr)) && localexit(1)) #define MAXPUSHBACKSTACK 4096 /* maximum number of character that can be pushed back */ /* * constructor for pushBackBuffer */ pushBackBuffer::pushBackBuffer (const char *filename) { charStack = (char *)malloc(MAXPUSHBACKSTACK); if (charStack == 0) { sys_fatal("malloc"); } stackPtr = 0; /* index to push back stack */ verbose = 0; eofFound = false; lineNo = 1; if (strcmp(filename, "") != 0) { stdIn = dup(0); if (stdIn < 0) { sys_fatal("dup stdin"); } close(0); if (open(filename, O_RDONLY) != 0) { sys_fatal("when trying to open file"); } else { fileName = filename; } } } pushBackBuffer::~pushBackBuffer () { if (charStack != 0) { free(charStack); } close(0); /* restore stdin in file descriptor 0 */ if (dup(stdIn) < 0) { sys_fatal("restore stdin"); } close(stdIn); } /* * localexit - wraps exit with a return code to aid the ERROR macro. */ static int localexit (int i) { exit(i); return( 1 ); } /* * getPB - returns a character, possibly a pushed back character. */ char pushBackBuffer::getPB (void) { if (stackPtr>0) { stackPtr--; return( charStack[stackPtr] ); } else { char ch; if (read(0, &ch, 1) == 1) { if (verbose) { printf("%c", ch); } if (ch == '\n') { lineNo++; } return( ch ); } else { eofFound = true; return( eof ); } } } /* * putPB - pushes a character onto the push back stack. * The same character is returned. */ char pushBackBuffer::putPB (char ch) { if (stackPtr<MAXPUSHBACKSTACK) { charStack[stackPtr] = ch ; stackPtr++; } else { ERROR("max push back stack exceeded, increase MAXPUSHBACKSTACK constant"); } return( ch ); } /* * isWhite - returns true if a white character is found. This character is NOT consumed. */ static bool isWhite (char ch) { return( (ch==' ') || (ch == '\t') || (ch == '\n') ); } /* * skipToNewline - skips characters until a newline is seen. */ void pushBackBuffer::skipToNewline (void) { while ((putPB(getPB()) != '\n') && (! eofFound)) { getPB(); } } /* * skipUntilToken - skips until a token is seen */ void pushBackBuffer::skipUntilToken (void) { char ch; while ((isWhite(putPB(getPB())) || (putPB(getPB()) == '#')) && (! eofFound)) { ch = getPB(); if (ch == '#') { skipToNewline(); } } } /* * isString - returns true if the string, s, matches the pushed back string. * if true is returned then this string is consumed, otherwise it is * left alone. */ bool pushBackBuffer::isString (const char *s) { ptrdiff_t length=ptrdiff_t(strlen(s)); ptrdiff_t i=0; while ((i<length) && (putPB(getPB())==s[i])) { if (getPB() != s[i]) { ERROR("assert failed"); } i++; } if (i==length) { return( true ); } else { i--; while (i>=0) { if (putPB(s[i]) != s[i]) { ERROR("assert failed"); } i--; } } return( false ); } /* * isDigit - returns true if the character, ch, is a digit. */ static bool isDigit (char ch) { return( ((ch>='0') && (ch<='9')) ); } /* * isHexDigit - returns true if the character, ch, is a hex digit. */ #if 0 static bool isHexDigit (char ch) { return( (isDigit(ch)) || ((ch>='a') && (ch<='f')) ); } #endif /* * readInt - returns an integer from the input stream. */ int pushBackBuffer::readInt (void) { int i =0; int s =1; char ch=getPB(); while (isWhite(ch)) { ch=getPB(); } // now read integer if (ch == '-') { s = -1; ch = getPB(); } while (isDigit(ch)) { i *= 10; if ((ch>='0') && (ch<='9')) { i += (int)(ch-'0'); } ch = getPB(); } if (ch != putPB(ch)) { ERROR("assert failed"); } return( i*s ); } /* * convertToFloat - converts integers, a and b into a.b */ static double convertToFloat (int a, int b) { int c=10; double f; while (b>c) { c *= 10; } f = ((double)a) + (((double)b)/((double)c)); return( f ); } /* * readNumber - returns a float representing the word just read. */ double pushBackBuffer::readNumber (void) { int i; char ch; i = readInt(); if ((ch = getPB()) == '.') { return convertToFloat(i, readInt()); } putPB(ch); return (double)i; } /* * readString - reads a string terminated by whitespace * and returns a malloced area of memory containing * a copy of the characters. */ char *pushBackBuffer::readString (void) { char buffer[MAXPUSHBACKSTACK]; char *str = 0; int i=0; char ch=getPB(); while (isWhite(ch)) { ch=getPB(); } while ((i < MAXPUSHBACKSTACK) && (! isWhite(ch)) && (! eofFound)) { buffer[i] = ch; i++; ch = getPB(); } if (i < MAXPUSHBACKSTACK) { buffer[i] = (char)0; str = (char *)malloc(strlen(buffer)+1); strcpy(str, buffer); } return( str ); } // Local Variables: // fill-column: 72 // mode: C++ // End: // vim: set cindent noexpandtab shiftwidth=2 textwidth=72: