File: example.c

package info (click to toggle)
libt3config 1.0.0-1
  • links: PTS
  • area: main
  • in suites: bookworm, bullseye, forky, sid, trixie
  • size: 604 kB
  • sloc: ansic: 3,938; sh: 846; xml: 172; lex: 87; makefile: 57
file content (116 lines) | stat: -rw-r--r-- 4,315 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <locale.h>
#include <unistd.h>
#include <stdarg.h>
#include <t3config/config.h>

#define STRING_DFLT(x, dflt) ((x) != NULL ? (x) : (dflt))

static t3_config_t *config;
static t3_config_schema_t *schema;

/* Alert the user of a fatal error and quit. */
static void fatal(const char *fmt, ...) {
    va_list args;

    va_start(args, fmt);
    vfprintf(stderr, fmt, args);
    va_end(args);
    exit(EXIT_FAILURE);
}

/* Cleanup memory used by config and schema. */
static void cleanup(void) {
    /* Both t3_config_delete and t3_config_delete_schema allow NULL pointers to be passed. */
    t3_config_delete(config);
    t3_config_delete_schema(schema);
}

int main(int argc, char *argv[]) {
    t3_config_error_t error;
    FILE *file = stdin;
    t3_config_opts_t opts;
    t3_config_t *foo;
    const char *path[2] = { NULL, NULL };
    const char *name = "<stdin>";
    int c;

    /* Set locale */
    setlocale(LC_ALL, "");
    /* Request as much information about errors as possible. */
    opts.flags = T3_CONFIG_VERBOSE_ERROR | T3_CONFIG_ERROR_FILE_NAME;

    /* Make sure we free memory on exit (useful for debugging purposes). */
    atexit(cleanup);
    while ((c = getopt(argc, argv, "s:hi::")) >= 0) {
        switch (c) {
            case 's': {
                /* Load a schema. */
                FILE *schema_file;
                if (schema != NULL)
                    fatal("more than one schema option\n");
                if ((schema_file = fopen(optarg, "r")) == NULL)
                    fatal("error opening schema '%s': %m\n", optarg);
                if ((schema = t3_config_read_schema_file(schema_file, &error, &opts)) == NULL)
                    fatal("%s:%d: error loading schema '%s': %s: %s\n", STRING_DFLT(error.file_name, optarg),
                        error.line_number, optarg, t3_config_strerror(error.error), STRING_DFLT(error.extra, ""));
                fclose(schema_file);
                break;
            }
            case 'h':
                printf("Usage: test [-s <schema>] [-i[<include dir>]] [<input>]\n");
                exit(EXIT_SUCCESS);
            case 'i':
                /* Configure the options for allowing the include mechanism. */
                opts.flags |= T3_CONFIG_INCLUDE_DFLT;
                path[0] = optarg == 0 ? "." : optarg;
                opts.include_callback.dflt.path = path;
                opts.include_callback.dflt.flags = 0;
                break;
            default:
                break;
        }
    }

    /* Open the input file if necessary. */
    if (argc - optind == 1) {
        if ((file = fopen(argv[optind], "r")) == NULL)
            fatal("could not open input '%s': %m\n");
        name = argv[optind];
    } else if (argc != optind) {
        fatal("more than one input specified\n");
    }

    /* Read the configuration. */
    if ((config = t3_config_read_file(file, &error, &opts)) == NULL)
        fatal("%s:%d: error loading input: %s: %s\n", STRING_DFLT(error.file_name, name), error.line_number,
            t3_config_strerror(error.error), STRING_DFLT(error.extra, ""));
    /* Close the file now that we are done with it. */
    fclose(file);

    /* Use the schema (if any) to validate the input. */
    if (schema != NULL && !t3_config_validate(config, schema, &error, T3_CONFIG_VERBOSE_ERROR | T3_CONFIG_ERROR_FILE_NAME))
        fatal("%s:%d: error validating input: %s: %s\n", STRING_DFLT(error.file_name, name), error.line_number,
            t3_config_strerror(error.error), STRING_DFLT(error.extra, ""));

    /* Retrieve the section named "foo". */
    foo = t3_config_get(config, "foo");
    if (foo != NULL) {
        /* Retrieve the integer "bar", with default value of 0. This verifies
           that bar has type int, which can already be checked through the schema.     */
        int bar_int = -1;
        t3_config_t *bar = t3_config_get(foo, "bar");
        if (t3_config_get_type(bar), T3_CONFIG_INT) {
            bar_int = t3_config_get_int(bar);
        }
    }

    /* Add a boolean value named "xxx" with value true. */
    t3_config_add_bool(config, "xxx", t3_true);

    /* Write the input to screen for checking the result. */
    t3_config_write_file(config, stdout);
    return EXIT_SUCCESS;
}