1 /* input stream management */
8 char path
[PATHLEN
]; /* for file buffers */
10 char *buf
; /* for string buffers */
12 int unbuf
[32]; /* unread characters */
13 int un
; /* number of unread characters */
16 int lnum
; /* file line number */
20 static struct inbuf
*buf
;
21 static char files
[NFILES
][PATHLEN
];
25 static char **args_init(char **args
);
26 static void args_free(char **args
);
28 static void in_new(void)
30 struct inbuf
*next
= xmalloc(sizeof(*next
));
31 memset(next
, 0, sizeof(*next
));
36 void in_push(char *s
, char **args
)
40 buf
->buf
= xmalloc(len
+ 1);
43 buf
->args
= args
? args_init(args
) : NULL
;
46 void in_so(char *path
)
48 FILE *fin
= path
&& path
[0] ? fopen(path
, "r") : stdin
;
50 errmsg("neatroff: failed to open <%s>\n", path
);
57 snprintf(buf
->path
, sizeof(buf
->path
), "%s", path
);
60 void in_lf(char *path
, int lnum
)
62 struct inbuf
*cur
= buf
;
63 while (cur
&& !cur
->fin
)
66 snprintf(cur
->path
, sizeof(cur
->path
), "%s", path
);
70 void in_queue(char *path
)
73 snprintf(files
[nfiles
++], PATHLEN
, "%s", path
? path
: "");
76 static void in_pop(void)
78 struct inbuf
*old
= buf
;
82 if (old
->fin
&& old
->fin
!= stdin
)
88 void in_nx(char *path
)
103 static int in_nextfile(void)
105 while (!buf
&& cfile
< nfiles
)
106 in_so(files
[cfile
++]);
113 while (buf
|| !in_nextfile()) {
115 return buf
->unbuf
[--buf
->un
];
116 if (buf
->buf
&& buf
->pos
< buf
->len
)
118 if (!buf
->buf
&& (c
= getc(buf
->fin
)) >= 0) {
125 return buf
? (unsigned char) buf
->buf
[buf
->pos
++] : -1;
132 if (buf
&& buf
->un
< sizeof(buf
->unbuf
))
133 buf
->unbuf
[buf
->un
++] = c
;
138 return buf
&& buf
->un
? buf
->unbuf
[buf
->un
- 1] : -1;
143 struct inbuf
*cur
= buf
;
144 while (cur
&& !cur
->args
)
146 return cur
&& cur
->args
&& i
< NARGS
&&
147 cur
->args
[i
] ? cur
->args
[i
] : "";
152 struct inbuf
*cur
= buf
;
154 while (cur
&& !cur
->args
)
156 while (cur
&& cur
->args
&& cur
->args
[n
])
163 struct inbuf
*cur
= buf
;
164 while (cur
&& !cur
->args
)
166 if (cur
&& cur
->args
) {
168 memmove(cur
->args
+ 1, cur
->args
+ 2,
169 (NARGS
- 2) * sizeof(cur
->args
[0]));
170 cur
->args
[NARGS
- 1] = NULL
;
174 char *in_filename(void)
176 struct inbuf
*cur
= buf
;
177 while (cur
&& !cur
->fin
)
179 return cur
&& cur
->path
[0] ? cur
->path
: "-";
184 struct inbuf
*cur
= buf
;
185 while (cur
&& !cur
->fin
)
187 return cur
? cur
->lnum
: 0;
190 static char **args_init(char **args
)
192 char **out
= xmalloc(NARGS
* sizeof(*out
));
194 for (i
= 0; i
< NARGS
; i
++) {
197 int len
= strlen(args
[i
]) + 1;
198 out
[i
] = xmalloc(len
);
199 memcpy(out
[i
], args
[i
], len
);
205 static void args_free(char **args
)
208 for (i
= 0; i
< NARGS
; i
++)