85e87abb4ef8a6a919a2459bd330a0f1f81755ba
[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 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 || !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 }
101
102 if (*section && !validate_name(*section))
103 goto error;
104 if (*option && !validate_name(*option))
105 goto error;
106
107 goto done;
108
109 error:
110 UCI_THROW(ctx, UCI_ERR_PARSE);
111
112 done:
113 return 0;
114 }
115