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

Revision 4673, 7.8 KB (checked in by khali, 7 years ago)

Rename sensors_chip_name.busname to path, as this is what we are using
it for by now.

  • 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
5    This program is free software; you can redistribute it and/or modify
6    it under the terms of the GNU General Public License as published by
7    the Free Software Foundation; either version 2 of the License, or
8    (at your option) any later version.
9
10    This program is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13    GNU General Public License for more details.
14
15    You should have received a copy of the GNU General Public License
16    along with this program; if not, write to the Free Software
17    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18*/
19
20#include <stdlib.h>
21#include <string.h>
22
23#include "error.h"
24#include "data.h"
25#include "sensors.h"
26#include "../version.h"
27
28const char *libsensors_version = LM_VERSION;
29
30sensors_chip *sensors_config_chips = NULL;
31int sensors_config_chips_count = 0;
32int sensors_config_chips_max = 0;
33
34sensors_bus *sensors_config_busses = NULL;
35int sensors_config_busses_count = 0;
36int sensors_config_busses_max = 0;
37
38sensors_chip_features *sensors_proc_chips = NULL;
39int sensors_proc_chips_count = 0;
40int sensors_proc_chips_max = 0;
41
42sensors_bus *sensors_proc_bus = NULL;
43int sensors_proc_bus_count = 0;
44int sensors_proc_bus_max = 0;
45
46static int sensors_substitute_chip(sensors_chip_name *name,int lineno);
47
48/* Wow, this must be one of the ugliest functions I have ever written.
49   The idea is that it parses a chip name. These are valid names:
50
51     lm78-i2c-10-5e             *-i2c-10-5e
52     lm78-i2c-10-*              *-i2c-10-*
53     lm78-i2c-*-5e              *-i2c-*-5e
54     lm78-i2c-*-*               *-i2c-*-*
55     lm78-isa-10dd              *-isa-10dd
56     lm78-isa-*                 *-isa-*
57     lm78-*                     *-*
58                                *
59   Here 'lm78' can be any prefix. To complicate matters, such a prefix
60   can also contain dashes (like lm78-j, for example!). 'i2c' and 'isa' are
61   literal strings, just like all dashes '-' and wildcards '*'. '10' can
62   be any decimal i2c bus number. '5e' can be any hexadecimal i2c device
63   address, and '10dd' any hexadecimal isa address.
64
65   If '*' is used in prefixes, together with dashes, ambigious parses are
66   introduced. In that case, the prefix is kept as small as possible.
67
68   The 'prefix' part in the result is freshly allocated. All old contents
69   of res is overwritten. res itself is not allocated. In case of an error
70   return (ie. != 0), res is undefined, but all allocations are undone.
71
72   Don't tell me there are bugs in here, because I'll start screaming :-)
73*/
74
75int sensors_parse_chip_name(const char *orig_name, sensors_chip_name *res)
76{
77  char *part2, *part3, *part4;
78  char *name = strdup(orig_name);
79  int i;
80
81  if (! name)
82    sensors_fatal_error("sensors_parse_chip_name","Allocating new name");
83  /* First split name in upto four pieces. */
84  if ((part4 = strrchr(name,'-')))
85    *part4++ = '\0';
86  if ((part3 = strrchr(name,'-')))
87    *part3++ = '\0';
88  if ((part2 = strrchr(name,'-'))) 
89    *part2++ = '\0';
90
91  /* No dashes found? */
92  if (! part4) {
93    if (!strcmp(name,"*")) {
94      res->prefix = SENSORS_CHIP_NAME_PREFIX_ANY;
95      res->bus = SENSORS_CHIP_NAME_BUS_ANY;
96      res->addr = SENSORS_CHIP_NAME_ADDR_ANY;
97      goto SUCCES;
98    } else 
99      goto ERROR;
100  }
101
102  /* At least one dash found. Now part4 is either '*', or an address */
103  if (!strcmp(part4,"*"))
104    res->addr = SENSORS_CHIP_NAME_ADDR_ANY;
105  else {
106    if ((strlen(part4) > 4) || (strlen(part4) == 0))
107      goto ERROR;
108    res->addr = 0;
109    for (i = 0; ; i++) { 
110      switch (part4[i]) {
111      case '0': case '1': case '2': case '3': case '4':
112      case '5': case '6': case '7': case '8': case '9':
113        res->addr = res->addr * 16 + part4[i] - '0';
114        break;
115      case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
116        res->addr = res->addr * 16 + part4[i] - 'a' + 10;
117        break;
118      case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
119        res->addr = res->addr * 16 + part4[i] - 'A' + 10;
120        break;
121      case 0:
122        goto DONE;
123      default:
124        goto ERROR;
125      }
126    }
127DONE:;
128  }
129
130  /* OK. So let's look at part3. It must either be the number of the
131     i2c bus (and then part2 *must* be "i2c"), or it must be "isa",
132     or, if part4 was "*", it belongs to 'prefix'. Or no second dash
133     was found at all, of course. */
134  if (! part3) {
135    if (res->addr == SENSORS_CHIP_NAME_ADDR_ANY) {
136      res->bus = SENSORS_CHIP_NAME_BUS_ANY;
137    } else
138      goto ERROR;
139  } else if (!strcmp(part3,"isa")) {
140    res->bus = SENSORS_CHIP_NAME_BUS_ISA;
141    if (part2)
142      *(part2-1) = '-';
143  } else if (!strcmp(part3,"pci")) {
144    res->bus = SENSORS_CHIP_NAME_BUS_PCI;
145    if (part2)
146      *(part2-1) = '-';
147  } else if (part2 && !strcmp(part2,"i2c") && !strcmp(part3,"*"))
148    res->bus = SENSORS_CHIP_NAME_BUS_ANY_I2C;
149  else if (part2 && !strcmp(part2,"i2c")) {
150    if ((strlen(part3) > 3) || (strlen(part3) == 0))
151      goto ERROR;
152    res->bus = 0;
153    for (i = 0; ; i++) { 
154      switch (part3[i]) {
155      case '0': case '1': case '2': case '3': case '4':
156      case '5': case '6': case '7': case '8': case '9':
157        res->bus = res->bus * 10 + part3[i] - '0';
158        break;
159      case 0:
160        goto DONE2;
161      default:
162        goto ERROR;
163      }
164    }
165DONE2:;
166  } else if (res->addr == SENSORS_CHIP_NAME_ADDR_ANY) {
167    res->bus = SENSORS_CHIP_NAME_BUS_ANY;
168    if (part2)
169      *(part2-1) = '-';
170    *(part3-1) = '-';
171  } else
172    goto ERROR;
173   
174  if (!strcmp(name,"*"))
175    res->prefix = SENSORS_CHIP_NAME_PREFIX_ANY;
176  else if (! (res->prefix = strdup(name)))
177    sensors_fatal_error("sensors_parse_chip_name","Allocating new name");
178  goto SUCCES;
179
180SUCCES:
181  free(name);
182  return 0;
183
184ERROR:
185  free(name);
186  return -SENSORS_ERR_CHIP_NAME;
187}
188
189int sensors_parse_i2cbus_name(const char *name, int *res)
190{
191  int i;
192
193  if (! strcmp(name,"isa")) {
194    *res = SENSORS_CHIP_NAME_BUS_ISA;
195    return 0;
196  }
197  if (strncmp(name,"i2c-",4)) {
198    return -SENSORS_ERR_BUS_NAME;
199  }
200  name += 4;
201  if ((strlen(name) > 3) || (strlen(name) == 0))
202    return -SENSORS_ERR_BUS_NAME;
203  *res = 0;
204  for (i = 0; ; i++) { 
205    switch (name[i]) {
206    case '0': case '1': case '2': case '3': case '4':
207    case '5': case '6': case '7': case '8': case '9':
208      *res = *res * 10 + name[i] - '0';
209      break;
210    case 0:
211      return 0;
212    default:
213      return -SENSORS_ERR_BUS_NAME;
214    }
215  }
216}
217
218
219int sensors_substitute_chip(sensors_chip_name *name,int lineno)
220{
221  int i,j;
222  for (i = 0; i < sensors_config_busses_count; i++)
223    if (sensors_config_busses[i].number == name->bus)
224      break;
225
226  if (i == sensors_config_busses_count) {
227    sensors_parse_error("Undeclared i2c bus referenced",lineno);
228    name->bus = sensors_proc_bus_count;
229    return -SENSORS_ERR_BUS_NAME;
230  }
231
232  /* Compare the adapter names */
233  for (j = 0; j < sensors_proc_bus_count; j++) {
234    if (!strcmp(sensors_config_busses[i].adapter,
235                sensors_proc_bus[j].adapter)) {
236      name->bus = sensors_proc_bus[j].number;
237      return 0;
238    }
239  }
240
241  /* We did not find anything. sensors_proc_bus_count is not a valid
242     bus number, so it will never be matched. Good. */
243  name->bus = sensors_proc_bus_count;
244  return 0;
245}
246
247     
248int sensors_substitute_busses(void)
249{
250  int err,i,j,lineno;
251  sensors_chip_name_list *chips;
252  int res=0;
253 
254  for(i = 0; i < sensors_config_chips_count; i++) {
255    lineno = sensors_config_chips[i].lineno;
256    chips = &sensors_config_chips[i].chips;
257    for(j = 0; j < chips->fits_count; j++)
258      if ((chips->fits[j].bus != SENSORS_CHIP_NAME_BUS_ISA) &&
259          (chips->fits[j].bus != SENSORS_CHIP_NAME_BUS_PCI) &&
260          (chips->fits[j].bus != SENSORS_CHIP_NAME_BUS_ANY) &&
261          (chips->fits[j].bus != SENSORS_CHIP_NAME_BUS_ANY_I2C))
262        if ((err = sensors_substitute_chip(chips->fits+j, lineno)))
263          res = err;
264  }
265  return res;
266}
Note: See TracBrowser for help on using the browser.