]>
git.ipfire.org Git - thirdparty/strongswan.git/blob - programs/pluto/lex.c
1 /* lexer (lexical analyzer) for control files
2 * Copyright (C) 1998-2001 D. Hugh Redelmeier.
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * RCSID $Id: lex.c,v 1.1 2004/03/15 20:35:28 as Exp $
27 #include "constants.h"
30 #include "whack.h" /* for RC_LOG_SERIOUS */
33 struct file_lex_position
*flp
= NULL
;
35 /* Open a file for lexical processing.
36 * new_flp and name must point into storage with will live
37 * at least until the file is closed.
40 lexopen(struct file_lex_position
*new_flp
, const char *name
, bool optional
)
42 FILE *f
= fopen(name
, "r");
46 if (!optional
|| errno
!= ENOENT
)
47 log_errno((e
, "could not open \"%s\"", name
));
52 new_flp
->previous
= flp
;
59 flp
->cur
= flp
->buffer
; /* nothing loaded yet */
60 flp
->under
= *flp
->cur
= '\0';
62 (void) shift(); /* prime tok */
74 /* Token decoding: shift() loads the next token into tok.
75 * Iff a token starts at the left margin, it is considered
76 * to be the first in a record. We create a special condition,
77 * Record Boundary (analogous to EOF), just before such a token.
78 * We are unwilling to shift through a record boundary:
79 * it must be overridden first.
80 * Returns FALSE iff Record Boundary or EOF (i.e. no token);
81 * tok will then be NULL.
85 #define tokeq(s) (streq(tok, (s)))
86 #define tokeqword(s) (strcasecmp(tok, (s)) == 0)
92 char *sor
= NULL
; /* start of record for any new lines */
94 passert(flp
->bdry
== B_none
);
103 case '\0': /* end of line */
104 case '#': /* comment to end of line: treat as end of line */
105 /* get the next line */
106 if (fgets(flp
->buffer
, sizeof(flp
->buffer
)-1, flp
->fp
) == NULL
)
109 tok
= flp
->cur
= NULL
;
114 /* strip trailing whitespace, including \n */
116 for (p
= flp
->buffer
+strlen(flp
->buffer
)-1
117 ; p
>flp
->buffer
&& isspace(p
[-1]); p
--)
122 sor
= p
= flp
->buffer
;
124 break; /* try again for a token */
126 case ' ': /* whitespace */
129 break; /* try again for a token */
131 case '"': /* quoted token */
135 /* we have a quoted token: note and advance to its end */
140 loglog(RC_LOG_SERIOUS
, "\"%s\" line %d: unterminated string"
141 , flp
->filename
, flp
->lino
);
142 p
= tok
+ strlen(tok
);
146 p
++; /* include delimiter in token */
149 /* remember token delimiter and replace with '\0' */
159 /* we seem to have a token: note and advance to its end */
162 if (p
[0] == '0' && p
[1] == 't')
164 /* 0t... token goes to end of line */
169 /* "ordinary" token: up to whitespace or end of line */
172 } while (*p
!= '\0' && !isspace(*p
))
175 /* fudge to separate ':' from a preceding adjacent token */
176 if (p
-1 > tok
&& p
[-1] == ':')
180 /* remember token delimiter and replace with '\0' */
187 /* we have a start-of-record: return it, deferring "real" token */
188 flp
->bdry
= B_record
;
197 /* ensures we are at a Record (or File) boundary, optionally warning if not */
200 flushline(const char *m
)
202 if (flp
->bdry
!= B_none
)
209 loglog(RC_LOG_SERIOUS
, "\"%s\" line %d: %s", flp
->filename
, flp
->lino
, m
);
210 do ; while (shift());