| //======================================================================== |
| // |
| // PSTokenizer.cc |
| // |
| // Copyright 2002-2003 Glyph & Cog, LLC |
| // |
| //======================================================================== |
| |
| //======================================================================== |
| // |
| // Modified under the Poppler project - http://poppler.freedesktop.org |
| // |
| // All changes made under the Poppler project to this file are licensed |
| // under GPL version 2 or later |
| // |
| // Copyright (C) 2006 Scott Turner <scotty1024@mac.com> |
| // Copyright (C) 2008 Albert Astals Cid <aacid@kde.org> |
| // Copyright (C) 2017 Vincent Le Garrec <legarrec.vincent@gmail.com> |
| // |
| // To see a description of the changes please see the Changelog file that |
| // came with your tarball or type make ChangeLog if you are building from git |
| // |
| //======================================================================== |
| |
| #include <config.h> |
| |
| #include <cstdio> |
| #include <cstdlib> |
| #include "PSTokenizer.h" |
| |
| //------------------------------------------------------------------------ |
| |
| // A '1' in this array means the character is white space. A '1' or |
| // '2' means the character ends a name or command. |
| static const char specialChars[256] = { |
| 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, // 0x |
| 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x |
| 1, 0, 0, 0, 0, 2, 0, 0, 2, 2, 0, 0, 0, 0, 0, 2, // 2x |
| 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, // 3x |
| 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 4x |
| 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 0, // 5x |
| 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 6x |
| 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 0, // 7x |
| 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8x |
| 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9x |
| 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // ax |
| 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // bx |
| 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // cx |
| 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // dx |
| 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // ex |
| 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 // fx |
| }; |
| |
| //------------------------------------------------------------------------ |
| |
| PSTokenizer::PSTokenizer(int (*getCharFuncA)(void *), void *dataA) |
| { |
| getCharFunc = getCharFuncA; |
| data = dataA; |
| charBuf = -1; |
| } |
| |
| PSTokenizer::~PSTokenizer() { } |
| |
| bool PSTokenizer::getToken(char *buf, int size, int *length) |
| { |
| bool comment, backslash; |
| int c; |
| int i; |
| |
| // skip leading whitespace and comments |
| comment = false; |
| while (true) { |
| if ((c = getChar()) == EOF) { |
| buf[0] = '\0'; |
| *length = 0; |
| return false; |
| } |
| if (comment) { |
| if (c == '\x0a' || c == '\x0d') { |
| comment = false; |
| } |
| } else if (c == '%') { |
| comment = true; |
| } else if (specialChars[static_cast<unsigned char>(c)] != 1) { |
| break; |
| } |
| } |
| |
| // Reserve room for terminating '\0' |
| size--; |
| |
| // read a token |
| i = 0; |
| buf[i++] = c; |
| if (c == '(') { |
| backslash = false; |
| while ((c = lookChar()) != EOF) { |
| consumeChar(); |
| if (i < size) { |
| buf[i++] = c; |
| } |
| if (c == '\\') { |
| backslash = true; |
| } else if (!backslash && c == ')') { |
| break; |
| } else { |
| backslash = false; |
| } |
| } |
| } else if (c == '<') { |
| while ((c = lookChar()) != EOF) { |
| consumeChar(); |
| if (i < size && specialChars[static_cast<unsigned char>(c)] != 1) { |
| buf[i++] = c; |
| } |
| if (c == '>') { |
| break; |
| } |
| } |
| } else if (c != '[' && c != ']') { |
| while ((c = lookChar()) != EOF && !specialChars[static_cast<unsigned char>(c)]) { |
| consumeChar(); |
| if (i < size) { |
| buf[i++] = c; |
| } |
| } |
| } |
| // Zero terminate token string |
| buf[i] = '\0'; |
| // Return length of token |
| *length = i; |
| |
| return true; |
| } |
| |
| int PSTokenizer::lookChar() |
| { |
| if (charBuf < 0) { |
| charBuf = (*getCharFunc)(data); |
| } |
| return charBuf; |
| } |
| |
| void PSTokenizer::consumeChar() |
| { |
| charBuf = -1; |
| } |
| |
| int PSTokenizer::getChar() |
| { |
| int c = charBuf; |
| |
| if (c < 0) { |
| c = (*getCharFunc)(data); |
| } else { |
| charBuf = -1; |
| } |
| return c; |
| } |