~jamesodhunt/ubuntu/raring/upstart/1.6

« back to all changes in this revision

Viewing changes to nih/tests/test_config.c

  • Committer: Scott James Remnant
  • Date: 2010-02-04 23:39:59 UTC
  • mfrom: (1182.1.45 upstart)
  • mto: This revision was merged to the branch mainline in revision 1250.
  • Revision ID: scott@netsplit.com-20100204233959-7kajqjnaoh7208ob
Tags: upstream-0.6.5
ImportĀ upstreamĀ versionĀ 0.6.5

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* libnih
2
 
 *
3
 
 * test_config.c - test suite for nih/config.c
4
 
 *
5
 
 * Copyright Ā© 2009 Scott James Remnant <scott@netsplit.com>.
6
 
 * Copyright Ā© 2009 Canonical Ltd.
7
 
 *
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.
11
 
 *
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.
16
 
 *
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.
20
 
 */
21
 
 
22
 
#include <nih/test.h>
23
 
 
24
 
#include <errno.h>
25
 
#include <limits.h>
26
 
#include <unistd.h>
27
 
 
28
 
#include <nih/macros.h>
29
 
#include <nih/alloc.h>
30
 
#include <nih/config.h>
31
 
#include <nih/main.h>
32
 
#include <nih/error.h>
33
 
#include <nih/errors.h>
34
 
 
35
 
 
36
 
void
37
 
test_has_token (void)
38
 
{
39
 
        char   buf[1024];
40
 
        size_t pos;
41
 
        int    ret;
42
 
 
43
 
        TEST_FUNCTION ("nih_config_has_token");
44
 
        strcpy (buf, "this is a test # comment\n");
45
 
 
46
 
        /* Check that an ordinary token character at the start of the line
47
 
         * causes the function to return TRUE.
48
 
         */
49
 
        TEST_FEATURE ("with token at start of string");
50
 
        ret = nih_config_has_token (buf, strlen (buf), NULL, NULL);
51
 
 
52
 
        TEST_TRUE (ret);
53
 
 
54
 
 
55
 
        /* Check that an ordinary token inside the string causes the function
56
 
         * to return TRUE.
57
 
         */
58
 
        TEST_FEATURE ("with token inside string");
59
 
        pos = 5;
60
 
        ret = nih_config_has_token (buf, strlen (buf), &pos, NULL);
61
 
 
62
 
        TEST_TRUE (ret);
63
 
 
64
 
 
65
 
        /* Check that a piece of whitespace causes the function to return TRUE.
66
 
         */
67
 
        TEST_FEATURE ("with whitespace");
68
 
        pos = 7;
69
 
        ret = nih_config_has_token (buf, strlen (buf), &pos, NULL);
70
 
 
71
 
        TEST_TRUE (ret);
72
 
 
73
 
 
74
 
        /* Check that a comment character causes the function to return FALSE.
75
 
         */
76
 
        TEST_FEATURE ("with start of comment");
77
 
        pos = 15;
78
 
        ret = nih_config_has_token (buf, strlen (buf), &pos, NULL);
79
 
 
80
 
        TEST_FALSE (ret);
81
 
 
82
 
 
83
 
        /* Check that a newline character causes the function to return FALSE.
84
 
         */
85
 
        TEST_FEATURE ("with newline");
86
 
        pos = 24;
87
 
        ret = nih_config_has_token (buf, strlen (buf), &pos, NULL);
88
 
 
89
 
        TEST_FALSE (ret);
90
 
 
91
 
 
92
 
        /* Check that the end of file causes the function to return FALSE.
93
 
         */
94
 
        TEST_FEATURE ("at end of file");
95
 
        pos = 25;
96
 
        ret = nih_config_has_token (buf, strlen (buf), &pos, NULL);
97
 
 
98
 
        TEST_FALSE (ret);
99
 
}
100
 
 
101
 
 
102
 
void
103
 
test_token (void)
104
 
{
105
 
        char      buf[1024], dest[1024];
106
 
        size_t    pos, lineno, len;
107
 
        int       ret;
108
 
        NihError *err;
109
 
 
110
 
        TEST_FUNCTION ("nih_config_token");
111
 
        program_name = "test";
112
 
 
113
 
        /* Check that we can obtain the length of the first simple token
114
 
         * in a string, and that the position is updated past it.  The
115
 
         * length of the token should be returned.
116
 
         */
117
 
        TEST_FEATURE ("with token at start of string");
118
 
        strcpy (buf, "this is a test");
119
 
        pos = 0;
120
 
 
121
 
        len = 0;
122
 
        ret = nih_config_token (buf, strlen (buf), &pos, NULL,
123
 
                                NULL, " ", FALSE, &len);
124
 
 
125
 
        TEST_EQ (ret, 0);
126
 
        TEST_EQ (len, 4);
127
 
        TEST_EQ (pos, 4);
128
 
 
129
 
 
130
 
        /* Check that we can obtain a length of a token that entirely fills
131
 
         * the remainder of the file.
132
 
         */
133
 
        TEST_FEATURE ("with token filling string");
134
 
        strcpy (buf, "wibble");
135
 
        pos = 0;
136
 
        len = 0;
137
 
        ret = nih_config_token (buf, strlen (buf), &pos, NULL,
138
 
                                NULL, " ", FALSE, &len);
139
 
 
140
 
        TEST_EQ (ret, 0);
141
 
        TEST_EQ (len, 6);
142
 
        TEST_EQ (pos, 6);
143
 
 
144
 
 
145
 
        /* Check that we can extract a token from the string and have it
146
 
         * copied into our destination buffer.
147
 
         */
148
 
        TEST_FEATURE ("with token to extract");
149
 
        strcpy (buf, "this is a test");
150
 
        ret = nih_config_token (buf, strlen (buf), NULL, NULL,
151
 
                                dest, " ", FALSE, NULL);
152
 
 
153
 
        TEST_EQ (ret, 0);
154
 
        TEST_EQ_STR (dest, "this");
155
 
 
156
 
 
157
 
        /* Check that we can obtain the length of a simple token inside the
158
 
         * string, and the the position is updated past it.
159
 
         */
160
 
        TEST_FEATURE ("with token inside string");
161
 
        pos = 5;
162
 
        len = 0;
163
 
        ret = nih_config_token (buf, strlen (buf), &pos, NULL,
164
 
                                NULL, " ", FALSE, &len);
165
 
 
166
 
        TEST_EQ (ret, 0);
167
 
        TEST_EQ (len, 2);
168
 
        TEST_EQ (pos, 7);
169
 
 
170
 
 
171
 
        /* Check that we can obtain the length of a token that contains
172
 
         * double quotes around the delimeter, the length should include
173
 
         * the quoted part at the quotes.
174
 
         */
175
 
        TEST_FEATURE ("with double quotes inside token");
176
 
        strcpy (buf, "\"this is a\" test");
177
 
        pos = 0;
178
 
        len = 0;
179
 
        ret = nih_config_token (buf, strlen (buf), &pos, NULL,
180
 
                                NULL, " ", FALSE, &len);
181
 
 
182
 
        TEST_EQ (ret, 0);
183
 
        TEST_EQ (len, 11);
184
 
        TEST_EQ (pos, 11);
185
 
 
186
 
 
187
 
        /* Check that we can extract a token that is surrounded by double
188
 
         * quotes, we should still get those.
189
 
         */
190
 
        TEST_FEATURE ("with double quotes around token to extract");
191
 
        len = 0;
192
 
        ret = nih_config_token (buf, strlen (buf), NULL, NULL,
193
 
                                dest, " ", FALSE, &len);
194
 
 
195
 
        TEST_EQ (ret, 0);
196
 
        TEST_EQ (len, 11);
197
 
        TEST_EQ_STR (dest, "\"this is a\"");
198
 
 
199
 
 
200
 
        /* Check that we can obtain the length of the quoted portion, with
201
 
         * the quotes removed; the position should still point past it.
202
 
         */
203
 
        TEST_FEATURE ("with double quotes and dequoting");
204
 
        pos = 0;
205
 
        len = 0;
206
 
        ret = nih_config_token (buf, strlen (buf), &pos, NULL,
207
 
                                NULL, " ", TRUE, &len);
208
 
 
209
 
        TEST_EQ (ret, 0);
210
 
        TEST_EQ (len, 9);
211
 
        TEST_EQ (pos, 11);
212
 
 
213
 
 
214
 
        /* Check that we can extract a quoted token and have the quotes
215
 
         * removed.
216
 
         */
217
 
        TEST_FEATURE ("with double quotes and extract with dequoting");
218
 
        ret = nih_config_token (buf, strlen (buf), NULL, NULL,
219
 
                                dest, " ", TRUE, NULL);
220
 
 
221
 
        TEST_EQ (ret, 0);
222
 
        TEST_EQ_STR (dest, "this is a");
223
 
 
224
 
 
225
 
        /* Check that we can obtain the length of a token that contains
226
 
         * single quotes around the delimeter, the length should include
227
 
         * the quoted part at the quotes.
228
 
         */
229
 
        TEST_FEATURE ("with single quotes inside token");
230
 
        strcpy (buf, "\'this is a\' test");
231
 
        pos = 0;
232
 
        len = 0;
233
 
        ret = nih_config_token (buf, strlen (buf), &pos, NULL,
234
 
                                NULL, " ", FALSE, &len);
235
 
 
236
 
        TEST_EQ (ret, 0);
237
 
        TEST_EQ (len, 11);
238
 
        TEST_EQ (pos, 11);
239
 
 
240
 
 
241
 
        /* Check that we can obtain the length of a token that contains
242
 
         * escaped spaces around the delimeter, the length should include
243
 
         * the backslashes.
244
 
         */
245
 
        TEST_FEATURE ("with escaped spaces inside token");
246
 
        strcpy (buf, "this\\ is\\ a test");
247
 
        pos = 0;
248
 
        len = 0;
249
 
        ret = nih_config_token (buf, strlen (buf), &pos, NULL,
250
 
                                NULL, " ", FALSE, &len);
251
 
 
252
 
        TEST_EQ (ret, 0);
253
 
        TEST_EQ (len, 11);
254
 
        TEST_EQ (pos, 11);
255
 
 
256
 
 
257
 
        /* Check that we can extract a token that contains escaped spaces
258
 
         * around the delimiter.
259
 
         */
260
 
        TEST_FEATURE ("with escaped spaces within extracted token");
261
 
        ret = nih_config_token (buf, strlen (buf), NULL, NULL,
262
 
                                dest, " ", FALSE, &len);
263
 
 
264
 
        TEST_EQ (ret, 0);
265
 
        TEST_EQ (len, 11);
266
 
        TEST_EQ_STR (dest, "this\\ is\\ a");
267
 
 
268
 
 
269
 
        /* Check that we can obtain the length of a token that contains
270
 
         * escaped spaces around the delimeter, without the blackslashes.
271
 
         */
272
 
        TEST_FEATURE ("with escaped spaces inside token and dequoting");
273
 
        pos = 0;
274
 
        len = 0;
275
 
        ret = nih_config_token (buf, strlen (buf), &pos, NULL,
276
 
                                NULL, " ", TRUE, &len);
277
 
 
278
 
        TEST_EQ (ret, 0);
279
 
        TEST_EQ (len, 9);
280
 
        TEST_EQ (pos, 11);
281
 
 
282
 
 
283
 
        /* Check that we can extract a token that contains escaped spaces
284
 
         * around the delimiter, while removing them.
285
 
         */
286
 
        TEST_FEATURE ("with escaped spaces within extracted dequoted token");
287
 
        len = 0;
288
 
        ret = nih_config_token (buf, strlen (buf), NULL, NULL,
289
 
                                dest, " ", TRUE, &len);
290
 
 
291
 
        TEST_EQ (ret, 0);
292
 
        TEST_EQ (len, 9);
293
 
        TEST_EQ_STR (dest, "this is a");
294
 
 
295
 
 
296
 
        /* Check that a newline inside a quoted string, and surrounding
297
 
         * whitespace, is treated as a single space character.
298
 
         */
299
 
        TEST_FEATURE ("with newline inside quoted string");
300
 
        strcpy (buf, "\"this is \n a\" test");
301
 
        pos = 0;
302
 
        lineno = 1;
303
 
        len = 0;
304
 
        ret = nih_config_token (buf, strlen (buf), &pos, &lineno,
305
 
                                NULL, " ", FALSE, &len);
306
 
 
307
 
        TEST_EQ (ret, 0);
308
 
        TEST_EQ (len, 11);
309
 
        TEST_EQ (pos, 13);
310
 
        TEST_EQ (lineno, 2);
311
 
 
312
 
 
313
 
        /* Check that extracting a token with a newline inside a quoted
314
 
         * string only returns a single space for the newline.
315
 
         */
316
 
        TEST_FEATURE ("with newline inside extracted quoted string");
317
 
        len = 0;
318
 
        ret = nih_config_token (buf, strlen (buf), NULL, NULL,
319
 
                                dest, " ", FALSE, &len);
320
 
 
321
 
        TEST_EQ (ret, 0);
322
 
        TEST_EQ (len, 11);
323
 
        TEST_EQ_STR (dest, "\"this is a\"");
324
 
 
325
 
 
326
 
        /* Check that lineno is incremented when we encounter a newline
327
 
         * inside a quoted string.
328
 
         */
329
 
        TEST_FEATURE ("with newline inside quoted string and lineno set");
330
 
        pos = 0;
331
 
        lineno = 1;
332
 
        len = 0;
333
 
        ret = nih_config_token (buf, strlen (buf), &pos, &lineno,
334
 
                                NULL, " ", FALSE, &len);
335
 
 
336
 
        TEST_EQ (ret, 0);
337
 
        TEST_EQ (len, 11);
338
 
        TEST_EQ (pos, 13);
339
 
        TEST_EQ (lineno, 2);
340
 
 
341
 
 
342
 
        /* Check that an escaped newline, and surrounding whitespace, is
343
 
         * treated as a single space character.
344
 
         */
345
 
        TEST_FEATURE ("with escaped newline");
346
 
        strcpy (buf, "this \\\n is a:test");
347
 
        pos = 0;
348
 
        lineno = 1;
349
 
        len = 0;
350
 
        ret = nih_config_token (buf, strlen (buf), &pos, &lineno,
351
 
                                NULL, ":", FALSE, &len);
352
 
 
353
 
        TEST_EQ (ret, 0);
354
 
        TEST_EQ (len, 9);
355
 
        TEST_EQ (pos, 12);
356
 
        TEST_EQ (lineno, 2);
357
 
 
358
 
 
359
 
        /* Check that extracting a token with an escaped newline inside it only
360
 
         * returns a single space for the newline.
361
 
         */
362
 
        TEST_FEATURE ("with escaped newline inside extracted string");
363
 
        ret = nih_config_token (buf, strlen (buf), NULL, NULL,
364
 
                                dest, ":", FALSE, NULL);
365
 
 
366
 
        TEST_EQ (ret, 0);
367
 
        TEST_EQ_STR (dest, "this is a");
368
 
 
369
 
 
370
 
        /* Check that lineno is incremented when we encounter an escaped
371
 
         * newline
372
 
         */
373
 
        TEST_FEATURE ("with escaped newline inside string and lineno set");
374
 
        pos = 0;
375
 
        lineno = 1;
376
 
        len = 0;
377
 
        ret = nih_config_token (buf, strlen (buf), &pos, &lineno,
378
 
                                NULL, ":", FALSE, &len);
379
 
 
380
 
        TEST_EQ (ret, 0);
381
 
        TEST_EQ (len, 9);
382
 
        TEST_EQ (pos, 12);
383
 
        TEST_EQ (lineno, 2);
384
 
 
385
 
 
386
 
        /* Check that we can obtain the length of a token that contains
387
 
         * escaped characters, the length should include the backslashes.
388
 
         */
389
 
        TEST_FEATURE ("with escaped characters inside token");
390
 
        strcpy (buf, "this\\$FOO");
391
 
        pos = 0;
392
 
        len = 0;
393
 
        ret = nih_config_token (buf, strlen (buf), &pos, NULL,
394
 
                                NULL, " ", FALSE, &len);
395
 
 
396
 
        TEST_EQ (ret, 0);
397
 
        TEST_EQ (len, 9);
398
 
        TEST_EQ (pos, 9);
399
 
 
400
 
 
401
 
        /* Check that we can extract a token that contains escaped
402
 
         * characters.
403
 
         */
404
 
        TEST_FEATURE ("with escaped characters within extracted token");
405
 
        ret = nih_config_token (buf, strlen (buf), NULL, NULL,
406
 
                                dest, " ", FALSE, &len);
407
 
 
408
 
        TEST_EQ (ret, 0);
409
 
        TEST_EQ (len, 9);
410
 
        TEST_EQ_STR (dest, "this\\$FOO");
411
 
 
412
 
 
413
 
        /* Check that we can obtain the length of a token that contains
414
 
         * escaped characters, including the backslashes, even though
415
 
         * we're dequoting.
416
 
         */
417
 
        TEST_FEATURE ("with escaped characters inside token and dequoting");
418
 
        pos = 0;
419
 
        len = 0;
420
 
        ret = nih_config_token (buf, strlen (buf), &pos, NULL,
421
 
                                NULL, " ", TRUE, &len);
422
 
 
423
 
        TEST_EQ (ret, 0);
424
 
        TEST_EQ (len, 9);
425
 
        TEST_EQ (pos, 9);
426
 
 
427
 
 
428
 
        /* Check that we can extract a token that contains escaped characters,
429
 
         * which should include the backslashes even though we're dequoting.
430
 
         */
431
 
        TEST_FEATURE ("with escaped characters within extracted dequoted token");
432
 
        len = 0;
433
 
        ret = nih_config_token (buf, strlen (buf), NULL, NULL,
434
 
                                dest, " ", TRUE, &len);
435
 
 
436
 
        TEST_EQ (ret, 0);
437
 
        TEST_EQ (len, 9);
438
 
        TEST_EQ_STR (dest, "this\\$FOO");
439
 
 
440
 
 
441
 
        /* Check that we can obtain the length of a token that contains
442
 
         * escaped backslashes, the length should include the backslashes.
443
 
         */
444
 
        TEST_FEATURE ("with escaped backslashes inside token");
445
 
        strcpy (buf, "this\\\\FOO");
446
 
        pos = 0;
447
 
        len = 0;
448
 
        ret = nih_config_token (buf, strlen (buf), &pos, NULL,
449
 
                                NULL, " ", FALSE, &len);
450
 
 
451
 
        TEST_EQ (ret, 0);
452
 
        TEST_EQ (len, 9);
453
 
        TEST_EQ (pos, 9);
454
 
 
455
 
 
456
 
        /* Check that we can extract a token that contains escaped
457
 
         * blackslashes.
458
 
         */
459
 
        TEST_FEATURE ("with escaped backslashes within extracted token");
460
 
        ret = nih_config_token (buf, strlen (buf), NULL, NULL,
461
 
                                dest, " ", FALSE, &len);
462
 
 
463
 
        TEST_EQ (ret, 0);
464
 
        TEST_EQ (len, 9);
465
 
        TEST_EQ_STR (dest, "this\\\\FOO");
466
 
 
467
 
 
468
 
        /* Check that we can obtain the length of a token that contains
469
 
         * escaped blackslashes, reduced to one since we're dequoting
470
 
         */
471
 
        TEST_FEATURE ("with escaped backslashes inside token and dequoting");
472
 
        pos = 0;
473
 
        len = 0;
474
 
        ret = nih_config_token (buf, strlen (buf), &pos, NULL,
475
 
                                NULL, " ", TRUE, &len);
476
 
 
477
 
        TEST_EQ (ret, 0);
478
 
        TEST_EQ (len, 8);
479
 
        TEST_EQ (pos, 9);
480
 
 
481
 
 
482
 
        /* Check that we can extract a token that contains escaped backslashes,
483
 
         * which should include only one of the backslashes because
484
 
         * we're dequoting.
485
 
         */
486
 
        TEST_FEATURE ("with escaped backslashes within extracted dequoted token");
487
 
        len = 0;
488
 
        ret = nih_config_token (buf, strlen (buf), NULL, NULL,
489
 
                                dest, " ", TRUE, &len);
490
 
 
491
 
        TEST_EQ (ret, 0);
492
 
        TEST_EQ (len, 8);
493
 
        TEST_EQ_STR (dest, "this\\FOO");
494
 
 
495
 
 
496
 
        /* Check that a slash at the end of the file causes a parser error
497
 
         * to be raised with pos and lineno set to the offending location.
498
 
         */
499
 
        TEST_FEATURE ("with slash at end of string");
500
 
        strcpy (buf, "wibble\\");
501
 
        pos = 0;
502
 
        len = 0;
503
 
        lineno = 1;
504
 
 
505
 
        ret = nih_config_token (buf, strlen (buf), &pos, &lineno,
506
 
                                NULL, " ", FALSE, NULL);
507
 
 
508
 
        TEST_LT (ret, 0);
509
 
        TEST_EQ (pos, 7);
510
 
        TEST_EQ (lineno, 1);
511
 
 
512
 
        err = nih_error_get ();
513
 
        TEST_EQ (err->number, NIH_CONFIG_TRAILING_SLASH);
514
 
        nih_free (err);
515
 
 
516
 
 
517
 
        /* Ceck that an unterminated quote causes a parser error to be
518
 
         * raised, with pos and lineno set to the offending location.
519
 
         */
520
 
        TEST_FEATURE ("with unterminated quote");
521
 
        strcpy (buf, "\"wibble\n");
522
 
        pos = 0;
523
 
        lineno = 1;
524
 
 
525
 
        ret = nih_config_token (buf, strlen (buf), &pos, &lineno,
526
 
                                NULL, " ", FALSE, NULL);
527
 
 
528
 
        TEST_LT (ret, 0);
529
 
        TEST_EQ (pos, 8);
530
 
        TEST_EQ (lineno, 2);
531
 
 
532
 
        err = nih_error_get ();
533
 
        TEST_EQ (err->number, NIH_CONFIG_UNTERMINATED_QUOTE);
534
 
        nih_free (err);
535
 
 
536
 
 
537
 
        /* Check that an empty token results in the position left unchanged
538
 
         * and zero being returned,
539
 
         */
540
 
        TEST_FEATURE ("with empty token");
541
 
        strcpy (buf, " wibble");
542
 
        pos = 0;
543
 
        len = 0;
544
 
        ret = nih_config_token (buf, strlen (buf), &pos, NULL,
545
 
                                NULL, " ", FALSE, &len);
546
 
 
547
 
        TEST_EQ (ret, 0);
548
 
        TEST_EQ (len, 0);
549
 
        TEST_EQ (pos, 0);
550
 
}
551
 
 
552
 
void
553
 
test_next_token (void)
554
 
{
555
 
        char      buf[1024];
556
 
        char     *str;
557
 
        size_t    pos, lineno;
558
 
        NihError *err;
559
 
 
560
 
        TEST_FUNCTION ("nih_config_next_token");
561
 
 
562
 
        /* Check that we can extract a token at the start of a string,
563
 
         * and have the position pointing past the whitespace to the next
564
 
         * argument.
565
 
         */
566
 
        TEST_FEATURE ("with token at start of string");
567
 
        TEST_ALLOC_FAIL {
568
 
                strcpy (buf, "this is a test");
569
 
                pos = 0;
570
 
 
571
 
                str = nih_config_next_token (NULL, buf,
572
 
                                             strlen (buf), &pos, NULL,
573
 
                                             NIH_CONFIG_CNLWS, FALSE);
574
 
 
575
 
                if (test_alloc_failed) {
576
 
                        TEST_EQ_P (str, NULL);
577
 
                        TEST_EQ (pos, 0);
578
 
 
579
 
                        err = nih_error_get ();
580
 
                        TEST_EQ (err->number, ENOMEM);
581
 
                        nih_free (err);
582
 
                        continue;
583
 
                }
584
 
 
585
 
                TEST_EQ (pos, 5);
586
 
                TEST_ALLOC_SIZE (str, 5);
587
 
                TEST_EQ_STR (str, "this");
588
 
 
589
 
                nih_free (str);
590
 
        }
591
 
 
592
 
 
593
 
        /* Check that we can extract an argument inside a string
594
 
         */
595
 
        TEST_FEATURE ("with token inside string");
596
 
        TEST_ALLOC_FAIL {
597
 
                strcpy (buf, "this is a test");
598
 
                pos = 5;
599
 
 
600
 
                str = nih_config_next_token (NULL, buf,
601
 
                                             strlen (buf), &pos, NULL,
602
 
                                             NIH_CONFIG_CNLWS, FALSE);
603
 
 
604
 
                if (test_alloc_failed) {
605
 
                        TEST_EQ_P (str, NULL);
606
 
                        TEST_EQ (pos, 5);
607
 
 
608
 
                        err = nih_error_get ();
609
 
                        TEST_EQ (err->number, ENOMEM);
610
 
                        nih_free (err);
611
 
                        continue;
612
 
                }
613
 
 
614
 
                TEST_EQ (pos, 8);
615
 
                TEST_ALLOC_SIZE (str, 3);
616
 
                TEST_EQ_STR (str, "is");
617
 
 
618
 
                nih_free (str);
619
 
        }
620
 
 
621
 
 
622
 
        /* Check that all trailing whitespace is eaten after the token. */
623
 
        TEST_FEATURE ("with consecutive whitespace after token");
624
 
        TEST_ALLOC_FAIL {
625
 
                strcpy (buf, "this \t  is a test");
626
 
                pos = 0;
627
 
 
628
 
                str = nih_config_next_token (NULL, buf,
629
 
                                             strlen (buf), &pos, NULL,
630
 
                                             NIH_CONFIG_CNLWS, FALSE);
631
 
 
632
 
                if (test_alloc_failed) {
633
 
                        TEST_EQ_P (str, NULL);
634
 
                        TEST_EQ (pos, 0);
635
 
 
636
 
                        err = nih_error_get ();
637
 
                        TEST_EQ (err->number, ENOMEM);
638
 
                        nih_free (err);
639
 
                        continue;
640
 
                }
641
 
 
642
 
                TEST_EQ (pos, 8);
643
 
                TEST_ALLOC_SIZE (str, 5);
644
 
                TEST_EQ_STR (str, "this");
645
 
 
646
 
                nih_free (str);
647
 
        }
648
 
 
649
 
 
650
 
        /* Check that any escaped newlines in the whitespace are skipped
651
 
         * over
652
 
         */
653
 
        TEST_FEATURE ("with escaped newlines in whitespace");
654
 
        TEST_ALLOC_FAIL {
655
 
                strcpy (buf, "this \\\n is a test");
656
 
                pos = 0;
657
 
 
658
 
                str = nih_config_next_token (NULL, buf,
659
 
                                             strlen (buf), &pos, NULL,
660
 
                                             NIH_CONFIG_CNLWS, FALSE);
661
 
 
662
 
                if (test_alloc_failed) {
663
 
                        TEST_EQ_P (str, NULL);
664
 
                        TEST_EQ (pos, 0);
665
 
 
666
 
                        err = nih_error_get ();
667
 
                        TEST_EQ (err->number, ENOMEM);
668
 
                        nih_free (err);
669
 
                        continue;
670
 
                }
671
 
 
672
 
                TEST_EQ (pos, 8);
673
 
                TEST_ALLOC_SIZE (str, 5);
674
 
                TEST_EQ_STR (str, "this");
675
 
 
676
 
                nih_free (str);
677
 
        }
678
 
 
679
 
 
680
 
        /* Check that the line number is incremented for any escaped newlines
681
 
         * in the whitespace.
682
 
         */
683
 
        TEST_FEATURE ("with line number set");
684
 
        TEST_ALLOC_FAIL {
685
 
                pos = 0;
686
 
                lineno = 1;
687
 
 
688
 
                str = nih_config_next_token (NULL, buf,
689
 
                                             strlen (buf), &pos, &lineno,
690
 
                                             NIH_CONFIG_CNLWS, FALSE);
691
 
 
692
 
                if (test_alloc_failed) {
693
 
                        TEST_EQ_P (str, NULL);
694
 
                        TEST_EQ (pos, 0);
695
 
                        TEST_EQ (lineno, 2);
696
 
 
697
 
                        err = nih_error_get ();
698
 
                        TEST_EQ (err->number, ENOMEM);
699
 
                        nih_free (err);
700
 
                        continue;
701
 
                }
702
 
 
703
 
                TEST_EQ (pos, 8);
704
 
                TEST_EQ (lineno, 2);
705
 
                TEST_ALLOC_SIZE (str, 5);
706
 
                TEST_EQ_STR (str, "this");
707
 
 
708
 
                nih_free (str);
709
 
        }
710
 
 
711
 
 
712
 
        /* Check that the returned token can have the quotes left in it,
713
 
         * but the whitespace around the newline collapsed.
714
 
         */
715
 
        TEST_FEATURE ("with token containing quotes");
716
 
        TEST_ALLOC_FAIL {
717
 
                strcpy (buf, "\"this \\\n is\" a test");
718
 
                pos = 0;
719
 
 
720
 
                str = nih_config_next_token (NULL, buf,
721
 
                                             strlen (buf), &pos, NULL,
722
 
                                             NIH_CONFIG_CNLWS, FALSE);
723
 
 
724
 
                if (test_alloc_failed) {
725
 
                        TEST_EQ_P (str, NULL);
726
 
                        TEST_EQ (pos, 0);
727
 
 
728
 
                        err = nih_error_get ();
729
 
                        TEST_EQ (err->number, ENOMEM);
730
 
                        nih_free (err);
731
 
                        continue;
732
 
                }
733
 
 
734
 
                TEST_EQ (pos, 13);
735
 
                TEST_ALLOC_SIZE (str, 10);
736
 
                TEST_EQ_STR (str, "\"this is\"");
737
 
 
738
 
                nih_free (str);
739
 
        }
740
 
 
741
 
 
742
 
        /* Check that the returned token can be thoroughly dequoted and any
743
 
         * whitespace around an embedded newline collapsed to a single
744
 
         * space.
745
 
         */
746
 
        TEST_FEATURE ("with quoted whitespace and newline in token");
747
 
        TEST_ALLOC_FAIL {
748
 
                strcpy (buf, "\"this \\\n is\" a test");
749
 
                pos = 0;
750
 
 
751
 
                str = nih_config_next_token (NULL, buf,
752
 
                                             strlen (buf), &pos, NULL,
753
 
                                             NIH_CONFIG_CNLWS, TRUE);
754
 
 
755
 
                if (test_alloc_failed) {
756
 
                        TEST_EQ_P (str, NULL);
757
 
                        TEST_EQ (pos, 0);
758
 
 
759
 
                        err = nih_error_get ();
760
 
                        TEST_EQ (err->number, ENOMEM);
761
 
                        nih_free (err);
762
 
                        continue;
763
 
                }
764
 
 
765
 
                TEST_EQ (pos, 13);
766
 
                TEST_ALLOC_SIZE (str, 8);
767
 
                TEST_EQ_STR (str, "this is");
768
 
 
769
 
                nih_free (str);
770
 
        }
771
 
 
772
 
 
773
 
        /* Check that an error is raised if there is no token at that
774
 
         * position.
775
 
         */
776
 
        TEST_FEATURE ("with empty line");
777
 
        TEST_ALLOC_FAIL {
778
 
                strcpy (buf, "\nthis is a test");
779
 
                pos = 0;
780
 
                lineno = 1;
781
 
 
782
 
                str = nih_config_next_token (NULL, buf,
783
 
                                             strlen (buf), &pos, &lineno,
784
 
                                             NIH_CONFIG_CNLWS, FALSE);
785
 
 
786
 
                TEST_EQ_P (str, NULL);
787
 
                TEST_EQ (pos, 0);
788
 
                TEST_EQ (lineno, 1);
789
 
 
790
 
                err = nih_error_get ();
791
 
                TEST_EQ (err->number, NIH_CONFIG_EXPECTED_TOKEN);
792
 
                nih_free (err);
793
 
        }
794
 
 
795
 
 
796
 
        /* Check that a parse error being found with the argument causes an
797
 
         * error to be raised, with pos and lineno at the site of the error.
798
 
         */
799
 
        TEST_FEATURE ("with parser error");
800
 
        TEST_ALLOC_FAIL {
801
 
                strcpy (buf, "\"this is a test\nand so is this");
802
 
                pos = 0;
803
 
                lineno = 1;
804
 
 
805
 
                str = nih_config_next_token (NULL, buf,
806
 
                                             strlen (buf), &pos, &lineno,
807
 
                                             NIH_CONFIG_CNLWS, FALSE);
808
 
 
809
 
                TEST_EQ_P (str, NULL);
810
 
                TEST_EQ (pos, 30);
811
 
                TEST_EQ (lineno, 2);
812
 
 
813
 
                err = nih_error_get ();
814
 
                TEST_EQ (err->number, NIH_CONFIG_UNTERMINATED_QUOTE);
815
 
                nih_free (err);
816
 
        }
817
 
}
818
 
 
819
 
void
820
 
test_next_arg (void)
821
 
{
822
 
        char      buf[1024];
823
 
        char     *str;
824
 
        size_t    pos, lineno;
825
 
        NihError *err;
826
 
 
827
 
        TEST_FUNCTION ("nih_config_next_arg");
828
 
 
829
 
        /* Check that we can extract an argument at the start of a string,
830
 
         * and have the position pointing past the whitespace to the next
831
 
         * argument.
832
 
         */
833
 
        TEST_FEATURE ("with argument at start of string");
834
 
        TEST_ALLOC_FAIL {
835
 
                strcpy (buf, "this is a test");
836
 
                pos = 0;
837
 
 
838
 
                str = nih_config_next_arg (NULL, buf,
839
 
                                           strlen (buf), &pos, NULL);
840
 
 
841
 
                if (test_alloc_failed) {
842
 
                        TEST_EQ_P (str, NULL);
843
 
                        TEST_EQ (pos, 0);
844
 
 
845
 
                        err = nih_error_get ();
846
 
                        TEST_EQ (err->number, ENOMEM);
847
 
                        nih_free (err);
848
 
                        continue;
849
 
                }
850
 
 
851
 
                TEST_EQ (pos, 5);
852
 
                TEST_ALLOC_SIZE (str, 5);
853
 
                TEST_EQ_STR (str, "this");
854
 
 
855
 
                nih_free (str);
856
 
        }
857
 
 
858
 
 
859
 
        /* Check that we can extract an argument inside a string
860
 
         */
861
 
        TEST_FEATURE ("with argument inside string");
862
 
        TEST_ALLOC_FAIL {
863
 
                strcpy (buf, "this is a test");
864
 
                pos = 5;
865
 
 
866
 
                str = nih_config_next_arg (NULL, buf,
867
 
                                           strlen (buf), &pos, NULL);
868
 
 
869
 
                if (test_alloc_failed) {
870
 
                        TEST_EQ_P (str, NULL);
871
 
                        TEST_EQ (pos, 5);
872
 
 
873
 
                        err = nih_error_get ();
874
 
                        TEST_EQ (err->number, ENOMEM);
875
 
                        nih_free (err);
876
 
                        continue;
877
 
                }
878
 
 
879
 
                TEST_EQ (pos, 8);
880
 
                TEST_ALLOC_SIZE (str, 3);
881
 
                TEST_EQ_STR (str, "is");
882
 
 
883
 
                nih_free (str);
884
 
        }
885
 
 
886
 
 
887
 
        /* Check that all trailing whitespace is eaten after the argument. */
888
 
        TEST_FEATURE ("with consecutive whitespace after argument");
889
 
        TEST_ALLOC_FAIL {
890
 
                strcpy (buf, "this \t  is a test");
891
 
                pos = 0;
892
 
 
893
 
                str = nih_config_next_arg (NULL, buf,
894
 
                                           strlen (buf), &pos, NULL);
895
 
 
896
 
                if (test_alloc_failed) {
897
 
                        TEST_EQ_P (str, NULL);
898
 
                        TEST_EQ (pos, 0);
899
 
 
900
 
                        err = nih_error_get ();
901
 
                        TEST_EQ (err->number, ENOMEM);
902
 
                        nih_free (err);
903
 
                        continue;
904
 
                }
905
 
 
906
 
                TEST_EQ (pos, 8);
907
 
                TEST_ALLOC_SIZE (str, 5);
908
 
                TEST_EQ_STR (str, "this");
909
 
 
910
 
                nih_free (str);
911
 
        }
912
 
 
913
 
 
914
 
        /* Check that any escaped newlines in the whitespace are skipped
915
 
         * over
916
 
         */
917
 
        TEST_FEATURE ("with escaped newlines in whitespace");
918
 
        TEST_ALLOC_FAIL {
919
 
                strcpy (buf, "this \\\n is a test");
920
 
                pos = 0;
921
 
 
922
 
                str = nih_config_next_arg (NULL, buf,
923
 
                                           strlen (buf), &pos, NULL);
924
 
 
925
 
                if (test_alloc_failed) {
926
 
                        TEST_EQ_P (str, NULL);
927
 
                        TEST_EQ (pos, 0);
928
 
 
929
 
                        err = nih_error_get ();
930
 
                        TEST_EQ (err->number, ENOMEM);
931
 
                        nih_free (err);
932
 
                        continue;
933
 
                }
934
 
 
935
 
                TEST_EQ (pos, 8);
936
 
                TEST_ALLOC_SIZE (str, 5);
937
 
                TEST_EQ_STR (str, "this");
938
 
 
939
 
                nih_free (str);
940
 
        }
941
 
 
942
 
 
943
 
        /* Check that the line number is incremented for any escaped newlines
944
 
         * in the whitespace.
945
 
         */
946
 
        TEST_FEATURE ("with line number set");
947
 
        TEST_ALLOC_FAIL {
948
 
                pos = 0;
949
 
                lineno = 1;
950
 
 
951
 
                str = nih_config_next_arg (NULL, buf,
952
 
                                           strlen (buf), &pos, &lineno);
953
 
 
954
 
                if (test_alloc_failed) {
955
 
                        TEST_EQ_P (str, NULL);
956
 
                        TEST_EQ (pos, 0);
957
 
                        TEST_EQ (lineno, 2);
958
 
 
959
 
                        err = nih_error_get ();
960
 
                        TEST_EQ (err->number, ENOMEM);
961
 
                        nih_free (err);
962
 
                        continue;
963
 
                }
964
 
 
965
 
                TEST_EQ (pos, 8);
966
 
                TEST_EQ (lineno, 2);
967
 
                TEST_ALLOC_SIZE (str, 5);
968
 
                TEST_EQ_STR (str, "this");
969
 
 
970
 
                nih_free (str);
971
 
        }
972
 
 
973
 
 
974
 
        /* Check that the returned argument is thoroughly dequoted and any
975
 
         * whitespace around an embedded newline collapsed to a single
976
 
         * space.
977
 
         */
978
 
        TEST_FEATURE ("with quoted whitespace and newline in arg");
979
 
        TEST_ALLOC_FAIL {
980
 
                strcpy (buf, "\"this \\\n is\" a test");
981
 
                pos = 0;
982
 
 
983
 
                str = nih_config_next_arg (NULL, buf,
984
 
                                           strlen (buf), &pos, NULL);
985
 
 
986
 
                if (test_alloc_failed) {
987
 
                        TEST_EQ_P (str, NULL);
988
 
                        TEST_EQ (pos, 0);
989
 
 
990
 
                        err = nih_error_get ();
991
 
                        TEST_EQ (err->number, ENOMEM);
992
 
                        nih_free (err);
993
 
                        continue;
994
 
                }
995
 
 
996
 
                TEST_EQ (pos, 13);
997
 
                TEST_ALLOC_SIZE (str, 8);
998
 
                TEST_EQ_STR (str, "this is");
999
 
 
1000
 
                nih_free (str);
1001
 
        }
1002
 
 
1003
 
 
1004
 
        /* Check that an error is raised if there is no argument at that
1005
 
         * position.
1006
 
         */
1007
 
        TEST_FEATURE ("with empty line");
1008
 
        TEST_ALLOC_FAIL {
1009
 
                strcpy (buf, "\nthis is a test");
1010
 
                pos = 0;
1011
 
                lineno = 1;
1012
 
 
1013
 
                str = nih_config_next_arg (NULL, buf,
1014
 
                                           strlen (buf), &pos, &lineno);
1015
 
 
1016
 
                TEST_EQ_P (str, NULL);
1017
 
                TEST_EQ (pos, 0);
1018
 
                TEST_EQ (lineno, 1);
1019
 
 
1020
 
                err = nih_error_get ();
1021
 
                TEST_EQ (err->number, NIH_CONFIG_EXPECTED_TOKEN);
1022
 
                nih_free (err);
1023
 
        }
1024
 
 
1025
 
 
1026
 
        /* Check that a parse error being found with the argument causes an
1027
 
         * error to be raised, with pos and lineno at the site of the error.
1028
 
         */
1029
 
        TEST_FEATURE ("with parser error");
1030
 
        TEST_ALLOC_FAIL {
1031
 
                strcpy (buf, "\"this is a test\nand so is this");
1032
 
                pos = 0;
1033
 
                lineno = 1;
1034
 
 
1035
 
                str = nih_config_next_arg (NULL, buf,
1036
 
                                           strlen (buf), &pos, &lineno);
1037
 
 
1038
 
                TEST_EQ_P (str, NULL);
1039
 
                TEST_EQ (pos, 30);
1040
 
                TEST_EQ (lineno, 2);
1041
 
 
1042
 
                err = nih_error_get ();
1043
 
                TEST_EQ (err->number, NIH_CONFIG_UNTERMINATED_QUOTE);
1044
 
                nih_free (err);
1045
 
        }
1046
 
}
1047
 
 
1048
 
void
1049
 
test_next_line (void)
1050
 
{
1051
 
        char   buf[1024];
1052
 
        size_t pos, lineno;
1053
 
 
1054
 
        TEST_FUNCTION ("nih_config_next_line");
1055
 
 
1056
 
        /* Check that we can skip a number of characters until the newline,
1057
 
         * pointing pos past it.
1058
 
         */
1059
 
        TEST_FEATURE ("with simple string");
1060
 
        strcpy (buf, "this is a test\nand so is this\n");
1061
 
        pos = 0;
1062
 
 
1063
 
        nih_config_next_line (buf, strlen (buf), &pos, NULL);
1064
 
 
1065
 
        TEST_EQ (pos, 15);
1066
 
 
1067
 
 
1068
 
        /* Check that lineno is incremented when we step over it.
1069
 
         */
1070
 
        TEST_FEATURE ("with line number set");
1071
 
        pos = 0;
1072
 
        lineno = 1;
1073
 
 
1074
 
        nih_config_next_line (buf, strlen (buf), &pos, &lineno);
1075
 
 
1076
 
        TEST_EQ (pos, 15);
1077
 
        TEST_EQ (lineno, 2);
1078
 
 
1079
 
 
1080
 
        /* Check that pos is only incremented by a single step if the
1081
 
         * character underneath is a newline.
1082
 
         */
1083
 
        TEST_FEATURE ("with newline at position");
1084
 
        strcpy (buf, "\nthis is a test");
1085
 
        pos = 0;
1086
 
        lineno = 1;
1087
 
 
1088
 
        nih_config_next_line (buf, strlen (buf), &pos, &lineno);
1089
 
 
1090
 
        TEST_EQ (pos, 1);
1091
 
        TEST_EQ (lineno, 2);
1092
 
 
1093
 
 
1094
 
        /* Check that the end of file can be reached without error.
1095
 
         */
1096
 
        TEST_FEATURE ("with no newline before end of file");
1097
 
        strcpy (buf, "this is a test");
1098
 
        pos = 0;
1099
 
 
1100
 
        nih_config_next_line (buf, strlen (buf), &pos, NULL);
1101
 
 
1102
 
        TEST_EQ (pos, 14);
1103
 
}
1104
 
 
1105
 
void
1106
 
test_skip_whitespace (void)
1107
 
{
1108
 
        char   buf[1024];
1109
 
        size_t pos, lineno;
1110
 
 
1111
 
        TEST_FUNCTION ("nih_config_next_whitespace");
1112
 
 
1113
 
        /* Check that we can skip an amount of plain whitespace characters
1114
 
         * until the next token, pointing pos at is.
1115
 
         */
1116
 
        TEST_FEATURE ("with plain whitespace");
1117
 
        strcpy (buf, "a  plain string\n");
1118
 
        pos = 1;
1119
 
        lineno = 1;
1120
 
 
1121
 
        nih_config_skip_whitespace (buf, strlen (buf), &pos, &lineno);
1122
 
 
1123
 
        TEST_EQ (pos, 3);
1124
 
        TEST_EQ (lineno, 1);
1125
 
 
1126
 
 
1127
 
        /* Check that we can skip a more complex series of whitespace
1128
 
         * characters until the next token.
1129
 
         */
1130
 
        TEST_FEATURE ("with complex whitespace");
1131
 
        strcpy (buf, "a more   \t  \r  complex string\n");
1132
 
        pos = 6;
1133
 
        lineno = 1;
1134
 
 
1135
 
        nih_config_skip_whitespace (buf, strlen (buf), &pos, &lineno);
1136
 
 
1137
 
        TEST_EQ (pos, 15);
1138
 
        TEST_EQ (lineno, 1);
1139
 
 
1140
 
 
1141
 
        /* Check that we can skip whitespace characters up until the end
1142
 
         * of the line, but that we don't step over it.
1143
 
         */
1144
 
        TEST_FEATURE ("with whitespace at end of line");
1145
 
        strcpy (buf, "trailing whitespace  \t\r\n");
1146
 
        pos = 19;
1147
 
        lineno = 1;
1148
 
 
1149
 
        nih_config_skip_whitespace (buf, strlen (buf), &pos, &lineno);
1150
 
 
1151
 
        TEST_EQ (pos, 23);
1152
 
        TEST_EQ (lineno, 1);
1153
 
 
1154
 
 
1155
 
        /* Check that we step over an escaped newline embedded in the
1156
 
         * whitespace, and increment lineno.
1157
 
         */
1158
 
        TEST_FEATURE ("with escaped newline");
1159
 
        strcpy (buf, "this has \\\n a newline");
1160
 
        pos = 8;
1161
 
        lineno = 1;
1162
 
 
1163
 
        nih_config_skip_whitespace (buf, strlen (buf), &pos, &lineno);
1164
 
 
1165
 
        TEST_EQ (pos, 12);
1166
 
        TEST_EQ (lineno, 2);
1167
 
}
1168
 
 
1169
 
void
1170
 
test_skip_comment (void)
1171
 
{
1172
 
        char      buf[1024];
1173
 
        size_t    pos, lineno;
1174
 
        int       ret;
1175
 
        NihError *err;
1176
 
 
1177
 
        TEST_FUNCTION ("nih_config_next_line");
1178
 
 
1179
 
        /* Check that we can skip a number of comment characters until the
1180
 
         * newline,  pointing pos past it.
1181
 
         */
1182
 
        TEST_FEATURE ("with simple string");
1183
 
        strcpy (buf, "# this is a test\nand so is this\n");
1184
 
        pos = 0;
1185
 
 
1186
 
        ret = nih_config_skip_comment (buf, strlen (buf), &pos, NULL);
1187
 
 
1188
 
        TEST_EQ (ret, 0);
1189
 
        TEST_EQ (pos, 17);
1190
 
 
1191
 
 
1192
 
        /* Check that lineno is incremented when we step over it.
1193
 
         */
1194
 
        TEST_FEATURE ("with line number set");
1195
 
        pos = 0;
1196
 
        lineno = 1;
1197
 
 
1198
 
        ret = nih_config_skip_comment (buf, strlen (buf), &pos, &lineno);
1199
 
 
1200
 
        TEST_EQ (ret, 0);
1201
 
        TEST_EQ (pos, 17);
1202
 
        TEST_EQ (lineno, 2);
1203
 
 
1204
 
 
1205
 
        /* Check that pos is only incremented by a single step if the
1206
 
         * character underneath is a newline.
1207
 
         */
1208
 
        TEST_FEATURE ("with newline at position");
1209
 
        strcpy (buf, "\nthis is a test");
1210
 
        pos = 0;
1211
 
        lineno = 1;
1212
 
 
1213
 
        ret = nih_config_skip_comment (buf, strlen (buf), &pos, &lineno);
1214
 
 
1215
 
        TEST_EQ (ret, 0);
1216
 
        TEST_EQ (pos, 1);
1217
 
        TEST_EQ (lineno, 2);
1218
 
 
1219
 
 
1220
 
        /* Check that the end of file can be reached without error.
1221
 
         */
1222
 
        TEST_FEATURE ("with no newline before end of file");
1223
 
        strcpy (buf, "# this is a test");
1224
 
        pos = 0;
1225
 
 
1226
 
        ret = nih_config_skip_comment (buf, strlen (buf), &pos, NULL);
1227
 
 
1228
 
        TEST_EQ (ret, 0);
1229
 
        TEST_EQ (pos, 16);
1230
 
 
1231
 
 
1232
 
        /* Check that attempting to skip an ordinary argument results in
1233
 
         * an error.
1234
 
         */
1235
 
        TEST_FEATURE ("with attempt to skip argument");
1236
 
        strcpy (buf, "this is a test\nand so it this\n");
1237
 
        pos = 0;
1238
 
 
1239
 
        ret = nih_config_skip_comment (buf, strlen (buf), &pos, NULL);
1240
 
 
1241
 
        TEST_LT (ret, 0);
1242
 
        TEST_EQ (pos, 0);
1243
 
 
1244
 
        err = nih_error_get ();
1245
 
        TEST_EQ (err->number, NIH_CONFIG_UNEXPECTED_TOKEN);
1246
 
        nih_free (err);
1247
 
}
1248
 
 
1249
 
 
1250
 
void
1251
 
test_parse_args (void)
1252
 
{
1253
 
        char       buf[1024];
1254
 
        char     **args;
1255
 
        size_t     pos, lineno;
1256
 
        NihError  *err;
1257
 
 
1258
 
        TEST_FUNCTION ("nih_config_parse_args");
1259
 
 
1260
 
        /* Check that we can parse a list of arguments from the start of
1261
 
         * a simple string.  They should be returned as a NULL-terminated
1262
 
         * array of strings, and the position should be updated to point to
1263
 
         * the start of the next line.
1264
 
         */
1265
 
        TEST_FEATURE ("with args at start of simple string");
1266
 
        TEST_ALLOC_FAIL {
1267
 
                strcpy (buf, "this is a test\nand so is this\n");
1268
 
                pos = 0;
1269
 
 
1270
 
                args = nih_config_parse_args (NULL, buf,
1271
 
                                              strlen (buf), &pos, NULL);
1272
 
 
1273
 
                if (test_alloc_failed) {
1274
 
                        TEST_EQ_P (args, NULL);
1275
 
 
1276
 
                        err = nih_error_get ();
1277
 
                        TEST_EQ (err->number, ENOMEM);
1278
 
                        nih_free (err);
1279
 
                        continue;
1280
 
                }
1281
 
 
1282
 
                TEST_EQ (pos, 15);
1283
 
                TEST_ALLOC_SIZE (args, sizeof (char *) * 5);
1284
 
                TEST_ALLOC_PARENT (args[0], args);
1285
 
                TEST_ALLOC_PARENT (args[1], args);
1286
 
                TEST_ALLOC_PARENT (args[2], args);
1287
 
                TEST_ALLOC_PARENT (args[3], args);
1288
 
                TEST_EQ_STR (args[0], "this");
1289
 
                TEST_EQ_STR (args[1], "is");
1290
 
                TEST_EQ_STR (args[2], "a");
1291
 
                TEST_EQ_STR (args[3], "test");
1292
 
                TEST_EQ_P (args[4], NULL);
1293
 
 
1294
 
                nih_free (args);
1295
 
        }
1296
 
 
1297
 
 
1298
 
        /* Check that we can parse a list of arguments from a position
1299
 
         * inside an existing string.
1300
 
         */
1301
 
        TEST_FEATURE ("with args inside simple string");
1302
 
        TEST_ALLOC_FAIL {
1303
 
                pos = 5;
1304
 
 
1305
 
                args = nih_config_parse_args (NULL, buf,
1306
 
                                              strlen (buf), &pos, NULL);
1307
 
 
1308
 
                if (test_alloc_failed) {
1309
 
                        TEST_EQ_P (args, NULL);
1310
 
 
1311
 
                        err = nih_error_get ();
1312
 
                        TEST_EQ (err->number, ENOMEM);
1313
 
                        nih_free (err);
1314
 
                        continue;
1315
 
                }
1316
 
 
1317
 
                TEST_EQ (pos, 15);
1318
 
                TEST_ALLOC_SIZE (args, sizeof (char *) * 4);
1319
 
                TEST_EQ_STR (args[0], "is");
1320
 
                TEST_EQ_STR (args[1], "a");
1321
 
                TEST_EQ_STR (args[2], "test");
1322
 
                TEST_EQ_P (args[3], NULL);
1323
 
 
1324
 
                nih_free (args);
1325
 
        }
1326
 
 
1327
 
 
1328
 
        /* Check that we can parse a list of arguments up to the end of the
1329
 
         * file, which doesn't have a newline.
1330
 
         */
1331
 
        TEST_FEATURE ("with args up to end of string");
1332
 
        TEST_ALLOC_FAIL {
1333
 
                strcpy (buf, "this is a test");
1334
 
                pos = 0;
1335
 
 
1336
 
                args = nih_config_parse_args (NULL, buf,
1337
 
                                              strlen (buf), &pos, NULL);
1338
 
 
1339
 
                if (test_alloc_failed) {
1340
 
                        TEST_EQ_P (args, NULL);
1341
 
 
1342
 
                        err = nih_error_get ();
1343
 
                        TEST_EQ (err->number, ENOMEM);
1344
 
                        nih_free (err);
1345
 
                        continue;
1346
 
                }
1347
 
 
1348
 
                TEST_EQ (pos, 14);
1349
 
                TEST_ALLOC_SIZE (args, sizeof (char *) * 5);
1350
 
                TEST_EQ_STR (args[0], "this");
1351
 
                TEST_EQ_STR (args[1], "is");
1352
 
                TEST_EQ_STR (args[2], "a");
1353
 
                TEST_EQ_STR (args[3], "test");
1354
 
                TEST_EQ_P (args[4], NULL);
1355
 
 
1356
 
                nih_free (args);
1357
 
        }
1358
 
 
1359
 
 
1360
 
        /* Check that we can ignore a comment at the end of the line, the
1361
 
         * position should be updated past the comment onto the next line.
1362
 
         */
1363
 
        TEST_FEATURE ("with args up to comment");
1364
 
        TEST_ALLOC_FAIL {
1365
 
                strcpy (buf, "this is a test # comment\nand so is this\n");
1366
 
                pos = 0;
1367
 
 
1368
 
                args = nih_config_parse_args (NULL, buf,
1369
 
                                              strlen (buf), &pos, NULL);
1370
 
 
1371
 
                if (test_alloc_failed) {
1372
 
                        TEST_EQ_P (args, NULL);
1373
 
 
1374
 
                        err = nih_error_get ();
1375
 
                        TEST_EQ (err->number, ENOMEM);
1376
 
                        nih_free (err);
1377
 
                        continue;
1378
 
                }
1379
 
 
1380
 
                TEST_EQ (pos, 25);
1381
 
                TEST_ALLOC_SIZE (args, sizeof (char *) * 5);
1382
 
                TEST_EQ_STR (args[0], "this");
1383
 
                TEST_EQ_STR (args[1], "is");
1384
 
                TEST_EQ_STR (args[2], "a");
1385
 
                TEST_EQ_STR (args[3], "test");
1386
 
                TEST_EQ_P (args[4], NULL);
1387
 
 
1388
 
                nih_free (args);
1389
 
        }
1390
 
 
1391
 
 
1392
 
        /* Check that we can ignore a comment at the end of the file, the
1393
 
         * position should be updated past the end.
1394
 
         */
1395
 
        TEST_FEATURE ("with args up to comment at end of file");
1396
 
        TEST_ALLOC_FAIL {
1397
 
                strcpy (buf, "this is a test # comment");
1398
 
                pos = 0;
1399
 
 
1400
 
                args = nih_config_parse_args (NULL, buf,
1401
 
                                              strlen (buf), &pos, NULL);
1402
 
 
1403
 
                if (test_alloc_failed) {
1404
 
                        TEST_EQ_P (args, NULL);
1405
 
 
1406
 
                        err = nih_error_get ();
1407
 
                        TEST_EQ (err->number, ENOMEM);
1408
 
                        nih_free (err);
1409
 
                        continue;
1410
 
                }
1411
 
 
1412
 
                TEST_EQ (pos, 24);
1413
 
                TEST_ALLOC_SIZE (args, sizeof (char *) * 5);
1414
 
                TEST_EQ_STR (args[0], "this");
1415
 
                TEST_EQ_STR (args[1], "is");
1416
 
                TEST_EQ_STR (args[2], "a");
1417
 
                TEST_EQ_STR (args[3], "test");
1418
 
                TEST_EQ_P (args[4], NULL);
1419
 
 
1420
 
                nih_free (args);
1421
 
        }
1422
 
 
1423
 
 
1424
 
        /* Check that the line number is incremented when a new line is
1425
 
         * encountered.
1426
 
         */
1427
 
        TEST_FEATURE ("with line number given");
1428
 
        TEST_ALLOC_FAIL {
1429
 
                strcpy (buf, "this is a test\nand so is this\n");
1430
 
                pos = 0;
1431
 
                lineno = 1;
1432
 
 
1433
 
                args = nih_config_parse_args (NULL, buf,
1434
 
                                              strlen (buf), &pos, &lineno);
1435
 
 
1436
 
                if (test_alloc_failed) {
1437
 
                        TEST_EQ_P (args, NULL);
1438
 
 
1439
 
                        err = nih_error_get ();
1440
 
                        TEST_EQ (err->number, ENOMEM);
1441
 
                        nih_free (err);
1442
 
                        continue;
1443
 
                }
1444
 
 
1445
 
                TEST_EQ (pos, 15);
1446
 
                TEST_EQ (lineno, 2);
1447
 
 
1448
 
                nih_free (args);
1449
 
        }
1450
 
 
1451
 
 
1452
 
        /* Check that consecutive whitespace, including escaped newlines,
1453
 
         * are treated as a single delimeter.  The line number should be
1454
 
         * incremented for both the embedded one and final one.
1455
 
         */
1456
 
        TEST_FEATURE ("with multiple whitespace between arguments");
1457
 
        TEST_ALLOC_FAIL {
1458
 
                strcpy (buf, "this   is \t  a  \\\n test\nand so is this\n");
1459
 
                pos = 0;
1460
 
                lineno = 1;
1461
 
 
1462
 
                args = nih_config_parse_args (NULL, buf,
1463
 
                                              strlen (buf), &pos, &lineno);
1464
 
 
1465
 
                if (test_alloc_failed) {
1466
 
                        TEST_EQ_P (args, NULL);
1467
 
 
1468
 
                        err = nih_error_get ();
1469
 
                        TEST_EQ (err->number, ENOMEM);
1470
 
                        nih_free (err);
1471
 
                        continue;
1472
 
                }
1473
 
 
1474
 
                TEST_EQ (pos, 24);
1475
 
                TEST_EQ (lineno, 3);
1476
 
                TEST_ALLOC_SIZE (args, sizeof (char *) * 5);
1477
 
                TEST_EQ_STR (args[0], "this");
1478
 
                TEST_EQ_STR (args[1], "is");
1479
 
                TEST_EQ_STR (args[2], "a");
1480
 
                TEST_EQ_STR (args[3], "test");
1481
 
                TEST_EQ_P (args[4], NULL);
1482
 
 
1483
 
                nih_free (args);
1484
 
        }
1485
 
 
1486
 
 
1487
 
        /* Check that each argument can be delimited by quotes, contain
1488
 
         * quoted newlines, and each is dequoted before being stored in the
1489
 
         * args array,
1490
 
         */
1491
 
        TEST_FEATURE ("with whitespace inside arguments");
1492
 
        TEST_ALLOC_FAIL {
1493
 
                strcpy (buf, "\"this is\" \"a\ntest\" \\\n and so\nis this\n");
1494
 
                pos = 0;
1495
 
                lineno = 1;
1496
 
 
1497
 
                args = nih_config_parse_args (NULL, buf,
1498
 
                                              strlen (buf), &pos, &lineno);
1499
 
 
1500
 
                if (test_alloc_failed) {
1501
 
                        TEST_EQ_P (args, NULL);
1502
 
 
1503
 
                        err = nih_error_get ();
1504
 
                        TEST_EQ (err->number, ENOMEM);
1505
 
                        nih_free (err);
1506
 
                        continue;
1507
 
                }
1508
 
 
1509
 
                TEST_EQ (pos, 29);
1510
 
                TEST_EQ (lineno, 4);
1511
 
                TEST_ALLOC_SIZE (args, sizeof (char *) * 5);
1512
 
                TEST_EQ_STR (args[0], "this is");
1513
 
                TEST_EQ_STR (args[1], "a test");
1514
 
                TEST_EQ_STR (args[2], "and");
1515
 
                TEST_EQ_STR (args[3], "so");
1516
 
                TEST_EQ_P (args[4], NULL);
1517
 
 
1518
 
                nih_free (args);
1519
 
        }
1520
 
 
1521
 
 
1522
 
        /* Check that an empty line results in a one element array being
1523
 
         * returned containing only NULL, and the position being incremented
1524
 
         * past the empty line.
1525
 
         */
1526
 
        TEST_FEATURE ("with empty line");
1527
 
        TEST_ALLOC_FAIL {
1528
 
                strcpy (buf, "\nand so is this\n");
1529
 
                pos = 0;
1530
 
 
1531
 
                args = nih_config_parse_args (NULL, buf,
1532
 
                                              strlen (buf), &pos, NULL);
1533
 
 
1534
 
                if (test_alloc_failed) {
1535
 
                        TEST_EQ_P (args, NULL);
1536
 
 
1537
 
                        err = nih_error_get ();
1538
 
                        TEST_EQ (err->number, ENOMEM);
1539
 
                        nih_free (err);
1540
 
                        continue;
1541
 
                }
1542
 
 
1543
 
                TEST_EQ (pos, 1);
1544
 
                TEST_ALLOC_SIZE (args, sizeof (char *) * 1);
1545
 
                TEST_EQ_P (args[0], NULL);
1546
 
 
1547
 
                nih_free (args);
1548
 
        }
1549
 
 
1550
 
 
1551
 
        /* Check that a line containing only a comment results in a one
1552
 
         * element array being returned containing only NULL, and the
1553
 
         * position being incremented past the comment and newline.
1554
 
         */
1555
 
        TEST_FEATURE ("with only comment in line");
1556
 
        TEST_ALLOC_FAIL {
1557
 
                strcpy (buf, "# line with comment\nand so is this\n");
1558
 
                pos = 0;
1559
 
 
1560
 
                args = nih_config_parse_args (NULL, buf,
1561
 
                                              strlen (buf), &pos, NULL);
1562
 
 
1563
 
                if (test_alloc_failed) {
1564
 
                        TEST_EQ_P (args, NULL);
1565
 
 
1566
 
                        err = nih_error_get ();
1567
 
                        TEST_EQ (err->number, ENOMEM);
1568
 
                        nih_free (err);
1569
 
                        continue;
1570
 
                }
1571
 
 
1572
 
                TEST_EQ (pos, 20);
1573
 
                TEST_ALLOC_SIZE (args, sizeof (char *) * 1);
1574
 
                TEST_EQ_P (args[0], NULL);
1575
 
 
1576
 
                nih_free (args);
1577
 
        }
1578
 
 
1579
 
 
1580
 
        /* Check that an error parsing the arguments results in NULL being
1581
 
         * returned and the error raised.
1582
 
         */
1583
 
        TEST_FEATURE ("with parser error");
1584
 
        TEST_ALLOC_FAIL {
1585
 
                strcpy (buf, "this is a \"test\nand so is this\n");
1586
 
                pos = 0;
1587
 
                lineno = 1;
1588
 
 
1589
 
                args = nih_config_parse_args (NULL, buf,
1590
 
                                              strlen (buf), &pos, &lineno);
1591
 
 
1592
 
                TEST_EQ_P (args, NULL);
1593
 
                if (! test_alloc_failed) {
1594
 
                        TEST_EQ (pos, 31);
1595
 
                        TEST_EQ (lineno, 3);
1596
 
                }
1597
 
 
1598
 
                err = nih_error_get ();
1599
 
                if (! test_alloc_failed)
1600
 
                        TEST_EQ (err->number, NIH_CONFIG_UNTERMINATED_QUOTE);
1601
 
                nih_free (err);
1602
 
        }
1603
 
}
1604
 
 
1605
 
void
1606
 
test_parse_command (void)
1607
 
{
1608
 
        char       buf[1024];
1609
 
        char      *str;
1610
 
        size_t     pos, lineno;
1611
 
        NihError  *err;
1612
 
 
1613
 
        TEST_FUNCTION ("nih_config_parse_command");
1614
 
 
1615
 
        /* Check that we can parse a command from the start of a simple
1616
 
         * string.  It should be returned as an allocated string and the
1617
 
         * position should be updated to point to the start of the next line.
1618
 
         */
1619
 
        TEST_FEATURE ("with command at start of simple string");
1620
 
        TEST_ALLOC_FAIL {
1621
 
                strcpy (buf, "this is a test\nand so is this\n");
1622
 
                pos = 0;
1623
 
 
1624
 
                str = nih_config_parse_command (NULL, buf,
1625
 
                                                strlen (buf), &pos, NULL);
1626
 
 
1627
 
                if (test_alloc_failed) {
1628
 
                        TEST_EQ_P (str, NULL);
1629
 
                        TEST_EQ (pos, 0);
1630
 
 
1631
 
                        err = nih_error_get ();
1632
 
                        TEST_EQ (err->number, ENOMEM);
1633
 
                        nih_free (err);
1634
 
                        continue;
1635
 
                }
1636
 
 
1637
 
                TEST_EQ (pos, 15);
1638
 
                TEST_ALLOC_SIZE (str, 15);
1639
 
                TEST_EQ_STR (str, "this is a test");
1640
 
 
1641
 
                nih_free (str);
1642
 
        }
1643
 
 
1644
 
 
1645
 
        /* Check that we can parse a command from inside a string.
1646
 
         */
1647
 
        TEST_FEATURE ("with command inside simple string");
1648
 
        TEST_ALLOC_FAIL {
1649
 
                strcpy (buf, "this is a test\nand so is this\n");
1650
 
                pos = 5;
1651
 
 
1652
 
                str = nih_config_parse_command (NULL, buf,
1653
 
                                                strlen (buf), &pos, NULL);
1654
 
 
1655
 
                if (test_alloc_failed) {
1656
 
                        TEST_EQ_P (str, NULL);
1657
 
                        TEST_EQ (pos, 5);
1658
 
 
1659
 
                        err = nih_error_get ();
1660
 
                        TEST_EQ (err->number, ENOMEM);
1661
 
                        nih_free (err);
1662
 
                        continue;
1663
 
                }
1664
 
 
1665
 
                TEST_EQ (pos, 15);
1666
 
                TEST_ALLOC_SIZE (str, 10);
1667
 
                TEST_EQ_STR (str, "is a test");
1668
 
 
1669
 
                nih_free (str);
1670
 
        }
1671
 
 
1672
 
 
1673
 
        /* Check that we can parse a command that ends with the end of file.
1674
 
         */
1675
 
        TEST_FEATURE ("with command at end of file");
1676
 
        TEST_ALLOC_FAIL {
1677
 
                strcpy (buf, "this is a test");
1678
 
                pos = 0;
1679
 
 
1680
 
                str = nih_config_parse_command (NULL, buf,
1681
 
                                                strlen (buf), &pos, NULL);
1682
 
 
1683
 
                if (test_alloc_failed) {
1684
 
                        TEST_EQ_P (str, NULL);
1685
 
                        TEST_EQ (pos, 0);
1686
 
 
1687
 
                        err = nih_error_get ();
1688
 
                        TEST_EQ (err->number, ENOMEM);
1689
 
                        nih_free (err);
1690
 
                        continue;
1691
 
                }
1692
 
 
1693
 
                TEST_EQ (pos, 14);
1694
 
                TEST_ALLOC_SIZE (str, 15);
1695
 
                TEST_EQ_STR (str, "this is a test");
1696
 
 
1697
 
                nih_free (str);
1698
 
        }
1699
 
 
1700
 
 
1701
 
        /* Check that we can parse a command that ends with a comment,
1702
 
         * but the position should be incremented past the end of the comment.
1703
 
         */
1704
 
        TEST_FEATURE ("with command up to comment");
1705
 
        TEST_ALLOC_FAIL {
1706
 
                strcpy (buf, ("this is a test # this is a comment\n"
1707
 
                              "and so is this\n"));
1708
 
                pos = 0;
1709
 
                lineno = 1;
1710
 
 
1711
 
                str = nih_config_parse_command (NULL, buf, strlen (buf), &pos,
1712
 
                                                &lineno);
1713
 
 
1714
 
                if (test_alloc_failed) {
1715
 
                        TEST_EQ_P (str, NULL);
1716
 
                        TEST_EQ (pos, 0);
1717
 
                        TEST_EQ (lineno, 2);
1718
 
 
1719
 
                        err = nih_error_get ();
1720
 
                        TEST_EQ (err->number, ENOMEM);
1721
 
                        nih_free (err);
1722
 
                        continue;
1723
 
                }
1724
 
 
1725
 
                TEST_EQ (pos, 35);
1726
 
                TEST_EQ (lineno, 2);
1727
 
                TEST_ALLOC_SIZE (str, 15);
1728
 
                TEST_EQ_STR (str, "this is a test");
1729
 
 
1730
 
                nih_free (str);
1731
 
        }
1732
 
 
1733
 
 
1734
 
        /* Check that we can parse a command that ends with a comment which
1735
 
         * runs up to the end of file.
1736
 
         */
1737
 
        TEST_FEATURE ("with command up to comment at end of file");
1738
 
        TEST_ALLOC_FAIL {
1739
 
                strcpy (buf, "this is a test # this is a comment");
1740
 
                pos = 0;
1741
 
                lineno = 1;
1742
 
 
1743
 
                str = nih_config_parse_command (NULL, buf, strlen (buf), &pos,
1744
 
                                                &lineno);
1745
 
 
1746
 
                if (test_alloc_failed) {
1747
 
                        TEST_EQ_P (str, NULL);
1748
 
                        TEST_EQ (pos, 0);
1749
 
                        TEST_EQ (lineno, 1);
1750
 
 
1751
 
                        err = nih_error_get ();
1752
 
                        TEST_EQ (err->number, ENOMEM);
1753
 
                        nih_free (err);
1754
 
                        continue;
1755
 
                }
1756
 
 
1757
 
                TEST_EQ (pos, 34);
1758
 
                TEST_EQ (lineno, 1);
1759
 
                TEST_ALLOC_SIZE (str, 15);
1760
 
                TEST_EQ_STR (str, "this is a test");
1761
 
 
1762
 
                nih_free (str);
1763
 
        }
1764
 
 
1765
 
 
1766
 
        /* Check that the command is returned including any quotes,
1767
 
         * consecutive whitespace, but with any whitespace around a quoted
1768
 
         * or escaped newline collapsed to a single space.
1769
 
         */
1770
 
        TEST_FEATURE ("with quotes, whitespace and newlines in string");
1771
 
        TEST_ALLOC_FAIL {
1772
 
                strcpy (buf, ("\"this   is\" a \"test \\\n of\" \\\n "
1773
 
                              "commands\nfoo\n"));
1774
 
                pos = 0;
1775
 
                lineno = 1;
1776
 
 
1777
 
                str = nih_config_parse_command (NULL, buf, strlen (buf), &pos,
1778
 
                                                &lineno);
1779
 
 
1780
 
                if (test_alloc_failed) {
1781
 
                        TEST_EQ_P (str, NULL);
1782
 
                        TEST_EQ (pos, 0);
1783
 
 
1784
 
                        err = nih_error_get ();
1785
 
                        TEST_EQ (err->number, ENOMEM);
1786
 
                        nih_free (err);
1787
 
                        continue;
1788
 
                }
1789
 
 
1790
 
                TEST_EQ (pos, 39);
1791
 
                TEST_EQ (lineno, 4);
1792
 
                TEST_ALLOC_SIZE (str, 33);
1793
 
                TEST_EQ_STR (str, "\"this   is\" a \"test of\" commands");
1794
 
 
1795
 
                nih_free (str);
1796
 
        }
1797
 
 
1798
 
 
1799
 
        /* Check that we can parse an empty line, and have the empty string
1800
 
         * returned.  The position should be updated past the newline.
1801
 
         */
1802
 
        TEST_FEATURE ("with empty line");
1803
 
        TEST_ALLOC_FAIL {
1804
 
                strcpy (buf, "\nthis is a test\n");
1805
 
                pos = 0;
1806
 
 
1807
 
                str = nih_config_parse_command (NULL, buf,
1808
 
                                                strlen (buf), &pos, NULL);
1809
 
 
1810
 
                if (test_alloc_failed) {
1811
 
                        TEST_EQ_P (str, NULL);
1812
 
                        TEST_EQ (pos, 0);
1813
 
 
1814
 
                        err = nih_error_get ();
1815
 
                        TEST_EQ (err->number, ENOMEM);
1816
 
                        nih_free (err);
1817
 
                        continue;
1818
 
                }
1819
 
 
1820
 
                TEST_EQ (pos, 1);
1821
 
                TEST_ALLOC_SIZE (str, 1);
1822
 
                TEST_EQ_STR (str, "");
1823
 
 
1824
 
                nih_free (str);
1825
 
        }
1826
 
 
1827
 
 
1828
 
        /* Check that we can parse a line containing only whitespace, and
1829
 
         * have the empty string returned.  The position should be updated
1830
 
         * past the newline.
1831
 
         */
1832
 
        TEST_FEATURE ("with only whitespace in line");
1833
 
        TEST_ALLOC_FAIL {
1834
 
                strcpy (buf, "  \t  \nthis is a test\n");
1835
 
                pos = 0;
1836
 
 
1837
 
                str = nih_config_parse_command (NULL, buf,
1838
 
                                                strlen (buf), &pos, NULL);
1839
 
 
1840
 
                if (test_alloc_failed) {
1841
 
                        TEST_EQ_P (str, NULL);
1842
 
                        TEST_EQ (pos, 0);
1843
 
 
1844
 
                        err = nih_error_get ();
1845
 
                        TEST_EQ (err->number, ENOMEM);
1846
 
                        nih_free (err);
1847
 
                        continue;
1848
 
                }
1849
 
 
1850
 
                TEST_EQ (pos, 6);
1851
 
                TEST_ALLOC_SIZE (str, 1);
1852
 
                TEST_EQ_STR (str, "");
1853
 
 
1854
 
                nih_free (str);
1855
 
        }
1856
 
 
1857
 
 
1858
 
        /* Check that we can parse a line with a comment in it, and have
1859
 
         * the empty string returned.  The position should be updated past
1860
 
         * the newline.
1861
 
         */
1862
 
        TEST_FEATURE ("with only comment in line");
1863
 
        TEST_ALLOC_FAIL {
1864
 
                strcpy (buf, "# this is a test\nthis is a test\n");
1865
 
                pos = 0;
1866
 
 
1867
 
                str = nih_config_parse_command (NULL, buf,
1868
 
                                                strlen (buf), &pos, NULL);
1869
 
 
1870
 
                if (test_alloc_failed) {
1871
 
                        TEST_EQ_P (str, NULL);
1872
 
                        TEST_EQ (pos, 0);
1873
 
 
1874
 
                        err = nih_error_get ();
1875
 
                        TEST_EQ (err->number, ENOMEM);
1876
 
                        nih_free (err);
1877
 
                        continue;
1878
 
                }
1879
 
 
1880
 
                TEST_EQ (pos, 17);
1881
 
                TEST_ALLOC_SIZE (str, 1);
1882
 
                TEST_EQ_STR (str, "");
1883
 
 
1884
 
                nih_free (str);
1885
 
        }
1886
 
 
1887
 
 
1888
 
        /* Check that we can parse a line with whitespace before a comment,
1889
 
         * and have the empty string returned.  The position should be updated
1890
 
         * past the newline.
1891
 
         */
1892
 
        TEST_FEATURE ("with whitespace and comment in line");
1893
 
        TEST_ALLOC_FAIL {
1894
 
                strcpy (buf, "  # this is a test\nthis is a test\n");
1895
 
                pos = 0;
1896
 
 
1897
 
                str = nih_config_parse_command (NULL, buf,
1898
 
                                                strlen (buf), &pos, NULL);
1899
 
 
1900
 
                if (test_alloc_failed) {
1901
 
                        TEST_EQ_P (str, NULL);
1902
 
                        TEST_EQ (pos, 0);
1903
 
 
1904
 
                        err = nih_error_get ();
1905
 
                        TEST_EQ (err->number, ENOMEM);
1906
 
                        nih_free (err);
1907
 
                        continue;
1908
 
                }
1909
 
 
1910
 
                TEST_EQ (pos, 19);
1911
 
                TEST_ALLOC_SIZE (str, 1);
1912
 
                TEST_EQ_STR (str, "");
1913
 
 
1914
 
                nih_free (str);
1915
 
        }
1916
 
 
1917
 
 
1918
 
        /* Check that a parser error while reading the command results in
1919
 
         * NULL being returned and the error raised.
1920
 
         */
1921
 
        TEST_FEATURE ("with parser error");
1922
 
        TEST_ALLOC_FAIL {
1923
 
                strcpy (buf, "this is a \"test\nand so is this\n");
1924
 
                pos = 0;
1925
 
                lineno = 1;
1926
 
 
1927
 
                str = nih_config_parse_command (NULL, buf, strlen (buf), &pos,
1928
 
                                                &lineno);
1929
 
 
1930
 
                TEST_EQ_P (str, NULL);
1931
 
                TEST_EQ (pos, 31);
1932
 
                TEST_EQ (lineno, 3);
1933
 
 
1934
 
                err = nih_error_get ();
1935
 
                TEST_EQ (err->number, NIH_CONFIG_UNTERMINATED_QUOTE);
1936
 
                nih_free (err);
1937
 
        }
1938
 
}
1939
 
 
1940
 
 
1941
 
void
1942
 
test_parse_block (void)
1943
 
{
1944
 
        char      buf[1024];
1945
 
        char     *str;
1946
 
        size_t    pos, lineno;
1947
 
        NihError *err;
1948
 
 
1949
 
        TEST_FUNCTION ("nih_config_parse_block");
1950
 
        program_name = "test";
1951
 
 
1952
 
 
1953
 
        /* Check that we can parse consecutive lines until we reach one
1954
 
         * that ends the block.  The block should be returned as an allocated
1955
 
         * string with each line in it, except the terminator; the position
1956
 
         * should be positioned after the end of the terminator.
1957
 
         */
1958
 
        TEST_FEATURE ("with simple block");
1959
 
        TEST_ALLOC_FAIL {
1960
 
                strcpy (buf, "this is\na test\nend foo\nblah\n");
1961
 
                pos = 0;
1962
 
 
1963
 
                str = nih_config_parse_block (NULL, buf,
1964
 
                                              strlen (buf), &pos, NULL, "foo");
1965
 
 
1966
 
                if (test_alloc_failed) {
1967
 
                        TEST_EQ_P (str, NULL);
1968
 
                        TEST_EQ (pos, 0);
1969
 
 
1970
 
                        err = nih_error_get ();
1971
 
                        TEST_EQ (err->number, ENOMEM);
1972
 
                        nih_free (err);
1973
 
                        continue;
1974
 
                }
1975
 
 
1976
 
                TEST_EQ (pos, 23);
1977
 
                TEST_ALLOC_SIZE (str, 16);
1978
 
                TEST_EQ_STR (str, "this is\na test\n");
1979
 
 
1980
 
                nih_free (str);
1981
 
        }
1982
 
 
1983
 
 
1984
 
        /* Check that the line number is incremented for each line that we
1985
 
         * discover in the block, including the terminating line.
1986
 
         */
1987
 
        TEST_FEATURE ("with line number set");
1988
 
        TEST_ALLOC_FAIL {
1989
 
                pos = 0;
1990
 
                lineno = 2;
1991
 
 
1992
 
                str = nih_config_parse_block (NULL, buf,
1993
 
                                              strlen (buf), &pos, &lineno,
1994
 
                                              "foo");
1995
 
 
1996
 
                if (test_alloc_failed) {
1997
 
                        TEST_EQ_P (str, NULL);
1998
 
                        TEST_EQ (pos, 0);
1999
 
 
2000
 
                        err = nih_error_get ();
2001
 
                        TEST_EQ (err->number, ENOMEM);
2002
 
                        nih_free (err);
2003
 
                        continue;
2004
 
                }
2005
 
 
2006
 
                TEST_EQ (pos, 23);
2007
 
                TEST_EQ (lineno, 5);
2008
 
                TEST_ALLOC_SIZE (str, 16);
2009
 
                TEST_EQ_STR (str, "this is\na test\n");
2010
 
 
2011
 
                nih_free (str);
2012
 
        }
2013
 
 
2014
 
 
2015
 
        /* Check that the common initial whitespace from each line is stripped,
2016
 
         * where common is defined as identical character sequences, not number
2017
 
         * of whitespace chars.
2018
 
         */
2019
 
        TEST_FEATURE ("with whitespace at start of block");
2020
 
        TEST_ALLOC_FAIL {
2021
 
                strcpy (buf, "    this is\n  \t a test\nend foo\nblah\n");
2022
 
                pos = 0;
2023
 
 
2024
 
                str = nih_config_parse_block (NULL, buf,
2025
 
                                              strlen (buf), &pos, NULL, "foo");
2026
 
 
2027
 
                if (test_alloc_failed) {
2028
 
                        TEST_EQ_P (str, NULL);
2029
 
                        TEST_EQ (pos, 0);
2030
 
 
2031
 
                        err = nih_error_get ();
2032
 
                        TEST_EQ (err->number, ENOMEM);
2033
 
                        nih_free (err);
2034
 
                        continue;
2035
 
                }
2036
 
 
2037
 
                TEST_EQ (pos, 31);
2038
 
                TEST_ALLOC_SIZE (str, 20);
2039
 
                TEST_EQ_STR (str, "  this is\n\t a test\n");
2040
 
 
2041
 
                nih_free (str);
2042
 
        }
2043
 
 
2044
 
 
2045
 
        /* Check that we can parse a block that ends in a terminator with
2046
 
         * extraneous whitespace around the words.
2047
 
         */
2048
 
        TEST_FEATURE ("with whitespace in terminator");
2049
 
        TEST_ALLOC_FAIL {
2050
 
                strcpy (buf, "this is\na test\n  end \t foo  \nblah\n");
2051
 
                pos = 0;
2052
 
 
2053
 
                str = nih_config_parse_block (NULL, buf,
2054
 
                                              strlen (buf), &pos, NULL, "foo");
2055
 
 
2056
 
                if (test_alloc_failed) {
2057
 
                        TEST_EQ_P (str, NULL);
2058
 
                        TEST_EQ (pos, 0);
2059
 
 
2060
 
                        err = nih_error_get ();
2061
 
                        TEST_EQ (err->number, ENOMEM);
2062
 
                        nih_free (err);
2063
 
                        continue;
2064
 
                }
2065
 
 
2066
 
                TEST_EQ (pos, 29);
2067
 
                TEST_ALLOC_SIZE (str, 16);
2068
 
                TEST_EQ_STR (str, "this is\na test\n");
2069
 
 
2070
 
                nih_free (str);
2071
 
        }
2072
 
 
2073
 
 
2074
 
        /* Check that we can parse a block that ends in a terminator which
2075
 
         * is at the end of the file.
2076
 
         */
2077
 
        TEST_FEATURE ("with terminator at end of file");
2078
 
        TEST_ALLOC_FAIL {
2079
 
                strcpy (buf, "this is\na test\nend foo");
2080
 
                pos = 0;
2081
 
 
2082
 
                str = nih_config_parse_block (NULL, buf,
2083
 
                                              strlen (buf), &pos, NULL, "foo");
2084
 
 
2085
 
                if (test_alloc_failed) {
2086
 
                        TEST_EQ_P (str, NULL);
2087
 
                        TEST_EQ (pos, 0);
2088
 
 
2089
 
                        err = nih_error_get ();
2090
 
                        TEST_EQ (err->number, ENOMEM);
2091
 
                        nih_free (err);
2092
 
                        continue;
2093
 
                }
2094
 
 
2095
 
                TEST_EQ (pos, 22);
2096
 
                TEST_ALLOC_SIZE (str, 16);
2097
 
                TEST_EQ_STR (str, "this is\na test\n");
2098
 
 
2099
 
                nih_free (str);
2100
 
        }
2101
 
 
2102
 
 
2103
 
        /* Check that we can parse a block that ends in a terminator which
2104
 
         * has a comment following it.
2105
 
         */
2106
 
        TEST_FEATURE ("with terminator and comment");
2107
 
        TEST_ALLOC_FAIL {
2108
 
                strcpy (buf, "this is\na test\nend foo # comment\ntest\n");
2109
 
                pos = 0;
2110
 
 
2111
 
                str = nih_config_parse_block (NULL, buf,
2112
 
                                              strlen (buf), &pos, NULL, "foo");
2113
 
 
2114
 
                if (test_alloc_failed) {
2115
 
                        TEST_EQ_P (str, NULL);
2116
 
                        TEST_EQ (pos, 0);
2117
 
 
2118
 
                        err = nih_error_get ();
2119
 
                        TEST_EQ (err->number, ENOMEM);
2120
 
                        nih_free (err);
2121
 
                        continue;
2122
 
                }
2123
 
 
2124
 
                TEST_EQ (pos, 33);
2125
 
                TEST_ALLOC_SIZE (str, 16);
2126
 
                TEST_EQ_STR (str, "this is\na test\n");
2127
 
 
2128
 
                nih_free (str);
2129
 
        }
2130
 
 
2131
 
 
2132
 
        /* Check that we can parse a block that ends in a terminator which
2133
 
         * has a comment and then the end of file.
2134
 
         */
2135
 
        TEST_FEATURE ("with terminator and comment at end of file");
2136
 
        TEST_ALLOC_FAIL {
2137
 
                strcpy (buf, "this is\na test\nend foo # comment");
2138
 
                pos = 0;
2139
 
 
2140
 
                str = nih_config_parse_block (NULL, buf,
2141
 
                                              strlen (buf), &pos, NULL, "foo");
2142
 
 
2143
 
                if (test_alloc_failed) {
2144
 
                        TEST_EQ_P (str, NULL);
2145
 
                        TEST_EQ (pos, 0);
2146
 
 
2147
 
                        err = nih_error_get ();
2148
 
                        TEST_EQ (err->number, ENOMEM);
2149
 
                        nih_free (err);
2150
 
                        continue;
2151
 
                }
2152
 
 
2153
 
                TEST_EQ (pos, 32);
2154
 
                TEST_ALLOC_SIZE (str, 16);
2155
 
                TEST_EQ_STR (str, "this is\na test\n");
2156
 
 
2157
 
                nih_free (str);
2158
 
        }
2159
 
 
2160
 
 
2161
 
        /* Check that various bogus forms of terminator are ignored.
2162
 
         */
2163
 
        TEST_FEATURE ("with various things that aren't terminators");
2164
 
        TEST_ALLOC_FAIL {
2165
 
                strcpy (buf, "endfoo\nend a\nend fooish\nend foo\ntest\n");
2166
 
                pos = 0;
2167
 
 
2168
 
                str = nih_config_parse_block (NULL, buf,
2169
 
                                              strlen (buf), &pos, NULL, "foo");
2170
 
 
2171
 
                if (test_alloc_failed) {
2172
 
                        TEST_EQ_P (str, NULL);
2173
 
                        TEST_EQ (pos, 0);
2174
 
 
2175
 
                        err = nih_error_get ();
2176
 
                        TEST_EQ (err->number, ENOMEM);
2177
 
                        nih_free (err);
2178
 
                        continue;
2179
 
                }
2180
 
 
2181
 
                TEST_EQ (pos, 32);
2182
 
                TEST_ALLOC_SIZE (str, 25);
2183
 
                TEST_EQ_STR (str, "endfoo\nend a\nend fooish\n");
2184
 
 
2185
 
                nih_free (str);
2186
 
        }
2187
 
 
2188
 
 
2189
 
        /* Check that reaching the end of the file without finding the block
2190
 
         * terminator causes an error to be raised and NULL to be returned.
2191
 
         */
2192
 
        TEST_FEATURE ("with no terminator before end of file");
2193
 
        TEST_ALLOC_FAIL {
2194
 
                strcpy (buf, "this is\na test\n");
2195
 
                pos = 0;
2196
 
                lineno = 2;
2197
 
 
2198
 
                str = nih_config_parse_block (NULL, buf,
2199
 
                                              strlen (buf), &pos, &lineno,
2200
 
                                              "foo");
2201
 
 
2202
 
                TEST_EQ_P (str, NULL);
2203
 
                TEST_EQ (pos, 15);
2204
 
                TEST_EQ (lineno, 4);
2205
 
 
2206
 
                err = nih_error_get ();
2207
 
                TEST_EQ (err->number, NIH_CONFIG_UNTERMINATED_BLOCK);
2208
 
                nih_free (err);
2209
 
        }
2210
 
}
2211
 
 
2212
 
void
2213
 
test_skip_block (void)
2214
 
{
2215
 
        char      buf[1024];
2216
 
        int       ret;
2217
 
        size_t    pos, lineno, endpos;
2218
 
        NihError *err;
2219
 
 
2220
 
        TEST_FUNCTION ("nih_config_skip_block");
2221
 
        program_name = "test";
2222
 
 
2223
 
 
2224
 
        /* Check that we can find the end of a simple block.  pos should be
2225
 
         * updated to point past the block, and the returned endpos should
2226
 
         * point at the end of the block itself.
2227
 
         */
2228
 
        TEST_FEATURE ("with simple block");
2229
 
        strcpy (buf, "this is\na test\nend foo\nblah\n");
2230
 
        pos = 0;
2231
 
 
2232
 
        ret = nih_config_skip_block (buf, strlen (buf), &pos, NULL,
2233
 
                                     "foo", &endpos);
2234
 
 
2235
 
        TEST_EQ (ret, 0);
2236
 
        TEST_EQ (pos, 23);
2237
 
        TEST_EQ (endpos, 15);
2238
 
 
2239
 
 
2240
 
        /* Check that the line number is incremented for each line that we
2241
 
         * discover in the block, including the terminating line.
2242
 
         */
2243
 
        TEST_FEATURE ("with line number set");
2244
 
        pos = 0;
2245
 
        lineno = 2;
2246
 
 
2247
 
        ret = nih_config_skip_block (buf, strlen (buf), &pos, &lineno,
2248
 
                                     "foo", &endpos);
2249
 
 
2250
 
        TEST_EQ (ret, 0);
2251
 
        TEST_EQ (pos, 23);
2252
 
        TEST_EQ (endpos, 15);
2253
 
        TEST_EQ (lineno, 5);
2254
 
 
2255
 
 
2256
 
        /* Check that we can find the end of a block that ends in a terminator
2257
 
         * with extraneous whitespace around the words.
2258
 
         */
2259
 
        TEST_FEATURE ("with whitespace in terminator");
2260
 
        strcpy (buf, "this is\na test\n  end \t foo  \nblah\n");
2261
 
        pos = 0;
2262
 
 
2263
 
        ret = nih_config_skip_block (buf, strlen (buf), &pos, NULL,
2264
 
                                     "foo", &endpos);
2265
 
 
2266
 
        TEST_EQ (ret, 0);
2267
 
        TEST_EQ (pos, 29);
2268
 
        TEST_EQ (endpos, 15);
2269
 
 
2270
 
 
2271
 
        /* Check that we can find the end of a block that ends in a
2272
 
         * terminator which is at the end of the file.
2273
 
         */
2274
 
        TEST_FEATURE ("with terminator at end of file");
2275
 
        strcpy (buf, "this is\na test\nend foo");
2276
 
        pos = 0;
2277
 
 
2278
 
        ret = nih_config_skip_block (buf, strlen (buf), &pos, NULL,
2279
 
                                     "foo", &endpos);
2280
 
 
2281
 
        TEST_EQ (ret, 0);
2282
 
        TEST_EQ (pos, 22);
2283
 
        TEST_EQ (endpos, 15);
2284
 
 
2285
 
 
2286
 
        /* Check that we can find the end of a block that ends in a
2287
 
         * terminator which has a comment following it.
2288
 
         */
2289
 
        TEST_FEATURE ("with terminator and comment");
2290
 
        strcpy (buf, "this is\na test\nend foo # comment\ntest\n");
2291
 
        pos = 0;
2292
 
 
2293
 
        ret = nih_config_skip_block (buf, strlen (buf), &pos, NULL,
2294
 
                                     "foo", &endpos);
2295
 
 
2296
 
        TEST_EQ (ret, 0);
2297
 
        TEST_EQ (pos, 33);
2298
 
        TEST_EQ (endpos, 15);
2299
 
 
2300
 
 
2301
 
        /* Check that we can find the end of a block that ends in a
2302
 
         * terminator which has a comment and then the end of file.
2303
 
         */
2304
 
        TEST_FEATURE ("with terminator and comment at end of file");
2305
 
        strcpy (buf, "this is\na test\nend foo # comment");
2306
 
        pos = 0;
2307
 
 
2308
 
        ret = nih_config_skip_block (buf, strlen (buf), &pos, NULL,
2309
 
                                     "foo", &endpos);
2310
 
 
2311
 
        TEST_EQ (ret, 0);
2312
 
        TEST_EQ (pos, 32);
2313
 
        TEST_EQ (endpos, 15);
2314
 
 
2315
 
 
2316
 
        /* Check that various bogus forms of terminator are ignored.
2317
 
         */
2318
 
        TEST_FEATURE ("with various things that aren't terminators");
2319
 
        strcpy (buf, "endfoo\nend a\nend fooish\nend foo\ntest\n");
2320
 
        pos = 0;
2321
 
 
2322
 
        ret = nih_config_skip_block (buf, strlen (buf), &pos, NULL,
2323
 
                                     "foo", &endpos);
2324
 
 
2325
 
        TEST_EQ (ret, 0);
2326
 
        TEST_EQ (pos, 32);
2327
 
        TEST_EQ (endpos, 24);
2328
 
 
2329
 
 
2330
 
        /* Check that reaching the end of the file without finding the block
2331
 
         * terminator causes an error to be raised and NULL to be returned.
2332
 
         */
2333
 
        TEST_FEATURE ("with no terminator before end of file");
2334
 
        strcpy (buf, "this is\na test\n");
2335
 
        pos = 0;
2336
 
        lineno = 2;
2337
 
 
2338
 
        ret = nih_config_skip_block (buf, strlen (buf), &pos, &lineno,
2339
 
                                     "foo", &endpos);
2340
 
 
2341
 
        TEST_LT (ret, 0);
2342
 
        TEST_EQ (pos, 15);
2343
 
        TEST_EQ (lineno, 4);
2344
 
 
2345
 
        err = nih_error_get ();
2346
 
        TEST_EQ (err->number, NIH_CONFIG_UNTERMINATED_BLOCK);
2347
 
        nih_free (err);
2348
 
}
2349
 
 
2350
 
 
2351
 
static int handler_called = 0;
2352
 
static void *last_data = NULL;
2353
 
static NihConfigStanza *last_stanza = NULL;
2354
 
static const char *last_file = NULL;
2355
 
static size_t last_len = 0;
2356
 
static size_t last_pos = 0;
2357
 
static size_t last_lineno = 0;
2358
 
 
2359
 
static int
2360
 
my_handler (void            *data,
2361
 
            NihConfigStanza *stanza,
2362
 
            const char      *file,
2363
 
            size_t           len,
2364
 
            size_t          *pos,
2365
 
            size_t          *lineno)
2366
 
{
2367
 
        handler_called++;
2368
 
 
2369
 
        last_data = data;
2370
 
        last_stanza = stanza;
2371
 
        last_file = file;
2372
 
        last_len = len;
2373
 
        last_pos = *pos;
2374
 
        if (lineno) {
2375
 
                last_lineno = *lineno;
2376
 
        } else {
2377
 
                last_lineno = -1;
2378
 
        }
2379
 
 
2380
 
        if (strcmp (stanza->name, "foo"))
2381
 
                nih_config_next_line (file, len, pos, lineno);
2382
 
 
2383
 
        return 100;
2384
 
}
2385
 
 
2386
 
static NihConfigStanza stanzas[] = {
2387
 
        { "foo", my_handler },
2388
 
        { "bar", my_handler },
2389
 
 
2390
 
        { "frodo", my_handler },
2391
 
        { "bilbo", my_handler },
2392
 
 
2393
 
        NIH_CONFIG_LAST
2394
 
};
2395
 
 
2396
 
static NihConfigStanza any_stanzas[] = {
2397
 
        { "", my_handler },
2398
 
 
2399
 
        NIH_CONFIG_LAST
2400
 
};
2401
 
 
2402
 
void
2403
 
test_parse_stanza (void)
2404
 
{
2405
 
        char      buf[1024];
2406
 
        size_t    pos, lineno;
2407
 
        int       ret;
2408
 
        NihError *err;
2409
 
 
2410
 
        TEST_FUNCTION ("nih_config_stanza");
2411
 
        program_name = "test";
2412
 
 
2413
 
 
2414
 
        /* Check that the handler is called with all of the right arguments
2415
 
         * if the stanza is found at the start of the string.  The pos should
2416
 
         * only be incremented up to the point after the first argument,
2417
 
         * leaving it up to the stanza handler to increment it.
2418
 
         */
2419
 
        TEST_FEATURE ("with stanza at start of string");
2420
 
        strcpy (buf, "foo this is a test\nwibble\n");
2421
 
 
2422
 
        handler_called = 0;
2423
 
        last_data = NULL;
2424
 
        last_file = NULL;
2425
 
        last_len = 0;
2426
 
        last_pos = -1;
2427
 
        last_lineno = 0;
2428
 
 
2429
 
        ret = nih_config_parse_stanza (buf, strlen (buf), NULL, NULL,
2430
 
                                       stanzas, &ret);
2431
 
 
2432
 
        TEST_TRUE (handler_called);
2433
 
        TEST_EQ_P (last_data, &ret);
2434
 
        TEST_EQ_P (last_file, buf);
2435
 
        TEST_EQ (last_len, strlen (buf));
2436
 
        TEST_EQ (last_pos, 4);
2437
 
        TEST_EQ (last_lineno, (size_t)-1);
2438
 
 
2439
 
        TEST_EQ (ret, 100);
2440
 
 
2441
 
 
2442
 
        /* Check that the handler can be called with a position inside the
2443
 
         * string.
2444
 
         */
2445
 
        TEST_FEATURE ("with stanza inside string");
2446
 
        strcpy (buf, "snarf foo this is a test\nwibble\n");
2447
 
        pos = 6;
2448
 
 
2449
 
        handler_called = 0;
2450
 
        last_data = NULL;
2451
 
        last_file = NULL;
2452
 
        last_len = 0;
2453
 
        last_pos = -1;
2454
 
        last_lineno = 0;
2455
 
 
2456
 
        ret = nih_config_parse_stanza (buf, strlen (buf), &pos, NULL,
2457
 
                                       stanzas, &ret);
2458
 
 
2459
 
        TEST_TRUE (handler_called);
2460
 
        TEST_EQ_P (last_data, &ret);
2461
 
        TEST_EQ_P (last_file, buf);
2462
 
        TEST_EQ (last_len, strlen (buf));
2463
 
        TEST_EQ (last_pos, 10);
2464
 
        TEST_EQ (last_lineno, (size_t)-1);
2465
 
 
2466
 
        TEST_EQ (ret, 100);
2467
 
        TEST_EQ (pos, 10);
2468
 
 
2469
 
 
2470
 
        /* Check that the position can be updated by the handler function
2471
 
         * to point wherever it thinks the stanza ends.
2472
 
         */
2473
 
        TEST_FEATURE ("with position moved by stanza");
2474
 
        strcpy (buf, "bar this is a test\nwibble\n");
2475
 
        pos = 0;
2476
 
        lineno = 1;
2477
 
 
2478
 
        handler_called = 0;
2479
 
        last_data = NULL;
2480
 
        last_file = NULL;
2481
 
        last_len = 0;
2482
 
        last_pos = -1;
2483
 
        last_lineno = 0;
2484
 
 
2485
 
        ret = nih_config_parse_stanza (buf, strlen (buf), &pos, &lineno,
2486
 
                                       stanzas, &ret);
2487
 
 
2488
 
        TEST_TRUE (handler_called);
2489
 
        TEST_EQ_P (last_data, &ret);
2490
 
        TEST_EQ_P (last_file, buf);
2491
 
        TEST_EQ (last_len, strlen (buf));
2492
 
        TEST_EQ (last_pos, 4);
2493
 
        TEST_EQ (last_lineno, 1);
2494
 
 
2495
 
        TEST_EQ (ret, 100);
2496
 
        TEST_EQ (pos, 19);
2497
 
        TEST_EQ (lineno, 2);
2498
 
 
2499
 
 
2500
 
        /* Check that finding an unknown stanza results in an error being
2501
 
         * raised, and no handler called.
2502
 
         */
2503
 
        TEST_FEATURE ("with unknown stanza");
2504
 
        strcpy (buf, "wibble this is a test\nwibble\n");
2505
 
        pos = 0;
2506
 
        lineno = 1;
2507
 
 
2508
 
        handler_called = 0;
2509
 
 
2510
 
        ret = nih_config_parse_stanza (buf, strlen (buf), &pos, &lineno,
2511
 
                                       stanzas, &ret);
2512
 
 
2513
 
        TEST_FALSE (handler_called);
2514
 
        TEST_LT (ret, 0);
2515
 
        TEST_EQ (pos, 0);
2516
 
        TEST_EQ (lineno, 1);
2517
 
 
2518
 
        err = nih_error_get ();
2519
 
        TEST_EQ (err->number, NIH_CONFIG_UNKNOWN_STANZA);
2520
 
        nih_free (err);
2521
 
 
2522
 
 
2523
 
        /* Check that unknown stanzas can be handled by an entry in the
2524
 
         * table with a zero-length name.
2525
 
         */
2526
 
        TEST_FEATURE ("with unknown stanza and catch-all");
2527
 
        pos = 0;
2528
 
 
2529
 
        handler_called = 0;
2530
 
        last_data = NULL;
2531
 
        last_file = NULL;
2532
 
        last_len = 0;
2533
 
        last_pos = -1;
2534
 
        last_lineno = 0;
2535
 
 
2536
 
        ret = nih_config_parse_stanza (buf, strlen (buf), NULL, NULL,
2537
 
                                       any_stanzas, &ret);
2538
 
 
2539
 
        TEST_TRUE (handler_called);
2540
 
        TEST_EQ_P (last_data, &ret);
2541
 
        TEST_EQ_P (last_file, buf);
2542
 
        TEST_EQ (last_len, strlen (buf));
2543
 
        TEST_EQ (last_pos, 7);
2544
 
        TEST_EQ (last_lineno, (size_t)-1);
2545
 
 
2546
 
        TEST_EQ (ret, 100);
2547
 
 
2548
 
 
2549
 
        /* Check that an error is raised if there is no stanza at this
2550
 
         * position in the file.
2551
 
         */
2552
 
        TEST_FEATURE ("with empty line");
2553
 
        strcpy (buf, "\nfoo this is a test\n");
2554
 
        pos = 0;
2555
 
        lineno = 1;
2556
 
 
2557
 
        handler_called = 0;
2558
 
 
2559
 
        ret = nih_config_parse_stanza (buf, strlen (buf), &pos, &lineno,
2560
 
                                       stanzas, &ret);
2561
 
 
2562
 
        TEST_FALSE (handler_called);
2563
 
        TEST_LT (ret, 0);
2564
 
        TEST_EQ (pos, 0);
2565
 
        TEST_EQ (lineno, 1);
2566
 
 
2567
 
        err = nih_error_get ();
2568
 
        TEST_EQ (err->number, NIH_CONFIG_EXPECTED_TOKEN);
2569
 
        nih_free (err);
2570
 
}
2571
 
 
2572
 
 
2573
 
void
2574
 
test_parse_file (void)
2575
 
{
2576
 
        char      buf[1024];
2577
 
        size_t    pos, lineno;
2578
 
        int       ret;
2579
 
        NihError *err;
2580
 
 
2581
 
        TEST_FUNCTION ("nih_config_parse_file");
2582
 
 
2583
 
 
2584
 
        /* Check that a simple sequence of stanzas is parsed, with the
2585
 
         * handler being called for each.  When finished, the position
2586
 
         * should be past the end of the file.
2587
 
         */
2588
 
        TEST_FEATURE ("with simple lines");
2589
 
        strcpy (buf, "frodo test\nbilbo test\n");
2590
 
        pos = 0;
2591
 
        lineno = 1;
2592
 
 
2593
 
        handler_called = 0;
2594
 
        last_data = NULL;
2595
 
        last_file = NULL;
2596
 
        last_len = 0;
2597
 
        last_pos = -1;
2598
 
        last_lineno = 0;
2599
 
 
2600
 
        ret = nih_config_parse_file (buf, strlen (buf), &pos, &lineno,
2601
 
                                     stanzas, &buf);
2602
 
 
2603
 
        TEST_EQ (ret, 0);
2604
 
        TEST_EQ (pos, 22);
2605
 
 
2606
 
        TEST_EQ (handler_called, 2);
2607
 
        TEST_EQ_P (last_data, &buf);
2608
 
        TEST_EQ_P (last_file, buf);
2609
 
        TEST_EQ (last_len, strlen (buf));
2610
 
        TEST_EQ (last_pos, 17);
2611
 
        TEST_EQ (last_lineno, 2);
2612
 
 
2613
 
 
2614
 
        /* Check that a line ending in a comment can be parsed, with the
2615
 
         * comment skipped.
2616
 
         */
2617
 
        TEST_FEATURE ("with comment at end of line");
2618
 
        strcpy (buf, "frodo test # foo comment\nbilbo test\n");
2619
 
        pos = 0;
2620
 
        lineno = 1;
2621
 
 
2622
 
        handler_called = 0;
2623
 
        last_data = NULL;
2624
 
        last_file = NULL;
2625
 
        last_len = 0;
2626
 
        last_pos = -1;
2627
 
        last_lineno = 0;
2628
 
 
2629
 
        ret = nih_config_parse_file (buf, strlen (buf), &pos, &lineno,
2630
 
                                     stanzas, &buf);
2631
 
 
2632
 
        TEST_EQ (ret, 0);
2633
 
        TEST_EQ (pos, 36);
2634
 
 
2635
 
        TEST_EQ (handler_called, 2);
2636
 
        TEST_EQ_P (last_data, &buf);
2637
 
        TEST_EQ_P (last_file, buf);
2638
 
        TEST_EQ (last_len, strlen (buf));
2639
 
        TEST_EQ (last_pos, 31);
2640
 
        TEST_EQ (last_lineno, 2);
2641
 
 
2642
 
 
2643
 
        /* Check that whitespace at the start of a line is skipped. */
2644
 
        TEST_FEATURE ("with whitespace at start of line");
2645
 
        strcpy (buf, "    frodo test\n  \t \t bilbo test\n");
2646
 
        pos = 0;
2647
 
        lineno = 1;
2648
 
 
2649
 
        handler_called = 0;
2650
 
        last_data = NULL;
2651
 
        last_file = NULL;
2652
 
        last_len = 0;
2653
 
        last_pos = -1;
2654
 
        last_lineno = 0;
2655
 
 
2656
 
        ret = nih_config_parse_file (buf, strlen (buf), &pos, &lineno,
2657
 
                                     stanzas, &buf);
2658
 
 
2659
 
        TEST_EQ (ret, 0);
2660
 
        TEST_EQ (pos, 32);
2661
 
 
2662
 
        TEST_EQ (handler_called, 2);
2663
 
        TEST_EQ_P (last_data, &buf);
2664
 
        TEST_EQ_P (last_file, buf);
2665
 
        TEST_EQ (last_len, strlen (buf));
2666
 
        TEST_EQ (last_pos, 27);
2667
 
        TEST_EQ (last_lineno, 2);
2668
 
 
2669
 
 
2670
 
        /* Check that an empty line is skipped over properly. */
2671
 
        TEST_FEATURE ("with empty line");
2672
 
        strcpy (buf, "\nfrodo test\nbilbo test\n");
2673
 
        pos = 0;
2674
 
        lineno = 1;
2675
 
 
2676
 
        handler_called = 0;
2677
 
        last_data = NULL;
2678
 
        last_file = NULL;
2679
 
        last_len = 0;
2680
 
        last_pos = -1;
2681
 
        last_lineno = 0;
2682
 
 
2683
 
        ret = nih_config_parse_file (buf, strlen (buf), &pos, &lineno,
2684
 
                                     stanzas, &buf);
2685
 
 
2686
 
        TEST_EQ (ret, 0);
2687
 
        TEST_EQ (pos, 23);
2688
 
 
2689
 
        TEST_EQ (handler_called, 2);
2690
 
        TEST_EQ_P (last_data, &buf);
2691
 
        TEST_EQ_P (last_file, buf);
2692
 
        TEST_EQ (last_len, strlen (buf));
2693
 
        TEST_EQ (last_pos, 18);
2694
 
        TEST_EQ (last_lineno, 3);
2695
 
 
2696
 
 
2697
 
        /* Check that a line containing whitespace is skipped over. */
2698
 
        TEST_FEATURE ("with line containing only whitespace");
2699
 
        strcpy (buf, "  \t  \nfrodo test\nbilbo test\n");
2700
 
        pos = 0;
2701
 
        lineno = 1;
2702
 
 
2703
 
        handler_called = 0;
2704
 
        last_data = NULL;
2705
 
        last_file = NULL;
2706
 
        last_len = 0;
2707
 
        last_pos = -1;
2708
 
        last_lineno = 0;
2709
 
 
2710
 
        ret = nih_config_parse_file (buf, strlen (buf), &pos, &lineno,
2711
 
                                     stanzas, &buf);
2712
 
 
2713
 
        TEST_EQ (ret, 0);
2714
 
        TEST_EQ (pos, 28);
2715
 
 
2716
 
        TEST_EQ (handler_called, 2);
2717
 
        TEST_EQ_P (last_data, &buf);
2718
 
        TEST_EQ_P (last_file, buf);
2719
 
        TEST_EQ (last_len, strlen (buf));
2720
 
        TEST_EQ (last_pos, 23);
2721
 
        TEST_EQ (last_lineno, 3);
2722
 
 
2723
 
 
2724
 
        /* Check that a line containing a comment is skipped over. */
2725
 
        TEST_FEATURE ("with line containing only a comment");
2726
 
        strcpy (buf, "# hello\nfrodo test\nbilbo test\n");
2727
 
        pos = 0;
2728
 
        lineno = 1;
2729
 
 
2730
 
        handler_called = 0;
2731
 
        last_data = NULL;
2732
 
        last_file = NULL;
2733
 
        last_len = 0;
2734
 
        last_pos = -1;
2735
 
        last_lineno = 0;
2736
 
 
2737
 
        ret = nih_config_parse_file (buf, strlen (buf), &pos, &lineno,
2738
 
                                     stanzas, &buf);
2739
 
 
2740
 
        TEST_EQ (ret, 0);
2741
 
        TEST_EQ (pos, 30);
2742
 
 
2743
 
        TEST_EQ (handler_called, 2);
2744
 
        TEST_EQ_P (last_data, &buf);
2745
 
        TEST_EQ_P (last_file, buf);
2746
 
        TEST_EQ (last_len, strlen (buf));
2747
 
        TEST_EQ (last_pos, 25);
2748
 
        TEST_EQ (last_lineno, 3);
2749
 
 
2750
 
 
2751
 
        /* Check that a line containing a comment after some whitespace
2752
 
         * is skipped over.
2753
 
         */
2754
 
        TEST_FEATURE ("with line containing a comment and whitespace");
2755
 
        strcpy (buf, "  \t  # hello\nfrodo test\nbilbo test\n");
2756
 
        pos = 0;
2757
 
        lineno = 1;
2758
 
 
2759
 
        handler_called = 0;
2760
 
        last_data = NULL;
2761
 
        last_file = NULL;
2762
 
        last_len = 0;
2763
 
        last_pos = -1;
2764
 
        last_lineno = 0;
2765
 
 
2766
 
        ret = nih_config_parse_file (buf, strlen (buf), &pos, &lineno,
2767
 
                                     stanzas, &buf);
2768
 
 
2769
 
        TEST_EQ (ret, 0);
2770
 
        TEST_EQ (pos, 35);
2771
 
 
2772
 
        TEST_EQ (handler_called, 2);
2773
 
        TEST_EQ_P (last_data, &buf);
2774
 
        TEST_EQ_P (last_file, buf);
2775
 
        TEST_EQ (last_len, strlen (buf));
2776
 
        TEST_EQ (last_pos, 30);
2777
 
        TEST_EQ (last_lineno, 3);
2778
 
 
2779
 
 
2780
 
        /* Check that a parser error is raised with the position and line
2781
 
         * number set to where it was found.  Only handlers up to that point
2782
 
         * should be called.
2783
 
         */
2784
 
        TEST_FEATURE ("with parser error");
2785
 
        strcpy (buf, "frodo test\n\"bilbo test\n");
2786
 
        pos = 0;
2787
 
        lineno = 1;
2788
 
 
2789
 
        handler_called = 0;
2790
 
        last_data = NULL;
2791
 
        last_file = NULL;
2792
 
        last_len = 0;
2793
 
        last_pos = -1;
2794
 
        last_lineno = 0;
2795
 
 
2796
 
        ret = nih_config_parse_file (buf, strlen (buf), &pos, &lineno,
2797
 
                                     stanzas, &buf);
2798
 
 
2799
 
        TEST_LT (ret, 0);
2800
 
        TEST_EQ (pos, 23);
2801
 
        TEST_EQ (lineno, 3);
2802
 
 
2803
 
        TEST_EQ (handler_called, 1);
2804
 
        TEST_EQ_P (last_data, &buf);
2805
 
        TEST_EQ_P (last_file, buf);
2806
 
        TEST_EQ (last_len, strlen (buf));
2807
 
        TEST_EQ (last_pos, 6);
2808
 
        TEST_EQ (last_lineno, 1);
2809
 
 
2810
 
        err = nih_error_get ();
2811
 
        TEST_EQ (err->number, NIH_CONFIG_UNTERMINATED_QUOTE);
2812
 
        nih_free (err);
2813
 
}
2814
 
 
2815
 
void
2816
 
test_parse (void)
2817
 
{
2818
 
        FILE     *fd;
2819
 
        char      filename[PATH_MAX];
2820
 
        size_t    pos, lineno;
2821
 
        NihError *err;
2822
 
        int       ret;
2823
 
 
2824
 
        TEST_FUNCTION ("nih_config_parse");
2825
 
 
2826
 
        /* Check that a file that exists is parsed, with the handlers
2827
 
         * called and zero returned.
2828
 
         */
2829
 
        TEST_FEATURE ("with existing file");
2830
 
        TEST_FILENAME (filename);
2831
 
 
2832
 
        fd = fopen (filename, "w");
2833
 
        fprintf (fd, "frodo test\n");
2834
 
        fprintf (fd, "bilbo test\n");
2835
 
        fclose (fd);
2836
 
 
2837
 
        handler_called = 0;
2838
 
        last_data = NULL;
2839
 
        last_file = NULL;
2840
 
        last_len = 0;
2841
 
        last_pos = -1;
2842
 
        last_lineno = 0;
2843
 
 
2844
 
        lineno = 1;
2845
 
 
2846
 
        ret = nih_config_parse (filename, NULL, &lineno, stanzas, &ret);
2847
 
 
2848
 
        TEST_EQ (ret, 0);
2849
 
 
2850
 
        TEST_EQ (handler_called, 2);
2851
 
        TEST_EQ_P (last_data, &ret);
2852
 
        TEST_NE_P (last_file, NULL);
2853
 
        TEST_EQ (last_len, 22);
2854
 
        TEST_EQ (last_pos, 17);
2855
 
        TEST_EQ (last_lineno, 2);
2856
 
 
2857
 
        unlink (filename);
2858
 
 
2859
 
 
2860
 
        /* Check that an error is raised if the file doesn't exist. */
2861
 
        TEST_FEATURE ("with non-existant file");
2862
 
        handler_called = 0;
2863
 
 
2864
 
        ret = nih_config_parse (filename, NULL, NULL, stanzas, &ret);
2865
 
 
2866
 
        TEST_LT (ret, 0);
2867
 
        TEST_FALSE (handler_called);
2868
 
 
2869
 
        err = nih_error_get ();
2870
 
        TEST_EQ (err->number, ENOENT);
2871
 
        nih_free (err);
2872
 
 
2873
 
 
2874
 
        /* Check that a parser error is raised with the position and line
2875
 
         * number set to where it was found.
2876
 
         */
2877
 
        TEST_FEATURE ("with parser error");
2878
 
        fd = fopen (filename, "w");
2879
 
        fprintf (fd, "# first line comment\n");
2880
 
        fprintf (fd, "\n");
2881
 
        fprintf (fd, "frodo test\n");
2882
 
        fprintf (fd, "\"bilbo test\n");
2883
 
        fprintf (fd, "wibble\n");
2884
 
        fclose (fd);
2885
 
 
2886
 
        pos = 0;
2887
 
        lineno = 1;
2888
 
 
2889
 
        handler_called = 0;
2890
 
        last_data = NULL;
2891
 
        last_file = NULL;
2892
 
        last_len = 0;
2893
 
        last_pos = -1;
2894
 
        last_lineno = 0;
2895
 
 
2896
 
        ret = nih_config_parse (filename, &pos, &lineno, stanzas, &ret);
2897
 
 
2898
 
        TEST_LT (ret, 0);
2899
 
 
2900
 
        TEST_EQ (handler_called, 1);
2901
 
        TEST_EQ_P (last_data, &ret);
2902
 
        TEST_NE_P (last_file, NULL);
2903
 
        TEST_EQ (last_len, 52);
2904
 
        TEST_EQ (last_pos, 28);
2905
 
        TEST_EQ (last_lineno, 3);
2906
 
 
2907
 
        TEST_EQ (pos, 52);
2908
 
        TEST_EQ (lineno, 6);
2909
 
 
2910
 
        err = nih_error_get ();
2911
 
        TEST_EQ (err->number, NIH_CONFIG_UNTERMINATED_QUOTE);
2912
 
        nih_free (err);
2913
 
 
2914
 
        unlink (filename);
2915
 
}
2916
 
 
2917
 
 
2918
 
int
2919
 
main (int   argc,
2920
 
      char *argv[])
2921
 
{
2922
 
        test_has_token ();
2923
 
        test_token ();
2924
 
        test_next_token ();
2925
 
        test_next_arg ();
2926
 
        test_next_line ();
2927
 
        test_skip_whitespace ();
2928
 
        test_skip_comment ();
2929
 
        test_parse_args ();
2930
 
        test_parse_command ();
2931
 
        test_parse_block ();
2932
 
        test_skip_block ();
2933
 
        test_parse_stanza ();
2934
 
        test_parse_file ();
2935
 
        test_parse ();
2936
 
 
2937
 
        return 0;
2938
 
}