1 //========================================================================
5 // Copyright 1996 Derek B. Noonburg
7 //========================================================================
10 #pragma implementation
20 //------------------------------------------------------------------------
22 // A '1' in this array means the corresponding character ends a name
24 static char endOfNameChars[128] = {
25 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, // 0x
26 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x
27 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, // 2x
28 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, // 3x
29 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 4x
30 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, // 5x
31 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 6x
32 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0 // 7x
35 //------------------------------------------------------------------------
37 //------------------------------------------------------------------------
39 Lexer::Lexer(Stream *str) {
42 curStr.initStream(str);
43 streams = new Array();
44 streams->add(curStr.copy(&obj));
50 Lexer::Lexer(Object *obj) {
53 if (obj->isStream()) {
54 streams = new Array();
56 streams->add(obj->copy(&obj2));
58 streams = obj->getArray();
62 if (streams->getLength() > 0) {
63 streams->get(strPtr, &curStr);
75 int Lexer::getChar() {
79 while (!curStr.isNone() && (c = curStr.streamGetChar()) == EOF) {
82 if (strPtr < streams->getLength()) {
83 streams->get(strPtr, &curStr);
90 int Lexer::lookChar() {
94 while (!curStr.isNone() && (c = curStr.streamLookChar()) == EOF) {
97 if (strPtr < streams->getLength()) {
98 streams->get(strPtr, &curStr);
105 Object *Lexer::getObj(Object *obj) {
108 GBool comment, neg, done;
115 // skip whitespace and comments
118 if ((c = getChar()) == EOF)
119 return obj->initEOF();
121 if (c == '\r' || c == '\n')
123 } else if (c == '%') {
125 } else if (!isspace(c)) {
130 // start reading token
134 case '0': case '1': case '2': case '3': case '4':
135 case '5': case '6': case '7': case '8': case '9':
141 } else if (c == '.') {
150 xi = xi * 10 + (c - '0');
151 } else if (c == '.') {
170 xf = xf + scale * (c - '0');
187 switch (c = getChar()) {
192 error(getPos(), "Unterminated string");
206 switch (c = getChar()) {
227 case '0': case '1': case '2': case '3':
228 case '4': case '5': case '6': case '7':
231 if (c >= '0' && c <= '7') {
233 c2 = (c2 << 3) + (c - '0');
235 if (c >= '0' && c <= '7') {
237 c2 = (c2 << 3) + (c - '0');
249 error(getPos(), "Unterminated string");
264 if (n == tokBufSize) {
266 s = new GString(tokBuf, tokBufSize);
268 s->append(tokBuf, tokBufSize);
277 s = new GString(tokBuf, n);
279 s->append(tokBuf, n);
287 while ((c = lookChar()) != EOF && !(c < 128 && endOfNameChars[c])) {
291 if (c2 >= '0' && c2 <= '9')
293 else if (c2 >= 'A' && c2 <= 'F')
295 else if (c2 >= 'a' && c2 <= 'f')
302 if (c2 >= '0' && c2 <= '9')
304 else if (c2 >= 'A' && c2 <= 'F')
306 else if (c2 >= 'a' && c2 <= 'f')
309 error(getPos(), "Illegal digit in hex char in name");
312 if (++n == tokBufSize) {
313 error(getPos(), "Name token too long");
319 obj->initName(tokBuf);
327 obj->initCmd(tokBuf);
330 // hex string or dict punctuation
337 tokBuf[0] = tokBuf[1] = '<';
339 obj->initCmd(tokBuf);
351 } else if (c == EOF) {
352 error(getPos(), "Unterminated hex string");
354 } else if (!isspace(c)) {
356 if (c >= '0' && c <= '9')
358 else if (c >= 'A' && c <= 'F')
360 else if (c >= 'a' && c <= 'f')
363 error(getPos(), "Illegal character <%02x> in hex string", c);
365 if (n == tokBufSize) {
367 s = new GString(tokBuf, tokBufSize);
369 s->append(tokBuf, tokBufSize);
381 s = new GString(tokBuf, n);
383 s->append(tokBuf, n);
385 s->append((char)(c2 << 4));
395 tokBuf[0] = tokBuf[1] = '>';
397 obj->initCmd(tokBuf);
399 error(getPos(), "Illegal character '>'");
408 error(getPos(), "Illegal character '%c'", c);
417 while ((c = lookChar()) != EOF && !(c < 128 && endOfNameChars[c])) {
419 if (++n == tokBufSize) {
420 error(getPos(), "Command token too long");
426 if (tokBuf[0] == 't' && !strcmp(tokBuf, "true"))
427 obj->initBool(gTrue);
428 else if (tokBuf[0] == 'f' && !strcmp(tokBuf, "false"))
429 obj->initBool(gFalse);
430 else if (tokBuf[0] == 'n' && !strcmp(tokBuf, "null"))
433 obj->initCmd(tokBuf);
440 void Lexer::skipToNextLine() {
445 if (c == EOF || c == '\n')
448 if ((c = lookChar()) == '\n')