1
=== modified file 'ChangeLog.nih'
2
--- ChangeLog.nih 2007-02-09 17:30:41 +0000
3
+++ ChangeLog.nih 2007-02-11 17:01:06 +0000
5
+2007-02-11 Johan Kiviniemi <johan@kiviniemi.name>
7
+ * nih/hash.h (NIH_HASH_FOREACH, NIH_HASH_FOREACH_SAFE): Added missing
8
+ parenthesis around hash, in case it's a complicated expression with
9
+ unsurprising precedence results.
11
+2007-02-11 Scott James Remnant <scott@netsplit.com>
13
+ * nih/config.c (nih_config_skip_whitespace): It turns out that when
14
+ parsing, it's often useful to skip any whitespace while retaining the
15
+ "step over newlines" behaviour. Seperate it out into its own
17
+ (nih_config_next_token): Call the new function.
18
+ * nih/config.h: Add prototype.
19
+ * nih/tests/test_config.c (test_skip_whitespace): Check the function
21
+ * nih/config.c: Remove macro definitions
22
+ * nih/config.h: and make them public instead
23
+ * nih/tests/test_config.c: Use macros.
25
+ * nih/config.c (nih_config_next_token): Strange hybrid function,
26
+ it behaves like next_arg() but accepts the same arguments as token();
27
+ it skips whitespace, but only if the initial whitespace character is
28
+ in the delim argument.
29
+ (nih_config_next_arg): This becomes a wrapper around next_token.
30
+ * nih/config.h: Add prototype.
31
+ * nih/tests/test_config.c (test_next_token): Check the new function.
33
+ * nih/config.c (nih_config_next_token): Rename to nih_config_token,
34
+ since this doesn't behave like the next_arg() function, and we want
35
+ a similar token function that behaves like that.
36
+ * nih/config.h: Update.
37
+ * nih/tests/test_config.c (test_next_token): Rename and update.
39
2007-02-09 Scott James Remnant <scott@netsplit.com>
41
* nih/hash.h (NIH_HASH_FOREACH_SAFE): Oops, s/list/hash/
43
=== modified file 'nih/config.c'
44
--- nih/config.c 2007-02-06 12:44:12 +0000
45
+++ nih/config.c 2007-02-11 16:28:57 +0000
47
#include <nih/errors.h>
53
- * Definition of what characters we consider whitespace.
60
- * Definition of what characters nominally end a line; a comment start
61
- * character or a newline.
68
- * Defintion of what characters nominally separate tokens.
70
-#define CNLWS " \t\r#\n"
74
/* Prototypes for static functions */
75
static ssize_t nih_config_block_end (const char *file, size_t len,
76
size_t *lineno, size_t *pos,
78
nih_assert (file != NULL);
81
- if ((p < len) && (! strchr (CNL, file[p]))) {
82
+ if ((p < len) && (! strchr (NIH_CONFIG_CNL, file[p]))) {
90
- * nih_config_next_token:
92
* @file: file or string to parse,
93
* @len: length of @file,
94
* @pos: offset within @file,
96
* @delim: characters to stop on,
97
* @dequote: remove quotes and escapes.
99
- * Extracts a single token from @file which is stopped when any character
100
+ * Parses a single token from @file which is stopped when any character
101
* in @delim is encountered outside of a quoted string and not escaped
104
@@ -154,13 +130,13 @@
105
* or negative value on raised error.
108
-nih_config_next_token (const char *file,
115
+nih_config_token (const char *file,
123
size_t p, ws = 0, nlws = 0, qc = 0, i = 0;
129
- } else if (strchr (WS, file[p])) {
130
+ } else if (strchr (NIH_CONFIG_WS, file[p])) {
136
} else if (strchr (delim, file[p])) {
138
- } else if (strchr (WS, file[p])) {
139
+ } else if (strchr (NIH_CONFIG_WS, file[p])) {
143
@@ -294,17 +270,20 @@
147
- * nih_config_next_arg:
148
+ * nih_config_next_token:
149
* @parent: parent of returned argument,
150
* @file: file or string to parse,
151
* @len: length of @file,
152
* @pos: offset within @file,
153
- * @lineno: line number.
154
+ * @lineno: line number,
155
+ * @delim: characters to stop on,
156
+ * @dequote: remove quotes and escapes.
158
- * Extracts a single argument from @file, a dequoted token that is stopped
159
- * on any comment, space or newline character that is not quoted or escaped
160
- * with a backslash. Any whitespace after the argument is also consumed,
161
- * but not returned, including that with escaped newlines within it.
162
+ * Extracts a single token from @file which is stopped when any character
163
+ * in @delim is encountered outside of a quoted string and not escaped
164
+ * using a backslash. If @delim contains any whitespace character, then
165
+ * all whitespace after the token is also consumed, but not returned,
166
+ * including that with escaped newlines within it.
168
* @file may be a memory mapped file, in which case @pos should be given
169
* as the offset within and @len should be the length of the file as a
170
@@ -317,20 +296,25 @@
171
* If @lineno is given it will be incremented each time a new line is
172
* discovered in the file.
174
+ * If you also want quotes to be removed and escaped characters to be
175
+ * replaced with the character itself, set @dequote to TRUE.
177
* If @parent is not NULL, it should be a pointer to another allocated
178
* block which will be used as the parent for this block. When @parent
179
* is freed, the returned block will be freed too. If you have clean-up
180
* that would need to be run, you can assign a destructor function using
181
* the nih_alloc_set_destructor() function.
183
- * Returns: the argument found or NULL on raised error.
184
+ * Returns: the token found or NULL on raised error.
187
-nih_config_next_arg (const void *parent,
192
+nih_config_next_token (const void *parent,
200
size_t p, arg_start, arg_end;
204
p = (pos ? *pos : 0);
206
- arg_len = nih_config_next_token (file, len, &p, lineno,
207
- NULL, CNLWS, TRUE);
208
+ arg_len = nih_config_token (file, len, &p, lineno,
209
+ NULL, delim, dequote);
213
@@ -352,38 +336,15 @@
217
- /* Skip any amount of whitespace between them, we also need to
218
- * detect an escaped newline here.
221
- if (file[p] == '\\') {
222
- /* Escape character, only continue scanning if
223
- * the next character is newline
225
- if ((len - p > 1) && (file[p + 1] == '\n')) {
230
- } else if (! strchr (WS, file[p])) {
234
- if (file[p] == '\n')
238
- /* Whitespace characer */
241
+ nih_config_skip_whitespace (file, len, &p, lineno);
243
/* Copy in the new token */
244
arg = nih_alloc (parent, arg_len + 1);
246
nih_return_system_error (NULL);
248
- if (nih_config_next_token (file + arg_start, arg_end - arg_start, NULL,
249
- NULL, arg, CNLWS, TRUE) < 0)
250
+ if (nih_config_token (file + arg_start, arg_end - arg_start, NULL,
251
+ NULL, arg, delim, dequote) < 0)
259
+ * nih_config_next_arg:
260
+ * @parent: parent of returned argument,
261
+ * @file: file or string to parse,
262
+ * @len: length of @file,
263
+ * @pos: offset within @file,
264
+ * @lineno: line number.
266
+ * Extracts a single argument from @file, a dequoted token that is stopped
267
+ * on any comment, space or newline character that is not quoted or escaped
268
+ * with a backslash. Any whitespace after the argument is also consumed,
269
+ * but not returned, including that with escaped newlines within it.
271
+ * @file may be a memory mapped file, in which case @pos should be given
272
+ * as the offset within and @len should be the length of the file as a
275
+ * If @pos is given then it will be used as the offset within @file to
276
+ * begin (otherwise the start is assumed), and will be updated to point
277
+ * to @delim or past the end of the file.
279
+ * If @lineno is given it will be incremented each time a new line is
280
+ * discovered in the file.
282
+ * If @parent is not NULL, it should be a pointer to another allocated
283
+ * block which will be used as the parent for this block. When @parent
284
+ * is freed, the returned block will be freed too. If you have clean-up
285
+ * that would need to be run, you can assign a destructor function using
286
+ * the nih_alloc_set_destructor() function.
288
+ * Returns: the argument found or NULL on raised error.
291
+nih_config_next_arg (const void *parent,
297
+ nih_assert (file != NULL);
299
+ return nih_config_next_token (parent, file, len, pos, lineno,
300
+ NIH_CONFIG_CNLWS, TRUE);
304
* nih_config_next_line:
305
* @file: file or string to parse,
306
* @len: length of @file,
313
+ * nih_config_skip_whitespace:
314
+ * @file: file or string to parse,
315
+ * @len: length of @file,
316
+ * @pos: offset within @file,
317
+ * @lineno: line number.
319
+ * Skips an amount of whitespace and finds either the next token or the end
320
+ * of the current line in @file. Escaped newlines within the whitespace
321
+ * are treated as whitespace.
323
+ * @file may be a memory mapped file, in which case @pos should be given
324
+ * as the offset within and @len should be the length of the file as a
327
+ * @pos is used as the offset within @file to begin, and will be updated
328
+ * to point to past the end of the line or file.
330
+ * If @lineno is given it will be incremented each time a new line is
331
+ * discovered in the file.
334
+nih_config_skip_whitespace (const char *file,
339
+ nih_assert (file != NULL);
340
+ nih_assert (pos != NULL);
342
+ /* Skip any amount of whitespace between them, we also need to
343
+ * detect an escaped newline here.
345
+ while (*pos < len) {
346
+ if (file[*pos] == '\\') {
347
+ /* Escape character, only continue scanning if
348
+ * the next character is newline
350
+ if ((len - *pos > 1) && (file[*pos + 1] == '\n')) {
355
+ } else if (! strchr (NIH_CONFIG_WS, file[*pos])) {
359
+ if (file[*pos] == '\n')
363
+ /* Whitespace characer */
369
* nih_config_skip_comment:
370
* @file: file or string to parse,
371
@@ -614,14 +677,14 @@
373
p = (pos ? *pos : 0);
375
- cmd_len = nih_config_next_token (file, len, &p, lineno,
377
+ cmd_len = nih_config_token (file, len, &p, lineno, NULL,
378
+ NIH_CONFIG_CNL, FALSE);
384
- /* nih_config_next_token will eat up to the end of the file, a comment
385
+ /* nih_config_token will eat up to the end of the file, a comment
386
* or a newline; so this must always succeed.
388
if (nih_config_skip_comment (file, len, &p, lineno) < 0)
391
nih_return_system_error (NULL);
393
- if (nih_config_next_token (file + cmd_start, cmd_end - cmd_start, NULL,
394
- NULL, cmd, CNL, FALSE) < 0)
395
+ if (nih_config_token (file + cmd_start, cmd_end - cmd_start, NULL,
396
+ NULL, cmd, NIH_CONFIG_CNL, FALSE) < 0)
403
/* Count initial whitespace */
404
- while ((p < len) && strchr (WS, file[p]))
405
+ while ((p < len) && strchr (NIH_CONFIG_WS, file[p]))
412
/* Skip initial whitespace */
413
- while ((p < len) && strchr (WS, file[p]))
414
+ while ((p < len) && strchr (NIH_CONFIG_WS, file[p]))
417
/* Check the first word (check we have at least 4 chars because of
418
@@ -823,12 +886,12 @@
421
/* Must be whitespace after */
422
- if (! strchr (WS, file[p + 3]))
423
+ if (! strchr (NIH_CONFIG_WS, file[p + 3]))
426
/* Find the second word */
428
- while ((p < len) && strchr (WS, file[p]))
429
+ while ((p < len) && strchr (NIH_CONFIG_WS, file[p]))
432
/* Check the second word */
435
/* May be followed by whitespace */
437
- while ((p < len) && strchr (WS, file[p]))
438
+ while ((p < len) && strchr (NIH_CONFIG_WS, file[p]))
441
/* May be a comment, in which case eat up to the newline
442
@@ -1017,7 +1080,7 @@
445
/* Skip initial whitespace */
446
- while ((p < len) && strchr (WS, file[p]))
447
+ while ((p < len) && strchr (NIH_CONFIG_WS, file[p]))
450
/* Skip lines with only comments in them; because has_token
452
=== modified file 'nih/config.h'
453
--- nih/config.h 2007-01-22 01:51:17 +0000
454
+++ nih/config.h 2007-02-11 16:35:38 +0000
456
#define NIH_CONFIG_LAST { NULL, NULL }
462
+ * Definition of what characters we consider whitespace.
464
+#define NIH_CONFIG_WS " \t\r"
469
+ * Definition of what characters nominally end a line; a comment start
470
+ * character or a newline.
472
+#define NIH_CONFIG_CNL "#\n"
475
+ * NIH_CONFIG_CNLWS:
477
+ * Defintion of what characters nominally separate tokens.
479
+#define NIH_CONFIG_CNLWS " \t\r#\n"
484
-int nih_config_has_token (const char *file, size_t len, size_t *pos,
487
-ssize_t nih_config_next_token (const char *file, size_t len, size_t *pos,
488
- size_t *lineno, char *dest,
489
- const char *delim, int dequote)
490
- __attribute__ ((warn_unused_result));
491
-char * nih_config_next_arg (const void *parent,
492
- const char *file, size_t len, size_t *pos,
494
- __attribute__ ((warn_unused_result, malloc));
495
-void nih_config_next_line (const char *file, size_t len, size_t *pos,
497
-int nih_config_skip_comment (const char *file, size_t len, size_t *pos,
499
- __attribute__ ((warn_unused_result));
501
-char ** nih_config_parse_args (const void *parent,
502
- const char *file, size_t len, size_t *pos,
504
- __attribute__ ((warn_unused_result, malloc));
505
-char * nih_config_parse_command (const void *parent,
506
- const char *file, size_t len, size_t *pos,
508
- __attribute__ ((warn_unused_result, malloc));
510
-char * nih_config_parse_block (const void *parent,
511
- const char *file, size_t len, size_t *pos,
512
- size_t *lineno, const char *type)
513
- __attribute__ ((warn_unused_result, malloc));
515
-int nih_config_parse_stanza (const char *file, size_t len, size_t *pos,
516
- size_t *lineno, NihConfigStanza *stanzas,
518
- __attribute__ ((warn_unused_result));
520
-int nih_config_parse_file (const char *file, size_t len, size_t *pos,
521
- size_t *lineno, NihConfigStanza *stanzas,
523
- __attribute__ ((warn_unused_result));
524
-int nih_config_parse (const char *filename,
525
- size_t *pos, size_t *lineno,
526
- NihConfigStanza *stanzas, void *data)
527
+int nih_config_has_token (const char *file, size_t len,
528
+ size_t *pos, size_t *lineno);
530
+ssize_t nih_config_token (const char *file, size_t len,
531
+ size_t *pos, size_t *lineno, char *dest,
532
+ const char *delim, int dequote)
533
+ __attribute__ ((warn_unused_result));
534
+char * nih_config_next_token (const void *parent, const char *file,
535
+ size_t len, size_t *pos, size_t *lineno,
536
+ const char *delim, int dequote)
537
+ __attribute__ ((warn_unused_result, malloc));
538
+char * nih_config_next_arg (const void *parent, const char *file,
539
+ size_t len, size_t *pos, size_t *lineno)
540
+ __attribute__ ((warn_unused_result, malloc));
541
+void nih_config_next_line (const char *file, size_t len,
542
+ size_t *pos, size_t *lineno);
544
+void nih_config_skip_whitespace (const char *file, size_t len,
545
+ size_t *pos, size_t *lineno);
546
+int nih_config_skip_comment (const char *file, size_t len,
547
+ size_t *pos, size_t *lineno)
548
+ __attribute__ ((warn_unused_result));
550
+char ** nih_config_parse_args (const void *parent, const char *file,
551
+ size_t len, size_t *pos, size_t *lineno)
552
+ __attribute__ ((warn_unused_result, malloc));
553
+char * nih_config_parse_command (const void *parent, const char *file,
554
+ size_t len, size_t *pos, size_t *lineno)
555
+ __attribute__ ((warn_unused_result, malloc));
557
+char * nih_config_parse_block (const void *parent, const char *file,
558
+ size_t len, size_t *pos, size_t *lineno,
560
+ __attribute__ ((warn_unused_result, malloc));
562
+int nih_config_parse_stanza (const char *file, size_t len,
563
+ size_t *pos, size_t *lineno,
564
+ NihConfigStanza *stanzas, void *data)
565
+ __attribute__ ((warn_unused_result));
567
+int nih_config_parse_file (const char *file, size_t len,
568
+ size_t *pos, size_t *lineno,
569
+ NihConfigStanza *stanzas, void *data)
570
+ __attribute__ ((warn_unused_result));
571
+int nih_config_parse (const char *filename, size_t *pos,
572
+ size_t *lineno, NihConfigStanza *stanzas,
574
__attribute__ ((warn_unused_result));
578
=== modified file 'nih/hash.c'
579
--- nih/hash.c 2007-02-09 16:46:45 +0000
580
+++ nih/hash.c 2007-02-11 00:28:30 +0000
583
* hash.c - Fuller/Noll/Vo hash table implementation
585
- * Copyright © 2006 Scott James Remnant <scott@netsplit.com>.
586
+ * Copyright © 2007 Scott James Remnant <scott@netsplit.com>.
588
* This program is free software; you can redistribute it and/or modify
589
* it under the terms of the GNU General Public License as published by
591
=== modified file 'nih/hash.h'
592
--- nih/hash.h 2007-02-09 17:30:41 +0000
593
+++ nih/hash.h 2007-02-11 17:00:37 +0000
595
* NIH_HASH_FOREACH_SAFE() instead.
597
#define NIH_HASH_FOREACH(hash, iter) \
598
- for (size_t _##iter##_i = 0; _##iter##_i < hash->size; _##iter##_i++) \
599
- NIH_LIST_FOREACH (&hash->bins[_##iter##_i], iter)
600
+ for (size_t _##iter##_i = 0; _##iter##_i < (hash)->size; \
602
+ NIH_LIST_FOREACH (&(hash)->bins[_##iter##_i], iter)
605
* NIH_HASH_FOREACH_SAFE:
607
* would need to use NIH_HASH_FOREACH() instead, as this would skip it.
609
#define NIH_HASH_FOREACH_SAFE(hash, iter) \
610
- for (size_t _##iter##_i = 0; _##iter##_i < hash->size; _##iter##_i++) \
611
- NIH_LIST_FOREACH_SAFE (&hash->bins[_##iter##_i], iter)
612
+ for (size_t _##iter##_i = 0; _##iter##_i < (hash)->size; \
614
+ NIH_LIST_FOREACH_SAFE (&(hash)->bins[_##iter##_i], iter)
619
=== modified file 'nih/tests/test_config.c'
620
--- nih/tests/test_config.c 2007-01-21 11:49:36 +0000
621
+++ nih/tests/test_config.c 2007-02-11 16:37:48 +0000
626
-test_next_token (void)
629
char buf[1024], dest[1024];
634
- TEST_FUNCTION ("nih_config_next_token");
635
+ TEST_FUNCTION ("nih_config_token");
636
program_name = "test";
638
/* Check that we can obtain the length of the first simple token
640
strcpy (buf, "this is a test");
643
- ret = nih_config_next_token (buf, strlen (buf), &pos, NULL,
645
+ ret = nih_config_token (buf, strlen (buf), &pos, NULL,
651
TEST_FEATURE ("with token filling string");
652
strcpy (buf, "wibble");
654
- ret = nih_config_next_token (buf, strlen (buf), &pos, NULL,
656
+ ret = nih_config_token (buf, strlen (buf), &pos, NULL,
663
TEST_FEATURE ("with token to extract");
664
strcpy (buf, "this is a test");
665
- ret = nih_config_next_token (buf, strlen (buf), NULL, NULL,
667
+ ret = nih_config_token (buf, strlen (buf), NULL, NULL,
671
TEST_EQ_STR (dest, "this");
674
TEST_FEATURE ("with token inside string");
676
- ret = nih_config_next_token (buf, strlen (buf), &pos, NULL,
678
+ ret = nih_config_token (buf, strlen (buf), &pos, NULL,
684
TEST_FEATURE ("with double quotes inside token");
685
strcpy (buf, "\"this is a\" test");
687
- ret = nih_config_next_token (buf, strlen (buf), &pos, NULL,
689
+ ret = nih_config_token (buf, strlen (buf), &pos, NULL,
695
* quotes, we should still get those.
697
TEST_FEATURE ("with double quotes around token to extract");
698
- ret = nih_config_next_token (buf, strlen (buf), NULL, NULL,
700
+ ret = nih_config_token (buf, strlen (buf), NULL, NULL,
704
TEST_EQ_STR (dest, "\"this is a\"");
707
TEST_FEATURE ("with double quotes and dequoting");
709
- ret = nih_config_next_token (buf, strlen (buf), &pos, NULL,
711
+ ret = nih_config_token (buf, strlen (buf), &pos, NULL,
719
TEST_FEATURE ("with double quotes and extract with dequoting");
720
- ret = nih_config_next_token (buf, strlen (buf), NULL, NULL,
722
+ ret = nih_config_token (buf, strlen (buf), NULL, NULL,
726
TEST_EQ_STR (dest, "this is a");
728
TEST_FEATURE ("with single quotes inside token");
729
strcpy (buf, "\'this is a\' test");
731
- ret = nih_config_next_token (buf, strlen (buf), &pos, NULL,
733
+ ret = nih_config_token (buf, strlen (buf), &pos, NULL,
739
TEST_FEATURE ("with escaped spaces inside token");
740
strcpy (buf, "this\\ is\\ a test");
742
- ret = nih_config_next_token (buf, strlen (buf), &pos, NULL,
744
+ ret = nih_config_token (buf, strlen (buf), &pos, NULL,
750
* around the delimiter.
752
TEST_FEATURE ("with escaped spaces within extracted token");
753
- ret = nih_config_next_token (buf, strlen (buf), NULL, NULL,
755
+ ret = nih_config_token (buf, strlen (buf), NULL, NULL,
759
TEST_EQ_STR (dest, "this\\ is\\ a");
762
TEST_FEATURE ("with escaped spaces inside token and dequoting");
764
- ret = nih_config_next_token (buf, strlen (buf), &pos, NULL,
766
+ ret = nih_config_token (buf, strlen (buf), &pos, NULL,
772
* around the delimiter, while removing them.
774
TEST_FEATURE ("with escaped spaces within extracted dequoted token");
775
- ret = nih_config_next_token (buf, strlen (buf), NULL, NULL,
777
+ ret = nih_config_token (buf, strlen (buf), NULL, NULL,
781
TEST_EQ_STR (dest, "this is a");
783
strcpy (buf, "\"this is \n a\" test");
786
- ret = nih_config_next_token (buf, strlen (buf), &pos, &lineno,
788
+ ret = nih_config_token (buf, strlen (buf), &pos, &lineno,
794
* string only returns a single space for the newline.
796
TEST_FEATURE ("with newline inside extracted quoted string");
797
- ret = nih_config_next_token (buf, strlen (buf), NULL, NULL,
799
+ ret = nih_config_token (buf, strlen (buf), NULL, NULL,
803
TEST_EQ_STR (dest, "\"this is a\"");
805
TEST_FEATURE ("with newline inside quoted string and lineno set");
808
- ret = nih_config_next_token (buf, strlen (buf), &pos, &lineno,
810
+ ret = nih_config_token (buf, strlen (buf), &pos, &lineno,
816
strcpy (buf, "this \\\n is a:test");
819
- ret = nih_config_next_token (buf, strlen (buf), &pos, &lineno,
821
+ ret = nih_config_token (buf, strlen (buf), &pos, &lineno,
827
* returns a single space for the newline.
829
TEST_FEATURE ("with escaped newline inside extracted string");
830
- ret = nih_config_next_token (buf, strlen (buf), NULL, NULL,
832
+ ret = nih_config_token (buf, strlen (buf), NULL, NULL,
836
TEST_EQ_STR (dest, "this is a");
838
TEST_FEATURE ("with escaped newline inside string and lineno set");
841
- ret = nih_config_next_token (buf, strlen (buf), &pos, &lineno,
843
+ ret = nih_config_token (buf, strlen (buf), &pos, &lineno,
852
- ret = nih_config_next_token (buf, strlen (buf), &pos, &lineno,
854
+ ret = nih_config_token (buf, strlen (buf), &pos, &lineno,
863
- ret = nih_config_next_token (buf, strlen (buf), &pos, &lineno,
865
+ ret = nih_config_token (buf, strlen (buf), &pos, &lineno,
870
@@ -397,14 +397,281 @@
871
TEST_FEATURE ("with empty token");
872
strcpy (buf, " wibble");
874
- ret = nih_config_next_token (buf, strlen (buf), &pos, NULL,
876
+ ret = nih_config_token (buf, strlen (buf), &pos, NULL,
884
+test_next_token (void)
888
+ size_t pos, lineno;
891
+ TEST_FUNCTION ("nih_config_next_token");
893
+ /* Check that we can extract a token at the start of a string,
894
+ * and have the position pointing past the whitespace to the next
897
+ TEST_FEATURE ("with token at start of string");
899
+ strcpy (buf, "this is a test");
902
+ str = nih_config_next_token (NULL, buf,
903
+ strlen (buf), &pos, NULL,
904
+ NIH_CONFIG_CNLWS, FALSE);
906
+ if (test_alloc_failed) {
907
+ TEST_EQ_P (str, NULL);
910
+ err = nih_error_get ();
911
+ TEST_EQ (err->number, ENOMEM);
917
+ TEST_ALLOC_SIZE (str, 5);
918
+ TEST_EQ_STR (str, "this");
924
+ /* Check that we can extract an argument inside a string
926
+ TEST_FEATURE ("with token inside string");
928
+ strcpy (buf, "this is a test");
931
+ str = nih_config_next_token (NULL, buf,
932
+ strlen (buf), &pos, NULL,
933
+ NIH_CONFIG_CNLWS, FALSE);
935
+ if (test_alloc_failed) {
936
+ TEST_EQ_P (str, NULL);
939
+ err = nih_error_get ();
940
+ TEST_EQ (err->number, ENOMEM);
946
+ TEST_ALLOC_SIZE (str, 3);
947
+ TEST_EQ_STR (str, "is");
953
+ /* Check that all trailing whitespace is eaten after the token. */
954
+ TEST_FEATURE ("with consecutive whitespace after token");
956
+ strcpy (buf, "this \t is a test");
959
+ str = nih_config_next_token (NULL, buf,
960
+ strlen (buf), &pos, NULL,
961
+ NIH_CONFIG_CNLWS, FALSE);
963
+ if (test_alloc_failed) {
964
+ TEST_EQ_P (str, NULL);
967
+ err = nih_error_get ();
968
+ TEST_EQ (err->number, ENOMEM);
974
+ TEST_ALLOC_SIZE (str, 5);
975
+ TEST_EQ_STR (str, "this");
981
+ /* Check that any escaped newlines in the whitespace are skipped
984
+ TEST_FEATURE ("with escaped newlines in whitespace");
986
+ strcpy (buf, "this \\\n is a test");
989
+ str = nih_config_next_token (NULL, buf,
990
+ strlen (buf), &pos, NULL,
991
+ NIH_CONFIG_CNLWS, FALSE);
993
+ if (test_alloc_failed) {
994
+ TEST_EQ_P (str, NULL);
997
+ err = nih_error_get ();
998
+ TEST_EQ (err->number, ENOMEM);
1004
+ TEST_ALLOC_SIZE (str, 5);
1005
+ TEST_EQ_STR (str, "this");
1011
+ /* Check that the line number is incremented for any escaped newlines
1012
+ * in the whitespace.
1014
+ TEST_FEATURE ("with line number set");
1019
+ str = nih_config_next_token (NULL, buf,
1020
+ strlen (buf), &pos, &lineno,
1021
+ NIH_CONFIG_CNLWS, FALSE);
1023
+ if (test_alloc_failed) {
1024
+ TEST_EQ_P (str, NULL);
1026
+ TEST_EQ (lineno, 2);
1028
+ err = nih_error_get ();
1029
+ TEST_EQ (err->number, ENOMEM);
1035
+ TEST_EQ (lineno, 2);
1036
+ TEST_ALLOC_SIZE (str, 5);
1037
+ TEST_EQ_STR (str, "this");
1043
+ /* Check that the returned token can have the quotes left in it,
1044
+ * but the whitespace around the newline collapsed.
1046
+ TEST_FEATURE ("with token containing quotes");
1048
+ strcpy (buf, "\"this \\\n is\" a test");
1051
+ str = nih_config_next_token (NULL, buf,
1052
+ strlen (buf), &pos, NULL,
1053
+ NIH_CONFIG_CNLWS, FALSE);
1055
+ if (test_alloc_failed) {
1056
+ TEST_EQ_P (str, NULL);
1059
+ err = nih_error_get ();
1060
+ TEST_EQ (err->number, ENOMEM);
1065
+ TEST_EQ (pos, 13);
1066
+ TEST_ALLOC_SIZE (str, 10);
1067
+ TEST_EQ_STR (str, "\"this is\"");
1073
+ /* Check that the returned token can be thoroughly dequoted and any
1074
+ * whitespace around an embedded newline collapsed to a single
1077
+ TEST_FEATURE ("with quoted whitespace and newline in token");
1079
+ strcpy (buf, "\"this \\\n is\" a test");
1082
+ str = nih_config_next_token (NULL, buf,
1083
+ strlen (buf), &pos, NULL,
1084
+ NIH_CONFIG_CNLWS, TRUE);
1086
+ if (test_alloc_failed) {
1087
+ TEST_EQ_P (str, NULL);
1090
+ err = nih_error_get ();
1091
+ TEST_EQ (err->number, ENOMEM);
1096
+ TEST_EQ (pos, 13);
1097
+ TEST_ALLOC_SIZE (str, 8);
1098
+ TEST_EQ_STR (str, "this is");
1104
+ /* Check that an error is raised if there is no token at that
1107
+ TEST_FEATURE ("with empty line");
1109
+ strcpy (buf, "\nthis is a test");
1113
+ str = nih_config_next_token (NULL, buf,
1114
+ strlen (buf), &pos, &lineno,
1115
+ NIH_CONFIG_CNLWS, FALSE);
1117
+ TEST_EQ_P (str, NULL);
1119
+ TEST_EQ (lineno, 1);
1121
+ err = nih_error_get ();
1122
+ TEST_EQ (err->number, NIH_CONFIG_EXPECTED_TOKEN);
1127
+ /* Check that a parse error being found with the argument causes an
1128
+ * error to be raised, with pos and lineno at the site of the error.
1130
+ TEST_FEATURE ("with parser error");
1132
+ strcpy (buf, "\"this is a test\nand so is this");
1136
+ str = nih_config_next_token (NULL, buf,
1137
+ strlen (buf), &pos, &lineno,
1138
+ NIH_CONFIG_CNLWS, FALSE);
1140
+ TEST_EQ_P (str, NULL);
1141
+ TEST_EQ (pos, 30);
1142
+ TEST_EQ (lineno, 2);
1144
+ err = nih_error_get ();
1145
+ TEST_EQ (err->number, NIH_CONFIG_UNTERMINATED_QUOTE);
1151
test_next_arg (void)
1154
@@ -691,6 +958,70 @@
1158
+test_skip_whitespace (void)
1161
+ size_t pos, lineno;
1163
+ TEST_FUNCTION ("nih_config_next_whitespace");
1165
+ /* Check that we can skip an amount of plain whitespace characters
1166
+ * until the next token, pointing pos at is.
1168
+ TEST_FEATURE ("with plain whitespace");
1169
+ strcpy (buf, "a plain string\n");
1173
+ nih_config_skip_whitespace (buf, strlen (buf), &pos, &lineno);
1176
+ TEST_EQ (lineno, 1);
1179
+ /* Check that we can skip a more complex series of whitespace
1180
+ * characters until the next token.
1182
+ TEST_FEATURE ("with complex whitespace");
1183
+ strcpy (buf, "a more \t \r complex string\n");
1187
+ nih_config_skip_whitespace (buf, strlen (buf), &pos, &lineno);
1189
+ TEST_EQ (pos, 15);
1190
+ TEST_EQ (lineno, 1);
1193
+ /* Check that we can skip whitespace characters up until the end
1194
+ * of the line, but that we don't step over it.
1196
+ TEST_FEATURE ("with whitespace at end of line");
1197
+ strcpy (buf, "trailing whitespace \t\r\n");
1201
+ nih_config_skip_whitespace (buf, strlen (buf), &pos, &lineno);
1203
+ TEST_EQ (pos, 23);
1204
+ TEST_EQ (lineno, 1);
1207
+ /* Check that we step over an escaped newline embedded in the
1208
+ * whitespace, and increment lineno.
1210
+ TEST_FEATURE ("with escaped newline");
1211
+ strcpy (buf, "this has \\\n a newline");
1215
+ nih_config_skip_whitespace (buf, strlen (buf), &pos, &lineno);
1217
+ TEST_EQ (pos, 12);
1218
+ TEST_EQ (lineno, 2);
1222
test_skip_comment (void)
1225
@@ -2306,9 +2637,11 @@
1233
+ test_skip_whitespace ();
1234
test_skip_comment ();
1236
test_parse_command ();