Relicense to ISC License.
[routeros-api.git] / src / ros_parse.c
1 /**
2  * librouteros - src/ros_parse.c
3  * Copyright (C) 2009  Florian octo Forster
4  *
5  * Permission to use, copy, modify, and/or distribute this software for any
6  * purpose with or without fee is hereby granted, provided that the above
7  * copyright notice and this permission notice appear in all copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
10  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11  * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
12  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
14  * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15  * PERFORMANCE OF THIS SOFTWARE.
16  *
17  * Authors:
18  *   Florian octo Forster <octo at verplant.org>
19  **/
20
21 #ifndef _ISOC99_SOURCE
22 # define _ISOC99_SOURCE
23 #endif
24
25 #ifndef _POSIX_C_SOURCE
26 # define _POSIX_C_SOURCE 200112L
27 #endif
28
29 #include "config.h"
30
31 #include <stdlib.h>
32 #include <stdbool.h>
33 #include <stdint.h>
34 #include <inttypes.h>
35 #include <string.h>
36 #include <strings.h>
37 #include <math.h>
38 #include <errno.h>
39 #include <assert.h>
40
41 #include "routeros_api.h"
42
43 _Bool sstrtob (const char *str) /* {{{ */
44 {
45         if (str == NULL)
46                 return (false);
47
48         if (strcasecmp ("true", str) == 0)
49                 return (true);
50         return (false);
51 } /* }}} _Bool sstrtob */
52
53 unsigned int sstrtoui (const char *str) /* {{{ */
54 {
55         unsigned int ret;
56         char *endptr;
57
58         if (str == NULL)
59                 return (0);
60
61         errno = 0;
62         endptr = NULL;
63         ret = (unsigned int) strtoul (str, &endptr, /* base = */ 10);
64         if ((endptr == str) || (errno != 0))
65                 return (0);
66
67         return (ret);
68 } /* }}} unsigned int sstrtoui */
69
70 uint64_t sstrtoui64 (const char *str) /* {{{ */
71 {
72         uint64_t ret;
73         char *endptr;
74
75         if (str == NULL)
76                 return (0);
77
78         errno = 0;
79         endptr = NULL;
80         ret = (uint64_t) strtoull (str, &endptr, /* base = */ 10);
81         if ((endptr == str) || (errno != 0))
82                 return (0);
83
84         return (ret);
85 } /* }}} uint64_t sstrtoui64 */
86
87 double sstrtod (const char *str) /* {{{ */
88 {
89         double ret;
90         char *endptr;
91
92         if (str == NULL)
93                 return (NAN);
94
95         errno = 0;
96         endptr = NULL;
97         ret = strtod (str, &endptr);
98         if ((endptr == str) || (errno != 0))
99                 return (NAN);
100
101         return (ret);
102 } /* }}} double sstrtod */
103
104 int sstrto_rx_tx_counters (const char *str, /* {{{ */
105                 uint64_t *rx, uint64_t *tx)
106 {
107         const char *ptr;
108         char *endptr;
109
110         if ((rx == NULL) || (tx == NULL))
111                 return (EINVAL);
112
113         *rx = 0;
114         *tx = 0;
115
116         if (str == NULL)
117                 return (EINVAL);
118
119         ptr = str;
120         errno = 0;
121         endptr = NULL;
122         *rx = (uint64_t) strtoull (ptr, &endptr, /* base = */ 10);
123         if ((endptr == str) || (errno != 0))
124         {
125                 *rx = 0;
126                 return (EIO);
127         }
128
129         assert (endptr != NULL);
130         if ((*endptr != '/') && (*endptr != ','))
131                 return (EIO);
132
133         ptr = endptr + 1;
134         errno = 0;
135         endptr = NULL;
136         *tx = (uint64_t) strtoull (ptr, &endptr, /* base = */ 10);
137         if ((endptr == str) || (errno != 0))
138         {
139                 *rx = 0;
140                 *tx = 0;
141                 return (EIO);
142         }
143
144         return (0);
145 } /* }}} int sstrto_rx_tx_counters */
146
147 /* have_hour is initially set to false and later set to true when the first
148  * colon is found. It is used to determine whether the number before the colon
149  * is hours or minutes. External code should use the sstrtodate() macro. */
150 uint64_t _sstrtodate (const char *str, _Bool have_hour) /* {{{ */
151 {
152         uint64_t ret;
153         char *endptr;
154
155         if ((str == NULL) || (*str == 0))
156                 return (0);
157
158         /* Example string: 6w6d18:33:07 */
159         errno = 0;
160         endptr = NULL;
161         ret = (uint64_t) strtoull (str, &endptr, /* base = */ 10);
162         if ((endptr == str) || (errno != 0))
163                 return (0);
164
165         switch (*endptr)
166         {
167                 case 'y': ret *= 365 * 86400; break;
168                 case 'w': ret *=   7 * 86400; break;
169                 case 'd': ret *=       86400; break;
170                 case ':': ret *= have_hour ? 60 : 3600; have_hour = true; break;
171         }
172
173         return (ret + _sstrtodate (endptr + 1, have_hour));
174 } /* }}} uint64_t _sstrtodate */
175
176 /* vim: set ts=2 sw=2 noet fdm=marker : */