set -O0 for debug builds
[project/uci.git] / util.c
1 /*
2  * libuci - Library for the Unified Configuration Interface
3  * Copyright (C) 2008 Felix Fietkau <nbd@openwrt.org>
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU Lesser General Public License version 2.1
7  * as published by the Free Software Foundation
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  */
14
15 /*
16  * This file contains wrappers to standard functions, which
17  * throw exceptions upon failure.
18  */
19 #include <stdbool.h>
20 #include <ctype.h>
21
22 static void *uci_malloc(struct uci_context *ctx, size_t size)
23 {
24         void *ptr;
25
26         ptr = malloc(size);
27         if (!ptr)
28                 UCI_THROW(ctx, UCI_ERR_MEM);
29         memset(ptr, 0, size);
30
31         return ptr;
32 }
33
34 static void *uci_realloc(struct uci_context *ctx, void *ptr, size_t size)
35 {
36         ptr = realloc(ptr, size);
37         if (!ptr)
38                 UCI_THROW(ctx, UCI_ERR_MEM);
39
40         return ptr;
41 }
42
43 static char *uci_strdup(struct uci_context *ctx, const char *str)
44 {
45         char *ptr;
46
47         ptr = strdup(str);
48         if (!ptr)
49                 UCI_THROW(ctx, UCI_ERR_MEM);
50
51         return ptr;
52 }
53
54 static bool uci_validate_name(char *str)
55 {
56         if (!*str)
57                 return false;
58
59         while (*str) {
60                 if (!isalnum(*str) && (*str != '_'))
61                         return false;
62                 str++;
63         }
64         return true;
65 }
66
67 int uci_parse_tuple(struct uci_context *ctx, char *str, char **package, char **section, char **option, char **value)
68 {
69         char *last = NULL;
70
71         UCI_HANDLE_ERR(ctx);
72         UCI_ASSERT(ctx, str && package && section && option);
73
74         *package = strtok(str, ".");
75         if (!*package || !uci_validate_name(*package))
76                 goto error;
77
78         last = *package;
79         *section = strtok(NULL, ".");
80         if (!*section)
81                 goto lastval;
82
83         last = *section;
84         *option = strtok(NULL, ".");
85         if (!*option)
86                 goto lastval;
87
88         last = *option;
89
90 lastval:
91         last = strchr(last, '=');
92         if (last) {
93                 if (!value)
94                         goto error;
95
96                 *last = 0;
97                 last++;
98                 if (!*last)
99                         goto error;
100                 *value = last;
101         }
102
103         if (*section && !uci_validate_name(*section))
104                 goto error;
105         if (*option && !uci_validate_name(*option))
106                 goto error;
107
108         goto done;
109
110 error:
111         UCI_THROW(ctx, UCI_ERR_PARSE);
112
113 done:
114         return 0;
115 }
116