0f0f81cdf98c8996b813038d4e6fa3f19d9eaae8
5 * (c) 1999 Straylight/Edgeware
8 /*----- Licensing notice --------------------------------------------------*
10 * This file is part of the `fw' port forwarder.
12 * `fw' is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
17 * `fw' is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with `fw'; if not, write to the Free Software Foundation,
24 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
27 /*----- Header files ------------------------------------------------------*/
33 #include <mLib/dstr.h>
38 /*----- File scanner source -----------------------------------------------*/
40 /* --- File scanner block --- */
42 typedef struct fscan
{
50 static int fscan_scan(scansrc
*ss
)
52 fscan
*fs
= (fscan
*)ss
;
53 int ch
= getc(fs
->fp
);
59 /* --- @destroy@ --- */
61 static void fscan_destroy(scansrc
*ss
)
63 fscan
*fs
= (fscan
*)ss
;
64 if (!(fs
->f
& SCF_NOCLOSE
))
70 /* --- File scanner operations --- */
72 static scansrc_ops fscan_ops
= { fscan_scan
, fscan_destroy
};
74 /* --- @scan_file@ --- *
76 * Arguments: @FILE *fp@ = pointer to file descriptor
77 * @const char *name@ = pointer to source file name
78 * @unsigned f@ = flags
80 * Returns: A scanner source.
82 * Use: Creates a new scanner source for reading from a file.
85 scansrc
*scan_file(FILE *fp
, const char *name
, unsigned f
)
87 fscan
*fs
= CREATE(fscan
);
88 fs
->ss
.ops
= &fscan_ops
;
89 fs
->ss
.src
= xstrdup(name
);
96 /*---- Argv scanner source ------------------------------------------------*/
98 /* --- Argv scanner block --- */
100 typedef struct avscan
{
108 static int avscan_scan(scansrc
*ss
)
110 avscan
*as
= (avscan
*)ss
;
114 else if ((ch
= (unsigned char)*as
->p
++) == 0) {
122 /* --- @destroy@ --- */
124 static void avscan_destroy(scansrc
*ss
)
126 avscan
*as
= (avscan
*)ss
;
130 /* --- Argv scanner operations --- */
132 static scansrc_ops avscan_ops
= { avscan_scan
, avscan_destroy
};
134 /* --- @scan_argv@ --- *
136 * Arguments: @char **av@ = pointer to argument array (null terminated)
138 * Returns: A scanner source.
140 * Use: Creates a new scanner source for reading from an @argv@
144 scansrc
*scan_argv(char **av
)
146 avscan
*as
= CREATE(avscan
);
147 as
->ss
.ops
= &avscan_ops
;
148 as
->ss
.src
= "<argv>";
155 /*----- End-of-file sentinel block ----------------------------------------*/
159 static int eof_scan(scansrc
*ss
)
164 /* --- @destroy@ --- */
166 static void eof_destroy(scansrc
*ss
)
171 /* --- Eof scanner operations --- */
173 static scansrc_ops eof_ops
= { eof_scan
, eof_destroy
};
175 /* --- The end of file marker --- */
177 static scansrc scan_eof
= { &scan_eof
, &eof_ops
, "<eof>", 0, DSTR_INIT
};
179 /*----- General scanner handling ------------------------------------------*/
183 * Arguments: @scanner *sc@ = pointer to main scanner context
185 * Returns: Character read, or end-of-file.
187 * Use: Scans a character from a source of characters.
190 int scan(scanner
*sc
)
193 if (sc
->head
->pushback
.len
)
194 ch
= sc
->head
->pushback
.buf
[--sc
->head
->pushback
.len
];
196 scansrc
*ss
= sc
->head
;
199 else if ((ch
= ss
->ops
->scan(ss
)) == EOF
) {
201 if (sc
->head
== &scan_eof
)
202 sc
->tail
= &sc
->head
;
203 ss
->ops
->destroy(ss
);
210 /* --- @unscan@ --- *
212 * Arguments: @scanner *sc@ = pointer to main scanner context
213 * @int ch@ = character to unscan
217 * Use: Scans a character from a source of characters.
220 void unscan(scanner
*sc
, int ch
)
222 DPUTC(&sc
->head
->pushback
, ch
);
225 /* --- @scan_push@ --- *
227 * Arguments: @scanner *sc@ = pointer to main scanner context
228 * @scansrc *ss@ = souorce to push
232 * Use: Pushes a scanner source onto the front of the queue.
235 void scan_push(scanner
*sc
, scansrc
*ss
)
238 if (sc
->head
== &scan_eof
)
239 sc
->tail
= &ss
->next
;
241 dstr_create(&ss
->pushback
);
246 /* --- @scan_add@ --- *
248 * Arguments: @scanner *sc@ = pointer to main scanner context
249 * @scansrc *ss@ = souorce to push
253 * Use: Adds a scanner source onto the end of the queue.
256 void scan_add(scanner
*sc
, scansrc
*ss
)
258 ss
->next
= &scan_eof
;
260 sc
->tail
= &ss
->next
;
261 dstr_create(&ss
->pushback
);
266 /* --- @scan_create@ --- *
268 * Arguments: @scanner *sc@ = scanner context to initialize
272 * Use: Initializes a scanner block ready for use.
275 void scan_create(scanner
*sc
)
277 sc
->head
= &scan_eof
;
278 sc
->tail
= &sc
->head
;
280 sc
->wbegin
= sc
->wcont
= 0;
283 /* --- @scan_destroy@ --- *
285 * Arguments: @scanner *sc@ = pointer to scanner context
289 * Use: Destroys a scanner and all the sources attached to it.
292 void scan_destroy(scanner
*sc
)
294 scansrc
*ss
= sc
->head
;
295 while (ss
!= &scan_eof
) {
300 dstr_destroy(&sss
->pushback
);
301 sss
->ops
->destroy(sss
);
303 dstr_destroy(&sc
->d
);
307 sc
->head
= &scan_eof
;
308 sc
->tail
= &sc
->head
;
311 /*----- That's all, folks -------------------------------------------------*/