root/lm-sensors/tags/V3-0-1/lib/data.c

Revision 4736, 6.7 kB (checked in by khali, 1 year ago)

Mass reindent, coding style and whitespace cleanups.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1 /*
2     data.c - Part of libsensors, a Linux library for reading sensor data.
3     Copyright (c) 1998, 1999  Frodo Looijaard <frodol@dds.nl>
4     Copyright (C) 2007        Jean Delvare <khali@linux-fr.org>
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 2 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, write to the Free Software
18     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21 /* this define needed for strndup() */
22 #define _GNU_SOURCE
23
24 #include <stdlib.h>
25 #include <string.h>
26
27 #include "access.h"
28 #include "error.h"
29 #include "data.h"
30 #include "sensors.h"
31 #include "../version.h"
32
33 const char *libsensors_version = LM_VERSION;
34
35 sensors_chip *sensors_config_chips = NULL;
36 int sensors_config_chips_count = 0;
37 int sensors_config_chips_max = 0;
38
39 sensors_bus *sensors_config_busses = NULL;
40 int sensors_config_busses_count = 0;
41 int sensors_config_busses_max = 0;
42
43 sensors_chip_features *sensors_proc_chips = NULL;
44 int sensors_proc_chips_count = 0;
45 int sensors_proc_chips_max = 0;
46
47 sensors_bus *sensors_proc_bus = NULL;
48 int sensors_proc_bus_count = 0;
49 int sensors_proc_bus_max = 0;
50
51 static int sensors_substitute_chip(sensors_chip_name *name, int lineno);
52
53 /*
54    Parse a chip name to the internal representation. These are valid names:
55
56      lm78-i2c-10-5e             *-i2c-10-5e
57      lm78-i2c-10-*              *-i2c-10-*
58      lm78-i2c-*-5e              *-i2c-*-5e
59      lm78-i2c-*-*               *-i2c-*-*
60      lm78-isa-10dd              *-isa-10dd
61      lm78-isa-*                 *-isa-*
62      lm78-*                     *-*
63
64    Here 'lm78' can be any prefix. 'i2c' and 'isa' are
65    literal strings, just like all dashes '-' and wildcards '*'. '10' can
66    be any decimal i2c bus number. '5e' can be any hexadecimal i2c device
67    address, and '10dd' any hexadecimal isa address.
68
69    The 'prefix' part in the result is freshly allocated. All old contents
70    of res is overwritten. res itself is not allocated. In case of an error
71    return (ie. != 0), res is undefined, but all allocations are undone.
72 */
73
74 int sensors_parse_chip_name(const char *name, sensors_chip_name *res)
75 {
76         char *dash;
77
78         /* First, the prefix. It's either "*" or a real chip name. */
79         if (!strncmp(name, "*-", 2)) {
80                 res->prefix = SENSORS_CHIP_NAME_PREFIX_ANY;
81                 name += 2;
82         } else {
83                 if (!(dash = strchr(name, '-')))
84                         return -SENSORS_ERR_CHIP_NAME;
85                 res->prefix = strndup(name, dash - name);
86                 if (!res->prefix)
87                         sensors_fatal_error("sensors_parse_chip_name",
88                                             "Allocating name prefix");
89                 name = dash + 1;
90         }
91
92         /* Then we have either a sole "*" (all chips with this name) or a bus
93            type and an address. */
94         if (!strcmp(name, "*")) {
95                 res->bus.type = SENSORS_BUS_TYPE_ANY;
96                 res->bus.nr = SENSORS_BUS_NR_ANY;
97                 res->addr = SENSORS_CHIP_NAME_ADDR_ANY;
98                 return 0;
99         }
100
101         if (!(dash = strchr(name, '-')))
102                 goto ERROR;
103         if (!strncmp(name, "i2c", dash - name))
104                 res->bus.type = SENSORS_BUS_TYPE_I2C;
105         else if (!strncmp(name, "isa", dash - name))
106                 res->bus.type = SENSORS_BUS_TYPE_ISA;
107         else if (!strncmp(name, "pci", dash - name))
108                 res->bus.type = SENSORS_BUS_TYPE_PCI;
109         else if (!strncmp(name, "spi", dash - name))
110                 res->bus.type = SENSORS_BUS_TYPE_SPI;
111         else
112                 goto ERROR;
113         name = dash + 1;
114
115         /* Some bus types (i2c, spi) have an additional bus number.
116            For these, the next part is either a "*" (any bus of that type)
117            or a decimal number. */
118         switch (res->bus.type) {
119         case SENSORS_BUS_TYPE_I2C:
120         case SENSORS_BUS_TYPE_SPI:
121                 if (!strncmp(name, "*-", 2)) {
122                         res->bus.nr = SENSORS_BUS_NR_ANY;
123                         name += 2;
124                         break;
125                 }
126
127                 res->bus.nr = strtoul(name, &dash, 10);
128                 if (*name == '\0' || *dash != '-' || res->bus.nr < 0)
129                         goto ERROR;
130                 name = dash + 1;
131                 break;
132         default:
133                 res->bus.nr = SENSORS_BUS_NR_ANY;
134         }
135
136         /* Last part is the chip address, or "*" for any address. */
137         if (!strcmp(name, "*")) {
138                 res->addr = SENSORS_CHIP_NAME_ADDR_ANY;
139         } else {
140                 res->addr = strtoul(name, &dash, 16);
141                 if (*name == '\0' || *dash != '\0' || res->addr < 0)
142                         goto ERROR;
143         }
144
145         return 0;
146
147 ERROR:
148         free(res->prefix);
149         return -SENSORS_ERR_CHIP_NAME;
150 }
151
152 int sensors_snprintf_chip_name(char *str, size_t size,
153                                const sensors_chip_name *chip)
154 {
155         if (sensors_chip_name_has_wildcards(chip))
156                 return -SENSORS_ERR_WILDCARDS;
157
158         switch (chip->bus.type) {
159         case SENSORS_BUS_TYPE_ISA:
160                 return snprintf(str, size, "%s-isa-%04x", chip->prefix,
161                                 chip->addr);
162         case SENSORS_BUS_TYPE_PCI:
163                 return snprintf(str, size, "%s-pci-%04x", chip->prefix,
164                                 chip->addr);
165         case SENSORS_BUS_TYPE_I2C:
166                 return snprintf(str, size, "%s-i2c-%hd-%02x", chip->prefix,
167                                 chip->bus.nr, chip->addr);
168         case SENSORS_BUS_TYPE_SPI:
169                 return snprintf(str, size, "%s-spi-%hd-%x", chip->prefix,
170                                 chip->bus.nr, chip->addr);
171         }
172
173         return -SENSORS_ERR_CHIP_NAME;
174 }
175
176 int sensors_parse_bus_id(const char *name, sensors_bus_id *bus)
177 {
178         char *endptr;
179
180         if (strncmp(name, "i2c-", 4)) {
181                 return -SENSORS_ERR_BUS_NAME;
182         }
183         name += 4;
184         bus->type = SENSORS_BUS_TYPE_I2C;
185         bus->nr = strtoul(name, &endptr, 10);
186         if (*name == '\0' || *endptr != '\0' || bus->nr < 0)
187                 return -SENSORS_ERR_BUS_NAME;
188         return 0;
189 }
190
191 int sensors_substitute_chip(sensors_chip_name *name, int lineno)
192 {
193         int i, j;
194         for (i = 0; i < sensors_config_busses_count; i++)
195                 if (sensors_config_busses[i].bus.type == name->bus.type &&
196                     sensors_config_busses[i].bus.nr == name->bus.nr)
197                         break;
198
199         if (i == sensors_config_busses_count) {
200                 sensors_parse_error("Undeclared bus id referenced", lineno);
201                 name->bus.nr = SENSORS_BUS_NR_IGNORE;
202                 return -SENSORS_ERR_BUS_NAME;
203         }
204
205         /* Compare the adapter names */
206         for (j = 0; j < sensors_proc_bus_count; j++) {
207                 if (!strcmp(sensors_config_busses[i].adapter,
208                             sensors_proc_bus[j].adapter)) {
209                         name->bus.nr = sensors_proc_bus[j].bus.nr;
210                         return 0;
211                 }
212         }
213
214         /* We did not find a matching bus name, simply ignore this chip
215            config entry. */
216         name->bus.nr = SENSORS_BUS_NR_IGNORE;
217         return 0;
218 }
219
220 int sensors_substitute_busses(void)
221 {
222         int err, i, j, lineno;
223         sensors_chip_name_list *chips;
224         int res = 0;
225
226         for (i = 0; i < sensors_config_chips_count; i++) {
227                 lineno = sensors_config_chips[i].lineno;
228                 chips = &sensors_config_chips[i].chips;
229                 for (j = 0; j < chips->fits_count; j++) {
230                         /* We can only substitute if a specific bus number
231                            is given. */
232                         if (chips->fits[j].bus.nr == SENSORS_BUS_NR_ANY)
233                                 continue;
234
235                         err = sensors_substitute_chip(&chips->fits[j], lineno);
236                         if (err)
237                                 res = err;
238                 }
239         }
240         return res;
241 }
Note: See TracBrowser for help on using the browser.