📄 psrm.cc
字号:
{ resource *r = read_resource_arg(&ptr); if (r) r->flags |= resource::SUPPLIED; return 1;}int resource_manager::do_include_resource(const char *ptr, int rank, FILE *, FILE *outfp){ resource *r = read_resource_arg(&ptr); if (r) { if (r->type == RESOURCE_FONT) { if (rank >= 0) supply_resource(r, rank + 1, outfp); else r->flags |= resource::FONT_NEEDED; } else supply_resource(r, rank, outfp); } return 0;}int resource_manager::do_begin_document(const char *ptr, int, FILE *, FILE *){ resource *r = read_file_arg(&ptr); if (r) r->flags |= resource::SUPPLIED; return 1;}int resource_manager::do_include_document(const char *ptr, int rank, FILE *, FILE *outfp){ resource *r = read_file_arg(&ptr); if (r) supply_resource(r, rank, outfp, 1); return 0;}int resource_manager::do_begin_procset(const char *ptr, int, FILE *, FILE *outfp){ resource *r = read_procset_arg(&ptr); if (r) { r->flags |= resource::SUPPLIED; if (outfp) { fputs("%%BeginResource: ", outfp); r->print_type_and_name(outfp); putc('\n', outfp); } } return 0;}int resource_manager::do_include_procset(const char *ptr, int rank, FILE *, FILE *outfp){ resource *r = read_procset_arg(&ptr); if (r) supply_resource(r, rank, outfp); return 0;}int resource_manager::do_begin_file(const char *ptr, int, FILE *, FILE *outfp){ resource *r = read_file_arg(&ptr); if (r) { r->flags |= resource::SUPPLIED; if (outfp) { fputs("%%BeginResource: ", outfp); r->print_type_and_name(outfp); putc('\n', outfp); } } return 0;}int resource_manager::do_include_file(const char *ptr, int rank, FILE *, FILE *outfp){ resource *r = read_file_arg(&ptr); if (r) supply_resource(r, rank, outfp); return 0;}int resource_manager::do_begin_font(const char *ptr, int, FILE *, FILE *outfp){ resource *r = read_font_arg(&ptr); if (r) { r->flags |= resource::SUPPLIED; if (outfp) { fputs("%%BeginResource: ", outfp); r->print_type_and_name(outfp); putc('\n', outfp); } } return 0;}int resource_manager::do_include_font(const char *ptr, int rank, FILE *, FILE *outfp){ resource *r = read_font_arg(&ptr); if (r) { if (rank >= 0) supply_resource(r, rank + 1, outfp); else r->flags |= resource::FONT_NEEDED; } return 0;}int resource_manager::change_to_end_resource(const char *, int, FILE *, FILE *outfp){ if (outfp) fputs("%%EndResource\n", outfp); return 0;}int resource_manager::do_begin_preview(const char *, int, FILE *fp, FILE *){ char buf[PS_LINE_MAX + 2]; do { if (!ps_get_line(buf, fp)) { error("end of file in preview section"); break; } } while (!matches_comment(buf, "EndPreview")); return 0;}int read_one_of(const char **ptr, const char **s, int n){ while (white_space(**ptr)) *ptr += 1; if (**ptr == '\0') return -1; const char *start = *ptr; do { ++ptr; } while (**ptr != '\0' && !white_space(**ptr)); for (int i = 0; i < n; i++) if (strlen(s[i]) == *ptr - start && memcmp(s[i], start, *ptr - start) == 0) return i; return -1;}int resource_manager::do_begin_data(const char *ptr, int, FILE *fp, FILE *outfp){ while (white_space(*ptr)) ptr++; const char *start = ptr; unsigned numberof; if (!read_uint_arg(&ptr, &numberof)) return 0; static const char *types[] = { "Binary", "Hex", "ASCII" }; const int Binary = 0; int type = 0; static const char *units[] = { "Bytes", "Lines" }; const int Bytes = 0; int unit = Bytes; while (white_space(*ptr)) ptr++; if (*ptr != '\0') { type = read_one_of(&ptr, types, 3); if (type < 0) { error("bad data type"); return 0; } while (white_space(*ptr)) ptr++; if (*ptr != '\0') { unit = read_one_of(&ptr, units, 2); if (unit < 0) { error("expected `Bytes' or `Lines'"); return 0; } } } if (type != Binary) return 1; if (outfp) { fputs("%%BeginData: ", outfp); fputs(start, outfp); } if (numberof > 0) { unsigned bytecount = 0; unsigned linecount = 0; do { int c = getc(fp); if (c == EOF) { error("end of file within data section"); return 0; } if (outfp) putc(c, outfp); bytecount++; if (c == '\r') { int cc = getc(fp); if (cc != '\n') { linecount++; current_lineno++; } if (cc != EOF) ungetc(c, fp); } else if (c == '\n') { linecount++; current_lineno++; } } while ((unit == Bytes ? bytecount : linecount) < numberof); } char buf[PS_LINE_MAX + 2]; if (!ps_get_line(buf, fp)) { error("missing %%%%EndData line"); return 0; } if (!matches_comment(buf, "EndData")) error("bad %%%%EndData line"); if (outfp) fputs(buf, outfp); return 0;}int resource_manager::do_begin_binary(const char *ptr, int, FILE *fp, FILE *outfp){ if (!outfp) return 0; unsigned count; if (!read_uint_arg(&ptr, &count)) return 0; if (outfp) fprintf(outfp, "%%%%BeginData: %u Binary Bytes\n", count); while (count != 0) { int c = getc(fp); if (c == EOF) { error("end of file within binary section"); return 0; } if (outfp) putc(c, outfp); --count; if (c == '\r') { int cc = getc(fp); if (cc != '\n') current_lineno++; if (cc != EOF) ungetc(c, fp); } else if (c == '\n') current_lineno++; } char buf[PS_LINE_MAX + 2]; if (!ps_get_line(buf, fp)) { error("missing %%%%EndBinary line"); return 0; } if (!matches_comment(buf, "EndBinary")) { error("bad %%%%EndBinary line"); if (outfp) fputs(buf, outfp); } else if (outfp) fputs("%%EndData\n", outfp); return 0;}static unsigned parse_extensions(const char *ptr){ unsigned flags = 0; for (;;) { while (white_space(*ptr)) ptr++; if (*ptr == '\0') break; const char *name = ptr; do { ++ptr; } while (*ptr != '\0' && !white_space(*ptr)); for (int i = 0; i < NEXTENSIONS; i++) if (strlen(extension_table[i]) == ptr - name && memcmp(extension_table[i], name, ptr - name) == 0) { flags |= (1 << i); break; } if (i >= NEXTENSIONS) { string s(name, ptr - name); s += '\0'; error("unknown extension `%1'", s.contents()); } } return flags;}// XXX if it has not been surrounded with {Begin,End}Document need to strip// out Page: Trailer {Begin,End}Prolog {Begin,End}Setup sections.// XXX Perhaps the decision whether to use BeginDocument or// BeginResource: file should be postponed till we have seen// the first line of the file.void resource_manager::process_file(int rank, FILE *fp, const char *filename, FILE *outfp){ // If none of these comments appear in the header section, and we are // just analyzing the file (ie outfp is 0), then we can return immediately. static const char *header_comment_table[] = { "DocumentNeededResources:", "DocumentSuppliedResources:", "DocumentNeededFonts:", "DocumentSuppliedFonts:", "DocumentNeededProcSets:", "DocumentSuppliedProcSets:", "DocumentNeededFiles:", "DocumentSuppliedFiles:", }; const int NHEADER_COMMENTS = (sizeof(header_comment_table) / sizeof(header_comment_table[0])); struct comment_info { const char *name; int (resource_manager::*proc)(const char *, int, FILE *, FILE *); }; static comment_info comment_table[] = { "BeginResource:", &resource_manager::do_begin_resource, "IncludeResource:", &resource_manager::do_include_resource, "BeginDocument:", &resource_manager::do_begin_document, "IncludeDocument:", &resource_manager::do_include_document, "BeginProcSet:", &resource_manager::do_begin_procset, "IncludeProcSet:", &resource_manager::do_include_procset, "BeginFont:", &resource_manager::do_begin_font, "IncludeFont:", &resource_manager::do_include_font, "BeginFile:", &resource_manager::do_begin_file, "IncludeFile:", &resource_manager::do_include_file, "EndProcSet", &resource_manager::change_to_end_resource, "EndFont", &resource_manager::change_to_end_resource, "EndFile", &resource_manager::change_to_end_resource, "BeginPreview:", &resource_manager::do_begin_preview, "BeginData:", &resource_manager::do_begin_data, "BeginBinary:", &resource_manager::do_begin_binary, }; const int NCOMMENTS = sizeof(comment_table)/sizeof(comment_table[0]); char buf[PS_LINE_MAX + 2]; int saved_lineno = current_lineno; const char *saved_filename = current_filename; current_filename = filename; current_lineno = 0; if (!ps_get_line(buf, fp)) { current_filename = saved_filename; current_lineno = saved_lineno; return; } if (strlen(buf) < sizeof(PS_MAGIC) - 1 || memcmp(buf, PS_MAGIC, sizeof(PS_MAGIC) - 1) != 0) { if (outfp) { do { if (!(broken_flags & STRIP_PERCENT_BANG) || buf[0] != '%' || buf[1] != '!') fputs(buf, outfp); } while (ps_get_line(buf, fp)); } } else { if (!(broken_flags & STRIP_PERCENT_BANG) && outfp) fputs(buf, outfp); int in_header = 1; int interesting = 0; int had_extensions_comment = 0; int had_language_level_comment = 0; for (;;) { if (!ps_get_line(buf, fp)) break; int copy_this_line = 1; if (buf[0] == '%') { if (buf[1] == '%') { const char *ptr; for (int i = 0; i < NCOMMENTS; i++) if (ptr = matches_comment(buf, comment_table[i].name)) { copy_this_line = (this->*(comment_table[i].proc))(ptr, rank, fp, outfp); break; } if (i >= NCOMMENTS && in_header) { if (ptr = matches_comment(buf, "EndComments")) in_header = 0; else if (!had_extensions_comment && (ptr = matches_comment(buf, "Extensions:"))) { extensions |= parse_extensions(ptr); // XXX handle possibility that next line is %%+ had_extensions_comment = 1; } else if (!had_language_level_comment && (ptr = matches_comment(buf, "LanguageLevel:"))) { unsigned ll; if (read_uint_arg(&ptr, &ll) && ll > language_level) language_level = ll; had_language_level_comment = 1; } else { for (int i = 0; i < NHEADER_COMMENTS; i++) if (matches_comment(buf, header_comment_table[i])) { interesting = 1; break; } } } if ((broken_flags & STRIP_STRUCTURE_COMMENTS) && (matches_comment(buf, "EndProlog") || matches_comment(buf, "Page:") || matches_comment(buf, "Trailer"))) copy_this_line = 0; } else if (buf[1] == '!') { if (broken_flags & STRIP_PERCENT_BANG) copy_this_line = 0; } } else in_header = 0; if (!outfp && !in_header && !interesting) break; if (copy_this_line && outfp) fputs(buf, outfp); } } current_filename = saved_filename; current_lineno = saved_lineno;}void resource_manager::read_download_file(){ char *path = 0; FILE *fp = font::open_file("download", &path); if (!fp) fatal("can't find `download'"); char buf[512]; int lineno = 0; while (fgets(buf, sizeof(buf), fp)) { lineno++; char *p = strtok(buf, " \t\r\n"); if (p == 0 || *p == '#') continue; char *q = strtok(0, " \t\r\n"); if (!q) fatal_with_file_and_line(path, lineno, "missing filename"); lookup_font(p)->filename = strsave(q); } a_delete path; fclose(fp);}// XXX Can we share some code with ps_output::put_string()?static void print_ps_string(const string &s, FILE *outfp){ int len = s.length(); const char *str = s.contents(); int funny = 0; if (str[0] == '(') funny = 1; else { for (int i = 0; i < len; i++) if (str[i] <= 040 || str[i] > 0176) { funny = 1; break; } } if (!funny) { put_string(s, outfp); return; } int level = 0; for (int i = 0; i < len; i++) if (str[i] == '(') level++; else if (str[i] == ')' && --level < 0) break; putc('(', outfp); for (i = 0; i < len; i++) switch (str[i]) { case '(': case ')': if (level != 0) putc('\\', outfp); putc(str[i], outfp); break; case '\\': fputs("\\\\", outfp); break; case '\n': fputs("\\n", outfp); break; case '\r': fputs("\\r", outfp); break; case '\t': fputs("\\t", outfp); break; case '\b': fputs("\\b", outfp); break; case '\f': fputs("\\f", outfp); break; default: if (str[i] < 040 || str[i] > 0176) fprintf(outfp, "\\%03o", str[i] & 0377); else putc(str[i], outfp); break; } putc(')', outfp);}void resource_manager::print_extensions_comment(FILE *outfp){ if (extensions) { fputs("%%Extensions:", outfp); for (int i = 0; i < NEXTENSIONS; i++) if (extensions & (1 << i)) { putc(' ', outfp); fputs(extension_table[i], outfp); } putc('\n', outfp); }}void resource_manager::print_language_level_comment(FILE *outfp){ if (language_level) fprintf(outfp, "%%%%LanguageLevel: %u\n", language_level);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -