1 /*
2  * Author Jerry Lundström <jerry@dns-oarc.net>
3  * Copyright (c) 2017, OARC, Inc.
4  * All rights reserved.
5  *
6  * This file is part of parseconf.
7  *
8  * parseconf is free software: you can redistribute it and/or modify
9  * it under the terms of the GNU Lesser General Public License as published by
10  * the Free Software Foundation, either version 3 of the License, or
11  * (at your option) any later version.
12  *
13  * parseconf is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public License
19  * along with parseconf.  If not, see <http://www.gnu.org/licenses/>.
20  */
21 
22 #ifndef __parseconf_h
23 #define __parseconf_h
24 
25 #include <stddef.h>
26 #if PARSECONF_ENABLE_ASSERT
27 #include <assert.h>
28 #define parseconf_assert(x) assert(x)
29 #else
30 #define parseconf_assert(x)
31 #endif
32 
33 #define PARSECONF_VERSION_STR   "1.0.0"
34 #define PARSECONF_VERSION_MAJOR 1
35 #define PARSECONF_VERSION_MINOR 0
36 #define PARSECONF_VERSION_PATCH 0
37 
38 #define PARSECONF_EEXIST    -4
39 #define PARSECONF_ENOMEM    -3
40 #define PARSECONF_EINVAL    -2
41 #define PARSECONF_ERROR     -1
42 #define PARSECONF_OK        0
43 #define PARSECONF_LAST      1
44 #define PARSECONF_COMMENT   2
45 #define PARSECONF_EMPTY     3
46 
47 #define PARSECONF_EEXIST_STR    "Already exists"
48 #define PARSECONF_ENOMEM_STR    "Out of memory"
49 #define PARSECONF_EINVAL_STR    "Invalid arguments"
50 #define PARSECONF_ERROR_STR     "Generic error"
51 
52 #define PARSECONF_MAX_TOKENS    64
53 
54 #ifdef __cplusplus
55 extern "C" {
56 #endif
57 
58 const char* parseconf_version_str(void);
59 int parseconf_version_major(void);
60 int parseconf_version_minor(void);
61 int parseconf_version_patch(void);
62 
63 typedef enum parseconf_token_type parseconf_token_type_t;
64 #ifdef PARSECONF_USE_SHORT_TOKENS
65 enum parseconf_token_type {
66     END = 0,
67     STRING,
68     QSTRING,
69     NUMBER,
70     STRINGS,
71     QSTRINGS,
72     NUMBERS,
73     ANY,
74     FLOAT,
75     FLOATS,
76     NESTED
77 };
78 #define PARSECONF_TOKEN_END         END
79 #define PARSECONF_TOKEN_STRING      STRING
80 #define PARSECONF_TOKEN_QSTRING     QSTRING
81 #define PARSECONF_TOKEN_NUMBER      NUMBER
82 #define PARSECONF_TOKEN_STRINGS     STRINGS
83 #define PARSECONF_TOKEN_QSTRINGS    QSTRINGS
84 #define PARSECONF_TOKEN_NUMBERS     NUMBERS
85 #define PARSECONF_TOKEN_ANY         ANY
86 #define PARSECONF_TOKEN_FLOAT       FLOAT
87 #define PARSECONF_TOKEN_FLOATS      FLOATS
88 #define PARSECONF_TOKEN_NESTED      NESTED
89 #else
90 enum parseconf_token_type {
91     PARSECONF_TOKEN_END = 0,
92     PARSECONF_TOKEN_STRING,
93     PARSECONF_TOKEN_QSTRING,
94     PARSECONF_TOKEN_NUMBER,
95     PARSECONF_TOKEN_STRINGS,
96     PARSECONF_TOKEN_QSTRINGS,
97     PARSECONF_TOKEN_NUMBERS,
98     PARSECONF_TOKEN_ANY,
99     PARSECONF_TOKEN_FLOAT,
100     PARSECONF_TOKEN_FLOATS,
101     PARSECONF_TOKEN_NESTED
102 };
103 #endif
104 
105 typedef struct parseconf_token parseconf_token_t;
106 struct parseconf_token {
107     parseconf_token_type_t  type;
108     const char*             token;
109     size_t                  length;
110 };
111 
112 typedef int (*parseconf_token_callback_t)(void* user, const parseconf_token_t* tokens, const char** errstr);
113 
114 typedef enum parseconf_error parseconf_error_t;
115 enum parseconf_error {
116     PARSECONF_ERROR_NONE = 0,
117     PARSECONF_ERROR_INTERNAL,
118     PARSECONF_ERROR_EXPECT_STRING,
119     PARSECONF_ERROR_EXPECT_NUMBER,
120     PARSECONF_ERROR_EXPECT_QSTRING,
121     PARSECONF_ERROR_EXPECT_FLOAT,
122     PARSECONF_ERROR_EXPECT_ANY,
123     PARSECONF_ERROR_UNKNOWN,
124     PARSECONF_ERROR_NO_NESTED,
125     PARSECONF_ERROR_NO_CALLBACK,
126     PARSECONF_ERROR_CALLBACK,
127     PARSECONF_ERROR_FILE_ERRNO,
128     PARSECONF_ERROR_TOO_MANY_ARGUMENTS,
129     PARSECONF_ERROR_INVALID_SYNTAX
130 };
131 
132 typedef void (*parseconf_error_callback_t)(void* user, parseconf_error_t error, size_t line, size_t token, const parseconf_token_t* tokens, const char* errstr);
133 
134 #define PARSECONF_SYNTAX_END { 0, 0, 0, 0 }
135 typedef struct parseconf_syntax parseconf_syntax_t;
136 struct parseconf_syntax {
137     const char*                     token;
138     parseconf_token_callback_t      callback;
139     const parseconf_token_type_t*   syntax;
140     const parseconf_syntax_t*       nested;
141 };
142 
143 int parseconf_ulongint(const parseconf_token_t* token, unsigned long int* value, const char** errstr);
144 int parseconf_ulonglongint(const parseconf_token_t* token, unsigned long long int* value, const char** errstr);
145 int parseconf_double(const parseconf_token_t* token, double* value, const char** errstr);
146 int parseconf_longdouble(const parseconf_token_t* token, long double* value, const char** errstr);
147 
148 int parseconf_file(void* user, const char* file, const parseconf_syntax_t* syntax, parseconf_error_callback_t error_callback);
149 int parseconf_text(void* user, const char* text, const size_t length, const parseconf_syntax_t* syntax, parseconf_error_callback_t error_callback);
150 const char* parseconf_strerror(int errnum);
151 
152 #ifdef __cplusplus
153 }
154 #endif
155 
156 #endif /* __parseconf_h */
157