]> rtime.felk.cvut.cz Git - pes-rpp/rpp-test-sw.git/blob - rpp/lib/cmdproc/src/cmdproc_utils.c
Yet another place to fix
[pes-rpp/rpp-test-sw.git] / rpp / lib / cmdproc / src / cmdproc_utils.c
1 /*******************************************************************
2   Components for embedded applications builded for
3   laboratory and medical instruments firmware  
4  
5   utils.c - utilities for reading numbers and parsing of text line
6  
7   Copyright (C) 2001 by Pavel Pisa pisa@cmp.felk.cvut.cz
8             (C) 2002 by PiKRON Ltd. http://www.pikron.com
9
10  *******************************************************************/
11
12 #include <stdint.h>
13 #include <string.h>
14 #include <stdio.h>
15 #include <ctype.h>
16 #include <stdlib.h>
17 #include <cmdproc.h>
18 #include "i2str.h"
19
20 /* string parse and input routines */
21
22 /**
23  * si_skspace - Skip space and blank characters
24  * @ps:         Pointer to character poiter into parsed string
25  *
26  * Functions checks character **@ps by isspace() category and
27  * moves *@ps pointer after last blank character. If there is at least one
28  * blank character, returns 1, else returns 0.
29  */
30 int si_skspace(char **ps)
31 {
32         char *p = *ps;
33
34         if (!isspace((uint8_t) * (p++)))
35                 return 0;
36         while (isspace((uint8_t) * (p++))) ;
37         *ps = p - 1;
38
39         return 1;
40 }
41
42 /**
43  * si_fndsep - Finds field separator character
44  * @ps:         Pointer to character pointer into parsed string
45  * @sepchrs:    String of possible separator characters.
46  *
47  * Function skips blanks, then checks, if next character belongs
48  * to @sepchrs list. If character belongs, function returns found
49  * character and *@ps points after separator else returns -1.
50  */
51 int si_fndsep(char **ps, char *sepchrs)
52 {
53         char c;
54
55         si_skspace(ps);
56         c = **ps;
57         if (!c)
58                 return 0;
59         if (!strchr(sepchrs, c))
60                 return -1;
61         (*ps)++;
62
63         return c;
64 }
65
66 /**
67  * si_alnumn - Reads alphanumeric value
68  * @ps:         Pointer to character pointer into parsed string
69  * @pout:       Pointer to read value buffer
70  * @n:          Maximal number of read characters.
71  *
72  * Function reads alphanumeric characters and stores them in @pout,
73  * if there is no more alphanumeric characters or @n is reached,
74  * it returns count of stored characters.
75  */
76 int si_alnumn(char **ps, char *pout, int n)
77 {
78         char *p = *ps;
79         char c;
80         int ret = 0;
81
82         while (isalnum((uint8_t) (c = *p)) || (*p == '_')) {
83                 p++;
84                 *(pout++) = c;
85                 if (++ret == n)
86                         break;
87         }
88         *pout = 0;
89         *ps = p;
90
91         return ret;
92 }
93
94 /**
95  * si_alphan - Reads alphabetic value
96  * @ps:         Pointer to character pointer into parsed string
97  * @pout:       Pointer to read value buffer
98  * @n:          Maximal number of read characters.
99  *
100  * Function reads alphabetic characters and stores them in @pout,
101  * if there is no more alphabetic characters or @n is reached,
102  * it returns count of stored characters.
103  */
104 int si_alphan(char **ps, char *pout, int n)
105 {
106         char *p = *ps;
107         char c;
108         int ret = 0;
109
110         while (isalpha((uint8_t) (c = *p))) {
111                 p++;
112                 *(pout++) = c;
113                 if (++ret == n)
114                         break;
115         }
116         *pout = 0;
117         *ps = p;
118
119         return ret;
120 }
121
122 /**
123  * si_long - Reads numeric value
124  * @ps:         Pointer to character pointer into parsed string
125  * @val:        Pointer to long integer value buffer
126  * @base:       Base of converted number, 0 means select by C rules
127  *
128  * Function reads digits and converts them to longint value.
129  * It stops at end of the string or if non digit character is reached.
130  * Returns 1 for successful conversion or -1 if no character can be
131  * converted. Pointer *@ps paints after last character belonging to 
132  * numeric input.
133  */
134 int si_long(char **ps, long *val, int base)
135 {
136         char *p;
137
138         *val = strtol(*ps, &p, base);
139         if (*ps == p)
140                 return -1;
141
142         *ps = p;
143
144         return 1;
145 }
146
147 /**
148  * Read argument from commands in format (XX,XX,XX...)
149  * @param[in]   ps      Pointer to source string
150  * @param[out]  buf     Pointer to array, where numbers from argument will be stored
151  * @param[in]   base    Base of numbers in argument
152  * @return number of values
153  */
154 int read_arg(char **ps, uint32_t *buf, int n, int base)
155 {
156         uint32_t val;
157         int c;
158         int i;
159
160         if (si_fndsep(ps, "({") < 0)
161                 return -CMDERR_BADSEP;
162         i = 0;
163         si_skspace(ps);
164         if ((**ps != ')') && (**ps != '}'))
165                 do {
166                         if (i >= n)
167                                 return -CMDERR_BADPAR;
168                         if (si_long(ps, (long*)&val, base) < 0)
169                                 return -CMDERR_BADPAR;
170                         buf[i] = val;
171                         i++;
172                         if ((c = si_fndsep(ps, ",)}")) < 0)
173                                 return -CMDERR_BADSEP;
174                 } while (c == ',');
175
176         return i;
177 }
178