📄 pdf_lex.c.svn-base
字号:
#include "fitz.h"#include "mupdf.h"/* * pdf_lex will use fz_peekbyte and fz_readbyte. * have to check for file errors with fz_readerror() after lexing. */static inline int iswhite(int ch){ return ch == '\000' || ch == '\011' || ch == '\012' || ch == '\014' || ch == '\015' || ch == '\040';}static inline int isdelim(int ch){ return ch == '(' || ch == ')' || ch == '<' || ch == '>' || ch == '[' || ch == ']' || ch == '{' || ch == '}' || ch == '/' || ch == '%';}static inline int isregular(int ch){ return !isdelim(ch) && !iswhite(ch) && ch != EOF;}static inline int isnumber(int ch){ return ch == '+' || ch == '-' || ch == '.' || (ch >= '0' && ch <= '9');}static inline int ishex(int ch){ return (ch >= '0' && ch <= '9') || (ch >= 'A' && ch <= 'F') || (ch >= 'a' && ch <= 'f');}static inline int fromhex(int ch){ if (ch >= '0' && ch <= '9') return ch - '0'; else if (ch >= 'A' && ch <= 'F') return ch - 'A' + 0xA; else if (ch >= 'a' && ch <= 'f') return ch - 'a' + 0xA; return 0;}static inline voidlexwhite(fz_stream *f){ int c; while (1) { c = fz_peekbyte(f); if (!iswhite(c)) break; fz_readbyte(f); }}static inline voidlexcomment(fz_stream *f){ int c; while (1) { c = fz_readbyte(f); if (c == '\012') break; if (c == '\015') break; if (c == EOF) break; }}static voidlexnumber(fz_stream *f, char *s, int n){ while (n > 1) { if (!isnumber(fz_peekbyte(f))) break; *s++ = fz_readbyte(f); n--; } *s = '\0';}static voidlexname(fz_stream *f, char *s, int n){ char *p = s; char *q = s; while (n > 1) { if (!isregular(fz_peekbyte(f))) break; *s++ = fz_readbyte(f); n--; } *s = '\0'; while (*p) { if (p[0] == '#' && p[1] != 0 && p[2] != 0) { *q++ = fromhex(p[1]) * 16 + fromhex(p[2]); p += 3; } else *q++ = *p++; } *q = '\0';}static intlexstring(fz_stream *f, char *buf, int n){ char *s = buf; char *e = buf + n; int bal = 1; int oct; int c; while (s < e) { c = fz_readbyte(f); if (c == '(') { bal++; *s++ = c; } else if (c == ')') { bal --; if (bal == 0) break; *s++ = c; } else if (c == '\\') { c = fz_readbyte(f); if (c == 'n') *s++ = '\n'; else if (c == 'r') *s++ = '\r'; else if (c == 't') *s++ = '\t'; else if (c == 'b') *s++ = '\b'; else if (c == 'f') *s++ = '\f'; else if (c == '(') *s++ = '('; else if (c == ')') *s++ = ')'; else if (c == '\\') *s++ = '\\'; else if (c >= '0' && c <= '9') { oct = c - '0'; c = fz_peekbyte(f); if (c >= '0' && c <= '9') { fz_readbyte(f); oct = oct * 8 + (c - '0'); c = fz_peekbyte(f); if (c >= '0' && c <= '9') { fz_readbyte(f); oct = oct * 8 + (c - '0'); } } *s++ = oct; } else if (c == '\n') ; else if (c == '\r') { c = fz_peekbyte(f); if (c == '\n') fz_readbyte(f); } else *s++ = c; } else { *s++ = c; } } return s - buf;}static intlexhexstring(fz_stream *f, char *buf, int n){ char *s = buf; char *e = buf + n; int a = 0, x = 0; int c; while (s < e) { c = fz_readbyte(f); if (c == '>') break; else if (iswhite(c)) continue; else if (ishex(c)) { if (x) { *s++ = a * 16 + fromhex(c); x = !x; } else { a = fromhex(c); x = !x; } } else break; } return s - buf;}static pdf_token_etokenfromkeyword(char *key){ if (!strcmp(key, "R")) return PDF_TR; if (!strcmp(key, "true")) return PDF_TTRUE; if (!strcmp(key, "false")) return PDF_TFALSE; if (!strcmp(key, "null")) return PDF_TNULL; if (!strcmp(key, "obj")) return PDF_TOBJ; if (!strcmp(key, "endobj")) return PDF_TENDOBJ; if (!strcmp(key, "stream")) return PDF_TSTREAM; if (!strcmp(key, "endstream")) return PDF_TENDSTREAM; if (!strcmp(key, "xref")) return PDF_TXREF; if (!strcmp(key, "trailer")) return PDF_TTRAILER; if (!strcmp(key, "startxref")) return PDF_TSTARTXREF; return PDF_TKEYWORD;}fz_error *pdf_lex(pdf_token_e *tok, fz_stream *f, char *buf, int n, int *sl){ fz_error *error; int c; while (1) { c = fz_peekbyte(f); if (c == EOF) { *tok = PDF_TEOF; goto cleanupokay; } else if (iswhite(c)) lexwhite(f); else if (c == '%') lexcomment(f); else if (c == '/') { fz_readbyte(f); lexname(f, buf, n); *sl = strlen(buf); *tok = PDF_TNAME; goto cleanupokay; } else if (c == '(') { fz_readbyte(f); *sl = lexstring(f, buf, n); *tok = PDF_TSTRING; goto cleanupokay; } else if (c == '<') { fz_readbyte(f); c = fz_peekbyte(f); if (c == '<') { fz_readbyte(f); *tok = PDF_TODICT; goto cleanupokay; } else { *sl = lexhexstring(f, buf, n); *tok = PDF_TSTRING; goto cleanupokay; } } else if (c == '>') { fz_readbyte(f); c = fz_readbyte(f); if (c == '>') { *tok = PDF_TCDICT; goto cleanupokay; } *tok = PDF_TERROR; goto cleanuperror; } else if (c == '[') { fz_readbyte(f); *tok = PDF_TOARRAY; goto cleanupokay; } else if (c == ']') { fz_readbyte(f); *tok = PDF_TCARRAY; goto cleanupokay; } else if (c == '{') { fz_readbyte(f); *tok = PDF_TOBRACE; goto cleanupokay; } else if (c == '}') { fz_readbyte(f); *tok = PDF_TCBRACE; goto cleanupokay; } else if (isnumber(c)) { lexnumber(f, buf, n); *sl = strlen(buf); if (strchr(buf, '.')) { *tok = PDF_TREAL; goto cleanupokay; } *tok = PDF_TINT; goto cleanupokay; } else if (isregular(c)) { lexname(f, buf, n); *sl = strlen(buf); *tok = tokenfromkeyword(buf); goto cleanupokay; } else { *tok = PDF_TERROR; goto cleanuperror; } }cleanupokay: error = fz_readerror(f); if (error) { *tok = PDF_TERROR; return fz_rethrow(error, "cannot read token"); } return fz_okay;cleanuperror: error = fz_readerror(f); if (error) { *tok = PDF_TERROR; return fz_rethrow(error, "cannot read token"); } *tok = PDF_TERROR; return fz_throw("lexical error");}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -