⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 psrm.cc

📁 早期freebsd实现
💻 CC
📖 第 1 页 / 共 2 页
字号:
// -*- C++ -*-/* Copyright (C) 1989, 1990, 1991, 1992 Free Software Foundation, Inc.     Written by James Clark (jjc@jclark.com)This file is part of groff.groff is free software; you can redistribute it and/or modify it underthe terms of the GNU General Public License as published by the FreeSoftware Foundation; either version 2, or (at your option) any laterversion.groff is distributed in the hope that it will be useful, but WITHOUT ANYWARRANTY; without even the implied warranty of MERCHANTABILITY orFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public Licensefor more details.You should have received a copy of the GNU General Public License alongwith groff; see the file COPYING.  If not, write to the Free SoftwareFoundation, 675 Mass Ave, Cambridge, MA 02139, USA. */#include "driver.h"#include "stringclass.h"#include "cset.h"#include "ps.h"#define PROLOGUE "prologue"static void print_ps_string(const string &s, FILE *outfp);cset white_space("\n\r \t");string an_empty_string;const char *extension_table[] = {  "DPS",  "CMYK",  "Composite",  "FileSystem",};const int NEXTENSIONS = sizeof(extension_table)/sizeof(extension_table[0]);const char *resource_table[] = {  "font",  "procset",  "file",  "encoding",  "form",  "pattern",};const int NRESOURCES = sizeof(resource_table)/sizeof(resource_table[0]);struct resource {  resource *next;  resource_type type;  string name;  enum { NEEDED = 01, SUPPLIED = 02, FONT_NEEDED = 04, BUSY = 010 };  unsigned flags;  string version;  unsigned revision;  char *filename;  int rank;  resource(resource_type, string &, string & = an_empty_string, unsigned = 0);  ~resource();  void print_type_and_name(FILE *outfp);};resource::resource(resource_type t, string &n, string &v, unsigned r): type(t), revision(r), flags (0), filename(0), rank(-1), next(0){  name.move(n);  version.move(v);  if (type == RESOURCE_FILE) {    if (name.search('\0') >= 0)      error("filename contains a character with code 0");    filename = name.extract();  }}resource::~resource(){  a_delete filename;}void resource::print_type_and_name(FILE *outfp){  fputs(resource_table[type], outfp);  putc(' ', outfp);  print_ps_string(name, outfp);  if (type == RESOURCE_PROCSET) {    putc(' ', outfp);    print_ps_string(version, outfp);    fprintf(outfp, " %u", revision);  }}resource_manager::resource_manager(): resource_list(0), extensions(0), language_level(0){  read_download_file();  string procset_name("grops");  extern const char *version_string;  string procset_version(version_string);  procset_resource = lookup_resource(RESOURCE_PROCSET, procset_name,				     procset_version, 0);  procset_resource->flags |= resource::SUPPLIED;}resource_manager::~resource_manager(){  while (resource_list) {    resource *tem = resource_list;    resource_list = resource_list->next;    delete tem;  }}resource *resource_manager::lookup_resource(resource_type type,					    string &name,					    string &version,					    unsigned revision){  for (resource *r = resource_list; r; r = r->next)    if (r->type == type	&& r->name == name	&& r->version == version	&& r->revision == revision)      return r;  r = new resource(type, name, version, revision);  r->next = resource_list;  resource_list = r;  return r;}// Just a specialized version of lookup_resource().resource *resource_manager::lookup_font(const char *name){  for (resource *r = resource_list; r; r = r->next)    if (r->type == RESOURCE_FONT	&& strlen(name) == r->name.length()	&& memcmp(name, r->name.contents(), r->name.length()) == 0)      return r;  string s(name);  r = new resource(RESOURCE_FONT, s);  r->next = resource_list;  resource_list = r;  return r;}void resource_manager::need_font(const char *name){  lookup_font(name)->flags |= resource::FONT_NEEDED;}typedef resource *Presource;	// Work around g++ bug.void resource_manager::document_setup(ps_output &out){  int nranks = 0;  for (resource *r = resource_list; r; r = r->next)    if (r->rank >= nranks)      nranks = r->rank + 1;  if (nranks > 0) {    // Sort resource_list in reverse order of rank.    Presource *head = new Presource[nranks + 1];    Presource **tail = new Presource *[nranks + 1];    for (int i = 0; i < nranks + 1; i++) {      head[i] = 0;      tail[i] = &head[i];    }    for (r = resource_list; r; r = r->next) {      i = r->rank < 0 ? 0 : r->rank + 1;      *tail[i] = r;      tail[i] = &(*tail[i])->next;    }    resource_list = 0;    for (i = 0; i < nranks + 1; i++)      if (head[i]) {	*tail[i] = resource_list;	resource_list = head[i];      }    a_delete head;    a_delete tail;    // check it    for (r = resource_list; r; r = r->next)      if (r->next)	assert(r->rank >= r->next->rank);    for (r = resource_list; r; r = r->next)      if (r->type == RESOURCE_FONT && r->rank >= 0)	supply_resource(r, -1, out.get_file());  }}void resource_manager::print_resources_comment(unsigned flag, FILE *outfp){  int continued = 0;  for (resource *r = resource_list; r; r = r->next)    if (r->flags & flag) {      if (continued)	fputs("%%+ ", outfp);      else {	fputs(flag == resource::NEEDED	      ? "%%DocumentNeededResources: "	      : "%%DocumentSuppliedResources: ",	      outfp);	continued = 1;      }      r->print_type_and_name(outfp);      putc('\n', outfp);    }}void resource_manager::print_header_comments(ps_output &out){  for (resource *r = resource_list; r; r = r->next)    if (r->type == RESOURCE_FONT && (r->flags & resource::FONT_NEEDED))      supply_resource(r, 0, 0);  print_resources_comment(resource::NEEDED, out.get_file());  print_resources_comment(resource::SUPPLIED, out.get_file());  print_language_level_comment(out.get_file());  print_extensions_comment(out.get_file());}void resource_manager::output_prolog(ps_output &out){  FILE *outfp = out.get_file();  out.end_line();  char *path;  FILE *fp = font::open_file(PROLOGUE, &path);  if (!fp)    fatal("can't find `%1'", PROLOGUE);  fputs("%%BeginResource: ", outfp);  procset_resource->print_type_and_name(outfp);  putc('\n', outfp);  process_file(-1, fp, path, outfp);  fclose(fp);  a_delete path;  fputs("%%EndResource\n", outfp);}void resource_manager::import_file(const char *filename, ps_output &out){  out.end_line();  string name(filename);  resource *r = lookup_resource(RESOURCE_FILE, name);  supply_resource(r, -1, out.get_file(), 1);}void resource_manager::supply_resource(resource *r, int rank, FILE *outfp,				       int is_document){  if (r->flags & resource::BUSY) {    r->name += '\0';    fatal("loop detected in dependency graph for %1 `%2'",	  resource_table[r->type],	  r->name.contents());  }  r->flags |= resource::BUSY;  if (rank > r->rank)    r->rank = rank;  char *path;  FILE *fp = 0;  if (r->filename != 0) {    if (r->type == RESOURCE_FONT) {      fp = font::open_file(r->filename, &path);      if (!fp) {	error("can't find `%1'", r->filename);	a_delete r->filename;	r->filename = 0;      }    }    else {      errno = 0;      fp = fopen(r->filename, "r");      if (!fp) {	error("can't open `%1': %2", r->filename, strerror(errno));	a_delete r->filename;	r->filename = 0;      }      else	path = r->filename;    }  }  if (fp) {    if (outfp) {      if (r->type == RESOURCE_FILE && is_document) {	fputs("%%BeginDocument: ", outfp);	print_ps_string(r->name, outfp);	putc('\n', outfp);      }      else {	fputs("%%BeginResource: ", outfp);	r->print_type_and_name(outfp);	putc('\n', outfp);      }    }    process_file(rank, fp, path, outfp);    fclose(fp);    if (r->type == RESOURCE_FONT)      a_delete path;    if (outfp) {      if (r->type == RESOURCE_FILE && is_document)	fputs("%%EndDocument\n", outfp);      else	fputs("%%EndResource\n", outfp);    }    r->flags |= resource::SUPPLIED;  }  else {    if (outfp) {      if (r->type == RESOURCE_FILE && is_document) {	fputs("%%IncludeDocument: ", outfp);	print_ps_string(r->name, outfp);	putc('\n', outfp);      }      else {	fputs("%%IncludeResource: ", outfp);	r->print_type_and_name(outfp);	putc('\n', outfp);      }    }    r->flags |= resource::NEEDED;  }  r->flags &= ~resource::BUSY;}#define PS_LINE_MAX 255#define PS_MAGIC "%!PS-Adobe-"static int ps_get_line(char *buf, FILE *fp){  int c = getc(fp);  if (c == EOF) {    buf[0] = '\0';    return 0;  }  current_lineno++;  int i = 0;  int err = 0;  while (c != '\r' && c != '\n' && c != EOF) {    if ((c < 0x1b && !white_space(c)) || c == 0x7f)      error("illegal input character code %1", int(c));    else if (i < PS_LINE_MAX)      buf[i++] = c;    else if (!err) {      err = 1;      error("PostScript file non-conforming "	    "because length of line exceeds 255");    }    c = getc(fp);  }  buf[i++] = '\n';  buf[i] = '\0';  if (c == '\r') {    c = getc(fp);    if (c != EOF && c != '\n')      ungetc(c, fp);  }  return 1;}static int read_text_arg(const char **pp, string &res){  res.clear();  while (white_space(**pp))    *pp += 1;  if (**pp == '\0') {    error("missing argument");    return 0;  }  if (**pp != '(') {    for (; **pp != '\0' && !white_space(**pp); *pp += 1)      res += **pp;    return 1;  }  *pp += 1;  res.clear();  int level = 0;  for (;;) {    if (**pp == '\0' || **pp == '\r' || **pp == '\n') {      error("missing ')'");      return 0;    }    if (**pp == ')') {      if (level == 0) {	*pp += 1;	break;      }      res += **pp;      level--;    }    else if (**pp == '(') {      level++;      res += **pp;    }    else if (**pp == '\\') {      *pp += 1;      switch (**pp) {      case 'n':	res += '\n';	break;      case 'r':	res += '\n';	break;      case 't':	res += '\t';	break;      case 'b':	res += '\b';	break;      case 'f':	res += '\f';	break;      case '0':      case '1':      case '2':      case '3':      case '4':      case '5':      case '6':      case '7':	{	  int val = **pp - '0';	  if ((*pp)[1] >= '0' && (*pp)[1] <= '7') {	    *pp += 1;	    val = val*8 + (**pp - '0');	    if ((*pp)[1] >= '0' && (*pp)[1] <= '7') {	      *pp += 1;	      val = val*8 + (**pp - '0');	    }	  }	}	break;      default:	res += **pp;	break;      }    }    else      res += **pp;    *pp += 1;  }  return 1;}static int read_uint_arg(const char **pp, unsigned *res){  while (white_space(**pp))    *pp += 1;  if (**pp == '\0') {    error("missing argument");    return 0;  }  const char *start = *pp;  // XXX use strtoul  long n = strtol(start, (char **)pp, 10);  if (n == 0 && *pp == start) {    error("not an integer");    return 0;  }  if (n < 0) {    error("argument must not be negative");    return 0;  }  *res = unsigned(n);  return 1;}resource *resource_manager::read_file_arg(const char **ptr){  string arg;  if (!read_text_arg(ptr, arg))    return 0;  return lookup_resource(RESOURCE_FILE, arg);}resource *resource_manager::read_font_arg(const char **ptr){  string arg;  if (!read_text_arg(ptr, arg))    return 0;  return lookup_resource(RESOURCE_FONT, arg);}resource *resource_manager::read_procset_arg(const char **ptr){  string arg;  if (!read_text_arg(ptr, arg))    return 0;  string version;  if (!read_text_arg(ptr, version))      return 0;  unsigned revision;  if (!read_uint_arg(ptr, &revision))      return 0;  return lookup_resource(RESOURCE_PROCSET, arg, version, revision);}resource *resource_manager::read_resource_arg(const char **ptr){  while (white_space(**ptr))    *ptr += 1;  const char *name = *ptr;  while (**ptr != '\0' && !white_space(**ptr))    *ptr += 1;  if (name == *ptr) {    error("missing resource type");    return 0;  }  for (int ri = 0; ri < NRESOURCES; ri++)    if (strlen(resource_table[ri]) == *ptr - name	&& memcmp(resource_table[ri], name, *ptr - name) == 0)      break;  if (ri >= NRESOURCES) {    error("unknown resource type");    return 0;  }  if (ri == RESOURCE_PROCSET)    return read_procset_arg(ptr);  string arg;  if (!read_text_arg(ptr, arg))    return 0;  return lookup_resource(resource_type(ri), arg);}static const char *matches_comment(const char *buf, const char *comment){  if (buf[0] != '%' || buf[1] != '%')    return 0;  for (buf += 2; *comment; comment++, buf++)    if (*buf != *comment)      return 0;  if (comment[-1] == ':')    return buf;  if (*buf == '\0' || white_space(*buf))    return buf;  return 0;}// Return 1 if the line should be copied out.int resource_manager::do_begin_resource(const char *ptr, int, FILE *,					FILE *)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -