root/lm-sensors/branches/lm-sensors-3.0.0/lib/data.c @ 4736

Revision 4736, 6.7 KB (checked in by khali, 7 years 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
33const char *libsensors_version = LM_VERSION;
34
35sensors_chip *sensors_config_chips = NULL;
36int sensors_config_chips_count = 0;
37int sensors_config_chips_max = 0;
38
39sensors_bus *sensors_config_busses = NULL;
40int sensors_config_busses_count = 0;
41int sensors_config_busses_max = 0;
42
43sensors_chip_features *sensors_proc_chips = NULL;
44int sensors_proc_chips_count = 0;
45int sensors_proc_chips_max = 0;
46
47sensors_bus *sensors_proc_bus = NULL;
48int sensors_proc_bus_count = 0;
49int sensors_proc_bus_max = 0;
50
51static 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
74int 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
147ERROR:
148        free(res->prefix);
149        return -SENSORS_ERR_CHIP_NAME;
150}
151
152int 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
176int 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
191int 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
220int 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.