3
* config.c - configuration file parsing
5
* Copyright Ā© 2009 Scott James Remnant <scott@netsplit.com>.
6
* Copyright Ā© 2009 Canonical Ltd.
8
* This program is free software; you can redistribute it and/or modify
9
* it under the terms of the GNU General Public License version 2, as
10
* published by the Free Software Foundation.
12
* This program is distributed in the hope that it will be useful,
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
* GNU General Public License for more details.
17
* You should have received a copy of the GNU General Public License along
18
* with this program; if not, write to the Free Software Foundation, Inc.,
19
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24
#endif /* HAVE_CONFIG_H */
27
#include <sys/types.h>
32
#include <nih/macros.h>
33
#include <nih/alloc.h>
34
#include <nih/string.h>
36
#include <nih/config.h>
37
#include <nih/logging.h>
38
#include <nih/error.h>
39
#include <nih/errors.h>
42
/* Prototypes for static functions */
43
static int nih_config_block_end (const char *file, size_t len,
44
size_t *lineno, size_t *pos,
47
__attribute__ ((warn_unused_result));
48
static NihConfigStanza *nih_config_get_stanza (const char *name,
49
NihConfigStanza *stanzas);
53
* nih_config_has_token:
54
* @file: file or string to parse,
55
* @len: length of @file,
56
* @pos: offset within @file,
57
* @lineno: line number.
59
* Checks the current position in @file to see whether it has a parseable
60
* token at this position; ie. we're not at the end of file, and the
61
* current character is neither a comment or newline character.
63
* If this returns FALSE, it's normal to call nih_config_skip_comment()
64
* to move to the next parseable point and check again.
66
* @file may be a memory mapped file, in which case @pos should be given
67
* as the offset within and @len should be the length of the file as a
70
* @pos is used as the offset within @file to begin, otherwise the start
73
* Returns: TRUE if the current character is before the end of file and
74
* is neither a comment or newline, FALSE otherwise.
77
nih_config_has_token (const char *file,
84
nih_assert (file != NULL);
87
if ((p < len) && (! strchr (NIH_CONFIG_CNL, file[p]))) {
97
* @file: file or string to parse,
98
* @len: length of @file,
99
* @pos: offset within @file,
100
* @lineno: line number,
101
* @dest: destination to copy to,
102
* @delim: characters to stop on,
103
* @dequote: remove quotes and escapes.
104
* @toklen: pointer to store token length in.
106
* Parses a single token from @file which is stopped when any character
107
* in @delim is encountered outside of a quoted string and not escaped
108
* using a backslash. The length of the parsed token is stored in @toklen
111
* @file may be a memory mapped file, in which case @pos should be given
112
* as the offset within and @len should be the length of the file as a
113
* whole. Usually when @dest is given, @file is instead the pointer to
114
* the start of the token and @len is the difference between the start
115
* and end of the token (NOT the return value from this function).
117
* If @pos is given then it will be used as the offset within @file to
118
* begin (otherwise the start is assumed), and will be updated to point
119
* to @delim or past the end of the file.
121
* If @lineno is given it will be incremented each time a new line is
122
* discovered in the file.
124
* To copy the token into another string, collapsing any newlines and
125
* surrounding whitespace to a single space, pass @dest which should be
126
* pre-allocated to the right size (obtained by calling this function
129
* If you also want quotes to be removed and escaped characters to be
130
* replaced with the character itself, set @dequote to TRUE.
132
* Returns: zero on success, negative value on raised error.
135
nih_config_token (const char *file,
144
size_t p, ws = 0, nlws = 0, qc = 0, i = 0;
145
int slash = FALSE, quote = 0, nl = FALSE, ret = 0;
147
nih_assert (file != NULL);
148
nih_assert (delim != NULL);
150
/* We keep track of the following:
151
* slash whether a \ is in effect
152
* quote whether " or ' is in effect (set to which)
153
* ws number of consecutive whitespace chars so far
154
* nlws number of whitespace/newline chars
155
* nl TRUE if we need to copy ws into nlws at first non-WS
156
* qc number of quote characters that need removing.
159
for (p = (pos ? *pos : 0); p < len; p++) {
160
int extra = 0, isq = FALSE;
165
/* Escaped newline */
166
if (file[p] == '\n') {
172
} else if ((file[p] == '\\')
173
|| strchr (NIH_CONFIG_WS, file[p])) {
180
} else if (file[p] == '\\') {
184
if (file[p] == quote) {
187
} else if (file[p] == '\n') {
192
} else if (strchr (NIH_CONFIG_WS, file[p])) {
196
} else if ((file[p] == '\"') || (file[p] == '\'')) {
199
} else if (strchr (delim, file[p])) {
201
} else if (strchr (NIH_CONFIG_WS, file[p])) {
207
/* Newline is recorded as a single space;
208
* any surrounding whitespace is lost.
213
} else if (ws && dest) {
214
/* Whitespace that we've encountered to date is
217
memcpy (dest + i, file + p - ws - extra, ws);
221
/* Extra characters (the slash) needs to be copied
222
* unless we're dequoting the string
224
if (extra && dest && (! dequote)) {
225
memcpy (dest + i, file + p - extra, extra);
229
if (dest && (! (isq && dequote)))
240
/* Add the NULL byte */
245
/* A trailing slash on the end of the file makes no sense. */
247
nih_error_raise (NIH_CONFIG_TRAILING_SLASH,
248
_(NIH_CONFIG_TRAILING_SLASH_STR));
253
/* Leaving quotes open is also generally bad. */
255
nih_error_raise (NIH_CONFIG_UNTERMINATED_QUOTE,
256
_(NIH_CONFIG_UNTERMINATED_QUOTE_STR));
262
/* The token length we return is the length of the token with any
263
* newlines and surrounding whitespace converted to a single
264
* character and any trailing whitespace removed.
266
* The actual end of the text read is returned in *pos.
269
*toklen = p - (pos ? *pos : 0) - ws - nlws - qc;
279
* nih_config_next_token:
280
* @parent: parent object for returned token,
281
* @file: file or string to parse,
282
* @len: length of @file,
283
* @pos: offset within @file,
284
* @lineno: line number,
285
* @delim: characters to stop on,
286
* @dequote: remove quotes and escapes.
288
* Extracts a single token from @file which is stopped when any character
289
* in @delim is encountered outside of a quoted string and not escaped
290
* using a backslash. If @delim contains any whitespace character, then
291
* all whitespace after the token is also consumed, but not returned,
292
* including that with escaped newlines within it.
294
* @file may be a memory mapped file, in which case @pos should be given
295
* as the offset within and @len should be the length of the file as a
298
* If @pos is given then it will be used as the offset within @file to
299
* begin (otherwise the start is assumed), and will be updated to point
300
* to @delim or past the end of the file.
302
* If @lineno is given it will be incremented each time a new line is
303
* discovered in the file.
305
* If you also want quotes to be removed and escaped characters to be
306
* replaced with the character itself, set @dequote to TRUE.
308
* If @parent is not NULL, it should be a pointer to another object which
309
* will be used as a parent for the returned token. When all parents
310
* of the returned token are freed, the returned token will also be
313
* Returns: the token found or NULL on raised error.
316
nih_config_next_token (const void *parent,
324
size_t p, arg_start, arg_len, arg_end;
327
nih_assert (file != NULL);
329
p = (pos ? *pos : 0);
331
if (nih_config_token (file, len, &p, lineno, NULL, delim, dequote,
337
nih_error_raise (NIH_CONFIG_EXPECTED_TOKEN,
338
_(NIH_CONFIG_EXPECTED_TOKEN_STR));
342
nih_config_skip_whitespace (file, len, &p, lineno);
344
/* Copy in the new token */
345
arg = nih_alloc (parent, arg_len + 1);
347
nih_return_system_error (NULL);
349
if (nih_config_token (file + arg_start, arg_end - arg_start, NULL,
350
NULL, arg, delim, dequote, NULL) < 0)
361
* nih_config_next_arg:
362
* @parent: parent object for returned argument,
363
* @file: file or string to parse,
364
* @len: length of @file,
365
* @pos: offset within @file,
366
* @lineno: line number.
368
* Extracts a single argument from @file, a dequoted token that is stopped
369
* on any comment, space or newline character that is not quoted or escaped
370
* with a backslash. Any whitespace after the argument is also consumed,
371
* but not returned, including that with escaped newlines within it.
373
* @file may be a memory mapped file, in which case @pos should be given
374
* as the offset within and @len should be the length of the file as a
377
* If @pos is given then it will be used as the offset within @file to
378
* begin (otherwise the start is assumed), and will be updated to point
379
* to @delim or past the end of the file.
381
* If @lineno is given it will be incremented each time a new line is
382
* discovered in the file.
384
* If @parent is not NULL, it should be a pointer to another object which
385
* will be used as a parent for the returned argument. When all parents
386
* of the returned argument are freed, the returned argument will also be
389
* Returns: the argument found or NULL on raised error.
392
nih_config_next_arg (const void *parent,
398
nih_assert (file != NULL);
400
return nih_config_next_token (parent, file, len, pos, lineno,
401
NIH_CONFIG_CNLWS, TRUE);
405
* nih_config_next_line:
406
* @file: file or string to parse,
407
* @len: length of @file,
408
* @pos: offset within @file,
409
* @lineno: line number.
411
* Skips to the end of the current line in @file, ignoring any tokens,
412
* comments, etc. along the way. If you want to ensure that no arguments
413
* are missed, use nih_config_skip_comment() instead.
415
* @file may be a memory mapped file, in which case @pos should be given
416
* as the offset within and @len should be the length of the file as a
419
* @pos is used as the offset within @file to begin, and will be updated
420
* to point to past the end of the line or file.
422
* If @lineno is given it will be incremented each time a new line is
423
* discovered in the file.
426
nih_config_next_line (const char *file,
431
nih_assert (file != NULL);
432
nih_assert (pos != NULL);
434
/* Spool forwards until the end of the line */
435
while ((*pos < len) && (file[*pos] != '\n'))
448
* nih_config_skip_whitespace:
449
* @file: file or string to parse,
450
* @len: length of @file,
451
* @pos: offset within @file,
452
* @lineno: line number.
454
* Skips an amount of whitespace and finds either the next token or the end
455
* of the current line in @file. Escaped newlines within the whitespace
456
* are treated as whitespace.
458
* @file may be a memory mapped file, in which case @pos should be given
459
* as the offset within and @len should be the length of the file as a
462
* @pos is used as the offset within @file to begin, and will be updated
463
* to point to past the end of the line or file.
465
* If @lineno is given it will be incremented each time a new line is
466
* discovered in the file.
469
nih_config_skip_whitespace (const char *file,
474
nih_assert (file != NULL);
475
nih_assert (pos != NULL);
477
/* Skip any amount of whitespace between them, we also need to
478
* detect an escaped newline here.
481
if (file[*pos] == '\\') {
482
/* Escape character, only continue scanning if
483
* the next character is newline
485
if ((len - *pos > 1) && (file[*pos + 1] == '\n')) {
490
} else if (! strchr (NIH_CONFIG_WS, file[*pos])) {
494
if (file[*pos] == '\n')
498
/* Whitespace characer */
504
* nih_config_skip_comment:
505
* @file: file or string to parse,
506
* @len: length of @file,
507
* @pos: offset within @file,
508
* @lineno: line number.
510
* Skips a comment and finds the end of the current line in @file. If the
511
* current position does not point to the end of a line, or a comment,
512
* then an error is raised.
514
* @file may be a memory mapped file, in which case @pos should be given
515
* as the offset within and @len should be the length of the file as a
518
* @pos is used as the offset within @file to begin, and will be updated
519
* to point to past the end of the line or file.
521
* If @lineno is given it will be incremented each time a new line is
522
* discovered in the file.
524
* Returns: zero on success, negative value on raised error.
527
nih_config_skip_comment (const char *file,
532
nih_assert (file != NULL);
533
nih_assert (pos != NULL);
535
if (nih_config_has_token (file, len, pos, lineno)) {
536
nih_error_raise (NIH_CONFIG_UNEXPECTED_TOKEN,
537
_(NIH_CONFIG_UNEXPECTED_TOKEN_STR));
541
nih_config_next_line (file, len, pos, lineno);
548
* nih_config_parse_args:
549
* @parent: parent object for returned array,
550
* @file: file or string to parse,
551
* @len: length of @file,
552
* @pos: offset within @file,
553
* @lineno: line number.
555
* Extracts a list of arguments from @file, each argument is separated
556
* by whitespace and parsing is stopped when a newline is encountered
557
* outside of a quoted string and not escaped using a backslash.
559
* @file may be a memory mapped file, in which case @pos should be given
560
* as the offset within and @len should be the length of the file as a
563
* If @pos is given then it will be used as the offset within @file to
564
* begin (otherwise the start is assumed), and will be updated to point
565
* past the end of the line or the end of the file.
567
* If @lineno is given it will be incremented each time a new line is
568
* discovered in the file.
570
* The arguments are returned as a NULL-terminated array, with each argument
571
* dequoted before being returned.
573
* If @parent is not NULL, it should be a pointer to another object which
574
* will be used as a parent for the returned array. When all parents
575
* of the returned array are freed, the returned array will also be
578
* Returns: the list of arguments found or NULL on raised error.
581
nih_config_parse_args (const void *parent,
590
nih_assert (file != NULL);
592
/* Begin with an empty array */
594
args = nih_str_array_new (parent);
596
nih_return_system_error (NULL);
598
/* Loop through the arguments until we hit a comment or newline */
599
p = (pos ? *pos : 0);
600
while (nih_config_has_token (file, len, &p, lineno)) {
603
arg = nih_config_next_arg (args, file, len, &p, lineno);
610
if (! nih_str_array_addp (&args, parent, &nargs, arg)) {
611
nih_error_raise_system ();
617
/* nih_config_has_token has returned FALSE, we must be either past
618
* the end of the file, or at a comment or newline.
620
if (nih_config_skip_comment (file, len, &p, lineno) < 0)
621
nih_assert_not_reached ();
631
* nih_config_parse_command:
632
* @parent: parent object for returned string,
633
* @file: file or string to parse,
634
* @len: length of @file,
635
* @pos: offset within @file,
636
* @lineno: line number,
638
* Extracts a command and its arguments from @file, stopping when a
639
* newline is encountered outside of a quoted string and not escaped
640
* using a blackslash.
642
* @file may be a memory mapped file, in which case @pos should be given
643
* as the offset within and @len should be the length of the file as a
646
* If @pos is given then it will be used as the offset within @file to
647
* begin (otherwise the start is assumed), and will be updated to point
648
* past the end of the line or the end of the file.
650
* If @lineno is given it will be incremented each time a new line is
651
* discovered in the file.
653
* The command is returned as a string allocated with nih_alloc().
655
* If @parent is not NULL, it should be a pointer to another object which
656
* will be used as a parent for the returned string. When all parents
657
* of the returned string are freed, the returned string will also be
660
* Returns: the command found or NULL on raised error.
663
nih_config_parse_command (const void *parent,
670
size_t p, cmd_start, cmd_len, cmd_end;
672
nih_assert (file != NULL);
674
/* Find the length of string up to the first unescaped comment
677
p = (pos ? *pos : 0);
679
if (nih_config_token (file, len, &p, lineno, NULL,
680
NIH_CONFIG_CNL, FALSE, &cmd_len) < 0)
685
/* nih_config_token will eat up to the end of the file, a comment
686
* or a newline; so this must always succeed.
688
if (nih_config_skip_comment (file, len, &p, lineno) < 0)
689
nih_assert_not_reached ();
691
/* Now copy the string into the destination. */
692
cmd = nih_alloc (parent, cmd_len + 1);
694
nih_return_system_error (NULL);
696
if (nih_config_token (file + cmd_start, cmd_end - cmd_start, NULL,
697
NULL, cmd, NIH_CONFIG_CNL, FALSE, NULL) < 0)
709
* nih_config_parse_block:
710
* @parent: parent object for returned string,
711
* @file: file or string to parse,
712
* @len: length of @file,
713
* @pos: offset within @file,
714
* @lineno: line number,
715
* @type: block identifier.
717
* Extracts a block of text from @line, stopping when the pharse "end @type"
718
* is encountered without any quotes or blackslash escaping within it.
720
* @file may be a memory mapped file, in which case @pos should be given
721
* as the offset within and @len should be the length of the file as a
724
* If @pos is given then it will be used as the offset within @file to
725
* begin (otherwise the start is assumed), and will be updated to point
726
* past the end of the block or the end of the file.
728
* Either @file or @pos should point to the start of the block, after the
729
* opening stanza, rather than the start of the stanza that opens it.
731
* If @lineno is given it will be incremented each time a new line is
732
* discovered in the file.
734
* The block is returned as a string allocated with nih_alloc().
736
* If @parent is not NULL, it should be a pointer to another object which
737
* will be used as a parent for the returned string. When all parents
738
* of the returned string are freed, the returned string will also be
741
* Returns: the text contained within the block or NULL on raised error.
744
nih_config_parse_block (const void *parent,
752
size_t p, pp, sh_start, sh_len, sh_end, ws;
755
nih_assert (file != NULL);
756
nih_assert (type != NULL);
758
/* We need to find the end of the block which is a line that looks
761
* WS? end WS @type CNLWS?
763
* Just to make things more difficult for ourselves, we work out the
764
* common whitespace on the start of the block lines and remember
765
* not to copy those out later
767
p = (pos ? *pos : 0);
773
while (! nih_config_block_end (file, len, &p, lineno, type, &sh_end)) {
780
/* Count whitespace on the first line */
781
while ((p < len) && strchr (NIH_CONFIG_WS, file[p]))
786
/* Compare how much whitespace matches the
787
* first line; and decrease the count if it's
790
while ((p < len) && (p - line_start < ws)
791
&& (file[sh_start + p - line_start] == file[p]))
794
if (p - line_start < ws)
798
nih_config_next_line (file, len, &p, lineno);
801
nih_error_raise (NIH_CONFIG_UNTERMINATED_BLOCK,
802
_(NIH_CONFIG_UNTERMINATED_BLOCK_STR));
807
/* Copy the fragment into a string, removing common whitespace from
808
* the start. We can be less strict here because we already know
811
sh_len = sh_end - sh_start - (ws * lines);
812
block = nih_alloc (parent, sh_len + 1);
814
nih_return_system_error (NULL);
819
while (pp < sh_end) {
825
while (file[pp++] != '\n')
828
strncat (block, file + line_start, pp - line_start);
839
* nih_config_skip_block:
840
* @file: file or string to parse,
841
* @len: length of @file,
842
* @pos: offset within @file,
843
* @lineno: line number,
844
* @type: block identifier,
845
* @endpos: pointer to end of block.
847
* Skips over a block of text from @file, stopping when the phrase
848
* "end @type" is encountered without any quotes or blackslash escaping
851
* @file may be a memory mapped file, in which case @pos should be given
852
* as the offset within and @len should be the length of the file as a
855
* If @pos is given then it will be used as the offset within @file to
856
* begin (otherwise the start is assumed), and will be updated to point
857
* past the end of the block and block marker or the end of the file.
859
* Either @file or @pos should point to the start of the block, after the
860
* opening stanza, rather than the start of the stanza that opens it.
862
* If @lineno is given it will be incremented each time a new line is
863
* discovered in the file.
865
* @endpos will be set to the end of the block and the start of the block
866
* marker, this is useful for determining the length of the block skipped,
867
* to parse it for example.
869
* Returns: zero on success, negative value on raised error.
872
nih_config_skip_block (const char *file,
882
nih_assert (file != NULL);
883
nih_assert (type != NULL);
885
p = (pos ? *pos : 0);
887
while (! nih_config_block_end (file, len, &p, lineno, type, endpos)) {
888
nih_config_next_line (file, len, &p, lineno);
891
nih_error_raise (NIH_CONFIG_UNTERMINATED_BLOCK,
892
_(NIH_CONFIG_UNTERMINATED_BLOCK_STR));
906
* nih_config_block_end:
907
* @file: file or string to parse,
908
* @len: length of @file,
909
* @pos: offset within @file,
910
* @lineno: line number,
911
* @type: block identifier,
912
* @endpos: pointer to end of block.
914
* Determines whether the current line contains an end of block marker,
915
* and if so, sets @endpos to the end of the block.
917
* @file may be a memory mapped file, in which case @pos should be given
918
* as the offset within and @len should be the length of the file. @pos
919
* will be updated to point past the end of the block and the end block
920
* marker or the end of the file.
922
* @lineno will be incremented each time a new line is discovered.
924
* Returns: TRUE if at the end of the block, FALSE otherwise.
927
nih_config_block_end (const char *file,
936
nih_assert (file != NULL);
937
nih_assert (pos != NULL);
938
nih_assert (type != NULL);
942
/* Skip initial whitespace */
943
while ((p < len) && strchr (NIH_CONFIG_WS, file[p]))
946
/* Check the first word (check we have at least 4 chars because of
947
* the need for whitespace immediately after)
949
if ((len - p < 4) || strncmp (file + p, "end", 3))
952
/* Must be whitespace after */
953
if (! strchr (NIH_CONFIG_WS, file[p + 3]))
956
/* Find the second word */
958
while ((p < len) && strchr (NIH_CONFIG_WS, file[p]))
961
/* Check the second word */
962
if ((len - p < strlen (type))
963
|| strncmp (file + p, type, strlen (type)))
966
/* May be followed by whitespace */
968
while ((p < len) && strchr (NIH_CONFIG_WS, file[p]))
971
/* May be a comment, in which case eat up to the newline
973
if ((p < len) && (file[p] == '#')) {
974
while ((p < len) && (file[p] != '\n'))
978
/* Should be end of string, or a newline */
979
if ((p < len) && (file[p] != '\n'))
982
/* Point past the new line */
989
/* Set endpos to the beginning of the line (which is the end of the
990
* script) but update pos to point past this line.
1001
* nih_config_get_stanza:
1002
* @name: name of stanza,
1003
* @stanzas: table of stanza handlers.
1005
* Locates the handler for the @name stanza in the @stanzas table. The
1006
* last entry in the table should have NULL for both the name and handler
1007
* function pointers.
1009
* If any entry exists with the stanza name "", this is returned instead
1010
* of NULL if no specific entry is found.
1012
* Returns: stanza found or NULL if no handler for @name.
1014
static NihConfigStanza *
1015
nih_config_get_stanza (const char *name,
1016
NihConfigStanza *stanzas)
1018
NihConfigStanza *stanza, *catch = NULL;
1020
for (stanza = stanzas; (stanza->name && stanza->handler); stanza++) {
1021
if (! strlen (stanza->name))
1024
if (! strcmp (stanza->name, name))
1032
* nih_config_parse_stanza:
1033
* @file: file or string to parse,
1034
* @len: length of @file,
1035
* @pos: offset within @file,
1036
* @lineno: line number,
1037
* @stanzas: table of stanza handlers,
1038
* @data: pointer to pass to stanza handler.
1040
* Extracts a configuration stanza from @file and calls the handler
1041
* function for that stanza found in the @stanzas table to handle the
1042
* rest of the line from thereon in.
1044
* @file may be a memory mapped file, in which case @pos should be given
1045
* as the offset within and @len should be the length of the file as a
1048
* If @pos is given then it will be used as the offset within @file to
1049
* begin (otherwise the start is assumed), and will be updated to point
1050
* to @delim or past the end of the file.
1052
* If @lineno is given it will be incremented each time a new line is
1053
* discovered in the file.
1055
* Returns: zero on success or negative value on raised error.
1058
nih_config_parse_stanza (const char *file,
1062
NihConfigStanza *stanzas,
1065
NihConfigStanza *stanza;
1066
nih_local char *name = NULL;
1070
nih_assert (file != NULL);
1071
nih_assert (stanzas != NULL);
1073
p = (pos ? *pos : 0);
1075
/* Get the next dequoted argument from the file */
1076
name = nih_config_next_token (NULL, file, len, &p, lineno,
1077
NIH_CONFIG_CNLWS, FALSE);
1081
/* Lookup the stanza for it */
1082
stanza = nih_config_get_stanza (name, stanzas);
1084
nih_return_error (-1, NIH_CONFIG_UNKNOWN_STANZA,
1085
_(NIH_CONFIG_UNKNOWN_STANZA_STR));
1087
ret = stanza->handler (data, stanza, file, len, &p, lineno);
1098
* nih_config_parse_file:
1099
* @file: file or string to parse,
1100
* @len: length of @file,
1101
* @pos: offset within @file,
1102
* @lineno: line number,
1103
* @stanzas: table of stanza handlers,
1104
* @data: pointer to pass to stanza handler.
1106
* Parses configuration file lines from @file, skipping initial whitespace,
1107
* blank lines and comments while calling nih_config_parse_stanza() for
1110
* @file may be a memory mapped file, in which case @pos should be given
1111
* as the offset within and @len should be the length of the file as a
1114
* If @pos is given then it will be used as the offset within @file to
1115
* begin (otherwise the start is assumed), and will be updated to point
1116
* to @delim or past the end of the file.
1118
* If @lineno is given it will be incremented each time a new line is
1119
* discovered in the file.
1121
* Returns: zero on success, negative value on raised error.
1124
nih_config_parse_file (const char *file,
1128
NihConfigStanza *stanzas,
1134
nih_assert (file != NULL);
1135
nih_assert (stanzas != NULL);
1137
p = (pos ? *pos : 0);
1140
/* Skip initial whitespace */
1141
while ((p < len) && strchr (NIH_CONFIG_WS, file[p]))
1144
/* Skip lines with only comments in them; because has_token
1145
* returns FALSE we know we're either past the end of the
1146
* file, at a comment, or a newline.
1148
if (! nih_config_has_token (file, len, &p, lineno)) {
1149
if (nih_config_skip_comment (file, len,
1151
nih_assert_not_reached ();
1156
/* Must have a stanza, parse it */
1157
if (nih_config_parse_stanza (file, len, &p, lineno,
1173
* @filename: name of file to parse,
1174
* @pos: offset within @file,
1175
* @lineno: line number,
1176
* @stanzas: table of stanza handlers,
1177
* @data: pointer to pass to stanza handler.
1179
* Reads @filename into memory and them parses configuration lines from it
1180
* using nih_config_parse_file().
1182
* If @pos is given then it will be used as the offset within @file to
1183
* begin (otherwise the start is assumed), and will be updated to point
1184
* to @delim or past the end of the file.
1186
* If @lineno is given it will be incremented each time a new line is
1187
* discovered in the file.
1189
* Returns: zero on success, negative value on raised error.
1192
nih_config_parse (const char *filename,
1195
NihConfigStanza *stanzas,
1198
nih_local char *file = NULL;
1202
nih_assert (filename != NULL);
1204
file = nih_file_read (NULL, filename, &len);
1211
ret = nih_config_parse_file (file, len, pos, lineno, stanzas, data);