2
/* Copyright (C) 1989, 1990, 1991, 1992, 2001 Free Software Foundation, Inc.
3
Written by James Clark (jjc@jclark.com)
5
This file is part of groff.
7
groff is free software; you can redistribute it and/or modify it under
8
the terms of the GNU General Public License as published by the Free
9
Software Foundation; either version 2, or (at your option) any later
12
groff is distributed in the hope that it will be useful, but WITHOUT ANY
13
WARRANTY; without even the implied warranty of MERCHANTABILITY or
14
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17
You should have received a copy of the GNU General Public License along
18
with groff; see the file COPYING. If not, write to the Free Software
19
Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
25
const char *current_filename=0;
27
const char *device = 0;
30
int get_integer(); // don't read the newline
31
int possibly_get_integer(int *);
32
char *get_string(int is_long = 0);
35
struct environment_list {
37
environment_list *next;
39
environment_list(const environment &, environment_list *);
42
environment_list::environment_list(const environment &e, environment_list *p)
49
return getc(current_file);
53
* remember_filename - is needed as get_string might overwrite the
54
* filename eventually.
57
void remember_filename(const char *filename)
59
if (current_filename != 0) {
60
free((char *)current_filename);
62
if (strcmp(filename, "-") == 0) {
63
filename = "<standard input>";
65
current_filename = (const char *)malloc(strlen(filename) + 1);
66
if (current_filename == 0) {
67
fatal("can't malloc space for filename");
69
strcpy((char *)current_filename, (char *)filename);
72
void do_file(const char *filename)
75
if (filename[0] == '-' && filename[1] == '\0') {
76
remember_filename(filename);
81
current_file = fopen(filename, "r");
82
if (current_file == 0) {
83
error("can't open `%1'", filename);
86
remember_filename(filename);
94
environment_list *env_list = 0;
102
fatal("the first command must be `x T'");
105
fatal("the first command must be `x T'");
106
char *dev = get_string();
108
device = strsave(dev);
109
if (!font::load_desc())
110
fatal("sorry, I can't continue");
113
if (device == 0 || strcmp(device, dev) != 0)
114
fatal("all files must use the same device");
117
env.size = 10*font::sizescale;
118
command = get_char();
120
fatal("the second command must be `x res'");
123
fatal("the second command must be `x res'");
124
int n = get_integer();
126
fatal("resolution does not match");
129
fatal("horizontal resolution does not match");
132
fatal("vertical resolution does not match");
134
command = get_char();
136
fatal("the third command must be `x init'");
139
fatal("the third command must be `x init'");
143
while ((command = get_char()) != EOF) {
146
env.size = get_integer();
147
if (env.height == env.size)
151
env.fontno = get_integer();
154
remember_filename(get_string());
159
fatal("`C' command illegal before first `p' command");
160
char *s = get_string();
161
pr->set_special_char(s, &env);
167
fatal("`N' command illegal before first `p' command");
168
pr->set_numbered_char(get_integer(), &env);
172
env.hpos = get_integer();
175
env.hpos += get_integer();
178
env.vpos = get_integer();
181
env.vpos += get_integer();
196
fatal("digit expected");
197
env.hpos += (command - '0')*10 + (c - '0');
203
fatal("`c' command illegal before first `p' command");
206
fatal("missing argument to `c' command");
207
pr->set_ascii_char(c, &env);
212
fatal("`n' command illegal before first `p' command");
225
pr->end_page(env.vpos);
227
pr->begin_page(get_integer());
231
env_list = new environment_list(env, env_list);
239
environment_list *tem = env_list;
240
env_list = env_list->next;
247
fatal("`u' command illegal before first `p' command");
248
int kern = get_integer();
258
pr->set_ascii_char(c, &env, &w);
259
env.hpos += w + kern;
269
fatal("`t' command illegal before first `p' command");
271
while ((c = get_char()) != EOF && c != ' ') {
277
pr->set_ascii_char(c, &env, &w);
288
fatal("`D' command illegal before first `p' command");
290
while ((c = get_char()) == ' ')
296
for (np = 0; possibly_get_integer(&n); np++) {
305
memcpy(p, oldp, szp*sizeof(int));
312
pr->draw(c, p, np, &env);
317
else if (c == 'f' || c == 't')
321
for (i = 0; i < np/2; i++) {
323
env.vpos += p[i*2 + 1];
325
// there might be an odd number of characters
335
char *s = get_string();
336
int suppress_skip = 0;
339
error("duplicate `x init' command");
342
error("duplicate `x T' command");
345
error("duplicate `x res' command");
355
int n = get_integer();
356
char *name = get_string();
357
pr->load_font(n, name);
361
env.height = get_integer();
362
if (env.height == env.size)
366
env.slant = get_integer();
370
fatal("`x X' command illegal before first `p' command");
371
pr->special(get_string(1), &env);
376
pr->special(get_string(), &env, 'u');
379
error("unrecognised x command `%1'", s);
386
error("unrecognised command code %1", int(command));
392
pr->end_page(env.vpos);
406
fatal("integer expected");
415
} while (csdigit(c));
417
ungetc(c, current_file);
421
int possibly_get_integer(int *res)
433
ungetc(c, current_file);
444
} while (csdigit(c));
446
ungetc(c, current_file);
452
char *get_string(int is_long)
459
for (int i = 0;; i++) {
463
buf = new char[buf_size];
467
int old_size = buf_size;
469
buf = new char[buf_size];
470
memcpy(buf, old_buf, old_size);
474
if ((!is_long && (c == ' ' || c == '\n')) || c == EOF) {
478
if (is_long && c == '\n') {
492
ungetc(c, current_file);
499
while ((c = get_char()) != EOF)