sr: No need for dynamic hardware driver registration.
[sigrok-cli.git] / parsers.c
1 /*
2  * This file is part of the sigrok project.
3  *
4  * Copyright (C) 2011 Bert Vermeulen <bert@biot.com>
5  *
6  * This program is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
18  */
19
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <stdint.h>
23 #include <string.h>
24 #include <glib.h>
25 #include <sigrok.h>
26 #include "sigrok-cli.h"
27
28 char **parse_probestring(int max_probes, const char *probestring)
29 {
30         int tmp, b, e, i;
31         char **tokens, **range, **probelist, *name, str[8];
32         gboolean error;
33
34         error = FALSE;
35         range = NULL;
36         if (!(probelist = g_try_malloc0(max_probes * sizeof(char *)))) {
37                 /* TODO: Handle errors. */
38         }
39         tokens = g_strsplit(probestring, ",", max_probes);
40
41         for (i = 0; tokens[i]; i++) {
42                 if (strchr(tokens[i], '-')) {
43                         /* A range of probes in the form 1-5. */
44                         range = g_strsplit(tokens[i], "-", 2);
45                         if (!range[0] || !range[1] || range[2]) {
46                                 /* Need exactly two arguments. */
47                                 printf("Invalid probe syntax '%s'.\n",
48                                        tokens[i]);
49                                 error = TRUE;
50                                 break;
51                         }
52
53                         b = strtol(range[0], NULL, 10);
54                         e = strtol(range[1], NULL, 10);
55                         if (b < 1 || e > max_probes || b >= e) {
56                                 printf("Invalid probe range '%s'.\n",
57                                        tokens[i]);
58                                 error = TRUE;
59                                 break;
60                         }
61
62                         while (b <= e) {
63                                 snprintf(str, 7, "%d", b);
64                                 probelist[b - 1] = g_strdup(str);
65                                 b++;
66                         }
67                 } else {
68                         tmp = strtol(tokens[i], NULL, 10);
69                         if (tmp < 1 || tmp > max_probes) {
70                                 printf("Invalid probe %d.\n", tmp);
71                                 error = TRUE;
72                                 break;
73                         }
74
75                         if ((name = strchr(tokens[i], '='))) {
76                                 probelist[tmp - 1] = g_strdup(++name);
77                                 if (strlen(probelist[tmp - 1]) > SR_MAX_PROBENAME_LEN)
78                                         probelist[tmp - 1][SR_MAX_PROBENAME_LEN] = 0;
79                         } else {
80                                 snprintf(str, 7, "%d", tmp);
81                                 probelist[tmp - 1] = g_strdup(str);
82                         }
83                 }
84         }
85
86         if (error) {
87                 for (i = 0; i < max_probes; i++)
88                         if (probelist[i])
89                                 g_free(probelist[i]);
90                 g_free(probelist);
91                 probelist = NULL;
92         }
93
94         g_strfreev(tokens);
95         if (range)
96                 g_strfreev(range);
97
98         return probelist;
99 }
100
101 GHashTable *parse_generic_arg(const char *arg)
102 {
103         GHashTable *hash;
104         int i;
105         char **elements, *e;
106
107         if (!arg || !arg[0])
108                 return NULL;
109
110         hash = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
111         elements = g_strsplit(arg, ":", 0);
112         g_hash_table_insert(hash, g_strdup("sigrok_key"), g_strdup(elements[0]));
113         for (i = 1; elements[i]; i++) {
114                 e = strchr(elements[i], '=');
115                 if (!e)
116                         g_hash_table_insert(hash, g_strdup(elements[i]), NULL);
117                 else {
118                         *e++ = '\0';
119                         g_hash_table_insert(hash, g_strdup(elements[i]), g_strdup(e));
120                 }
121         }
122         g_strfreev(elements);
123
124         return hash;
125 }
126
127 struct sr_dev *parse_devstring(const char *devstring)
128 {
129         struct sr_dev *dev, *d;
130         struct sr_dev_plugin **plugins;
131         GSList *devs, *l;
132         int i, num_devs, dev_num, dev_cnt;
133         char *tmp;
134
135         if (!devstring)
136                 return NULL;
137
138         dev = NULL;
139         dev_num = strtol(devstring, &tmp, 10);
140         if (tmp != devstring) {
141                 /* argument is numeric, meaning a device ID. Make all driver
142                  * plugins scan for devices.
143                  */
144                 num_devs = num_real_devs();
145                 if (dev_num < 0 || dev_num >= num_devs)
146                         return NULL;
147
148                 dev_cnt = 0;
149                 devs = sr_dev_list();
150                 for (l = devs; l; l = l->next) {
151                         d = l->data;
152                         if (sr_dev_has_hwcap(d, SR_HWCAP_DEMO_DEV))
153                                 continue;
154                         if (dev_cnt == dev_num) {
155                                 if (dev_num == dev_cnt) {
156                                         dev = d;
157                                         break;
158                                 }
159                         }
160                         dev_cnt++;
161                 }
162         } else {
163                 /* select device by driver -- only initialize that driver,
164                  * no need to let them all scan
165                  */
166                 dev = NULL;
167                 plugins = sr_hw_list();
168                 for (i = 0; plugins[i]; i++) {
169                         if (strcmp(plugins[i]->name, devstring))
170                                 continue;
171                         num_devs = sr_hw_init(plugins[i]);
172                         if (num_devs == 1) {
173                                 devs = sr_dev_list();
174                                 dev = devs->data;
175                         } else if (num_devs > 1) {
176                                 printf("driver '%s' found %d devices, select by ID instead.\n",
177                                                 devstring, num_devs);
178                         }
179                         /* fall through: selected driver found no devices */
180                         break;
181                 }
182         }
183
184         return dev;
185 }