2 /* Copyright (C) 1989, 1990, 1991, 1992 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
24 const char *current_filename
;
26 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
);
52 void do_file(const char *filename
)
55 if (filename
[0] == '-' && filename
[1] == '\0') {
56 current_filename
= "<standard input>";
61 current_file
= fopen(filename
, "r");
62 if (current_file
== 0) {
63 error("can't open `%1'", filename
);
66 current_filename
= filename
;
74 environment_list
*env_list
= 0;
82 fatal("the first command must be `x T'");
85 fatal("the first command must be `x T'");
86 char *dev
= get_string();
88 device
= strsave(dev
);
89 if (!font::load_desc())
90 fatal("sorry, I can't continue");
93 if (device
== 0 || strcmp(device
, dev
) != 0)
94 fatal("all files must use the same device");
97 env
.size
= 10*font::sizescale
;
100 fatal("the second command must be `x res'");
103 fatal("the second command must be `x res'");
104 int n
= get_integer();
106 fatal("resolution does not match");
109 fatal("horizontal resolution does not match");
112 fatal("vertical resolution does not match");
114 command
= get_char();
116 fatal("the third command must be `x init'");
119 fatal("the third command must be `x init'");
123 while ((command
= get_char()) != EOF
) {
126 env
.size
= get_integer();
127 if (env
.height
== env
.size
)
131 env
.fontno
= get_integer();
136 fatal("`C' command illegal before first `p' command");
137 char *s
= get_string();
138 pr
->set_special_char(s
, &env
);
144 fatal("`N' command illegal before first `p' command");
145 pr
->set_numbered_char(get_integer(), &env
);
149 env
.hpos
= get_integer();
152 env
.hpos
+= get_integer();
155 env
.vpos
= get_integer();
158 env
.vpos
+= get_integer();
172 if (!isascii(c
) || !isdigit(c
))
173 fatal("digit expected");
174 env
.hpos
+= (command
- '0')*10 + (c
- '0');
180 fatal("`c' command illegal before first `p' command");
183 fatal("missing argument to `c' command");
184 pr
->set_ascii_char(c
, &env
);
189 fatal("`n' command illegal before first `p' command");
204 pr
->begin_page(get_integer());
208 env_list
= new environment_list(env
, env_list
);
216 environment_list
*tem
= env_list
;
217 env_list
= env_list
->next
;
224 fatal("`u' command illegal before first `p' command");
225 int kern
= get_integer();
235 pr
->set_ascii_char(c
, &env
, &w
);
236 env
.hpos
+= w
+ kern
;
246 fatal("`t' command illegal before first `p' command");
248 while ((c
= get_char()) != EOF
&& c
!= ' ') {
254 pr
->set_ascii_char(c
, &env
, &w
);
265 fatal("`D' command illegal before first `p' command");
267 while ((c
= get_char()) == ' ')
272 for (int np
= 0; possibly_get_integer(&n
); np
++) {
281 memcpy(p
, oldp
, szp
*sizeof(int));
288 pr
->draw(c
, p
, np
, &env
);
294 for (int i
= 0; i
< np
/2; i
++) {
296 env
.vpos
+= p
[i
*2 + 1];
298 // there might be an odd number of characters
308 char *s
= get_string();
309 int suppress_skip
= 0;
312 error("duplicate `x init' command");
315 error("duplicate `x T' command");
318 error("duplicate `x res' command");
328 int n
= get_integer();
329 char *name
= get_string();
330 pr
->load_font(n
, name
);
334 env
.height
= get_integer();
335 if (env
.height
== env
.size
)
339 env
.slant
= get_integer();
343 fatal("`x X' command illegal before first `p' command");
344 pr
->special(get_string(1), &env
);
348 error("unrecognised x command `%1'", s
);
355 error("unrecognised command code %1", int(command
));
374 if (!isascii(c
) || !isdigit(c
))
375 fatal("integer expected");
384 } while (isascii(c
) && isdigit(c
));
386 ungetc(c
, current_file
);
390 int possibly_get_integer(int *res
)
400 if (!isascii(c
) || !isdigit(c
)) {
402 ungetc(c
, current_file
);
413 } while (isascii(c
) && isdigit(c
));
415 ungetc(c
, current_file
);
421 char *get_string(int is_long
)
428 for (int i
= 0;; i
++) {
432 buf
= new char[buf_size
];
436 int old_size
= buf_size
;
438 buf
= new char[buf_size
];
439 memcpy(buf
, old_buf
, old_size
);
443 if ((!is_long
&& (c
== ' ' || c
== '\n')) || c
== EOF
) {
447 if (is_long
&& c
== '\n') {
461 ungetc(c
, current_file
);
468 while ((c
= get_char()) != EOF
)