blob: a5eb7c86cd2dbb8819c9bbdea72db68d8beb66b3 [file] [log] [blame]
//========================================================================
//
// 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 <stdio.h>
#include <stdlib.h>
#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 (1) {
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;
}