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

📄 input.cc

📁 早期freebsd实现
💻 CC
字号:
// -*- 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 "device.h"const char *current_filename;int current_lineno;const char *device = 0;FILE *current_file;int get_integer();		// don't read the newlineint possibly_get_integer(int *);char *get_string(int is_long = 0);void skip_line();struct environment_list {  environment env;  environment_list *next;  environment_list(const environment &, environment_list *);};environment_list::environment_list(const environment &e, environment_list *p): env(e), next(p){}inline int get_char(){  return getc(current_file);}void do_file(const char *filename){  int npages = 0;  if (filename[0] == '-' && filename[1] == '\0') {    current_filename = "<standard input>";    current_file = stdin;  }  else {    errno = 0;    current_file = fopen(filename, "r");    if (current_file == 0) {      error("can't open `%1'", filename);      return;    }    current_filename = filename;  }  environment env;  env.vpos = -1;  env.hpos = -1;  env.fontno = -1;  env.height = 0;  env.slant = 0;  environment_list *env_list = 0;  current_lineno = 1;  int command;  char *s;  command = get_char();  if (command == EOF)    return;  if (command != 'x')    fatal("the first command must be `x T'");  s = get_string();  if (s[0] != 'T')    fatal("the first command must be `x T'");  char *dev = get_string();  if (pr == 0) {    device = strsave(dev);    if (!font::load_desc())      fatal("sorry, I can't continue");  }  else {    if (device == 0 || strcmp(device, dev) != 0)      fatal("all files must use the same device");  }  skip_line();  env.size = 10*font::sizescale;  command = get_char();  if (command != 'x')    fatal("the second command must be `x res'");  s = get_string();  if (s[0] != 'r')    fatal("the second command must be `x res'");  int n = get_integer();  if (n != font::res)    fatal("resolution does not match");  n = get_integer();  if (n != font::hor)    fatal("horizontal resolution does not match");  n = get_integer();  if (n != font::vert)    fatal("vertical resolution does not match");  skip_line();  command = get_char();  if (command != 'x')    fatal("the third command must be `x init'");  s = get_string();  if (s[0] != 'i')    fatal("the third command must be `x init'");  skip_line();  if (pr == 0)    pr = make_printer();  while ((command = get_char()) != EOF) {    switch (command) {    case 's':      env.size = get_integer();      if (env.height == env.size)	env.height = 0;      break;    case 'f':      env.fontno = get_integer();      break;    case 'C':      {	if (npages == 0)	  fatal("`C' command illegal before first `p' command");	char *s = get_string();	pr->set_special_char(s, &env);      }      break;    case 'N':      {	if (npages == 0)	  fatal("`N' command illegal before first `p' command");	pr->set_numbered_char(get_integer(), &env);      }      break;    case 'H':      env.hpos = get_integer();      break;    case 'h':      env.hpos += get_integer();      break;    case 'V':      env.vpos = get_integer();      break;    case 'v':      env.vpos += get_integer();      break;    case '0':    case '1':    case '2':    case '3':    case '4':    case '5':    case '6':    case '7':    case '8':    case '9':      {	int c = get_char();	if (!isascii(c) || !isdigit(c))	  fatal("digit expected");	env.hpos += (command - '0')*10 + (c - '0');      }      // fall through    case 'c':      {	if (npages == 0)	  fatal("`c' command illegal before first `p' command");	int c = get_char();	if (c == EOF)	  fatal("missing argument to `c' command");	pr->set_ascii_char(c, &env);      }      break;    case 'n':      if (npages == 0)	fatal("`n' command illegal before first `p' command");      pr->end_of_line();      (void)get_integer();      (void)get_integer();      break;    case 'w':    case ' ':      break;    case '\n':      current_lineno++;      break;    case 'p':      if (npages)	pr->end_page(env.vpos);      npages++;      pr->begin_page(get_integer());      env.vpos = 0;      break;    case '{':      env_list = new environment_list(env, env_list);      break;    case '}':      if (!env_list) {	fatal("can't pop");      }      else {	env = env_list->env;	environment_list *tem = env_list;	env_list = env_list->next;	delete tem;      }      break;    case 'u':      {	if (npages == 0)	  fatal("`u' command illegal before first `p' command");	int kern = get_integer();	int c = get_char();	while (c == ' ')	  c = get_char();	while (c != EOF) {	  if (c == '\n') {	    current_lineno++;	    break;	  }	  int w;	  pr->set_ascii_char(c, &env, &w);	  env.hpos += w + kern;	  c = get_char();	  if (c == ' ')	    break;	}      }      break;    case 't':      {	if (npages == 0)	  fatal("`t' command illegal before first `p' command");	int c;	while ((c = get_char()) != EOF && c != ' ') {	  if (c == '\n') {	    current_lineno++;	    break;	  }	  int w;	  pr->set_ascii_char(c, &env, &w);	  env.hpos += w;	}      }      break;    case '#':      skip_line();      break;    case 'D':      {	if (npages == 0)	  fatal("`D' command illegal before first `p' command");	int c;	while ((c = get_char()) == ' ')	  ;	int n;	int *p = 0;	int szp = 0;	for (int np = 0; possibly_get_integer(&n); np++) {	  if (np >= szp) {	    if (szp == 0) {	      szp = 16;	      p = new int[szp];	    }	    else {	      int *oldp = p;	      p = new int[szp*2];	      memcpy(p, oldp, szp*sizeof(int));	      szp *= 2;	      a_delete oldp;	    }	  }	  p[np] = n;	}	pr->draw(c, p, np, &env);	if (c == 'e') {	  if (np > 0)	    env.hpos += p[0];	}	else { 	  for (int i = 0; i < np/2; i++) {	    env.hpos += p[i*2];	    env.vpos += p[i*2 + 1];	  }	  // there might be an odd number of characters	  if (i*2 < np)	    env.hpos += p[i*2];	}	a_delete p;	skip_line();      }      break;    case 'x':      {	char *s = get_string();	int suppress_skip = 0;	switch (s[0]) {	case 'i':	  error("duplicate `x init' command");	  break;	case 'T':	  error("duplicate `x T' command");	  break;	case 'r':	  error("duplicate `x res' command");	  break;	case 'p':	  break;	case 's':	  break;	case 't':	  break;	case 'f':	  {	    int n = get_integer();	    char *name = get_string();	    pr->load_font(n, name);	  }	  break;	case 'H':	  env.height = get_integer();	  if (env.height == env.size)	    env.height = 0;	  break;	case 'S':	  env.slant = get_integer();	  break;	case 'X':	  if (npages == 0)	    fatal("`x X' command illegal before first `p' command");	  pr->special(get_string(1), &env);	  suppress_skip = 1;	  break;	default:	  error("unrecognised x command `%1'", s);	}	if (!suppress_skip)	  skip_line();      }      break;    default:      error("unrecognised command code %1", int(command));      skip_line();      break;    }  }  if (npages)    pr->end_page(env.vpos);}int get_integer(){  int c = get_char();  while (c == ' ')    c = get_char();  int neg = 0;  if (c == '-') {    neg = 1;    c = get_char();  }  if (!isascii(c) || !isdigit(c))    fatal("integer expected");  int total = 0;  do {    total = total*10;    if (neg)      total -= c - '0';    else      total += c - '0';    c = get_char();  }  while (isascii(c) && isdigit(c));  if (c != EOF)    ungetc(c, current_file);  return total;}int possibly_get_integer(int *res){  int c = get_char();  while (c == ' ')    c = get_char();  int neg = 0;  if (c == '-') {    neg = 1;    c = get_char();  }  if (!isascii(c) || !isdigit(c)) {    if (c != EOF)      ungetc(c, current_file);    return 0;  }  int total = 0;  do {    total = total*10;    if (neg)      total -= c - '0';    else      total += c - '0';    c = get_char();  }  while (isascii(c) && isdigit(c));  if (c != EOF)    ungetc(c, current_file);  *res = total;  return 1;}char *get_string(int is_long){  static char *buf;  static int buf_size;  int c = get_char();  while (c == ' ')    c = get_char();  for (int i = 0;; i++) {    if (i >= buf_size) {      if (buf_size == 0) {	buf_size = 16;	buf = new char[buf_size];      }      else {	char *old_buf = buf;	int old_size = buf_size;	buf_size *= 2;	buf = new char[buf_size];	memcpy(buf, old_buf, old_size);	a_delete old_buf;      }    }    if ((!is_long && (c == ' ' || c == '\n')) || c == EOF) {      buf[i] = '\0';      break;    }    if (is_long && c == '\n') {      current_lineno++;      c = get_char();      if (c == '+')	c = '\n';      else {	buf[i] = '\0';	break;      }    }      buf[i] = c;    c = get_char();  }  if (c != EOF)    ungetc(c, current_file);  return buf;}void skip_line(){  int c;  while ((c = get_char()) != EOF)    if (c == '\n') {      current_lineno++;      break;    }}

⌨️ 快捷键说明

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