2 * Most functions and variables in neatroff are prefixed with tokens
3 * that indicate their purpose, such as:
5 * + tr_xyz: the implementation of troff request .xyz (mostly tr.c)
6 * + in_xyz: input layer (in.c)
7 * + cp_xyz: copy-mode interpretation layer (cp.c)
8 * + ren_xyz: rendering characters into lines (ren.c)
9 * + out_xyz: output layer for generating troff output (out.c)
10 * + dev_xyz: output devices (dev.c)
11 * + num_xyz: number registers (reg.c)
12 * + str_xyz: string registers (reg.c)
13 * + env_xyz: environments (reg.c)
14 * + eval_xyz: integer expression evaluation (eval.c)
15 * + font_xyz: fonts (font.c)
16 * + sbuf_xyz: variable length string buffers (sbuf.c)
17 * + dict_xyz: dictionaries (dict.c)
18 * + wb_xyz: word buffers (wb.c)
19 * + fmt_xyz: line formatting buffers (fmt.c)
20 * + n_xyz: builtin number register xyz
21 * + c_xyz: characters for requests like hc and mc
25 /* predefined array limits */
26 #define PATHLEN 1024 /* path length */
27 #define NFILES 16 /* number of input files */
28 #define NFONTS 32 /* number of fonts */
29 #define FNLEN 32 /* font name length */
30 #define GNLEN 32 /* glyph name length */
31 #define NMLEN 128 /* macro/register/environment name length */
32 #define RNLEN NMLEN /* register/macro name */
33 #define NREGS 8192 /* number of mapped names */
34 #define ILNLEN 1000 /* line limit of input files */
35 #define NARGS 32 /* number of macro arguments */
36 #define NPREV 16 /* environment stack depth */
37 #define NTRAPS 1024 /* number of traps per page */
38 #define NIES 128 /* number of nested .ie commands */
39 #define NTABS 16 /* number of tab stops */
40 #define NCMAPS 512 /* number of character translations (.tr) */
41 #define NSSTR 32 /* number of nested sstr_push() calls */
42 #define NFIELDS 32 /* number of fields */
43 #define NCHARS 32 /* number of characters for .eos, .hydash, .hystop */
44 #define MAXFRAC 100000 /* maximum value of the fractional part */
45 #define NCDEFS 128 /* number of character definitions (.char) */
46 #define NHYPHS 16384 /* hyphenation dictionary/patterns (.hw) */
47 #define NHYPHSWORD 16 /* number of hyphenations per word */
48 #define NHCODES 512 /* number of .hcode characters */
49 #define WORDLEN 256 /* word length (for hyph.c) */
50 #define NFEATS 128 /* number of features per font */
51 #define NSCRPS 64 /* number of scripts per font */
52 #define NLANGS 64 /* number of languages per font */
54 /* converting scales */
55 #define SC_IN (dev_res) /* inch in units */
56 #define SC_PT (SC_IN / 72) /* point in units */
57 #define SC_EM (n_s * SC_IN / 72)
59 /* escape sequences */
60 #define ESC_Q "bCDhHjlLNoRSvwxXZ?" /* \X'ccc' quoted escape sequences */
61 #define ESC_P "*fgkmns" /* \Xc \X(cc \X[ccc] escape sequences */
63 #define MIN(a, b) ((a) < (b) ? (a) : (b))
64 #define MAX(a, b) ((a) < (b) ? (b) : (a))
65 #define LEN(a) (sizeof(a) / sizeof((a)[0]))
67 /* special characters */
68 extern int c_ec
; /* escape character (\) */
69 extern int c_cc
; /* basic control character (.) */
70 extern int c_c2
; /* no-break control character (') */
71 extern char c_pc
[]; /* page number character (%) */
72 #define c_ni 4 /* non-interpreted copy-mode escape */
73 #define c_hc env_hc()/* hyphenation character */
74 #define c_mc env_mc()/* margin character (.mc) */
77 #define c_bp "\\:" /* zero-width word break point */
78 #define c_nb "\\~" /* stretchable no-break space */
80 /* number registers */
81 #define num_get(id) (*nreg(id))
82 void num_set(int id
, int val
);
83 void num_inc(int id
, int pos
);
85 char *num_str(int id
);
86 char *num_getfmt(int id
);
87 void num_setfmt(int id
, char *fmt
);
88 void num_setinc(int id
, int val
);
90 int eval(char *s
, int unit
);
91 int eval_up(char **s
, int unit
);
92 int eval_re(char *s
, int orig
, int unit
);
94 /* string registers */
95 void str_set(int id
, char *s
);
96 void str_dset(int id
, void *d
);
97 char *str_get(int id
);
98 void *str_dget(int id
);
100 void str_rn(int src
, int dst
);
102 /* saving and restoring registers before and after printing diverted lines */
109 struct fmt
*env_fmt(void);
110 struct wb
*env_wb(void);
115 int tab_next(int pos
);
116 int tab_type(int pos
);
118 /* mapping integers to sets */
119 struct iset
*iset_make(void);
120 void iset_free(struct iset
*iset
);
121 int *iset_get(struct iset
*iset
, int key
);
122 void iset_put(struct iset
*iset
, int key
, int ent
);
123 int iset_len(struct iset
*iset
, int key
);
125 /* mapping strings to longs */
126 struct dict
*dict_make(int notfound
, int dupkeys
, int hashlen
);
127 void dict_free(struct dict
*d
);
128 void dict_put(struct dict
*d
, char *key
, int val
);
129 int dict_get(struct dict
*d
, char *key
);
130 int dict_idx(struct dict
*d
, char *key
);
131 char *dict_key(struct dict
*d
, int idx
);
132 int dict_val(struct dict
*d
, int idx
);
133 int dict_prefix(struct dict
*d
, char *key
, int *idx
);
135 /* device related variables */
142 char id
[GNLEN
]; /* device-dependent glyph identifier */
143 char name
[GNLEN
]; /* the first character mapped to this glyph */
144 struct font
*font
; /* glyph font */
145 short wid
; /* character width */
146 short llx
, lly
, urx
, ury
; /* character bounding box */
147 short type
; /* character type; ascender/descender */
150 /* output device functions */
151 int dev_open(char *dir
, char *dev
);
152 void dev_close(void);
153 int dev_mnt(int pos
, char *id
, char *name
);
154 int dev_pos(char *id
);
155 struct font
*dev_font(int pos
);
156 int dev_fontpos(struct font
*fn
);
157 struct glyph
*dev_glyph(char *c
, int fn
);
159 /* font-related functions */
160 struct font
*font_open(char *path
);
161 void font_close(struct font
*fn
);
162 struct glyph
*font_glyph(struct font
*fn
, char *id
);
163 struct glyph
*font_find(struct font
*fn
, char *name
);
164 int font_map(struct font
*fn
, char *name
, char *id
);
165 int font_mapped(struct font
*fn
, char *name
);
166 int font_special(struct font
*fn
);
167 int font_wid(struct font
*fn
, int sz
, int w
);
168 int font_gwid(struct font
*fn
, struct font
*cfn
, int sz
, int w
);
169 int font_swid(struct font
*fn
, int sz
, int ss
);
170 void font_setcs(struct font
*fn
, int cs
, int ps
);
171 int font_getcs(struct font
*fn
);
172 void font_setbd(struct font
*fn
, int bd
);
173 int font_getbd(struct font
*fn
);
174 void font_track(struct font
*fn
, int s1
, int n1
, int s2
, int n2
);
175 void font_setzoom(struct font
*fn
, int zoom
);
176 int font_zoom(struct font
*fn
, int sz
);
177 int font_feat(struct font
*fn
, char *name
, int val
);
178 void font_scrp(struct font
*fn
, char *name
);
179 void font_lang(struct font
*fn
, char *name
);
180 int font_layout(struct font
*fn
, struct glyph
**src
, int nsrc
, int sz
,
181 struct glyph
**dst
, int *dmap
,
182 int *x
, int *y
, int *xadv
, int *yadv
, int lg
, int kn
);
184 /* different layers of neatroff */
185 int in_next(void); /* input layer */
186 int cp_next(void); /* copy-mode layer */
187 int tr_next(void); /* troff layer */
189 void in_push(char *s
, char **args
);
190 void in_so(char *path
); /* .so request */
191 void in_nx(char *path
); /* .nx request */
192 void in_ex(void); /* .ex request */
193 void in_lf(char *path
, int ln
); /* .lf request */
194 void in_queue(char *path
); /* queue the given input file */
195 char *in_arg(int i
); /* look up argument */
196 int in_nargs(void); /* number of arguments */
197 void in_shift(void); /* shift the arguments */
198 void in_back(int c
); /* push back input character */
199 int in_top(void); /* the first pushed-back character */
200 char *in_filename(void); /* current filename */
201 int in_lnum(void); /* current line number */
203 void cp_blk(int skip
); /* skip or read the next line or block */
204 void cp_reqbeg(void); /* beginning of a request line */
205 void cp_copymode(int mode
); /* do not interpret \w and \E */
206 #define cp_back in_back /* cp.c is stateless */
207 int tr_nextreq(void); /* read the next troff request */
208 void tr_req(int reg
, char **args
); /* execute a built-in troff request */
210 /* variable length string buffer */
212 char *s
; /* allocated buffer */
213 int sz
; /* buffer size */
214 int n
; /* length of the string stored in s */
217 void sbuf_init(struct sbuf
*sbuf
);
218 void sbuf_done(struct sbuf
*sbuf
);
219 char *sbuf_out(struct sbuf
*sbuf
);
220 char *sbuf_buf(struct sbuf
*sbuf
);
221 void sbuf_add(struct sbuf
*sbuf
, int c
);
222 void sbuf_append(struct sbuf
*sbuf
, char *s
);
223 void sbuf_printf(struct sbuf
*sbuf
, char *s
, ...);
224 void sbuf_cut(struct sbuf
*sbuf
, int n
);
225 int sbuf_len(struct sbuf
*sbuf
);
226 int sbuf_empty(struct sbuf
*sbuf
);
231 int f
, s
, m
, cd
; /* the last output font and size */
232 int r_f
, r_s
, r_m
, r_cd
;/* current font and size; use n_f and n_s if -1 */
233 int part
; /* partial input (\c) */
234 int cost
; /* the extra cost of line break after this word */
235 int els_neg
, els_pos
; /* extra line spacing */
236 int h
, v
; /* buffer vertical and horizontal positions */
237 int ct
, sb
, st
; /* \w registers */
238 int llx
, lly
, urx
, ury
; /* bounding box */
239 int icleft
; /* pending left italic correction */
241 char sub_c
[WORDLEN
][GNLEN
]; /* the collected subword */
242 int sub_n
; /* collected subword length */
243 int sub_collect
; /* enable subword collection */
246 void wb_init(struct wb
*wb
);
247 void wb_done(struct wb
*wb
);
248 void wb_hmov(struct wb
*wb
, int n
);
249 void wb_vmov(struct wb
*wb
, int n
);
250 void wb_els(struct wb
*wb
, int els
);
251 void wb_etc(struct wb
*wb
, char *x
);
252 void wb_put(struct wb
*wb
, char *c
);
253 void wb_putraw(struct wb
*wb
, char *c
);
254 void wb_putexpand(struct wb
*wb
, char *c
);
255 int wb_part(struct wb
*wb
);
256 void wb_setpart(struct wb
*wb
);
257 int wb_cost(struct wb
*wb
);
258 void wb_setcost(struct wb
*wb
, int cost
);
259 void wb_drawl(struct wb
*wb
, int c
, int h
, int v
);
260 void wb_drawc(struct wb
*wb
, int c
, int r
);
261 void wb_drawe(struct wb
*wb
, int c
, int h
, int v
);
262 void wb_drawa(struct wb
*wb
, int c
, int h1
, int v1
, int h2
, int v2
);
263 void wb_drawxbeg(struct wb
*wb
, int c
);
264 void wb_drawxdot(struct wb
*wb
, int h
, int v
);
265 void wb_drawxcmd(struct wb
*wb
, char *cmd
);
266 void wb_drawxend(struct wb
*wb
);
267 void wb_italiccorrection(struct wb
*wb
);
268 void wb_italiccorrectionleft(struct wb
*wb
);
269 void wb_cat(struct wb
*wb
, struct wb
*src
);
270 void wb_catstr(struct wb
*wb
, char *beg
, char *end
);
271 int wb_wid(struct wb
*wb
);
272 int wb_hpos(struct wb
*wb
);
273 int wb_vpos(struct wb
*wb
);
274 int wb_empty(struct wb
*wb
);
275 int wb_eos(struct wb
*wb
);
276 void wb_wconf(struct wb
*wb
, int *ct
, int *st
, int *sb
,
277 int *llx
, int *lly
, int *urx
, int *ury
);
278 void wb_reset(struct wb
*wb
);
279 char *wb_buf(struct wb
*wb
);
280 void wb_fnszget(struct wb
*wb
, int *fn
, int *sz
, int *m
, int *cd
);
281 void wb_fnszset(struct wb
*wb
, int fn
, int sz
, int m
, int cd
);
282 void wb_flushdir(struct wb
*wb
);
283 void wb_reset(struct wb
*wb
);
284 int wb_keshideh(char *word
, struct wb
*dst
, int wid
);
285 int wb_hywid(struct wb
*wb
);
286 int wb_swid(struct wb
*wb
);
287 int c_eossent(char *s
);
288 int c_eostran(char *s
);
289 int c_hydash(char *s
);
290 int c_hystop(char *s
);
291 int c_hymark(char *s
);
293 /* character translation (.tr) */
294 void cmap_add(char *c1
, char *c2
);
295 char *cmap_map(char *c
);
296 /* character definition (.char) */
297 char *cdef_map(char *c
, int fn
);
298 int cdef_expand(struct wb
*wb
, char *c
, int fn
);
300 /* hyphenation flags */
301 #define HY_LAST 0x02 /* do not hyphenate last lines */
302 #define HY_FINAL2 0x04 /* do not hyphenate the final two characters */
303 #define HY_FIRST2 0x08 /* do not hyphenate the first two characters */
305 void hyphenate(char *hyphs
, char *word
, int flg
);
306 int hy_cput(char *d
, char *s
);
307 void hyph_init(void);
308 void hyph_done(void);
310 /* adjustment types */
311 #define AD_C 0 /* center */
312 #define AD_L 1 /* adjust left margin (flag) */
313 #define AD_R 2 /* adjust right margin (flag) */
314 #define AD_B 3 /* adjust both margin (mask) */
315 #define AD_P 4 /* paragraph-at-once adjustment (flag) */
316 #define AD_K 8 /* keshideh adjustment (flag) */
318 /* line formatting */
319 struct fmt
*fmt_alloc(void);
320 void fmt_free(struct fmt
*fmt
);
321 int fmt_wid(struct fmt
*fmt
);
322 void fmt_space(struct fmt
*fmt
);
323 void fmt_suppressnl(struct fmt
*fmt
);
324 int fmt_word(struct fmt
*fmt
, struct wb
*wb
);
325 int fmt_newline(struct fmt
*fmt
);
326 int fmt_fillreq(struct fmt
*f
);
327 int fmt_fill(struct fmt
*fmt
, int br
);
328 int fmt_morelines(struct fmt
*fmt
);
329 int fmt_morewords(struct fmt
*fmt
);
330 char *fmt_nextline(struct fmt
*fmt
, int *w
,
331 int *li
, int *lI
, int *ll
, int *els_neg
, int *els_pos
);
334 int render(void); /* the main loop */
335 int ren_parse(struct wb
*wb
, char *c
);
336 int ren_char(struct wb
*wb
, int (*next
)(void), void (*back
)(int));
337 int ren_wid(int (*next
)(void), void (*back
)(int));
338 void ren_tl(int (*next
)(void), void (*back
)(int));
339 void ren_hline(struct wb
*wb
, int l
, char *c
); /* horizontal line */
340 void ren_hlcmd(struct wb
*wb
, char *arg
); /* \l */
341 void ren_vlcmd(struct wb
*wb
, char *arg
); /* \L */
342 void ren_bcmd(struct wb
*wb
, char *arg
); /* \b */
343 void ren_ocmd(struct wb
*wb
, char *arg
); /* \o */
344 void ren_dcmd(struct wb
*wb
, char *arg
); /* \D */
345 void ren_zcmd(struct wb
*wb
, char *arg
); /* \Z */
348 void out_line(char *s
); /* output rendered line */
349 void out(char *s
, ...); /* output troff cmd */
352 void tr_ab(char **args
);
353 void tr_bp(char **args
);
354 void tr_br(char **args
);
355 void tr_ce(char **args
);
356 void tr_ch(char **args
);
357 void tr_cl(char **args
);
358 void tr_di(char **args
);
359 void tr_divbeg(char **args
);
360 void tr_divend(char **args
);
361 void tr_divvs(char **args
);
362 void tr_dt(char **args
);
363 void tr_em(char **args
);
364 void tr_ev(char **args
);
365 void tr_fc(char **args
);
366 void tr_fi(char **args
);
367 void tr_fp(char **args
);
368 void tr_fspecial(char **args
);
369 void tr_ft(char **args
);
370 void tr_hcode(char **args
);
371 void tr_hpf(char **args
);
372 void tr_hpfa(char **args
);
373 void tr_hw(char **args
);
374 void tr_in(char **args
);
375 void tr_ll(char **args
);
376 void tr_mk(char **args
);
377 void tr_ne(char **args
);
378 void tr_nf(char **args
);
379 void tr_ns(char **args
);
380 void tr_os(char **args
);
381 void tr_pn(char **args
);
382 void tr_ps(char **args
);
383 void tr_rs(char **args
);
384 void tr_rt(char **args
);
385 void tr_sp(char **args
);
386 void tr_sv(char **args
);
387 void tr_ta(char **args
);
388 void tr_ti(char **args
);
389 void tr_wh(char **args
);
390 void tr_popren(char **args
);
391 void tr_transparent(char **args
);
393 void tr_in2(char **args
);
394 void tr_ti2(char **args
);
395 void tr_l2r(char **args
);
396 void tr_r2l(char **args
);
401 char *tr_args(char **args
, int brk
, int (*next
)(void), void (*back
)(int));
404 void errmsg(char *msg
, ...);
405 void errdie(char *msg
);
406 void *xmalloc(long len
);
407 void *mextend(void *old
, long oldsz
, long newsz
, int memsz
);
410 int utf8next(char *s
, int (*next
)(void));
411 int utf8read(char **s
, char *d
);
412 int utf8one(char *s
);
413 /* reading escapes and characters */
414 int charnext(char *c
, int (*next
)(void), void (*back
)(int));
415 int charread(char **s
, char *c
);
416 int charnext_delim(char *c
, int (*next
)(void), void (*back
)(int), char *delim
);
417 int charread_delim(char **s
, char *c
, char *delim
);
418 void charnext_str(char *d
, char *c
);
419 char *quotednext(int (*next
)(void), void (*back
)(int));
420 char *unquotednext(int cmd
, int (*next
)(void), void (*back
)(int));
421 int escread(char **s
, char **d
);
422 /* string streams; nested next()/back() interface for string buffers */
423 void sstr_push(char *s
);
424 char *sstr_pop(void);
426 void sstr_back(int c
);
428 /* internal commands */
429 #define TR_DIVBEG "\07<" /* diversion begins */
430 #define TR_DIVEND "\07>" /* diversion ends */
431 #define TR_DIVVS "\07V" /* the amount of \n(.v inside diversions */
432 #define TR_POPREN "\07P" /* exit render_rec() */
434 /* mapping register, macro and environment names to indices */
435 #define DOTMAP(c2) (c2) /* optimized mapping for ".x" names */
437 int map(char *s
); /* map name s to an index */
438 char *map_name(int id
); /* return the name mapped to id */
444 void dir_fix(struct sbuf
*sbuf
, char *s
);
448 #define CLR_R(c) (((c) >> 16) & 0xff)
449 #define CLR_G(c) (((c) >> 8) & 0xff)
450 #define CLR_B(c) ((c) & 0xff)
451 #define CLR_RGB(r, g, b) (((r) << 16) | ((g) << 8) | (b))
453 char *clr_str(int c
);
454 int clr_get(char *s
);
456 /* builtin number registers; n_X for .X register */
457 #define n_a (*nreg(DOTMAP('a')))
458 #define n_cp (*nreg(DOTMAP('C')))
459 #define n_d (*nreg(DOTMAP('d')))
460 #define n_f (*nreg(DOTMAP('f')))
461 #define n_h (*nreg(DOTMAP('h')))
462 #define n_i (*nreg(DOTMAP('i')))
463 #define n_it (*nreg(map(".it"))) /* .it trap macro */
464 #define n_itn (*nreg(map(".itn"))) /* .it lines left */
465 #define n_I (*nreg(DOTMAP('I'))) /* base indent */
466 #define n_j (*nreg(DOTMAP('j')))
467 #define n_l (*nreg(DOTMAP('l')))
468 #define n_L (*nreg(DOTMAP('L')))
469 #define n_lsn (*nreg(map("lsn"))) /* for .lsm */
470 #define n_n (*nreg(DOTMAP('n')))
471 #define n_nI (*nreg(map(".nI"))) /* i for .nm */
472 #define n_nm (*nreg(map(".nm"))) /* .nm enabled */
473 #define n_nM (*nreg(map(".nM"))) /* m for .nm */
474 #define n_nn (*nreg(map(".nn"))) /* remaining .nn */
475 #define n_nS (*nreg(map(".nS"))) /* s for .nm */
476 #define n_m (*nreg(DOTMAP('m')))
477 #define n_mc (*nreg(map(".mc"))) /* .mc enabled */
478 #define n_mcn (*nreg(map(".mcn"))) /* .mc distance */
479 #define n_o (*nreg(DOTMAP('o')))
480 #define n_p (*nreg(DOTMAP('p')))
481 #define n_s (*nreg(DOTMAP('s')))
482 #define n_u (*nreg(DOTMAP('u')))
483 #define n_v (*nreg(DOTMAP('v')))
484 #define n_ct (*nreg(map("ct")))
485 #define n_td (*nreg(map(".td"))) /* text direction */
486 #define n_cd (*nreg(map(".cd"))) /* current direction */
487 #define n_dl (*nreg(map("dl")))
488 #define n_dn (*nreg(map("dn")))
489 #define n_ln (*nreg(map("ln")))
490 #define n_nl (*nreg(map("nl")))
491 #define n_sb (*nreg(map("sb")))
492 #define n_st (*nreg(map("st")))
493 #define n_pg (*nreg(map("%"))) /* % */
494 #define n_lb (*nreg(map(".b0"))) /* input line beg */
495 #define n_ce (*nreg(map(".ce"))) /* .ce remaining */
496 #define n_f0 (*nreg(map(".f0"))) /* last .f */
497 #define n_lg (*nreg(map(".lg"))) /* .lg mode */
498 #define n_hy (*nreg(map(".hy"))) /* .hy mode */
499 #define n_hycost (*nreg(map(".hycost"))) /* hyphenation cost */
500 #define n_hycost2 (*nreg(map(".hycost2"))) /* hyphenation cost #2 */
501 #define n_hycost3 (*nreg(map(".hycost3"))) /* hyphenation cost #3 */
502 #define n_hlm (*nreg(map(".hlm"))) /* .hlm */
503 #define n_i0 (*nreg(map(".i0"))) /* last .i */
504 #define n_ti (*nreg(map(".ti"))) /* pending .ti */
505 #define n_kn (*nreg(map(".kn"))) /* .kn mode */
506 #define n_tI (*nreg(map(".tI"))) /* pending .ti2 */
507 #define n_I0 (*nreg(map(".I0"))) /* last .I */
508 #define n_l0 (*nreg(map(".l0"))) /* last .l */
509 #define n_L0 (*nreg(map(".L0"))) /* last .L */
510 #define n_m0 (*nreg(map(".m0"))) /* last .m */
511 #define n_mk (*nreg(map(".mk"))) /* .mk internal register */
512 #define n_na (*nreg(map(".na"))) /* .na mode */
513 #define n_ns (*nreg(map(".ns"))) /* .ns mode */
514 #define n_o0 (*nreg(map(".o0"))) /* last .o */
515 #define n_pmll (*nreg(map(".pmll"))) /* minimum line length (.pmll) */
516 #define n_pmllcost (*nreg(map(".pmllcost"))) /* short line cost */
517 #define n_ss (*nreg(map(".ss"))) /* word space (.ss) */
518 #define n_sss (*nreg(map(".sss"))) /* sentence space (.ss) */
519 #define n_ssh (*nreg(map(".ssh"))) /* word space compression (.ssh) */
520 #define n_s0 (*nreg(map(".s0"))) /* last .s */
521 #define n_sv (*nreg(map(".sv"))) /* .sv value */
522 #define n_lt (*nreg(map(".lt"))) /* .lt value */
523 #define n_t0 (*nreg(map(".lt0"))) /* previous .lt value */
524 #define n_v0 (*nreg(map(".v0"))) /* last .v */
525 #define n_llx (*nreg(map("bbllx"))) /* \w bounding box */
526 #define n_lly (*nreg(map("bblly"))) /* \w bounding box */
527 #define n_urx (*nreg(map("bburx"))) /* \w bounding box */
528 #define n_ury (*nreg(map("bbury"))) /* \w bounding box */
530 /* functions for implementing read-only registers */
531 int f_nexttrap(void); /* .t */
532 int f_divreg(void); /* .z */
533 int f_hpos(void); /* .k */