]>
git.ipfire.org Git - thirdparty/cups.git/blob - pdftops/Lexer.cxx
4ca8cfe9f51e323d3fa41fd16bf6a7fddbcb0f8f
1 //========================================================================
5 // Copyright 1996 Derek B. Noonburg
7 //========================================================================
10 #pragma implementation
20 //------------------------------------------------------------------------
22 // A '1' in this array means the character is white space. A '1' or
23 // '2' means the character ends a name or command.
24 static char specialChars
[256] = {
25 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 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, 2, 0, 0, 2, 2, 0, 0, 0, 0, 0, 2, // 2x
28 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 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, 2, 0, 2, 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, 2, 0, 2, 0, 0, // 7x
33 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 8x
34 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 9x
35 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // ax
36 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // bx
37 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // cx
38 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // dx
39 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // ex
40 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 // fx
43 //------------------------------------------------------------------------
45 //------------------------------------------------------------------------
47 Lexer::Lexer(Stream
*str
) {
50 curStr
.initStream(str
);
51 streams
= new Array();
52 streams
->add(curStr
.copy(&obj
));
58 Lexer::Lexer(Object
*obj
) {
61 if (obj
->isStream()) {
62 streams
= new Array();
64 streams
->add(obj
->copy(&obj2
));
66 streams
= obj
->getArray();
70 if (streams
->getLength() > 0) {
71 streams
->get(strPtr
, &curStr
);
77 if (!curStr
.isNone()) {
86 int Lexer::getChar() {
90 while (!curStr
.isNone() && (c
= curStr
.streamGetChar()) == EOF
) {
94 if (strPtr
< streams
->getLength()) {
95 streams
->get(strPtr
, &curStr
);
102 int Lexer::lookChar() {
103 if (curStr
.isNone()) {
106 return curStr
.streamLookChar();
109 Object
*Lexer::getObj(Object
*obj
) {
112 GBool comment
, neg
, done
;
119 // skip whitespace and comments
122 if ((c
= getChar()) == EOF
) {
123 return obj
->initEOF();
126 if (c
== '\r' || c
== '\n')
128 } else if (c
== '%') {
130 } else if (specialChars
[c
] != 1) {
135 // start reading token
139 case '0': case '1': case '2': case '3': case '4':
140 case '5': case '6': case '7': case '8': case '9':
146 } else if (c
== '.') {
155 xi
= xi
* 10 + (c
- '0');
156 } else if (c
== '.') {
176 xf
= xf
+ scale
* (c
- '0');
193 switch (c
= getChar()) {
197 // This breaks some PDF files, e.g., ones from Photoshop.
201 error(getPos(), "Unterminated string");
215 switch (c
= getChar()) {
236 case '0': case '1': case '2': case '3':
237 case '4': case '5': case '6': case '7':
240 if (c
>= '0' && c
<= '7') {
242 c2
= (c2
<< 3) + (c
- '0');
244 if (c
>= '0' && c
<= '7') {
246 c2
= (c2
<< 3) + (c
- '0');
259 error(getPos(), "Unterminated string");
274 if (n
== tokBufSize
) {
276 s
= new GString(tokBuf
, tokBufSize
);
278 s
->append(tokBuf
, tokBufSize
);
287 s
= new GString(tokBuf
, n
);
289 s
->append(tokBuf
, n
);
297 while ((c
= lookChar()) != EOF
&& !specialChars
[c
]) {
301 if (c2
>= '0' && c2
<= '9') {
303 } else if (c2
>= 'A' && c2
<= 'F') {
305 } else if (c2
>= 'a' && c2
<= 'f') {
313 if (c2
>= '0' && c2
<= '9') {
315 } else if (c2
>= 'A' && c2
<= 'F') {
317 } else if (c2
>= 'a' && c2
<= 'f') {
320 error(getPos(), "Illegal digit in hex char in name");
324 if (++n
== tokBufSize
) {
325 error(getPos(), "Name token too long");
331 obj
->initName(tokBuf
);
339 obj
->initCmd(tokBuf
);
342 // hex string or dict punctuation
349 tokBuf
[0] = tokBuf
[1] = '<';
351 obj
->initCmd(tokBuf
);
363 } else if (c
== EOF
) {
364 error(getPos(), "Unterminated hex string");
366 } else if (specialChars
[c
] != 1) {
368 if (c
>= '0' && c
<= '9')
370 else if (c
>= 'A' && c
<= 'F')
372 else if (c
>= 'a' && c
<= 'f')
375 error(getPos(), "Illegal character <%02x> in hex string", c
);
377 if (n
== tokBufSize
) {
379 s
= new GString(tokBuf
, tokBufSize
);
381 s
->append(tokBuf
, tokBufSize
);
393 s
= new GString(tokBuf
, n
);
395 s
->append(tokBuf
, n
);
397 s
->append((char)(c2
<< 4));
407 tokBuf
[0] = tokBuf
[1] = '>';
409 obj
->initCmd(tokBuf
);
411 error(getPos(), "Illegal character '>'");
420 error(getPos(), "Illegal character '%c'", c
);
429 while ((c
= lookChar()) != EOF
&& !specialChars
[c
]) {
431 if (++n
== tokBufSize
) {
432 error(getPos(), "Command token too long");
438 if (tokBuf
[0] == 't' && !strcmp(tokBuf
, "true")) {
439 obj
->initBool(gTrue
);
440 } else if (tokBuf
[0] == 'f' && !strcmp(tokBuf
, "false")) {
441 obj
->initBool(gFalse
);
442 } else if (tokBuf
[0] == 'n' && !strcmp(tokBuf
, "null")) {
445 obj
->initCmd(tokBuf
);
453 void Lexer::skipToNextLine() {
458 if (c
== EOF
|| c
== '\n') {
462 if ((c
= lookChar()) == '\n') {