95126ef4950c97e03384746b616efcf251f5467e
[routeros-api.git] / src / ros_parse.c
1 /**
2  * librouteros - src/ros_parse.c
3  * Copyright (C) 2009  Florian octo Forster
4  *
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License as published by the
7  * Free Software Foundation; only version 2 of the License is applicable.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License along
15  * with this program; if not, write to the Free Software Foundation, Inc.,
16  * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
17  *
18  * Authors:
19  *   Florian octo Forster <octo at verplant.org>
20  **/
21
22 #ifndef _ISOC99_SOURCE
23 # define _ISOC99_SOURCE
24 #endif
25
26 #ifndef _POSIX_C_SOURCE
27 # define _POSIX_C_SOURCE 200112L
28 #endif
29
30 #include "config.h"
31
32 #include <stdlib.h>
33 #include <stdbool.h>
34 #include <stdint.h>
35 #include <inttypes.h>
36 #include <string.h>
37 #include <strings.h>
38 #include <math.h>
39 #include <errno.h>
40 #include <assert.h>
41
42 #include "routeros_api.h"
43
44 _Bool sstrtob (const char *str) /* {{{ */
45 {
46         if (str == NULL)
47                 return (false);
48
49         if (strcasecmp ("true", str) == 0)
50                 return (true);
51         return (false);
52 } /* }}} _Bool sstrtob */
53
54 unsigned int sstrtoui (const char *str) /* {{{ */
55 {
56         unsigned int ret;
57         char *endptr;
58
59         if (str == NULL)
60                 return (0);
61
62         errno = 0;
63         endptr = NULL;
64         ret = (unsigned int) strtoul (str, &endptr, /* base = */ 10);
65         if ((endptr == str) || (errno != 0))
66                 return (0);
67
68         return (ret);
69 } /* }}} unsigned int sstrtoui */
70
71 uint64_t sstrtoui64 (const char *str) /* {{{ */
72 {
73         uint64_t ret;
74         char *endptr;
75
76         if (str == NULL)
77                 return (0);
78
79         errno = 0;
80         endptr = NULL;
81         ret = (uint64_t) strtoull (str, &endptr, /* base = */ 10);
82         if ((endptr == str) || (errno != 0))
83                 return (0);
84
85         return (ret);
86 } /* }}} uint64_t sstrtoui64 */
87
88 double sstrtod (const char *str) /* {{{ */
89 {
90         double ret;
91         char *endptr;
92
93         if (str == NULL)
94                 return (NAN);
95
96         errno = 0;
97         endptr = NULL;
98         ret = strtod (str, &endptr);
99         if ((endptr == str) || (errno != 0))
100                 return (NAN);
101
102         return (ret);
103 } /* }}} double sstrtod */
104
105 int sstrto_rx_tx_counters (const char *str, /* {{{ */
106                 uint64_t *rx, uint64_t *tx)
107 {
108         const char *ptr;
109         char *endptr;
110
111         if ((rx == NULL) || (tx == NULL))
112                 return (EINVAL);
113
114         *rx = 0;
115         *tx = 0;
116
117         if (str == NULL)
118                 return (EINVAL);
119
120         ptr = str;
121         errno = 0;
122         endptr = NULL;
123         *rx = (uint64_t) strtoull (ptr, &endptr, /* base = */ 10);
124         if ((endptr == str) || (errno != 0))
125         {
126                 *rx = 0;
127                 return (EIO);
128         }
129
130         assert (endptr != NULL);
131         if ((*endptr != '/') && (*endptr != ','))
132                 return (EIO);
133
134         ptr = endptr + 1;
135         errno = 0;
136         endptr = NULL;
137         *tx = (uint64_t) strtoull (ptr, &endptr, /* base = */ 10);
138         if ((endptr == str) || (errno != 0))
139         {
140                 *rx = 0;
141                 *tx = 0;
142                 return (EIO);
143         }
144
145         return (0);
146 } /* }}} int sstrto_rx_tx_counters */
147
148 /* have_hour is initially set to false and later set to true when the first
149  * colon is found. It is used to determine whether the number before the colon
150  * is hours or minutes. External code should use the sstrtodate() macro. */
151 uint64_t _sstrtodate (const char *str, _Bool have_hour) /* {{{ */
152 {
153         uint64_t ret;
154         char *endptr;
155
156         if ((str == NULL) || (*str == 0))
157                 return (0);
158
159         /* Example string: 6w6d18:33:07 */
160         errno = 0;
161         endptr = NULL;
162         ret = (uint64_t) strtoull (str, &endptr, /* base = */ 10);
163         if ((endptr == str) || (errno != 0))
164                 return (0);
165
166         switch (*endptr)
167         {
168                 case 'y': ret *= 365 * 86400; break;
169                 case 'w': ret *=   7 * 86400; break;
170                 case 'd': ret *=       86400; break;
171                 case ':': ret *= have_hour ? 60 : 3600; have_hour = true; break;
172         }
173
174         return (ret + _sstrtodate (endptr + 1, have_hour));
175 } /* }}} uint64_t _sstrtodate */
176
177 /* vim: set ts=2 sw=2 noet fdm=marker : */